7 #define NEED_newRV_noinc
8 #define NEED_sv_2pv_nolen
14 #define i_int_hlines_testing() 1
22 #if i_int_hlines_testing()
28 /* These functions are all shared - then comes platform dependant code */
29 static int getstr(void *hv_t,char *key,char **store) {
33 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
35 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
37 svpp=hv_fetch(hv, key, strlen(key), 0);
38 *store=SvPV(*svpp, PL_na );
43 static int getint(void *hv_t,char *key,int *store) {
47 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
49 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
51 svpp=hv_fetch(hv, key, strlen(key), 0);
52 *store=(int)SvIV(*svpp);
56 static int getdouble(void *hv_t,char* key,double *store) {
60 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
62 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
63 svpp=hv_fetch(hv, key, strlen(key), 0);
64 *store=(float)SvNV(*svpp);
68 static int getvoid(void *hv_t,char* key,void **store) {
72 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
74 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
76 svpp=hv_fetch(hv, key, strlen(key), 0);
77 *store = INT2PTR(void*, SvIV(*svpp));
82 static int getobj(void *hv_t,char *key,char *type,void **store) {
86 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
88 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
90 svpp=hv_fetch(hv, key, strlen(key), 0);
92 if (sv_derived_from(*svpp,type)) {
93 IV tmp = SvIV((SV*)SvRV(*svpp));
94 *store = INT2PTR(void*, tmp);
96 mm_log((1,"getobj: key exists in hash but is not of correct type"));
103 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
105 void my_SvREFCNT_dec(void *p) {
106 SvREFCNT_dec((SV*)p);
111 i_log_entry(char *string, int level) {
112 mm_log((level, string));
116 typedef struct i_reader_data_tag
118 /* presumably a CODE ref or name of a sub */
122 /* used by functions that want callbacks */
123 static int read_callback(char *userdata, char *buffer, int need, int want) {
124 i_reader_data *rd = (i_reader_data *)userdata;
128 dSP; dTARG = sv_newmortal();
129 /* thanks to Simon Cozens for help with the dTARG above */
139 count = perl_call_sv(rd->sv, G_SCALAR);
144 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
150 char *ptr = SvPV(data, len);
152 croak("Too much data returned in reader callback");
154 memcpy(buffer, ptr, len);
170 SV *sv; /* a coderef or sub name */
173 /* used by functions that want callbacks */
174 static int write_callback(char *userdata, char const *data, int size) {
175 i_writer_data *wd = (i_writer_data *)userdata;
185 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
188 count = perl_call_sv(wd->sv, G_SCALAR);
193 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
196 success = SvTRUE(sv);
206 #define CBDATA_BUFSIZE 8192
209 /* the SVs we use to call back to Perl */
215 /* we need to remember whether the buffer contains write data or
221 /* how far we've read into the buffer (not used for writing) */
224 /* the amount of space used/data available in the buffer */
227 /* the maximum amount to fill the buffer before flushing
228 If any write is larger than this then the buffer is flushed and
229 the full write is performed. The write is _not_ split into
234 char buffer[CBDATA_BUFSIZE];
239 call_writer(cbd, buf, size)
241 Low-level function to call the perl writer callback.
245 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
251 if (!SvOK(cbd->writecb))
258 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
261 count = perl_call_sv(cbd->writecb, G_SCALAR);
265 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
268 success = SvTRUE(sv);
275 return success ? size : -1;
278 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
285 if (!SvOK(cbd->readcb))
292 PUSHs(sv_2mortal(newSViv(size)));
293 PUSHs(sv_2mortal(newSViv(maxread)));
296 count = perl_call_sv(cbd->readcb, G_SCALAR);
301 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
307 char *ptr = SvPV(data, len);
309 croak("Too much data returned in reader callback");
311 memcpy(buf, ptr, len);
325 static ssize_t write_flush(struct cbdata *cbd) {
329 result = call_writer(cbd, cbd->buffer, cbd->used);
334 return 1; /* success of some sort */
338 static off_t io_seeker(void *p, off_t offset, int whence) {
339 struct cbdata *cbd = p;
344 if (!SvOK(cbd->seekcb))
348 if (cbd->used && write_flush(cbd) <= 0)
352 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
353 offset -= cbd->where - cbd->used;
356 cbd->where = cbd->used = 0;
362 PUSHs(sv_2mortal(newSViv(offset)));
363 PUSHs(sv_2mortal(newSViv(whence)));
366 count = perl_call_sv(cbd->seekcb, G_SCALAR);
371 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
382 static ssize_t io_writer(void *p, void const *data, size_t size) {
383 struct cbdata *cbd = p;
385 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
387 if (cbd->reading && cbd->where < cbd->used) {
388 /* we read past the place where the caller expected us to be
389 so adjust our position a bit */
390 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
395 cbd->where = cbd->used = 0;
398 if (cbd->used && cbd->used + size > cbd->maxlength) {
399 int write_res = write_flush(cbd);
400 if (write_res <= 0) {
405 if (cbd->used+size <= cbd->maxlength) {
406 memcpy(cbd->buffer + cbd->used, data, size);
410 /* it doesn't fit - just pass it up */
411 return call_writer(cbd, data, size);
415 io_reader(void *p, void *data, size_t size) {
416 struct cbdata *cbd = p;
418 char *out = data; /* so we can do pointer arithmetic */
420 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
422 if (write_flush(cbd) <= 0)
428 if (size <= cbd->used - cbd->where) {
430 memcpy(data, cbd->buffer+cbd->where, size);
435 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
436 total += cbd->used - cbd->where;
437 size -= cbd->used - cbd->where;
438 out += cbd->used - cbd->where;
439 if (size < sizeof(cbd->buffer)) {
443 && (did_read = call_reader(cbd, cbd->buffer, size,
444 sizeof(cbd->buffer))) > 0) {
446 cbd->used = did_read;
448 copy_size = i_min(size, cbd->used);
449 memcpy(out, cbd->buffer, copy_size);
450 cbd->where += copy_size;
459 /* just read the rest - too big for our buffer*/
461 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
473 static int io_closer(void *p) {
474 struct cbdata *cbd = p;
476 if (cbd->writing && cbd->used > 0) {
477 if (write_flush(cbd) < 0)
482 if (SvOK(cbd->closecb)) {
490 perl_call_sv(cbd->closecb, G_VOID);
501 static void io_destroyer(void *p) {
502 struct cbdata *cbd = p;
504 SvREFCNT_dec(cbd->writecb);
505 SvREFCNT_dec(cbd->readcb);
506 SvREFCNT_dec(cbd->seekcb);
507 SvREFCNT_dec(cbd->closecb);
515 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
518 for (i = 0; i < count; ++i)
519 if (strEQ(names[i].name, name))
520 return names[i].value;
524 static struct value_name transp_names[] =
527 { "threshold", tr_threshold },
528 { "errdiff", tr_errdiff },
529 { "ordered", tr_ordered, },
532 static struct value_name make_color_names[] =
534 { "none", mc_none, },
535 { "webmap", mc_web_map, },
536 { "addi", mc_addi, },
537 { "mediancut", mc_median_cut, },
540 static struct value_name translate_names[] =
543 { "giflib", pt_giflib, },
545 { "closest", pt_closest, },
546 { "perturb", pt_perturb, },
547 { "errdiff", pt_errdiff, },
550 static struct value_name errdiff_names[] =
552 { "floyd", ed_floyd, },
553 { "jarvis", ed_jarvis, },
554 { "stucki", ed_stucki, },
555 { "custom", ed_custom, },
558 static struct value_name orddith_names[] =
560 { "random", od_random, },
561 { "dot8", od_dot8, },
562 { "dot4", od_dot4, },
563 { "hline", od_hline, },
564 { "vline", od_vline, },
565 { "/line", od_slashline, },
566 { "slashline", od_slashline, },
567 { "\\line", od_backline, },
568 { "backline", od_backline, },
569 { "tiny", od_tiny, },
570 { "custom", od_custom, },
573 /* look through the hash for quantization options */
574 static void handle_quant_opts(i_quantize *quant, HV *hv)
576 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
582 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
584 sv = hv_fetch(hv, "transp", 6, 0);
585 if (sv && *sv && (str = SvPV(*sv, len))) {
587 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
589 if (quant->transp != tr_none) {
590 quant->tr_threshold = 127;
591 sv = hv_fetch(hv, "tr_threshold", 12, 0);
593 quant->tr_threshold = SvIV(*sv);
595 if (quant->transp == tr_errdiff) {
596 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
597 if (sv && *sv && (str = SvPV(*sv, len)))
598 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
600 if (quant->transp == tr_ordered) {
601 quant->tr_orddith = od_tiny;
602 sv = hv_fetch(hv, "tr_orddith", 10, 0);
603 if (sv && *sv && (str = SvPV(*sv, len)))
604 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
606 if (quant->tr_orddith == od_custom) {
607 sv = hv_fetch(hv, "tr_map", 6, 0);
608 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
609 AV *av = (AV*)SvRV(*sv);
610 len = av_len(av) + 1;
611 if (len > sizeof(quant->tr_custom))
612 len = sizeof(quant->tr_custom);
613 for (i = 0; i < len; ++i) {
614 SV **sv2 = av_fetch(av, i, 0);
616 quant->tr_custom[i] = SvIV(*sv2);
619 while (i < sizeof(quant->tr_custom))
620 quant->tr_custom[i++] = 0;
625 quant->make_colors = mc_addi;
626 sv = hv_fetch(hv, "make_colors", 11, 0);
627 if (sv && *sv && (str = SvPV(*sv, len))) {
629 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
631 sv = hv_fetch(hv, "colors", 6, 0);
632 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
633 /* needs to be an array of Imager::Color
634 note that the caller allocates the mc_color array and sets mc_size
636 AV *av = (AV *)SvRV(*sv);
637 quant->mc_count = av_len(av)+1;
638 if (quant->mc_count > quant->mc_size)
639 quant->mc_count = quant->mc_size;
640 for (i = 0; i < quant->mc_count; ++i) {
641 SV **sv1 = av_fetch(av, i, 0);
642 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
643 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
644 quant->mc_colors[i] = *col;
648 sv = hv_fetch(hv, "max_colors", 10, 0);
651 if (i <= quant->mc_size && i >= quant->mc_count)
655 quant->translate = pt_closest;
656 sv = hv_fetch(hv, "translate", 9, 0);
657 if (sv && *sv && (str = SvPV(*sv, len))) {
658 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
660 sv = hv_fetch(hv, "errdiff", 7, 0);
661 if (sv && *sv && (str = SvPV(*sv, len))) {
662 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
664 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
665 /* get the error diffusion map */
666 sv = hv_fetch(hv, "errdiff_width", 13, 0);
668 quant->ed_width = SvIV(*sv);
669 sv = hv_fetch(hv, "errdiff_height", 14, 0);
671 quant->ed_height = SvIV(*sv);
672 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
674 quant->ed_orig = SvIV(*sv);
675 if (quant->ed_width > 0 && quant->ed_height > 0) {
677 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
678 sv = hv_fetch(hv, "errdiff_map", 11, 0);
679 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
680 AV *av = (AV*)SvRV(*sv);
681 len = av_len(av) + 1;
682 if (len > quant->ed_width * quant->ed_height)
683 len = quant->ed_width * quant->ed_height;
684 for (i = 0; i < len; ++i) {
685 SV **sv2 = av_fetch(av, i, 0);
687 quant->ed_map[i] = SvIV(*sv2);
688 sum += quant->ed_map[i];
694 myfree(quant->ed_map);
696 quant->errdiff = ed_floyd;
700 sv = hv_fetch(hv, "perturb", 7, 0);
702 quant->perturb = SvIV(*sv);
705 static void cleanup_quant_opts(i_quantize *quant) {
706 myfree(quant->mc_colors);
708 myfree(quant->ed_map);
711 /* copies the color map from the hv into the colors member of the HV */
712 static void copy_colors_back(HV *hv, i_quantize *quant) {
718 sv = hv_fetch(hv, "colors", 6, 0);
719 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
722 ref = newRV_inc((SV*) av);
723 sv = hv_store(hv, "colors", 6, ref, 0);
726 av = (AV *)SvRV(*sv);
728 av_extend(av, quant->mc_count+1);
729 for (i = 0; i < quant->mc_count; ++i) {
730 i_color *in = quant->mc_colors+i;
731 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
732 work = sv_newmortal();
733 sv_setref_pv(work, "Imager::Color", (void *)c);
735 if (!av_store(av, i, work)) {
741 /* loads the segments of a fountain fill into an array */
742 static i_fountain_seg *
743 load_fount_segs(AV *asegs, int *count) {
744 /* Each element of segs must contain:
745 [ start, middle, end, c0, c1, segtype, colortrans ]
746 start, middle, end are doubles from 0 to 1
747 c0, c1 are Imager::Color::Float or Imager::Color objects
748 segtype, colortrans are ints
752 i_fountain_seg *segs;
756 *count = av_len(asegs)+1;
758 croak("i_fountain must have at least one segment");
759 segs = mymalloc(sizeof(i_fountain_seg) * *count);
760 for(i = 0; i < *count; i++) {
761 SV **sv1 = av_fetch(asegs, i, 0);
762 if (!sv1 || !*sv1 || !SvROK(*sv1)
763 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
765 croak("i_fountain: segs must be an arrayref of arrayrefs");
767 aseg = (AV *)SvRV(*sv1);
768 if (av_len(aseg) != 7-1) {
770 croak("i_fountain: a segment must have 7 members");
772 for (j = 0; j < 3; ++j) {
773 SV **sv2 = av_fetch(aseg, j, 0);
776 croak("i_fountain: XS error");
778 work[j] = SvNV(*sv2);
780 segs[i].start = work[0];
781 segs[i].middle = work[1];
782 segs[i].end = work[2];
783 for (j = 0; j < 2; ++j) {
784 SV **sv3 = av_fetch(aseg, 3+j, 0);
785 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
786 (!sv_derived_from(*sv3, "Imager::Color")
787 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
789 croak("i_fountain: segs must contain colors in elements 3 and 4");
791 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
792 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
795 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
797 for (ch = 0; ch < MAXCHANNELS; ++ch) {
798 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
802 for (j = 0; j < 2; ++j) {
803 SV **sv2 = av_fetch(aseg, j+5, 0);
806 croak("i_fountain: XS error");
808 worki[j] = SvIV(*sv2);
810 segs[i].type = worki[0];
811 segs[i].color = worki[1];
817 /* validates the indexes supplied to i_ppal
819 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
824 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
825 int color_count = i_colorcount(im);
828 if (color_count == -1)
829 croak("i_plin() called on direct color image");
831 for (i = 0; i < count; ++i) {
832 if (indexes[i] >= color_count) {
833 croak("i_plin() called with out of range color index %d (max %d)",
834 indexes[i], color_count-1);
840 /* I don't think ICLF_* names belong at the C interface
841 this makes the XS code think we have them, to let us avoid
842 putting function bodies in the XS code
844 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
845 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
848 /* the m_init_log() function was called init_log(), renamed to reduce
849 potential naming conflicts */
850 #define init_log m_init_log
852 #if i_int_hlines_testing()
854 typedef i_int_hlines *Imager__Internal__Hlines;
856 static i_int_hlines *
857 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
858 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
859 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
864 static i_int_hlines *
865 i_int_hlines_new_img(i_img *im) {
866 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
867 i_int_init_hlines_img(result, im);
873 i_int_hlines_DESTROY(i_int_hlines *hlines) {
874 i_int_hlines_destroy(hlines);
878 static int seg_compare(const void *vleft, const void *vright) {
879 const i_int_hline_seg *left = vleft;
880 const i_int_hline_seg *right = vright;
882 return left->minx - right->minx;
886 i_int_hlines_dump(i_int_hlines *hlines) {
887 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
888 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
891 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
892 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
895 /* sort the segments, if any */
897 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
899 sv_catpvf(dump, " %d (%d):", y, entry->count);
900 for (i = 0; i < entry->count; ++i) {
901 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
902 entry->segs[i].x_limit);
904 sv_catpv(dump, "\n");
914 #define i_exif_enabled() 1
916 #define i_exif_enabled() 0
919 /* trying to use more C style names, map them here */
920 #define i_io_DESTROY(ig) io_glue_destroy(ig)
922 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
925 ICL_new_internal(r,g,b,a)
937 ICL_set_internal(cl,r,g,b,a)
944 ICL_set_internal(cl, r, g, b, a);
958 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
959 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
960 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
961 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
967 RETVAL = mymalloc(sizeof(i_color));
969 i_hsv_to_rgb(RETVAL);
977 RETVAL = mymalloc(sizeof(i_color));
979 i_rgb_to_hsv(RETVAL);
985 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
988 ICLF_new_internal(r, g, b, a)
996 Imager::Color::Float cl
1000 Imager::Color::Float cl
1004 EXTEND(SP, MAXCHANNELS);
1005 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1006 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1007 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1011 ICLF_set_internal(cl,r,g,b,a)
1012 Imager::Color::Float cl
1025 Imager::Color::Float
1027 Imager::Color::Float c
1029 RETVAL = mymalloc(sizeof(i_fcolor));
1031 i_hsv_to_rgbf(RETVAL);
1035 Imager::Color::Float
1037 Imager::Color::Float c
1039 RETVAL = mymalloc(sizeof(i_fcolor));
1041 i_rgb_to_hsvf(RETVAL);
1045 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1059 MODULE = Imager PACKAGE = Imager
1078 SvPV(ST(0), length);
1079 SvREFCNT_inc(ST(0));
1080 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1085 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1094 cbd = mymalloc(sizeof(struct cbdata));
1095 SvREFCNT_inc(writecb);
1096 cbd->writecb = writecb;
1097 SvREFCNT_inc(readcb);
1098 cbd->readcb = readcb;
1099 SvREFCNT_inc(seekcb);
1100 cbd->seekcb = seekcb;
1101 SvREFCNT_inc(closecb);
1102 cbd->closecb = closecb;
1103 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1104 if (maxwrite > CBDATA_BUFSIZE)
1105 maxwrite = CBDATA_BUFSIZE;
1106 cbd->maxlength = maxwrite;
1107 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1116 unsigned char* data;
1120 tlength = io_slurp(ig, &data);
1122 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1127 i_set_image_file_limits(width, height, bytes)
1133 i_get_image_file_limits()
1135 int width, height, bytes;
1137 if (i_get_image_file_limits(&width, &height, &bytes)) {
1139 PUSHs(sv_2mortal(newSViv(width)));
1140 PUSHs(sv_2mortal(newSViv(height)));
1141 PUSHs(sv_2mortal(newSViv(bytes)));
1144 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1147 i_io_write(ig, data_sv)
1155 if (SvUTF8(data_sv)) {
1156 data_sv = sv_2mortal(newSVsv(data_sv));
1157 /* yes, we want this to croak() if the SV can't be downgraded */
1158 sv_utf8_downgrade(data_sv, FALSE);
1161 data = SvPV(data_sv, size);
1162 RETVAL = i_io_write(ig, data, size);
1167 i_io_read(ig, buffer_sv, size)
1176 croak("size negative in call to i_io_read()");
1177 /* prevent an undefined value warning if they supplied an
1179 Orginally conditional on !SvOK(), but this will prevent the
1180 downgrade from croaking */
1181 sv_setpvn(buffer_sv, "", 0);
1183 if (SvUTF8(buffer_sv))
1184 sv_utf8_downgrade(buffer_sv, FALSE);
1186 buffer = SvGROW(buffer_sv, size+1);
1187 result = i_io_read(ig, buffer, size);
1189 SvCUR_set(buffer_sv, result);
1190 *SvEND(buffer_sv) = '\0';
1191 SvPOK_only(buffer_sv);
1193 PUSHs(sv_2mortal(newSViv(result)));
1199 i_io_read2(ig, size)
1208 croak("size negative in call to i_io_read2()");
1209 buffer_sv = newSV(size);
1210 buffer = SvGROW(buffer_sv, size+1);
1211 result = i_io_read(ig, buffer, size);
1213 SvCUR_set(buffer_sv, result);
1214 *SvEND(buffer_sv) = '\0';
1215 SvPOK_only(buffer_sv);
1217 PUSHs(sv_2mortal(buffer_sv));
1221 SvREFCNT_dec(buffer_sv);
1225 i_io_seek(ig, position, whence)
1238 MODULE = Imager PACKAGE = Imager
1249 while( (item=i_format_list[i++]) != NULL ) {
1251 PUSHs(sv_2mortal(newSVpv(item,0)));
1268 i_img_empty_ch(im,x,y,ch)
1275 i_sametype(im, x, y)
1281 i_sametype_chans(im, x, y, channels)
1288 i_init_log(name,level)
1293 i_log_entry(string,level)
1312 i_img_info(im,info);
1314 PUSHs(sv_2mortal(newSViv(info[0])));
1315 PUSHs(sv_2mortal(newSViv(info[1])));
1316 PUSHs(sv_2mortal(newSViv(info[2])));
1317 PUSHs(sv_2mortal(newSViv(info[3])));
1323 i_img_setmask(im,ch_mask)
1332 i_img_getchannels(im)
1341 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1346 i_line(im,x1,y1,x2,y2,val,endp)
1356 i_line_aa(im,x1,y1,x2,y2,val,endp)
1366 i_box(im,x1,y1,x2,y2,val)
1375 i_box_filled(im,x1,y1,x2,y2,val)
1384 i_box_cfill(im,x1,y1,x2,y2,fill)
1390 Imager::FillHandle fill
1393 i_arc(im,x,y,rad,d1,d2,val)
1403 i_arc_aa(im,x,y,rad,d1,d2,val)
1413 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1420 Imager::FillHandle fill
1423 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1430 Imager::FillHandle fill
1434 i_circle_aa(im,x,y,rad,val)
1444 i_bezier_multi(im,xc,yc,val)
1457 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1458 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1459 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1460 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1461 av1=(AV*)SvRV(ST(1));
1462 av2=(AV*)SvRV(ST(2));
1463 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1465 x=mymalloc( len*sizeof(double) );
1466 y=mymalloc( len*sizeof(double) );
1467 for(i=0;i<len;i++) {
1468 sv1=(*(av_fetch(av1,i,0)));
1469 sv2=(*(av_fetch(av2,i,0)));
1470 x[i]=(double)SvNV(sv1);
1471 y[i]=(double)SvNV(sv2);
1473 i_bezier_multi(im,len,x,y,val);
1479 i_poly_aa(im,xc,yc,val)
1492 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1493 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1494 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1495 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1496 av1=(AV*)SvRV(ST(1));
1497 av2=(AV*)SvRV(ST(2));
1498 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1500 x=mymalloc( len*sizeof(double) );
1501 y=mymalloc( len*sizeof(double) );
1502 for(i=0;i<len;i++) {
1503 sv1=(*(av_fetch(av1,i,0)));
1504 sv2=(*(av_fetch(av2,i,0)));
1505 x[i]=(double)SvNV(sv1);
1506 y[i]=(double)SvNV(sv2);
1508 i_poly_aa(im,len,x,y,val);
1513 i_poly_aa_cfill(im,xc,yc,fill)
1515 Imager::FillHandle fill
1525 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1526 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1527 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1528 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1529 av1=(AV*)SvRV(ST(1));
1530 av2=(AV*)SvRV(ST(2));
1531 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1533 x=mymalloc( len*sizeof(double) );
1534 y=mymalloc( len*sizeof(double) );
1535 for(i=0;i<len;i++) {
1536 sv1=(*(av_fetch(av1,i,0)));
1537 sv2=(*(av_fetch(av2,i,0)));
1538 x[i]=(double)SvNV(sv1);
1539 y[i]=(double)SvNV(sv2);
1541 i_poly_aa_cfill(im,len,x,y,fill);
1548 i_flood_fill(im,seedx,seedy,dcol)
1555 i_flood_cfill(im,seedx,seedy,fill)
1559 Imager::FillHandle fill
1562 i_flood_fill_border(im,seedx,seedy,dcol, border)
1567 Imager::Color border
1570 i_flood_cfill_border(im,seedx,seedy,fill, border)
1574 Imager::FillHandle fill
1575 Imager::Color border
1579 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1591 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1608 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1620 i_flipxy(im, direction)
1625 i_rotate90(im, degrees)
1630 i_rotate_exact(im, amount, ...)
1634 i_color *backp = NULL;
1635 i_fcolor *fbackp = NULL;
1639 /* extract the bg colors if any */
1640 /* yes, this is kind of strange */
1641 for (i = 2; i < items; ++i) {
1643 if (sv_derived_from(sv1, "Imager::Color")) {
1644 IV tmp = SvIV((SV*)SvRV(sv1));
1645 backp = INT2PTR(i_color *, tmp);
1647 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1648 IV tmp = SvIV((SV*)SvRV(sv1));
1649 fbackp = INT2PTR(i_fcolor *, tmp);
1652 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1657 i_matrix_transform(im, xsize, ysize, matrix, ...)
1667 i_color *backp = NULL;
1668 i_fcolor *fbackp = NULL;
1670 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1671 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1672 av=(AV*)SvRV(ST(3));
1676 for (i = 0; i < len; ++i) {
1677 sv1=(*(av_fetch(av,i,0)));
1678 matrix[i] = SvNV(sv1);
1682 /* extract the bg colors if any */
1683 /* yes, this is kind of strange */
1684 for (i = 4; i < items; ++i) {
1686 if (sv_derived_from(sv1, "Imager::Color")) {
1687 IV tmp = SvIV((SV*)SvRV(sv1));
1688 backp = INT2PTR(i_color *, tmp);
1690 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1691 IV tmp = SvIV((SV*)SvRV(sv1));
1692 fbackp = INT2PTR(i_fcolor *, tmp);
1695 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1700 i_gaussian(im,stdev)
1705 i_unsharp_mask(im,stdev,scale)
1720 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1721 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1722 av=(AV*)SvRV(ST(1));
1724 coeff=mymalloc( len*sizeof(float) );
1725 for(i=0;i<len;i++) {
1726 sv1=(*(av_fetch(av,i,0)));
1727 coeff[i]=(float)SvNV(sv1);
1729 i_conv(im,coeff,len);
1733 i_convert(im, src, coeff)
1746 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1747 croak("i_convert: parameter 3 must be an arrayref\n");
1748 avmain = (AV*)SvRV(ST(2));
1749 outchan = av_len(avmain)+1;
1750 /* find the biggest */
1752 for (j=0; j < outchan; ++j) {
1753 temp = av_fetch(avmain, j, 0);
1754 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1755 avsub = (AV*)SvRV(*temp);
1756 len = av_len(avsub)+1;
1761 coeff = mymalloc(sizeof(float) * outchan * inchan);
1762 for (j = 0; j < outchan; ++j) {
1763 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1764 len = av_len(avsub)+1;
1765 for (i = 0; i < len; ++i) {
1766 temp = av_fetch(avsub, i, 0);
1768 coeff[i+j*inchan] = SvNV(*temp);
1770 coeff[i+j*inchan] = 0;
1773 coeff[i++ + j*inchan] = 0;
1775 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1785 unsigned int mask = 0;
1791 unsigned char (*maps)[256];
1793 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1794 croak("i_map: parameter 2 must be an arrayref\n");
1795 avmain = (AV*)SvRV(ST(1));
1796 len = av_len(avmain)+1;
1797 if (im->channels < len) len = im->channels;
1799 maps = mymalloc( len * sizeof(unsigned char [256]) );
1801 for (j=0; j<len ; j++) {
1802 temp = av_fetch(avmain, j, 0);
1803 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1804 avsub = (AV*)SvRV(*temp);
1805 if(av_len(avsub) != 255) continue;
1807 for (i=0; i<256 ; i++) {
1809 temp = av_fetch(avsub, i, 0);
1810 val = temp ? SvIV(*temp) : 0;
1812 if (val>255) val = 255;
1817 i_map(im, maps, mask);
1830 i_init_fonts(t1log=0)
1845 i_t1_destroy(font_id)
1850 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1869 str = SvPV(str_sv, len);
1870 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1877 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1886 int cords[BOUNDING_BOX_COUNT];
1894 str = SvPV(str_sv, len);
1895 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1898 for (i = 0; i < rc; ++i)
1899 PUSHs(sv_2mortal(newSViv(cords[i])));
1905 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1924 str = SvPV(str_sv, len);
1925 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1931 i_t1_has_chars(handle, text_sv, utf8 = 0)
1943 if (SvUTF8(text_sv))
1946 text = SvPV(text_sv, len);
1947 work = mymalloc(len);
1948 count = i_t1_has_chars(handle, text, len, utf8, work);
1949 if (GIMME_V == G_ARRAY) {
1951 for (i = 0; i < count; ++i) {
1952 PUSHs(sv_2mortal(newSViv(work[i])));
1957 PUSHs(sv_2mortal(newSVpv(work, count)));
1962 i_t1_face_name(handle)
1968 len = i_t1_face_name(handle, name, sizeof(name));
1971 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1975 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1986 if (SvUTF8(text_sv))
1989 text = SvPV(text_sv, work_len);
1994 ch = i_utf8_advance(&text, &len);
1996 i_push_error(0, "invalid UTF8 character");
2005 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
2006 PUSHs(sv_2mortal(newSVpv(name, 0)));
2009 PUSHs(&PL_sv_undef);
2023 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2025 #define TT_DESTROY(handle) i_tt_destroy(handle)
2029 Imager::Font::TT handle
2032 MODULE = Imager PACKAGE = Imager
2036 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2037 Imager::Font::TT handle
2055 str = SvPV(str_sv, len);
2056 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2057 len, smooth, utf8, align);
2063 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2064 Imager::Font::TT handle
2082 str = SvPV(str_sv, len);
2083 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2084 smooth, utf8, align);
2090 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2091 Imager::Font::TT handle
2096 int cords[BOUNDING_BOX_COUNT],rc;
2105 str = SvPV(str_sv, len);
2106 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2108 for (i = 0; i < rc; ++i) {
2109 PUSHs(sv_2mortal(newSViv(cords[i])));
2114 i_tt_has_chars(handle, text_sv, utf8)
2115 Imager::Font::TT handle
2126 if (SvUTF8(text_sv))
2129 text = SvPV(text_sv, len);
2130 work = mymalloc(len);
2131 count = i_tt_has_chars(handle, text, len, utf8, work);
2132 if (GIMME_V == G_ARRAY) {
2134 for (i = 0; i < count; ++i) {
2135 PUSHs(sv_2mortal(newSViv(work[i])));
2140 PUSHs(sv_2mortal(newSVpv(work, count)));
2145 i_tt_dump_names(handle)
2146 Imager::Font::TT handle
2149 i_tt_face_name(handle)
2150 Imager::Font::TT handle
2155 len = i_tt_face_name(handle, name, sizeof(name));
2158 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2162 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2163 Imager::Font::TT handle
2174 if (SvUTF8(text_sv))
2177 text = SvPV(text_sv, work_len);
2182 ch = i_utf8_advance(&text, &len);
2184 i_push_error(0, "invalid UTF8 character");
2193 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2194 PUSHs(sv_2mortal(newSVpv(name, 0)));
2197 PUSHs(&PL_sv_undef);
2206 i_writejpeg_wiol(im, ig, qfactor)
2222 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2223 if (iptc_itext == NULL) {
2226 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2231 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2233 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2244 i_test_format_probe(ig, length)
2253 i_readtiff_wiol(ig, length, page=0)
2259 i_readtiff_multi_wiol(ig, length)
2267 imgs = i_readtiff_multi_wiol(ig, length, &count);
2270 for (i = 0; i < count; ++i) {
2271 SV *sv = sv_newmortal();
2272 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2280 i_writetiff_wiol(im, ig)
2285 i_writetiff_multi_wiol(ig, ...)
2293 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2294 img_count = items - 1;
2296 if (img_count < 1) {
2299 i_push_error(0, "You need to specify images to save");
2302 imgs = mymalloc(sizeof(i_img *) * img_count);
2303 for (i = 0; i < img_count; ++i) {
2306 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2307 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2311 i_push_error(0, "Only images can be saved");
2318 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2326 i_writetiff_wiol_faxable(im, ig, fine)
2332 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2341 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2342 img_count = items - 2;
2344 if (img_count < 1) {
2347 i_push_error(0, "You need to specify images to save");
2350 imgs = mymalloc(sizeof(i_img *) * img_count);
2351 for (i = 0; i < img_count; ++i) {
2354 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2355 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2359 i_push_error(0, "Only images can be saved");
2366 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2374 #endif /* HAVE_LIBTIFF */
2380 i_readpng_wiol(ig, length)
2386 i_writepng_wiol(im, ig)
2399 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2402 i_writegif(im,fd,colors,pixdev,fixed)
2409 Imager__Color fixed;
2416 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2417 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2418 av=(AV*)SvRV(ST(4));
2419 fixedlen=av_len(av)+1;
2420 fixed=mymalloc( fixedlen*sizeof(i_color) );
2421 for(i=0;i<fixedlen;i++) {
2422 sv1=(*(av_fetch(av,i,0)));
2423 if (sv_derived_from(sv1, "Imager::Color")) {
2424 Itmp = SvIV((SV*)SvRV(sv1));
2425 tmp = INT2PTR(i_color*, Itmp);
2426 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2429 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2431 ST(0) = sv_newmortal();
2432 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2433 else sv_setiv(ST(0), (IV)RETVAL);
2439 i_writegifmc(im,fd,colors)
2446 i_writegif_gen(fd, ...)
2451 i_img **imgs = NULL;
2457 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2458 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2459 croak("i_writegif_gen: Second argument must be a hash ref");
2460 hv = (HV *)SvRV(ST(1));
2461 memset(&quant, 0, sizeof(quant));
2462 quant.mc_size = 256;
2463 handle_quant_opts(&quant, hv);
2464 img_count = items - 2;
2466 if (img_count < 1) {
2469 i_push_error(0, "You need to specify images to save");
2472 imgs = mymalloc(sizeof(i_img *) * img_count);
2473 for (i = 0; i < img_count; ++i) {
2476 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2477 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2481 i_push_error(0, "Only images can be saved");
2487 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2491 copy_colors_back(hv, &quant);
2494 ST(0) = sv_newmortal();
2495 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2496 else sv_setiv(ST(0), (IV)RETVAL);
2497 cleanup_quant_opts(&quant);
2501 i_writegif_callback(cb, maxbuffer,...)
2505 i_img **imgs = NULL;
2512 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2513 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2514 croak("i_writegif_callback: Second argument must be a hash ref");
2515 hv = (HV *)SvRV(ST(2));
2516 memset(&quant, 0, sizeof(quant));
2517 quant.mc_size = 256;
2518 handle_quant_opts(&quant, hv);
2519 img_count = items - 3;
2521 if (img_count < 1) {
2525 imgs = mymalloc(sizeof(i_img *) * img_count);
2526 for (i = 0; i < img_count; ++i) {
2529 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2530 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2539 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2543 copy_colors_back(hv, &quant);
2546 ST(0) = sv_newmortal();
2547 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2548 else sv_setiv(ST(0), (IV)RETVAL);
2549 cleanup_quant_opts(&quant);
2552 i_writegif_wiol(ig, opts,...)
2556 i_img **imgs = NULL;
2562 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2563 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2564 croak("i_writegif_callback: Second argument must be a hash ref");
2565 hv = (HV *)SvRV(ST(1));
2566 memset(&quant, 0, sizeof(quant));
2567 quant.mc_size = 256;
2568 handle_quant_opts(&quant, hv);
2569 img_count = items - 2;
2571 if (img_count < 1) {
2575 imgs = mymalloc(sizeof(i_img *) * img_count);
2576 for (i = 0; i < img_count; ++i) {
2579 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2580 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2588 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2592 copy_colors_back(hv, &quant);
2595 ST(0) = sv_newmortal();
2596 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2597 else sv_setiv(ST(0), (IV)RETVAL);
2598 cleanup_quant_opts(&quant);
2611 colour_table = NULL;
2614 if(GIMME_V == G_ARRAY) {
2615 rimg = i_readgif(fd,&colour_table,&colours);
2617 /* don't waste time with colours if they aren't wanted */
2618 rimg = i_readgif(fd,NULL,NULL);
2621 if (colour_table == NULL) {
2624 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2627 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2628 /* I don't know if I have the reference counts right or not :( */
2629 /* Neither do I :-) */
2630 /* No Idea here either */
2633 av_extend(ct, colours);
2634 for(q=0; q<colours; q++) {
2636 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2637 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2639 myfree(colour_table);
2643 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2645 PUSHs(newRV_noinc((SV*)ct));
2659 colour_table = NULL;
2662 if(GIMME_V == G_ARRAY) {
2663 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2665 /* don't waste time with colours if they aren't wanted */
2666 rimg = i_readgif_wiol(ig,NULL,NULL);
2669 if (colour_table == NULL) {
2672 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2675 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2676 /* I don't know if I have the reference counts right or not :( */
2677 /* Neither do I :-) */
2678 /* No Idea here either */
2681 av_extend(ct, colours);
2682 for(q=0; q<colours; q++) {
2684 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2685 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2687 myfree(colour_table);
2691 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2693 PUSHs(newRV_noinc((SV*)ct));
2697 i_readgif_single_wiol(ig, page=0)
2702 i_readgif_scalar(...)
2714 data = (char *)SvPV(ST(0), length);
2718 if(GIMME_V == G_ARRAY) {
2719 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2721 /* don't waste time with colours if they aren't wanted */
2722 rimg=i_readgif_scalar(data,length,NULL,NULL);
2725 if (colour_table == NULL) {
2728 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2731 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2732 /* I don't know if I have the reference counts right or not :( */
2733 /* Neither do I :-) */
2735 av_extend(ct, colours);
2736 for(q=0; q<colours; q++) {
2738 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2739 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2741 myfree(colour_table);
2745 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2747 PUSHs(newRV_noinc((SV*)ct));
2751 i_readgif_callback(...)
2766 if(GIMME_V == G_ARRAY) {
2767 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2769 /* don't waste time with colours if they aren't wanted */
2770 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2773 if (colour_table == NULL) {
2776 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2779 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2780 /* I don't know if I have the reference counts right or not :( */
2781 /* Neither do I :-) */
2782 /* Neither do I - maybe I'll move this somewhere */
2784 av_extend(ct, colours);
2785 for(q=0; q<colours; q++) {
2787 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2788 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2790 myfree(colour_table);
2794 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2796 PUSHs(newRV_noinc((SV*)ct));
2807 imgs = i_readgif_multi(fd, &count);
2810 for (i = 0; i < count; ++i) {
2811 SV *sv = sv_newmortal();
2812 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2819 i_readgif_multi_scalar(data)
2827 data = (char *)SvPV(ST(0), length);
2828 imgs = i_readgif_multi_scalar(data, length, &count);
2831 for (i = 0; i < count; ++i) {
2832 SV *sv = sv_newmortal();
2833 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2840 i_readgif_multi_callback(cb)
2848 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2851 for (i = 0; i < count; ++i) {
2852 SV *sv = sv_newmortal();
2853 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2860 i_readgif_multi_wiol(ig)
2867 imgs = i_readgif_multi_wiol(ig, &count);
2870 for (i = 0; i < count; ++i) {
2871 SV *sv = sv_newmortal();
2872 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2884 i_readpnm_wiol(ig, length)
2890 i_writeppm_wiol(im, ig)
2896 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2905 i_writeraw_wiol(im,ig)
2910 i_writebmp_wiol(im,ig)
2920 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2929 idlen = SvCUR(ST(4));
2930 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2936 i_readtga_wiol(ig, length)
2942 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2951 idlen = SvCUR(ST(4));
2952 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2958 i_readrgb_wiol(ig, length)
2965 i_scaleaxis(im,Value,Axis)
2971 i_scale_nn(im,scx,scy)
2977 i_scale_mixing(im, width, height)
2987 i_count_colors(im,maxc)
2993 i_transform(im,opx,opy,parm)
3006 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
3007 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
3008 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
3009 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
3010 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
3011 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
3012 av=(AV*)SvRV(ST(1));
3014 opx=mymalloc( opxl*sizeof(int) );
3015 for(i=0;i<opxl;i++) {
3016 sv1=(*(av_fetch(av,i,0)));
3017 opx[i]=(int)SvIV(sv1);
3019 av=(AV*)SvRV(ST(2));
3021 opy=mymalloc( opyl*sizeof(int) );
3022 for(i=0;i<opyl;i++) {
3023 sv1=(*(av_fetch(av,i,0)));
3024 opy[i]=(int)SvIV(sv1);
3026 av=(AV*)SvRV(ST(3));
3027 parmlen=av_len(av)+1;
3028 parm=mymalloc( parmlen*sizeof(double) );
3029 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
3030 sv1=(*(av_fetch(av,i,0)));
3031 parm[i]=(double)SvNV(sv1);
3033 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
3037 ST(0) = sv_newmortal();
3038 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3039 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3042 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
3067 in_imgs_count = av_len(av_in_imgs)+1;
3068 for (i = 0; i < in_imgs_count; ++i) {
3069 sv1 = *av_fetch(av_in_imgs, i, 0);
3070 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3071 croak("sv_in_img must contain only images");
3074 if (in_imgs_count > 0) {
3075 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
3076 for (i = 0; i < in_imgs_count; ++i) {
3077 sv1 = *av_fetch(av_in_imgs,i,0);
3078 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3079 croak("Parameter 5 must contain only images");
3081 tmp = SvIV((SV*)SvRV(sv1));
3082 in_imgs[i] = INT2PTR(i_img*, tmp);
3086 /* no input images */
3089 /* default the output size from the first input if possible */
3091 width = SvIV(sv_width);
3092 else if (in_imgs_count)
3093 width = in_imgs[0]->xsize;
3095 croak("No output image width supplied");
3097 if (SvOK(sv_height))
3098 height = SvIV(sv_height);
3099 else if (in_imgs_count)
3100 height = in_imgs[0]->ysize;
3102 croak("No output image height supplied");
3104 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3105 if (ops_len % sizeof(struct rm_op))
3106 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3107 ops_count = ops_len / sizeof(struct rm_op);
3109 n_regs_count = av_len(av_n_regs)+1;
3110 n_regs = mymalloc(n_regs_count * sizeof(double));
3111 for (i = 0; i < n_regs_count; ++i) {
3112 sv1 = *av_fetch(av_n_regs,i,0);
3114 n_regs[i] = SvNV(sv1);
3116 c_regs_count = av_len(av_c_regs)+1;
3117 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3118 /* I don't bother initializing the colou?r registers */
3120 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3121 n_regs, n_regs_count,
3122 c_regs, c_regs_count, in_imgs, in_imgs_count);
3127 ST(0) = sv_newmortal();
3128 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3129 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3133 i_contrast(im,intensity)
3142 i_noise(im,amount,type)
3148 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3158 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3177 i_postlevels(im,levels)
3187 i_watermark(im,wmark,tx,ty,pixdiff)
3189 Imager::ImgRaw wmark
3196 i_autolevels(im,lsat,usat,skew)
3203 i_radnoise(im,xo,yo,rscale,ascale)
3211 i_turbnoise(im, xo, yo, scale)
3234 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3235 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3236 croak("i_gradgen: Second argument must be an array ref");
3237 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3238 croak("i_gradgen: Third argument must be an array ref");
3239 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3240 croak("i_gradgen: Fourth argument must be an array ref");
3241 axx = (AV *)SvRV(ST(1));
3242 ayy = (AV *)SvRV(ST(2));
3243 ac = (AV *)SvRV(ST(3));
3244 dmeasure = (int)SvIV(ST(4));
3246 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3247 num = num <= av_len(ac) ? num : av_len(ac);
3249 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3250 xo = mymalloc( sizeof(int) * num );
3251 yo = mymalloc( sizeof(int) * num );
3252 ival = mymalloc( sizeof(i_color) * num );
3253 for(i = 0; i<num; i++) {
3254 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3255 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3256 sv = *av_fetch(ac, i, 0);
3257 if ( !sv_derived_from(sv, "Imager::Color") ) {
3258 free(axx); free(ayy); free(ac);
3259 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3261 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3263 i_gradgen(im, num, xo, yo, ival, dmeasure);
3269 i_diff_image(im, im2, mindist=0)
3275 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3285 double ssample_param
3289 i_fountain_seg *segs;
3291 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3292 croak("i_fountain: argument 11 must be an array ref");
3294 asegs = (AV *)SvRV(ST(10));
3295 segs = load_fount_segs(asegs, &count);
3296 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3297 super_sample, ssample_param, count, segs);
3303 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3312 double ssample_param
3316 i_fountain_seg *segs;
3318 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3319 croak("i_fountain: argument 11 must be an array ref");
3321 asegs = (AV *)SvRV(ST(9));
3322 segs = load_fount_segs(asegs, &count);
3323 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3324 super_sample, ssample_param, count, segs);
3337 errors = i_errors();
3339 while (errors[i].msg) {
3341 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3342 if (!av_store(av, 0, sv)) {
3345 sv = newSViv(errors[i].code);
3346 if (!av_store(av, 1, sv)) {
3349 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3357 i_push_error(code, msg)
3362 i_nearest_color(im, ...)
3377 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3378 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3379 croak("i_nearest_color: Second argument must be an array ref");
3380 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3381 croak("i_nearest_color: Third argument must be an array ref");
3382 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3383 croak("i_nearest_color: Fourth argument must be an array ref");
3384 axx = (AV *)SvRV(ST(1));
3385 ayy = (AV *)SvRV(ST(2));
3386 ac = (AV *)SvRV(ST(3));
3387 dmeasure = (int)SvIV(ST(4));
3389 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3390 num = num <= av_len(ac) ? num : av_len(ac);
3392 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3393 xo = mymalloc( sizeof(int) * num );
3394 yo = mymalloc( sizeof(int) * num );
3395 ival = mymalloc( sizeof(i_color) * num );
3396 for(i = 0; i<num; i++) {
3397 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3398 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3399 sv = *av_fetch(ac, i, 0);
3400 if ( !sv_derived_from(sv, "Imager::Color") ) {
3401 free(axx); free(ayy); free(ac);
3402 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3404 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3406 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3420 rc=DSO_open(filename,&evstr);
3424 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3425 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3428 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3434 DSO_close(dso_handle)
3438 DSO_funclist(dso_handle_v)
3442 DSO_handle *dso_handle;
3444 dso_handle=(DSO_handle*)dso_handle_v;
3446 while( dso_handle->function_list[i].name != NULL) {
3448 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3450 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3455 DSO_call(handle,func_index,hv)
3461 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3462 hv=(HV*)SvRV(ST(2));
3463 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3464 DSO_call( (DSO_handle *)handle,func_index,hv);
3469 i_get_pixel(im, x, y)
3476 color = (i_color *)mymalloc(sizeof(i_color));
3477 if (i_gpix(im, x, y, color) == 0) {
3478 RETVAL = NEWSV(0, 0);
3479 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3483 RETVAL = &PL_sv_undef;
3490 i_ppix(im, x, y, cl)
3497 i_img_pal_new(x, y, channels, maxpal)
3504 i_img_to_pal(src, quant)
3510 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3511 croak("i_img_to_pal: second argument must be a hash ref");
3512 hv = (HV *)SvRV(ST(1));
3513 memset(&quant, 0, sizeof(quant));
3514 quant.mc_size = 256;
3515 handle_quant_opts(&quant, hv);
3516 RETVAL = i_img_to_pal(src, &quant);
3518 copy_colors_back(hv, &quant);
3520 cleanup_quant_opts(&quant);
3539 work = mymalloc((r-l) * sizeof(i_palidx));
3540 count = i_gpal(im, l, r, y, work);
3541 if (GIMME_V == G_ARRAY) {
3543 for (i = 0; i < count; ++i) {
3544 PUSHs(sv_2mortal(newSViv(work[i])));
3549 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3554 if (GIMME_V != G_ARRAY) {
3556 PUSHs(&PL_sv_undef);
3561 i_ppal(im, l, y, ...)
3572 work = mymalloc(sizeof(i_palidx) * (items-3));
3573 for (i=0; i < items-3; ++i) {
3574 work[i] = SvIV(ST(i+3));
3576 validate_i_ppal(im, work, items - 3);
3577 RETVAL = i_ppal(im, l, l+items-3, y, work);
3587 i_ppal_p(im, l, y, data)
3593 i_palidx const *work;
3598 work = (i_palidx const *)SvPV(data, len);
3599 len /= sizeof(i_palidx);
3601 validate_i_ppal(im, work, len);
3602 RETVAL = i_ppal(im, l, l+len, y, work);
3611 i_addcolors(im, ...)
3619 croak("i_addcolors: no colors to add");
3620 colors = mymalloc((items-1) * sizeof(i_color));
3621 for (i=0; i < items-1; ++i) {
3622 if (sv_isobject(ST(i+1))
3623 && sv_derived_from(ST(i+1), "Imager::Color")) {
3624 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3625 colors[i] = *INT2PTR(i_color *, tmp);
3629 croak("i_addcolor: pixels must be Imager::Color objects");
3632 index = i_addcolors(im, colors, items-1);
3635 RETVAL = newSVpv("0 but true", 0);
3637 else if (index == -1) {
3638 RETVAL = &PL_sv_undef;
3641 RETVAL = newSViv(index);
3647 i_setcolors(im, index, ...)
3655 croak("i_setcolors: no colors to add");
3656 colors = mymalloc((items-2) * sizeof(i_color));
3657 for (i=0; i < items-2; ++i) {
3658 if (sv_isobject(ST(i+2))
3659 && sv_derived_from(ST(i+2), "Imager::Color")) {
3660 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3661 colors[i] = *INT2PTR(i_color *, tmp);
3665 croak("i_setcolors: pixels must be Imager::Color objects");
3668 RETVAL = i_setcolors(im, index, colors, items-2);
3674 i_getcolors(im, index, ...)
3683 croak("i_getcolors: too many arguments");
3685 count = SvIV(ST(2));
3687 croak("i_getcolors: count must be positive");
3688 colors = mymalloc(sizeof(i_color) * count);
3689 if (i_getcolors(im, index, colors, count)) {
3690 for (i = 0; i < count; ++i) {
3692 SV *sv = sv_newmortal();
3693 pv = mymalloc(sizeof(i_color));
3695 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3711 i_findcolor(im, color)
3717 if (i_findcolor(im, color, &index)) {
3718 RETVAL = newSViv(index);
3721 RETVAL = &PL_sv_undef;
3739 i_gsamp(im, l, r, y, ...)
3751 croak("No channel numbers supplied to g_samp()");
3753 chan_count = items - 4;
3754 chans = mymalloc(sizeof(int) * chan_count);
3755 for (i = 0; i < chan_count; ++i)
3756 chans[i] = SvIV(ST(i+4));
3757 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3758 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3760 if (GIMME_V == G_ARRAY) {
3762 for (i = 0; i < count; ++i)
3763 PUSHs(sv_2mortal(newSViv(data[i])));
3767 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3772 if (GIMME_V != G_ARRAY) {
3774 PUSHs(&PL_sv_undef);
3780 i_img_masked_new(targ, mask, x, y, w, h)
3790 if (!sv_isobject(ST(1))
3791 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3792 croak("i_img_masked_new: parameter 2 must undef or an image");
3794 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3798 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3803 i_plin(im, l, y, ...)
3814 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3815 /* supplied as a byte string */
3816 work = (i_color *)SvPV(ST(3), len);
3817 count = len / sizeof(i_color);
3818 if (count * sizeof(i_color) != len) {
3819 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3821 RETVAL = i_plin(im, l, l+count, y, work);
3824 work = mymalloc(sizeof(i_color) * (items-3));
3825 for (i=0; i < items-3; ++i) {
3826 if (sv_isobject(ST(i+3))
3827 && sv_derived_from(ST(i+3), "Imager::Color")) {
3828 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3829 work[i] = *INT2PTR(i_color *, tmp);
3833 croak("i_plin: pixels must be Imager::Color objects");
3836 RETVAL = i_plin(im, l, l+items-3, y, work);
3847 i_ppixf(im, x, y, cl)
3851 Imager::Color::Float cl
3854 i_gsampf(im, l, r, y, ...)
3866 croak("No channel numbers supplied to g_sampf()");
3868 chan_count = items - 4;
3869 chans = mymalloc(sizeof(int) * chan_count);
3870 for (i = 0; i < chan_count; ++i)
3871 chans[i] = SvIV(ST(i+4));
3872 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3873 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3875 if (GIMME_V == G_ARRAY) {
3877 for (i = 0; i < count; ++i)
3878 PUSHs(sv_2mortal(newSVnv(data[i])));
3882 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3887 if (GIMME_V != G_ARRAY) {
3889 PUSHs(&PL_sv_undef);
3894 i_plinf(im, l, y, ...)
3905 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3906 /* supplied as a byte string */
3907 work = (i_fcolor *)SvPV(ST(3), len);
3908 count = len / sizeof(i_fcolor);
3909 if (count * sizeof(i_fcolor) != len) {
3910 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3912 RETVAL = i_plinf(im, l, l+count, y, work);
3915 work = mymalloc(sizeof(i_fcolor) * (items-3));
3916 for (i=0; i < items-3; ++i) {
3917 if (sv_isobject(ST(i+3))
3918 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3919 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3920 work[i] = *INT2PTR(i_fcolor *, tmp);
3924 croak("i_plinf: pixels must be Imager::Color::Float objects");
3928 RETVAL = i_plinf(im, l, l+items-3, y, work);
3946 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3947 if (i_gpixf(im, x, y, color) == 0) {
3948 RETVAL = NEWSV(0,0);
3949 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3953 RETVAL = &PL_sv_undef;
3969 vals = mymalloc((r-l) * sizeof(i_color));
3970 count = i_glin(im, l, r, y, vals);
3971 if (GIMME_V == G_ARRAY) {
3973 for (i = 0; i < count; ++i) {
3975 i_color *col = mymalloc(sizeof(i_color));
3977 sv = sv_newmortal();
3978 sv_setref_pv(sv, "Imager::Color", (void *)col);
3984 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3990 i_glinf(im, l, r, y)
4000 vals = mymalloc((r-l) * sizeof(i_fcolor));
4001 count = i_glinf(im, l, r, y, vals);
4002 if (GIMME_V == G_ARRAY) {
4004 for (i = 0; i < count; ++i) {
4006 i_fcolor *col = mymalloc(sizeof(i_fcolor));
4008 sv = sv_newmortal();
4009 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
4015 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
4021 i_img_16_new(x, y, ch)
4027 i_img_double_new(x, y, ch)
4033 i_tags_addn(im, name, code, idata)
4042 name = SvPV(ST(1), len);
4045 RETVAL = i_tags_addn(&im->tags, name, code, idata);
4050 i_tags_add(im, name, code, data, idata)
4060 name = SvPV(ST(1), len);
4064 data = SvPV(ST(3), len);
4069 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
4074 i_tags_find(im, name, start)
4081 if (i_tags_find(&im->tags, name, start, &entry)) {
4083 RETVAL = newSVpv("0 but true", 0);
4085 RETVAL = newSViv(entry);
4087 RETVAL = &PL_sv_undef;
4093 i_tags_findn(im, code, start)
4100 if (i_tags_findn(&im->tags, code, start, &entry)) {
4102 RETVAL = newSVpv("0 but true", 0);
4104 RETVAL = newSViv(entry);
4107 RETVAL = &PL_sv_undef;
4113 i_tags_delete(im, entry)
4117 RETVAL = i_tags_delete(&im->tags, entry);
4122 i_tags_delbyname(im, name)
4126 RETVAL = i_tags_delbyname(&im->tags, name);
4131 i_tags_delbycode(im, code)
4135 RETVAL = i_tags_delbycode(&im->tags, code);
4140 i_tags_get(im, index)
4144 if (index >= 0 && index < im->tags.count) {
4145 i_img_tag *entry = im->tags.tags + index;
4149 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4152 PUSHs(sv_2mortal(newSViv(entry->code)));
4155 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4158 PUSHs(sv_2mortal(newSViv(entry->idata)));
4163 i_tags_get_string(im, what_sv)
4167 char const *name = NULL;
4171 if (SvIOK(what_sv)) {
4172 code = SvIV(what_sv);
4176 name = SvPV_nolen(what_sv);
4179 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4181 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4188 RETVAL = im->tags.count;
4195 i_wf_bbox(face, size, text_sv, utf8=0)
4201 int cords[BOUNDING_BOX_COUNT];
4206 text = SvPV(text_sv, text_len);
4208 if (SvUTF8(text_sv))
4211 if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) {
4213 for (i = 0; i < rc; ++i)
4214 PUSHs(sv_2mortal(newSViv(cords[i])));
4218 i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
4233 text = SvPV(text_sv, text_len);
4235 if (SvUTF8(text_sv))
4238 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len,
4244 i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
4259 text = SvPV(text_sv, text_len);
4261 if (SvUTF8(text_sv))
4264 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len,
4277 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4279 #define FT2_DESTROY(font) i_ft2_destroy(font)
4283 Imager::Font::FT2 font
4285 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4288 i_ft2_new(name, index)
4293 i_ft2_setdpi(font, xdpi, ydpi)
4294 Imager::Font::FT2 font
4300 Imager::Font::FT2 font
4304 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4306 PUSHs(sv_2mortal(newSViv(xdpi)));
4307 PUSHs(sv_2mortal(newSViv(ydpi)));
4311 i_ft2_sethinting(font, hinting)
4312 Imager::Font::FT2 font
4316 i_ft2_settransform(font, matrix)
4317 Imager::Font::FT2 font
4325 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4326 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4327 av=(AV*)SvRV(ST(1));
4331 for (i = 0; i < len; ++i) {
4332 sv1=(*(av_fetch(av,i,0)));
4333 matrix[i] = SvNV(sv1);
4337 RETVAL = i_ft2_settransform(font, matrix);
4342 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4343 Imager::Font::FT2 font
4349 int bbox[BOUNDING_BOX_COUNT];
4355 text = SvPV(text_sv, text_len);
4357 if (SvUTF8(text_sv))
4360 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4363 for (i = 0; i < rc; ++i)
4364 PUSHs(sv_2mortal(newSViv(bbox[i])));
4368 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4369 Imager::Font::FT2 font
4383 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4386 for (i = 0; i < 8; ++i)
4387 PUSHs(sv_2mortal(newSViv(bbox[i])));
4391 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4392 Imager::Font::FT2 font
4408 if (SvUTF8(ST(7))) {
4412 text = SvPV(ST(7), len);
4413 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4414 len, align, aa, vlayout, utf8);
4419 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
4420 Imager::Font::FT2 font
4440 text = SvPV(text_sv, len);
4441 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4442 len, align, aa, vlayout, 1);
4447 ft2_transform_box(font, x0, x1, x2, x3)
4448 Imager::Font::FT2 font
4456 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4457 ft2_transform_box(font, box);
4459 PUSHs(sv_2mortal(newSViv(box[0])));
4460 PUSHs(sv_2mortal(newSViv(box[1])));
4461 PUSHs(sv_2mortal(newSViv(box[2])));
4462 PUSHs(sv_2mortal(newSViv(box[3])));
4465 i_ft2_has_chars(handle, text_sv, utf8)
4466 Imager::Font::FT2 handle
4477 if (SvUTF8(text_sv))
4480 text = SvPV(text_sv, len);
4481 work = mymalloc(len);
4482 count = i_ft2_has_chars(handle, text, len, utf8, work);
4483 if (GIMME_V == G_ARRAY) {
4485 for (i = 0; i < count; ++i) {
4486 PUSHs(sv_2mortal(newSViv(work[i])));
4491 PUSHs(sv_2mortal(newSVpv(work, count)));
4496 i_ft2_face_name(handle)
4497 Imager::Font::FT2 handle
4502 len = i_ft2_face_name(handle, name, sizeof(name));
4505 PUSHs(sv_2mortal(newSVpv(name, 0)));
4509 i_ft2_can_face_name()
4512 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4513 Imager::Font::FT2 handle
4524 if (SvUTF8(text_sv))
4527 text = SvPV(text_sv, work_len);
4532 ch = i_utf8_advance(&text, &len);
4534 i_push_error(0, "invalid UTF8 character");
4543 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4545 PUSHs(sv_2mortal(newSVpv(name, 0)));
4548 PUSHs(&PL_sv_undef);
4553 i_ft2_can_do_glyph_names()
4556 i_ft2_face_has_glyph_names(handle)
4557 Imager::Font::FT2 handle
4560 i_ft2_is_multiple_master(handle)
4561 Imager::Font::FT2 handle
4564 i_ft2_get_multiple_masters(handle)
4565 Imager::Font::FT2 handle
4570 if (i_ft2_get_multiple_masters(handle, &mm)) {
4571 EXTEND(SP, 2+mm.num_axis);
4572 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4573 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4574 for (i = 0; i < mm.num_axis; ++i) {
4578 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4580 av_store(av, 0, sv);
4581 sv = newSViv(mm.axis[i].minimum);
4583 av_store(av, 1, sv);
4584 sv = newSViv(mm.axis[i].maximum);
4586 av_store(av, 2, sv);
4587 PUSHs(newRV_noinc((SV *)av));
4592 i_ft2_set_mm_coords(handle, ...)
4593 Imager::Font::FT2 handle
4599 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4600 transfer the array manually */
4601 ix_coords = items-1;
4602 coords = mymalloc(sizeof(long) * ix_coords);
4603 for (i = 0; i < ix_coords; ++i) {
4604 coords[i] = (long)SvIV(ST(1+i));
4606 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4613 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4617 Imager::FillHandle fill
4619 MODULE = Imager PACKAGE = Imager
4622 i_new_fill_solid(cl, combine)
4627 i_new_fill_solidf(cl, combine)
4628 Imager::Color::Float cl
4632 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4640 unsigned char *cust_hatch;
4644 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4648 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4653 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4654 Imager::Color::Float fg
4655 Imager::Color::Float bg
4661 unsigned char *cust_hatch;
4665 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4669 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4674 i_new_fill_image(src, matrix, xoff, yoff, combine)
4691 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4692 croak("i_new_fill_image: parameter must be an arrayref");
4693 av=(AV*)SvRV(ST(1));
4697 for (i = 0; i < len; ++i) {
4698 sv1=(*(av_fetch(av,i,0)));
4699 matrix[i] = SvNV(sv1);
4705 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4709 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4711 # this class is only exposed for testing
4714 i_int_hlines_testing()
4716 #if i_int_hlines_testing()
4718 Imager::Internal::Hlines
4719 i_int_hlines_new(start_y, count_y, start_x, count_x)
4725 Imager::Internal::Hlines
4726 i_int_hlines_new_img(im)
4730 i_int_hlines_add(hlines, y, minx, width)
4731 Imager::Internal::Hlines hlines
4737 i_int_hlines_DESTROY(hlines)
4738 Imager::Internal::Hlines hlines
4741 i_int_hlines_dump(hlines)
4742 Imager::Internal::Hlines hlines
4747 PERL_SET_GLOBAL_CALLBACKS;