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 /* the m_init_log() function was called init_log(), renamed to reduce
867 potential naming conflicts */
868 #define init_log m_init_log
870 #if i_int_hlines_testing()
872 typedef i_int_hlines *Imager__Internal__Hlines;
874 static i_int_hlines *
875 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
876 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
877 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
882 static i_int_hlines *
883 i_int_hlines_new_img(i_img *im) {
884 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
885 i_int_init_hlines_img(result, im);
891 i_int_hlines_DESTROY(i_int_hlines *hlines) {
892 i_int_hlines_destroy(hlines);
896 #define i_int_hlines_CLONE_SKIP(cls) 1
898 static int seg_compare(const void *vleft, const void *vright) {
899 const i_int_hline_seg *left = vleft;
900 const i_int_hline_seg *right = vright;
902 return left->minx - right->minx;
906 i_int_hlines_dump(i_int_hlines *hlines) {
908 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
909 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
912 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
913 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
916 /* sort the segments, if any */
918 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
920 sv_catpvf(dump, " %d (%d):", y, entry->count);
921 for (i = 0; i < entry->count; ++i) {
922 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
923 entry->segs[i].x_limit);
925 sv_catpv(dump, "\n");
934 static im_pl_ext_funcs im_perl_funcs =
936 IMAGER_PL_API_VERSION,
938 ip_handle_quant_opts,
939 ip_cleanup_quant_opts,
943 #define PERL_PL_SET_GLOBAL_CALLBACKS \
944 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
947 #define i_exif_enabled() 1
949 #define i_exif_enabled() 0
952 /* trying to use more C style names, map them here */
953 #define i_io_DESTROY(ig) io_glue_destroy(ig)
955 #define i_img_get_width(im) ((im)->xsize)
956 #define i_img_get_height(im) ((im)->ysize)
958 #define i_img_epsilonf() (DBL_EPSILON * 4)
960 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
963 ICL_new_internal(r,g,b,a)
975 ICL_set_internal(cl,r,g,b,a)
982 ICL_set_internal(cl, r, g, b, a);
996 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
997 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
998 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
999 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
1005 RETVAL = mymalloc(sizeof(i_color));
1007 i_hsv_to_rgb(RETVAL);
1015 RETVAL = mymalloc(sizeof(i_color));
1017 i_rgb_to_hsv(RETVAL);
1023 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1025 Imager::Color::Float
1026 ICLF_new_internal(r, g, b, a)
1034 Imager::Color::Float cl
1038 Imager::Color::Float cl
1042 EXTEND(SP, MAXCHANNELS);
1043 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1044 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1045 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1049 ICLF_set_internal(cl,r,g,b,a)
1050 Imager::Color::Float cl
1063 Imager::Color::Float
1065 Imager::Color::Float c
1067 RETVAL = mymalloc(sizeof(i_fcolor));
1069 i_hsv_to_rgbf(RETVAL);
1073 Imager::Color::Float
1075 Imager::Color::Float c
1077 RETVAL = mymalloc(sizeof(i_fcolor));
1079 i_rgb_to_hsvf(RETVAL);
1083 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1097 MODULE = Imager PACKAGE = Imager
1116 SvPV(ST(0), length);
1117 SvREFCNT_inc(ST(0));
1118 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1123 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1132 cbd = mymalloc(sizeof(struct cbdata));
1133 SvREFCNT_inc(writecb);
1134 cbd->writecb = writecb;
1135 SvREFCNT_inc(readcb);
1136 cbd->readcb = readcb;
1137 SvREFCNT_inc(seekcb);
1138 cbd->seekcb = seekcb;
1139 SvREFCNT_inc(closecb);
1140 cbd->closecb = closecb;
1141 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1142 if (maxwrite > CBDATA_BUFSIZE)
1143 maxwrite = CBDATA_BUFSIZE;
1144 cbd->maxlength = maxwrite;
1145 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1154 unsigned char* data;
1158 tlength = io_slurp(ig, &data);
1160 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1165 i_set_image_file_limits(width, height, bytes)
1171 i_get_image_file_limits()
1173 int width, height, bytes;
1175 if (i_get_image_file_limits(&width, &height, &bytes)) {
1177 PUSHs(sv_2mortal(newSViv(width)));
1178 PUSHs(sv_2mortal(newSViv(height)));
1179 PUSHs(sv_2mortal(newSViv(bytes)));
1182 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1185 i_io_write(ig, data_sv)
1193 if (SvUTF8(data_sv)) {
1194 data_sv = sv_2mortal(newSVsv(data_sv));
1195 /* yes, we want this to croak() if the SV can't be downgraded */
1196 sv_utf8_downgrade(data_sv, FALSE);
1199 data = SvPV(data_sv, size);
1200 RETVAL = i_io_write(ig, data, size);
1205 i_io_read(ig, buffer_sv, size)
1214 croak("size negative in call to i_io_read()");
1215 /* prevent an undefined value warning if they supplied an
1217 Orginally conditional on !SvOK(), but this will prevent the
1218 downgrade from croaking */
1219 sv_setpvn(buffer_sv, "", 0);
1221 if (SvUTF8(buffer_sv))
1222 sv_utf8_downgrade(buffer_sv, FALSE);
1224 buffer = SvGROW(buffer_sv, size+1);
1225 result = i_io_read(ig, buffer, size);
1227 SvCUR_set(buffer_sv, result);
1228 *SvEND(buffer_sv) = '\0';
1229 SvPOK_only(buffer_sv);
1231 PUSHs(sv_2mortal(newSViv(result)));
1237 i_io_read2(ig, size)
1246 croak("size negative in call to i_io_read2()");
1247 buffer_sv = newSV(size);
1248 buffer = SvGROW(buffer_sv, size+1);
1249 result = i_io_read(ig, buffer, size);
1251 SvCUR_set(buffer_sv, result);
1252 *SvEND(buffer_sv) = '\0';
1253 SvPOK_only(buffer_sv);
1255 PUSHs(sv_2mortal(buffer_sv));
1259 SvREFCNT_dec(buffer_sv);
1263 i_io_seek(ig, position, whence)
1277 i_io_CLONE_SKIP(...)
1283 MODULE = Imager PACKAGE = Imager
1294 while( (item=i_format_list[i++]) != NULL ) {
1296 PUSHs(sv_2mortal(newSVpv(item,0)));
1309 i_img_empty_ch(im,x,y,ch)
1316 i_sametype(im, x, y)
1322 i_sametype_chans(im, x, y, channels)
1329 i_init_log(name_sv,level)
1333 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1335 i_init_log(name, level);
1338 i_log_entry(string,level)
1357 i_img_info(im,info);
1359 PUSHs(sv_2mortal(newSViv(info[0])));
1360 PUSHs(sv_2mortal(newSViv(info[1])));
1361 PUSHs(sv_2mortal(newSViv(info[2])));
1362 PUSHs(sv_2mortal(newSViv(info[3])));
1368 i_img_setmask(im,ch_mask)
1377 i_img_getchannels(im)
1386 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1394 i_img_get_height(im)
1399 i_img_is_monochrome(im)
1405 result = i_img_is_monochrome(im, &zero_is_white);
1407 if (GIMME_V == G_ARRAY) {
1410 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1419 i_line(im,x1,y1,x2,y2,val,endp)
1429 i_line_aa(im,x1,y1,x2,y2,val,endp)
1439 i_box(im,x1,y1,x2,y2,val)
1448 i_box_filled(im,x1,y1,x2,y2,val)
1457 i_box_cfill(im,x1,y1,x2,y2,fill)
1463 Imager::FillHandle fill
1466 i_arc(im,x,y,rad,d1,d2,val)
1476 i_arc_aa(im,x,y,rad,d1,d2,val)
1486 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1493 Imager::FillHandle fill
1496 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1503 Imager::FillHandle fill
1507 i_circle_aa(im,x,y,rad,val)
1515 i_circle_out(im,x,y,rad,val)
1523 i_circle_out_aa(im,x,y,rad,val)
1531 i_arc_out(im,x,y,rad,d1,d2,val)
1541 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1552 i_bezier_multi(im,xc,yc,val)
1565 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1566 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1567 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1568 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1569 av1=(AV*)SvRV(ST(1));
1570 av2=(AV*)SvRV(ST(2));
1571 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1573 x=mymalloc( len*sizeof(double) );
1574 y=mymalloc( len*sizeof(double) );
1575 for(i=0;i<len;i++) {
1576 sv1=(*(av_fetch(av1,i,0)));
1577 sv2=(*(av_fetch(av2,i,0)));
1578 x[i]=(double)SvNV(sv1);
1579 y[i]=(double)SvNV(sv2);
1581 i_bezier_multi(im,len,x,y,val);
1587 i_poly_aa(im,xc,yc,val)
1600 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1601 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1602 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1603 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1604 av1=(AV*)SvRV(ST(1));
1605 av2=(AV*)SvRV(ST(2));
1606 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1608 x=mymalloc( len*sizeof(double) );
1609 y=mymalloc( len*sizeof(double) );
1610 for(i=0;i<len;i++) {
1611 sv1=(*(av_fetch(av1,i,0)));
1612 sv2=(*(av_fetch(av2,i,0)));
1613 x[i]=(double)SvNV(sv1);
1614 y[i]=(double)SvNV(sv2);
1616 RETVAL = i_poly_aa(im,len,x,y,val);
1623 i_poly_aa_cfill(im,xc,yc,fill)
1625 Imager::FillHandle fill
1635 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1636 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1637 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1638 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1639 av1=(AV*)SvRV(ST(1));
1640 av2=(AV*)SvRV(ST(2));
1641 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1643 x=mymalloc( len*sizeof(double) );
1644 y=mymalloc( len*sizeof(double) );
1645 for(i=0;i<len;i++) {
1646 sv1=(*(av_fetch(av1,i,0)));
1647 sv2=(*(av_fetch(av2,i,0)));
1648 x[i]=(double)SvNV(sv1);
1649 y[i]=(double)SvNV(sv2);
1651 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1660 i_flood_fill(im,seedx,seedy,dcol)
1667 i_flood_cfill(im,seedx,seedy,fill)
1671 Imager::FillHandle fill
1674 i_flood_fill_border(im,seedx,seedy,dcol, border)
1679 Imager::Color border
1682 i_flood_cfill_border(im,seedx,seedy,fill, border)
1686 Imager::FillHandle fill
1687 Imager::Color border
1691 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1703 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1720 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1731 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1744 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)
1760 i_combine(src_av, channels_av = NULL)
1764 i_img **imgs = NULL;
1766 int *channels = NULL;
1771 in_count = av_len(src_av) + 1;
1773 imgs = mymalloc(sizeof(i_img*) * in_count);
1774 channels = mymalloc(sizeof(int) * in_count);
1775 for (i = 0; i < in_count; ++i) {
1776 psv = av_fetch(src_av, i, 0);
1777 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1780 croak("imgs must contain only images");
1782 tmp = SvIV((SV*)SvRV(*psv));
1783 imgs[i] = INT2PTR(i_img*, tmp);
1785 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1787 channels[i] = SvIV(*psv);
1794 RETVAL = i_combine(imgs, channels, in_count);
1801 i_flipxy(im, direction)
1806 i_rotate90(im, degrees)
1811 i_rotate_exact(im, amount, ...)
1815 i_color *backp = NULL;
1816 i_fcolor *fbackp = NULL;
1820 /* extract the bg colors if any */
1821 /* yes, this is kind of strange */
1822 for (i = 2; i < items; ++i) {
1824 if (sv_derived_from(sv1, "Imager::Color")) {
1825 IV tmp = SvIV((SV*)SvRV(sv1));
1826 backp = INT2PTR(i_color *, tmp);
1828 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1829 IV tmp = SvIV((SV*)SvRV(sv1));
1830 fbackp = INT2PTR(i_fcolor *, tmp);
1833 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1838 i_matrix_transform(im, xsize, ysize, matrix, ...)
1848 i_color *backp = NULL;
1849 i_fcolor *fbackp = NULL;
1851 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1852 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1853 av=(AV*)SvRV(ST(3));
1857 for (i = 0; i < len; ++i) {
1858 sv1=(*(av_fetch(av,i,0)));
1859 matrix[i] = SvNV(sv1);
1863 /* extract the bg colors if any */
1864 /* yes, this is kind of strange */
1865 for (i = 4; i < items; ++i) {
1867 if (sv_derived_from(sv1, "Imager::Color")) {
1868 IV tmp = SvIV((SV*)SvRV(sv1));
1869 backp = INT2PTR(i_color *, tmp);
1871 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1872 IV tmp = SvIV((SV*)SvRV(sv1));
1873 fbackp = INT2PTR(i_fcolor *, tmp);
1876 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1881 i_gaussian(im,stdev)
1886 i_unsharp_mask(im,stdev,scale)
1901 len = av_len(coef) + 1;
1902 c_coef=mymalloc( len * sizeof(double) );
1903 for(i = 0; i < len; i++) {
1904 sv1 = (*(av_fetch(coef, i, 0)));
1905 c_coef[i] = (double)SvNV(sv1);
1907 RETVAL = i_conv(im, c_coef, len);
1913 i_convert(src, avmain)
1925 outchan = av_len(avmain)+1;
1926 /* find the biggest */
1928 for (j=0; j < outchan; ++j) {
1929 temp = av_fetch(avmain, j, 0);
1930 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1931 avsub = (AV*)SvRV(*temp);
1932 len = av_len(avsub)+1;
1937 coeff = mymalloc(sizeof(double) * outchan * inchan);
1938 for (j = 0; j < outchan; ++j) {
1939 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1940 len = av_len(avsub)+1;
1941 for (i = 0; i < len; ++i) {
1942 temp = av_fetch(avsub, i, 0);
1944 coeff[i+j*inchan] = SvNV(*temp);
1946 coeff[i+j*inchan] = 0;
1949 coeff[i++ + j*inchan] = 0;
1951 RETVAL = i_convert(src, coeff, outchan, inchan);
1961 unsigned int mask = 0;
1967 unsigned char (*maps)[256];
1969 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1970 croak("i_map: parameter 2 must be an arrayref\n");
1971 avmain = (AV*)SvRV(ST(1));
1972 len = av_len(avmain)+1;
1973 if (im->channels < len) len = im->channels;
1975 maps = mymalloc( len * sizeof(unsigned char [256]) );
1977 for (j=0; j<len ; j++) {
1978 temp = av_fetch(avmain, j, 0);
1979 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1980 avsub = (AV*)SvRV(*temp);
1981 if(av_len(avsub) != 255) continue;
1983 for (i=0; i<256 ; i++) {
1985 temp = av_fetch(avsub, i, 0);
1986 val = temp ? SvIV(*temp) : 0;
1988 if (val>255) val = 255;
1993 i_map(im, maps, mask);
2004 i_img_diffd(im1,im2)
2009 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2019 _is_color_object(sv)
2023 RETVAL = SvOK(sv) && SvROK(sv) &&
2024 (sv_derived_from(sv, "Imager::Color")
2025 || sv_derived_from(sv, "Imager::Color::Float"));
2040 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2042 #define TT_DESTROY(handle) i_tt_destroy(handle)
2046 Imager::Font::TT handle
2056 MODULE = Imager PACKAGE = Imager
2060 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2061 Imager::Font::TT handle
2079 str = SvPV(str_sv, len);
2080 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2081 len, smooth, utf8, align);
2087 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2088 Imager::Font::TT handle
2106 str = SvPV(str_sv, len);
2107 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2108 smooth, utf8, align);
2114 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2115 Imager::Font::TT handle
2120 int cords[BOUNDING_BOX_COUNT],rc;
2129 str = SvPV(str_sv, len);
2130 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2132 for (i = 0; i < rc; ++i) {
2133 PUSHs(sv_2mortal(newSViv(cords[i])));
2138 i_tt_has_chars(handle, text_sv, utf8)
2139 Imager::Font::TT handle
2150 if (SvUTF8(text_sv))
2153 text = SvPV(text_sv, len);
2154 work = mymalloc(len);
2155 count = i_tt_has_chars(handle, text, len, utf8, work);
2156 if (GIMME_V == G_ARRAY) {
2158 for (i = 0; i < count; ++i) {
2159 PUSHs(sv_2mortal(newSViv(work[i])));
2164 PUSHs(sv_2mortal(newSVpv(work, count)));
2169 i_tt_dump_names(handle)
2170 Imager::Font::TT handle
2173 i_tt_face_name(handle)
2174 Imager::Font::TT handle
2179 len = i_tt_face_name(handle, name, sizeof(name));
2182 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2186 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2187 Imager::Font::TT handle
2198 if (SvUTF8(text_sv))
2201 text = SvPV(text_sv, work_len);
2206 ch = i_utf8_advance(&text, &len);
2208 i_push_error(0, "invalid UTF8 character");
2217 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2218 PUSHs(sv_2mortal(newSVpv(name, 0)));
2221 PUSHs(&PL_sv_undef);
2228 i_test_format_probe(ig, length)
2233 i_readpnm_wiol(ig, allow_incomplete)
2235 int allow_incomplete
2239 i_readpnm_multi_wiol(ig, allow_incomplete)
2241 int allow_incomplete
2247 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2250 for (i = 0; i < count; ++i) {
2251 SV *sv = sv_newmortal();
2252 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2259 i_writeppm_wiol(im, ig)
2268 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2277 i_writeraw_wiol(im,ig)
2282 i_writebmp_wiol(im,ig)
2287 i_readbmp_wiol(ig, allow_incomplete=0)
2289 int allow_incomplete
2293 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2302 idlen = SvCUR(ST(4));
2303 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2309 i_readtga_wiol(ig, length)
2317 i_scaleaxis(im,Value,Axis)
2323 i_scale_nn(im,scx,scy)
2329 i_scale_mixing(im, width, height)
2339 i_count_colors(im,maxc)
2344 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2349 unsigned int * col_usage = NULL;
2352 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2353 EXTEND(SP, col_cnt);
2354 for (i = 0; i < col_cnt; i++) {
2355 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2362 i_transform(im,opx,opy,parm)
2375 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2376 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2377 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2378 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2379 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2380 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2381 av=(AV*)SvRV(ST(1));
2383 opx=mymalloc( opxl*sizeof(int) );
2384 for(i=0;i<opxl;i++) {
2385 sv1=(*(av_fetch(av,i,0)));
2386 opx[i]=(int)SvIV(sv1);
2388 av=(AV*)SvRV(ST(2));
2390 opy=mymalloc( opyl*sizeof(int) );
2391 for(i=0;i<opyl;i++) {
2392 sv1=(*(av_fetch(av,i,0)));
2393 opy[i]=(int)SvIV(sv1);
2395 av=(AV*)SvRV(ST(3));
2396 parmlen=av_len(av)+1;
2397 parm=mymalloc( parmlen*sizeof(double) );
2398 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2399 sv1=(*(av_fetch(av,i,0)));
2400 parm[i]=(double)SvNV(sv1);
2402 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2406 ST(0) = sv_newmortal();
2407 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2408 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2411 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2436 in_imgs_count = av_len(av_in_imgs)+1;
2437 for (i = 0; i < in_imgs_count; ++i) {
2438 sv1 = *av_fetch(av_in_imgs, i, 0);
2439 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2440 croak("sv_in_img must contain only images");
2443 if (in_imgs_count > 0) {
2444 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2445 for (i = 0; i < in_imgs_count; ++i) {
2446 sv1 = *av_fetch(av_in_imgs,i,0);
2447 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2448 croak("Parameter 5 must contain only images");
2450 tmp = SvIV((SV*)SvRV(sv1));
2451 in_imgs[i] = INT2PTR(i_img*, tmp);
2455 /* no input images */
2458 /* default the output size from the first input if possible */
2460 width = SvIV(sv_width);
2461 else if (in_imgs_count)
2462 width = in_imgs[0]->xsize;
2464 croak("No output image width supplied");
2466 if (SvOK(sv_height))
2467 height = SvIV(sv_height);
2468 else if (in_imgs_count)
2469 height = in_imgs[0]->ysize;
2471 croak("No output image height supplied");
2473 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2474 if (ops_len % sizeof(struct rm_op))
2475 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2476 ops_count = ops_len / sizeof(struct rm_op);
2478 n_regs_count = av_len(av_n_regs)+1;
2479 n_regs = mymalloc(n_regs_count * sizeof(double));
2480 for (i = 0; i < n_regs_count; ++i) {
2481 sv1 = *av_fetch(av_n_regs,i,0);
2483 n_regs[i] = SvNV(sv1);
2485 c_regs_count = av_len(av_c_regs)+1;
2486 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2487 /* I don't bother initializing the colou?r registers */
2489 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2490 n_regs, n_regs_count,
2491 c_regs, c_regs_count, in_imgs, in_imgs_count);
2496 ST(0) = sv_newmortal();
2497 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2498 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2502 i_contrast(im,intensity)
2515 i_noise(im,amount,type)
2521 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2531 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2550 i_postlevels(im,levels)
2560 i_watermark(im,wmark,tx,ty,pixdiff)
2562 Imager::ImgRaw wmark
2569 i_autolevels(im,lsat,usat,skew)
2576 i_radnoise(im,xo,yo,rscale,ascale)
2584 i_turbnoise(im, xo, yo, scale)
2607 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2608 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2609 croak("i_gradgen: Second argument must be an array ref");
2610 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2611 croak("i_gradgen: Third argument must be an array ref");
2612 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2613 croak("i_gradgen: Fourth argument must be an array ref");
2614 axx = (AV *)SvRV(ST(1));
2615 ayy = (AV *)SvRV(ST(2));
2616 ac = (AV *)SvRV(ST(3));
2617 dmeasure = (int)SvIV(ST(4));
2619 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2620 num = num <= av_len(ac) ? num : av_len(ac);
2622 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2623 xo = mymalloc( sizeof(int) * num );
2624 yo = mymalloc( sizeof(int) * num );
2625 ival = mymalloc( sizeof(i_color) * num );
2626 for(i = 0; i<num; i++) {
2627 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2628 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2629 sv = *av_fetch(ac, i, 0);
2630 if ( !sv_derived_from(sv, "Imager::Color") ) {
2631 free(axx); free(ayy); free(ac);
2632 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2634 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2636 i_gradgen(im, num, xo, yo, ival, dmeasure);
2642 i_diff_image(im, im2, mindist=0)
2648 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2658 double ssample_param
2662 i_fountain_seg *segs;
2664 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2665 croak("i_fountain: argument 11 must be an array ref");
2667 asegs = (AV *)SvRV(ST(10));
2668 segs = load_fount_segs(aTHX_ asegs, &count);
2669 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2670 super_sample, ssample_param, count, segs);
2676 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2685 double ssample_param
2689 i_fountain_seg *segs;
2691 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2692 croak("i_fountain: argument 11 must be an array ref");
2694 asegs = (AV *)SvRV(ST(9));
2695 segs = load_fount_segs(aTHX_ asegs, &count);
2696 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2697 super_sample, ssample_param, count, segs);
2703 i_new_fill_opacity(other_fill, alpha_mult)
2704 Imager::FillHandle other_fill
2715 errors = i_errors();
2717 while (errors[i].msg) {
2719 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2720 if (!av_store(av, 0, sv)) {
2723 sv = newSViv(errors[i].code);
2724 if (!av_store(av, 1, sv)) {
2727 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2735 i_push_error(code, msg)
2740 i_nearest_color(im, ...)
2755 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2756 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2757 croak("i_nearest_color: Second argument must be an array ref");
2758 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2759 croak("i_nearest_color: Third argument must be an array ref");
2760 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2761 croak("i_nearest_color: Fourth argument must be an array ref");
2762 axx = (AV *)SvRV(ST(1));
2763 ayy = (AV *)SvRV(ST(2));
2764 ac = (AV *)SvRV(ST(3));
2765 dmeasure = (int)SvIV(ST(4));
2767 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2768 num = num <= av_len(ac) ? num : av_len(ac);
2770 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2771 xo = mymalloc( sizeof(int) * num );
2772 yo = mymalloc( sizeof(int) * num );
2773 ival = mymalloc( sizeof(i_color) * num );
2774 for(i = 0; i<num; i++) {
2775 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2776 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2777 sv = *av_fetch(ac, i, 0);
2778 if ( !sv_derived_from(sv, "Imager::Color") ) {
2779 free(axx); free(ayy); free(ac);
2780 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2782 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2784 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2798 rc=DSO_open(filename,&evstr);
2802 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2803 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2806 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2812 DSO_close(dso_handle)
2816 DSO_funclist(dso_handle_v)
2820 DSO_handle *dso_handle;
2821 func_ptr *functions;
2823 dso_handle=(DSO_handle*)dso_handle_v;
2824 functions = DSO_funclist(dso_handle);
2826 while( functions[i].name != NULL) {
2828 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2830 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2834 DSO_call(handle,func_index,hv)
2840 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2841 hv=(HV*)SvRV(ST(2));
2842 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2843 DSO_call( (DSO_handle *)handle,func_index,hv);
2846 i_get_pixel(im, x, y)
2853 color = (i_color *)mymalloc(sizeof(i_color));
2854 if (i_gpix(im, x, y, color) == 0) {
2855 RETVAL = NEWSV(0, 0);
2856 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2860 RETVAL = &PL_sv_undef;
2867 i_ppix(im, x, y, cl)
2874 i_img_pal_new(x, y, channels, maxpal)
2881 i_img_to_pal(src, quant)
2887 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2888 croak("i_img_to_pal: second argument must be a hash ref");
2889 hv = (HV *)SvRV(ST(1));
2890 memset(&quant, 0, sizeof(quant));
2892 quant.mc_size = 256;
2893 ip_handle_quant_opts(aTHX_ &quant, hv);
2894 RETVAL = i_img_to_pal(src, &quant);
2896 ip_copy_colors_back(aTHX_ hv, &quant);
2898 ip_cleanup_quant_opts(aTHX_ &quant);
2917 work = mymalloc((r-l) * sizeof(i_palidx));
2918 count = i_gpal(im, l, r, y, work);
2919 if (GIMME_V == G_ARRAY) {
2921 for (i = 0; i < count; ++i) {
2922 PUSHs(sv_2mortal(newSViv(work[i])));
2927 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
2932 if (GIMME_V != G_ARRAY) {
2934 PUSHs(&PL_sv_undef);
2939 i_ppal(im, l, y, ...)
2948 work = mymalloc(sizeof(i_palidx) * (items-3));
2949 for (i=0; i < items-3; ++i) {
2950 work[i] = SvIV(ST(i+3));
2952 validate_i_ppal(im, work, items - 3);
2953 RETVAL = i_ppal(im, l, l+items-3, y, work);
2963 i_ppal_p(im, l, y, data)
2969 i_palidx const *work;
2972 work = (i_palidx const *)SvPV(data, len);
2973 len /= sizeof(i_palidx);
2975 validate_i_ppal(im, work, len);
2976 RETVAL = i_ppal(im, l, l+len, y, work);
2985 i_addcolors(im, ...)
2993 croak("i_addcolors: no colors to add");
2994 colors = mymalloc((items-1) * sizeof(i_color));
2995 for (i=0; i < items-1; ++i) {
2996 if (sv_isobject(ST(i+1))
2997 && sv_derived_from(ST(i+1), "Imager::Color")) {
2998 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2999 colors[i] = *INT2PTR(i_color *, tmp);
3003 croak("i_addcolor: pixels must be Imager::Color objects");
3006 index = i_addcolors(im, colors, items-1);
3009 RETVAL = newSVpv("0 but true", 0);
3011 else if (index == -1) {
3012 RETVAL = &PL_sv_undef;
3015 RETVAL = newSViv(index);
3021 i_setcolors(im, index, ...)
3029 croak("i_setcolors: no colors to add");
3030 colors = mymalloc((items-2) * sizeof(i_color));
3031 for (i=0; i < items-2; ++i) {
3032 if (sv_isobject(ST(i+2))
3033 && sv_derived_from(ST(i+2), "Imager::Color")) {
3034 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3035 colors[i] = *INT2PTR(i_color *, tmp);
3039 croak("i_setcolors: pixels must be Imager::Color objects");
3042 RETVAL = i_setcolors(im, index, colors, items-2);
3048 i_getcolors(im, index, ...)
3057 croak("i_getcolors: too many arguments");
3059 count = SvIV(ST(2));
3061 croak("i_getcolors: count must be positive");
3062 colors = mymalloc(sizeof(i_color) * count);
3063 if (i_getcolors(im, index, colors, count)) {
3064 for (i = 0; i < count; ++i) {
3066 SV *sv = sv_newmortal();
3067 pv = mymalloc(sizeof(i_color));
3069 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3085 i_findcolor(im, color)
3091 if (i_findcolor(im, color, &index)) {
3092 RETVAL = newSViv(index);
3095 RETVAL = &PL_sv_undef;
3113 i_gsamp(im, l, r, y, ...)
3125 croak("No channel numbers supplied to g_samp()");
3127 chan_count = items - 4;
3128 chans = mymalloc(sizeof(int) * chan_count);
3129 for (i = 0; i < chan_count; ++i)
3130 chans[i] = SvIV(ST(i+4));
3131 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3132 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3134 if (GIMME_V == G_ARRAY) {
3136 for (i = 0; i < count; ++i)
3137 PUSHs(sv_2mortal(newSViv(data[i])));
3141 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3146 if (GIMME_V != G_ARRAY) {
3148 PUSHs(&PL_sv_undef);
3153 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3169 croak("No channel numbers supplied to g_samp()");
3171 chan_count = items - 7;
3172 chans = mymalloc(sizeof(int) * chan_count);
3173 for (i = 0; i < chan_count; ++i)
3174 chans[i] = SvIV(ST(i+7));
3175 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3176 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3178 for (i = 0; i < count; ++i) {
3179 av_store(target, i+offset, newSVuv(data[i]));
3191 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3209 if (SvOK(channels_sv)) {
3211 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3212 croak("channels is not an array ref");
3214 channels_av = (AV *)SvRV(channels_sv);
3215 chan_count = av_len(channels_av) + 1;
3216 if (chan_count < 1) {
3217 croak("i_psamp_bits: no channels provided");
3219 channels = mymalloc(sizeof(int) * chan_count);
3220 for (i = 0; i < chan_count; ++i)
3221 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3224 chan_count = im->channels;
3228 data_count = av_len(data_av) + 1;
3229 if (data_offset < 0) {
3230 croak("data_offset must by non-negative");
3232 if (data_offset > data_count) {
3233 croak("data_offset greater than number of samples supplied");
3235 if (pixel_count == -1 ||
3236 data_offset + pixel_count * chan_count > data_count) {
3237 pixel_count = (data_count - data_offset) / chan_count;
3240 data_used = pixel_count * chan_count;
3241 data = mymalloc(sizeof(unsigned) * data_count);
3242 for (i = 0; i < data_used; ++i)
3243 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3245 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3256 i_img_masked_new(targ, mask, x, y, w, h)
3266 if (!sv_isobject(ST(1))
3267 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3268 croak("i_img_masked_new: parameter 2 must undef or an image");
3270 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3274 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3279 i_plin(im, l, y, ...)
3290 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3291 /* supplied as a byte string */
3292 work = (i_color *)SvPV(ST(3), len);
3293 count = len / sizeof(i_color);
3294 if (count * sizeof(i_color) != len) {
3295 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3297 RETVAL = i_plin(im, l, l+count, y, work);
3300 work = mymalloc(sizeof(i_color) * (items-3));
3301 for (i=0; i < items-3; ++i) {
3302 if (sv_isobject(ST(i+3))
3303 && sv_derived_from(ST(i+3), "Imager::Color")) {
3304 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3305 work[i] = *INT2PTR(i_color *, tmp);
3309 croak("i_plin: pixels must be Imager::Color objects");
3312 RETVAL = i_plin(im, l, l+items-3, y, work);
3323 i_ppixf(im, x, y, cl)
3327 Imager::Color::Float cl
3330 i_gsampf(im, l, r, y, ...)
3342 croak("No channel numbers supplied to g_sampf()");
3344 chan_count = items - 4;
3345 chans = mymalloc(sizeof(int) * chan_count);
3346 for (i = 0; i < chan_count; ++i)
3347 chans[i] = SvIV(ST(i+4));
3348 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3349 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3351 if (GIMME_V == G_ARRAY) {
3353 for (i = 0; i < count; ++i)
3354 PUSHs(sv_2mortal(newSVnv(data[i])));
3358 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3363 if (GIMME_V != G_ARRAY) {
3365 PUSHs(&PL_sv_undef);
3370 i_plinf(im, l, y, ...)
3381 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3382 /* supplied as a byte string */
3383 work = (i_fcolor *)SvPV(ST(3), len);
3384 count = len / sizeof(i_fcolor);
3385 if (count * sizeof(i_fcolor) != len) {
3386 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3388 RETVAL = i_plinf(im, l, l+count, y, work);
3391 work = mymalloc(sizeof(i_fcolor) * (items-3));
3392 for (i=0; i < items-3; ++i) {
3393 if (sv_isobject(ST(i+3))
3394 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3395 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3396 work[i] = *INT2PTR(i_fcolor *, tmp);
3400 croak("i_plinf: pixels must be Imager::Color::Float objects");
3404 RETVAL = i_plinf(im, l, l+items-3, y, work);
3422 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3423 if (i_gpixf(im, x, y, color) == 0) {
3424 RETVAL = NEWSV(0,0);
3425 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3429 RETVAL = &PL_sv_undef;
3445 vals = mymalloc((r-l) * sizeof(i_color));
3446 memset(vals, 0, (r-l) * sizeof(i_color));
3447 count = i_glin(im, l, r, y, vals);
3448 if (GIMME_V == G_ARRAY) {
3450 for (i = 0; i < count; ++i) {
3452 i_color *col = mymalloc(sizeof(i_color));
3454 sv = sv_newmortal();
3455 sv_setref_pv(sv, "Imager::Color", (void *)col);
3461 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3467 i_glinf(im, l, r, y)
3477 for (i = 0; i < MAXCHANNELS; ++i)
3478 zero.channel[i] = 0;
3480 vals = mymalloc((r-l) * sizeof(i_fcolor));
3481 for (i = 0; i < r-l; ++i)
3483 count = i_glinf(im, l, r, y, vals);
3484 if (GIMME_V == G_ARRAY) {
3486 for (i = 0; i < count; ++i) {
3488 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3490 sv = sv_newmortal();
3491 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3497 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3503 i_img_16_new(x, y, ch)
3513 i_img_double_new(x, y, ch)
3519 i_tags_addn(im, name, code, idata)
3528 name = SvPV(ST(1), len);
3531 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3536 i_tags_add(im, name, code, data, idata)
3546 name = SvPV(ST(1), len);
3550 data = SvPV(ST(3), len);
3555 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3560 i_tags_find(im, name, start)
3567 if (i_tags_find(&im->tags, name, start, &entry)) {
3569 RETVAL = newSVpv("0 but true", 0);
3571 RETVAL = newSViv(entry);
3573 RETVAL = &PL_sv_undef;
3579 i_tags_findn(im, code, start)
3586 if (i_tags_findn(&im->tags, code, start, &entry)) {
3588 RETVAL = newSVpv("0 but true", 0);
3590 RETVAL = newSViv(entry);
3593 RETVAL = &PL_sv_undef;
3599 i_tags_delete(im, entry)
3603 RETVAL = i_tags_delete(&im->tags, entry);
3608 i_tags_delbyname(im, name)
3612 RETVAL = i_tags_delbyname(&im->tags, name);
3617 i_tags_delbycode(im, code)
3621 RETVAL = i_tags_delbycode(&im->tags, code);
3626 i_tags_get(im, index)
3630 if (index >= 0 && index < im->tags.count) {
3631 i_img_tag *entry = im->tags.tags + index;
3635 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3638 PUSHs(sv_2mortal(newSViv(entry->code)));
3641 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3644 PUSHs(sv_2mortal(newSViv(entry->idata)));
3649 i_tags_get_string(im, what_sv)
3653 char const *name = NULL;
3657 if (SvIOK(what_sv)) {
3658 code = SvIV(what_sv);
3662 name = SvPV_nolen(what_sv);
3665 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3667 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3674 RETVAL = im->tags.count;
3680 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3684 Imager::FillHandle fill
3687 IFILL_CLONE_SKIP(...)
3693 MODULE = Imager PACKAGE = Imager
3696 i_new_fill_solid(cl, combine)
3701 i_new_fill_solidf(cl, combine)
3702 Imager::Color::Float cl
3706 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3714 unsigned char *cust_hatch;
3718 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3722 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3727 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3728 Imager::Color::Float fg
3729 Imager::Color::Float bg
3735 unsigned char *cust_hatch;
3739 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3743 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3748 i_new_fill_image(src, matrix, xoff, yoff, combine)
3765 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3766 croak("i_new_fill_image: parameter must be an arrayref");
3767 av=(AV*)SvRV(ST(1));
3771 for (i = 0; i < len; ++i) {
3772 sv1=(*(av_fetch(av,i,0)));
3773 matrix[i] = SvNV(sv1);
3779 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3783 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3785 # this class is only exposed for testing
3788 i_int_hlines_testing()
3790 #if i_int_hlines_testing()
3792 Imager::Internal::Hlines
3793 i_int_hlines_new(start_y, count_y, start_x, count_x)
3799 Imager::Internal::Hlines
3800 i_int_hlines_new_img(im)
3804 i_int_hlines_add(hlines, y, minx, width)
3805 Imager::Internal::Hlines hlines
3811 i_int_hlines_DESTROY(hlines)
3812 Imager::Internal::Hlines hlines
3815 i_int_hlines_dump(hlines)
3816 Imager::Internal::Hlines hlines
3819 i_int_hlines_CLONE_SKIP(cls)
3825 PERL_SET_GLOBAL_CALLBACKS;
3826 PERL_PL_SET_GLOBAL_CALLBACKS;