1 #define PERL_NO_GET_CONTEXT
8 #define NEED_newRV_noinc
9 #define NEED_sv_2pv_nolen
15 #define i_int_hlines_testing() 1
22 #include "imextpltypes.h"
25 #if i_int_hlines_testing()
31 /* These functions are all shared - then comes platform dependant code */
32 static int getstr(void *hv_t,char *key,char **store) {
37 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
39 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
41 svpp=hv_fetch(hv, key, strlen(key), 0);
42 *store=SvPV(*svpp, PL_na );
47 static int getint(void *hv_t,char *key,int *store) {
52 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
54 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
56 svpp=hv_fetch(hv, key, strlen(key), 0);
57 *store=(int)SvIV(*svpp);
61 static int getdouble(void *hv_t,char* key,double *store) {
66 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
68 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
69 svpp=hv_fetch(hv, key, strlen(key), 0);
70 *store=(float)SvNV(*svpp);
74 static int getvoid(void *hv_t,char* key,void **store) {
79 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
81 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
83 svpp=hv_fetch(hv, key, strlen(key), 0);
84 *store = INT2PTR(void*, SvIV(*svpp));
89 static int getobj(void *hv_t,char *key,char *type,void **store) {
94 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
96 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
98 svpp=hv_fetch(hv, key, strlen(key), 0);
100 if (sv_derived_from(*svpp,type)) {
101 IV tmp = SvIV((SV*)SvRV(*svpp));
102 *store = INT2PTR(void*, tmp);
104 mm_log((1,"getobj: key exists in hash but is not of correct type"));
111 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
113 void my_SvREFCNT_dec(void *p) {
115 SvREFCNT_dec((SV*)p);
120 i_log_entry(char *string, int level) {
121 mm_log((level, string));
125 typedef struct i_reader_data_tag
127 /* presumably a CODE ref or name of a sub */
131 /* used by functions that want callbacks */
132 static int read_callback(char *userdata, char *buffer, int need, int want) {
134 i_reader_data *rd = (i_reader_data *)userdata;
138 dSP; dTARG = sv_newmortal();
139 /* thanks to Simon Cozens for help with the dTARG above */
149 count = perl_call_sv(rd->sv, G_SCALAR);
154 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
160 char *ptr = SvPV(data, len);
162 croak("Too much data returned in reader callback");
164 memcpy(buffer, ptr, len);
180 SV *sv; /* a coderef or sub name */
183 /* used by functions that want callbacks */
184 static int write_callback(char *userdata, char const *data, int size) {
186 i_writer_data *wd = (i_writer_data *)userdata;
196 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
199 count = perl_call_sv(wd->sv, G_SCALAR);
204 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
207 success = SvTRUE(sv);
217 #define CBDATA_BUFSIZE 8192
220 /* the SVs we use to call back to Perl */
226 /* we need to remember whether the buffer contains write data or
232 /* how far we've read into the buffer (not used for writing) */
235 /* the amount of space used/data available in the buffer */
238 /* the maximum amount to fill the buffer before flushing
239 If any write is larger than this then the buffer is flushed and
240 the full write is performed. The write is _not_ split into
245 char buffer[CBDATA_BUFSIZE];
250 call_writer(cbd, buf, size)
252 Low-level function to call the perl writer callback.
256 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
263 if (!SvOK(cbd->writecb))
270 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
273 count = perl_call_sv(cbd->writecb, G_SCALAR);
277 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
280 success = SvTRUE(sv);
287 return success ? size : -1;
290 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
298 if (!SvOK(cbd->readcb))
305 PUSHs(sv_2mortal(newSViv(size)));
306 PUSHs(sv_2mortal(newSViv(maxread)));
309 count = perl_call_sv(cbd->readcb, G_SCALAR);
314 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
320 char *ptr = SvPV(data, len);
322 croak("Too much data returned in reader callback");
324 memcpy(buf, ptr, len);
338 static ssize_t write_flush(struct cbdata *cbd) {
343 result = call_writer(cbd, cbd->buffer, cbd->used);
348 return 1; /* success of some sort */
352 static off_t io_seeker(void *p, off_t offset, int whence) {
354 struct cbdata *cbd = p;
359 if (!SvOK(cbd->seekcb))
363 if (cbd->used && write_flush(cbd) <= 0)
367 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
368 offset -= cbd->where - cbd->used;
371 cbd->where = cbd->used = 0;
377 PUSHs(sv_2mortal(newSViv(offset)));
378 PUSHs(sv_2mortal(newSViv(whence)));
381 count = perl_call_sv(cbd->seekcb, G_SCALAR);
386 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
397 static ssize_t io_writer(void *p, void const *data, size_t size) {
399 struct cbdata *cbd = p;
401 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
403 if (cbd->reading && cbd->where < cbd->used) {
404 /* we read past the place where the caller expected us to be
405 so adjust our position a bit */
406 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
411 cbd->where = cbd->used = 0;
414 if (cbd->used && cbd->used + size > cbd->maxlength) {
415 int write_res = write_flush(cbd);
416 if (write_res <= 0) {
421 if (cbd->used+size <= cbd->maxlength) {
422 memcpy(cbd->buffer + cbd->used, data, size);
426 /* it doesn't fit - just pass it up */
427 return call_writer(cbd, data, size);
431 io_reader(void *p, void *data, size_t size) {
433 struct cbdata *cbd = p;
435 char *out = data; /* so we can do pointer arithmetic */
437 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
439 if (write_flush(cbd) <= 0)
445 if (size <= cbd->used - cbd->where) {
447 memcpy(data, cbd->buffer+cbd->where, size);
452 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
453 total += cbd->used - cbd->where;
454 size -= cbd->used - cbd->where;
455 out += cbd->used - cbd->where;
456 if (size < sizeof(cbd->buffer)) {
460 && (did_read = call_reader(cbd, cbd->buffer, size,
461 sizeof(cbd->buffer))) > 0) {
463 cbd->used = did_read;
465 copy_size = i_min(size, cbd->used);
466 memcpy(out, cbd->buffer, copy_size);
467 cbd->where += copy_size;
476 /* just read the rest - too big for our buffer*/
478 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
490 static int io_closer(void *p) {
492 struct cbdata *cbd = p;
494 if (cbd->writing && cbd->used > 0) {
495 if (write_flush(cbd) < 0)
500 if (SvOK(cbd->closecb)) {
508 perl_call_sv(cbd->closecb, G_VOID);
519 static void io_destroyer(void *p) {
521 struct cbdata *cbd = p;
523 SvREFCNT_dec(cbd->writecb);
524 SvREFCNT_dec(cbd->readcb);
525 SvREFCNT_dec(cbd->seekcb);
526 SvREFCNT_dec(cbd->closecb);
534 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
537 for (i = 0; i < count; ++i)
538 if (strEQ(names[i].name, name))
539 return names[i].value;
543 static struct value_name transp_names[] =
546 { "threshold", tr_threshold },
547 { "errdiff", tr_errdiff },
548 { "ordered", tr_ordered, },
551 static struct value_name make_color_names[] =
553 { "none", mc_none, },
554 { "webmap", mc_web_map, },
555 { "addi", mc_addi, },
556 { "mediancut", mc_median_cut, },
557 { "mono", mc_mono, },
558 { "monochrome", mc_mono, },
561 static struct value_name translate_names[] =
563 { "giflib", pt_giflib, },
564 { "closest", pt_closest, },
565 { "perturb", pt_perturb, },
566 { "errdiff", pt_errdiff, },
569 static struct value_name errdiff_names[] =
571 { "floyd", ed_floyd, },
572 { "jarvis", ed_jarvis, },
573 { "stucki", ed_stucki, },
574 { "custom", ed_custom, },
577 static struct value_name orddith_names[] =
579 { "random", od_random, },
580 { "dot8", od_dot8, },
581 { "dot4", od_dot4, },
582 { "hline", od_hline, },
583 { "vline", od_vline, },
584 { "/line", od_slashline, },
585 { "slashline", od_slashline, },
586 { "\\line", od_backline, },
587 { "backline", od_backline, },
588 { "tiny", od_tiny, },
589 { "custom", od_custom, },
592 /* look through the hash for quantization options */
594 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
596 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
602 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
604 sv = hv_fetch(hv, "transp", 6, 0);
605 if (sv && *sv && (str = SvPV(*sv, len))) {
607 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
609 if (quant->transp != tr_none) {
610 quant->tr_threshold = 127;
611 sv = hv_fetch(hv, "tr_threshold", 12, 0);
613 quant->tr_threshold = SvIV(*sv);
615 if (quant->transp == tr_errdiff) {
616 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
617 if (sv && *sv && (str = SvPV(*sv, len)))
618 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
620 if (quant->transp == tr_ordered) {
621 quant->tr_orddith = od_tiny;
622 sv = hv_fetch(hv, "tr_orddith", 10, 0);
623 if (sv && *sv && (str = SvPV(*sv, len)))
624 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
626 if (quant->tr_orddith == od_custom) {
627 sv = hv_fetch(hv, "tr_map", 6, 0);
628 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
629 AV *av = (AV*)SvRV(*sv);
630 len = av_len(av) + 1;
631 if (len > sizeof(quant->tr_custom))
632 len = sizeof(quant->tr_custom);
633 for (i = 0; i < len; ++i) {
634 SV **sv2 = av_fetch(av, i, 0);
636 quant->tr_custom[i] = SvIV(*sv2);
639 while (i < sizeof(quant->tr_custom))
640 quant->tr_custom[i++] = 0;
645 quant->make_colors = mc_median_cut;
646 sv = hv_fetch(hv, "make_colors", 11, 0);
647 if (sv && *sv && (str = SvPV(*sv, len))) {
649 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
651 sv = hv_fetch(hv, "colors", 6, 0);
652 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
653 /* needs to be an array of Imager::Color
654 note that the caller allocates the mc_color array and sets mc_size
656 AV *av = (AV *)SvRV(*sv);
657 quant->mc_count = av_len(av)+1;
658 if (quant->mc_count > quant->mc_size)
659 quant->mc_count = quant->mc_size;
660 for (i = 0; i < quant->mc_count; ++i) {
661 SV **sv1 = av_fetch(av, i, 0);
662 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
663 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
664 quant->mc_colors[i] = *col;
668 sv = hv_fetch(hv, "max_colors", 10, 0);
671 if (i <= quant->mc_size && i >= quant->mc_count)
675 quant->translate = pt_closest;
676 sv = hv_fetch(hv, "translate", 9, 0);
677 if (sv && *sv && (str = SvPV(*sv, len))) {
678 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
680 sv = hv_fetch(hv, "errdiff", 7, 0);
681 if (sv && *sv && (str = SvPV(*sv, len))) {
682 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
684 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
685 /* get the error diffusion map */
686 sv = hv_fetch(hv, "errdiff_width", 13, 0);
688 quant->ed_width = SvIV(*sv);
689 sv = hv_fetch(hv, "errdiff_height", 14, 0);
691 quant->ed_height = SvIV(*sv);
692 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
694 quant->ed_orig = SvIV(*sv);
695 if (quant->ed_width > 0 && quant->ed_height > 0) {
697 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
698 sv = hv_fetch(hv, "errdiff_map", 11, 0);
699 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
700 AV *av = (AV*)SvRV(*sv);
701 len = av_len(av) + 1;
702 if (len > quant->ed_width * quant->ed_height)
703 len = quant->ed_width * quant->ed_height;
704 for (i = 0; i < len; ++i) {
705 SV **sv2 = av_fetch(av, i, 0);
707 quant->ed_map[i] = SvIV(*sv2);
708 sum += quant->ed_map[i];
714 myfree(quant->ed_map);
716 quant->errdiff = ed_floyd;
720 sv = hv_fetch(hv, "perturb", 7, 0);
722 quant->perturb = SvIV(*sv);
726 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
727 myfree(quant->mc_colors);
729 myfree(quant->ed_map);
732 /* copies the color map from the hv into the colors member of the HV */
734 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
740 sv = hv_fetch(hv, "colors", 6, 0);
741 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
746 av = (AV *)SvRV(*sv);
748 av_extend(av, quant->mc_count+1);
749 for (i = 0; i < quant->mc_count; ++i) {
750 i_color *in = quant->mc_colors+i;
751 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
752 work = sv_newmortal();
753 sv_setref_pv(work, "Imager::Color", (void *)c);
759 /* loads the segments of a fountain fill into an array */
760 static i_fountain_seg *
761 load_fount_segs(pTHX_ AV *asegs, int *count) {
762 /* Each element of segs must contain:
763 [ start, middle, end, c0, c1, segtype, colortrans ]
764 start, middle, end are doubles from 0 to 1
765 c0, c1 are Imager::Color::Float or Imager::Color objects
766 segtype, colortrans are ints
770 i_fountain_seg *segs;
774 *count = av_len(asegs)+1;
776 croak("i_fountain must have at least one segment");
777 segs = mymalloc(sizeof(i_fountain_seg) * *count);
778 for(i = 0; i < *count; i++) {
779 SV **sv1 = av_fetch(asegs, i, 0);
780 if (!sv1 || !*sv1 || !SvROK(*sv1)
781 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
783 croak("i_fountain: segs must be an arrayref of arrayrefs");
785 aseg = (AV *)SvRV(*sv1);
786 if (av_len(aseg) != 7-1) {
788 croak("i_fountain: a segment must have 7 members");
790 for (j = 0; j < 3; ++j) {
791 SV **sv2 = av_fetch(aseg, j, 0);
794 croak("i_fountain: XS error");
796 work[j] = SvNV(*sv2);
798 segs[i].start = work[0];
799 segs[i].middle = work[1];
800 segs[i].end = work[2];
801 for (j = 0; j < 2; ++j) {
802 SV **sv3 = av_fetch(aseg, 3+j, 0);
803 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
804 (!sv_derived_from(*sv3, "Imager::Color")
805 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
807 croak("i_fountain: segs must contain colors in elements 3 and 4");
809 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
810 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
813 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
815 for (ch = 0; ch < MAXCHANNELS; ++ch) {
816 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
820 for (j = 0; j < 2; ++j) {
821 SV **sv2 = av_fetch(aseg, j+5, 0);
824 croak("i_fountain: XS error");
826 worki[j] = SvIV(*sv2);
828 segs[i].type = worki[0];
829 segs[i].color = worki[1];
835 /* validates the indexes supplied to i_ppal
837 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
842 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
843 int color_count = i_colorcount(im);
846 if (color_count == -1)
847 croak("i_plin() called on direct color image");
849 for (i = 0; i < count; ++i) {
850 if (indexes[i] >= color_count) {
851 croak("i_plin() called with out of range color index %d (max %d)",
852 indexes[i], color_count-1);
858 /* I don't think ICLF_* names belong at the C interface
859 this makes the XS code think we have them, to let us avoid
860 putting function bodies in the XS code
862 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
863 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
866 #define i_log_enabled() 1
868 #define i_log_enabled() 0
871 #if i_int_hlines_testing()
873 typedef i_int_hlines *Imager__Internal__Hlines;
875 static i_int_hlines *
876 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
877 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
878 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
883 static i_int_hlines *
884 i_int_hlines_new_img(i_img *im) {
885 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
886 i_int_init_hlines_img(result, im);
892 i_int_hlines_DESTROY(i_int_hlines *hlines) {
893 i_int_hlines_destroy(hlines);
897 #define i_int_hlines_CLONE_SKIP(cls) 1
899 static int seg_compare(const void *vleft, const void *vright) {
900 const i_int_hline_seg *left = vleft;
901 const i_int_hline_seg *right = vright;
903 return left->minx - right->minx;
907 i_int_hlines_dump(i_int_hlines *hlines) {
909 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
910 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
913 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
914 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
917 /* sort the segments, if any */
919 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
921 sv_catpvf(dump, " %d (%d):", y, entry->count);
922 for (i = 0; i < entry->count; ++i) {
923 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
924 entry->segs[i].x_limit);
926 sv_catpv(dump, "\n");
935 static im_pl_ext_funcs im_perl_funcs =
937 IMAGER_PL_API_VERSION,
939 ip_handle_quant_opts,
940 ip_cleanup_quant_opts,
944 #define PERL_PL_SET_GLOBAL_CALLBACKS \
945 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
948 #define i_exif_enabled() 1
950 #define i_exif_enabled() 0
953 /* trying to use more C style names, map them here */
954 #define i_io_DESTROY(ig) io_glue_destroy(ig)
956 #define i_img_get_width(im) ((im)->xsize)
957 #define i_img_get_height(im) ((im)->ysize)
959 #define i_img_epsilonf() (DBL_EPSILON * 4)
961 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
964 ICL_new_internal(r,g,b,a)
976 ICL_set_internal(cl,r,g,b,a)
983 ICL_set_internal(cl, r, g, b, a);
997 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
998 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
999 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
1000 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
1006 RETVAL = mymalloc(sizeof(i_color));
1008 i_hsv_to_rgb(RETVAL);
1016 RETVAL = mymalloc(sizeof(i_color));
1018 i_rgb_to_hsv(RETVAL);
1024 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1026 Imager::Color::Float
1027 ICLF_new_internal(r, g, b, a)
1035 Imager::Color::Float cl
1039 Imager::Color::Float cl
1043 EXTEND(SP, MAXCHANNELS);
1044 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1045 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1046 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1050 ICLF_set_internal(cl,r,g,b,a)
1051 Imager::Color::Float cl
1064 Imager::Color::Float
1066 Imager::Color::Float c
1068 RETVAL = mymalloc(sizeof(i_fcolor));
1070 i_hsv_to_rgbf(RETVAL);
1074 Imager::Color::Float
1076 Imager::Color::Float c
1078 RETVAL = mymalloc(sizeof(i_fcolor));
1080 i_rgb_to_hsvf(RETVAL);
1084 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1098 MODULE = Imager PACKAGE = Imager
1117 SvPV(ST(0), length);
1118 SvREFCNT_inc(ST(0));
1119 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1124 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1133 cbd = mymalloc(sizeof(struct cbdata));
1134 SvREFCNT_inc(writecb);
1135 cbd->writecb = writecb;
1136 SvREFCNT_inc(readcb);
1137 cbd->readcb = readcb;
1138 SvREFCNT_inc(seekcb);
1139 cbd->seekcb = seekcb;
1140 SvREFCNT_inc(closecb);
1141 cbd->closecb = closecb;
1142 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1143 if (maxwrite > CBDATA_BUFSIZE)
1144 maxwrite = CBDATA_BUFSIZE;
1145 cbd->maxlength = maxwrite;
1146 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1155 unsigned char* data;
1159 tlength = io_slurp(ig, &data);
1161 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1166 i_set_image_file_limits(width, height, bytes)
1172 i_get_image_file_limits()
1174 int width, height, bytes;
1176 if (i_get_image_file_limits(&width, &height, &bytes)) {
1178 PUSHs(sv_2mortal(newSViv(width)));
1179 PUSHs(sv_2mortal(newSViv(height)));
1180 PUSHs(sv_2mortal(newSViv(bytes)));
1183 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1186 i_io_write(ig, data_sv)
1194 if (SvUTF8(data_sv)) {
1195 data_sv = sv_2mortal(newSVsv(data_sv));
1196 /* yes, we want this to croak() if the SV can't be downgraded */
1197 sv_utf8_downgrade(data_sv, FALSE);
1200 data = SvPV(data_sv, size);
1201 RETVAL = i_io_write(ig, data, size);
1206 i_io_read(ig, buffer_sv, size)
1215 croak("size negative in call to i_io_read()");
1216 /* prevent an undefined value warning if they supplied an
1218 Orginally conditional on !SvOK(), but this will prevent the
1219 downgrade from croaking */
1220 sv_setpvn(buffer_sv, "", 0);
1222 if (SvUTF8(buffer_sv))
1223 sv_utf8_downgrade(buffer_sv, FALSE);
1225 buffer = SvGROW(buffer_sv, size+1);
1226 result = i_io_read(ig, buffer, size);
1228 SvCUR_set(buffer_sv, result);
1229 *SvEND(buffer_sv) = '\0';
1230 SvPOK_only(buffer_sv);
1232 PUSHs(sv_2mortal(newSViv(result)));
1238 i_io_read2(ig, size)
1247 croak("size negative in call to i_io_read2()");
1248 buffer_sv = newSV(size);
1249 buffer = SvGROW(buffer_sv, size+1);
1250 result = i_io_read(ig, buffer, size);
1252 SvCUR_set(buffer_sv, result);
1253 *SvEND(buffer_sv) = '\0';
1254 SvPOK_only(buffer_sv);
1256 PUSHs(sv_2mortal(buffer_sv));
1260 SvREFCNT_dec(buffer_sv);
1264 i_io_seek(ig, position, whence)
1278 i_io_CLONE_SKIP(...)
1284 MODULE = Imager PACKAGE = Imager
1295 while( (item=i_format_list[i++]) != NULL ) {
1297 PUSHs(sv_2mortal(newSVpv(item,0)));
1310 i_img_empty_ch(im,x,y,ch)
1317 i_sametype(im, x, y)
1323 i_sametype_chans(im, x, y, channels)
1330 i_init_log(name_sv,level)
1334 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1336 RETVAL = i_init_log(name, level);
1341 i_log_entry(string,level)
1362 i_img_info(im,info);
1364 PUSHs(sv_2mortal(newSViv(info[0])));
1365 PUSHs(sv_2mortal(newSViv(info[1])));
1366 PUSHs(sv_2mortal(newSViv(info[2])));
1367 PUSHs(sv_2mortal(newSViv(info[3])));
1373 i_img_setmask(im,ch_mask)
1382 i_img_getchannels(im)
1391 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1399 i_img_get_height(im)
1404 i_img_is_monochrome(im)
1410 result = i_img_is_monochrome(im, &zero_is_white);
1412 if (GIMME_V == G_ARRAY) {
1415 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1424 i_line(im,x1,y1,x2,y2,val,endp)
1434 i_line_aa(im,x1,y1,x2,y2,val,endp)
1444 i_box(im,x1,y1,x2,y2,val)
1453 i_box_filled(im,x1,y1,x2,y2,val)
1462 i_box_filledf(im,x1,y1,x2,y2,val)
1468 Imager::Color::Float val
1471 i_box_cfill(im,x1,y1,x2,y2,fill)
1477 Imager::FillHandle fill
1480 i_arc(im,x,y,rad,d1,d2,val)
1490 i_arc_aa(im,x,y,rad,d1,d2,val)
1500 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1507 Imager::FillHandle fill
1510 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1517 Imager::FillHandle fill
1521 i_circle_aa(im,x,y,rad,val)
1529 i_circle_out(im,x,y,rad,val)
1537 i_circle_out_aa(im,x,y,rad,val)
1545 i_arc_out(im,x,y,rad,d1,d2,val)
1555 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1566 i_bezier_multi(im,xc,yc,val)
1579 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1580 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1581 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1582 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1583 av1=(AV*)SvRV(ST(1));
1584 av2=(AV*)SvRV(ST(2));
1585 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1587 x=mymalloc( len*sizeof(double) );
1588 y=mymalloc( len*sizeof(double) );
1589 for(i=0;i<len;i++) {
1590 sv1=(*(av_fetch(av1,i,0)));
1591 sv2=(*(av_fetch(av2,i,0)));
1592 x[i]=(double)SvNV(sv1);
1593 y[i]=(double)SvNV(sv2);
1595 i_bezier_multi(im,len,x,y,val);
1601 i_poly_aa(im,xc,yc,val)
1614 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1615 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1616 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1617 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1618 av1=(AV*)SvRV(ST(1));
1619 av2=(AV*)SvRV(ST(2));
1620 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1622 x=mymalloc( len*sizeof(double) );
1623 y=mymalloc( len*sizeof(double) );
1624 for(i=0;i<len;i++) {
1625 sv1=(*(av_fetch(av1,i,0)));
1626 sv2=(*(av_fetch(av2,i,0)));
1627 x[i]=(double)SvNV(sv1);
1628 y[i]=(double)SvNV(sv2);
1630 RETVAL = i_poly_aa(im,len,x,y,val);
1637 i_poly_aa_cfill(im,xc,yc,fill)
1639 Imager::FillHandle fill
1649 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1650 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1651 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1652 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1653 av1=(AV*)SvRV(ST(1));
1654 av2=(AV*)SvRV(ST(2));
1655 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1657 x=mymalloc( len*sizeof(double) );
1658 y=mymalloc( len*sizeof(double) );
1659 for(i=0;i<len;i++) {
1660 sv1=(*(av_fetch(av1,i,0)));
1661 sv2=(*(av_fetch(av2,i,0)));
1662 x[i]=(double)SvNV(sv1);
1663 y[i]=(double)SvNV(sv2);
1665 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1674 i_flood_fill(im,seedx,seedy,dcol)
1681 i_flood_cfill(im,seedx,seedy,fill)
1685 Imager::FillHandle fill
1688 i_flood_fill_border(im,seedx,seedy,dcol, border)
1693 Imager::Color border
1696 i_flood_cfill_border(im,seedx,seedy,fill, border)
1700 Imager::FillHandle fill
1701 Imager::Color border
1705 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1717 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1734 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1745 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1758 i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width, height, combine = ic_normal, opacity = 0.0)
1774 i_combine(src_av, channels_av = NULL)
1778 i_img **imgs = NULL;
1780 int *channels = NULL;
1785 in_count = av_len(src_av) + 1;
1787 imgs = mymalloc(sizeof(i_img*) * in_count);
1788 channels = mymalloc(sizeof(int) * in_count);
1789 for (i = 0; i < in_count; ++i) {
1790 psv = av_fetch(src_av, i, 0);
1791 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1794 croak("imgs must contain only images");
1796 tmp = SvIV((SV*)SvRV(*psv));
1797 imgs[i] = INT2PTR(i_img*, tmp);
1799 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1801 channels[i] = SvIV(*psv);
1808 RETVAL = i_combine(imgs, channels, in_count);
1815 i_flipxy(im, direction)
1820 i_rotate90(im, degrees)
1825 i_rotate_exact(im, amount, ...)
1829 i_color *backp = NULL;
1830 i_fcolor *fbackp = NULL;
1834 /* extract the bg colors if any */
1835 /* yes, this is kind of strange */
1836 for (i = 2; i < items; ++i) {
1838 if (sv_derived_from(sv1, "Imager::Color")) {
1839 IV tmp = SvIV((SV*)SvRV(sv1));
1840 backp = INT2PTR(i_color *, tmp);
1842 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1843 IV tmp = SvIV((SV*)SvRV(sv1));
1844 fbackp = INT2PTR(i_fcolor *, tmp);
1847 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1852 i_matrix_transform(im, xsize, ysize, matrix, ...)
1862 i_color *backp = NULL;
1863 i_fcolor *fbackp = NULL;
1865 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1866 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1867 av=(AV*)SvRV(ST(3));
1871 for (i = 0; i < len; ++i) {
1872 sv1=(*(av_fetch(av,i,0)));
1873 matrix[i] = SvNV(sv1);
1877 /* extract the bg colors if any */
1878 /* yes, this is kind of strange */
1879 for (i = 4; i < items; ++i) {
1881 if (sv_derived_from(sv1, "Imager::Color")) {
1882 IV tmp = SvIV((SV*)SvRV(sv1));
1883 backp = INT2PTR(i_color *, tmp);
1885 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1886 IV tmp = SvIV((SV*)SvRV(sv1));
1887 fbackp = INT2PTR(i_fcolor *, tmp);
1890 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1895 i_gaussian(im,stdev)
1900 i_unsharp_mask(im,stdev,scale)
1915 len = av_len(coef) + 1;
1916 c_coef=mymalloc( len * sizeof(double) );
1917 for(i = 0; i < len; i++) {
1918 sv1 = (*(av_fetch(coef, i, 0)));
1919 c_coef[i] = (double)SvNV(sv1);
1921 RETVAL = i_conv(im, c_coef, len);
1927 i_convert(src, avmain)
1939 outchan = av_len(avmain)+1;
1940 /* find the biggest */
1942 for (j=0; j < outchan; ++j) {
1943 temp = av_fetch(avmain, j, 0);
1944 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1945 avsub = (AV*)SvRV(*temp);
1946 len = av_len(avsub)+1;
1951 coeff = mymalloc(sizeof(double) * outchan * inchan);
1952 for (j = 0; j < outchan; ++j) {
1953 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1954 len = av_len(avsub)+1;
1955 for (i = 0; i < len; ++i) {
1956 temp = av_fetch(avsub, i, 0);
1958 coeff[i+j*inchan] = SvNV(*temp);
1960 coeff[i+j*inchan] = 0;
1963 coeff[i++ + j*inchan] = 0;
1965 RETVAL = i_convert(src, coeff, outchan, inchan);
1975 unsigned int mask = 0;
1981 unsigned char (*maps)[256];
1983 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1984 croak("i_map: parameter 2 must be an arrayref\n");
1985 avmain = (AV*)SvRV(ST(1));
1986 len = av_len(avmain)+1;
1987 if (im->channels < len) len = im->channels;
1989 maps = mymalloc( len * sizeof(unsigned char [256]) );
1991 for (j=0; j<len ; j++) {
1992 temp = av_fetch(avmain, j, 0);
1993 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1994 avsub = (AV*)SvRV(*temp);
1995 if(av_len(avsub) != 255) continue;
1997 for (i=0; i<256 ; i++) {
1999 temp = av_fetch(avsub, i, 0);
2000 val = temp ? SvIV(*temp) : 0;
2002 if (val>255) val = 255;
2007 i_map(im, maps, mask);
2018 i_img_diffd(im1,im2)
2023 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2033 _is_color_object(sv)
2037 RETVAL = SvOK(sv) && SvROK(sv) &&
2038 (sv_derived_from(sv, "Imager::Color")
2039 || sv_derived_from(sv, "Imager::Color::Float"));
2054 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2056 #define TT_DESTROY(handle) i_tt_destroy(handle)
2060 Imager::Font::TT handle
2070 MODULE = Imager PACKAGE = Imager
2074 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2075 Imager::Font::TT handle
2093 str = SvPV(str_sv, len);
2094 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2095 len, smooth, utf8, align);
2101 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2102 Imager::Font::TT handle
2120 str = SvPV(str_sv, len);
2121 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2122 smooth, utf8, align);
2128 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2129 Imager::Font::TT handle
2134 int cords[BOUNDING_BOX_COUNT],rc;
2143 str = SvPV(str_sv, len);
2144 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2146 for (i = 0; i < rc; ++i) {
2147 PUSHs(sv_2mortal(newSViv(cords[i])));
2152 i_tt_has_chars(handle, text_sv, utf8)
2153 Imager::Font::TT handle
2164 if (SvUTF8(text_sv))
2167 text = SvPV(text_sv, len);
2168 work = mymalloc(len);
2169 count = i_tt_has_chars(handle, text, len, utf8, work);
2170 if (GIMME_V == G_ARRAY) {
2172 for (i = 0; i < count; ++i) {
2173 PUSHs(sv_2mortal(newSViv(work[i])));
2178 PUSHs(sv_2mortal(newSVpv(work, count)));
2183 i_tt_dump_names(handle)
2184 Imager::Font::TT handle
2187 i_tt_face_name(handle)
2188 Imager::Font::TT handle
2193 len = i_tt_face_name(handle, name, sizeof(name));
2196 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2200 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2201 Imager::Font::TT handle
2212 if (SvUTF8(text_sv))
2215 text = SvPV(text_sv, work_len);
2220 ch = i_utf8_advance(&text, &len);
2222 i_push_error(0, "invalid UTF8 character");
2231 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2232 PUSHs(sv_2mortal(newSVpv(name, 0)));
2235 PUSHs(&PL_sv_undef);
2242 i_test_format_probe(ig, length)
2247 i_readpnm_wiol(ig, allow_incomplete)
2249 int allow_incomplete
2253 i_readpnm_multi_wiol(ig, allow_incomplete)
2255 int allow_incomplete
2261 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2264 for (i = 0; i < count; ++i) {
2265 SV *sv = sv_newmortal();
2266 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2273 i_writeppm_wiol(im, ig)
2282 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2291 i_writeraw_wiol(im,ig)
2296 i_writebmp_wiol(im,ig)
2301 i_readbmp_wiol(ig, allow_incomplete=0)
2303 int allow_incomplete
2307 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2316 idlen = SvCUR(ST(4));
2317 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2323 i_readtga_wiol(ig, length)
2331 i_scaleaxis(im,Value,Axis)
2337 i_scale_nn(im,scx,scy)
2343 i_scale_mixing(im, width, height)
2353 i_count_colors(im,maxc)
2358 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2363 unsigned int * col_usage = NULL;
2366 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2367 EXTEND(SP, col_cnt);
2368 for (i = 0; i < col_cnt; i++) {
2369 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2376 i_transform(im,opx,opy,parm)
2389 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2390 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2391 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2392 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2393 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2394 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2395 av=(AV*)SvRV(ST(1));
2397 opx=mymalloc( opxl*sizeof(int) );
2398 for(i=0;i<opxl;i++) {
2399 sv1=(*(av_fetch(av,i,0)));
2400 opx[i]=(int)SvIV(sv1);
2402 av=(AV*)SvRV(ST(2));
2404 opy=mymalloc( opyl*sizeof(int) );
2405 for(i=0;i<opyl;i++) {
2406 sv1=(*(av_fetch(av,i,0)));
2407 opy[i]=(int)SvIV(sv1);
2409 av=(AV*)SvRV(ST(3));
2410 parmlen=av_len(av)+1;
2411 parm=mymalloc( parmlen*sizeof(double) );
2412 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2413 sv1=(*(av_fetch(av,i,0)));
2414 parm[i]=(double)SvNV(sv1);
2416 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2420 ST(0) = sv_newmortal();
2421 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2422 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2425 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2450 in_imgs_count = av_len(av_in_imgs)+1;
2451 for (i = 0; i < in_imgs_count; ++i) {
2452 sv1 = *av_fetch(av_in_imgs, i, 0);
2453 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2454 croak("sv_in_img must contain only images");
2457 if (in_imgs_count > 0) {
2458 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2459 for (i = 0; i < in_imgs_count; ++i) {
2460 sv1 = *av_fetch(av_in_imgs,i,0);
2461 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2462 croak("Parameter 5 must contain only images");
2464 tmp = SvIV((SV*)SvRV(sv1));
2465 in_imgs[i] = INT2PTR(i_img*, tmp);
2469 /* no input images */
2472 /* default the output size from the first input if possible */
2474 width = SvIV(sv_width);
2475 else if (in_imgs_count)
2476 width = in_imgs[0]->xsize;
2478 croak("No output image width supplied");
2480 if (SvOK(sv_height))
2481 height = SvIV(sv_height);
2482 else if (in_imgs_count)
2483 height = in_imgs[0]->ysize;
2485 croak("No output image height supplied");
2487 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2488 if (ops_len % sizeof(struct rm_op))
2489 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2490 ops_count = ops_len / sizeof(struct rm_op);
2492 n_regs_count = av_len(av_n_regs)+1;
2493 n_regs = mymalloc(n_regs_count * sizeof(double));
2494 for (i = 0; i < n_regs_count; ++i) {
2495 sv1 = *av_fetch(av_n_regs,i,0);
2497 n_regs[i] = SvNV(sv1);
2499 c_regs_count = av_len(av_c_regs)+1;
2500 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2501 /* I don't bother initializing the colou?r registers */
2503 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2504 n_regs, n_regs_count,
2505 c_regs, c_regs_count, in_imgs, in_imgs_count);
2510 ST(0) = sv_newmortal();
2511 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2512 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2516 i_contrast(im,intensity)
2529 i_noise(im,amount,type)
2535 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2545 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2564 i_postlevels(im,levels)
2574 i_watermark(im,wmark,tx,ty,pixdiff)
2576 Imager::ImgRaw wmark
2583 i_autolevels(im,lsat,usat,skew)
2590 i_radnoise(im,xo,yo,rscale,ascale)
2598 i_turbnoise(im, xo, yo, scale)
2621 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2622 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2623 croak("i_gradgen: Second argument must be an array ref");
2624 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2625 croak("i_gradgen: Third argument must be an array ref");
2626 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2627 croak("i_gradgen: Fourth argument must be an array ref");
2628 axx = (AV *)SvRV(ST(1));
2629 ayy = (AV *)SvRV(ST(2));
2630 ac = (AV *)SvRV(ST(3));
2631 dmeasure = (int)SvIV(ST(4));
2633 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2634 num = num <= av_len(ac) ? num : av_len(ac);
2636 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2637 xo = mymalloc( sizeof(int) * num );
2638 yo = mymalloc( sizeof(int) * num );
2639 ival = mymalloc( sizeof(i_color) * num );
2640 for(i = 0; i<num; i++) {
2641 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2642 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2643 sv = *av_fetch(ac, i, 0);
2644 if ( !sv_derived_from(sv, "Imager::Color") ) {
2645 free(axx); free(ayy); free(ac);
2646 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2648 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2650 i_gradgen(im, num, xo, yo, ival, dmeasure);
2656 i_diff_image(im, im2, mindist=0)
2662 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2672 double ssample_param
2676 i_fountain_seg *segs;
2678 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2679 croak("i_fountain: argument 11 must be an array ref");
2681 asegs = (AV *)SvRV(ST(10));
2682 segs = load_fount_segs(aTHX_ asegs, &count);
2683 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2684 super_sample, ssample_param, count, segs);
2690 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2699 double ssample_param
2703 i_fountain_seg *segs;
2705 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2706 croak("i_fountain: argument 11 must be an array ref");
2708 asegs = (AV *)SvRV(ST(9));
2709 segs = load_fount_segs(aTHX_ asegs, &count);
2710 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2711 super_sample, ssample_param, count, segs);
2717 i_new_fill_opacity(other_fill, alpha_mult)
2718 Imager::FillHandle other_fill
2729 errors = i_errors();
2731 while (errors[i].msg) {
2733 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2734 if (!av_store(av, 0, sv)) {
2737 sv = newSViv(errors[i].code);
2738 if (!av_store(av, 1, sv)) {
2741 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2749 i_push_error(code, msg)
2754 i_nearest_color(im, ...)
2769 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2770 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2771 croak("i_nearest_color: Second argument must be an array ref");
2772 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2773 croak("i_nearest_color: Third argument must be an array ref");
2774 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2775 croak("i_nearest_color: Fourth argument must be an array ref");
2776 axx = (AV *)SvRV(ST(1));
2777 ayy = (AV *)SvRV(ST(2));
2778 ac = (AV *)SvRV(ST(3));
2779 dmeasure = (int)SvIV(ST(4));
2781 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2782 num = num <= av_len(ac) ? num : av_len(ac);
2784 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2785 xo = mymalloc( sizeof(int) * num );
2786 yo = mymalloc( sizeof(int) * num );
2787 ival = mymalloc( sizeof(i_color) * num );
2788 for(i = 0; i<num; i++) {
2789 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2790 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2791 sv = *av_fetch(ac, i, 0);
2792 if ( !sv_derived_from(sv, "Imager::Color") ) {
2793 free(axx); free(ayy); free(ac);
2794 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2796 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2798 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2812 rc=DSO_open(filename,&evstr);
2816 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2817 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2820 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2826 DSO_close(dso_handle)
2830 DSO_funclist(dso_handle_v)
2834 DSO_handle *dso_handle;
2835 func_ptr *functions;
2837 dso_handle=(DSO_handle*)dso_handle_v;
2838 functions = DSO_funclist(dso_handle);
2840 while( functions[i].name != NULL) {
2842 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2844 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2848 DSO_call(handle,func_index,hv)
2854 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2855 hv=(HV*)SvRV(ST(2));
2856 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2857 DSO_call( (DSO_handle *)handle,func_index,hv);
2860 i_get_pixel(im, x, y)
2867 color = (i_color *)mymalloc(sizeof(i_color));
2868 if (i_gpix(im, x, y, color) == 0) {
2869 RETVAL = NEWSV(0, 0);
2870 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2874 RETVAL = &PL_sv_undef;
2881 i_ppix(im, x, y, cl)
2888 i_img_pal_new(x, y, channels, maxpal)
2895 i_img_to_pal(src, quant)
2901 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2902 croak("i_img_to_pal: second argument must be a hash ref");
2903 hv = (HV *)SvRV(ST(1));
2904 memset(&quant, 0, sizeof(quant));
2906 quant.mc_size = 256;
2907 ip_handle_quant_opts(aTHX_ &quant, hv);
2908 RETVAL = i_img_to_pal(src, &quant);
2910 ip_copy_colors_back(aTHX_ hv, &quant);
2912 ip_cleanup_quant_opts(aTHX_ &quant);
2931 work = mymalloc((r-l) * sizeof(i_palidx));
2932 count = i_gpal(im, l, r, y, work);
2933 if (GIMME_V == G_ARRAY) {
2935 for (i = 0; i < count; ++i) {
2936 PUSHs(sv_2mortal(newSViv(work[i])));
2941 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
2946 if (GIMME_V != G_ARRAY) {
2948 PUSHs(&PL_sv_undef);
2953 i_ppal(im, l, y, ...)
2962 work = mymalloc(sizeof(i_palidx) * (items-3));
2963 for (i=0; i < items-3; ++i) {
2964 work[i] = SvIV(ST(i+3));
2966 validate_i_ppal(im, work, items - 3);
2967 RETVAL = i_ppal(im, l, l+items-3, y, work);
2977 i_ppal_p(im, l, y, data)
2983 i_palidx const *work;
2986 work = (i_palidx const *)SvPV(data, len);
2987 len /= sizeof(i_palidx);
2989 validate_i_ppal(im, work, len);
2990 RETVAL = i_ppal(im, l, l+len, y, work);
2999 i_addcolors(im, ...)
3007 croak("i_addcolors: no colors to add");
3008 colors = mymalloc((items-1) * sizeof(i_color));
3009 for (i=0; i < items-1; ++i) {
3010 if (sv_isobject(ST(i+1))
3011 && sv_derived_from(ST(i+1), "Imager::Color")) {
3012 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3013 colors[i] = *INT2PTR(i_color *, tmp);
3017 croak("i_addcolor: pixels must be Imager::Color objects");
3020 index = i_addcolors(im, colors, items-1);
3023 RETVAL = newSVpv("0 but true", 0);
3025 else if (index == -1) {
3026 RETVAL = &PL_sv_undef;
3029 RETVAL = newSViv(index);
3035 i_setcolors(im, index, ...)
3043 croak("i_setcolors: no colors to add");
3044 colors = mymalloc((items-2) * sizeof(i_color));
3045 for (i=0; i < items-2; ++i) {
3046 if (sv_isobject(ST(i+2))
3047 && sv_derived_from(ST(i+2), "Imager::Color")) {
3048 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3049 colors[i] = *INT2PTR(i_color *, tmp);
3053 croak("i_setcolors: pixels must be Imager::Color objects");
3056 RETVAL = i_setcolors(im, index, colors, items-2);
3062 i_getcolors(im, index, ...)
3071 croak("i_getcolors: too many arguments");
3073 count = SvIV(ST(2));
3075 croak("i_getcolors: count must be positive");
3076 colors = mymalloc(sizeof(i_color) * count);
3077 if (i_getcolors(im, index, colors, count)) {
3078 for (i = 0; i < count; ++i) {
3080 SV *sv = sv_newmortal();
3081 pv = mymalloc(sizeof(i_color));
3083 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3099 i_findcolor(im, color)
3105 if (i_findcolor(im, color, &index)) {
3106 RETVAL = newSViv(index);
3109 RETVAL = &PL_sv_undef;
3127 i_gsamp(im, l, r, y, ...)
3139 croak("No channel numbers supplied to g_samp()");
3141 chan_count = items - 4;
3142 chans = mymalloc(sizeof(int) * chan_count);
3143 for (i = 0; i < chan_count; ++i)
3144 chans[i] = SvIV(ST(i+4));
3145 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3146 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3148 if (GIMME_V == G_ARRAY) {
3150 for (i = 0; i < count; ++i)
3151 PUSHs(sv_2mortal(newSViv(data[i])));
3155 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3160 if (GIMME_V != G_ARRAY) {
3162 PUSHs(&PL_sv_undef);
3167 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3183 croak("No channel numbers supplied to g_samp()");
3185 chan_count = items - 7;
3186 chans = mymalloc(sizeof(int) * chan_count);
3187 for (i = 0; i < chan_count; ++i)
3188 chans[i] = SvIV(ST(i+7));
3189 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3190 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3192 for (i = 0; i < count; ++i) {
3193 av_store(target, i+offset, newSVuv(data[i]));
3205 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3223 if (SvOK(channels_sv)) {
3225 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3226 croak("channels is not an array ref");
3228 channels_av = (AV *)SvRV(channels_sv);
3229 chan_count = av_len(channels_av) + 1;
3230 if (chan_count < 1) {
3231 croak("i_psamp_bits: no channels provided");
3233 channels = mymalloc(sizeof(int) * chan_count);
3234 for (i = 0; i < chan_count; ++i)
3235 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3238 chan_count = im->channels;
3242 data_count = av_len(data_av) + 1;
3243 if (data_offset < 0) {
3244 croak("data_offset must by non-negative");
3246 if (data_offset > data_count) {
3247 croak("data_offset greater than number of samples supplied");
3249 if (pixel_count == -1 ||
3250 data_offset + pixel_count * chan_count > data_count) {
3251 pixel_count = (data_count - data_offset) / chan_count;
3254 data_used = pixel_count * chan_count;
3255 data = mymalloc(sizeof(unsigned) * data_count);
3256 for (i = 0; i < data_used; ++i)
3257 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3259 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3270 i_img_masked_new(targ, mask, x, y, w, h)
3280 if (!sv_isobject(ST(1))
3281 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3282 croak("i_img_masked_new: parameter 2 must undef or an image");
3284 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3288 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3293 i_plin(im, l, y, ...)
3304 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3305 /* supplied as a byte string */
3306 work = (i_color *)SvPV(ST(3), len);
3307 count = len / sizeof(i_color);
3308 if (count * sizeof(i_color) != len) {
3309 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3311 RETVAL = i_plin(im, l, l+count, y, work);
3314 work = mymalloc(sizeof(i_color) * (items-3));
3315 for (i=0; i < items-3; ++i) {
3316 if (sv_isobject(ST(i+3))
3317 && sv_derived_from(ST(i+3), "Imager::Color")) {
3318 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3319 work[i] = *INT2PTR(i_color *, tmp);
3323 croak("i_plin: pixels must be Imager::Color objects");
3326 RETVAL = i_plin(im, l, l+items-3, y, work);
3337 i_ppixf(im, x, y, cl)
3341 Imager::Color::Float cl
3344 i_gsampf(im, l, r, y, ...)
3356 croak("No channel numbers supplied to g_sampf()");
3358 chan_count = items - 4;
3359 chans = mymalloc(sizeof(int) * chan_count);
3360 for (i = 0; i < chan_count; ++i)
3361 chans[i] = SvIV(ST(i+4));
3362 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3363 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3365 if (GIMME_V == G_ARRAY) {
3367 for (i = 0; i < count; ++i)
3368 PUSHs(sv_2mortal(newSVnv(data[i])));
3372 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3377 if (GIMME_V != G_ARRAY) {
3379 PUSHs(&PL_sv_undef);
3384 i_plinf(im, l, y, ...)
3395 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3396 /* supplied as a byte string */
3397 work = (i_fcolor *)SvPV(ST(3), len);
3398 count = len / sizeof(i_fcolor);
3399 if (count * sizeof(i_fcolor) != len) {
3400 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3402 RETVAL = i_plinf(im, l, l+count, y, work);
3405 work = mymalloc(sizeof(i_fcolor) * (items-3));
3406 for (i=0; i < items-3; ++i) {
3407 if (sv_isobject(ST(i+3))
3408 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3409 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3410 work[i] = *INT2PTR(i_fcolor *, tmp);
3414 croak("i_plinf: pixels must be Imager::Color::Float objects");
3418 RETVAL = i_plinf(im, l, l+items-3, y, work);
3436 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3437 if (i_gpixf(im, x, y, color) == 0) {
3438 RETVAL = NEWSV(0,0);
3439 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3443 RETVAL = &PL_sv_undef;
3459 vals = mymalloc((r-l) * sizeof(i_color));
3460 memset(vals, 0, (r-l) * sizeof(i_color));
3461 count = i_glin(im, l, r, y, vals);
3462 if (GIMME_V == G_ARRAY) {
3464 for (i = 0; i < count; ++i) {
3466 i_color *col = mymalloc(sizeof(i_color));
3468 sv = sv_newmortal();
3469 sv_setref_pv(sv, "Imager::Color", (void *)col);
3475 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3481 i_glinf(im, l, r, y)
3491 for (i = 0; i < MAXCHANNELS; ++i)
3492 zero.channel[i] = 0;
3494 vals = mymalloc((r-l) * sizeof(i_fcolor));
3495 for (i = 0; i < r-l; ++i)
3497 count = i_glinf(im, l, r, y, vals);
3498 if (GIMME_V == G_ARRAY) {
3500 for (i = 0; i < count; ++i) {
3502 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3504 sv = sv_newmortal();
3505 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3511 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3517 i_img_16_new(x, y, ch)
3527 i_img_double_new(x, y, ch)
3533 i_tags_addn(im, name, code, idata)
3542 name = SvPV(ST(1), len);
3545 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3550 i_tags_add(im, name, code, data, idata)
3560 name = SvPV(ST(1), len);
3564 data = SvPV(ST(3), len);
3569 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3574 i_tags_find(im, name, start)
3581 if (i_tags_find(&im->tags, name, start, &entry)) {
3583 RETVAL = newSVpv("0 but true", 0);
3585 RETVAL = newSViv(entry);
3587 RETVAL = &PL_sv_undef;
3593 i_tags_findn(im, code, start)
3600 if (i_tags_findn(&im->tags, code, start, &entry)) {
3602 RETVAL = newSVpv("0 but true", 0);
3604 RETVAL = newSViv(entry);
3607 RETVAL = &PL_sv_undef;
3613 i_tags_delete(im, entry)
3617 RETVAL = i_tags_delete(&im->tags, entry);
3622 i_tags_delbyname(im, name)
3626 RETVAL = i_tags_delbyname(&im->tags, name);
3631 i_tags_delbycode(im, code)
3635 RETVAL = i_tags_delbycode(&im->tags, code);
3640 i_tags_get(im, index)
3644 if (index >= 0 && index < im->tags.count) {
3645 i_img_tag *entry = im->tags.tags + index;
3649 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3652 PUSHs(sv_2mortal(newSViv(entry->code)));
3655 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3658 PUSHs(sv_2mortal(newSViv(entry->idata)));
3663 i_tags_get_string(im, what_sv)
3667 char const *name = NULL;
3671 if (SvIOK(what_sv)) {
3672 code = SvIV(what_sv);
3676 name = SvPV_nolen(what_sv);
3679 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3681 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3688 RETVAL = im->tags.count;
3694 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3698 Imager::FillHandle fill
3701 IFILL_CLONE_SKIP(...)
3707 MODULE = Imager PACKAGE = Imager
3710 i_new_fill_solid(cl, combine)
3715 i_new_fill_solidf(cl, combine)
3716 Imager::Color::Float cl
3720 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3728 unsigned char *cust_hatch;
3732 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3736 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3741 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3742 Imager::Color::Float fg
3743 Imager::Color::Float bg
3749 unsigned char *cust_hatch;
3753 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3757 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3762 i_new_fill_image(src, matrix, xoff, yoff, combine)
3779 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3780 croak("i_new_fill_image: parameter must be an arrayref");
3781 av=(AV*)SvRV(ST(1));
3785 for (i = 0; i < len; ++i) {
3786 sv1=(*(av_fetch(av,i,0)));
3787 matrix[i] = SvNV(sv1);
3793 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3797 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3799 # this class is only exposed for testing
3802 i_int_hlines_testing()
3804 #if i_int_hlines_testing()
3806 Imager::Internal::Hlines
3807 i_int_hlines_new(start_y, count_y, start_x, count_x)
3813 Imager::Internal::Hlines
3814 i_int_hlines_new_img(im)
3818 i_int_hlines_add(hlines, y, minx, width)
3819 Imager::Internal::Hlines hlines
3825 i_int_hlines_DESTROY(hlines)
3826 Imager::Internal::Hlines hlines
3829 i_int_hlines_dump(hlines)
3830 Imager::Internal::Hlines hlines
3833 i_int_hlines_CLONE_SKIP(cls)
3839 PERL_SET_GLOBAL_CALLBACKS;
3840 PERL_PL_SET_GLOBAL_CALLBACKS;