#include "XSUB.h"
#include "ppport.h"
#ifdef __cplusplus
-
+}
#endif
-#include "image.h"
+#define i_int_hlines_testing() 1
+
+#include "imager.h"
#include "feat.h"
#include "dynaload.h"
#include "regmach.h"
+#include "imextdef.h"
typedef io_glue* Imager__IO;
-typedef i_color* Imager__Color;
-typedef i_fcolor* Imager__Color__Float;
-typedef i_img* Imager__ImgRaw;
-#ifdef HAVE_LIBTT
-typedef TT_Fonthandle* Imager__Font__TT;
+#if i_int_hlines_testing()
+#include "imageri.h"
#endif
-#ifdef HAVE_FT2
-typedef FT2_Fonthandle* Imager__Font__FT2;
-#endif
+#include "imperl.h"
/* These functions are all shared - then comes platform dependant code */
static int getstr(void *hv_t,char *key,char **store) {
{ "custom", od_custom, },
};
-static int
-hv_fetch_bool(HV *hv, char *name, int def) {
- SV **sv;
-
- sv = hv_fetch(hv, name, strlen(name), 0);
- if (sv && *sv) {
- return SvTRUE(*sv);
- }
- else
- return def;
-}
-
-static int
-hv_fetch_int(HV *hv, char *name, int def) {
- SV **sv;
-
- sv = hv_fetch(hv, name, strlen(name), 0);
- if (sv && *sv) {
- return SvIV(*sv);
- }
- else
- return def;
-}
-
/* look through the hash for quantization options */
static void handle_quant_opts(i_quantize *quant, HV *hv)
{
myfree(quant->ed_map);
}
-#if 0
-/* look through the hash for options to add to opts */
-static void handle_gif_opts(i_gif_opts *opts, HV *hv)
-{
- SV **sv;
- int i;
- /**((char *)0) = '\0';*/
- opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
- opts->interlace = hv_fetch_bool(hv, "interlace", 0);
-
- sv = hv_fetch(hv, "gif_delays", 10, 0);
- if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
- AV *av = (AV*)SvRV(*sv);
- opts->delay_count = av_len(av)+1;
- opts->delays = mymalloc(sizeof(int) * opts->delay_count);
- for (i = 0; i < opts->delay_count; ++i) {
- SV *sv1 = *av_fetch(av, i, 0);
- opts->delays[i] = SvIV(sv1);
- }
- }
- sv = hv_fetch(hv, "gif_user_input", 14, 0);
- if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
- AV *av = (AV*)SvRV(*sv);
- opts->user_input_count = av_len(av)+1;
- opts->user_input_flags = mymalloc(opts->user_input_count);
- for (i = 0; i < opts->user_input_count; ++i) {
- SV *sv1 = *av_fetch(av, i, 0);
- opts->user_input_flags[i] = SvIV(sv1) != 0;
- }
- }
- sv = hv_fetch(hv, "gif_disposal", 12, 0);
- if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
- AV *av = (AV*)SvRV(*sv);
- opts->disposal_count = av_len(av)+1;
- opts->disposal = mymalloc(opts->disposal_count);
- for (i = 0; i < opts->disposal_count; ++i) {
- SV *sv1 = *av_fetch(av, i, 0);
- opts->disposal[i] = SvIV(sv1);
- }
- }
- sv = hv_fetch(hv, "gif_tran_color", 14, 0);
- if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
- i_color *col = INT2PTR(i_color *, SvIV((SV *)SvRV(*sv)));
- opts->tran_color = *col;
- }
- sv = hv_fetch(hv, "gif_positions", 13, 0);
- if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
- AV *av = (AV *)SvRV(*sv);
- opts->position_count = av_len(av) + 1;
- opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
- for (i = 0; i < opts->position_count; ++i) {
- SV **sv2 = av_fetch(av, i, 0);
- opts->positions[i].x = opts->positions[i].y = 0;
- if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
- AV *av2 = (AV*)SvRV(*sv2);
- SV **sv3;
- sv3 = av_fetch(av2, 0, 0);
- if (sv3 && *sv3)
- opts->positions[i].x = SvIV(*sv3);
- sv3 = av_fetch(av2, 1, 0);
- if (sv3 && *sv3)
- opts->positions[i].y = SvIV(*sv3);
- }
- }
- }
- /* Netscape2.0 loop count extension */
- opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
-
- opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
-}
-
-static void cleanup_gif_opts(i_gif_opts *opts) {
- if (opts->delays)
- myfree(opts->delays);
- if (opts->user_input_flags)
- myfree(opts->user_input_flags);
- if (opts->disposal)
- myfree(opts->disposal);
- if (opts->positions)
- myfree(opts->positions);
-}
-
-#endif
-
/* copies the color map from the hv into the colors member of the HV */
static void copy_colors_back(HV *hv, i_quantize *quant) {
SV **sv;
*/
int i, j;
AV *aseg;
- SV *sv;
i_fountain_seg *segs;
double work[3];
int worki[2];
#define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
#define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
-/* for the fill objects
- Since a fill object may later have dependent images, (or fills!)
- we need perl wrappers - oh well
-*/
-#define IFILL_DESTROY(fill) i_fill_destroy(fill);
-typedef i_fill_t* Imager__FillHandle;
/* the m_init_log() function was called init_log(), renamed to reduce
potential naming conflicts */
#define init_log m_init_log
+#if i_int_hlines_testing()
+
+typedef i_int_hlines *Imager__Internal__Hlines;
+
+static i_int_hlines *
+i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
+ i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
+ i_int_init_hlines(result, start_y, count_y, start_x, count_x);
+
+ return result;
+}
+
+static i_int_hlines *
+i_int_hlines_new_img(i_img *im) {
+ i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
+ i_int_init_hlines_img(result, im);
+
+ return result;
+}
+
+static void
+i_int_hlines_DESTROY(i_int_hlines *hlines) {
+ i_int_hlines_destroy(hlines);
+ myfree(hlines);
+}
+
+static int seg_compare(const void *vleft, const void *vright) {
+ const i_int_hline_seg *left = vleft;
+ const i_int_hline_seg *right = vright;
+
+ return left->minx - right->minx;
+}
+
+static SV *
+i_int_hlines_dump(i_int_hlines *hlines) {
+ SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
+ hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
+ int y;
+
+ for (y = hlines->start_y; y < hlines->limit_y; ++y) {
+ i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
+ if (entry) {
+ int i;
+ /* sort the segments, if any */
+ if (entry->count)
+ qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
+
+ sv_catpvf(dump, " %d (%d):", y, entry->count);
+ for (i = 0; i < entry->count; ++i) {
+ sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
+ entry->segs[i].x_limit);
+ }
+ sv_catpv(dump, "\n");
+ }
+ }
+
+ return dump;
+}
+
+#endif
+
+#ifdef IMEXIF_ENABLE
+#define i_exif_enabled() 1
+#else
+#define i_exif_enabled() 0
+#endif
+
MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
Imager::Color
i_rgb_to_hsvf(RETVAL);
OUTPUT:
RETVAL
-
MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
myfree(data);
+undef_int
+i_set_image_file_limits(width, height, bytes)
+ int width
+ int height
+ int bytes
+
+void
+i_get_image_file_limits()
+ PREINIT:
+ int width, height, bytes;
+ PPCODE:
+ if (i_get_image_file_limits(&width, &height, &bytes)) {
+ EXTEND(SP, 3);
+ PUSHs(sv_2mortal(newSViv(width)));
+ PUSHs(sv_2mortal(newSViv(height)));
+ PUSHs(sv_2mortal(newSViv(bytes)));
+ }
+
MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
void
float d2
Imager::Color val
+void
+i_arc_aa(im,x,y,rad,d1,d2,val)
+ Imager::ImgRaw im
+ double x
+ double y
+ double rad
+ double d1
+ double d2
+ Imager::Color val
+
void
i_arc_cfill(im,x,y,rad,d1,d2,fill)
Imager::ImgRaw im
float d2
Imager::FillHandle fill
+void
+i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
+ Imager::ImgRaw im
+ double x
+ double y
+ double rad
+ double d1
+ double d2
+ Imager::FillHandle fill
void
int ty
Imager::Color trans
-void
-i_copy(im,src)
- Imager::ImgRaw im
+Imager::ImgRaw
+i_copy(src)
Imager::ImgRaw src
undef_int
-i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
+i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
int xb
int len_ignored
int smooth
int utf8
+ int align
PREINIT:
char *str;
STRLEN len;
#endif
str = SvPV(str_sv, len);
RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
- len, smooth, utf8);
+ len, smooth, utf8, align);
OUTPUT:
RETVAL
undef_int
-i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
+i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
Imager::Font::TT handle
Imager::ImgRaw im
int xb
int len_ignored
int smooth
int utf8
+ int align
PREINIT:
char *str;
STRLEN len;
#endif
str = SvPV(str_sv, len);
RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
- smooth, utf8);
+ smooth, utf8, align);
OUTPUT:
RETVAL
-undef_int
+void
i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
Imager::Font::TT handle
float point
myfree(iptc_itext);
}
+int
+i_exif_enabled()
#endif
#ifdef HAVE_LIBTIFF
Imager::ImgRaw
-i_readtiff_wiol(ig, length)
+i_readtiff_wiol(ig, length, page=0)
Imager::IO ig
int length
+ int page
void
i_readtiff_multi_wiol(ig, length)
PUSHs(newRV_noinc((SV*)ct));
}
+Imager::ImgRaw
+i_readgif_single_wiol(ig, page=0)
+ Imager::IO ig
+ int page
+
void
i_readgif_scalar(...)
PROTOTYPE: $
i_readgif_callback(...)
PROTOTYPE: &
PREINIT:
- char* data;
- int length;
int* colour_table;
int colours, q, w;
i_img* rimg;
-# this is mostly for testing...
-# this function results in 'RETVAL' : unreferenced local variable
-# in VC++, and might be subtley wrong
-# the most obvious change may result in a double free so I'm leaving it
-# for now
SV *
i_get_pixel(im, x, y)
Imager::ImgRaw im
CODE:
color = (i_color *)mymalloc(sizeof(i_color));
if (i_gpix(im, x, y, color) == 0) {
- ST(0) = sv_newmortal();
- sv_setref_pv(ST(0), "Imager::Color", (void *)color);
+ RETVAL = NEWSV(0, 0);
+ sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
}
else {
myfree(color);
- ST(0) = &PL_sv_undef;
+ RETVAL = &PL_sv_undef;
}
+ OUTPUT:
+ RETVAL
int
}
else {
myfree(colors);
- croak("i_plin: pixels must be Imager::Color objects");
+ croak("i_addcolor: pixels must be Imager::Color objects");
}
}
index = i_addcolors(im, colors, items-1);
myfree(colors);
if (index == 0) {
- ST(0) = sv_2mortal(newSVpv("0 but true", 0));
+ RETVAL = newSVpv("0 but true", 0);
}
else if (index == -1) {
- ST(0) = &PL_sv_undef;
+ RETVAL = &PL_sv_undef;
}
else {
- ST(0) = sv_2mortal(newSViv(index));
+ RETVAL = newSViv(index);
}
+ OUTPUT:
+ RETVAL
undef_int
i_setcolors(im, index, ...)
myfree(colors);
-SV *
+undef_neg_int
i_colorcount(im)
Imager::ImgRaw im
- PREINIT:
- int count;
- CODE:
- count = i_colorcount(im);
- if (count >= 0) {
- ST(0) = sv_2mortal(newSViv(count));
- }
- else {
- ST(0) = &PL_sv_undef;
- }
-SV *
+undef_neg_int
i_maxcolors(im)
Imager::ImgRaw im
- PREINIT:
- int count;
- CODE:
- count = i_maxcolors(im);
- if (count >= 0) {
- ST(0) = sv_2mortal(newSViv(count));
- }
- else {
- ST(0) = &PL_sv_undef;
- }
SV *
i_findcolor(im, color)
i_palidx index;
CODE:
if (i_findcolor(im, color, &index)) {
- ST(0) = sv_2mortal(newSViv(index));
+ RETVAL = newSViv(index);
}
else {
- ST(0) = &PL_sv_undef;
+ RETVAL = &PL_sv_undef;
}
+ OUTPUT:
+ RETVAL
int
i_img_bits(im)
PREINIT:
i_color *work;
int i;
+ STRLEN len;
+ int count;
CODE:
if (items > 3) {
- work = mymalloc(sizeof(i_color) * (items-3));
- for (i=0; i < items-3; ++i) {
- if (sv_isobject(ST(i+3))
- && sv_derived_from(ST(i+3), "Imager::Color")) {
- IV tmp = SvIV((SV *)SvRV(ST(i+3)));
- work[i] = *INT2PTR(i_color *, tmp);
+ if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
+ /* supplied as a byte string */
+ work = (i_color *)SvPV(ST(3), len);
+ count = len / sizeof(i_color);
+ if (count * sizeof(i_color) != len) {
+ croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
}
- else {
- myfree(work);
- croak("i_plin: pixels must be Imager::Color objects");
+ RETVAL = i_plin(im, l, l+count, y, work);
+ }
+ else {
+ work = mymalloc(sizeof(i_color) * (items-3));
+ for (i=0; i < items-3; ++i) {
+ if (sv_isobject(ST(i+3))
+ && sv_derived_from(ST(i+3), "Imager::Color")) {
+ IV tmp = SvIV((SV *)SvRV(ST(i+3)));
+ work[i] = *INT2PTR(i_color *, tmp);
+ }
+ else {
+ myfree(work);
+ croak("i_plin: pixels must be Imager::Color objects");
+ }
}
+ RETVAL = i_plin(im, l, l+items-3, y, work);
+ myfree(work);
}
- /**(char *)0 = 1;*/
- RETVAL = i_plin(im, l, l+items-3, y, work);
- myfree(work);
}
else {
RETVAL = 0;
PREINIT:
i_fcolor *work;
int i;
+ STRLEN len;
+ int count;
CODE:
if (items > 3) {
- work = mymalloc(sizeof(i_fcolor) * (items-3));
- for (i=0; i < items-3; ++i) {
- if (sv_isobject(ST(i+3))
- && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
- IV tmp = SvIV((SV *)SvRV(ST(i+3)));
- work[i] = *INT2PTR(i_fcolor *, tmp);
+ if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
+ /* supplied as a byte string */
+ work = (i_fcolor *)SvPV(ST(3), len);
+ count = len / sizeof(i_fcolor);
+ if (count * sizeof(i_fcolor) != len) {
+ croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
}
- else {
- myfree(work);
- croak("i_plin: pixels must be Imager::Color::Float objects");
+ RETVAL = i_plinf(im, l, l+count, y, work);
+ }
+ else {
+ work = mymalloc(sizeof(i_fcolor) * (items-3));
+ for (i=0; i < items-3; ++i) {
+ if (sv_isobject(ST(i+3))
+ && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
+ IV tmp = SvIV((SV *)SvRV(ST(i+3)));
+ work[i] = *INT2PTR(i_fcolor *, tmp);
+ }
+ else {
+ myfree(work);
+ croak("i_plinf: pixels must be Imager::Color::Float objects");
+ }
}
+ /**(char *)0 = 1;*/
+ RETVAL = i_plinf(im, l, l+items-3, y, work);
+ myfree(work);
}
- /**(char *)0 = 1;*/
- RETVAL = i_plinf(im, l, l+items-3, y, work);
- myfree(work);
}
else {
RETVAL = 0;
CODE:
color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
if (i_gpixf(im, x, y, color) == 0) {
- ST(0) = sv_newmortal();
- sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
+ RETVAL = NEWSV(0,0);
+ sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
}
else {
myfree(color);
- ST(0) = &PL_sv_undef;
+ RETVAL = &PL_sv_undef;
}
-
+ OUTPUT:
+ RETVAL
+
void
i_glin(im, l, r, y)
Imager::ImgRaw im
if (l < r) {
vals = mymalloc((r-l) * sizeof(i_color));
count = i_glin(im, l, r, y, vals);
- EXTEND(SP, count);
- for (i = 0; i < count; ++i) {
- SV *sv;
- i_color *col = mymalloc(sizeof(i_color));
- sv = sv_newmortal();
- sv_setref_pv(sv, "Imager::Color", (void *)col);
- PUSHs(sv);
+ if (GIMME_V == G_ARRAY) {
+ EXTEND(SP, count);
+ for (i = 0; i < count; ++i) {
+ SV *sv;
+ i_color *col = mymalloc(sizeof(i_color));
+ *col = vals[i];
+ sv = sv_newmortal();
+ sv_setref_pv(sv, "Imager::Color", (void *)col);
+ PUSHs(sv);
+ }
+ }
+ else if (count) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
}
myfree(vals);
}
if (l < r) {
vals = mymalloc((r-l) * sizeof(i_fcolor));
count = i_glinf(im, l, r, y, vals);
- EXTEND(SP, count);
- for (i = 0; i < count; ++i) {
- SV *sv;
- i_fcolor *col = mymalloc(sizeof(i_fcolor));
- *col = vals[i];
- sv = sv_newmortal();
- sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
- PUSHs(sv);
+ if (GIMME_V == G_ARRAY) {
+ EXTEND(SP, count);
+ for (i = 0; i < count; ++i) {
+ SV *sv;
+ i_fcolor *col = mymalloc(sizeof(i_fcolor));
+ *col = vals[i];
+ sv = sv_newmortal();
+ sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
+ PUSHs(sv);
+ }
+ }
+ else if (count) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
}
myfree(vals);
}
CODE:
if (i_tags_find(&im->tags, name, start, &entry)) {
if (entry == 0)
- ST(0) = sv_2mortal(newSVpv("0 but true", 0));
+ RETVAL = newSVpv("0 but true", 0);
else
- ST(0) = sv_2mortal(newSViv(entry));
+ RETVAL = newSViv(entry);
} else {
- ST(0) = &PL_sv_undef;
+ RETVAL = &PL_sv_undef;
}
+ OUTPUT:
+ RETVAL
SV *
i_tags_findn(im, code, start)
CODE:
if (i_tags_findn(&im->tags, code, start, &entry)) {
if (entry == 0)
- ST(0) = sv_2mortal(newSVpv("0 but true", 0));
+ RETVAL = newSVpv("0 but true", 0);
else
- ST(0) = sv_2mortal(newSViv(entry));
+ RETVAL = newSViv(entry);
}
- else
- ST(0) = &PL_sv_undef;
+ else {
+ RETVAL = &PL_sv_undef;
+ }
+ OUTPUT:
+ RETVAL
int
i_tags_delete(im, entry)
}
}
+void
+i_tags_get_string(im, what_sv)
+ Imager::ImgRaw im
+ SV *what_sv
+ PREINIT:
+ char const *name = NULL;
+ int code;
+ char buffer[200];
+ PPCODE:
+ if (SvIOK(what_sv)) {
+ code = SvIV(what_sv);
+ name = NULL;
+ }
+ else {
+ name = SvPV_nolen(what_sv);
+ code = 0;
+ }
+ if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
+ EXTEND(SP, 1);
+ PUSHs(sv_2mortal(newSVpv(buffer, 0)));
+ }
+
int
i_tags_count(im)
Imager::ImgRaw im
OUTPUT:
RETVAL
+undef_int
+i_wf_addfont(font)
+ char *font
#endif
OUTPUT:
RETVAL
+MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
+
+# this class is only exposed for testing
+
+int
+i_int_hlines_testing()
+
+#if i_int_hlines_testing()
+
+Imager::Internal::Hlines
+i_int_hlines_new(start_y, count_y, start_x, count_x)
+ int start_y
+ int count_y
+ int start_x
+ int count_x
+
+Imager::Internal::Hlines
+i_int_hlines_new_img(im)
+ Imager::ImgRaw im
+
+void
+i_int_hlines_add(hlines, y, minx, width)
+ Imager::Internal::Hlines hlines
+ int y
+ int minx
+ int width
+
+void
+i_int_hlines_DESTROY(hlines)
+ Imager::Internal::Hlines hlines
+
+SV *
+i_int_hlines_dump(hlines)
+ Imager::Internal::Hlines hlines
+
+#endif
+
+BOOT:
+ PERL_SET_GLOBAL_CALLBACKS;