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_filledf(im,x1,y1,x2,y2,val)
1463 Imager::Color::Float val
1466 i_box_cfill(im,x1,y1,x2,y2,fill)
1472 Imager::FillHandle fill
1475 i_arc(im,x,y,rad,d1,d2,val)
1485 i_arc_aa(im,x,y,rad,d1,d2,val)
1495 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1502 Imager::FillHandle fill
1505 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1512 Imager::FillHandle fill
1516 i_circle_aa(im,x,y,rad,val)
1524 i_circle_out(im,x,y,rad,val)
1532 i_circle_out_aa(im,x,y,rad,val)
1540 i_arc_out(im,x,y,rad,d1,d2,val)
1550 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1561 i_bezier_multi(im,xc,yc,val)
1574 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1575 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1576 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1577 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1578 av1=(AV*)SvRV(ST(1));
1579 av2=(AV*)SvRV(ST(2));
1580 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1582 x=mymalloc( len*sizeof(double) );
1583 y=mymalloc( len*sizeof(double) );
1584 for(i=0;i<len;i++) {
1585 sv1=(*(av_fetch(av1,i,0)));
1586 sv2=(*(av_fetch(av2,i,0)));
1587 x[i]=(double)SvNV(sv1);
1588 y[i]=(double)SvNV(sv2);
1590 i_bezier_multi(im,len,x,y,val);
1596 i_poly_aa(im,xc,yc,val)
1609 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1610 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1611 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1612 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1613 av1=(AV*)SvRV(ST(1));
1614 av2=(AV*)SvRV(ST(2));
1615 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1617 x=mymalloc( len*sizeof(double) );
1618 y=mymalloc( len*sizeof(double) );
1619 for(i=0;i<len;i++) {
1620 sv1=(*(av_fetch(av1,i,0)));
1621 sv2=(*(av_fetch(av2,i,0)));
1622 x[i]=(double)SvNV(sv1);
1623 y[i]=(double)SvNV(sv2);
1625 RETVAL = i_poly_aa(im,len,x,y,val);
1632 i_poly_aa_cfill(im,xc,yc,fill)
1634 Imager::FillHandle fill
1644 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1645 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1646 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1647 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1648 av1=(AV*)SvRV(ST(1));
1649 av2=(AV*)SvRV(ST(2));
1650 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1652 x=mymalloc( len*sizeof(double) );
1653 y=mymalloc( len*sizeof(double) );
1654 for(i=0;i<len;i++) {
1655 sv1=(*(av_fetch(av1,i,0)));
1656 sv2=(*(av_fetch(av2,i,0)));
1657 x[i]=(double)SvNV(sv1);
1658 y[i]=(double)SvNV(sv2);
1660 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1669 i_flood_fill(im,seedx,seedy,dcol)
1676 i_flood_cfill(im,seedx,seedy,fill)
1680 Imager::FillHandle fill
1683 i_flood_fill_border(im,seedx,seedy,dcol, border)
1688 Imager::Color border
1691 i_flood_cfill_border(im,seedx,seedy,fill, border)
1695 Imager::FillHandle fill
1696 Imager::Color border
1700 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1712 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1729 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1740 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1753 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)
1769 i_combine(src_av, channels_av = NULL)
1773 i_img **imgs = NULL;
1775 int *channels = NULL;
1780 in_count = av_len(src_av) + 1;
1782 imgs = mymalloc(sizeof(i_img*) * in_count);
1783 channels = mymalloc(sizeof(int) * in_count);
1784 for (i = 0; i < in_count; ++i) {
1785 psv = av_fetch(src_av, i, 0);
1786 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1789 croak("imgs must contain only images");
1791 tmp = SvIV((SV*)SvRV(*psv));
1792 imgs[i] = INT2PTR(i_img*, tmp);
1794 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1796 channels[i] = SvIV(*psv);
1803 RETVAL = i_combine(imgs, channels, in_count);
1810 i_flipxy(im, direction)
1815 i_rotate90(im, degrees)
1820 i_rotate_exact(im, amount, ...)
1824 i_color *backp = NULL;
1825 i_fcolor *fbackp = NULL;
1829 /* extract the bg colors if any */
1830 /* yes, this is kind of strange */
1831 for (i = 2; i < items; ++i) {
1833 if (sv_derived_from(sv1, "Imager::Color")) {
1834 IV tmp = SvIV((SV*)SvRV(sv1));
1835 backp = INT2PTR(i_color *, tmp);
1837 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1838 IV tmp = SvIV((SV*)SvRV(sv1));
1839 fbackp = INT2PTR(i_fcolor *, tmp);
1842 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1847 i_matrix_transform(im, xsize, ysize, matrix, ...)
1857 i_color *backp = NULL;
1858 i_fcolor *fbackp = NULL;
1860 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1861 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1862 av=(AV*)SvRV(ST(3));
1866 for (i = 0; i < len; ++i) {
1867 sv1=(*(av_fetch(av,i,0)));
1868 matrix[i] = SvNV(sv1);
1872 /* extract the bg colors if any */
1873 /* yes, this is kind of strange */
1874 for (i = 4; i < items; ++i) {
1876 if (sv_derived_from(sv1, "Imager::Color")) {
1877 IV tmp = SvIV((SV*)SvRV(sv1));
1878 backp = INT2PTR(i_color *, tmp);
1880 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1881 IV tmp = SvIV((SV*)SvRV(sv1));
1882 fbackp = INT2PTR(i_fcolor *, tmp);
1885 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1890 i_gaussian(im,stdev)
1895 i_unsharp_mask(im,stdev,scale)
1910 len = av_len(coef) + 1;
1911 c_coef=mymalloc( len * sizeof(double) );
1912 for(i = 0; i < len; i++) {
1913 sv1 = (*(av_fetch(coef, i, 0)));
1914 c_coef[i] = (double)SvNV(sv1);
1916 RETVAL = i_conv(im, c_coef, len);
1922 i_convert(src, avmain)
1934 outchan = av_len(avmain)+1;
1935 /* find the biggest */
1937 for (j=0; j < outchan; ++j) {
1938 temp = av_fetch(avmain, j, 0);
1939 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1940 avsub = (AV*)SvRV(*temp);
1941 len = av_len(avsub)+1;
1946 coeff = mymalloc(sizeof(double) * outchan * inchan);
1947 for (j = 0; j < outchan; ++j) {
1948 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1949 len = av_len(avsub)+1;
1950 for (i = 0; i < len; ++i) {
1951 temp = av_fetch(avsub, i, 0);
1953 coeff[i+j*inchan] = SvNV(*temp);
1955 coeff[i+j*inchan] = 0;
1958 coeff[i++ + j*inchan] = 0;
1960 RETVAL = i_convert(src, coeff, outchan, inchan);
1970 unsigned int mask = 0;
1976 unsigned char (*maps)[256];
1978 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1979 croak("i_map: parameter 2 must be an arrayref\n");
1980 avmain = (AV*)SvRV(ST(1));
1981 len = av_len(avmain)+1;
1982 if (im->channels < len) len = im->channels;
1984 maps = mymalloc( len * sizeof(unsigned char [256]) );
1986 for (j=0; j<len ; j++) {
1987 temp = av_fetch(avmain, j, 0);
1988 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1989 avsub = (AV*)SvRV(*temp);
1990 if(av_len(avsub) != 255) continue;
1992 for (i=0; i<256 ; i++) {
1994 temp = av_fetch(avsub, i, 0);
1995 val = temp ? SvIV(*temp) : 0;
1997 if (val>255) val = 255;
2002 i_map(im, maps, mask);
2013 i_img_diffd(im1,im2)
2018 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2028 _is_color_object(sv)
2032 RETVAL = SvOK(sv) && SvROK(sv) &&
2033 (sv_derived_from(sv, "Imager::Color")
2034 || sv_derived_from(sv, "Imager::Color::Float"));
2049 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2051 #define TT_DESTROY(handle) i_tt_destroy(handle)
2055 Imager::Font::TT handle
2065 MODULE = Imager PACKAGE = Imager
2069 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2070 Imager::Font::TT handle
2088 str = SvPV(str_sv, len);
2089 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2090 len, smooth, utf8, align);
2096 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2097 Imager::Font::TT handle
2115 str = SvPV(str_sv, len);
2116 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2117 smooth, utf8, align);
2123 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2124 Imager::Font::TT handle
2129 int cords[BOUNDING_BOX_COUNT],rc;
2138 str = SvPV(str_sv, len);
2139 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2141 for (i = 0; i < rc; ++i) {
2142 PUSHs(sv_2mortal(newSViv(cords[i])));
2147 i_tt_has_chars(handle, text_sv, utf8)
2148 Imager::Font::TT handle
2159 if (SvUTF8(text_sv))
2162 text = SvPV(text_sv, len);
2163 work = mymalloc(len);
2164 count = i_tt_has_chars(handle, text, len, utf8, work);
2165 if (GIMME_V == G_ARRAY) {
2167 for (i = 0; i < count; ++i) {
2168 PUSHs(sv_2mortal(newSViv(work[i])));
2173 PUSHs(sv_2mortal(newSVpv(work, count)));
2178 i_tt_dump_names(handle)
2179 Imager::Font::TT handle
2182 i_tt_face_name(handle)
2183 Imager::Font::TT handle
2188 len = i_tt_face_name(handle, name, sizeof(name));
2191 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2195 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2196 Imager::Font::TT handle
2207 if (SvUTF8(text_sv))
2210 text = SvPV(text_sv, work_len);
2215 ch = i_utf8_advance(&text, &len);
2217 i_push_error(0, "invalid UTF8 character");
2226 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2227 PUSHs(sv_2mortal(newSVpv(name, 0)));
2230 PUSHs(&PL_sv_undef);
2237 i_test_format_probe(ig, length)
2242 i_readpnm_wiol(ig, allow_incomplete)
2244 int allow_incomplete
2248 i_readpnm_multi_wiol(ig, allow_incomplete)
2250 int allow_incomplete
2256 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2259 for (i = 0; i < count; ++i) {
2260 SV *sv = sv_newmortal();
2261 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2268 i_writeppm_wiol(im, ig)
2277 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2286 i_writeraw_wiol(im,ig)
2291 i_writebmp_wiol(im,ig)
2296 i_readbmp_wiol(ig, allow_incomplete=0)
2298 int allow_incomplete
2302 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2311 idlen = SvCUR(ST(4));
2312 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2318 i_readtga_wiol(ig, length)
2326 i_scaleaxis(im,Value,Axis)
2332 i_scale_nn(im,scx,scy)
2338 i_scale_mixing(im, width, height)
2348 i_count_colors(im,maxc)
2353 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2358 unsigned int * col_usage = NULL;
2361 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2362 EXTEND(SP, col_cnt);
2363 for (i = 0; i < col_cnt; i++) {
2364 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2371 i_transform(im,opx,opy,parm)
2384 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2385 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2386 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2387 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2388 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2389 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2390 av=(AV*)SvRV(ST(1));
2392 opx=mymalloc( opxl*sizeof(int) );
2393 for(i=0;i<opxl;i++) {
2394 sv1=(*(av_fetch(av,i,0)));
2395 opx[i]=(int)SvIV(sv1);
2397 av=(AV*)SvRV(ST(2));
2399 opy=mymalloc( opyl*sizeof(int) );
2400 for(i=0;i<opyl;i++) {
2401 sv1=(*(av_fetch(av,i,0)));
2402 opy[i]=(int)SvIV(sv1);
2404 av=(AV*)SvRV(ST(3));
2405 parmlen=av_len(av)+1;
2406 parm=mymalloc( parmlen*sizeof(double) );
2407 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2408 sv1=(*(av_fetch(av,i,0)));
2409 parm[i]=(double)SvNV(sv1);
2411 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2415 ST(0) = sv_newmortal();
2416 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2417 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2420 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2445 in_imgs_count = av_len(av_in_imgs)+1;
2446 for (i = 0; i < in_imgs_count; ++i) {
2447 sv1 = *av_fetch(av_in_imgs, i, 0);
2448 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2449 croak("sv_in_img must contain only images");
2452 if (in_imgs_count > 0) {
2453 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2454 for (i = 0; i < in_imgs_count; ++i) {
2455 sv1 = *av_fetch(av_in_imgs,i,0);
2456 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2457 croak("Parameter 5 must contain only images");
2459 tmp = SvIV((SV*)SvRV(sv1));
2460 in_imgs[i] = INT2PTR(i_img*, tmp);
2464 /* no input images */
2467 /* default the output size from the first input if possible */
2469 width = SvIV(sv_width);
2470 else if (in_imgs_count)
2471 width = in_imgs[0]->xsize;
2473 croak("No output image width supplied");
2475 if (SvOK(sv_height))
2476 height = SvIV(sv_height);
2477 else if (in_imgs_count)
2478 height = in_imgs[0]->ysize;
2480 croak("No output image height supplied");
2482 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2483 if (ops_len % sizeof(struct rm_op))
2484 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2485 ops_count = ops_len / sizeof(struct rm_op);
2487 n_regs_count = av_len(av_n_regs)+1;
2488 n_regs = mymalloc(n_regs_count * sizeof(double));
2489 for (i = 0; i < n_regs_count; ++i) {
2490 sv1 = *av_fetch(av_n_regs,i,0);
2492 n_regs[i] = SvNV(sv1);
2494 c_regs_count = av_len(av_c_regs)+1;
2495 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2496 /* I don't bother initializing the colou?r registers */
2498 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2499 n_regs, n_regs_count,
2500 c_regs, c_regs_count, in_imgs, in_imgs_count);
2505 ST(0) = sv_newmortal();
2506 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2507 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2511 i_contrast(im,intensity)
2524 i_noise(im,amount,type)
2530 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2540 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2559 i_postlevels(im,levels)
2569 i_watermark(im,wmark,tx,ty,pixdiff)
2571 Imager::ImgRaw wmark
2578 i_autolevels(im,lsat,usat,skew)
2585 i_radnoise(im,xo,yo,rscale,ascale)
2593 i_turbnoise(im, xo, yo, scale)
2616 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2617 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2618 croak("i_gradgen: Second argument must be an array ref");
2619 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2620 croak("i_gradgen: Third argument must be an array ref");
2621 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2622 croak("i_gradgen: Fourth argument must be an array ref");
2623 axx = (AV *)SvRV(ST(1));
2624 ayy = (AV *)SvRV(ST(2));
2625 ac = (AV *)SvRV(ST(3));
2626 dmeasure = (int)SvIV(ST(4));
2628 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2629 num = num <= av_len(ac) ? num : av_len(ac);
2631 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2632 xo = mymalloc( sizeof(int) * num );
2633 yo = mymalloc( sizeof(int) * num );
2634 ival = mymalloc( sizeof(i_color) * num );
2635 for(i = 0; i<num; i++) {
2636 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2637 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2638 sv = *av_fetch(ac, i, 0);
2639 if ( !sv_derived_from(sv, "Imager::Color") ) {
2640 free(axx); free(ayy); free(ac);
2641 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2643 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2645 i_gradgen(im, num, xo, yo, ival, dmeasure);
2651 i_diff_image(im, im2, mindist=0)
2657 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2667 double ssample_param
2671 i_fountain_seg *segs;
2673 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2674 croak("i_fountain: argument 11 must be an array ref");
2676 asegs = (AV *)SvRV(ST(10));
2677 segs = load_fount_segs(aTHX_ asegs, &count);
2678 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2679 super_sample, ssample_param, count, segs);
2685 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2694 double ssample_param
2698 i_fountain_seg *segs;
2700 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2701 croak("i_fountain: argument 11 must be an array ref");
2703 asegs = (AV *)SvRV(ST(9));
2704 segs = load_fount_segs(aTHX_ asegs, &count);
2705 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2706 super_sample, ssample_param, count, segs);
2712 i_new_fill_opacity(other_fill, alpha_mult)
2713 Imager::FillHandle other_fill
2724 errors = i_errors();
2726 while (errors[i].msg) {
2728 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2729 if (!av_store(av, 0, sv)) {
2732 sv = newSViv(errors[i].code);
2733 if (!av_store(av, 1, sv)) {
2736 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2744 i_push_error(code, msg)
2749 i_nearest_color(im, ...)
2764 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2765 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2766 croak("i_nearest_color: Second argument must be an array ref");
2767 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2768 croak("i_nearest_color: Third argument must be an array ref");
2769 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2770 croak("i_nearest_color: Fourth argument must be an array ref");
2771 axx = (AV *)SvRV(ST(1));
2772 ayy = (AV *)SvRV(ST(2));
2773 ac = (AV *)SvRV(ST(3));
2774 dmeasure = (int)SvIV(ST(4));
2776 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2777 num = num <= av_len(ac) ? num : av_len(ac);
2779 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2780 xo = mymalloc( sizeof(int) * num );
2781 yo = mymalloc( sizeof(int) * num );
2782 ival = mymalloc( sizeof(i_color) * num );
2783 for(i = 0; i<num; i++) {
2784 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2785 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2786 sv = *av_fetch(ac, i, 0);
2787 if ( !sv_derived_from(sv, "Imager::Color") ) {
2788 free(axx); free(ayy); free(ac);
2789 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2791 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2793 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2807 rc=DSO_open(filename,&evstr);
2811 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2812 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2815 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2821 DSO_close(dso_handle)
2825 DSO_funclist(dso_handle_v)
2829 DSO_handle *dso_handle;
2830 func_ptr *functions;
2832 dso_handle=(DSO_handle*)dso_handle_v;
2833 functions = DSO_funclist(dso_handle);
2835 while( functions[i].name != NULL) {
2837 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2839 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2843 DSO_call(handle,func_index,hv)
2849 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2850 hv=(HV*)SvRV(ST(2));
2851 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2852 DSO_call( (DSO_handle *)handle,func_index,hv);
2855 i_get_pixel(im, x, y)
2862 color = (i_color *)mymalloc(sizeof(i_color));
2863 if (i_gpix(im, x, y, color) == 0) {
2864 RETVAL = NEWSV(0, 0);
2865 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2869 RETVAL = &PL_sv_undef;
2876 i_ppix(im, x, y, cl)
2883 i_img_pal_new(x, y, channels, maxpal)
2890 i_img_to_pal(src, quant)
2896 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2897 croak("i_img_to_pal: second argument must be a hash ref");
2898 hv = (HV *)SvRV(ST(1));
2899 memset(&quant, 0, sizeof(quant));
2901 quant.mc_size = 256;
2902 ip_handle_quant_opts(aTHX_ &quant, hv);
2903 RETVAL = i_img_to_pal(src, &quant);
2905 ip_copy_colors_back(aTHX_ hv, &quant);
2907 ip_cleanup_quant_opts(aTHX_ &quant);
2926 work = mymalloc((r-l) * sizeof(i_palidx));
2927 count = i_gpal(im, l, r, y, work);
2928 if (GIMME_V == G_ARRAY) {
2930 for (i = 0; i < count; ++i) {
2931 PUSHs(sv_2mortal(newSViv(work[i])));
2936 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
2941 if (GIMME_V != G_ARRAY) {
2943 PUSHs(&PL_sv_undef);
2948 i_ppal(im, l, y, ...)
2957 work = mymalloc(sizeof(i_palidx) * (items-3));
2958 for (i=0; i < items-3; ++i) {
2959 work[i] = SvIV(ST(i+3));
2961 validate_i_ppal(im, work, items - 3);
2962 RETVAL = i_ppal(im, l, l+items-3, y, work);
2972 i_ppal_p(im, l, y, data)
2978 i_palidx const *work;
2981 work = (i_palidx const *)SvPV(data, len);
2982 len /= sizeof(i_palidx);
2984 validate_i_ppal(im, work, len);
2985 RETVAL = i_ppal(im, l, l+len, y, work);
2994 i_addcolors(im, ...)
3002 croak("i_addcolors: no colors to add");
3003 colors = mymalloc((items-1) * sizeof(i_color));
3004 for (i=0; i < items-1; ++i) {
3005 if (sv_isobject(ST(i+1))
3006 && sv_derived_from(ST(i+1), "Imager::Color")) {
3007 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3008 colors[i] = *INT2PTR(i_color *, tmp);
3012 croak("i_addcolor: pixels must be Imager::Color objects");
3015 index = i_addcolors(im, colors, items-1);
3018 RETVAL = newSVpv("0 but true", 0);
3020 else if (index == -1) {
3021 RETVAL = &PL_sv_undef;
3024 RETVAL = newSViv(index);
3030 i_setcolors(im, index, ...)
3038 croak("i_setcolors: no colors to add");
3039 colors = mymalloc((items-2) * sizeof(i_color));
3040 for (i=0; i < items-2; ++i) {
3041 if (sv_isobject(ST(i+2))
3042 && sv_derived_from(ST(i+2), "Imager::Color")) {
3043 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3044 colors[i] = *INT2PTR(i_color *, tmp);
3048 croak("i_setcolors: pixels must be Imager::Color objects");
3051 RETVAL = i_setcolors(im, index, colors, items-2);
3057 i_getcolors(im, index, ...)
3066 croak("i_getcolors: too many arguments");
3068 count = SvIV(ST(2));
3070 croak("i_getcolors: count must be positive");
3071 colors = mymalloc(sizeof(i_color) * count);
3072 if (i_getcolors(im, index, colors, count)) {
3073 for (i = 0; i < count; ++i) {
3075 SV *sv = sv_newmortal();
3076 pv = mymalloc(sizeof(i_color));
3078 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3094 i_findcolor(im, color)
3100 if (i_findcolor(im, color, &index)) {
3101 RETVAL = newSViv(index);
3104 RETVAL = &PL_sv_undef;
3122 i_gsamp(im, l, r, y, ...)
3134 croak("No channel numbers supplied to g_samp()");
3136 chan_count = items - 4;
3137 chans = mymalloc(sizeof(int) * chan_count);
3138 for (i = 0; i < chan_count; ++i)
3139 chans[i] = SvIV(ST(i+4));
3140 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3141 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3143 if (GIMME_V == G_ARRAY) {
3145 for (i = 0; i < count; ++i)
3146 PUSHs(sv_2mortal(newSViv(data[i])));
3150 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3155 if (GIMME_V != G_ARRAY) {
3157 PUSHs(&PL_sv_undef);
3162 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3178 croak("No channel numbers supplied to g_samp()");
3180 chan_count = items - 7;
3181 chans = mymalloc(sizeof(int) * chan_count);
3182 for (i = 0; i < chan_count; ++i)
3183 chans[i] = SvIV(ST(i+7));
3184 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3185 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3187 for (i = 0; i < count; ++i) {
3188 av_store(target, i+offset, newSVuv(data[i]));
3200 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3218 if (SvOK(channels_sv)) {
3220 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3221 croak("channels is not an array ref");
3223 channels_av = (AV *)SvRV(channels_sv);
3224 chan_count = av_len(channels_av) + 1;
3225 if (chan_count < 1) {
3226 croak("i_psamp_bits: no channels provided");
3228 channels = mymalloc(sizeof(int) * chan_count);
3229 for (i = 0; i < chan_count; ++i)
3230 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3233 chan_count = im->channels;
3237 data_count = av_len(data_av) + 1;
3238 if (data_offset < 0) {
3239 croak("data_offset must by non-negative");
3241 if (data_offset > data_count) {
3242 croak("data_offset greater than number of samples supplied");
3244 if (pixel_count == -1 ||
3245 data_offset + pixel_count * chan_count > data_count) {
3246 pixel_count = (data_count - data_offset) / chan_count;
3249 data_used = pixel_count * chan_count;
3250 data = mymalloc(sizeof(unsigned) * data_count);
3251 for (i = 0; i < data_used; ++i)
3252 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3254 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3265 i_img_masked_new(targ, mask, x, y, w, h)
3275 if (!sv_isobject(ST(1))
3276 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3277 croak("i_img_masked_new: parameter 2 must undef or an image");
3279 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3283 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3288 i_plin(im, l, y, ...)
3299 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3300 /* supplied as a byte string */
3301 work = (i_color *)SvPV(ST(3), len);
3302 count = len / sizeof(i_color);
3303 if (count * sizeof(i_color) != len) {
3304 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3306 RETVAL = i_plin(im, l, l+count, y, work);
3309 work = mymalloc(sizeof(i_color) * (items-3));
3310 for (i=0; i < items-3; ++i) {
3311 if (sv_isobject(ST(i+3))
3312 && sv_derived_from(ST(i+3), "Imager::Color")) {
3313 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3314 work[i] = *INT2PTR(i_color *, tmp);
3318 croak("i_plin: pixels must be Imager::Color objects");
3321 RETVAL = i_plin(im, l, l+items-3, y, work);
3332 i_ppixf(im, x, y, cl)
3336 Imager::Color::Float cl
3339 i_gsampf(im, l, r, y, ...)
3351 croak("No channel numbers supplied to g_sampf()");
3353 chan_count = items - 4;
3354 chans = mymalloc(sizeof(int) * chan_count);
3355 for (i = 0; i < chan_count; ++i)
3356 chans[i] = SvIV(ST(i+4));
3357 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3358 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3360 if (GIMME_V == G_ARRAY) {
3362 for (i = 0; i < count; ++i)
3363 PUSHs(sv_2mortal(newSVnv(data[i])));
3367 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3372 if (GIMME_V != G_ARRAY) {
3374 PUSHs(&PL_sv_undef);
3379 i_plinf(im, l, y, ...)
3390 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3391 /* supplied as a byte string */
3392 work = (i_fcolor *)SvPV(ST(3), len);
3393 count = len / sizeof(i_fcolor);
3394 if (count * sizeof(i_fcolor) != len) {
3395 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3397 RETVAL = i_plinf(im, l, l+count, y, work);
3400 work = mymalloc(sizeof(i_fcolor) * (items-3));
3401 for (i=0; i < items-3; ++i) {
3402 if (sv_isobject(ST(i+3))
3403 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3404 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3405 work[i] = *INT2PTR(i_fcolor *, tmp);
3409 croak("i_plinf: pixels must be Imager::Color::Float objects");
3413 RETVAL = i_plinf(im, l, l+items-3, y, work);
3431 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3432 if (i_gpixf(im, x, y, color) == 0) {
3433 RETVAL = NEWSV(0,0);
3434 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3438 RETVAL = &PL_sv_undef;
3454 vals = mymalloc((r-l) * sizeof(i_color));
3455 memset(vals, 0, (r-l) * sizeof(i_color));
3456 count = i_glin(im, l, r, y, vals);
3457 if (GIMME_V == G_ARRAY) {
3459 for (i = 0; i < count; ++i) {
3461 i_color *col = mymalloc(sizeof(i_color));
3463 sv = sv_newmortal();
3464 sv_setref_pv(sv, "Imager::Color", (void *)col);
3470 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3476 i_glinf(im, l, r, y)
3486 for (i = 0; i < MAXCHANNELS; ++i)
3487 zero.channel[i] = 0;
3489 vals = mymalloc((r-l) * sizeof(i_fcolor));
3490 for (i = 0; i < r-l; ++i)
3492 count = i_glinf(im, l, r, y, vals);
3493 if (GIMME_V == G_ARRAY) {
3495 for (i = 0; i < count; ++i) {
3497 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3499 sv = sv_newmortal();
3500 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3506 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3512 i_img_16_new(x, y, ch)
3522 i_img_double_new(x, y, ch)
3528 i_tags_addn(im, name, code, idata)
3537 name = SvPV(ST(1), len);
3540 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3545 i_tags_add(im, name, code, data, idata)
3555 name = SvPV(ST(1), len);
3559 data = SvPV(ST(3), len);
3564 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3569 i_tags_find(im, name, start)
3576 if (i_tags_find(&im->tags, name, start, &entry)) {
3578 RETVAL = newSVpv("0 but true", 0);
3580 RETVAL = newSViv(entry);
3582 RETVAL = &PL_sv_undef;
3588 i_tags_findn(im, code, start)
3595 if (i_tags_findn(&im->tags, code, start, &entry)) {
3597 RETVAL = newSVpv("0 but true", 0);
3599 RETVAL = newSViv(entry);
3602 RETVAL = &PL_sv_undef;
3608 i_tags_delete(im, entry)
3612 RETVAL = i_tags_delete(&im->tags, entry);
3617 i_tags_delbyname(im, name)
3621 RETVAL = i_tags_delbyname(&im->tags, name);
3626 i_tags_delbycode(im, code)
3630 RETVAL = i_tags_delbycode(&im->tags, code);
3635 i_tags_get(im, index)
3639 if (index >= 0 && index < im->tags.count) {
3640 i_img_tag *entry = im->tags.tags + index;
3644 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3647 PUSHs(sv_2mortal(newSViv(entry->code)));
3650 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3653 PUSHs(sv_2mortal(newSViv(entry->idata)));
3658 i_tags_get_string(im, what_sv)
3662 char const *name = NULL;
3666 if (SvIOK(what_sv)) {
3667 code = SvIV(what_sv);
3671 name = SvPV_nolen(what_sv);
3674 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3676 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3683 RETVAL = im->tags.count;
3689 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3693 Imager::FillHandle fill
3696 IFILL_CLONE_SKIP(...)
3702 MODULE = Imager PACKAGE = Imager
3705 i_new_fill_solid(cl, combine)
3710 i_new_fill_solidf(cl, combine)
3711 Imager::Color::Float cl
3715 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3723 unsigned char *cust_hatch;
3727 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3731 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3736 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3737 Imager::Color::Float fg
3738 Imager::Color::Float bg
3744 unsigned char *cust_hatch;
3748 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3752 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3757 i_new_fill_image(src, matrix, xoff, yoff, combine)
3774 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3775 croak("i_new_fill_image: parameter must be an arrayref");
3776 av=(AV*)SvRV(ST(1));
3780 for (i = 0; i < len; ++i) {
3781 sv1=(*(av_fetch(av,i,0)));
3782 matrix[i] = SvNV(sv1);
3788 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3792 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3794 # this class is only exposed for testing
3797 i_int_hlines_testing()
3799 #if i_int_hlines_testing()
3801 Imager::Internal::Hlines
3802 i_int_hlines_new(start_y, count_y, start_x, count_x)
3808 Imager::Internal::Hlines
3809 i_int_hlines_new_img(im)
3813 i_int_hlines_add(hlines, y, minx, width)
3814 Imager::Internal::Hlines hlines
3820 i_int_hlines_DESTROY(hlines)
3821 Imager::Internal::Hlines hlines
3824 i_int_hlines_dump(hlines)
3825 Imager::Internal::Hlines hlines
3828 i_int_hlines_CLONE_SKIP(cls)
3834 PERL_SET_GLOBAL_CALLBACKS;
3835 PERL_PL_SET_GLOBAL_CALLBACKS;