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)
865 #if i_int_hlines_testing()
867 typedef i_int_hlines *Imager__Internal__Hlines;
869 static i_int_hlines *
870 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
871 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
872 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
877 static i_int_hlines *
878 i_int_hlines_new_img(i_img *im) {
879 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
880 i_int_init_hlines_img(result, im);
886 i_int_hlines_DESTROY(i_int_hlines *hlines) {
887 i_int_hlines_destroy(hlines);
891 #define i_int_hlines_CLONE_SKIP(cls) 1
893 static int seg_compare(const void *vleft, const void *vright) {
894 const i_int_hline_seg *left = vleft;
895 const i_int_hline_seg *right = vright;
897 return left->minx - right->minx;
901 i_int_hlines_dump(i_int_hlines *hlines) {
903 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
904 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
907 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
908 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
911 /* sort the segments, if any */
913 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
915 sv_catpvf(dump, " %d (%d):", y, entry->count);
916 for (i = 0; i < entry->count; ++i) {
917 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
918 entry->segs[i].x_limit);
920 sv_catpv(dump, "\n");
929 static im_pl_ext_funcs im_perl_funcs =
931 IMAGER_PL_API_VERSION,
933 ip_handle_quant_opts,
934 ip_cleanup_quant_opts,
938 #define PERL_PL_SET_GLOBAL_CALLBACKS \
939 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
942 #define i_exif_enabled() 1
944 #define i_exif_enabled() 0
947 /* trying to use more C style names, map them here */
948 #define i_io_DESTROY(ig) io_glue_destroy(ig)
950 #define i_img_get_width(im) ((im)->xsize)
951 #define i_img_get_height(im) ((im)->ysize)
953 #define i_img_epsilonf() (DBL_EPSILON * 4)
955 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
958 ICL_new_internal(r,g,b,a)
970 ICL_set_internal(cl,r,g,b,a)
977 ICL_set_internal(cl, r, g, b, a);
991 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
992 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
993 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
994 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
1000 RETVAL = mymalloc(sizeof(i_color));
1002 i_hsv_to_rgb(RETVAL);
1010 RETVAL = mymalloc(sizeof(i_color));
1012 i_rgb_to_hsv(RETVAL);
1018 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1020 Imager::Color::Float
1021 ICLF_new_internal(r, g, b, a)
1029 Imager::Color::Float cl
1033 Imager::Color::Float cl
1037 EXTEND(SP, MAXCHANNELS);
1038 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1039 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1040 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1044 ICLF_set_internal(cl,r,g,b,a)
1045 Imager::Color::Float cl
1058 Imager::Color::Float
1060 Imager::Color::Float c
1062 RETVAL = mymalloc(sizeof(i_fcolor));
1064 i_hsv_to_rgbf(RETVAL);
1068 Imager::Color::Float
1070 Imager::Color::Float c
1072 RETVAL = mymalloc(sizeof(i_fcolor));
1074 i_rgb_to_hsvf(RETVAL);
1078 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1092 MODULE = Imager PACKAGE = Imager
1111 SvPV(ST(0), length);
1112 SvREFCNT_inc(ST(0));
1113 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1118 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1127 cbd = mymalloc(sizeof(struct cbdata));
1128 SvREFCNT_inc(writecb);
1129 cbd->writecb = writecb;
1130 SvREFCNT_inc(readcb);
1131 cbd->readcb = readcb;
1132 SvREFCNT_inc(seekcb);
1133 cbd->seekcb = seekcb;
1134 SvREFCNT_inc(closecb);
1135 cbd->closecb = closecb;
1136 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1137 if (maxwrite > CBDATA_BUFSIZE)
1138 maxwrite = CBDATA_BUFSIZE;
1139 cbd->maxlength = maxwrite;
1140 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1149 unsigned char* data;
1153 tlength = io_slurp(ig, &data);
1155 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1160 i_set_image_file_limits(width, height, bytes)
1166 i_get_image_file_limits()
1168 int width, height, bytes;
1170 if (i_get_image_file_limits(&width, &height, &bytes)) {
1172 PUSHs(sv_2mortal(newSViv(width)));
1173 PUSHs(sv_2mortal(newSViv(height)));
1174 PUSHs(sv_2mortal(newSViv(bytes)));
1177 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1180 i_io_write(ig, data_sv)
1188 if (SvUTF8(data_sv)) {
1189 data_sv = sv_2mortal(newSVsv(data_sv));
1190 /* yes, we want this to croak() if the SV can't be downgraded */
1191 sv_utf8_downgrade(data_sv, FALSE);
1194 data = SvPV(data_sv, size);
1195 RETVAL = i_io_write(ig, data, size);
1200 i_io_read(ig, buffer_sv, size)
1209 croak("size negative in call to i_io_read()");
1210 /* prevent an undefined value warning if they supplied an
1212 Orginally conditional on !SvOK(), but this will prevent the
1213 downgrade from croaking */
1214 sv_setpvn(buffer_sv, "", 0);
1216 if (SvUTF8(buffer_sv))
1217 sv_utf8_downgrade(buffer_sv, FALSE);
1219 buffer = SvGROW(buffer_sv, size+1);
1220 result = i_io_read(ig, buffer, size);
1222 SvCUR_set(buffer_sv, result);
1223 *SvEND(buffer_sv) = '\0';
1224 SvPOK_only(buffer_sv);
1226 PUSHs(sv_2mortal(newSViv(result)));
1232 i_io_read2(ig, size)
1241 croak("size negative in call to i_io_read2()");
1242 buffer_sv = newSV(size);
1243 buffer = SvGROW(buffer_sv, size+1);
1244 result = i_io_read(ig, buffer, size);
1246 SvCUR_set(buffer_sv, result);
1247 *SvEND(buffer_sv) = '\0';
1248 SvPOK_only(buffer_sv);
1250 PUSHs(sv_2mortal(buffer_sv));
1254 SvREFCNT_dec(buffer_sv);
1258 i_io_seek(ig, position, whence)
1272 i_io_CLONE_SKIP(...)
1278 MODULE = Imager PACKAGE = Imager
1289 while( (item=i_format_list[i++]) != NULL ) {
1291 PUSHs(sv_2mortal(newSVpv(item,0)));
1304 i_img_empty_ch(im,x,y,ch)
1311 i_sametype(im, x, y)
1317 i_sametype_chans(im, x, y, channels)
1324 i_init_log(name_sv,level)
1328 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1330 i_init_log(name, level);
1333 i_log_entry(string,level)
1352 i_img_info(im,info);
1354 PUSHs(sv_2mortal(newSViv(info[0])));
1355 PUSHs(sv_2mortal(newSViv(info[1])));
1356 PUSHs(sv_2mortal(newSViv(info[2])));
1357 PUSHs(sv_2mortal(newSViv(info[3])));
1363 i_img_setmask(im,ch_mask)
1372 i_img_getchannels(im)
1381 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1389 i_img_get_height(im)
1394 i_img_is_monochrome(im)
1400 result = i_img_is_monochrome(im, &zero_is_white);
1402 if (GIMME_V == G_ARRAY) {
1405 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1414 i_line(im,x1,y1,x2,y2,val,endp)
1424 i_line_aa(im,x1,y1,x2,y2,val,endp)
1434 i_box(im,x1,y1,x2,y2,val)
1443 i_box_filled(im,x1,y1,x2,y2,val)
1452 i_box_filledf(im,x1,y1,x2,y2,val)
1458 Imager::Color::Float val
1461 i_box_cfill(im,x1,y1,x2,y2,fill)
1467 Imager::FillHandle fill
1470 i_arc(im,x,y,rad,d1,d2,val)
1480 i_arc_aa(im,x,y,rad,d1,d2,val)
1490 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1497 Imager::FillHandle fill
1500 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1507 Imager::FillHandle fill
1511 i_circle_aa(im,x,y,rad,val)
1519 i_circle_out(im,x,y,rad,val)
1527 i_circle_out_aa(im,x,y,rad,val)
1535 i_arc_out(im,x,y,rad,d1,d2,val)
1545 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1556 i_bezier_multi(im,xc,yc,val)
1569 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1570 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1571 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1572 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1573 av1=(AV*)SvRV(ST(1));
1574 av2=(AV*)SvRV(ST(2));
1575 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1577 x=mymalloc( len*sizeof(double) );
1578 y=mymalloc( len*sizeof(double) );
1579 for(i=0;i<len;i++) {
1580 sv1=(*(av_fetch(av1,i,0)));
1581 sv2=(*(av_fetch(av2,i,0)));
1582 x[i]=(double)SvNV(sv1);
1583 y[i]=(double)SvNV(sv2);
1585 i_bezier_multi(im,len,x,y,val);
1591 i_poly_aa(im,xc,yc,val)
1604 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1605 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1606 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1607 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1608 av1=(AV*)SvRV(ST(1));
1609 av2=(AV*)SvRV(ST(2));
1610 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1612 x=mymalloc( len*sizeof(double) );
1613 y=mymalloc( len*sizeof(double) );
1614 for(i=0;i<len;i++) {
1615 sv1=(*(av_fetch(av1,i,0)));
1616 sv2=(*(av_fetch(av2,i,0)));
1617 x[i]=(double)SvNV(sv1);
1618 y[i]=(double)SvNV(sv2);
1620 RETVAL = i_poly_aa(im,len,x,y,val);
1627 i_poly_aa_cfill(im,xc,yc,fill)
1629 Imager::FillHandle fill
1639 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1640 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1641 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1642 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1643 av1=(AV*)SvRV(ST(1));
1644 av2=(AV*)SvRV(ST(2));
1645 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1647 x=mymalloc( len*sizeof(double) );
1648 y=mymalloc( len*sizeof(double) );
1649 for(i=0;i<len;i++) {
1650 sv1=(*(av_fetch(av1,i,0)));
1651 sv2=(*(av_fetch(av2,i,0)));
1652 x[i]=(double)SvNV(sv1);
1653 y[i]=(double)SvNV(sv2);
1655 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1664 i_flood_fill(im,seedx,seedy,dcol)
1671 i_flood_cfill(im,seedx,seedy,fill)
1675 Imager::FillHandle fill
1678 i_flood_fill_border(im,seedx,seedy,dcol, border)
1683 Imager::Color border
1686 i_flood_cfill_border(im,seedx,seedy,fill, border)
1690 Imager::FillHandle fill
1691 Imager::Color border
1695 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1707 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1724 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1735 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1748 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)
1764 i_combine(src_av, channels_av = NULL)
1768 i_img **imgs = NULL;
1770 int *channels = NULL;
1775 in_count = av_len(src_av) + 1;
1777 imgs = mymalloc(sizeof(i_img*) * in_count);
1778 channels = mymalloc(sizeof(int) * in_count);
1779 for (i = 0; i < in_count; ++i) {
1780 psv = av_fetch(src_av, i, 0);
1781 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1784 croak("imgs must contain only images");
1786 tmp = SvIV((SV*)SvRV(*psv));
1787 imgs[i] = INT2PTR(i_img*, tmp);
1789 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1791 channels[i] = SvIV(*psv);
1798 RETVAL = i_combine(imgs, channels, in_count);
1805 i_flipxy(im, direction)
1810 i_rotate90(im, degrees)
1815 i_rotate_exact(im, amount, ...)
1819 i_color *backp = NULL;
1820 i_fcolor *fbackp = NULL;
1824 /* extract the bg colors if any */
1825 /* yes, this is kind of strange */
1826 for (i = 2; i < items; ++i) {
1828 if (sv_derived_from(sv1, "Imager::Color")) {
1829 IV tmp = SvIV((SV*)SvRV(sv1));
1830 backp = INT2PTR(i_color *, tmp);
1832 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1833 IV tmp = SvIV((SV*)SvRV(sv1));
1834 fbackp = INT2PTR(i_fcolor *, tmp);
1837 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1842 i_matrix_transform(im, xsize, ysize, matrix, ...)
1852 i_color *backp = NULL;
1853 i_fcolor *fbackp = NULL;
1855 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1856 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1857 av=(AV*)SvRV(ST(3));
1861 for (i = 0; i < len; ++i) {
1862 sv1=(*(av_fetch(av,i,0)));
1863 matrix[i] = SvNV(sv1);
1867 /* extract the bg colors if any */
1868 /* yes, this is kind of strange */
1869 for (i = 4; i < items; ++i) {
1871 if (sv_derived_from(sv1, "Imager::Color")) {
1872 IV tmp = SvIV((SV*)SvRV(sv1));
1873 backp = INT2PTR(i_color *, tmp);
1875 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1876 IV tmp = SvIV((SV*)SvRV(sv1));
1877 fbackp = INT2PTR(i_fcolor *, tmp);
1880 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1885 i_gaussian(im,stdev)
1890 i_unsharp_mask(im,stdev,scale)
1905 len = av_len(coef) + 1;
1906 c_coef=mymalloc( len * sizeof(double) );
1907 for(i = 0; i < len; i++) {
1908 sv1 = (*(av_fetch(coef, i, 0)));
1909 c_coef[i] = (double)SvNV(sv1);
1911 RETVAL = i_conv(im, c_coef, len);
1917 i_convert(src, avmain)
1929 outchan = av_len(avmain)+1;
1930 /* find the biggest */
1932 for (j=0; j < outchan; ++j) {
1933 temp = av_fetch(avmain, j, 0);
1934 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1935 avsub = (AV*)SvRV(*temp);
1936 len = av_len(avsub)+1;
1941 coeff = mymalloc(sizeof(double) * outchan * inchan);
1942 for (j = 0; j < outchan; ++j) {
1943 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1944 len = av_len(avsub)+1;
1945 for (i = 0; i < len; ++i) {
1946 temp = av_fetch(avsub, i, 0);
1948 coeff[i+j*inchan] = SvNV(*temp);
1950 coeff[i+j*inchan] = 0;
1953 coeff[i++ + j*inchan] = 0;
1955 RETVAL = i_convert(src, coeff, outchan, inchan);
1965 unsigned int mask = 0;
1971 unsigned char (*maps)[256];
1973 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1974 croak("i_map: parameter 2 must be an arrayref\n");
1975 avmain = (AV*)SvRV(ST(1));
1976 len = av_len(avmain)+1;
1977 if (im->channels < len) len = im->channels;
1979 maps = mymalloc( len * sizeof(unsigned char [256]) );
1981 for (j=0; j<len ; j++) {
1982 temp = av_fetch(avmain, j, 0);
1983 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1984 avsub = (AV*)SvRV(*temp);
1985 if(av_len(avsub) != 255) continue;
1987 for (i=0; i<256 ; i++) {
1989 temp = av_fetch(avsub, i, 0);
1990 val = temp ? SvIV(*temp) : 0;
1992 if (val>255) val = 255;
1997 i_map(im, maps, mask);
2008 i_img_diffd(im1,im2)
2013 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2023 _is_color_object(sv)
2027 RETVAL = SvOK(sv) && SvROK(sv) &&
2028 (sv_derived_from(sv, "Imager::Color")
2029 || sv_derived_from(sv, "Imager::Color::Float"));
2044 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2046 #define TT_DESTROY(handle) i_tt_destroy(handle)
2050 Imager::Font::TT handle
2060 MODULE = Imager PACKAGE = Imager
2064 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2065 Imager::Font::TT handle
2083 str = SvPV(str_sv, len);
2084 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2085 len, smooth, utf8, align);
2091 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2092 Imager::Font::TT handle
2110 str = SvPV(str_sv, len);
2111 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2112 smooth, utf8, align);
2118 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2119 Imager::Font::TT handle
2124 int cords[BOUNDING_BOX_COUNT],rc;
2133 str = SvPV(str_sv, len);
2134 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2136 for (i = 0; i < rc; ++i) {
2137 PUSHs(sv_2mortal(newSViv(cords[i])));
2142 i_tt_has_chars(handle, text_sv, utf8)
2143 Imager::Font::TT handle
2154 if (SvUTF8(text_sv))
2157 text = SvPV(text_sv, len);
2158 work = mymalloc(len);
2159 count = i_tt_has_chars(handle, text, len, utf8, work);
2160 if (GIMME_V == G_ARRAY) {
2162 for (i = 0; i < count; ++i) {
2163 PUSHs(sv_2mortal(newSViv(work[i])));
2168 PUSHs(sv_2mortal(newSVpv(work, count)));
2173 i_tt_dump_names(handle)
2174 Imager::Font::TT handle
2177 i_tt_face_name(handle)
2178 Imager::Font::TT handle
2183 len = i_tt_face_name(handle, name, sizeof(name));
2186 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2190 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2191 Imager::Font::TT handle
2202 if (SvUTF8(text_sv))
2205 text = SvPV(text_sv, work_len);
2210 ch = i_utf8_advance(&text, &len);
2212 i_push_error(0, "invalid UTF8 character");
2221 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2222 PUSHs(sv_2mortal(newSVpv(name, 0)));
2225 PUSHs(&PL_sv_undef);
2232 i_test_format_probe(ig, length)
2237 i_readpnm_wiol(ig, allow_incomplete)
2239 int allow_incomplete
2243 i_readpnm_multi_wiol(ig, allow_incomplete)
2245 int allow_incomplete
2251 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2254 for (i = 0; i < count; ++i) {
2255 SV *sv = sv_newmortal();
2256 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2263 i_writeppm_wiol(im, ig)
2272 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2281 i_writeraw_wiol(im,ig)
2286 i_writebmp_wiol(im,ig)
2291 i_readbmp_wiol(ig, allow_incomplete=0)
2293 int allow_incomplete
2297 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2306 idlen = SvCUR(ST(4));
2307 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2313 i_readtga_wiol(ig, length)
2321 i_scaleaxis(im,Value,Axis)
2327 i_scale_nn(im,scx,scy)
2333 i_scale_mixing(im, width, height)
2343 i_count_colors(im,maxc)
2348 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2353 unsigned int * col_usage = NULL;
2356 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2357 EXTEND(SP, col_cnt);
2358 for (i = 0; i < col_cnt; i++) {
2359 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2366 i_transform(im,opx,opy,parm)
2379 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2380 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2381 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2382 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2383 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2384 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2385 av=(AV*)SvRV(ST(1));
2387 opx=mymalloc( opxl*sizeof(int) );
2388 for(i=0;i<opxl;i++) {
2389 sv1=(*(av_fetch(av,i,0)));
2390 opx[i]=(int)SvIV(sv1);
2392 av=(AV*)SvRV(ST(2));
2394 opy=mymalloc( opyl*sizeof(int) );
2395 for(i=0;i<opyl;i++) {
2396 sv1=(*(av_fetch(av,i,0)));
2397 opy[i]=(int)SvIV(sv1);
2399 av=(AV*)SvRV(ST(3));
2400 parmlen=av_len(av)+1;
2401 parm=mymalloc( parmlen*sizeof(double) );
2402 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2403 sv1=(*(av_fetch(av,i,0)));
2404 parm[i]=(double)SvNV(sv1);
2406 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2410 ST(0) = sv_newmortal();
2411 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2412 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2415 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2440 in_imgs_count = av_len(av_in_imgs)+1;
2441 for (i = 0; i < in_imgs_count; ++i) {
2442 sv1 = *av_fetch(av_in_imgs, i, 0);
2443 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2444 croak("sv_in_img must contain only images");
2447 if (in_imgs_count > 0) {
2448 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2449 for (i = 0; i < in_imgs_count; ++i) {
2450 sv1 = *av_fetch(av_in_imgs,i,0);
2451 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2452 croak("Parameter 5 must contain only images");
2454 tmp = SvIV((SV*)SvRV(sv1));
2455 in_imgs[i] = INT2PTR(i_img*, tmp);
2459 /* no input images */
2462 /* default the output size from the first input if possible */
2464 width = SvIV(sv_width);
2465 else if (in_imgs_count)
2466 width = in_imgs[0]->xsize;
2468 croak("No output image width supplied");
2470 if (SvOK(sv_height))
2471 height = SvIV(sv_height);
2472 else if (in_imgs_count)
2473 height = in_imgs[0]->ysize;
2475 croak("No output image height supplied");
2477 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2478 if (ops_len % sizeof(struct rm_op))
2479 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2480 ops_count = ops_len / sizeof(struct rm_op);
2482 n_regs_count = av_len(av_n_regs)+1;
2483 n_regs = mymalloc(n_regs_count * sizeof(double));
2484 for (i = 0; i < n_regs_count; ++i) {
2485 sv1 = *av_fetch(av_n_regs,i,0);
2487 n_regs[i] = SvNV(sv1);
2489 c_regs_count = av_len(av_c_regs)+1;
2490 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2491 /* I don't bother initializing the colou?r registers */
2493 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2494 n_regs, n_regs_count,
2495 c_regs, c_regs_count, in_imgs, in_imgs_count);
2500 ST(0) = sv_newmortal();
2501 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2502 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2506 i_contrast(im,intensity)
2519 i_noise(im,amount,type)
2525 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2535 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2554 i_postlevels(im,levels)
2564 i_watermark(im,wmark,tx,ty,pixdiff)
2566 Imager::ImgRaw wmark
2573 i_autolevels(im,lsat,usat,skew)
2580 i_radnoise(im,xo,yo,rscale,ascale)
2588 i_turbnoise(im, xo, yo, scale)
2611 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2612 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2613 croak("i_gradgen: Second argument must be an array ref");
2614 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2615 croak("i_gradgen: Third argument must be an array ref");
2616 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2617 croak("i_gradgen: Fourth argument must be an array ref");
2618 axx = (AV *)SvRV(ST(1));
2619 ayy = (AV *)SvRV(ST(2));
2620 ac = (AV *)SvRV(ST(3));
2621 dmeasure = (int)SvIV(ST(4));
2623 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2624 num = num <= av_len(ac) ? num : av_len(ac);
2626 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2627 xo = mymalloc( sizeof(int) * num );
2628 yo = mymalloc( sizeof(int) * num );
2629 ival = mymalloc( sizeof(i_color) * num );
2630 for(i = 0; i<num; i++) {
2631 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2632 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2633 sv = *av_fetch(ac, i, 0);
2634 if ( !sv_derived_from(sv, "Imager::Color") ) {
2635 free(axx); free(ayy); free(ac);
2636 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2638 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2640 i_gradgen(im, num, xo, yo, ival, dmeasure);
2646 i_diff_image(im, im2, mindist=0)
2652 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2662 double ssample_param
2666 i_fountain_seg *segs;
2668 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2669 croak("i_fountain: argument 11 must be an array ref");
2671 asegs = (AV *)SvRV(ST(10));
2672 segs = load_fount_segs(aTHX_ asegs, &count);
2673 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2674 super_sample, ssample_param, count, segs);
2680 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2689 double ssample_param
2693 i_fountain_seg *segs;
2695 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2696 croak("i_fountain: argument 11 must be an array ref");
2698 asegs = (AV *)SvRV(ST(9));
2699 segs = load_fount_segs(aTHX_ asegs, &count);
2700 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2701 super_sample, ssample_param, count, segs);
2707 i_new_fill_opacity(other_fill, alpha_mult)
2708 Imager::FillHandle other_fill
2719 errors = i_errors();
2721 while (errors[i].msg) {
2723 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2724 if (!av_store(av, 0, sv)) {
2727 sv = newSViv(errors[i].code);
2728 if (!av_store(av, 1, sv)) {
2731 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2739 i_push_error(code, msg)
2744 i_nearest_color(im, ...)
2759 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2760 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2761 croak("i_nearest_color: Second argument must be an array ref");
2762 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2763 croak("i_nearest_color: Third argument must be an array ref");
2764 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2765 croak("i_nearest_color: Fourth argument must be an array ref");
2766 axx = (AV *)SvRV(ST(1));
2767 ayy = (AV *)SvRV(ST(2));
2768 ac = (AV *)SvRV(ST(3));
2769 dmeasure = (int)SvIV(ST(4));
2771 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2772 num = num <= av_len(ac) ? num : av_len(ac);
2774 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2775 xo = mymalloc( sizeof(int) * num );
2776 yo = mymalloc( sizeof(int) * num );
2777 ival = mymalloc( sizeof(i_color) * num );
2778 for(i = 0; i<num; i++) {
2779 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2780 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2781 sv = *av_fetch(ac, i, 0);
2782 if ( !sv_derived_from(sv, "Imager::Color") ) {
2783 free(axx); free(ayy); free(ac);
2784 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2786 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2788 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2802 rc=DSO_open(filename,&evstr);
2806 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2807 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2810 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2816 DSO_close(dso_handle)
2820 DSO_funclist(dso_handle_v)
2824 DSO_handle *dso_handle;
2825 func_ptr *functions;
2827 dso_handle=(DSO_handle*)dso_handle_v;
2828 functions = DSO_funclist(dso_handle);
2830 while( functions[i].name != NULL) {
2832 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2834 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2838 DSO_call(handle,func_index,hv)
2844 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2845 hv=(HV*)SvRV(ST(2));
2846 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2847 DSO_call( (DSO_handle *)handle,func_index,hv);
2850 i_get_pixel(im, x, y)
2857 color = (i_color *)mymalloc(sizeof(i_color));
2858 if (i_gpix(im, x, y, color) == 0) {
2859 RETVAL = NEWSV(0, 0);
2860 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2864 RETVAL = &PL_sv_undef;
2871 i_ppix(im, x, y, cl)
2878 i_img_pal_new(x, y, channels, maxpal)
2885 i_img_to_pal(src, quant)
2891 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2892 croak("i_img_to_pal: second argument must be a hash ref");
2893 hv = (HV *)SvRV(ST(1));
2894 memset(&quant, 0, sizeof(quant));
2896 quant.mc_size = 256;
2897 ip_handle_quant_opts(aTHX_ &quant, hv);
2898 RETVAL = i_img_to_pal(src, &quant);
2900 ip_copy_colors_back(aTHX_ hv, &quant);
2902 ip_cleanup_quant_opts(aTHX_ &quant);
2921 work = mymalloc((r-l) * sizeof(i_palidx));
2922 count = i_gpal(im, l, r, y, work);
2923 if (GIMME_V == G_ARRAY) {
2925 for (i = 0; i < count; ++i) {
2926 PUSHs(sv_2mortal(newSViv(work[i])));
2931 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
2936 if (GIMME_V != G_ARRAY) {
2938 PUSHs(&PL_sv_undef);
2943 i_ppal(im, l, y, ...)
2952 work = mymalloc(sizeof(i_palidx) * (items-3));
2953 for (i=0; i < items-3; ++i) {
2954 work[i] = SvIV(ST(i+3));
2956 validate_i_ppal(im, work, items - 3);
2957 RETVAL = i_ppal(im, l, l+items-3, y, work);
2967 i_ppal_p(im, l, y, data)
2973 i_palidx const *work;
2976 work = (i_palidx const *)SvPV(data, len);
2977 len /= sizeof(i_palidx);
2979 validate_i_ppal(im, work, len);
2980 RETVAL = i_ppal(im, l, l+len, y, work);
2989 i_addcolors(im, ...)
2997 croak("i_addcolors: no colors to add");
2998 colors = mymalloc((items-1) * sizeof(i_color));
2999 for (i=0; i < items-1; ++i) {
3000 if (sv_isobject(ST(i+1))
3001 && sv_derived_from(ST(i+1), "Imager::Color")) {
3002 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3003 colors[i] = *INT2PTR(i_color *, tmp);
3007 croak("i_addcolor: pixels must be Imager::Color objects");
3010 index = i_addcolors(im, colors, items-1);
3013 RETVAL = newSVpv("0 but true", 0);
3015 else if (index == -1) {
3016 RETVAL = &PL_sv_undef;
3019 RETVAL = newSViv(index);
3025 i_setcolors(im, index, ...)
3033 croak("i_setcolors: no colors to add");
3034 colors = mymalloc((items-2) * sizeof(i_color));
3035 for (i=0; i < items-2; ++i) {
3036 if (sv_isobject(ST(i+2))
3037 && sv_derived_from(ST(i+2), "Imager::Color")) {
3038 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3039 colors[i] = *INT2PTR(i_color *, tmp);
3043 croak("i_setcolors: pixels must be Imager::Color objects");
3046 RETVAL = i_setcolors(im, index, colors, items-2);
3052 i_getcolors(im, index, ...)
3061 croak("i_getcolors: too many arguments");
3063 count = SvIV(ST(2));
3065 croak("i_getcolors: count must be positive");
3066 colors = mymalloc(sizeof(i_color) * count);
3067 if (i_getcolors(im, index, colors, count)) {
3068 for (i = 0; i < count; ++i) {
3070 SV *sv = sv_newmortal();
3071 pv = mymalloc(sizeof(i_color));
3073 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3089 i_findcolor(im, color)
3095 if (i_findcolor(im, color, &index)) {
3096 RETVAL = newSViv(index);
3099 RETVAL = &PL_sv_undef;
3117 i_gsamp(im, l, r, y, ...)
3129 croak("No channel numbers supplied to g_samp()");
3131 chan_count = items - 4;
3132 chans = mymalloc(sizeof(int) * chan_count);
3133 for (i = 0; i < chan_count; ++i)
3134 chans[i] = SvIV(ST(i+4));
3135 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3136 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3138 if (GIMME_V == G_ARRAY) {
3140 for (i = 0; i < count; ++i)
3141 PUSHs(sv_2mortal(newSViv(data[i])));
3145 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3150 if (GIMME_V != G_ARRAY) {
3152 PUSHs(&PL_sv_undef);
3157 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3173 croak("No channel numbers supplied to g_samp()");
3175 chan_count = items - 7;
3176 chans = mymalloc(sizeof(int) * chan_count);
3177 for (i = 0; i < chan_count; ++i)
3178 chans[i] = SvIV(ST(i+7));
3179 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3180 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3182 for (i = 0; i < count; ++i) {
3183 av_store(target, i+offset, newSVuv(data[i]));
3195 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3213 if (SvOK(channels_sv)) {
3215 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3216 croak("channels is not an array ref");
3218 channels_av = (AV *)SvRV(channels_sv);
3219 chan_count = av_len(channels_av) + 1;
3220 if (chan_count < 1) {
3221 croak("i_psamp_bits: no channels provided");
3223 channels = mymalloc(sizeof(int) * chan_count);
3224 for (i = 0; i < chan_count; ++i)
3225 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3228 chan_count = im->channels;
3232 data_count = av_len(data_av) + 1;
3233 if (data_offset < 0) {
3234 croak("data_offset must by non-negative");
3236 if (data_offset > data_count) {
3237 croak("data_offset greater than number of samples supplied");
3239 if (pixel_count == -1 ||
3240 data_offset + pixel_count * chan_count > data_count) {
3241 pixel_count = (data_count - data_offset) / chan_count;
3244 data_used = pixel_count * chan_count;
3245 data = mymalloc(sizeof(unsigned) * data_count);
3246 for (i = 0; i < data_used; ++i)
3247 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3249 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3260 i_img_masked_new(targ, mask, x, y, w, h)
3270 if (!sv_isobject(ST(1))
3271 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3272 croak("i_img_masked_new: parameter 2 must undef or an image");
3274 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3278 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3283 i_plin(im, l, y, ...)
3294 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3295 /* supplied as a byte string */
3296 work = (i_color *)SvPV(ST(3), len);
3297 count = len / sizeof(i_color);
3298 if (count * sizeof(i_color) != len) {
3299 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3301 RETVAL = i_plin(im, l, l+count, y, work);
3304 work = mymalloc(sizeof(i_color) * (items-3));
3305 for (i=0; i < items-3; ++i) {
3306 if (sv_isobject(ST(i+3))
3307 && sv_derived_from(ST(i+3), "Imager::Color")) {
3308 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3309 work[i] = *INT2PTR(i_color *, tmp);
3313 croak("i_plin: pixels must be Imager::Color objects");
3316 RETVAL = i_plin(im, l, l+items-3, y, work);
3327 i_ppixf(im, x, y, cl)
3331 Imager::Color::Float cl
3334 i_gsampf(im, l, r, y, ...)
3346 croak("No channel numbers supplied to g_sampf()");
3348 chan_count = items - 4;
3349 chans = mymalloc(sizeof(int) * chan_count);
3350 for (i = 0; i < chan_count; ++i)
3351 chans[i] = SvIV(ST(i+4));
3352 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3353 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3355 if (GIMME_V == G_ARRAY) {
3357 for (i = 0; i < count; ++i)
3358 PUSHs(sv_2mortal(newSVnv(data[i])));
3362 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3367 if (GIMME_V != G_ARRAY) {
3369 PUSHs(&PL_sv_undef);
3374 i_plinf(im, l, y, ...)
3385 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3386 /* supplied as a byte string */
3387 work = (i_fcolor *)SvPV(ST(3), len);
3388 count = len / sizeof(i_fcolor);
3389 if (count * sizeof(i_fcolor) != len) {
3390 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3392 RETVAL = i_plinf(im, l, l+count, y, work);
3395 work = mymalloc(sizeof(i_fcolor) * (items-3));
3396 for (i=0; i < items-3; ++i) {
3397 if (sv_isobject(ST(i+3))
3398 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3399 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3400 work[i] = *INT2PTR(i_fcolor *, tmp);
3404 croak("i_plinf: pixels must be Imager::Color::Float objects");
3408 RETVAL = i_plinf(im, l, l+items-3, y, work);
3426 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3427 if (i_gpixf(im, x, y, color) == 0) {
3428 RETVAL = NEWSV(0,0);
3429 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3433 RETVAL = &PL_sv_undef;
3449 vals = mymalloc((r-l) * sizeof(i_color));
3450 memset(vals, 0, (r-l) * sizeof(i_color));
3451 count = i_glin(im, l, r, y, vals);
3452 if (GIMME_V == G_ARRAY) {
3454 for (i = 0; i < count; ++i) {
3456 i_color *col = mymalloc(sizeof(i_color));
3458 sv = sv_newmortal();
3459 sv_setref_pv(sv, "Imager::Color", (void *)col);
3465 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3471 i_glinf(im, l, r, y)
3481 for (i = 0; i < MAXCHANNELS; ++i)
3482 zero.channel[i] = 0;
3484 vals = mymalloc((r-l) * sizeof(i_fcolor));
3485 for (i = 0; i < r-l; ++i)
3487 count = i_glinf(im, l, r, y, vals);
3488 if (GIMME_V == G_ARRAY) {
3490 for (i = 0; i < count; ++i) {
3492 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3494 sv = sv_newmortal();
3495 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3501 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3507 i_img_16_new(x, y, ch)
3517 i_img_double_new(x, y, ch)
3523 i_tags_addn(im, name, code, idata)
3532 name = SvPV(ST(1), len);
3535 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3540 i_tags_add(im, name, code, data, idata)
3550 name = SvPV(ST(1), len);
3554 data = SvPV(ST(3), len);
3559 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3564 i_tags_find(im, name, start)
3571 if (i_tags_find(&im->tags, name, start, &entry)) {
3573 RETVAL = newSVpv("0 but true", 0);
3575 RETVAL = newSViv(entry);
3577 RETVAL = &PL_sv_undef;
3583 i_tags_findn(im, code, start)
3590 if (i_tags_findn(&im->tags, code, start, &entry)) {
3592 RETVAL = newSVpv("0 but true", 0);
3594 RETVAL = newSViv(entry);
3597 RETVAL = &PL_sv_undef;
3603 i_tags_delete(im, entry)
3607 RETVAL = i_tags_delete(&im->tags, entry);
3612 i_tags_delbyname(im, name)
3616 RETVAL = i_tags_delbyname(&im->tags, name);
3621 i_tags_delbycode(im, code)
3625 RETVAL = i_tags_delbycode(&im->tags, code);
3630 i_tags_get(im, index)
3634 if (index >= 0 && index < im->tags.count) {
3635 i_img_tag *entry = im->tags.tags + index;
3639 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3642 PUSHs(sv_2mortal(newSViv(entry->code)));
3645 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3648 PUSHs(sv_2mortal(newSViv(entry->idata)));
3653 i_tags_get_string(im, what_sv)
3657 char const *name = NULL;
3661 if (SvIOK(what_sv)) {
3662 code = SvIV(what_sv);
3666 name = SvPV_nolen(what_sv);
3669 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3671 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3678 RETVAL = im->tags.count;
3684 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3688 Imager::FillHandle fill
3691 IFILL_CLONE_SKIP(...)
3697 MODULE = Imager PACKAGE = Imager
3700 i_new_fill_solid(cl, combine)
3705 i_new_fill_solidf(cl, combine)
3706 Imager::Color::Float cl
3710 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3718 unsigned char *cust_hatch;
3722 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3726 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3731 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3732 Imager::Color::Float fg
3733 Imager::Color::Float bg
3739 unsigned char *cust_hatch;
3743 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3747 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3752 i_new_fill_image(src, matrix, xoff, yoff, combine)
3769 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3770 croak("i_new_fill_image: parameter must be an arrayref");
3771 av=(AV*)SvRV(ST(1));
3775 for (i = 0; i < len; ++i) {
3776 sv1=(*(av_fetch(av,i,0)));
3777 matrix[i] = SvNV(sv1);
3783 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3787 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3789 # this class is only exposed for testing
3792 i_int_hlines_testing()
3794 #if i_int_hlines_testing()
3796 Imager::Internal::Hlines
3797 i_int_hlines_new(start_y, count_y, start_x, count_x)
3803 Imager::Internal::Hlines
3804 i_int_hlines_new_img(im)
3808 i_int_hlines_add(hlines, y, minx, width)
3809 Imager::Internal::Hlines hlines
3815 i_int_hlines_DESTROY(hlines)
3816 Imager::Internal::Hlines hlines
3819 i_int_hlines_dump(hlines)
3820 Imager::Internal::Hlines hlines
3823 i_int_hlines_CLONE_SKIP(cls)
3829 PERL_SET_GLOBAL_CALLBACKS;
3830 PERL_PL_SET_GLOBAL_CALLBACKS;