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 /* I don't think ICLF_* names belong at the C interface
818 this makes the XS code think we have them, to let us avoid
819 putting function bodies in the XS code
821 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
822 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
825 /* the m_init_log() function was called init_log(), renamed to reduce
826 potential naming conflicts */
827 #define init_log m_init_log
829 #if i_int_hlines_testing()
831 typedef i_int_hlines *Imager__Internal__Hlines;
833 static i_int_hlines *
834 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
835 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
836 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
841 static i_int_hlines *
842 i_int_hlines_new_img(i_img *im) {
843 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
844 i_int_init_hlines_img(result, im);
850 i_int_hlines_DESTROY(i_int_hlines *hlines) {
851 i_int_hlines_destroy(hlines);
855 static int seg_compare(const void *vleft, const void *vright) {
856 const i_int_hline_seg *left = vleft;
857 const i_int_hline_seg *right = vright;
859 return left->minx - right->minx;
863 i_int_hlines_dump(i_int_hlines *hlines) {
864 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
865 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
868 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
869 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
872 /* sort the segments, if any */
874 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
876 sv_catpvf(dump, " %d (%d):", y, entry->count);
877 for (i = 0; i < entry->count; ++i) {
878 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
879 entry->segs[i].x_limit);
881 sv_catpv(dump, "\n");
891 #define i_exif_enabled() 1
893 #define i_exif_enabled() 0
896 /* trying to use more C style names, map them here */
897 #define i_io_DESTROY(ig) io_glue_destroy(ig)
899 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
902 ICL_new_internal(r,g,b,a)
914 ICL_set_internal(cl,r,g,b,a)
921 ICL_set_internal(cl, r, g, b, a);
935 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
936 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
937 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
938 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
944 RETVAL = mymalloc(sizeof(i_color));
946 i_hsv_to_rgb(RETVAL);
954 RETVAL = mymalloc(sizeof(i_color));
956 i_rgb_to_hsv(RETVAL);
962 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
965 ICLF_new_internal(r, g, b, a)
973 Imager::Color::Float cl
977 Imager::Color::Float cl
981 EXTEND(SP, MAXCHANNELS);
982 for (ch = 0; ch < MAXCHANNELS; ++ch) {
983 /* printf("%d: %g\n", ch, cl->channel[ch]); */
984 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
988 ICLF_set_internal(cl,r,g,b,a)
989 Imager::Color::Float cl
1002 Imager::Color::Float
1004 Imager::Color::Float c
1006 RETVAL = mymalloc(sizeof(i_fcolor));
1008 i_hsv_to_rgbf(RETVAL);
1012 Imager::Color::Float
1014 Imager::Color::Float c
1016 RETVAL = mymalloc(sizeof(i_fcolor));
1018 i_rgb_to_hsvf(RETVAL);
1022 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1036 MODULE = Imager PACKAGE = Imager
1055 SvPV(ST(0), length);
1056 SvREFCNT_inc(ST(0));
1057 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1062 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1071 cbd = mymalloc(sizeof(struct cbdata));
1072 SvREFCNT_inc(writecb);
1073 cbd->writecb = writecb;
1074 SvREFCNT_inc(readcb);
1075 cbd->readcb = readcb;
1076 SvREFCNT_inc(seekcb);
1077 cbd->seekcb = seekcb;
1078 SvREFCNT_inc(closecb);
1079 cbd->closecb = closecb;
1080 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1081 if (maxwrite > CBDATA_BUFSIZE)
1082 maxwrite = CBDATA_BUFSIZE;
1083 cbd->maxlength = maxwrite;
1084 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1093 unsigned char* data;
1097 tlength = io_slurp(ig, &data);
1099 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1104 i_set_image_file_limits(width, height, bytes)
1110 i_get_image_file_limits()
1112 int width, height, bytes;
1114 if (i_get_image_file_limits(&width, &height, &bytes)) {
1116 PUSHs(sv_2mortal(newSViv(width)));
1117 PUSHs(sv_2mortal(newSViv(height)));
1118 PUSHs(sv_2mortal(newSViv(bytes)));
1121 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1124 i_io_write(ig, data_sv)
1132 if (SvUTF8(data_sv)) {
1133 data_sv = sv_2mortal(newSVsv(data_sv));
1134 /* yes, we want this to croak() if the SV can't be downgraded */
1135 sv_utf8_downgrade(data_sv, FALSE);
1138 data = SvPV(data_sv, size);
1139 RETVAL = i_io_write(ig, data, size);
1144 i_io_read(ig, buffer_sv, size)
1153 croak("size negative in call to i_io_read()");
1154 /* prevent an undefined value warning if they supplied an
1156 Orginally conditional on !SvOK(), but this will prevent the
1157 downgrade from croaking */
1158 sv_setpvn(buffer_sv, "", 0);
1160 if (SvUTF8(buffer_sv))
1161 sv_utf8_downgrade(buffer_sv, FALSE);
1163 buffer = SvGROW(buffer_sv, size+1);
1164 result = i_io_read(ig, buffer, size);
1166 SvCUR_set(buffer_sv, result);
1167 *SvEND(buffer_sv) = '\0';
1168 SvPOK_only(buffer_sv);
1170 PUSHs(sv_2mortal(newSViv(result)));
1176 i_io_read2(ig, size)
1185 croak("size negative in call to i_io_read2()");
1186 buffer_sv = newSV(size);
1187 buffer = SvGROW(buffer_sv, size+1);
1188 result = i_io_read(ig, buffer, size);
1190 SvCUR_set(buffer_sv, result);
1191 *SvEND(buffer_sv) = '\0';
1192 SvPOK_only(buffer_sv);
1194 PUSHs(sv_2mortal(buffer_sv));
1198 SvREFCNT_dec(buffer_sv);
1202 i_io_seek(ig, position, whence)
1215 MODULE = Imager PACKAGE = Imager
1226 while( (item=i_format_list[i++]) != NULL ) {
1228 PUSHs(sv_2mortal(newSVpv(item,0)));
1245 i_img_empty_ch(im,x,y,ch)
1252 i_sametype(im, x, y)
1258 i_sametype_chans(im, x, y, channels)
1265 i_init_log(name,level)
1270 i_log_entry(string,level)
1289 i_img_info(im,info);
1291 PUSHs(sv_2mortal(newSViv(info[0])));
1292 PUSHs(sv_2mortal(newSViv(info[1])));
1293 PUSHs(sv_2mortal(newSViv(info[2])));
1294 PUSHs(sv_2mortal(newSViv(info[3])));
1300 i_img_setmask(im,ch_mask)
1309 i_img_getchannels(im)
1318 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1323 i_line(im,x1,y1,x2,y2,val,endp)
1333 i_line_aa(im,x1,y1,x2,y2,val,endp)
1343 i_box(im,x1,y1,x2,y2,val)
1352 i_box_filled(im,x1,y1,x2,y2,val)
1361 i_box_cfill(im,x1,y1,x2,y2,fill)
1367 Imager::FillHandle fill
1370 i_arc(im,x,y,rad,d1,d2,val)
1380 i_arc_aa(im,x,y,rad,d1,d2,val)
1390 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1397 Imager::FillHandle fill
1400 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1407 Imager::FillHandle fill
1411 i_circle_aa(im,x,y,rad,val)
1421 i_bezier_multi(im,xc,yc,val)
1434 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1435 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1436 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1437 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1438 av1=(AV*)SvRV(ST(1));
1439 av2=(AV*)SvRV(ST(2));
1440 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1442 x=mymalloc( len*sizeof(double) );
1443 y=mymalloc( len*sizeof(double) );
1444 for(i=0;i<len;i++) {
1445 sv1=(*(av_fetch(av1,i,0)));
1446 sv2=(*(av_fetch(av2,i,0)));
1447 x[i]=(double)SvNV(sv1);
1448 y[i]=(double)SvNV(sv2);
1450 i_bezier_multi(im,len,x,y,val);
1456 i_poly_aa(im,xc,yc,val)
1469 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1470 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1471 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1472 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1473 av1=(AV*)SvRV(ST(1));
1474 av2=(AV*)SvRV(ST(2));
1475 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1477 x=mymalloc( len*sizeof(double) );
1478 y=mymalloc( len*sizeof(double) );
1479 for(i=0;i<len;i++) {
1480 sv1=(*(av_fetch(av1,i,0)));
1481 sv2=(*(av_fetch(av2,i,0)));
1482 x[i]=(double)SvNV(sv1);
1483 y[i]=(double)SvNV(sv2);
1485 i_poly_aa(im,len,x,y,val);
1490 i_poly_aa_cfill(im,xc,yc,fill)
1492 Imager::FillHandle fill
1502 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1503 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1504 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1505 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1506 av1=(AV*)SvRV(ST(1));
1507 av2=(AV*)SvRV(ST(2));
1508 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1510 x=mymalloc( len*sizeof(double) );
1511 y=mymalloc( len*sizeof(double) );
1512 for(i=0;i<len;i++) {
1513 sv1=(*(av_fetch(av1,i,0)));
1514 sv2=(*(av_fetch(av2,i,0)));
1515 x[i]=(double)SvNV(sv1);
1516 y[i]=(double)SvNV(sv2);
1518 i_poly_aa_cfill(im,len,x,y,fill);
1525 i_flood_fill(im,seedx,seedy,dcol)
1532 i_flood_cfill(im,seedx,seedy,fill)
1536 Imager::FillHandle fill
1539 i_flood_fill_border(im,seedx,seedy,dcol, border)
1544 Imager::Color border
1547 i_flood_cfill_border(im,seedx,seedy,fill, border)
1551 Imager::FillHandle fill
1552 Imager::Color border
1556 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1568 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1585 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1597 i_flipxy(im, direction)
1602 i_rotate90(im, degrees)
1607 i_rotate_exact(im, amount, ...)
1611 i_color *backp = NULL;
1612 i_fcolor *fbackp = NULL;
1616 /* extract the bg colors if any */
1617 /* yes, this is kind of strange */
1618 for (i = 2; i < items; ++i) {
1620 if (sv_derived_from(sv1, "Imager::Color")) {
1621 IV tmp = SvIV((SV*)SvRV(sv1));
1622 backp = INT2PTR(i_color *, tmp);
1624 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1625 IV tmp = SvIV((SV*)SvRV(sv1));
1626 fbackp = INT2PTR(i_fcolor *, tmp);
1629 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1634 i_matrix_transform(im, xsize, ysize, matrix, ...)
1644 i_color *backp = NULL;
1645 i_fcolor *fbackp = NULL;
1647 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1648 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1649 av=(AV*)SvRV(ST(3));
1653 for (i = 0; i < len; ++i) {
1654 sv1=(*(av_fetch(av,i,0)));
1655 matrix[i] = SvNV(sv1);
1659 /* extract the bg colors if any */
1660 /* yes, this is kind of strange */
1661 for (i = 4; i < items; ++i) {
1663 if (sv_derived_from(sv1, "Imager::Color")) {
1664 IV tmp = SvIV((SV*)SvRV(sv1));
1665 backp = INT2PTR(i_color *, tmp);
1667 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1668 IV tmp = SvIV((SV*)SvRV(sv1));
1669 fbackp = INT2PTR(i_fcolor *, tmp);
1672 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1677 i_gaussian(im,stdev)
1682 i_unsharp_mask(im,stdev,scale)
1697 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1698 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1699 av=(AV*)SvRV(ST(1));
1701 coeff=mymalloc( len*sizeof(float) );
1702 for(i=0;i<len;i++) {
1703 sv1=(*(av_fetch(av,i,0)));
1704 coeff[i]=(float)SvNV(sv1);
1706 i_conv(im,coeff,len);
1710 i_convert(im, src, coeff)
1723 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1724 croak("i_convert: parameter 3 must be an arrayref\n");
1725 avmain = (AV*)SvRV(ST(2));
1726 outchan = av_len(avmain)+1;
1727 /* find the biggest */
1729 for (j=0; j < outchan; ++j) {
1730 temp = av_fetch(avmain, j, 0);
1731 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1732 avsub = (AV*)SvRV(*temp);
1733 len = av_len(avsub)+1;
1738 coeff = mymalloc(sizeof(float) * outchan * inchan);
1739 for (j = 0; j < outchan; ++j) {
1740 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1741 len = av_len(avsub)+1;
1742 for (i = 0; i < len; ++i) {
1743 temp = av_fetch(avsub, i, 0);
1745 coeff[i+j*inchan] = SvNV(*temp);
1747 coeff[i+j*inchan] = 0;
1750 coeff[i++ + j*inchan] = 0;
1752 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1762 unsigned int mask = 0;
1768 unsigned char (*maps)[256];
1770 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1771 croak("i_map: parameter 2 must be an arrayref\n");
1772 avmain = (AV*)SvRV(ST(1));
1773 len = av_len(avmain)+1;
1774 if (im->channels < len) len = im->channels;
1776 maps = mymalloc( len * sizeof(unsigned char [256]) );
1778 for (j=0; j<len ; j++) {
1779 temp = av_fetch(avmain, j, 0);
1780 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1781 avsub = (AV*)SvRV(*temp);
1782 if(av_len(avsub) != 255) continue;
1784 for (i=0; i<256 ; i++) {
1786 temp = av_fetch(avsub, i, 0);
1787 val = temp ? SvIV(*temp) : 0;
1789 if (val>255) val = 255;
1794 i_map(im, maps, mask);
1807 i_init_fonts(t1log=0)
1822 i_t1_destroy(font_id)
1827 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1846 str = SvPV(str_sv, len);
1847 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1854 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1863 int cords[BOUNDING_BOX_COUNT];
1871 str = SvPV(str_sv, len);
1872 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1875 for (i = 0; i < rc; ++i)
1876 PUSHs(sv_2mortal(newSViv(cords[i])));
1882 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1901 str = SvPV(str_sv, len);
1902 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1908 i_t1_has_chars(handle, text_sv, utf8 = 0)
1920 if (SvUTF8(text_sv))
1923 text = SvPV(text_sv, len);
1924 work = mymalloc(len);
1925 count = i_t1_has_chars(handle, text, len, utf8, work);
1926 if (GIMME_V == G_ARRAY) {
1928 for (i = 0; i < count; ++i) {
1929 PUSHs(sv_2mortal(newSViv(work[i])));
1934 PUSHs(sv_2mortal(newSVpv(work, count)));
1939 i_t1_face_name(handle)
1945 len = i_t1_face_name(handle, name, sizeof(name));
1948 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1952 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1963 if (SvUTF8(text_sv))
1966 text = SvPV(text_sv, work_len);
1971 ch = i_utf8_advance(&text, &len);
1973 i_push_error(0, "invalid UTF8 character");
1982 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1983 PUSHs(sv_2mortal(newSVpv(name, 0)));
1986 PUSHs(&PL_sv_undef);
2000 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2002 #define TT_DESTROY(handle) i_tt_destroy(handle)
2006 Imager::Font::TT handle
2009 MODULE = Imager PACKAGE = Imager
2013 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2014 Imager::Font::TT handle
2032 str = SvPV(str_sv, len);
2033 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2034 len, smooth, utf8, align);
2040 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2041 Imager::Font::TT handle
2059 str = SvPV(str_sv, len);
2060 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2061 smooth, utf8, align);
2067 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2068 Imager::Font::TT handle
2073 int cords[BOUNDING_BOX_COUNT],rc;
2082 str = SvPV(str_sv, len);
2083 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2085 for (i = 0; i < rc; ++i) {
2086 PUSHs(sv_2mortal(newSViv(cords[i])));
2091 i_tt_has_chars(handle, text_sv, utf8)
2092 Imager::Font::TT handle
2103 if (SvUTF8(text_sv))
2106 text = SvPV(text_sv, len);
2107 work = mymalloc(len);
2108 count = i_tt_has_chars(handle, text, len, utf8, work);
2109 if (GIMME_V == G_ARRAY) {
2111 for (i = 0; i < count; ++i) {
2112 PUSHs(sv_2mortal(newSViv(work[i])));
2117 PUSHs(sv_2mortal(newSVpv(work, count)));
2122 i_tt_dump_names(handle)
2123 Imager::Font::TT handle
2126 i_tt_face_name(handle)
2127 Imager::Font::TT handle
2132 len = i_tt_face_name(handle, name, sizeof(name));
2135 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2139 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2140 Imager::Font::TT handle
2151 if (SvUTF8(text_sv))
2154 text = SvPV(text_sv, work_len);
2159 ch = i_utf8_advance(&text, &len);
2161 i_push_error(0, "invalid UTF8 character");
2170 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2171 PUSHs(sv_2mortal(newSVpv(name, 0)));
2174 PUSHs(&PL_sv_undef);
2183 i_writejpeg_wiol(im, ig, qfactor)
2199 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2200 if (iptc_itext == NULL) {
2203 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2208 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2210 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2221 i_test_format_probe(ig, length)
2230 i_readtiff_wiol(ig, length, page=0)
2236 i_readtiff_multi_wiol(ig, length)
2244 imgs = i_readtiff_multi_wiol(ig, length, &count);
2247 for (i = 0; i < count; ++i) {
2248 SV *sv = sv_newmortal();
2249 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2257 i_writetiff_wiol(im, ig)
2262 i_writetiff_multi_wiol(ig, ...)
2270 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2271 img_count = items - 1;
2273 if (img_count < 1) {
2276 i_push_error(0, "You need to specify images to save");
2279 imgs = mymalloc(sizeof(i_img *) * img_count);
2280 for (i = 0; i < img_count; ++i) {
2283 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2284 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2288 i_push_error(0, "Only images can be saved");
2295 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2303 i_writetiff_wiol_faxable(im, ig, fine)
2309 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2318 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2319 img_count = items - 2;
2321 if (img_count < 1) {
2324 i_push_error(0, "You need to specify images to save");
2327 imgs = mymalloc(sizeof(i_img *) * img_count);
2328 for (i = 0; i < img_count; ++i) {
2331 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2332 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2336 i_push_error(0, "Only images can be saved");
2343 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2351 #endif /* HAVE_LIBTIFF */
2357 i_readpng_wiol(ig, length)
2363 i_writepng_wiol(im, ig)
2376 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2379 i_writegif(im,fd,colors,pixdev,fixed)
2386 Imager__Color fixed;
2393 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2394 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2395 av=(AV*)SvRV(ST(4));
2396 fixedlen=av_len(av)+1;
2397 fixed=mymalloc( fixedlen*sizeof(i_color) );
2398 for(i=0;i<fixedlen;i++) {
2399 sv1=(*(av_fetch(av,i,0)));
2400 if (sv_derived_from(sv1, "Imager::Color")) {
2401 Itmp = SvIV((SV*)SvRV(sv1));
2402 tmp = INT2PTR(i_color*, Itmp);
2403 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2406 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2408 ST(0) = sv_newmortal();
2409 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2410 else sv_setiv(ST(0), (IV)RETVAL);
2416 i_writegifmc(im,fd,colors)
2423 i_writegif_gen(fd, ...)
2428 i_img **imgs = NULL;
2434 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2435 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2436 croak("i_writegif_gen: Second argument must be a hash ref");
2437 hv = (HV *)SvRV(ST(1));
2438 memset(&quant, 0, sizeof(quant));
2439 quant.mc_size = 256;
2440 handle_quant_opts(&quant, hv);
2441 img_count = items - 2;
2443 if (img_count < 1) {
2446 i_push_error(0, "You need to specify images to save");
2449 imgs = mymalloc(sizeof(i_img *) * img_count);
2450 for (i = 0; i < img_count; ++i) {
2453 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2454 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2458 i_push_error(0, "Only images can be saved");
2464 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2468 copy_colors_back(hv, &quant);
2471 ST(0) = sv_newmortal();
2472 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2473 else sv_setiv(ST(0), (IV)RETVAL);
2474 cleanup_quant_opts(&quant);
2478 i_writegif_callback(cb, maxbuffer,...)
2482 i_img **imgs = NULL;
2489 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2490 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2491 croak("i_writegif_callback: Second argument must be a hash ref");
2492 hv = (HV *)SvRV(ST(2));
2493 memset(&quant, 0, sizeof(quant));
2494 quant.mc_size = 256;
2495 handle_quant_opts(&quant, hv);
2496 img_count = items - 3;
2498 if (img_count < 1) {
2502 imgs = mymalloc(sizeof(i_img *) * img_count);
2503 for (i = 0; i < img_count; ++i) {
2506 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2507 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2516 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2520 copy_colors_back(hv, &quant);
2523 ST(0) = sv_newmortal();
2524 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2525 else sv_setiv(ST(0), (IV)RETVAL);
2526 cleanup_quant_opts(&quant);
2529 i_writegif_wiol(ig, opts,...)
2533 i_img **imgs = NULL;
2539 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2540 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2541 croak("i_writegif_callback: Second argument must be a hash ref");
2542 hv = (HV *)SvRV(ST(1));
2543 memset(&quant, 0, sizeof(quant));
2544 quant.mc_size = 256;
2545 handle_quant_opts(&quant, hv);
2546 img_count = items - 2;
2548 if (img_count < 1) {
2552 imgs = mymalloc(sizeof(i_img *) * img_count);
2553 for (i = 0; i < img_count; ++i) {
2556 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2557 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2565 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2569 copy_colors_back(hv, &quant);
2572 ST(0) = sv_newmortal();
2573 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2574 else sv_setiv(ST(0), (IV)RETVAL);
2575 cleanup_quant_opts(&quant);
2588 colour_table = NULL;
2591 if(GIMME_V == G_ARRAY) {
2592 rimg = i_readgif(fd,&colour_table,&colours);
2594 /* don't waste time with colours if they aren't wanted */
2595 rimg = i_readgif(fd,NULL,NULL);
2598 if (colour_table == NULL) {
2601 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2604 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2605 /* I don't know if I have the reference counts right or not :( */
2606 /* Neither do I :-) */
2607 /* No Idea here either */
2610 av_extend(ct, colours);
2611 for(q=0; q<colours; q++) {
2613 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2614 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2616 myfree(colour_table);
2620 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2622 PUSHs(newRV_noinc((SV*)ct));
2636 colour_table = NULL;
2639 if(GIMME_V == G_ARRAY) {
2640 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2642 /* don't waste time with colours if they aren't wanted */
2643 rimg = i_readgif_wiol(ig,NULL,NULL);
2646 if (colour_table == NULL) {
2649 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2652 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2653 /* I don't know if I have the reference counts right or not :( */
2654 /* Neither do I :-) */
2655 /* No Idea here either */
2658 av_extend(ct, colours);
2659 for(q=0; q<colours; q++) {
2661 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2662 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2664 myfree(colour_table);
2668 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2670 PUSHs(newRV_noinc((SV*)ct));
2674 i_readgif_single_wiol(ig, page=0)
2679 i_readgif_scalar(...)
2691 data = (char *)SvPV(ST(0), length);
2695 if(GIMME_V == G_ARRAY) {
2696 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2698 /* don't waste time with colours if they aren't wanted */
2699 rimg=i_readgif_scalar(data,length,NULL,NULL);
2702 if (colour_table == NULL) {
2705 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2708 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2709 /* I don't know if I have the reference counts right or not :( */
2710 /* Neither do I :-) */
2712 av_extend(ct, colours);
2713 for(q=0; q<colours; q++) {
2715 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2716 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2718 myfree(colour_table);
2722 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2724 PUSHs(newRV_noinc((SV*)ct));
2728 i_readgif_callback(...)
2743 if(GIMME_V == G_ARRAY) {
2744 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2746 /* don't waste time with colours if they aren't wanted */
2747 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2750 if (colour_table == NULL) {
2753 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2756 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2757 /* I don't know if I have the reference counts right or not :( */
2758 /* Neither do I :-) */
2759 /* Neither do I - maybe I'll move this somewhere */
2761 av_extend(ct, colours);
2762 for(q=0; q<colours; q++) {
2764 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2765 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2767 myfree(colour_table);
2771 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2773 PUSHs(newRV_noinc((SV*)ct));
2784 imgs = i_readgif_multi(fd, &count);
2787 for (i = 0; i < count; ++i) {
2788 SV *sv = sv_newmortal();
2789 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2796 i_readgif_multi_scalar(data)
2804 data = (char *)SvPV(ST(0), length);
2805 imgs = i_readgif_multi_scalar(data, length, &count);
2808 for (i = 0; i < count; ++i) {
2809 SV *sv = sv_newmortal();
2810 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2817 i_readgif_multi_callback(cb)
2825 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2828 for (i = 0; i < count; ++i) {
2829 SV *sv = sv_newmortal();
2830 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2837 i_readgif_multi_wiol(ig)
2844 imgs = i_readgif_multi_wiol(ig, &count);
2847 for (i = 0; i < count; ++i) {
2848 SV *sv = sv_newmortal();
2849 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2861 i_readpnm_wiol(ig, length)
2867 i_writeppm_wiol(im, ig)
2873 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2882 i_writeraw_wiol(im,ig)
2887 i_writebmp_wiol(im,ig)
2897 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2906 idlen = SvCUR(ST(4));
2907 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2913 i_readtga_wiol(ig, length)
2919 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2928 idlen = SvCUR(ST(4));
2929 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2935 i_readrgb_wiol(ig, length)
2942 i_scaleaxis(im,Value,Axis)
2948 i_scale_nn(im,scx,scy)
2958 i_count_colors(im,maxc)
2964 i_transform(im,opx,opy,parm)
2977 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2978 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2979 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2980 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2981 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2982 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2983 av=(AV*)SvRV(ST(1));
2985 opx=mymalloc( opxl*sizeof(int) );
2986 for(i=0;i<opxl;i++) {
2987 sv1=(*(av_fetch(av,i,0)));
2988 opx[i]=(int)SvIV(sv1);
2990 av=(AV*)SvRV(ST(2));
2992 opy=mymalloc( opyl*sizeof(int) );
2993 for(i=0;i<opyl;i++) {
2994 sv1=(*(av_fetch(av,i,0)));
2995 opy[i]=(int)SvIV(sv1);
2997 av=(AV*)SvRV(ST(3));
2998 parmlen=av_len(av)+1;
2999 parm=mymalloc( parmlen*sizeof(double) );
3000 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
3001 sv1=(*(av_fetch(av,i,0)));
3002 parm[i]=(double)SvNV(sv1);
3004 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
3008 ST(0) = sv_newmortal();
3009 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3010 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3013 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
3038 in_imgs_count = av_len(av_in_imgs)+1;
3039 for (i = 0; i < in_imgs_count; ++i) {
3040 sv1 = *av_fetch(av_in_imgs, i, 0);
3041 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3042 croak("sv_in_img must contain only images");
3045 if (in_imgs_count > 0) {
3046 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
3047 for (i = 0; i < in_imgs_count; ++i) {
3048 sv1 = *av_fetch(av_in_imgs,i,0);
3049 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3050 croak("Parameter 5 must contain only images");
3052 tmp = SvIV((SV*)SvRV(sv1));
3053 in_imgs[i] = INT2PTR(i_img*, tmp);
3057 /* no input images */
3060 /* default the output size from the first input if possible */
3062 width = SvIV(sv_width);
3063 else if (in_imgs_count)
3064 width = in_imgs[0]->xsize;
3066 croak("No output image width supplied");
3068 if (SvOK(sv_height))
3069 height = SvIV(sv_height);
3070 else if (in_imgs_count)
3071 height = in_imgs[0]->ysize;
3073 croak("No output image height supplied");
3075 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3076 if (ops_len % sizeof(struct rm_op))
3077 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3078 ops_count = ops_len / sizeof(struct rm_op);
3080 n_regs_count = av_len(av_n_regs)+1;
3081 n_regs = mymalloc(n_regs_count * sizeof(double));
3082 for (i = 0; i < n_regs_count; ++i) {
3083 sv1 = *av_fetch(av_n_regs,i,0);
3085 n_regs[i] = SvNV(sv1);
3087 c_regs_count = av_len(av_c_regs)+1;
3088 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3089 /* I don't bother initializing the colou?r registers */
3091 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3092 n_regs, n_regs_count,
3093 c_regs, c_regs_count, in_imgs, in_imgs_count);
3098 ST(0) = sv_newmortal();
3099 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3100 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3104 i_contrast(im,intensity)
3113 i_noise(im,amount,type)
3119 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3129 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3148 i_postlevels(im,levels)
3158 i_watermark(im,wmark,tx,ty,pixdiff)
3160 Imager::ImgRaw wmark
3167 i_autolevels(im,lsat,usat,skew)
3174 i_radnoise(im,xo,yo,rscale,ascale)
3182 i_turbnoise(im, xo, yo, scale)
3205 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3206 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3207 croak("i_gradgen: Second argument must be an array ref");
3208 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3209 croak("i_gradgen: Third argument must be an array ref");
3210 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3211 croak("i_gradgen: Fourth argument must be an array ref");
3212 axx = (AV *)SvRV(ST(1));
3213 ayy = (AV *)SvRV(ST(2));
3214 ac = (AV *)SvRV(ST(3));
3215 dmeasure = (int)SvIV(ST(4));
3217 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3218 num = num <= av_len(ac) ? num : av_len(ac);
3220 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3221 xo = mymalloc( sizeof(int) * num );
3222 yo = mymalloc( sizeof(int) * num );
3223 ival = mymalloc( sizeof(i_color) * num );
3224 for(i = 0; i<num; i++) {
3225 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3226 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3227 sv = *av_fetch(ac, i, 0);
3228 if ( !sv_derived_from(sv, "Imager::Color") ) {
3229 free(axx); free(ayy); free(ac);
3230 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3232 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3234 i_gradgen(im, num, xo, yo, ival, dmeasure);
3240 i_diff_image(im, im2, mindist=0)
3246 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3256 double ssample_param
3260 i_fountain_seg *segs;
3262 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3263 croak("i_fountain: argument 11 must be an array ref");
3265 asegs = (AV *)SvRV(ST(10));
3266 segs = load_fount_segs(asegs, &count);
3267 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3268 super_sample, ssample_param, count, segs);
3274 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3283 double ssample_param
3287 i_fountain_seg *segs;
3289 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3290 croak("i_fountain: argument 11 must be an array ref");
3292 asegs = (AV *)SvRV(ST(9));
3293 segs = load_fount_segs(asegs, &count);
3294 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3295 super_sample, ssample_param, count, segs);
3308 errors = i_errors();
3310 while (errors[i].msg) {
3312 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3313 if (!av_store(av, 0, sv)) {
3316 sv = newSViv(errors[i].code);
3317 if (!av_store(av, 1, sv)) {
3320 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3328 i_push_error(code, msg)
3333 i_nearest_color(im, ...)
3348 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3349 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3350 croak("i_nearest_color: Second argument must be an array ref");
3351 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3352 croak("i_nearest_color: Third argument must be an array ref");
3353 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3354 croak("i_nearest_color: Fourth argument must be an array ref");
3355 axx = (AV *)SvRV(ST(1));
3356 ayy = (AV *)SvRV(ST(2));
3357 ac = (AV *)SvRV(ST(3));
3358 dmeasure = (int)SvIV(ST(4));
3360 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3361 num = num <= av_len(ac) ? num : av_len(ac);
3363 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3364 xo = mymalloc( sizeof(int) * num );
3365 yo = mymalloc( sizeof(int) * num );
3366 ival = mymalloc( sizeof(i_color) * num );
3367 for(i = 0; i<num; i++) {
3368 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3369 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3370 sv = *av_fetch(ac, i, 0);
3371 if ( !sv_derived_from(sv, "Imager::Color") ) {
3372 free(axx); free(ayy); free(ac);
3373 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3375 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3377 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3391 rc=DSO_open(filename,&evstr);
3395 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3396 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3399 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3405 DSO_close(dso_handle)
3409 DSO_funclist(dso_handle_v)
3413 DSO_handle *dso_handle;
3415 dso_handle=(DSO_handle*)dso_handle_v;
3417 while( dso_handle->function_list[i].name != NULL) {
3419 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3421 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3426 DSO_call(handle,func_index,hv)
3432 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3433 hv=(HV*)SvRV(ST(2));
3434 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3435 DSO_call( (DSO_handle *)handle,func_index,hv);
3440 i_get_pixel(im, x, y)
3447 color = (i_color *)mymalloc(sizeof(i_color));
3448 if (i_gpix(im, x, y, color) == 0) {
3449 RETVAL = NEWSV(0, 0);
3450 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3454 RETVAL = &PL_sv_undef;
3461 i_ppix(im, x, y, cl)
3468 i_img_pal_new(x, y, channels, maxpal)
3475 i_img_to_pal(src, quant)
3481 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3482 croak("i_img_to_pal: second argument must be a hash ref");
3483 hv = (HV *)SvRV(ST(1));
3484 memset(&quant, 0, sizeof(quant));
3485 quant.mc_size = 256;
3486 handle_quant_opts(&quant, hv);
3487 RETVAL = i_img_to_pal(src, &quant);
3489 copy_colors_back(hv, &quant);
3491 cleanup_quant_opts(&quant);
3510 work = mymalloc((r-l) * sizeof(i_palidx));
3511 count = i_gpal(im, l, r, y, work);
3512 if (GIMME_V == G_ARRAY) {
3514 for (i = 0; i < count; ++i) {
3515 PUSHs(sv_2mortal(newSViv(work[i])));
3520 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3525 if (GIMME_V != G_ARRAY) {
3527 PUSHs(&PL_sv_undef);
3532 i_ppal(im, l, y, ...)
3541 work = mymalloc(sizeof(i_palidx) * (items-3));
3542 for (i=0; i < items-3; ++i) {
3543 work[i] = SvIV(ST(i+3));
3545 RETVAL = i_ppal(im, l, l+items-3, y, work);
3555 i_addcolors(im, ...)
3563 croak("i_addcolors: no colors to add");
3564 colors = mymalloc((items-1) * sizeof(i_color));
3565 for (i=0; i < items-1; ++i) {
3566 if (sv_isobject(ST(i+1))
3567 && sv_derived_from(ST(i+1), "Imager::Color")) {
3568 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3569 colors[i] = *INT2PTR(i_color *, tmp);
3573 croak("i_addcolor: pixels must be Imager::Color objects");
3576 index = i_addcolors(im, colors, items-1);
3579 RETVAL = newSVpv("0 but true", 0);
3581 else if (index == -1) {
3582 RETVAL = &PL_sv_undef;
3585 RETVAL = newSViv(index);
3591 i_setcolors(im, index, ...)
3599 croak("i_setcolors: no colors to add");
3600 colors = mymalloc((items-2) * sizeof(i_color));
3601 for (i=0; i < items-2; ++i) {
3602 if (sv_isobject(ST(i+2))
3603 && sv_derived_from(ST(i+2), "Imager::Color")) {
3604 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3605 colors[i] = *INT2PTR(i_color *, tmp);
3609 croak("i_setcolors: pixels must be Imager::Color objects");
3612 RETVAL = i_setcolors(im, index, colors, items-2);
3618 i_getcolors(im, index, ...)
3627 croak("i_getcolors: too many arguments");
3629 count = SvIV(ST(2));
3631 croak("i_getcolors: count must be positive");
3632 colors = mymalloc(sizeof(i_color) * count);
3633 if (i_getcolors(im, index, colors, count)) {
3634 for (i = 0; i < count; ++i) {
3636 SV *sv = sv_newmortal();
3637 pv = mymalloc(sizeof(i_color));
3639 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3655 i_findcolor(im, color)
3661 if (i_findcolor(im, color, &index)) {
3662 RETVAL = newSViv(index);
3665 RETVAL = &PL_sv_undef;
3683 i_gsamp(im, l, r, y, ...)
3695 croak("No channel numbers supplied to g_samp()");
3697 chan_count = items - 4;
3698 chans = mymalloc(sizeof(int) * chan_count);
3699 for (i = 0; i < chan_count; ++i)
3700 chans[i] = SvIV(ST(i+4));
3701 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3702 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3704 if (GIMME_V == G_ARRAY) {
3706 for (i = 0; i < count; ++i)
3707 PUSHs(sv_2mortal(newSViv(data[i])));
3711 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3716 if (GIMME_V != G_ARRAY) {
3718 PUSHs(&PL_sv_undef);
3724 i_img_masked_new(targ, mask, x, y, w, h)
3734 if (!sv_isobject(ST(1))
3735 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3736 croak("i_img_masked_new: parameter 2 must undef or an image");
3738 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3742 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3747 i_plin(im, l, y, ...)
3758 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3759 /* supplied as a byte string */
3760 work = (i_color *)SvPV(ST(3), len);
3761 count = len / sizeof(i_color);
3762 if (count * sizeof(i_color) != len) {
3763 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3765 RETVAL = i_plin(im, l, l+count, y, work);
3768 work = mymalloc(sizeof(i_color) * (items-3));
3769 for (i=0; i < items-3; ++i) {
3770 if (sv_isobject(ST(i+3))
3771 && sv_derived_from(ST(i+3), "Imager::Color")) {
3772 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3773 work[i] = *INT2PTR(i_color *, tmp);
3777 croak("i_plin: pixels must be Imager::Color objects");
3780 RETVAL = i_plin(im, l, l+items-3, y, work);
3791 i_ppixf(im, x, y, cl)
3795 Imager::Color::Float cl
3798 i_gsampf(im, l, r, y, ...)
3810 croak("No channel numbers supplied to g_sampf()");
3812 chan_count = items - 4;
3813 chans = mymalloc(sizeof(int) * chan_count);
3814 for (i = 0; i < chan_count; ++i)
3815 chans[i] = SvIV(ST(i+4));
3816 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3817 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3819 if (GIMME_V == G_ARRAY) {
3821 for (i = 0; i < count; ++i)
3822 PUSHs(sv_2mortal(newSVnv(data[i])));
3826 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3831 if (GIMME_V != G_ARRAY) {
3833 PUSHs(&PL_sv_undef);
3838 i_plinf(im, l, y, ...)
3849 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3850 /* supplied as a byte string */
3851 work = (i_fcolor *)SvPV(ST(3), len);
3852 count = len / sizeof(i_fcolor);
3853 if (count * sizeof(i_fcolor) != len) {
3854 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3856 RETVAL = i_plinf(im, l, l+count, y, work);
3859 work = mymalloc(sizeof(i_fcolor) * (items-3));
3860 for (i=0; i < items-3; ++i) {
3861 if (sv_isobject(ST(i+3))
3862 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3863 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3864 work[i] = *INT2PTR(i_fcolor *, tmp);
3868 croak("i_plinf: pixels must be Imager::Color::Float objects");
3872 RETVAL = i_plinf(im, l, l+items-3, y, work);
3890 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3891 if (i_gpixf(im, x, y, color) == 0) {
3892 RETVAL = NEWSV(0,0);
3893 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3897 RETVAL = &PL_sv_undef;
3913 vals = mymalloc((r-l) * sizeof(i_color));
3914 count = i_glin(im, l, r, y, vals);
3915 if (GIMME_V == G_ARRAY) {
3917 for (i = 0; i < count; ++i) {
3919 i_color *col = mymalloc(sizeof(i_color));
3921 sv = sv_newmortal();
3922 sv_setref_pv(sv, "Imager::Color", (void *)col);
3928 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3934 i_glinf(im, l, r, y)
3944 vals = mymalloc((r-l) * sizeof(i_fcolor));
3945 count = i_glinf(im, l, r, y, vals);
3946 if (GIMME_V == G_ARRAY) {
3948 for (i = 0; i < count; ++i) {
3950 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3952 sv = sv_newmortal();
3953 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3959 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3965 i_img_16_new(x, y, ch)
3971 i_img_double_new(x, y, ch)
3977 i_tags_addn(im, name, code, idata)
3986 name = SvPV(ST(1), len);
3989 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3994 i_tags_add(im, name, code, data, idata)
4004 name = SvPV(ST(1), len);
4008 data = SvPV(ST(3), len);
4013 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
4018 i_tags_find(im, name, start)
4025 if (i_tags_find(&im->tags, name, start, &entry)) {
4027 RETVAL = newSVpv("0 but true", 0);
4029 RETVAL = newSViv(entry);
4031 RETVAL = &PL_sv_undef;
4037 i_tags_findn(im, code, start)
4044 if (i_tags_findn(&im->tags, code, start, &entry)) {
4046 RETVAL = newSVpv("0 but true", 0);
4048 RETVAL = newSViv(entry);
4051 RETVAL = &PL_sv_undef;
4057 i_tags_delete(im, entry)
4061 RETVAL = i_tags_delete(&im->tags, entry);
4066 i_tags_delbyname(im, name)
4070 RETVAL = i_tags_delbyname(&im->tags, name);
4075 i_tags_delbycode(im, code)
4079 RETVAL = i_tags_delbycode(&im->tags, code);
4084 i_tags_get(im, index)
4088 if (index >= 0 && index < im->tags.count) {
4089 i_img_tag *entry = im->tags.tags + index;
4093 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4096 PUSHs(sv_2mortal(newSViv(entry->code)));
4099 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4102 PUSHs(sv_2mortal(newSViv(entry->idata)));
4107 i_tags_get_string(im, what_sv)
4111 char const *name = NULL;
4115 if (SvIOK(what_sv)) {
4116 code = SvIV(what_sv);
4120 name = SvPV_nolen(what_sv);
4123 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4125 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4132 RETVAL = im->tags.count;
4139 i_wf_bbox(face, size, text)
4144 int cords[BOUNDING_BOX_COUNT];
4147 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4149 for (i = 0; i < rc; ++i)
4150 PUSHs(sv_2mortal(newSViv(cords[i])));
4154 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4165 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4171 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4182 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4195 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4197 #define FT2_DESTROY(font) i_ft2_destroy(font)
4201 Imager::Font::FT2 font
4203 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4206 i_ft2_new(name, index)
4211 i_ft2_setdpi(font, xdpi, ydpi)
4212 Imager::Font::FT2 font
4218 Imager::Font::FT2 font
4222 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4224 PUSHs(sv_2mortal(newSViv(xdpi)));
4225 PUSHs(sv_2mortal(newSViv(ydpi)));
4229 i_ft2_sethinting(font, hinting)
4230 Imager::Font::FT2 font
4234 i_ft2_settransform(font, matrix)
4235 Imager::Font::FT2 font
4243 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4244 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4245 av=(AV*)SvRV(ST(1));
4249 for (i = 0; i < len; ++i) {
4250 sv1=(*(av_fetch(av,i,0)));
4251 matrix[i] = SvNV(sv1);
4255 RETVAL = i_ft2_settransform(font, matrix);
4260 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4261 Imager::Font::FT2 font
4267 int bbox[BOUNDING_BOX_COUNT];
4273 text = SvPV(text_sv, text_len);
4275 if (SvUTF8(text_sv))
4278 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4281 for (i = 0; i < rc; ++i)
4282 PUSHs(sv_2mortal(newSViv(bbox[i])));
4286 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4287 Imager::Font::FT2 font
4301 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4304 for (i = 0; i < 8; ++i)
4305 PUSHs(sv_2mortal(newSViv(bbox[i])));
4309 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4310 Imager::Font::FT2 font
4326 if (SvUTF8(ST(7))) {
4330 text = SvPV(ST(7), len);
4331 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4332 len, align, aa, vlayout, utf8);
4337 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4338 Imager::Font::FT2 font
4355 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4356 strlen(text), align, aa, vlayout, 1);
4361 ft2_transform_box(font, x0, x1, x2, x3)
4362 Imager::Font::FT2 font
4370 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4371 ft2_transform_box(font, box);
4373 PUSHs(sv_2mortal(newSViv(box[0])));
4374 PUSHs(sv_2mortal(newSViv(box[1])));
4375 PUSHs(sv_2mortal(newSViv(box[2])));
4376 PUSHs(sv_2mortal(newSViv(box[3])));
4379 i_ft2_has_chars(handle, text_sv, utf8)
4380 Imager::Font::FT2 handle
4391 if (SvUTF8(text_sv))
4394 text = SvPV(text_sv, len);
4395 work = mymalloc(len);
4396 count = i_ft2_has_chars(handle, text, len, utf8, work);
4397 if (GIMME_V == G_ARRAY) {
4399 for (i = 0; i < count; ++i) {
4400 PUSHs(sv_2mortal(newSViv(work[i])));
4405 PUSHs(sv_2mortal(newSVpv(work, count)));
4410 i_ft2_face_name(handle)
4411 Imager::Font::FT2 handle
4416 len = i_ft2_face_name(handle, name, sizeof(name));
4419 PUSHs(sv_2mortal(newSVpv(name, 0)));
4423 i_ft2_can_face_name()
4426 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4427 Imager::Font::FT2 handle
4438 if (SvUTF8(text_sv))
4441 text = SvPV(text_sv, work_len);
4446 ch = i_utf8_advance(&text, &len);
4448 i_push_error(0, "invalid UTF8 character");
4457 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4459 PUSHs(sv_2mortal(newSVpv(name, 0)));
4462 PUSHs(&PL_sv_undef);
4467 i_ft2_can_do_glyph_names()
4470 i_ft2_face_has_glyph_names(handle)
4471 Imager::Font::FT2 handle
4474 i_ft2_is_multiple_master(handle)
4475 Imager::Font::FT2 handle
4478 i_ft2_get_multiple_masters(handle)
4479 Imager::Font::FT2 handle
4484 if (i_ft2_get_multiple_masters(handle, &mm)) {
4485 EXTEND(SP, 2+mm.num_axis);
4486 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4487 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4488 for (i = 0; i < mm.num_axis; ++i) {
4492 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4494 av_store(av, 0, sv);
4495 sv = newSViv(mm.axis[i].minimum);
4497 av_store(av, 1, sv);
4498 sv = newSViv(mm.axis[i].maximum);
4500 av_store(av, 2, sv);
4501 PUSHs(newRV_noinc((SV *)av));
4506 i_ft2_set_mm_coords(handle, ...)
4507 Imager::Font::FT2 handle
4513 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4514 transfer the array manually */
4515 ix_coords = items-1;
4516 coords = mymalloc(sizeof(long) * ix_coords);
4517 for (i = 0; i < ix_coords; ++i) {
4518 coords[i] = (long)SvIV(ST(1+i));
4520 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4527 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4531 Imager::FillHandle fill
4533 MODULE = Imager PACKAGE = Imager
4536 i_new_fill_solid(cl, combine)
4541 i_new_fill_solidf(cl, combine)
4542 Imager::Color::Float cl
4546 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4554 unsigned char *cust_hatch;
4558 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4562 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4567 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4568 Imager::Color::Float fg
4569 Imager::Color::Float bg
4575 unsigned char *cust_hatch;
4579 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4583 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4588 i_new_fill_image(src, matrix, xoff, yoff, combine)
4605 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4606 croak("i_new_fill_image: parameter must be an arrayref");
4607 av=(AV*)SvRV(ST(1));
4611 for (i = 0; i < len; ++i) {
4612 sv1=(*(av_fetch(av,i,0)));
4613 matrix[i] = SvNV(sv1);
4619 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4623 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4625 # this class is only exposed for testing
4628 i_int_hlines_testing()
4630 #if i_int_hlines_testing()
4632 Imager::Internal::Hlines
4633 i_int_hlines_new(start_y, count_y, start_x, count_x)
4639 Imager::Internal::Hlines
4640 i_int_hlines_new_img(im)
4644 i_int_hlines_add(hlines, y, minx, width)
4645 Imager::Internal::Hlines hlines
4651 i_int_hlines_DESTROY(hlines)
4652 Imager::Internal::Hlines hlines
4655 i_int_hlines_dump(hlines)
4656 Imager::Internal::Hlines hlines
4661 PERL_SET_GLOBAL_CALLBACKS;