#include "imperl.h"
+#define ARRAY_COUNT(array) (sizeof(array)/sizeof(*array))
+
/*
Context object management
START_MY_CXT
-im_context_t fallback_context;
-
static void
start_context(pTHX) {
dMY_CXT;
MY_CXT.ctx = im_context_new();
sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
-
- /* Ideally we'd free this reference, but the error message memory
- was never released on exit, so the associated memory here is reasonable
- to keep.
- With logging enabled we always need at least one context, since
- objects may be released fairly late and attempt to get the log file.
- */
- im_context_refinc(MY_CXT.ctx, "start_context");
- fallback_context = MY_CXT.ctx;
}
static im_context_t
dTHX;
dMY_CXT;
- return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
+ return MY_CXT.ctx;
}
#else
static void
start_context(pTHX) {
perl_context = im_context_new();
- im_context_refinc(perl_context, "start_context");
+
+ /* just so it gets destroyed */
+ sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", perl_context);
}
static im_context_t
const i_fsample_t *samples;
} i_fsample_list;
+typedef struct {
+ size_t count;
+ const i_polygon_t *polygons;
+} i_polygon_list;
+
/*
Allocate memory that will be discarded when mortals are discarded.
static void *
malloc_temp(pTHX_ size_t size) {
- SV *sv = sv_2mortal(newSV(size));
+ void *result;
+ Newx(result, size, char);
+ SAVEFREEPV(result);
- return SvPVX(sv);
+ return result;
}
static void *
calloc_temp(pTHX_ size_t size) {
- void *result = malloc_temp(aTHX_ size);
- memset(result, 0, size);
+ void *result;
+ Newxz(result, size, char);
+ SAVEFREEPV(result);
return result;
}
static i_color
S_sv_to_i_color(pTHX_ SV *sv, const char *pname) {
if (!sv_derived_from(sv, "Imager::Color")) {
- croak("%s: not a color object");
+ croak("%s: not a color object", pname);
}
return *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
}
UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
-void my_SvREFCNT_dec(void *p) {
- dTHX;
- SvREFCNT_dec((SV*)p);
+static void
+free_buffer(void *p) {
+ myfree(p);
}
if (SvOK(cbd->closecb)) {
dSP;
I32 count;
- SV *sv;
ENTER;
SAVETMPS;
SPAGAIN;
- sv = POPs;
- success = SvTRUE(sv);
+ if (count) {
+ SV *sv = POPs;
+ success = SvTRUE(sv);
+ }
+ else
+ success = 0;
PUTBACK;
FREETMPS;
myfree(cbd);
}
-static i_io_glue_t *
-do_io_new_buffer(pTHX_ SV *data_sv) {
- const char *data;
- STRLEN length;
+static bool
+im_SvREFSCALAR(SV *sv) {
+ svtype type = SvTYPE(sv);
+
+ switch (type) {
+ case SVt_PV:
+ case SVt_PVIV:
+ case SVt_PVNV:
+ case SVt_PVMG:
+ case SVt_IV:
+ case SVt_NV:
+ case SVt_PVLV:
+#if PERL_VERSION > 10
+ case SVt_REGEXP:
+#endif
+ return 1;
- data = SvPVbyte(data_sv, length);
- SvREFCNT_inc(data_sv);
- return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
+ default:
+ return 0;
+ }
}
static const char *
}
}
+static i_io_glue_t *
+do_io_new_buffer(pTHX_ SV *data_sv) {
+ const char *data;
+ char *data_copy;
+ STRLEN length;
+ SV *sv;
+
+ SvGETMAGIC(data_sv);
+ if (SvROK(data_sv)) {
+ if (im_SvREFSCALAR(SvRV(data_sv))) {
+ sv = SvRV(data_sv);
+ }
+ else {
+ i_push_errorf(0, "data is not a scalar or a reference to scalar");
+ return NULL;
+ }
+ }
+ else {
+ sv = data_sv;
+ }
+
+ /* previously this would keep the SV around, but this is unsafe in
+ many ways, so always copy the bytes */
+ data = SvPVbyte(sv, length);
+ data_copy = mymalloc(length);
+ memcpy(data_copy, data, length);
+ return io_new_buffer(data_copy, length, free_buffer, data_copy);
+}
+
static i_io_glue_t *
do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
struct cbdata *cbd;
char *name;
int value;
};
-static int lookup_name(struct value_name *names, int count, char *name, int def_value)
+static int lookup_name(const struct value_name *names, int count, char *name, int def_value)
{
int i;
for (i = 0; i < count; ++i)
}
}
+static struct value_name
+poly_fill_mode_names[] =
+{
+ { "evenodd", i_pfm_evenodd },
+ { "nonzero", i_pfm_nonzero }
+};
+
+static i_poly_fill_mode_t
+S_get_poly_fill_mode(pTHX_ SV *sv) {
+ if (looks_like_number(sv)) {
+ IV work = SvIV(sv);
+ if (work < (IV)i_pfm_evenodd || work > (IV)i_pfm_nonzero)
+ work = (IV)i_pfm_evenodd;
+ return (i_poly_fill_mode_t)work;
+ }
+ else {
+ return (i_poly_fill_mode_t)lookup_name
+ (poly_fill_mode_names, ARRAY_COUNT(poly_fill_mode_names),
+ SvPV_nolen(sv), i_pfm_evenodd);
+ }
+}
+
+static void
+S_get_polygon_list(pTHX_ i_polygon_list *polys, SV *sv) {
+ AV *av;
+ int i;
+ i_polygon_t *s;
+
+ SvGETMAGIC(sv);
+ if (!SvOK(sv) || !SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV)
+ croak("polys must be an arrayref");
+
+ av = (AV*)SvRV(sv);
+ polys->count = av_len(av) + 1;
+ if (polys->count < 1)
+ croak("polypolygon: no polygons provided");
+ s = malloc_temp(aTHX_ sizeof(i_polygon_t) * polys->count);
+ for (i = 0; i < polys->count; ++i) {
+ SV **poly_sv = av_fetch(av, i, 0);
+ AV *poly_av;
+ SV **x_sv, **y_sv;
+ AV *x_av, *y_av;
+ double *x_data, *y_data;
+ ssize_t j;
+ ssize_t point_count;
+
+ if (!poly_sv)
+ croak("poly_polygon: nothing found for polygon %d", i);
+ /* needs to be another av */
+ SvGETMAGIC(*poly_sv);
+ if (!SvOK(*poly_sv) || !SvROK(*poly_sv) || SvTYPE(SvRV(*poly_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d isn't an arrayref", i);
+ poly_av = (AV*)SvRV(*poly_sv);
+ /* with two elements */
+ if (av_len(poly_av) != 1)
+ croak("poly_polygon: polygon %d should contain two arrays", i);
+ x_sv = av_fetch(poly_av, 0, 0);
+ y_sv = av_fetch(poly_av, 1, 0);
+ if (!x_sv)
+ croak("poly_polygon: polygon %d has no x elements", i);
+ if (!y_sv)
+ croak("poly_polygon: polygon %d has no y elements", i);
+ SvGETMAGIC(*x_sv);
+ SvGETMAGIC(*y_sv);
+ if (!SvOK(*x_sv) || !SvROK(*x_sv) || SvTYPE(SvRV(*x_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d x elements isn't an array", i);
+ if (!SvOK(*y_sv) || !SvROK(*y_sv) || SvTYPE(SvRV(*y_sv)) != SVt_PVAV)
+ croak("poly_polygon: polygon %d y elements isn't an array", i);
+ x_av = (AV*)SvRV(*x_sv);
+ y_av = (AV*)SvRV(*y_sv);
+ if (av_len(x_av) != av_len(y_av))
+ croak("poly_polygon: polygon %d x and y arrays different lengths", i+1);
+ point_count = av_len(x_av)+1;
+ x_data = malloc_temp(aTHX_ sizeof(double) * point_count * 2);
+ y_data = x_data + point_count;
+
+ for (j = 0; j < point_count; ++j) {
+ SV **x_item_sv = av_fetch(x_av, j, 0);
+ SV **y_item_sv = av_fetch(y_av, j, 0);
+ x_data[j] = x_item_sv ? SvNV(*x_item_sv) : 0;
+ y_data[j] = y_item_sv ? SvNV(*y_item_sv) : 0;
+ }
+ s[i].x = x_data;
+ s[i].y = y_data;
+ s[i].count = point_count;
+ }
+ polys->polygons = s;
+}
+
/* loads the segments of a fountain fill into an array */
static i_fountain_seg *
load_fount_segs(pTHX_ AV *asegs, int *count) {
#define IIM_new i_img_8_new
#define IIM_DESTROY i_img_destroy
+typedef int SysRet;
#ifdef IMEXIF_ENABLE
#define i_exif_enabled() 1
io_new_buffer(data_sv)
SV *data_sv
CODE:
+ i_clear_error();
RETVAL = do_io_new_buffer(aTHX_ data_sv);
+ if (!RETVAL)
+ XSRETURN(0);
OUTPUT:
RETVAL
SV *readcb;
SV *seekcb;
SV *closecb;
- int maxwrite;
CODE:
RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
OUTPUT:
io_new_buffer(class, data_sv)
SV *data_sv
CODE:
+ i_clear_error();
RETVAL = do_io_new_buffer(aTHX_ data_sv);
+ if (!RETVAL)
+ XSRETURN(0);
OUTPUT:
RETVAL
if (size <= 0)
croak("size negative in call to i_io_raw_read()");
/* prevent an undefined value warning if they supplied an
- undef buffer.
+ undef buffer.
Orginally conditional on !SvOK(), but this will prevent the
- downgrade from croaking */
- sv_setpvn(buffer_sv, "", 0);
+ downgrade from croaking */
+ sv_setpvn(buffer_sv, "", 0);
#ifdef SvUTF8
- if (SvUTF8(buffer_sv))
+ if (SvUTF8(buffer_sv))
sv_utf8_downgrade(buffer_sv, FALSE);
#endif
buffer = SvGROW(buffer_sv, size+1);
if (size <= 0)
croak("size negative in call to i_io_read()");
/* prevent an undefined value warning if they supplied an
- undef buffer.
+ undef buffer.
Orginally conditional on !SvOK(), but this will prevent the
- downgrade from croaking */
- sv_setpvn(buffer_sv, "", 0);
+ downgrade from croaking */
+ sv_setpvn(buffer_sv, "", 0);
#ifdef SvUTF8
- if (SvUTF8(buffer_sv))
+ if (SvUTF8(buffer_sv))
sv_utf8_downgrade(buffer_sv, FALSE);
#endif
buffer = SvGROW(buffer_sv, size+1);
i_img_get_height(im)
Imager::ImgRaw im
+int
+i_img_color_model(im)
+ Imager::ImgRaw im
+
+int
+i_img_color_channels(im)
+ Imager::ImgRaw im
+
+int
+i_img_alpha_channel(im)
+ Imager::ImgRaw im
+ CODE:
+ if (!i_img_alpha_channel(im, &RETVAL))
+ XSRETURN(0);
+ OUTPUT:
+ RETVAL
void
i_img_is_monochrome(im)
double rad
Imager::Color val
+void
+i_circle_aa_fill(im,x,y,rad,fill)
+ Imager::ImgRaw im
+ double x
+ double y
+ double rad
+ Imager::FillHandle fill
+
int
i_circle_out(im,x,y,rad,val)
Imager::ImgRaw im
void
-i_bezier_multi(im,xc,yc,val)
+i_bezier_multi(im,x,y,val)
Imager::ImgRaw im
- Imager::Color val
- PREINIT:
- double *x,*y;
- int len;
- AV *av1;
- AV *av2;
- SV *sv1;
- SV *sv2;
- int i;
- PPCODE:
- ICL_info(val);
- if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
- if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
- if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
- av1=(AV*)SvRV(ST(1));
- av2=(AV*)SvRV(ST(2));
- if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
- len=av_len(av1)+1;
- x=mymalloc( len*sizeof(double) );
- y=mymalloc( len*sizeof(double) );
- for(i=0;i<len;i++) {
- sv1=(*(av_fetch(av1,i,0)));
- sv2=(*(av_fetch(av2,i,0)));
- x[i]=(double)SvNV(sv1);
- y[i]=(double)SvNV(sv2);
- }
- i_bezier_multi(im,len,x,y,val);
- myfree(x);
- myfree(y);
-
+ double *x
+ double *y
+ Imager::Color val
+ PREINIT:
+ STRLEN size_x;
+ STRLEN size_y;
+ PPCODE:
+ if (size_x != size_y)
+ croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
+ i_bezier_multi(im,size_x,x,y,val);
int
-i_poly_aa(im,x,y,val)
+i_poly_aa_m(im,x,y,mode,val)
Imager::ImgRaw im
double *x
double *y
+ i_poly_fill_mode_t mode
Imager::Color val
PREINIT:
STRLEN size_x;
CODE:
if (size_x != size_y)
croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
- RETVAL = i_poly_aa(im, size_x, x, y, val);
+ RETVAL = i_poly_aa_m(im, size_x, x, y, mode, val);
OUTPUT:
RETVAL
int
-i_poly_aa_cfill(im, x, y, fill)
+i_poly_aa_cfill_m(im, x, y, mode, fill)
Imager::ImgRaw im
double *x
double *y
+ i_poly_fill_mode_t mode
Imager::FillHandle fill
PREINIT:
STRLEN size_x;
CODE:
if (size_x != size_y)
croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
- RETVAL = i_poly_aa_cfill(im, size_x, x, y, fill);
+ RETVAL = i_poly_aa_cfill_m(im, size_x, x, y, mode, fill);
OUTPUT:
RETVAL
+int
+i_poly_poly_aa(im, polys, mode, color)
+ Imager::ImgRaw im
+ i_polygon_list polys
+ i_poly_fill_mode_t mode
+ Imager::Color color
+ CODE:
+ RETVAL = i_poly_poly_aa(im, polys.count, polys.polygons, mode, color);
+ OUTPUT:
+ RETVAL
+
+int
+i_poly_poly_aa_cfill(im, polys, mode, fill)
+ Imager::ImgRaw im
+ i_polygon_list polys
+ i_poly_fill_mode_t mode
+ Imager::FillHandle fill
+ CODE:
+ RETVAL = i_poly_poly_aa_cfill(im, polys.count, polys.polygons, mode, fill);
+ OUTPUT:
+ RETVAL
+
undef_int
i_flood_fill(im,seedx,seedy,dcol)
Imager::ImgRaw im
AV *pmaps_av
PREINIT:
unsigned int mask = 0;
- AV *avmain;
AV *avsub;
SV **temp;
int len;
int col_cnt;
PPCODE:
col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
- EXTEND(SP, col_cnt);
- for (i = 0; i < col_cnt; i++) {
- PUSHs(sv_2mortal(newSViv( col_usage[i])));
+ if (col_cnt > 0) {
+ EXTEND(SP, col_cnt);
+ for (i = 0; i < col_cnt; i++) {
+ PUSHs(sv_2mortal(newSViv( col_usage[i])));
+ }
+ myfree(col_usage);
+ XSRETURN(col_cnt);
+ }
+ else {
+ XSRETURN_EMPTY;
}
- myfree(col_usage);
- XSRETURN(col_cnt);
void
float usat
float skew
+void
+i_autolevels_mono(im,lsat,usat)
+ Imager::ImgRaw im
+ float lsat
+ float usat
+
void
i_radnoise(im,xo,yo,rscale,ascale)
Imager::ImgRaw im
if (!av_store(av, 1, sv)) {
SvREFCNT_dec(sv);
}
- PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
+ XPUSHs(sv_2mortal(newRV_noinc((SV*)av)));
++i;
}
num = num <= av_len(ac) ? num : av_len(ac);
num++;
if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
- xo = mymalloc( sizeof(i_img_dim) * num );
- yo = mymalloc( sizeof(i_img_dim) * num );
- ival = mymalloc( sizeof(i_color) * num );
+ xo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+ yo = malloc_temp(aTHX_ sizeof(i_img_dim) * num );
+ ival = malloc_temp(aTHX_ sizeof(i_color) * num );
for(i = 0; i<num; i++) {
xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
DSO_call(handle,func_index,hv)
void* handle
int func_index
- PREINIT:
- HV* hv;
+ HV *hv
PPCODE:
- if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
- hv=(HV*)SvRV(ST(2));
- if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
DSO_call( (DSO_handle *)handle,func_index,hv);
-SV *
+Imager::Color
i_get_pixel(im, x, y)
Imager::ImgRaw im
i_img_dim x
i_img_dim y;
- PREINIT:
- i_color *color;
CODE:
- color = (i_color *)mymalloc(sizeof(i_color));
- if (i_gpix(im, x, y, color) == 0) {
- RETVAL = NEWSV(0, 0);
- sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
- }
- else {
- myfree(color);
- RETVAL = &PL_sv_undef;
+ RETVAL = (i_color *)mymalloc(sizeof(i_color));
+ memset(RETVAL, 0, sizeof(*RETVAL));
+ if (i_gpix(im, x, y, RETVAL) != 0) {
+ myfree(RETVAL);
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
PUSHs(sv_c);
}
ip_cleanup_quant_opts(aTHX_ &quant);
+ myfree(imgs);
void
OUTPUT:
RETVAL
-SV *
+SysRet
i_addcolors(im, ...)
Imager::ImgRaw im
PREINIT:
- int index;
i_color *colors;
int i;
CODE:
croak("i_addcolor: pixels must be Imager::Color objects");
}
}
- index = i_addcolors(im, colors, items-1);
+ RETVAL = i_addcolors(im, colors, items-1);
myfree(colors);
- if (index == 0) {
- RETVAL = newSVpv("0 but true", 0);
- }
- else if (index == -1) {
- RETVAL = &PL_sv_undef;
- }
- else {
- RETVAL = newSViv(index);
- }
OUTPUT:
RETVAL
RETVAL
void
-i_getcolors(im, index, ...)
+i_getcolors(im, index, count=1)
Imager::ImgRaw im
int index
+ int count
PREINIT:
i_color *colors;
- int count = 1;
int i;
PPCODE:
- if (items > 3)
- croak("i_getcolors: too many arguments");
- if (items == 3)
- count = SvIV(ST(2));
if (count < 1)
croak("i_getcolors: count must be positive");
- colors = mymalloc(sizeof(i_color) * count);
+ colors = malloc_temp(aTHX_ sizeof(i_color) * count);
if (i_getcolors(im, index, colors, count)) {
+ EXTEND(SP, count);
for (i = 0; i < count; ++i) {
SV *sv = make_i_color_sv(aTHX_ colors+i);
PUSHs(sv);
}
}
- myfree(colors);
-
undef_neg_int
i_colorcount(im)
i_maxcolors(im)
Imager::ImgRaw im
-SV *
+i_palidx
i_findcolor(im, color)
Imager::ImgRaw im
Imager::Color color
- PREINIT:
- i_palidx index;
CODE:
- if (i_findcolor(im, color, &index)) {
- RETVAL = newSViv(index);
- }
- else {
- RETVAL = &PL_sv_undef;
+ if (!i_findcolor(im, color, &RETVAL)) {
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
i_img_dim count, i;
PPCODE:
if (l < r) {
- data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
+ data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count);
count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
if (GIMME_V == G_ARRAY) {
EXTEND(SP, count);
}
else {
if (GIMME_V != G_ARRAY) {
- EXTEND(SP, 1);
- PUSHs(&PL_sv_undef);
+ XSRETURN_UNDEF;
}
}
}
else {
if (GIMME_V != G_ARRAY) {
- EXTEND(SP, 1);
- PUSHs(&PL_sv_undef);
+ XSRETURN_UNDEF;
}
}
OUTPUT:
RETVAL
-SV *
+Imager::Color::Float
i_gpixf(im, x, y)
Imager::ImgRaw im
i_img_dim x
i_img_dim y;
- PREINIT:
- i_fcolor *color;
CODE:
- color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
- if (i_gpixf(im, x, y, color) == 0) {
- RETVAL = NEWSV(0,0);
- sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
- }
- else {
- myfree(color);
- RETVAL = &PL_sv_undef;
+ RETVAL = (i_fcolor *)mymalloc(sizeof(i_fcolor));
+ memset(RETVAL, 0, sizeof(*RETVAL));
+ if (i_gpixf(im, x, y, RETVAL) != 0) {
+ myfree(RETVAL);
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
Imager::ImgRaw im
undef_int
-i_tags_addn(im, name, code, idata)
+i_tags_addn(im, name_sv, code, idata)
Imager::ImgRaw im
+ SV *name_sv
int code
int idata
PREINIT:
char *name;
STRLEN len;
CODE:
- if (SvOK(ST(1)))
- name = SvPV(ST(1), len);
+ SvGETMAGIC(name_sv);
+ if (SvOK(name_sv))
+ name = SvPV_nomg(name_sv, len);
else
name = NULL;
RETVAL = i_tags_addn(&im->tags, name, code, idata);
RETVAL
undef_int
-i_tags_add(im, name, code, data, idata)
+i_tags_add(im, name_sv, code, data_sv, idata)
Imager::ImgRaw im
+ SV *name_sv
int code
+ SV *data_sv
int idata
PREINIT:
char *name;
char *data;
STRLEN len;
CODE:
- if (SvOK(ST(1)))
- name = SvPV(ST(1), len);
+ SvGETMAGIC(name_sv);
+ if (SvOK(name_sv))
+ name = SvPV_nomg(name_sv, len);
else
name = NULL;
- if (SvOK(ST(3)))
- data = SvPV(ST(3), len);
+ SvGETMAGIC(data_sv);
+ if (SvOK(data_sv))
+ data = SvPV(data_sv, len);
else {
data = NULL;
len = 0;
OUTPUT:
RETVAL
-SV *
+SysRet
i_tags_find(im, name, start)
Imager::ImgRaw im
char *name
int entry;
CODE:
if (i_tags_find(&im->tags, name, start, &entry)) {
- if (entry == 0)
- RETVAL = newSVpv("0 but true", 0);
- else
- RETVAL = newSViv(entry);
+ RETVAL = entry;
} else {
- RETVAL = &PL_sv_undef;
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
-SV *
+SysRet
i_tags_findn(im, code, start)
Imager::ImgRaw im
int code
int entry;
CODE:
if (i_tags_findn(&im->tags, code, start, &entry)) {
- if (entry == 0)
- RETVAL = newSVpv("0 but true", 0);
- else
- RETVAL = newSViv(entry);
+ RETVAL = entry;
}
else {
- RETVAL = &PL_sv_undef;
+ XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int combine
Imager::FillHandle
-i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
Imager::Color fg
Imager::Color bg
int combine
int hatch
+ SV *cust_hatch_sv
i_img_dim dx
i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
CODE:
- if (SvOK(ST(4))) {
- cust_hatch = (unsigned char *)SvPV(ST(4), len);
+ SvGETMAGIC(cust_hatch_sv);
+ if (SvOK(cust_hatch_sv)) {
+ cust_hatch = (unsigned char *)SvPV_nomg(cust_hatch_sv, len);
}
else
cust_hatch = NULL;
RETVAL
Imager::FillHandle
-i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
Imager::Color::Float fg
Imager::Color::Float bg
int combine
int hatch
+ SV *cust_hatch_sv
i_img_dim dx
i_img_dim dy
PREINIT:
unsigned char *cust_hatch;
STRLEN len;
CODE:
- if (SvOK(ST(4))) {
- cust_hatch = (unsigned char *)SvPV(ST(4), len);
+ SvGETMAGIC(cust_hatch_sv);
+ if (SvOK(cust_hatch_sv)) {
+ cust_hatch = (unsigned char *)SvPV(cust_hatch_sv, len);
}
else
cust_hatch = NULL;
RETVAL
Imager::FillHandle
-i_new_fill_image(src, matrix, xoff, yoff, combine)
+i_new_fill_image(src, matrix_sv, xoff, yoff, combine)
Imager::ImgRaw src
+ SV *matrix_sv
i_img_dim xoff
i_img_dim yoff
int combine
SV *sv1;
int i;
CODE:
- if (!SvOK(ST(1))) {
+ SvGETMAGIC(matrix_sv);
+ if (!SvOK(matrix_sv)) {
matrixp = NULL;
}
else {
- if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
- croak("i_new_fill_image: parameter must be an arrayref");
- av=(AV*)SvRV(ST(1));
+ if (!SvROK(matrix_sv) || SvTYPE(SvRV(matrix_sv)) != SVt_PVAV)
+ croak("i_new_fill_image: matrix parameter must be an arrayref or undef");
+ av=(AV*)SvRV(matrix_sv);
len=av_len(av)+1;
if (len > 9)
len = 9;