X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/ec6d89084477350e1b224644166f4bd337f67055..4326b23a38b971802036792fd8af38076f1c3fae:/Imager.xs diff --git a/Imager.xs b/Imager.xs index 821b1a1f..d1512c0c 100644 --- a/Imager.xs +++ b/Imager.xs @@ -559,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, }, @@ -643,7 +641,7 @@ ip_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 = @@ -953,6 +951,9 @@ static im_pl_ext_funcs im_perl_funcs = /* 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 @@ -1386,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 @@ -1747,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 @@ -1864,7 +1915,7 @@ i_convert(src, avmain) Imager::ImgRaw src AV *avmain PREINIT: - float *coeff; + double *coeff; int outchan; int inchan; SV **temp; @@ -1884,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; @@ -1959,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 @@ -2108,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 @@ -2302,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: @@ -2336,193 +2398,11 @@ 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) - Imager::IO ig - int allow_incomplete - int page - -void -i_readtiff_multi_wiol(ig, length) - Imager::IO ig - int length - PREINIT: - i_img **imgs; - int count; - int i; - PPCODE: - imgs = i_readtiff_multi_wiol(ig, length, &count); - if (imgs) { - EXTEND(SP, count); - for (i = 0; i < count; ++i) { - SV *sv = sv_newmortal(); - sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]); - PUSHs(sv); - } - myfree(imgs); - } - - -undef_int -i_writetiff_wiol(im, ig) - Imager::ImgRaw im - Imager::IO ig - -undef_int -i_writetiff_multi_wiol(ig, ...) - 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 - -undef_int -i_writetiff_wiol_faxable(im, ig, fine) - Imager::ImgRaw im - Imager::IO ig - int fine - -undef_int -i_writetiff_multi_wiol_faxable(ig, fine, ...) - 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 - -#endif - - - - Imager::ImgRaw i_readpnm_wiol(ig, allow_incomplete) Imager::IO ig @@ -3969,437 +3849,7 @@ i_tags_count(im) OUTPUT: RETVAL -#ifdef HAVE_WIN32 - -void -i_wf_bbox(face, size, text_sv, utf8=0) - char *face - int size - SV *text_sv - int utf8 - PREINIT: - int cords[BOUNDING_BOX_COUNT]; - int rc, i; - char const *text; - STRLEN text_len; - PPCODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) { - EXTEND(SP, rc); - for (i = 0; i < rc; ++i) - PUSHs(sv_2mortal(newSViv(cords[i]))); - } - -undef_int -i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0) - char *face - Imager::ImgRaw im - int tx - int ty - Imager::Color cl - int size - SV *text_sv - int align - int aa - int utf8 - PREINIT: - char const *text; - STRLEN text_len; - CODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len, - align, aa, utf8); - OUTPUT: - RETVAL - -undef_int -i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0) - char *face - Imager::ImgRaw im - int tx - int ty - int channel - int size - SV *text_sv - int align - int aa - int utf8 - PREINIT: - char const *text; - STRLEN text_len; - CODE: - text = SvPV(text_sv, text_len); -#ifdef SvUTF8 - if (SvUTF8(text_sv)) - utf8 = 1; -#endif - RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len, - align, aa, utf8); - OUTPUT: - RETVAL - -undef_int -i_wf_addfont(font) - char *font - -undef_int -i_wf_delfont(font) - char *font - -#endif - -#ifdef HAVE_FT2 - -MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_ - -#define FT2_DESTROY(font) i_ft2_destroy(font) - -void -FT2_DESTROY(font) - Imager::Font::FT2 font - -int -FT2_CLONE_SKIP(...) - CODE: - RETVAL = 1; - OUTPUT: - RETVAL -MODULE = Imager PACKAGE = Imager::Font::FreeType2 - -Imager::Font::FT2 -i_ft2_new(name, index) - char *name - int index - -undef_int -i_ft2_setdpi(font, xdpi, ydpi) - Imager::Font::FT2 font - int xdpi - int ydpi - -void -i_ft2_getdpi(font) - Imager::Font::FT2 font - PREINIT: - int xdpi, ydpi; - CODE: - if (i_ft2_getdpi(font, &xdpi, &ydpi)) { - EXTEND(SP, 2); - PUSHs(sv_2mortal(newSViv(xdpi))); - PUSHs(sv_2mortal(newSViv(ydpi))); - } - -undef_int -i_ft2_sethinting(font, hinting) - Imager::Font::FT2 font - int hinting - -undef_int -i_ft2_settransform(font, matrix) - Imager::Font::FT2 font - PREINIT: - double matrix[6]; - int len; - AV *av; - SV *sv1; - int i; - CODE: - if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV) - croak("i_ft2_settransform: parameter 2 must be an array ref\n"); - av=(AV*)SvRV(ST(1)); - len=av_len(av)+1; - if (len > 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_