X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/2086be616008dccc688f2f294d558fc44863ec11..4326b23a38b971802036792fd8af38076f1c3fae:/Imager.xs diff --git a/Imager.xs b/Imager.xs index 22395eb0..d1512c0c 100644 --- a/Imager.xs +++ b/Imager.xs @@ -19,6 +19,7 @@ extern "C" { #include "dynaload.h" #include "regmach.h" #include "imextdef.h" +#include "imextpltypes.h" #if i_int_hlines_testing() #include "imageri.h" @@ -558,9 +559,7 @@ static struct value_name make_color_names[] = static struct value_name translate_names[] = { -#ifdef HAVE_LIBGIF { "giflib", pt_giflib, }, -#endif { "closest", pt_closest, }, { "perturb", pt_perturb, }, { "errdiff", pt_errdiff, }, @@ -590,7 +589,8 @@ static struct value_name orddith_names[] = }; /* look through the hash for quantization options */ -static void handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) +static void +ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) { /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/ SV **sv; @@ -641,7 +641,7 @@ static void handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) } } } - quant->make_colors = mc_addi; + quant->make_colors = mc_median_cut; sv = hv_fetch(hv, "make_colors", 11, 0); if (sv && *sv && (str = SvPV(*sv, len))) { quant->make_colors = @@ -721,14 +721,16 @@ static void handle_quant_opts(pTHX_ i_quantize *quant, HV *hv) quant->perturb = SvIV(*sv); } -static void cleanup_quant_opts(i_quantize *quant) { +static void +ip_cleanup_quant_opts(pTHX_ i_quantize *quant) { myfree(quant->mc_colors); if (quant->ed_map) myfree(quant->ed_map); } /* copies the color map from the hv into the colors member of the HV */ -static void copy_colors_back(pTHX_ HV *hv, i_quantize *quant) { +static void +ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) { SV **sv; AV *av; int i; @@ -928,6 +930,18 @@ i_int_hlines_dump(i_int_hlines *hlines) { #endif +static im_pl_ext_funcs im_perl_funcs = +{ + IMAGER_PL_API_VERSION, + IMAGER_PL_API_LEVEL, + ip_handle_quant_opts, + ip_cleanup_quant_opts, + ip_copy_colors_back +}; + +#define PERL_PL_SET_GLOBAL_CALLBACKS \ + sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs)); + #ifdef IMEXIF_ENABLE #define i_exif_enabled() 1 #else @@ -937,6 +951,9 @@ i_int_hlines_dump(i_int_hlines *hlines) { /* trying to use more C style names, map them here */ #define i_io_DESTROY(ig) io_glue_destroy(ig) +#define i_img_get_width(im) ((im)->xsize) +#define i_img_get_height(im) ((im)->ysize) + MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_ Imager::Color @@ -1370,6 +1387,15 @@ i_img_getdata(im) sv_2mortal(newSVpv((char *)im->idata, im->bytes)) : &PL_sv_undef); +IV +i_img_get_width(im) + Imager::ImgRaw im + +IV +i_img_get_height(im) + Imager::ImgRaw im + + void i_img_is_monochrome(im) Imager::ImgRaw im @@ -1731,6 +1757,47 @@ i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, int combine double opacity +Imager::ImgRaw +i_combine(src_av, channels_av = NULL) + AV *src_av + AV *channels_av + PREINIT: + i_img **imgs = NULL; + STRLEN in_count; + int *channels = NULL; + int i; + SV **psv; + IV tmp; + CODE: + in_count = av_len(src_av) + 1; + if (in_count > 0) { + imgs = mymalloc(sizeof(i_img*) * in_count); + channels = mymalloc(sizeof(int) * in_count); + for (i = 0; i < in_count; ++i) { + psv = av_fetch(src_av, i, 0); + if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) { + myfree(imgs); + myfree(channels); + croak("imgs must contain only images"); + } + tmp = SvIV((SV*)SvRV(*psv)); + imgs[i] = INT2PTR(i_img*, tmp); + if (channels_av && + (psv = av_fetch(channels_av, i, 0)) != NULL && + *psv) { + channels[i] = SvIV(*psv); + } + else { + channels[i] = 0; + } + } + } + RETVAL = i_combine(imgs, channels, in_count); + myfree(imgs); + myfree(channels); + OUTPUT: + RETVAL + undef_int i_flipxy(im, direction) Imager::ImgRaw im @@ -1848,7 +1915,7 @@ i_convert(src, avmain) Imager::ImgRaw src AV *avmain PREINIT: - float *coeff; + double *coeff; int outchan; int inchan; SV **temp; @@ -1868,7 +1935,7 @@ i_convert(src, avmain) inchan = len; } } - coeff = mymalloc(sizeof(float) * outchan * inchan); + coeff = mymalloc(sizeof(double) * outchan * inchan); for (j = 0; j < outchan; ++j) { avsub = (AV*)SvRV(*av_fetch(avmain, j, 0)); len = av_len(avsub)+1; @@ -1943,6 +2010,17 @@ undef_int i_init_fonts(t1log=0) int t1log +bool +_is_color_object(sv) + SV* sv + CODE: + SvGETMAGIC(sv); + RETVAL = SvOK(sv) && SvROK(sv) && + (sv_derived_from(sv, "Imager::Color") + || sv_derived_from(sv, "Imager::Color::Float")); + OUTPUT: + RETVAL + #ifdef HAVE_LIBT1 void @@ -2092,7 +2170,7 @@ i_t1_glyph_name(handle, text_sv, utf8 = 0) PREINIT: char const *text; STRLEN work_len; - int len; + size_t len; char name[255]; PPCODE: #ifdef SvUTF8 @@ -2286,7 +2364,7 @@ i_tt_glyph_name(handle, text_sv, utf8 = 0) PREINIT: char const *text; STRLEN work_len; - int len; + size_t len; int outsize; char name[255]; PPCODE: @@ -2320,71 +2398,27 @@ i_tt_glyph_name(handle, text_sv, utf8 = 0) #endif - -#ifdef HAVE_LIBJPEG -undef_int -i_writejpeg_wiol(im, ig, qfactor) - Imager::ImgRaw im - Imager::IO ig - int qfactor - - -void -i_readjpeg_wiol(ig) - Imager::IO ig - PREINIT: - char* iptc_itext; - int tlength; - i_img* rimg; - SV* r; - PPCODE: - iptc_itext = NULL; - rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength); - if (iptc_itext == NULL) { - r = sv_newmortal(); - EXTEND(SP,1); - sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg); - PUSHs(r); - } else { - r = sv_newmortal(); - EXTEND(SP,2); - sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg); - PUSHs(r); - PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength))); - myfree(iptc_itext); - } - -int -i_exif_enabled() - -#endif - - const char * i_test_format_probe(ig, length) Imager::IO ig int length - - -#ifdef HAVE_LIBTIFF - Imager::ImgRaw -i_readtiff_wiol(ig, allow_incomplete, page=0) +i_readpnm_wiol(ig, allow_incomplete) Imager::IO ig int allow_incomplete - int page + void -i_readtiff_multi_wiol(ig, length) - Imager::IO ig - int length +i_readpnm_multi_wiol(ig, allow_incomplete) + Imager::IO ig + int allow_incomplete PREINIT: i_img **imgs; - int count; + int count=0; int i; PPCODE: - imgs = i_readtiff_multi_wiol(ig, length, &count); + imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete); if (imgs) { EXTEND(SP, count); for (i = 0; i < count; ++i) { @@ -2395,750 +2429,107 @@ i_readtiff_multi_wiol(ig, length) myfree(imgs); } - undef_int -i_writetiff_wiol(im, ig) +i_writeppm_wiol(im, ig) Imager::ImgRaw im Imager::IO ig -undef_int -i_writetiff_multi_wiol(ig, ...) + + + + +Imager::ImgRaw +i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl) Imager::IO ig - PREINIT: - int i; - int img_count; - i_img **imgs; - CODE: - if (items < 2) - croak("Usage: i_writetiff_multi_wiol(ig, images...)"); - img_count = items - 1; - RETVAL = 1; - if (img_count < 1) { - RETVAL = 0; - i_clear_error(); - i_push_error(0, "You need to specify images to save"); - } - else { - imgs = mymalloc(sizeof(i_img *) * img_count); - for (i = 0; i < img_count; ++i) { - SV *sv = ST(1+i); - imgs[i] = NULL; - if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) { - imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv))); - } - else { - i_clear_error(); - i_push_error(0, "Only images can be saved"); - myfree(imgs); - RETVAL = 0; - break; - } - } - if (RETVAL) { - RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count); - } - myfree(imgs); - } - OUTPUT: - RETVAL + int x + int y + int datachannels + int storechannels + int intrl undef_int -i_writetiff_wiol_faxable(im, ig, fine) +i_writeraw_wiol(im,ig) Imager::ImgRaw im Imager::IO ig - int fine undef_int -i_writetiff_multi_wiol_faxable(ig, fine, ...) +i_writebmp_wiol(im,ig) + Imager::ImgRaw im Imager::IO ig - int fine - PREINIT: - int i; - int img_count; - i_img **imgs; - CODE: - if (items < 3) - croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)"); - img_count = items - 2; - RETVAL = 1; - if (img_count < 1) { - RETVAL = 0; - i_clear_error(); - i_push_error(0, "You need to specify images to save"); - } - else { - imgs = mymalloc(sizeof(i_img *) * img_count); - for (i = 0; i < img_count; ++i) { - SV *sv = ST(2+i); - imgs[i] = NULL; - if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) { - imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv))); - } - else { - i_clear_error(); - i_push_error(0, "Only images can be saved"); - myfree(imgs); - RETVAL = 0; - break; - } - } - if (RETVAL) { - RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine); - } - myfree(imgs); - } - OUTPUT: - RETVAL - -const char * -i_tiff_libversion() - -bool -i_tiff_has_compression(name) - const char *name - -#endif /* HAVE_LIBTIFF */ - - -#ifdef HAVE_LIBPNG Imager::ImgRaw -i_readpng_wiol(ig, length) +i_readbmp_wiol(ig, allow_incomplete=0) Imager::IO ig - int length + int allow_incomplete undef_int -i_writepng_wiol(im, ig) +i_writetga_wiol(im,ig, wierdpack, compress, idstring) Imager::ImgRaw im Imager::IO ig + int wierdpack + int compress + char* idstring + PREINIT: + int idlen; + CODE: + idlen = SvCUR(ST(4)); + RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen); + OUTPUT: + RETVAL -#endif +Imager::ImgRaw +i_readtga_wiol(ig, length) + Imager::IO ig + int length -#ifdef HAVE_LIBGIF -void -i_giflib_version() - PPCODE: - PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1))); -undef_int -i_writegif(im,fd,colors,pixdev,fixed) +Imager::ImgRaw +i_scaleaxis(im,Value,Axis) Imager::ImgRaw im - int fd - int colors - int pixdev - PREINIT: - int fixedlen; - Imager__Color fixed; - Imager__Color tmp; - AV* av; - SV* sv1; - IV Itmp; - int i; - CODE: - if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n"); - if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n"); - av=(AV*)SvRV(ST(4)); - fixedlen=av_len(av)+1; - fixed=mymalloc( fixedlen*sizeof(i_color) ); - for(i=0;i 6) - len = 6; - for (i = 0; i < len; ++i) { - sv1=(*(av_fetch(av,i,0))); - matrix[i] = SvNV(sv1); - } - for (; i < 6; ++i) - matrix[i] = 0; - RETVAL = i_ft2_settransform(font, matrix); - OUTPUT: - RETVAL - -void -i_ft2_bbox(font, cheight, cwidth, text_sv, utf8) - Imager::Font::FT2 font - double cheight - double cwidth - SV *text_sv - int utf8 - PREINIT: - int bbox[BOUNDING_BOX_COUNT]; - int i; - char *text; - STRLEN text_len; - int rc; - PPCODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8); - if (rc) { - EXTEND(SP, rc); - for (i = 0; i < rc; ++i) - PUSHs(sv_2mortal(newSViv(bbox[i]))); - } - -void -i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8) - Imager::Font::FT2 font - double cheight - double cwidth - char *text - int vlayout - int utf8 - PREINIT: - int bbox[8]; - int i; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(ST(3))) - utf8 = 1; -#endif - if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout, - utf8, bbox)) { - EXTEND(SP, 8); - for (i = 0; i < 8; ++i) - PUSHs(sv_2mortal(newSViv(bbox[i]))); - } - -undef_int -i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8) - Imager::Font::FT2 font - Imager::ImgRaw im - int tx - int ty - Imager::Color cl - double cheight - double cwidth - int align - int aa - int vlayout - int utf8 - PREINIT: - char *text; - STRLEN len; - CODE: -#ifdef SvUTF8 - if (SvUTF8(ST(7))) { - utf8 = 1; - } -#endif - text = SvPV(ST(7), len); - RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, - len, align, aa, vlayout, utf8); - OUTPUT: - RETVAL - -undef_int -i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8) - Imager::Font::FT2 font - Imager::ImgRaw im - int tx - int ty - int channel - double cheight - double cwidth - SV *text_sv - int align - int aa - int vlayout - int utf8 - PREINIT: - char const *text; - STRLEN len; - CODE: -#ifdef SvUTF8 - if (SvUTF8(ST(7))) - utf8 = 1; -#endif - text = SvPV(text_sv, len); - RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, - len, align, aa, vlayout, 1); - OUTPUT: - RETVAL - -void -ft2_transform_box(font, x0, x1, x2, x3) - Imager::Font::FT2 font - int x0 - int x1 - int x2 - int x3 - PREINIT: - int box[4]; - PPCODE: - box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3; - ft2_transform_box(font, box); - EXTEND(SP, 4); - PUSHs(sv_2mortal(newSViv(box[0]))); - PUSHs(sv_2mortal(newSViv(box[1]))); - PUSHs(sv_2mortal(newSViv(box[2]))); - PUSHs(sv_2mortal(newSViv(box[3]))); - -void -i_ft2_has_chars(handle, text_sv, utf8) - Imager::Font::FT2 handle - SV *text_sv - int utf8 - PREINIT: - char *text; - STRLEN len; - char *work; - int count; - int i; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - text = SvPV(text_sv, len); - work = mymalloc(len); - count = i_ft2_has_chars(handle, text, len, utf8, work); - if (GIMME_V == G_ARRAY) { - EXTEND(SP, count); - for (i = 0; i < count; ++i) { - PUSHs(sv_2mortal(newSViv(work[i]))); - } - } - else { - EXTEND(SP, 1); - PUSHs(sv_2mortal(newSVpv(work, count))); - } - myfree(work); - -void -i_ft2_face_name(handle) - Imager::Font::FT2 handle - PREINIT: - char name[255]; - int len; - PPCODE: - len = i_ft2_face_name(handle, name, sizeof(name)); - if (len) { - EXTEND(SP, 1); - PUSHs(sv_2mortal(newSVpv(name, 0))); - } - -undef_int -i_ft2_can_face_name() - -void -i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1) - Imager::Font::FT2 handle - SV *text_sv - int utf8 - int reliable_only - PREINIT: - char const *text; - STRLEN work_len; - int len; - char name[255]; - PPCODE: -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - text = SvPV(text_sv, work_len); - len = work_len; - while (len) { - unsigned long ch; - if (utf8) { - ch = i_utf8_advance(&text, &len); - if (ch == ~0UL) { - i_push_error(0, "invalid UTF8 character"); - break; - } - } - else { - ch = *text++; - --len; - } - EXTEND(SP, 1); - if (i_ft2_glyph_name(handle, ch, name, sizeof(name), - reliable_only)) { - PUSHs(sv_2mortal(newSVpv(name, 0))); - } - else { - PUSHs(&PL_sv_undef); - } - } - -int -i_ft2_can_do_glyph_names() - -int -i_ft2_face_has_glyph_names(handle) - Imager::Font::FT2 handle - -int -i_ft2_is_multiple_master(handle) - Imager::Font::FT2 handle - -void -i_ft2_get_multiple_masters(handle) - Imager::Font::FT2 handle - PREINIT: - i_font_mm mm; - int i; - PPCODE: - if (i_ft2_get_multiple_masters(handle, &mm)) { - EXTEND(SP, 2+mm.num_axis); - PUSHs(sv_2mortal(newSViv(mm.num_axis))); - PUSHs(sv_2mortal(newSViv(mm.num_designs))); - for (i = 0; i < mm.num_axis; ++i) { - AV *av = newAV(); - SV *sv; - av_extend(av, 3); - sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name)); - SvREFCNT_inc(sv); - av_store(av, 0, sv); - sv = newSViv(mm.axis[i].minimum); - SvREFCNT_inc(sv); - av_store(av, 1, sv); - sv = newSViv(mm.axis[i].maximum); - SvREFCNT_inc(sv); - av_store(av, 2, sv); - PUSHs(newRV_noinc((SV *)av)); - } - } - -undef_int -i_ft2_set_mm_coords(handle, ...) - Imager::Font::FT2 handle - PROTOTYPE: DISABLE - PREINIT: - long *coords; - int ix_coords, i; - CODE: - /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so - transfer the array manually */ - ix_coords = items-1; - coords = mymalloc(sizeof(long) * ix_coords); - for (i = 0; i < ix_coords; ++i) { - coords[i] = (long)SvIV(ST(1+i)); - } - RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords); - myfree(coords); - OUTPUT: - RETVAL - -#endif MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_ @@ -5031,3 +3997,4 @@ i_int_hlines_CLONE_SKIP(cls) BOOT: PERL_SET_GLOBAL_CALLBACKS; + PERL_PL_SET_GLOBAL_CALLBACKS; \ No newline at end of file