X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/eee347a18c9da0881485544779e91bcdf119e942..6a160bce857f1d340fa20c1d4a67d242b5e098f1:/Imager.xs diff --git a/Imager.xs b/Imager.xs index c47884ec..2b757fed 100644 --- a/Imager.xs +++ b/Imager.xs @@ -21,6 +21,7 @@ extern "C" { #include "regmach.h" #include "imextdef.h" #include "imextpltypes.h" +#include "imperlio.h" #include #if i_int_hlines_testing() @@ -29,6 +30,10 @@ extern "C" { #include "imperl.h" +#ifndef SV_COW_DROP_PV +#define SV_COW_DROP_PV +#endif + /* Context object management @@ -121,6 +126,36 @@ malloc_temp(pTHX_ size_t size) { return SvPVX(sv); } +static void * +calloc_temp(pTHX_ size_t size) { + void *result = malloc_temp(aTHX_ size); + memset(result, 0, size); + + return result; +} + +/* for use with the T_AVARRAY typemap */ +#define doublePtr(size) ((double *)calloc_temp(aTHX_ sizeof(double) * (size))) +#define SvDouble(sv, pname) (SvNV(sv)) + +#define intPtr(size) ((int *)calloc_temp(aTHX_ sizeof(int) * (size))) +#define SvInt(sv, pname) (SvIV(sv)) + +#define i_img_dimPtr(size) ((i_img_dim *)calloc_temp(aTHX_ sizeof(i_img_dim) * (size))) +#define SvI_img_dim(sv, pname) (SvIV(sv)) + +#define i_colorPtr(size) ((i_color *)calloc_temp(aTHX_ sizeof(i_color *) * (size))) + +#define SvI_color(sv, pname) S_sv_to_i_color(aTHX_ sv, pname) + +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", pname); + } + return *INT2PTR(i_color *, SvIV((SV *)SvRV(sv))); +} + /* These functions are all shared - then comes platform dependant code */ static int getstr(void *hv_t,char *key,char **store) { dTHX; @@ -203,9 +238,9 @@ static int getobj(void *hv_t,char *key,char *type,void **store) { 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); } @@ -380,7 +415,6 @@ static int io_closer(void *p) { if (SvOK(cbd->closecb)) { dSP; I32 count; - SV *sv; ENTER; SAVETMPS; @@ -391,8 +425,12 @@ static int io_closer(void *p) { SPAGAIN; - sv = POPs; - success = SvTRUE(sv); + if (count) { + SV *sv = POPs; + success = SvTRUE(sv); + } + else + success = 0; PUTBACK; FREETMPS; @@ -413,14 +451,41 @@ static void io_destroyer(void *p) { myfree(cbd); } +static bool +im_SvREFSCALAR(SV *sv) { + svtype type = SvTYPE(sv); + return type == SVt_PV || type == SVt_PVIV || type == SVt_PVNV + || type == SVt_PVMG || type == SVt_IV || type == SVt_NV + || type == SVt_PVLV || type == SVt_REGEXP; +} + static i_io_glue_t * do_io_new_buffer(pTHX_ SV *data_sv) { const char *data; + char *data_copy; STRLEN length; + SV *sv; - data = SvPVbyte(data_sv, length); - SvREFCNT_inc(data_sv); - return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv); + SvGETMAGIC(data_sv); + if (SvROK(data_sv)) { + if (im_SvREFSCALAR(data_sv)) { + sv = SvRV(data_sv); + } + else { + i_push_error(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 const char * @@ -899,6 +964,7 @@ static im_pl_ext_funcs im_perl_funcs = #define IIM_new i_img_8_new #define IIM_DESTROY i_img_destroy +typedef int SysRet; #ifdef IMEXIF_ENABLE #define i_exif_enabled() 1 @@ -953,10 +1019,10 @@ ICL_rgba(cl) Imager::Color cl PPCODE: EXTEND(SP, 4); - PUSHs(sv_2mortal(newSVnv(cl->rgba.r))); - PUSHs(sv_2mortal(newSVnv(cl->rgba.g))); - PUSHs(sv_2mortal(newSVnv(cl->rgba.b))); - PUSHs(sv_2mortal(newSVnv(cl->rgba.a))); + PUSHs(sv_2mortal(newSViv(cl->rgba.r))); + PUSHs(sv_2mortal(newSViv(cl->rgba.g))); + PUSHs(sv_2mortal(newSViv(cl->rgba.b))); + PUSHs(sv_2mortal(newSViv(cl->rgba.a))); Imager::Color i_hsv_to_rgb(c) @@ -1071,7 +1137,10 @@ Imager::IO 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 @@ -1081,7 +1150,6 @@ io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE) SV *readcb; SV *seekcb; SV *closecb; - int maxwrite; CODE: RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb); OUTPUT: @@ -1143,7 +1211,10 @@ Imager::IO 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 @@ -1165,6 +1236,14 @@ io_new_bufchain(class) OUTPUT: RETVAL +Imager::IO +io__new_perlio(class, io) + PerlIO *io + CODE: + RETVAL = im_io_new_perlio(aTHX_ io); + OUTPUT: + RETVAL + SV * io_slurp(class, ig) Imager::IO ig @@ -1189,14 +1268,7 @@ i_io_raw_write(ig, data_sv) void *data; STRLEN size; CODE: -#ifdef SvUTF8 - if (SvUTF8(data_sv)) { - data_sv = sv_2mortal(newSVsv(data_sv)); - /* yes, we want this to croak() if the SV can't be downgraded */ - sv_utf8_downgrade(data_sv, FALSE); - } -#endif - data = SvPV(data_sv, size); + data = SvPVbyte(data_sv, size); RETVAL = i_io_raw_write(ig, data, size); OUTPUT: RETVAL @@ -1212,15 +1284,9 @@ i_io_raw_read(ig, buffer_sv, size) PPCODE: if (size <= 0) croak("size negative in call to i_io_raw_read()"); - /* prevent an undefined value warning if they supplied an - undef buffer. - Orginally conditional on !SvOK(), but this will prevent the - downgrade from croaking */ - sv_setpvn(buffer_sv, "", 0); -#ifdef SvUTF8 - if (SvUTF8(buffer_sv)) - sv_utf8_downgrade(buffer_sv, FALSE); -#endif + if (SvTHINKFIRST(buffer_sv)) + sv_force_normal_flags(buffer_sv, SV_COW_DROP_PV); + SvUPGRADE(buffer_sv, SVt_PV); buffer = SvGROW(buffer_sv, size+1); result = i_io_raw_read(ig, buffer, size); if (result >= 0) { @@ -1343,15 +1409,9 @@ i_io_read(ig, buffer_sv, size) PPCODE: if (size <= 0) croak("size negative in call to i_io_read()"); - /* prevent an undefined value warning if they supplied an - undef buffer. - Orginally conditional on !SvOK(), but this will prevent the - downgrade from croaking */ - sv_setpvn(buffer_sv, "", 0); -#ifdef SvUTF8 - if (SvUTF8(buffer_sv)) - sv_utf8_downgrade(buffer_sv, FALSE); -#endif + if (SvTHINKFIRST(buffer_sv)) + sv_force_normal_flags(buffer_sv, SV_COW_DROP_PV); + SvUPGRADE(buffer_sv, SVt_PV); buffer = SvGROW(buffer_sv, size+1); result = i_io_read(ig, buffer, size); if (result >= 0) { @@ -1421,14 +1481,7 @@ i_io_write(ig, data_sv) void *data; STRLEN size; CODE: -#ifdef SvUTF8 - if (SvUTF8(data_sv)) { - data_sv = sv_2mortal(newSVsv(data_sv)); - /* yes, we want this to croak() if the SV can't be downgraded */ - sv_utf8_downgrade(data_sv, FALSE); - } -#endif - data = SvPV(data_sv, size); + data = SvPVbyte(data_sv, size); RETVAL = i_io_write(ig, data, size); OUTPUT: RETVAL @@ -1713,112 +1766,50 @@ i_arc_out_aa(im,x,y,rad,d1,d2,val) 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 9) - len = 9; - for (i = 0; i < len; ++i) { - sv1=(*(av_fetch(av,i,0))); - matrix[i] = SvNV(sv1); - } - for (; i < 9; ++i) - matrix[i] = 0; - /* extract the bg colors if any */ - /* yes, this is kind of strange */ - for (i = 4; i < items; ++i) { - sv1 = ST(i); - if (sv_derived_from(sv1, "Imager::Color")) { - IV tmp = SvIV((SV*)SvRV(sv1)); - backp = INT2PTR(i_color *, tmp); - } - else if (sv_derived_from(sv1, "Imager::Color::Float")) { - IV tmp = SvIV((SV*)SvRV(sv1)); - fbackp = INT2PTR(i_fcolor *, tmp); - } - } - RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp); - OUTPUT: - RETVAL + i_img_dim xsize + i_img_dim ysize + AV *matrix_av + PREINIT: + double matrix[9]; + STRLEN len; + SV *sv1; + int i; + i_color *backp = NULL; + i_fcolor *fbackp = NULL; + CODE: + len=av_len(matrix_av)+1; + if (len > 9) + len = 9; + for (i = 0; i < len; ++i) { + sv1=(*(av_fetch(matrix_av,i,0))); + matrix[i] = SvNV(sv1); + } + for (; i < 9; ++i) + matrix[i] = 0; + /* extract the bg colors if any */ + /* yes, this is kind of strange */ + for (i = 4; i < items; ++i) { + sv1 = ST(i); + if (sv_derived_from(sv1, "Imager::Color")) { + IV tmp = SvIV((SV*)SvRV(sv1)); + backp = INT2PTR(i_color *, tmp); + } + else if (sv_derived_from(sv1, "Imager::Color::Float")) { + IV tmp = SvIV((SV*)SvRV(sv1)); + fbackp = INT2PTR(i_fcolor *, tmp); + } + } + RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp); + OUTPUT: + RETVAL undef_int i_gaussian(im,stdev) @@ -2122,46 +2110,44 @@ i_convert(src, avmain) RETVAL -void -i_map(im, pmaps) +undef_int +i_map(im, pmaps_av) Imager::ImgRaw im - PREINIT: - unsigned int mask = 0; - AV *avmain; - AV *avsub; - SV **temp; - int len; - int i, j; - unsigned char (*maps)[256]; - CODE: - if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV) - croak("i_map: parameter 2 must be an arrayref\n"); - avmain = (AV*)SvRV(ST(1)); - len = av_len(avmain)+1; - if (im->channels < len) len = im->channels; - - maps = mymalloc( len * sizeof(unsigned char [256]) ); - - for (j=0; j255) val = 255; - maps[j][i] = val; - } - } - } - i_map(im, maps, mask); - myfree(maps); - - + AV *pmaps_av + PREINIT: + unsigned int mask = 0; + AV *avsub; + SV **temp; + int len; + int i, j; + unsigned char (*maps)[256]; + CODE: + len = av_len(pmaps_av)+1; + if (im->channels < len) + len = im->channels; + maps = mymalloc( len * sizeof(unsigned char [256]) ); + for (j=0; j255) val = 255; + maps[j][i] = val; + } + } + } + i_map(im, maps, mask); + myfree(maps); + RETVAL = 1; + OUTPUT: + RETVAL float i_img_diff(im1,im2) @@ -2223,7 +2209,7 @@ MODULE = Imager PACKAGE = Imager undef_int -i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1) +i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1) Imager::Font::TT handle Imager::ImgRaw im i_img_dim xb @@ -2238,11 +2224,11 @@ i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1) char *str; STRLEN len; CODE: + str = SvPV(str_sv, len); #ifdef SvUTF8 if (SvUTF8(str_sv)) utf8 = 1; #endif - str = SvPV(str_sv, len); RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str, len, smooth, utf8, align); OUTPUT: @@ -2250,7 +2236,7 @@ i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1) undef_int -i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1) +i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1) Imager::Font::TT handle Imager::ImgRaw im i_img_dim xb @@ -2265,11 +2251,11 @@ i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1) char *str; STRLEN len; CODE: + str = SvPV(str_sv, len); #ifdef SvUTF8 if (SvUTF8(str_sv)) utf8 = 1; #endif - str = SvPV(str_sv, len); RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len, smooth, utf8, align); OUTPUT: @@ -2277,7 +2263,7 @@ i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1) void -i_tt_bbox(handle,point,str_sv,len_ignored, utf8) +i_tt_bbox(handle,point,str_sv,utf8) Imager::Font::TT handle double point SV* str_sv @@ -2289,11 +2275,11 @@ i_tt_bbox(handle,point,str_sv,len_ignored, utf8) STRLEN len; int i; PPCODE: + str = SvPV(str_sv, len); #ifdef SvUTF8 if (SvUTF8(ST(2))) utf8 = 1; #endif - str = SvPV(str_sv, len); if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) { EXTEND(SP, rc); for (i = 0; i < rc; ++i) { @@ -2313,11 +2299,12 @@ i_tt_has_chars(handle, text_sv, utf8) size_t count; size_t i; PPCODE: + i_clear_error(); + text = SvPV(text_sv, len); #ifdef SvUTF8 if (SvUTF8(text_sv)) utf8 = 1; #endif - text = SvPV(text_sv, len); work = mymalloc(len); count = i_tt_has_chars(handle, text, len, utf8, work); if (GIMME_V == G_ARRAY) { @@ -2360,12 +2347,14 @@ i_tt_glyph_name(handle, text_sv, utf8 = 0) size_t len; size_t outsize; char name[255]; + SSize_t count = 0; PPCODE: + i_clear_error(); + text = SvPV(text_sv, work_len); #ifdef SvUTF8 if (SvUTF8(text_sv)) utf8 = 1; #endif - text = SvPV(text_sv, work_len); len = work_len; while (len) { unsigned long ch; @@ -2373,21 +2362,23 @@ i_tt_glyph_name(handle, text_sv, utf8 = 0) ch = i_utf8_advance(&text, &len); if (ch == ~0UL) { i_push_error(0, "invalid UTF8 character"); - break; + XSRETURN_EMPTY; } } else { ch = *text++; --len; } - EXTEND(SP, 1); + EXTEND(SP, count+1); if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) { - PUSHs(sv_2mortal(newSVpv(name, 0))); + ST(count) = sv_2mortal(newSVpv(name, 0)); } else { - PUSHs(&PL_sv_undef); - } + ST(count) = &PL_sv_undef; + } + ++count; } + XSRETURN(count); #endif @@ -2526,51 +2517,16 @@ i_get_anonymous_color_histo(im, maxc = 0x40000000) void -i_transform(im,opx,opy,parm) +i_transform(im, opx, opy, parm) Imager::ImgRaw im + int *opx + int *opy + double *parm PREINIT: - double* parm; - int *opx; - int *opy; - int opxl; - int opyl; - int parmlen; - AV* av; - SV* sv1; - int i; + STRLEN size_opx, size_opy, size_parm; i_img *result; PPCODE: - if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n"); - if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n"); - if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n"); - if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n"); - if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n"); - if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n"); - av=(AV*)SvRV(ST(1)); - opxl=av_len(av)+1; - opx=mymalloc( opxl*sizeof(int) ); - for(i=0;i 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) @@ -3285,18 +3183,13 @@ undef_neg_int 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 @@ -3325,7 +3218,7 @@ i_gsamp(im, l, r, y, channels) 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); @@ -3340,8 +3233,7 @@ i_gsamp(im, l, r, y, channels) } else { if (GIMME_V != G_ARRAY) { - EXTEND(SP, 1); - PUSHs(&PL_sv_undef); + XSRETURN_UNDEF; } } @@ -3589,8 +3481,7 @@ i_gsampf(im, l, r, y, channels) } else { if (GIMME_V != G_ARRAY) { - EXTEND(SP, 1); - PUSHs(&PL_sv_undef); + XSRETURN_UNDEF; } } @@ -3639,22 +3530,16 @@ i_plinf(im, l, y, ...) 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)); + if (i_gpixf(im, x, y, RETVAL) != 0) { + myfree(RETVAL); + XSRETURN_UNDEF; } OUTPUT: RETVAL @@ -3750,16 +3635,18 @@ i_img_to_drgb(im) 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); @@ -3767,21 +3654,25 @@ i_tags_addn(im, 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; @@ -3790,7 +3681,7 @@ i_tags_add(im, name, code, data, idata) OUTPUT: RETVAL -SV * +SysRet i_tags_find(im, name, start) Imager::ImgRaw im char *name @@ -3799,17 +3690,14 @@ i_tags_find(im, name, start) 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 @@ -3818,13 +3706,10 @@ i_tags_findn(im, code, start) 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 @@ -3938,19 +3823,21 @@ i_new_fill_solidf(cl, combine) 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; @@ -3959,19 +3846,21 @@ i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy) 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; @@ -3980,8 +3869,9 @@ i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy) 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 @@ -3993,13 +3883,14 @@ i_new_fill_image(src, matrix, xoff, yoff, 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;