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"
24 #if i_int_hlines_testing()
30 /* These functions are all shared - then comes platform dependant code */
31 static int getstr(void *hv_t,char *key,char **store) {
36 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
38 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
40 svpp=hv_fetch(hv, key, strlen(key), 0);
41 *store=SvPV(*svpp, PL_na );
46 static int getint(void *hv_t,char *key,int *store) {
51 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
53 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
55 svpp=hv_fetch(hv, key, strlen(key), 0);
56 *store=(int)SvIV(*svpp);
60 static int getdouble(void *hv_t,char* key,double *store) {
65 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
67 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
68 svpp=hv_fetch(hv, key, strlen(key), 0);
69 *store=(float)SvNV(*svpp);
73 static int getvoid(void *hv_t,char* key,void **store) {
78 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
80 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
82 svpp=hv_fetch(hv, key, strlen(key), 0);
83 *store = INT2PTR(void*, SvIV(*svpp));
88 static int getobj(void *hv_t,char *key,char *type,void **store) {
93 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
95 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
97 svpp=hv_fetch(hv, key, strlen(key), 0);
99 if (sv_derived_from(*svpp,type)) {
100 IV tmp = SvIV((SV*)SvRV(*svpp));
101 *store = INT2PTR(void*, tmp);
103 mm_log((1,"getobj: key exists in hash but is not of correct type"));
110 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
112 void my_SvREFCNT_dec(void *p) {
114 SvREFCNT_dec((SV*)p);
119 i_log_entry(char *string, int level) {
120 mm_log((level, string));
124 typedef struct i_reader_data_tag
126 /* presumably a CODE ref or name of a sub */
130 /* used by functions that want callbacks */
131 static int read_callback(char *userdata, char *buffer, int need, int want) {
133 i_reader_data *rd = (i_reader_data *)userdata;
137 dSP; dTARG = sv_newmortal();
138 /* thanks to Simon Cozens for help with the dTARG above */
148 count = perl_call_sv(rd->sv, G_SCALAR);
153 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
159 char *ptr = SvPV(data, len);
161 croak("Too much data returned in reader callback");
163 memcpy(buffer, ptr, len);
179 SV *sv; /* a coderef or sub name */
182 /* used by functions that want callbacks */
183 static int write_callback(char *userdata, char const *data, int size) {
185 i_writer_data *wd = (i_writer_data *)userdata;
195 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
198 count = perl_call_sv(wd->sv, G_SCALAR);
203 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
206 success = SvTRUE(sv);
216 #define CBDATA_BUFSIZE 8192
219 /* the SVs we use to call back to Perl */
225 /* we need to remember whether the buffer contains write data or
231 /* how far we've read into the buffer (not used for writing) */
234 /* the amount of space used/data available in the buffer */
237 /* the maximum amount to fill the buffer before flushing
238 If any write is larger than this then the buffer is flushed and
239 the full write is performed. The write is _not_ split into
244 char buffer[CBDATA_BUFSIZE];
249 call_writer(cbd, buf, size)
251 Low-level function to call the perl writer callback.
255 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
262 if (!SvOK(cbd->writecb))
269 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
272 count = perl_call_sv(cbd->writecb, G_SCALAR);
276 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
279 success = SvTRUE(sv);
286 return success ? size : -1;
289 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
297 if (!SvOK(cbd->readcb))
304 PUSHs(sv_2mortal(newSViv(size)));
305 PUSHs(sv_2mortal(newSViv(maxread)));
308 count = perl_call_sv(cbd->readcb, G_SCALAR);
313 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
319 char *ptr = SvPV(data, len);
321 croak("Too much data returned in reader callback");
323 memcpy(buf, ptr, len);
337 static ssize_t write_flush(struct cbdata *cbd) {
342 result = call_writer(cbd, cbd->buffer, cbd->used);
347 return 1; /* success of some sort */
351 static off_t io_seeker(void *p, off_t offset, int whence) {
353 struct cbdata *cbd = p;
358 if (!SvOK(cbd->seekcb))
362 if (cbd->used && write_flush(cbd) <= 0)
366 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
367 offset -= cbd->where - cbd->used;
370 cbd->where = cbd->used = 0;
376 PUSHs(sv_2mortal(newSViv(offset)));
377 PUSHs(sv_2mortal(newSViv(whence)));
380 count = perl_call_sv(cbd->seekcb, G_SCALAR);
385 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
396 static ssize_t io_writer(void *p, void const *data, size_t size) {
398 struct cbdata *cbd = p;
400 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
402 if (cbd->reading && cbd->where < cbd->used) {
403 /* we read past the place where the caller expected us to be
404 so adjust our position a bit */
405 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
410 cbd->where = cbd->used = 0;
413 if (cbd->used && cbd->used + size > cbd->maxlength) {
414 int write_res = write_flush(cbd);
415 if (write_res <= 0) {
420 if (cbd->used+size <= cbd->maxlength) {
421 memcpy(cbd->buffer + cbd->used, data, size);
425 /* it doesn't fit - just pass it up */
426 return call_writer(cbd, data, size);
430 io_reader(void *p, void *data, size_t size) {
432 struct cbdata *cbd = p;
434 char *out = data; /* so we can do pointer arithmetic */
436 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
438 if (write_flush(cbd) <= 0)
444 if (size <= cbd->used - cbd->where) {
446 memcpy(data, cbd->buffer+cbd->where, size);
451 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
452 total += cbd->used - cbd->where;
453 size -= cbd->used - cbd->where;
454 out += cbd->used - cbd->where;
455 if (size < sizeof(cbd->buffer)) {
459 && (did_read = call_reader(cbd, cbd->buffer, size,
460 sizeof(cbd->buffer))) > 0) {
462 cbd->used = did_read;
464 copy_size = i_min(size, cbd->used);
465 memcpy(out, cbd->buffer, copy_size);
466 cbd->where += copy_size;
475 /* just read the rest - too big for our buffer*/
477 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
489 static int io_closer(void *p) {
491 struct cbdata *cbd = p;
493 if (cbd->writing && cbd->used > 0) {
494 if (write_flush(cbd) < 0)
499 if (SvOK(cbd->closecb)) {
507 perl_call_sv(cbd->closecb, G_VOID);
518 static void io_destroyer(void *p) {
520 struct cbdata *cbd = p;
522 SvREFCNT_dec(cbd->writecb);
523 SvREFCNT_dec(cbd->readcb);
524 SvREFCNT_dec(cbd->seekcb);
525 SvREFCNT_dec(cbd->closecb);
533 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
536 for (i = 0; i < count; ++i)
537 if (strEQ(names[i].name, name))
538 return names[i].value;
542 static struct value_name transp_names[] =
545 { "threshold", tr_threshold },
546 { "errdiff", tr_errdiff },
547 { "ordered", tr_ordered, },
550 static struct value_name make_color_names[] =
552 { "none", mc_none, },
553 { "webmap", mc_web_map, },
554 { "addi", mc_addi, },
555 { "mediancut", mc_median_cut, },
556 { "mono", mc_mono, },
557 { "monochrome", mc_mono, },
560 static struct value_name translate_names[] =
562 { "giflib", pt_giflib, },
563 { "closest", pt_closest, },
564 { "perturb", pt_perturb, },
565 { "errdiff", pt_errdiff, },
568 static struct value_name errdiff_names[] =
570 { "floyd", ed_floyd, },
571 { "jarvis", ed_jarvis, },
572 { "stucki", ed_stucki, },
573 { "custom", ed_custom, },
576 static struct value_name orddith_names[] =
578 { "random", od_random, },
579 { "dot8", od_dot8, },
580 { "dot4", od_dot4, },
581 { "hline", od_hline, },
582 { "vline", od_vline, },
583 { "/line", od_slashline, },
584 { "slashline", od_slashline, },
585 { "\\line", od_backline, },
586 { "backline", od_backline, },
587 { "tiny", od_tiny, },
588 { "custom", od_custom, },
591 /* look through the hash for quantization options */
593 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
595 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
601 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
603 sv = hv_fetch(hv, "transp", 6, 0);
604 if (sv && *sv && (str = SvPV(*sv, len))) {
606 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
608 if (quant->transp != tr_none) {
609 quant->tr_threshold = 127;
610 sv = hv_fetch(hv, "tr_threshold", 12, 0);
612 quant->tr_threshold = SvIV(*sv);
614 if (quant->transp == tr_errdiff) {
615 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
616 if (sv && *sv && (str = SvPV(*sv, len)))
617 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
619 if (quant->transp == tr_ordered) {
620 quant->tr_orddith = od_tiny;
621 sv = hv_fetch(hv, "tr_orddith", 10, 0);
622 if (sv && *sv && (str = SvPV(*sv, len)))
623 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
625 if (quant->tr_orddith == od_custom) {
626 sv = hv_fetch(hv, "tr_map", 6, 0);
627 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
628 AV *av = (AV*)SvRV(*sv);
629 len = av_len(av) + 1;
630 if (len > sizeof(quant->tr_custom))
631 len = sizeof(quant->tr_custom);
632 for (i = 0; i < len; ++i) {
633 SV **sv2 = av_fetch(av, i, 0);
635 quant->tr_custom[i] = SvIV(*sv2);
638 while (i < sizeof(quant->tr_custom))
639 quant->tr_custom[i++] = 0;
644 quant->make_colors = mc_median_cut;
645 sv = hv_fetch(hv, "make_colors", 11, 0);
646 if (sv && *sv && (str = SvPV(*sv, len))) {
648 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
650 sv = hv_fetch(hv, "colors", 6, 0);
651 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
652 /* needs to be an array of Imager::Color
653 note that the caller allocates the mc_color array and sets mc_size
655 AV *av = (AV *)SvRV(*sv);
656 quant->mc_count = av_len(av)+1;
657 if (quant->mc_count > quant->mc_size)
658 quant->mc_count = quant->mc_size;
659 for (i = 0; i < quant->mc_count; ++i) {
660 SV **sv1 = av_fetch(av, i, 0);
661 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
662 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
663 quant->mc_colors[i] = *col;
667 sv = hv_fetch(hv, "max_colors", 10, 0);
670 if (i <= quant->mc_size && i >= quant->mc_count)
674 quant->translate = pt_closest;
675 sv = hv_fetch(hv, "translate", 9, 0);
676 if (sv && *sv && (str = SvPV(*sv, len))) {
677 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
679 sv = hv_fetch(hv, "errdiff", 7, 0);
680 if (sv && *sv && (str = SvPV(*sv, len))) {
681 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
683 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
684 /* get the error diffusion map */
685 sv = hv_fetch(hv, "errdiff_width", 13, 0);
687 quant->ed_width = SvIV(*sv);
688 sv = hv_fetch(hv, "errdiff_height", 14, 0);
690 quant->ed_height = SvIV(*sv);
691 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
693 quant->ed_orig = SvIV(*sv);
694 if (quant->ed_width > 0 && quant->ed_height > 0) {
696 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
697 sv = hv_fetch(hv, "errdiff_map", 11, 0);
698 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
699 AV *av = (AV*)SvRV(*sv);
700 len = av_len(av) + 1;
701 if (len > quant->ed_width * quant->ed_height)
702 len = quant->ed_width * quant->ed_height;
703 for (i = 0; i < len; ++i) {
704 SV **sv2 = av_fetch(av, i, 0);
706 quant->ed_map[i] = SvIV(*sv2);
707 sum += quant->ed_map[i];
713 myfree(quant->ed_map);
715 quant->errdiff = ed_floyd;
719 sv = hv_fetch(hv, "perturb", 7, 0);
721 quant->perturb = SvIV(*sv);
725 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
726 myfree(quant->mc_colors);
728 myfree(quant->ed_map);
731 /* copies the color map from the hv into the colors member of the HV */
733 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
739 sv = hv_fetch(hv, "colors", 6, 0);
740 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
745 av = (AV *)SvRV(*sv);
747 av_extend(av, quant->mc_count+1);
748 for (i = 0; i < quant->mc_count; ++i) {
749 i_color *in = quant->mc_colors+i;
750 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
751 work = sv_newmortal();
752 sv_setref_pv(work, "Imager::Color", (void *)c);
758 /* loads the segments of a fountain fill into an array */
759 static i_fountain_seg *
760 load_fount_segs(pTHX_ AV *asegs, int *count) {
761 /* Each element of segs must contain:
762 [ start, middle, end, c0, c1, segtype, colortrans ]
763 start, middle, end are doubles from 0 to 1
764 c0, c1 are Imager::Color::Float or Imager::Color objects
765 segtype, colortrans are ints
769 i_fountain_seg *segs;
773 *count = av_len(asegs)+1;
775 croak("i_fountain must have at least one segment");
776 segs = mymalloc(sizeof(i_fountain_seg) * *count);
777 for(i = 0; i < *count; i++) {
778 SV **sv1 = av_fetch(asegs, i, 0);
779 if (!sv1 || !*sv1 || !SvROK(*sv1)
780 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
782 croak("i_fountain: segs must be an arrayref of arrayrefs");
784 aseg = (AV *)SvRV(*sv1);
785 if (av_len(aseg) != 7-1) {
787 croak("i_fountain: a segment must have 7 members");
789 for (j = 0; j < 3; ++j) {
790 SV **sv2 = av_fetch(aseg, j, 0);
793 croak("i_fountain: XS error");
795 work[j] = SvNV(*sv2);
797 segs[i].start = work[0];
798 segs[i].middle = work[1];
799 segs[i].end = work[2];
800 for (j = 0; j < 2; ++j) {
801 SV **sv3 = av_fetch(aseg, 3+j, 0);
802 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
803 (!sv_derived_from(*sv3, "Imager::Color")
804 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
806 croak("i_fountain: segs must contain colors in elements 3 and 4");
808 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
809 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
812 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
814 for (ch = 0; ch < MAXCHANNELS; ++ch) {
815 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
819 for (j = 0; j < 2; ++j) {
820 SV **sv2 = av_fetch(aseg, j+5, 0);
823 croak("i_fountain: XS error");
825 worki[j] = SvIV(*sv2);
827 segs[i].type = worki[0];
828 segs[i].color = worki[1];
834 /* validates the indexes supplied to i_ppal
836 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
841 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
842 int color_count = i_colorcount(im);
845 if (color_count == -1)
846 croak("i_plin() called on direct color image");
848 for (i = 0; i < count; ++i) {
849 if (indexes[i] >= color_count) {
850 croak("i_plin() called with out of range color index %d (max %d)",
851 indexes[i], color_count-1);
857 /* I don't think ICLF_* names belong at the C interface
858 this makes the XS code think we have them, to let us avoid
859 putting function bodies in the XS code
861 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
862 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
865 /* the m_init_log() function was called init_log(), renamed to reduce
866 potential naming conflicts */
867 #define init_log m_init_log
869 #if i_int_hlines_testing()
871 typedef i_int_hlines *Imager__Internal__Hlines;
873 static i_int_hlines *
874 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
875 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
876 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
881 static i_int_hlines *
882 i_int_hlines_new_img(i_img *im) {
883 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
884 i_int_init_hlines_img(result, im);
890 i_int_hlines_DESTROY(i_int_hlines *hlines) {
891 i_int_hlines_destroy(hlines);
895 #define i_int_hlines_CLONE_SKIP(cls) 1
897 static int seg_compare(const void *vleft, const void *vright) {
898 const i_int_hline_seg *left = vleft;
899 const i_int_hline_seg *right = vright;
901 return left->minx - right->minx;
905 i_int_hlines_dump(i_int_hlines *hlines) {
907 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
908 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
911 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
912 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
915 /* sort the segments, if any */
917 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
919 sv_catpvf(dump, " %d (%d):", y, entry->count);
920 for (i = 0; i < entry->count; ++i) {
921 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
922 entry->segs[i].x_limit);
924 sv_catpv(dump, "\n");
933 static im_pl_ext_funcs im_perl_funcs =
935 IMAGER_PL_API_VERSION,
937 ip_handle_quant_opts,
938 ip_cleanup_quant_opts,
942 #define PERL_PL_SET_GLOBAL_CALLBACKS \
943 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
946 #define i_exif_enabled() 1
948 #define i_exif_enabled() 0
951 /* trying to use more C style names, map them here */
952 #define i_io_DESTROY(ig) io_glue_destroy(ig)
954 #define i_img_get_width(im) ((im)->xsize)
955 #define i_img_get_height(im) ((im)->ysize)
957 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
960 ICL_new_internal(r,g,b,a)
972 ICL_set_internal(cl,r,g,b,a)
979 ICL_set_internal(cl, r, g, b, a);
993 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
994 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
995 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
996 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
1002 RETVAL = mymalloc(sizeof(i_color));
1004 i_hsv_to_rgb(RETVAL);
1012 RETVAL = mymalloc(sizeof(i_color));
1014 i_rgb_to_hsv(RETVAL);
1020 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1022 Imager::Color::Float
1023 ICLF_new_internal(r, g, b, a)
1031 Imager::Color::Float cl
1035 Imager::Color::Float cl
1039 EXTEND(SP, MAXCHANNELS);
1040 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1041 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1042 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1046 ICLF_set_internal(cl,r,g,b,a)
1047 Imager::Color::Float cl
1060 Imager::Color::Float
1062 Imager::Color::Float c
1064 RETVAL = mymalloc(sizeof(i_fcolor));
1066 i_hsv_to_rgbf(RETVAL);
1070 Imager::Color::Float
1072 Imager::Color::Float c
1074 RETVAL = mymalloc(sizeof(i_fcolor));
1076 i_rgb_to_hsvf(RETVAL);
1080 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1094 MODULE = Imager PACKAGE = Imager
1113 SvPV(ST(0), length);
1114 SvREFCNT_inc(ST(0));
1115 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1120 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1129 cbd = mymalloc(sizeof(struct cbdata));
1130 SvREFCNT_inc(writecb);
1131 cbd->writecb = writecb;
1132 SvREFCNT_inc(readcb);
1133 cbd->readcb = readcb;
1134 SvREFCNT_inc(seekcb);
1135 cbd->seekcb = seekcb;
1136 SvREFCNT_inc(closecb);
1137 cbd->closecb = closecb;
1138 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1139 if (maxwrite > CBDATA_BUFSIZE)
1140 maxwrite = CBDATA_BUFSIZE;
1141 cbd->maxlength = maxwrite;
1142 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1151 unsigned char* data;
1155 tlength = io_slurp(ig, &data);
1157 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1162 i_set_image_file_limits(width, height, bytes)
1168 i_get_image_file_limits()
1170 int width, height, bytes;
1172 if (i_get_image_file_limits(&width, &height, &bytes)) {
1174 PUSHs(sv_2mortal(newSViv(width)));
1175 PUSHs(sv_2mortal(newSViv(height)));
1176 PUSHs(sv_2mortal(newSViv(bytes)));
1179 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1182 i_io_write(ig, data_sv)
1190 if (SvUTF8(data_sv)) {
1191 data_sv = sv_2mortal(newSVsv(data_sv));
1192 /* yes, we want this to croak() if the SV can't be downgraded */
1193 sv_utf8_downgrade(data_sv, FALSE);
1196 data = SvPV(data_sv, size);
1197 RETVAL = i_io_write(ig, data, size);
1202 i_io_read(ig, buffer_sv, size)
1211 croak("size negative in call to i_io_read()");
1212 /* prevent an undefined value warning if they supplied an
1214 Orginally conditional on !SvOK(), but this will prevent the
1215 downgrade from croaking */
1216 sv_setpvn(buffer_sv, "", 0);
1218 if (SvUTF8(buffer_sv))
1219 sv_utf8_downgrade(buffer_sv, FALSE);
1221 buffer = SvGROW(buffer_sv, size+1);
1222 result = i_io_read(ig, buffer, size);
1224 SvCUR_set(buffer_sv, result);
1225 *SvEND(buffer_sv) = '\0';
1226 SvPOK_only(buffer_sv);
1228 PUSHs(sv_2mortal(newSViv(result)));
1234 i_io_read2(ig, size)
1243 croak("size negative in call to i_io_read2()");
1244 buffer_sv = newSV(size);
1245 buffer = SvGROW(buffer_sv, size+1);
1246 result = i_io_read(ig, buffer, size);
1248 SvCUR_set(buffer_sv, result);
1249 *SvEND(buffer_sv) = '\0';
1250 SvPOK_only(buffer_sv);
1252 PUSHs(sv_2mortal(buffer_sv));
1256 SvREFCNT_dec(buffer_sv);
1260 i_io_seek(ig, position, whence)
1274 i_io_CLONE_SKIP(...)
1280 MODULE = Imager PACKAGE = Imager
1291 while( (item=i_format_list[i++]) != NULL ) {
1293 PUSHs(sv_2mortal(newSVpv(item,0)));
1310 i_img_empty_ch(im,x,y,ch)
1317 i_sametype(im, x, y)
1323 i_sametype_chans(im, x, y, channels)
1330 i_init_log(name_sv,level)
1334 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1336 i_init_log(name, level);
1339 i_log_entry(string,level)
1358 i_img_info(im,info);
1360 PUSHs(sv_2mortal(newSViv(info[0])));
1361 PUSHs(sv_2mortal(newSViv(info[1])));
1362 PUSHs(sv_2mortal(newSViv(info[2])));
1363 PUSHs(sv_2mortal(newSViv(info[3])));
1369 i_img_setmask(im,ch_mask)
1378 i_img_getchannels(im)
1387 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1395 i_img_get_height(im)
1400 i_img_is_monochrome(im)
1406 result = i_img_is_monochrome(im, &zero_is_white);
1408 if (GIMME_V == G_ARRAY) {
1411 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1420 i_line(im,x1,y1,x2,y2,val,endp)
1430 i_line_aa(im,x1,y1,x2,y2,val,endp)
1440 i_box(im,x1,y1,x2,y2,val)
1449 i_box_filled(im,x1,y1,x2,y2,val)
1458 i_box_cfill(im,x1,y1,x2,y2,fill)
1464 Imager::FillHandle fill
1467 i_arc(im,x,y,rad,d1,d2,val)
1477 i_arc_aa(im,x,y,rad,d1,d2,val)
1487 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1494 Imager::FillHandle fill
1497 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1504 Imager::FillHandle fill
1508 i_circle_aa(im,x,y,rad,val)
1516 i_circle_out(im,x,y,rad,val)
1524 i_circle_out_aa(im,x,y,rad,val)
1532 i_arc_out(im,x,y,rad,d1,d2,val)
1542 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1553 i_bezier_multi(im,xc,yc,val)
1566 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1567 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1568 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1569 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1570 av1=(AV*)SvRV(ST(1));
1571 av2=(AV*)SvRV(ST(2));
1572 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1574 x=mymalloc( len*sizeof(double) );
1575 y=mymalloc( len*sizeof(double) );
1576 for(i=0;i<len;i++) {
1577 sv1=(*(av_fetch(av1,i,0)));
1578 sv2=(*(av_fetch(av2,i,0)));
1579 x[i]=(double)SvNV(sv1);
1580 y[i]=(double)SvNV(sv2);
1582 i_bezier_multi(im,len,x,y,val);
1588 i_poly_aa(im,xc,yc,val)
1601 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1602 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1603 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1604 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1605 av1=(AV*)SvRV(ST(1));
1606 av2=(AV*)SvRV(ST(2));
1607 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1609 x=mymalloc( len*sizeof(double) );
1610 y=mymalloc( len*sizeof(double) );
1611 for(i=0;i<len;i++) {
1612 sv1=(*(av_fetch(av1,i,0)));
1613 sv2=(*(av_fetch(av2,i,0)));
1614 x[i]=(double)SvNV(sv1);
1615 y[i]=(double)SvNV(sv2);
1617 RETVAL = i_poly_aa(im,len,x,y,val);
1624 i_poly_aa_cfill(im,xc,yc,fill)
1626 Imager::FillHandle fill
1636 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1637 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1638 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1639 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1640 av1=(AV*)SvRV(ST(1));
1641 av2=(AV*)SvRV(ST(2));
1642 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1644 x=mymalloc( len*sizeof(double) );
1645 y=mymalloc( len*sizeof(double) );
1646 for(i=0;i<len;i++) {
1647 sv1=(*(av_fetch(av1,i,0)));
1648 sv2=(*(av_fetch(av2,i,0)));
1649 x[i]=(double)SvNV(sv1);
1650 y[i]=(double)SvNV(sv2);
1652 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1661 i_flood_fill(im,seedx,seedy,dcol)
1668 i_flood_cfill(im,seedx,seedy,fill)
1672 Imager::FillHandle fill
1675 i_flood_fill_border(im,seedx,seedy,dcol, border)
1680 Imager::Color border
1683 i_flood_cfill_border(im,seedx,seedy,fill, border)
1687 Imager::FillHandle fill
1688 Imager::Color border
1692 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1704 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1721 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1732 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1745 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)
1761 i_combine(src_av, channels_av = NULL)
1765 i_img **imgs = NULL;
1767 int *channels = NULL;
1772 in_count = av_len(src_av) + 1;
1774 imgs = mymalloc(sizeof(i_img*) * in_count);
1775 channels = mymalloc(sizeof(int) * in_count);
1776 for (i = 0; i < in_count; ++i) {
1777 psv = av_fetch(src_av, i, 0);
1778 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1781 croak("imgs must contain only images");
1783 tmp = SvIV((SV*)SvRV(*psv));
1784 imgs[i] = INT2PTR(i_img*, tmp);
1786 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1788 channels[i] = SvIV(*psv);
1795 RETVAL = i_combine(imgs, channels, in_count);
1802 i_flipxy(im, direction)
1807 i_rotate90(im, degrees)
1812 i_rotate_exact(im, amount, ...)
1816 i_color *backp = NULL;
1817 i_fcolor *fbackp = NULL;
1821 /* extract the bg colors if any */
1822 /* yes, this is kind of strange */
1823 for (i = 2; i < items; ++i) {
1825 if (sv_derived_from(sv1, "Imager::Color")) {
1826 IV tmp = SvIV((SV*)SvRV(sv1));
1827 backp = INT2PTR(i_color *, tmp);
1829 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1830 IV tmp = SvIV((SV*)SvRV(sv1));
1831 fbackp = INT2PTR(i_fcolor *, tmp);
1834 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1839 i_matrix_transform(im, xsize, ysize, matrix, ...)
1849 i_color *backp = NULL;
1850 i_fcolor *fbackp = NULL;
1852 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1853 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1854 av=(AV*)SvRV(ST(3));
1858 for (i = 0; i < len; ++i) {
1859 sv1=(*(av_fetch(av,i,0)));
1860 matrix[i] = SvNV(sv1);
1864 /* extract the bg colors if any */
1865 /* yes, this is kind of strange */
1866 for (i = 4; i < items; ++i) {
1868 if (sv_derived_from(sv1, "Imager::Color")) {
1869 IV tmp = SvIV((SV*)SvRV(sv1));
1870 backp = INT2PTR(i_color *, tmp);
1872 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1873 IV tmp = SvIV((SV*)SvRV(sv1));
1874 fbackp = INT2PTR(i_fcolor *, tmp);
1877 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1882 i_gaussian(im,stdev)
1887 i_unsharp_mask(im,stdev,scale)
1902 len = av_len(coef) + 1;
1903 c_coef=mymalloc( len * sizeof(double) );
1904 for(i = 0; i < len; i++) {
1905 sv1 = (*(av_fetch(coef, i, 0)));
1906 c_coef[i] = (double)SvNV(sv1);
1908 RETVAL = i_conv(im, c_coef, len);
1914 i_convert(src, avmain)
1926 outchan = av_len(avmain)+1;
1927 /* find the biggest */
1929 for (j=0; j < outchan; ++j) {
1930 temp = av_fetch(avmain, j, 0);
1931 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1932 avsub = (AV*)SvRV(*temp);
1933 len = av_len(avsub)+1;
1938 coeff = mymalloc(sizeof(double) * outchan * inchan);
1939 for (j = 0; j < outchan; ++j) {
1940 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1941 len = av_len(avsub)+1;
1942 for (i = 0; i < len; ++i) {
1943 temp = av_fetch(avsub, i, 0);
1945 coeff[i+j*inchan] = SvNV(*temp);
1947 coeff[i+j*inchan] = 0;
1950 coeff[i++ + j*inchan] = 0;
1952 RETVAL = i_convert(src, coeff, outchan, inchan);
1962 unsigned int mask = 0;
1968 unsigned char (*maps)[256];
1970 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1971 croak("i_map: parameter 2 must be an arrayref\n");
1972 avmain = (AV*)SvRV(ST(1));
1973 len = av_len(avmain)+1;
1974 if (im->channels < len) len = im->channels;
1976 maps = mymalloc( len * sizeof(unsigned char [256]) );
1978 for (j=0; j<len ; j++) {
1979 temp = av_fetch(avmain, j, 0);
1980 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1981 avsub = (AV*)SvRV(*temp);
1982 if(av_len(avsub) != 255) continue;
1984 for (i=0; i<256 ; i++) {
1986 temp = av_fetch(avsub, i, 0);
1987 val = temp ? SvIV(*temp) : 0;
1989 if (val>255) val = 255;
1994 i_map(im, maps, mask);
2005 i_img_diffd(im1,im2)
2010 _is_color_object(sv)
2014 RETVAL = SvOK(sv) && SvROK(sv) &&
2015 (sv_derived_from(sv, "Imager::Color")
2016 || sv_derived_from(sv, "Imager::Color::Float"));
2031 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2033 #define TT_DESTROY(handle) i_tt_destroy(handle)
2037 Imager::Font::TT handle
2047 MODULE = Imager PACKAGE = Imager
2051 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2052 Imager::Font::TT handle
2070 str = SvPV(str_sv, len);
2071 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2072 len, smooth, utf8, align);
2078 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2079 Imager::Font::TT handle
2097 str = SvPV(str_sv, len);
2098 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2099 smooth, utf8, align);
2105 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2106 Imager::Font::TT handle
2111 int cords[BOUNDING_BOX_COUNT],rc;
2120 str = SvPV(str_sv, len);
2121 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2123 for (i = 0; i < rc; ++i) {
2124 PUSHs(sv_2mortal(newSViv(cords[i])));
2129 i_tt_has_chars(handle, text_sv, utf8)
2130 Imager::Font::TT handle
2141 if (SvUTF8(text_sv))
2144 text = SvPV(text_sv, len);
2145 work = mymalloc(len);
2146 count = i_tt_has_chars(handle, text, len, utf8, work);
2147 if (GIMME_V == G_ARRAY) {
2149 for (i = 0; i < count; ++i) {
2150 PUSHs(sv_2mortal(newSViv(work[i])));
2155 PUSHs(sv_2mortal(newSVpv(work, count)));
2160 i_tt_dump_names(handle)
2161 Imager::Font::TT handle
2164 i_tt_face_name(handle)
2165 Imager::Font::TT handle
2170 len = i_tt_face_name(handle, name, sizeof(name));
2173 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2177 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2178 Imager::Font::TT handle
2189 if (SvUTF8(text_sv))
2192 text = SvPV(text_sv, work_len);
2197 ch = i_utf8_advance(&text, &len);
2199 i_push_error(0, "invalid UTF8 character");
2208 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2209 PUSHs(sv_2mortal(newSVpv(name, 0)));
2212 PUSHs(&PL_sv_undef);
2219 i_test_format_probe(ig, length)
2224 i_readpnm_wiol(ig, allow_incomplete)
2226 int allow_incomplete
2230 i_readpnm_multi_wiol(ig, allow_incomplete)
2232 int allow_incomplete
2238 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2241 for (i = 0; i < count; ++i) {
2242 SV *sv = sv_newmortal();
2243 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2250 i_writeppm_wiol(im, ig)
2259 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2268 i_writeraw_wiol(im,ig)
2273 i_writebmp_wiol(im,ig)
2278 i_readbmp_wiol(ig, allow_incomplete=0)
2280 int allow_incomplete
2284 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2293 idlen = SvCUR(ST(4));
2294 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2300 i_readtga_wiol(ig, length)
2308 i_scaleaxis(im,Value,Axis)
2314 i_scale_nn(im,scx,scy)
2320 i_scale_mixing(im, width, height)
2330 i_count_colors(im,maxc)
2335 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2340 unsigned int * col_usage = NULL;
2343 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2344 EXTEND(SP, col_cnt);
2345 for (i = 0; i < col_cnt; i++) {
2346 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2353 i_transform(im,opx,opy,parm)
2366 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2367 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2368 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2369 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2370 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2371 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2372 av=(AV*)SvRV(ST(1));
2374 opx=mymalloc( opxl*sizeof(int) );
2375 for(i=0;i<opxl;i++) {
2376 sv1=(*(av_fetch(av,i,0)));
2377 opx[i]=(int)SvIV(sv1);
2379 av=(AV*)SvRV(ST(2));
2381 opy=mymalloc( opyl*sizeof(int) );
2382 for(i=0;i<opyl;i++) {
2383 sv1=(*(av_fetch(av,i,0)));
2384 opy[i]=(int)SvIV(sv1);
2386 av=(AV*)SvRV(ST(3));
2387 parmlen=av_len(av)+1;
2388 parm=mymalloc( parmlen*sizeof(double) );
2389 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2390 sv1=(*(av_fetch(av,i,0)));
2391 parm[i]=(double)SvNV(sv1);
2393 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2397 ST(0) = sv_newmortal();
2398 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2399 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2402 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2427 in_imgs_count = av_len(av_in_imgs)+1;
2428 for (i = 0; i < in_imgs_count; ++i) {
2429 sv1 = *av_fetch(av_in_imgs, i, 0);
2430 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2431 croak("sv_in_img must contain only images");
2434 if (in_imgs_count > 0) {
2435 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2436 for (i = 0; i < in_imgs_count; ++i) {
2437 sv1 = *av_fetch(av_in_imgs,i,0);
2438 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2439 croak("Parameter 5 must contain only images");
2441 tmp = SvIV((SV*)SvRV(sv1));
2442 in_imgs[i] = INT2PTR(i_img*, tmp);
2446 /* no input images */
2449 /* default the output size from the first input if possible */
2451 width = SvIV(sv_width);
2452 else if (in_imgs_count)
2453 width = in_imgs[0]->xsize;
2455 croak("No output image width supplied");
2457 if (SvOK(sv_height))
2458 height = SvIV(sv_height);
2459 else if (in_imgs_count)
2460 height = in_imgs[0]->ysize;
2462 croak("No output image height supplied");
2464 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2465 if (ops_len % sizeof(struct rm_op))
2466 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2467 ops_count = ops_len / sizeof(struct rm_op);
2469 n_regs_count = av_len(av_n_regs)+1;
2470 n_regs = mymalloc(n_regs_count * sizeof(double));
2471 for (i = 0; i < n_regs_count; ++i) {
2472 sv1 = *av_fetch(av_n_regs,i,0);
2474 n_regs[i] = SvNV(sv1);
2476 c_regs_count = av_len(av_c_regs)+1;
2477 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2478 /* I don't bother initializing the colou?r registers */
2480 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2481 n_regs, n_regs_count,
2482 c_regs, c_regs_count, in_imgs, in_imgs_count);
2487 ST(0) = sv_newmortal();
2488 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2489 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2493 i_contrast(im,intensity)
2506 i_noise(im,amount,type)
2512 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2522 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2541 i_postlevels(im,levels)
2551 i_watermark(im,wmark,tx,ty,pixdiff)
2553 Imager::ImgRaw wmark
2560 i_autolevels(im,lsat,usat,skew)
2567 i_radnoise(im,xo,yo,rscale,ascale)
2575 i_turbnoise(im, xo, yo, scale)
2598 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2599 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2600 croak("i_gradgen: Second argument must be an array ref");
2601 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2602 croak("i_gradgen: Third argument must be an array ref");
2603 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2604 croak("i_gradgen: Fourth argument must be an array ref");
2605 axx = (AV *)SvRV(ST(1));
2606 ayy = (AV *)SvRV(ST(2));
2607 ac = (AV *)SvRV(ST(3));
2608 dmeasure = (int)SvIV(ST(4));
2610 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2611 num = num <= av_len(ac) ? num : av_len(ac);
2613 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2614 xo = mymalloc( sizeof(int) * num );
2615 yo = mymalloc( sizeof(int) * num );
2616 ival = mymalloc( sizeof(i_color) * num );
2617 for(i = 0; i<num; i++) {
2618 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2619 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2620 sv = *av_fetch(ac, i, 0);
2621 if ( !sv_derived_from(sv, "Imager::Color") ) {
2622 free(axx); free(ayy); free(ac);
2623 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2625 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2627 i_gradgen(im, num, xo, yo, ival, dmeasure);
2633 i_diff_image(im, im2, mindist=0)
2639 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2649 double ssample_param
2653 i_fountain_seg *segs;
2655 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2656 croak("i_fountain: argument 11 must be an array ref");
2658 asegs = (AV *)SvRV(ST(10));
2659 segs = load_fount_segs(aTHX_ asegs, &count);
2660 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2661 super_sample, ssample_param, count, segs);
2667 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2676 double ssample_param
2680 i_fountain_seg *segs;
2682 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2683 croak("i_fountain: argument 11 must be an array ref");
2685 asegs = (AV *)SvRV(ST(9));
2686 segs = load_fount_segs(aTHX_ asegs, &count);
2687 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2688 super_sample, ssample_param, count, segs);
2694 i_new_fill_opacity(other_fill, alpha_mult)
2695 Imager::FillHandle other_fill
2706 errors = i_errors();
2708 while (errors[i].msg) {
2710 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2711 if (!av_store(av, 0, sv)) {
2714 sv = newSViv(errors[i].code);
2715 if (!av_store(av, 1, sv)) {
2718 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2726 i_push_error(code, msg)
2731 i_nearest_color(im, ...)
2746 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2747 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2748 croak("i_nearest_color: Second argument must be an array ref");
2749 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2750 croak("i_nearest_color: Third argument must be an array ref");
2751 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2752 croak("i_nearest_color: Fourth argument must be an array ref");
2753 axx = (AV *)SvRV(ST(1));
2754 ayy = (AV *)SvRV(ST(2));
2755 ac = (AV *)SvRV(ST(3));
2756 dmeasure = (int)SvIV(ST(4));
2758 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2759 num = num <= av_len(ac) ? num : av_len(ac);
2761 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2762 xo = mymalloc( sizeof(int) * num );
2763 yo = mymalloc( sizeof(int) * num );
2764 ival = mymalloc( sizeof(i_color) * num );
2765 for(i = 0; i<num; i++) {
2766 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2767 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2768 sv = *av_fetch(ac, i, 0);
2769 if ( !sv_derived_from(sv, "Imager::Color") ) {
2770 free(axx); free(ayy); free(ac);
2771 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2773 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2775 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2789 rc=DSO_open(filename,&evstr);
2793 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2794 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2797 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2803 DSO_close(dso_handle)
2807 DSO_funclist(dso_handle_v)
2811 DSO_handle *dso_handle;
2812 func_ptr *functions;
2814 dso_handle=(DSO_handle*)dso_handle_v;
2815 functions = DSO_funclist(dso_handle);
2817 while( functions[i].name != NULL) {
2819 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2821 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2825 DSO_call(handle,func_index,hv)
2831 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2832 hv=(HV*)SvRV(ST(2));
2833 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2834 DSO_call( (DSO_handle *)handle,func_index,hv);
2837 i_get_pixel(im, x, y)
2844 color = (i_color *)mymalloc(sizeof(i_color));
2845 if (i_gpix(im, x, y, color) == 0) {
2846 RETVAL = NEWSV(0, 0);
2847 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2851 RETVAL = &PL_sv_undef;
2858 i_ppix(im, x, y, cl)
2865 i_img_pal_new(x, y, channels, maxpal)
2872 i_img_to_pal(src, quant)
2878 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2879 croak("i_img_to_pal: second argument must be a hash ref");
2880 hv = (HV *)SvRV(ST(1));
2881 memset(&quant, 0, sizeof(quant));
2883 quant.mc_size = 256;
2884 ip_handle_quant_opts(aTHX_ &quant, hv);
2885 RETVAL = i_img_to_pal(src, &quant);
2887 ip_copy_colors_back(aTHX_ hv, &quant);
2889 ip_cleanup_quant_opts(aTHX_ &quant);
2908 work = mymalloc((r-l) * sizeof(i_palidx));
2909 count = i_gpal(im, l, r, y, work);
2910 if (GIMME_V == G_ARRAY) {
2912 for (i = 0; i < count; ++i) {
2913 PUSHs(sv_2mortal(newSViv(work[i])));
2918 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
2923 if (GIMME_V != G_ARRAY) {
2925 PUSHs(&PL_sv_undef);
2930 i_ppal(im, l, y, ...)
2939 work = mymalloc(sizeof(i_palidx) * (items-3));
2940 for (i=0; i < items-3; ++i) {
2941 work[i] = SvIV(ST(i+3));
2943 validate_i_ppal(im, work, items - 3);
2944 RETVAL = i_ppal(im, l, l+items-3, y, work);
2954 i_ppal_p(im, l, y, data)
2960 i_palidx const *work;
2963 work = (i_palidx const *)SvPV(data, len);
2964 len /= sizeof(i_palidx);
2966 validate_i_ppal(im, work, len);
2967 RETVAL = i_ppal(im, l, l+len, y, work);
2976 i_addcolors(im, ...)
2984 croak("i_addcolors: no colors to add");
2985 colors = mymalloc((items-1) * sizeof(i_color));
2986 for (i=0; i < items-1; ++i) {
2987 if (sv_isobject(ST(i+1))
2988 && sv_derived_from(ST(i+1), "Imager::Color")) {
2989 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2990 colors[i] = *INT2PTR(i_color *, tmp);
2994 croak("i_addcolor: pixels must be Imager::Color objects");
2997 index = i_addcolors(im, colors, items-1);
3000 RETVAL = newSVpv("0 but true", 0);
3002 else if (index == -1) {
3003 RETVAL = &PL_sv_undef;
3006 RETVAL = newSViv(index);
3012 i_setcolors(im, index, ...)
3020 croak("i_setcolors: no colors to add");
3021 colors = mymalloc((items-2) * sizeof(i_color));
3022 for (i=0; i < items-2; ++i) {
3023 if (sv_isobject(ST(i+2))
3024 && sv_derived_from(ST(i+2), "Imager::Color")) {
3025 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3026 colors[i] = *INT2PTR(i_color *, tmp);
3030 croak("i_setcolors: pixels must be Imager::Color objects");
3033 RETVAL = i_setcolors(im, index, colors, items-2);
3039 i_getcolors(im, index, ...)
3048 croak("i_getcolors: too many arguments");
3050 count = SvIV(ST(2));
3052 croak("i_getcolors: count must be positive");
3053 colors = mymalloc(sizeof(i_color) * count);
3054 if (i_getcolors(im, index, colors, count)) {
3055 for (i = 0; i < count; ++i) {
3057 SV *sv = sv_newmortal();
3058 pv = mymalloc(sizeof(i_color));
3060 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3076 i_findcolor(im, color)
3082 if (i_findcolor(im, color, &index)) {
3083 RETVAL = newSViv(index);
3086 RETVAL = &PL_sv_undef;
3104 i_gsamp(im, l, r, y, ...)
3116 croak("No channel numbers supplied to g_samp()");
3118 chan_count = items - 4;
3119 chans = mymalloc(sizeof(int) * chan_count);
3120 for (i = 0; i < chan_count; ++i)
3121 chans[i] = SvIV(ST(i+4));
3122 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3123 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3125 if (GIMME_V == G_ARRAY) {
3127 for (i = 0; i < count; ++i)
3128 PUSHs(sv_2mortal(newSViv(data[i])));
3132 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3137 if (GIMME_V != G_ARRAY) {
3139 PUSHs(&PL_sv_undef);
3144 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3160 croak("No channel numbers supplied to g_samp()");
3162 chan_count = items - 7;
3163 chans = mymalloc(sizeof(int) * chan_count);
3164 for (i = 0; i < chan_count; ++i)
3165 chans[i] = SvIV(ST(i+7));
3166 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3167 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3169 for (i = 0; i < count; ++i) {
3170 av_store(target, i+offset, newSVuv(data[i]));
3182 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3200 if (SvOK(channels_sv)) {
3202 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3203 croak("channels is not an array ref");
3205 channels_av = (AV *)SvRV(channels_sv);
3206 chan_count = av_len(channels_av) + 1;
3207 if (chan_count < 1) {
3208 croak("i_psamp_bits: no channels provided");
3210 channels = mymalloc(sizeof(int) * chan_count);
3211 for (i = 0; i < chan_count; ++i)
3212 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3215 chan_count = im->channels;
3219 data_count = av_len(data_av) + 1;
3220 if (data_offset < 0) {
3221 croak("data_offset must by non-negative");
3223 if (data_offset > data_count) {
3224 croak("data_offset greater than number of samples supplied");
3226 if (pixel_count == -1 ||
3227 data_offset + pixel_count * chan_count > data_count) {
3228 pixel_count = (data_count - data_offset) / chan_count;
3231 data_used = pixel_count * chan_count;
3232 data = mymalloc(sizeof(unsigned) * data_count);
3233 for (i = 0; i < data_used; ++i)
3234 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3236 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3247 i_img_masked_new(targ, mask, x, y, w, h)
3257 if (!sv_isobject(ST(1))
3258 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3259 croak("i_img_masked_new: parameter 2 must undef or an image");
3261 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3265 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3270 i_plin(im, l, y, ...)
3281 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3282 /* supplied as a byte string */
3283 work = (i_color *)SvPV(ST(3), len);
3284 count = len / sizeof(i_color);
3285 if (count * sizeof(i_color) != len) {
3286 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3288 RETVAL = i_plin(im, l, l+count, y, work);
3291 work = mymalloc(sizeof(i_color) * (items-3));
3292 for (i=0; i < items-3; ++i) {
3293 if (sv_isobject(ST(i+3))
3294 && sv_derived_from(ST(i+3), "Imager::Color")) {
3295 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3296 work[i] = *INT2PTR(i_color *, tmp);
3300 croak("i_plin: pixels must be Imager::Color objects");
3303 RETVAL = i_plin(im, l, l+items-3, y, work);
3314 i_ppixf(im, x, y, cl)
3318 Imager::Color::Float cl
3321 i_gsampf(im, l, r, y, ...)
3333 croak("No channel numbers supplied to g_sampf()");
3335 chan_count = items - 4;
3336 chans = mymalloc(sizeof(int) * chan_count);
3337 for (i = 0; i < chan_count; ++i)
3338 chans[i] = SvIV(ST(i+4));
3339 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3340 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3342 if (GIMME_V == G_ARRAY) {
3344 for (i = 0; i < count; ++i)
3345 PUSHs(sv_2mortal(newSVnv(data[i])));
3349 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3354 if (GIMME_V != G_ARRAY) {
3356 PUSHs(&PL_sv_undef);
3361 i_plinf(im, l, y, ...)
3372 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3373 /* supplied as a byte string */
3374 work = (i_fcolor *)SvPV(ST(3), len);
3375 count = len / sizeof(i_fcolor);
3376 if (count * sizeof(i_fcolor) != len) {
3377 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3379 RETVAL = i_plinf(im, l, l+count, y, work);
3382 work = mymalloc(sizeof(i_fcolor) * (items-3));
3383 for (i=0; i < items-3; ++i) {
3384 if (sv_isobject(ST(i+3))
3385 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3386 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3387 work[i] = *INT2PTR(i_fcolor *, tmp);
3391 croak("i_plinf: pixels must be Imager::Color::Float objects");
3395 RETVAL = i_plinf(im, l, l+items-3, y, work);
3413 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3414 if (i_gpixf(im, x, y, color) == 0) {
3415 RETVAL = NEWSV(0,0);
3416 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3420 RETVAL = &PL_sv_undef;
3436 vals = mymalloc((r-l) * sizeof(i_color));
3437 memset(vals, 0, (r-l) * sizeof(i_color));
3438 count = i_glin(im, l, r, y, vals);
3439 if (GIMME_V == G_ARRAY) {
3441 for (i = 0; i < count; ++i) {
3443 i_color *col = mymalloc(sizeof(i_color));
3445 sv = sv_newmortal();
3446 sv_setref_pv(sv, "Imager::Color", (void *)col);
3452 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3458 i_glinf(im, l, r, y)
3468 for (i = 0; i < MAXCHANNELS; ++i)
3469 zero.channel[i] = 0;
3471 vals = mymalloc((r-l) * sizeof(i_fcolor));
3472 for (i = 0; i < r-l; ++i)
3474 count = i_glinf(im, l, r, y, vals);
3475 if (GIMME_V == G_ARRAY) {
3477 for (i = 0; i < count; ++i) {
3479 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3481 sv = sv_newmortal();
3482 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3488 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3494 i_img_16_new(x, y, ch)
3504 i_img_double_new(x, y, ch)
3510 i_tags_addn(im, name, code, idata)
3519 name = SvPV(ST(1), len);
3522 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3527 i_tags_add(im, name, code, data, idata)
3537 name = SvPV(ST(1), len);
3541 data = SvPV(ST(3), len);
3546 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3551 i_tags_find(im, name, start)
3558 if (i_tags_find(&im->tags, name, start, &entry)) {
3560 RETVAL = newSVpv("0 but true", 0);
3562 RETVAL = newSViv(entry);
3564 RETVAL = &PL_sv_undef;
3570 i_tags_findn(im, code, start)
3577 if (i_tags_findn(&im->tags, code, start, &entry)) {
3579 RETVAL = newSVpv("0 but true", 0);
3581 RETVAL = newSViv(entry);
3584 RETVAL = &PL_sv_undef;
3590 i_tags_delete(im, entry)
3594 RETVAL = i_tags_delete(&im->tags, entry);
3599 i_tags_delbyname(im, name)
3603 RETVAL = i_tags_delbyname(&im->tags, name);
3608 i_tags_delbycode(im, code)
3612 RETVAL = i_tags_delbycode(&im->tags, code);
3617 i_tags_get(im, index)
3621 if (index >= 0 && index < im->tags.count) {
3622 i_img_tag *entry = im->tags.tags + index;
3626 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3629 PUSHs(sv_2mortal(newSViv(entry->code)));
3632 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3635 PUSHs(sv_2mortal(newSViv(entry->idata)));
3640 i_tags_get_string(im, what_sv)
3644 char const *name = NULL;
3648 if (SvIOK(what_sv)) {
3649 code = SvIV(what_sv);
3653 name = SvPV_nolen(what_sv);
3656 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3658 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3665 RETVAL = im->tags.count;
3671 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3675 Imager::FillHandle fill
3678 IFILL_CLONE_SKIP(...)
3684 MODULE = Imager PACKAGE = Imager
3687 i_new_fill_solid(cl, combine)
3692 i_new_fill_solidf(cl, combine)
3693 Imager::Color::Float cl
3697 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3705 unsigned char *cust_hatch;
3709 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3713 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3718 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3719 Imager::Color::Float fg
3720 Imager::Color::Float bg
3726 unsigned char *cust_hatch;
3730 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3734 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3739 i_new_fill_image(src, matrix, xoff, yoff, combine)
3756 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3757 croak("i_new_fill_image: parameter must be an arrayref");
3758 av=(AV*)SvRV(ST(1));
3762 for (i = 0; i < len; ++i) {
3763 sv1=(*(av_fetch(av,i,0)));
3764 matrix[i] = SvNV(sv1);
3770 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3774 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3776 # this class is only exposed for testing
3779 i_int_hlines_testing()
3781 #if i_int_hlines_testing()
3783 Imager::Internal::Hlines
3784 i_int_hlines_new(start_y, count_y, start_x, count_x)
3790 Imager::Internal::Hlines
3791 i_int_hlines_new_img(im)
3795 i_int_hlines_add(hlines, y, minx, width)
3796 Imager::Internal::Hlines hlines
3802 i_int_hlines_DESTROY(hlines)
3803 Imager::Internal::Hlines hlines
3806 i_int_hlines_dump(hlines)
3807 Imager::Internal::Hlines hlines
3810 i_int_hlines_CLONE_SKIP(cls)
3816 PERL_SET_GLOBAL_CALLBACKS;
3817 PERL_PL_SET_GLOBAL_CALLBACKS;