12 #define i_int_hlines_testing() 1
20 typedef io_glue* Imager__IO;
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 : 0;
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) {
328 result = call_writer(cbd, cbd->buffer, cbd->used);
333 static off_t io_seeker(void *p, off_t offset, int whence) {
334 struct cbdata *cbd = p;
339 if (!SvOK(cbd->seekcb))
343 if (cbd->used && write_flush(cbd) <= 0)
347 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
348 offset -= cbd->where - cbd->used;
351 cbd->where = cbd->used = 0;
357 PUSHs(sv_2mortal(newSViv(offset)));
358 PUSHs(sv_2mortal(newSViv(whence)));
361 count = perl_call_sv(cbd->seekcb, G_SCALAR);
366 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
377 static ssize_t io_writer(void *p, void const *data, size_t size) {
378 struct cbdata *cbd = p;
380 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
382 if (cbd->reading && cbd->where < cbd->used) {
383 /* we read past the place where the caller expected us to be
384 so adjust our position a bit */
386 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
391 cbd->where = cbd->used = 0;
394 if (cbd->used && cbd->used + size > cbd->maxlength) {
395 if (write_flush(cbd) <= 0) {
400 if (cbd->used+size <= cbd->maxlength) {
401 memcpy(cbd->buffer + cbd->used, data, size);
405 /* it doesn't fit - just pass it up */
406 return call_writer(cbd, data, size);
409 static ssize_t io_reader(void *p, void *data, size_t size) {
410 struct cbdata *cbd = p;
412 char *out = data; /* so we can do pointer arithmetic */
415 if (write_flush(cbd) <= 0)
421 if (size <= cbd->used - cbd->where) {
423 memcpy(data, cbd->buffer+cbd->where, size);
428 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
429 total += cbd->used - cbd->where;
430 size -= cbd->used - cbd->where;
431 out += cbd->used - cbd->where;
432 if (size < sizeof(cbd->buffer)) {
436 && (did_read = call_reader(cbd, cbd->buffer, size,
437 sizeof(cbd->buffer))) > 0) {
439 cbd->used = did_read;
441 copy_size = i_min(size, cbd->used);
442 memcpy(out, cbd->buffer, copy_size);
443 cbd->where += copy_size;
450 /* just read the rest - too big for our buffer*/
452 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
462 static void io_closer(void *p) {
463 struct cbdata *cbd = p;
465 if (cbd->writing && cbd->used > 0) {
470 if (SvOK(cbd->closecb)) {
478 perl_call_sv(cbd->closecb, G_VOID);
487 static void io_destroyer(void *p) {
488 struct cbdata *cbd = p;
490 SvREFCNT_dec(cbd->writecb);
491 SvREFCNT_dec(cbd->readcb);
492 SvREFCNT_dec(cbd->seekcb);
493 SvREFCNT_dec(cbd->closecb);
501 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
504 for (i = 0; i < count; ++i)
505 if (strEQ(names[i].name, name))
506 return names[i].value;
510 static struct value_name transp_names[] =
513 { "threshold", tr_threshold },
514 { "errdiff", tr_errdiff },
515 { "ordered", tr_ordered, },
518 static struct value_name make_color_names[] =
520 { "none", mc_none, },
521 { "webmap", mc_web_map, },
522 { "addi", mc_addi, },
523 { "mediancut", mc_median_cut, },
526 static struct value_name translate_names[] =
529 { "giflib", pt_giflib, },
531 { "closest", pt_closest, },
532 { "perturb", pt_perturb, },
533 { "errdiff", pt_errdiff, },
536 static struct value_name errdiff_names[] =
538 { "floyd", ed_floyd, },
539 { "jarvis", ed_jarvis, },
540 { "stucki", ed_stucki, },
541 { "custom", ed_custom, },
544 static struct value_name orddith_names[] =
546 { "random", od_random, },
547 { "dot8", od_dot8, },
548 { "dot4", od_dot4, },
549 { "hline", od_hline, },
550 { "vline", od_vline, },
551 { "/line", od_slashline, },
552 { "slashline", od_slashline, },
553 { "\\line", od_backline, },
554 { "backline", od_backline, },
555 { "tiny", od_tiny, },
556 { "custom", od_custom, },
559 /* look through the hash for quantization options */
560 static void handle_quant_opts(i_quantize *quant, HV *hv)
562 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
568 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
570 sv = hv_fetch(hv, "transp", 6, 0);
571 if (sv && *sv && (str = SvPV(*sv, len))) {
573 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
575 if (quant->transp != tr_none) {
576 quant->tr_threshold = 127;
577 sv = hv_fetch(hv, "tr_threshold", 12, 0);
579 quant->tr_threshold = SvIV(*sv);
581 if (quant->transp == tr_errdiff) {
582 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
583 if (sv && *sv && (str = SvPV(*sv, len)))
584 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
586 if (quant->transp == tr_ordered) {
587 quant->tr_orddith = od_tiny;
588 sv = hv_fetch(hv, "tr_orddith", 10, 0);
589 if (sv && *sv && (str = SvPV(*sv, len)))
590 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
592 if (quant->tr_orddith == od_custom) {
593 sv = hv_fetch(hv, "tr_map", 6, 0);
594 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
595 AV *av = (AV*)SvRV(*sv);
596 len = av_len(av) + 1;
597 if (len > sizeof(quant->tr_custom))
598 len = sizeof(quant->tr_custom);
599 for (i = 0; i < len; ++i) {
600 SV **sv2 = av_fetch(av, i, 0);
602 quant->tr_custom[i] = SvIV(*sv2);
605 while (i < sizeof(quant->tr_custom))
606 quant->tr_custom[i++] = 0;
611 quant->make_colors = mc_addi;
612 sv = hv_fetch(hv, "make_colors", 11, 0);
613 if (sv && *sv && (str = SvPV(*sv, len))) {
615 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
617 sv = hv_fetch(hv, "colors", 6, 0);
618 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
619 /* needs to be an array of Imager::Color
620 note that the caller allocates the mc_color array and sets mc_size
622 AV *av = (AV *)SvRV(*sv);
623 quant->mc_count = av_len(av)+1;
624 if (quant->mc_count > quant->mc_size)
625 quant->mc_count = quant->mc_size;
626 for (i = 0; i < quant->mc_count; ++i) {
627 SV **sv1 = av_fetch(av, i, 0);
628 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
629 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
630 quant->mc_colors[i] = *col;
634 sv = hv_fetch(hv, "max_colors", 10, 0);
637 if (i <= quant->mc_size && i >= quant->mc_count)
641 quant->translate = pt_closest;
642 sv = hv_fetch(hv, "translate", 9, 0);
643 if (sv && *sv && (str = SvPV(*sv, len))) {
644 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
646 sv = hv_fetch(hv, "errdiff", 7, 0);
647 if (sv && *sv && (str = SvPV(*sv, len))) {
648 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
650 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
651 /* get the error diffusion map */
652 sv = hv_fetch(hv, "errdiff_width", 13, 0);
654 quant->ed_width = SvIV(*sv);
655 sv = hv_fetch(hv, "errdiff_height", 14, 0);
657 quant->ed_height = SvIV(*sv);
658 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
660 quant->ed_orig = SvIV(*sv);
661 if (quant->ed_width > 0 && quant->ed_height > 0) {
663 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
664 sv = hv_fetch(hv, "errdiff_map", 11, 0);
665 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
666 AV *av = (AV*)SvRV(*sv);
667 len = av_len(av) + 1;
668 if (len > quant->ed_width * quant->ed_height)
669 len = quant->ed_width * quant->ed_height;
670 for (i = 0; i < len; ++i) {
671 SV **sv2 = av_fetch(av, i, 0);
673 quant->ed_map[i] = SvIV(*sv2);
674 sum += quant->ed_map[i];
680 myfree(quant->ed_map);
682 quant->errdiff = ed_floyd;
686 sv = hv_fetch(hv, "perturb", 7, 0);
688 quant->perturb = SvIV(*sv);
691 static void cleanup_quant_opts(i_quantize *quant) {
692 myfree(quant->mc_colors);
694 myfree(quant->ed_map);
697 /* copies the color map from the hv into the colors member of the HV */
698 static void copy_colors_back(HV *hv, i_quantize *quant) {
704 sv = hv_fetch(hv, "colors", 6, 0);
705 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
708 ref = newRV_inc((SV*) av);
709 sv = hv_store(hv, "colors", 6, ref, 0);
712 av = (AV *)SvRV(*sv);
714 av_extend(av, quant->mc_count+1);
715 for (i = 0; i < quant->mc_count; ++i) {
716 i_color *in = quant->mc_colors+i;
717 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
718 work = sv_newmortal();
719 sv_setref_pv(work, "Imager::Color", (void *)c);
721 if (!av_store(av, i, work)) {
727 /* loads the segments of a fountain fill into an array */
728 static i_fountain_seg *
729 load_fount_segs(AV *asegs, int *count) {
730 /* Each element of segs must contain:
731 [ start, middle, end, c0, c1, segtype, colortrans ]
732 start, middle, end are doubles from 0 to 1
733 c0, c1 are Imager::Color::Float or Imager::Color objects
734 segtype, colortrans are ints
738 i_fountain_seg *segs;
742 *count = av_len(asegs)+1;
744 croak("i_fountain must have at least one segment");
745 segs = mymalloc(sizeof(i_fountain_seg) * *count);
746 for(i = 0; i < *count; i++) {
747 SV **sv1 = av_fetch(asegs, i, 0);
748 if (!sv1 || !*sv1 || !SvROK(*sv1)
749 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
751 croak("i_fountain: segs must be an arrayref of arrayrefs");
753 aseg = (AV *)SvRV(*sv1);
754 if (av_len(aseg) != 7-1) {
756 croak("i_fountain: a segment must have 7 members");
758 for (j = 0; j < 3; ++j) {
759 SV **sv2 = av_fetch(aseg, j, 0);
762 croak("i_fountain: XS error");
764 work[j] = SvNV(*sv2);
766 segs[i].start = work[0];
767 segs[i].middle = work[1];
768 segs[i].end = work[2];
769 for (j = 0; j < 2; ++j) {
770 SV **sv3 = av_fetch(aseg, 3+j, 0);
771 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
772 (!sv_derived_from(*sv3, "Imager::Color")
773 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
775 croak("i_fountain: segs must contain colors in elements 3 and 4");
777 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
778 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
781 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
783 for (ch = 0; ch < MAXCHANNELS; ++ch) {
784 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
788 for (j = 0; j < 2; ++j) {
789 SV **sv2 = av_fetch(aseg, j+5, 0);
792 croak("i_fountain: XS error");
794 worki[j] = SvIV(*sv2);
796 segs[i].type = worki[0];
797 segs[i].color = worki[1];
803 /* I don't think ICLF_* names belong at the C interface
804 this makes the XS code think we have them, to let us avoid
805 putting function bodies in the XS code
807 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
808 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
811 /* the m_init_log() function was called init_log(), renamed to reduce
812 potential naming conflicts */
813 #define init_log m_init_log
815 #if i_int_hlines_testing()
817 typedef i_int_hlines *Imager__Internal__Hlines;
819 static i_int_hlines *
820 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
821 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
822 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
827 static i_int_hlines *
828 i_int_hlines_new_img(i_img *im) {
829 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
830 i_int_init_hlines_img(result, im);
836 i_int_hlines_DESTROY(i_int_hlines *hlines) {
837 i_int_hlines_destroy(hlines);
841 static int seg_compare(const void *vleft, const void *vright) {
842 const i_int_hline_seg *left = vleft;
843 const i_int_hline_seg *right = vright;
845 return left->minx - right->minx;
849 i_int_hlines_dump(i_int_hlines *hlines) {
850 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
851 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
854 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
855 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
858 /* sort the segments, if any */
860 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
862 sv_catpvf(dump, " %d (%d):", y, entry->count);
863 for (i = 0; i < entry->count; ++i) {
864 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
865 entry->segs[i].x_limit);
867 sv_catpv(dump, "\n");
877 #define i_exif_enabled() 1
879 #define i_exif_enabled() 0
882 /* trying to use more C style names, map them here */
883 #define i_io_DESTROY(ig) io_glue_destroy(ig)
885 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
888 ICL_new_internal(r,g,b,a)
900 ICL_set_internal(cl,r,g,b,a)
907 ICL_set_internal(cl, r, g, b, a);
921 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
922 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
923 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
924 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
930 RETVAL = mymalloc(sizeof(i_color));
932 i_hsv_to_rgb(RETVAL);
940 RETVAL = mymalloc(sizeof(i_color));
942 i_rgb_to_hsv(RETVAL);
948 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
951 ICLF_new_internal(r, g, b, a)
959 Imager::Color::Float cl
963 Imager::Color::Float cl
967 EXTEND(SP, MAXCHANNELS);
968 for (ch = 0; ch < MAXCHANNELS; ++ch) {
969 /* printf("%d: %g\n", ch, cl->channel[ch]); */
970 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
974 ICLF_set_internal(cl,r,g,b,a)
975 Imager::Color::Float cl
990 Imager::Color::Float c
992 RETVAL = mymalloc(sizeof(i_fcolor));
994 i_hsv_to_rgbf(RETVAL);
1000 Imager::Color::Float c
1002 RETVAL = mymalloc(sizeof(i_fcolor));
1004 i_rgb_to_hsvf(RETVAL);
1008 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1022 MODULE = Imager PACKAGE = Imager
1041 SvPV(ST(0), length);
1042 SvREFCNT_inc(ST(0));
1043 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1048 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1057 cbd = mymalloc(sizeof(struct cbdata));
1058 SvREFCNT_inc(writecb);
1059 cbd->writecb = writecb;
1060 SvREFCNT_inc(readcb);
1061 cbd->readcb = readcb;
1062 SvREFCNT_inc(seekcb);
1063 cbd->seekcb = seekcb;
1064 SvREFCNT_inc(closecb);
1065 cbd->closecb = closecb;
1066 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1067 if (maxwrite > CBDATA_BUFSIZE)
1068 maxwrite = CBDATA_BUFSIZE;
1069 cbd->maxlength = maxwrite;
1070 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1079 unsigned char* data;
1083 tlength = io_slurp(ig, &data);
1085 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1090 i_set_image_file_limits(width, height, bytes)
1096 i_get_image_file_limits()
1098 int width, height, bytes;
1100 if (i_get_image_file_limits(&width, &height, &bytes)) {
1102 PUSHs(sv_2mortal(newSViv(width)));
1103 PUSHs(sv_2mortal(newSViv(height)));
1104 PUSHs(sv_2mortal(newSViv(bytes)));
1107 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1110 i_io_write(ig, data_sv)
1118 if (SvUTF8(data_sv)) {
1119 data_sv = sv_2mortal(newSVsv(data_sv));
1120 sv_utf8_downgrade(data_sv, FALSE);
1123 data = SvPV(data_sv, size);
1124 RETVAL = i_io_write(ig, data, size);
1129 i_io_read(ig, buffer_sv, size)
1138 croak("size negative in call to i_io_read()");
1139 /* prevent an undefined value warning if they supplied an
1141 Orginally conditional on !SvOK(), but this will prevent the
1142 downgrade from croaking */
1143 sv_setpvn(buffer_sv, "", 0);
1145 if (SvUTF8(buffer_sv))
1146 sv_utf8_downgrade(buffer_sv, FALSE);
1148 buffer = SvGROW(buffer_sv, size+1);
1149 result = i_io_read(ig, buffer, size);
1151 RETVAL = &PL_sv_undef;
1154 SvCUR_set(buffer_sv, result);
1155 *SvEND(buffer_sv) = '\0';
1156 SvPOK_only(buffer_sv);
1157 RETVAL = newSViv(result); /* XS will mortal this */
1164 i_io_seek(ig, position, whence)
1178 MODULE = Imager PACKAGE = Imager
1189 while( (item=i_format_list[i++]) != NULL ) {
1191 PUSHs(sv_2mortal(newSVpv(item,0)));
1208 i_img_empty_ch(im,x,y,ch)
1215 i_sametype(im, x, y)
1221 i_sametype_chans(im, x, y, channels)
1228 i_init_log(name,level)
1233 i_log_entry(string,level)
1252 i_img_info(im,info);
1254 PUSHs(sv_2mortal(newSViv(info[0])));
1255 PUSHs(sv_2mortal(newSViv(info[1])));
1256 PUSHs(sv_2mortal(newSViv(info[2])));
1257 PUSHs(sv_2mortal(newSViv(info[3])));
1263 i_img_setmask(im,ch_mask)
1272 i_img_getchannels(im)
1281 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1286 i_line(im,x1,y1,x2,y2,val,endp)
1296 i_line_aa(im,x1,y1,x2,y2,val,endp)
1306 i_box(im,x1,y1,x2,y2,val)
1315 i_box_filled(im,x1,y1,x2,y2,val)
1324 i_box_cfill(im,x1,y1,x2,y2,fill)
1330 Imager::FillHandle fill
1333 i_arc(im,x,y,rad,d1,d2,val)
1343 i_arc_aa(im,x,y,rad,d1,d2,val)
1353 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1360 Imager::FillHandle fill
1363 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1370 Imager::FillHandle fill
1374 i_circle_aa(im,x,y,rad,val)
1384 i_bezier_multi(im,xc,yc,val)
1397 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1398 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1399 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1400 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1401 av1=(AV*)SvRV(ST(1));
1402 av2=(AV*)SvRV(ST(2));
1403 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1405 x=mymalloc( len*sizeof(double) );
1406 y=mymalloc( len*sizeof(double) );
1407 for(i=0;i<len;i++) {
1408 sv1=(*(av_fetch(av1,i,0)));
1409 sv2=(*(av_fetch(av2,i,0)));
1410 x[i]=(double)SvNV(sv1);
1411 y[i]=(double)SvNV(sv2);
1413 i_bezier_multi(im,len,x,y,val);
1419 i_poly_aa(im,xc,yc,val)
1432 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1433 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1434 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1435 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1436 av1=(AV*)SvRV(ST(1));
1437 av2=(AV*)SvRV(ST(2));
1438 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1440 x=mymalloc( len*sizeof(double) );
1441 y=mymalloc( len*sizeof(double) );
1442 for(i=0;i<len;i++) {
1443 sv1=(*(av_fetch(av1,i,0)));
1444 sv2=(*(av_fetch(av2,i,0)));
1445 x[i]=(double)SvNV(sv1);
1446 y[i]=(double)SvNV(sv2);
1448 i_poly_aa(im,len,x,y,val);
1453 i_poly_aa_cfill(im,xc,yc,fill)
1455 Imager::FillHandle fill
1465 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1466 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1467 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1468 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1469 av1=(AV*)SvRV(ST(1));
1470 av2=(AV*)SvRV(ST(2));
1471 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1473 x=mymalloc( len*sizeof(double) );
1474 y=mymalloc( len*sizeof(double) );
1475 for(i=0;i<len;i++) {
1476 sv1=(*(av_fetch(av1,i,0)));
1477 sv2=(*(av_fetch(av2,i,0)));
1478 x[i]=(double)SvNV(sv1);
1479 y[i]=(double)SvNV(sv2);
1481 i_poly_aa_cfill(im,len,x,y,fill);
1488 i_flood_fill(im,seedx,seedy,dcol)
1495 i_flood_cfill(im,seedx,seedy,fill)
1499 Imager::FillHandle fill
1503 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1515 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1532 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1544 i_flipxy(im, direction)
1549 i_rotate90(im, degrees)
1554 i_rotate_exact(im, amount, ...)
1558 i_color *backp = NULL;
1559 i_fcolor *fbackp = NULL;
1563 /* extract the bg colors if any */
1564 /* yes, this is kind of strange */
1565 for (i = 2; i < items; ++i) {
1567 if (sv_derived_from(sv1, "Imager::Color")) {
1568 IV tmp = SvIV((SV*)SvRV(sv1));
1569 backp = INT2PTR(i_color *, tmp);
1571 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1572 IV tmp = SvIV((SV*)SvRV(sv1));
1573 fbackp = INT2PTR(i_fcolor *, tmp);
1576 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1581 i_matrix_transform(im, xsize, ysize, matrix, ...)
1591 i_color *backp = NULL;
1592 i_fcolor *fbackp = NULL;
1594 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1595 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1596 av=(AV*)SvRV(ST(3));
1600 for (i = 0; i < len; ++i) {
1601 sv1=(*(av_fetch(av,i,0)));
1602 matrix[i] = SvNV(sv1);
1606 /* extract the bg colors if any */
1607 /* yes, this is kind of strange */
1608 for (i = 4; i < items; ++i) {
1610 if (sv_derived_from(sv1, "Imager::Color")) {
1611 IV tmp = SvIV((SV*)SvRV(sv1));
1612 backp = INT2PTR(i_color *, tmp);
1614 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1615 IV tmp = SvIV((SV*)SvRV(sv1));
1616 fbackp = INT2PTR(i_fcolor *, tmp);
1619 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1624 i_gaussian(im,stdev)
1629 i_unsharp_mask(im,stdev,scale)
1644 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1645 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1646 av=(AV*)SvRV(ST(1));
1648 coeff=mymalloc( len*sizeof(float) );
1649 for(i=0;i<len;i++) {
1650 sv1=(*(av_fetch(av,i,0)));
1651 coeff[i]=(float)SvNV(sv1);
1653 i_conv(im,coeff,len);
1657 i_convert(im, src, coeff)
1670 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1671 croak("i_convert: parameter 3 must be an arrayref\n");
1672 avmain = (AV*)SvRV(ST(2));
1673 outchan = av_len(avmain)+1;
1674 /* find the biggest */
1676 for (j=0; j < outchan; ++j) {
1677 temp = av_fetch(avmain, j, 0);
1678 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1679 avsub = (AV*)SvRV(*temp);
1680 len = av_len(avsub)+1;
1685 coeff = mymalloc(sizeof(float) * outchan * inchan);
1686 for (j = 0; j < outchan; ++j) {
1687 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1688 len = av_len(avsub)+1;
1689 for (i = 0; i < len; ++i) {
1690 temp = av_fetch(avsub, i, 0);
1692 coeff[i+j*inchan] = SvNV(*temp);
1694 coeff[i+j*inchan] = 0;
1697 coeff[i++ + j*inchan] = 0;
1699 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1709 unsigned int mask = 0;
1715 unsigned char (*maps)[256];
1717 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1718 croak("i_map: parameter 2 must be an arrayref\n");
1719 avmain = (AV*)SvRV(ST(1));
1720 len = av_len(avmain)+1;
1721 if (im->channels < len) len = im->channels;
1723 maps = mymalloc( len * sizeof(unsigned char [256]) );
1725 for (j=0; j<len ; j++) {
1726 temp = av_fetch(avmain, j, 0);
1727 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1728 avsub = (AV*)SvRV(*temp);
1729 if(av_len(avsub) != 255) continue;
1731 for (i=0; i<256 ; i++) {
1733 temp = av_fetch(avsub, i, 0);
1734 val = temp ? SvIV(*temp) : 0;
1736 if (val>255) val = 255;
1741 i_map(im, maps, mask);
1754 i_init_fonts(t1log=0)
1769 i_t1_destroy(font_id)
1774 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1793 str = SvPV(str_sv, len);
1794 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1801 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1810 int cords[BOUNDING_BOX_COUNT];
1818 str = SvPV(str_sv, len);
1819 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1822 for (i = 0; i < rc; ++i)
1823 PUSHs(sv_2mortal(newSViv(cords[i])));
1829 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1848 str = SvPV(str_sv, len);
1849 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1855 i_t1_has_chars(handle, text_sv, utf8 = 0)
1867 if (SvUTF8(text_sv))
1870 text = SvPV(text_sv, len);
1871 work = mymalloc(len);
1872 count = i_t1_has_chars(handle, text, len, utf8, work);
1873 if (GIMME_V == G_ARRAY) {
1875 for (i = 0; i < count; ++i) {
1876 PUSHs(sv_2mortal(newSViv(work[i])));
1881 PUSHs(sv_2mortal(newSVpv(work, count)));
1886 i_t1_face_name(handle)
1892 len = i_t1_face_name(handle, name, sizeof(name));
1895 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1899 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1910 if (SvUTF8(text_sv))
1913 text = SvPV(text_sv, work_len);
1918 ch = i_utf8_advance(&text, &len);
1920 i_push_error(0, "invalid UTF8 character");
1929 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1930 PUSHs(sv_2mortal(newSVpv(name, 0)));
1933 PUSHs(&PL_sv_undef);
1947 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1949 #define TT_DESTROY(handle) i_tt_destroy(handle)
1953 Imager::Font::TT handle
1956 MODULE = Imager PACKAGE = Imager
1960 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1961 Imager::Font::TT handle
1979 str = SvPV(str_sv, len);
1980 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1981 len, smooth, utf8, align);
1987 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1988 Imager::Font::TT handle
2006 str = SvPV(str_sv, len);
2007 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2008 smooth, utf8, align);
2014 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2015 Imager::Font::TT handle
2020 int cords[BOUNDING_BOX_COUNT],rc;
2029 str = SvPV(str_sv, len);
2030 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2032 for (i = 0; i < rc; ++i) {
2033 PUSHs(sv_2mortal(newSViv(cords[i])));
2038 i_tt_has_chars(handle, text_sv, utf8)
2039 Imager::Font::TT handle
2050 if (SvUTF8(text_sv))
2053 text = SvPV(text_sv, len);
2054 work = mymalloc(len);
2055 count = i_tt_has_chars(handle, text, len, utf8, work);
2056 if (GIMME_V == G_ARRAY) {
2058 for (i = 0; i < count; ++i) {
2059 PUSHs(sv_2mortal(newSViv(work[i])));
2064 PUSHs(sv_2mortal(newSVpv(work, count)));
2069 i_tt_dump_names(handle)
2070 Imager::Font::TT handle
2073 i_tt_face_name(handle)
2074 Imager::Font::TT handle
2079 len = i_tt_face_name(handle, name, sizeof(name));
2082 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2086 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2087 Imager::Font::TT handle
2098 if (SvUTF8(text_sv))
2101 text = SvPV(text_sv, work_len);
2106 ch = i_utf8_advance(&text, &len);
2108 i_push_error(0, "invalid UTF8 character");
2117 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2118 PUSHs(sv_2mortal(newSVpv(name, 0)));
2121 PUSHs(&PL_sv_undef);
2130 i_writejpeg_wiol(im, ig, qfactor)
2146 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2147 if (iptc_itext == NULL) {
2150 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2155 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2157 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2168 i_test_format_probe(ig, length)
2177 i_readtiff_wiol(ig, length, page=0)
2183 i_readtiff_multi_wiol(ig, length)
2191 imgs = i_readtiff_multi_wiol(ig, length, &count);
2194 for (i = 0; i < count; ++i) {
2195 SV *sv = sv_newmortal();
2196 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2204 i_writetiff_wiol(im, ig)
2209 i_writetiff_multi_wiol(ig, ...)
2217 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2218 img_count = items - 1;
2220 if (img_count < 1) {
2223 i_push_error(0, "You need to specify images to save");
2226 imgs = mymalloc(sizeof(i_img *) * img_count);
2227 for (i = 0; i < img_count; ++i) {
2230 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2231 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2235 i_push_error(0, "Only images can be saved");
2242 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2250 i_writetiff_wiol_faxable(im, ig, fine)
2256 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2265 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2266 img_count = items - 2;
2268 if (img_count < 1) {
2271 i_push_error(0, "You need to specify images to save");
2274 imgs = mymalloc(sizeof(i_img *) * img_count);
2275 for (i = 0; i < img_count; ++i) {
2278 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2279 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2283 i_push_error(0, "Only images can be saved");
2290 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2298 #endif /* HAVE_LIBTIFF */
2304 i_readpng_wiol(ig, length)
2310 i_writepng_wiol(im, ig)
2323 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2326 i_writegif(im,fd,colors,pixdev,fixed)
2333 Imager__Color fixed;
2340 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2341 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2342 av=(AV*)SvRV(ST(4));
2343 fixedlen=av_len(av)+1;
2344 fixed=mymalloc( fixedlen*sizeof(i_color) );
2345 for(i=0;i<fixedlen;i++) {
2346 sv1=(*(av_fetch(av,i,0)));
2347 if (sv_derived_from(sv1, "Imager::Color")) {
2348 Itmp = SvIV((SV*)SvRV(sv1));
2349 tmp = INT2PTR(i_color*, Itmp);
2350 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2353 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2355 ST(0) = sv_newmortal();
2356 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2357 else sv_setiv(ST(0), (IV)RETVAL);
2363 i_writegifmc(im,fd,colors)
2370 i_writegif_gen(fd, ...)
2375 i_img **imgs = NULL;
2381 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2382 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2383 croak("i_writegif_gen: Second argument must be a hash ref");
2384 hv = (HV *)SvRV(ST(1));
2385 memset(&quant, 0, sizeof(quant));
2386 quant.mc_size = 256;
2387 handle_quant_opts(&quant, hv);
2388 img_count = items - 2;
2390 if (img_count < 1) {
2393 i_push_error(0, "You need to specify images to save");
2396 imgs = mymalloc(sizeof(i_img *) * img_count);
2397 for (i = 0; i < img_count; ++i) {
2400 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2401 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2405 i_push_error(0, "Only images can be saved");
2411 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2415 copy_colors_back(hv, &quant);
2418 ST(0) = sv_newmortal();
2419 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2420 else sv_setiv(ST(0), (IV)RETVAL);
2421 cleanup_quant_opts(&quant);
2425 i_writegif_callback(cb, maxbuffer,...)
2429 i_img **imgs = NULL;
2436 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2437 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2438 croak("i_writegif_callback: Second argument must be a hash ref");
2439 hv = (HV *)SvRV(ST(2));
2440 memset(&quant, 0, sizeof(quant));
2441 quant.mc_size = 256;
2442 handle_quant_opts(&quant, hv);
2443 img_count = items - 3;
2445 if (img_count < 1) {
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)));
2463 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2467 copy_colors_back(hv, &quant);
2470 ST(0) = sv_newmortal();
2471 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2472 else sv_setiv(ST(0), (IV)RETVAL);
2473 cleanup_quant_opts(&quant);
2476 i_writegif_wiol(ig, opts,...)
2480 i_img **imgs = NULL;
2486 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2487 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2488 croak("i_writegif_callback: Second argument must be a hash ref");
2489 hv = (HV *)SvRV(ST(1));
2490 memset(&quant, 0, sizeof(quant));
2491 quant.mc_size = 256;
2492 handle_quant_opts(&quant, hv);
2493 img_count = items - 2;
2495 if (img_count < 1) {
2499 imgs = mymalloc(sizeof(i_img *) * img_count);
2500 for (i = 0; i < img_count; ++i) {
2503 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2504 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2512 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2516 copy_colors_back(hv, &quant);
2519 ST(0) = sv_newmortal();
2520 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2521 else sv_setiv(ST(0), (IV)RETVAL);
2522 cleanup_quant_opts(&quant);
2535 colour_table = NULL;
2538 if(GIMME_V == G_ARRAY) {
2539 rimg = i_readgif(fd,&colour_table,&colours);
2541 /* don't waste time with colours if they aren't wanted */
2542 rimg = i_readgif(fd,NULL,NULL);
2545 if (colour_table == NULL) {
2548 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2551 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2552 /* I don't know if I have the reference counts right or not :( */
2553 /* Neither do I :-) */
2554 /* No Idea here either */
2557 av_extend(ct, colours);
2558 for(q=0; q<colours; q++) {
2560 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2561 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2563 myfree(colour_table);
2567 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2569 PUSHs(newRV_noinc((SV*)ct));
2583 colour_table = NULL;
2586 if(GIMME_V == G_ARRAY) {
2587 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2589 /* don't waste time with colours if they aren't wanted */
2590 rimg = i_readgif_wiol(ig,NULL,NULL);
2593 if (colour_table == NULL) {
2596 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2599 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2600 /* I don't know if I have the reference counts right or not :( */
2601 /* Neither do I :-) */
2602 /* No Idea here either */
2605 av_extend(ct, colours);
2606 for(q=0; q<colours; q++) {
2608 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2609 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2611 myfree(colour_table);
2615 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2617 PUSHs(newRV_noinc((SV*)ct));
2621 i_readgif_single_wiol(ig, page=0)
2626 i_readgif_scalar(...)
2638 data = (char *)SvPV(ST(0), length);
2642 if(GIMME_V == G_ARRAY) {
2643 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2645 /* don't waste time with colours if they aren't wanted */
2646 rimg=i_readgif_scalar(data,length,NULL,NULL);
2649 if (colour_table == NULL) {
2652 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2655 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2656 /* I don't know if I have the reference counts right or not :( */
2657 /* Neither do I :-) */
2659 av_extend(ct, colours);
2660 for(q=0; q<colours; q++) {
2662 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2663 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2665 myfree(colour_table);
2669 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2671 PUSHs(newRV_noinc((SV*)ct));
2675 i_readgif_callback(...)
2690 if(GIMME_V == G_ARRAY) {
2691 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2693 /* don't waste time with colours if they aren't wanted */
2694 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2697 if (colour_table == NULL) {
2700 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2703 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2704 /* I don't know if I have the reference counts right or not :( */
2705 /* Neither do I :-) */
2706 /* Neither do I - maybe I'll move this somewhere */
2708 av_extend(ct, colours);
2709 for(q=0; q<colours; q++) {
2711 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2712 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2714 myfree(colour_table);
2718 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2720 PUSHs(newRV_noinc((SV*)ct));
2731 imgs = i_readgif_multi(fd, &count);
2734 for (i = 0; i < count; ++i) {
2735 SV *sv = sv_newmortal();
2736 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2743 i_readgif_multi_scalar(data)
2751 data = (char *)SvPV(ST(0), length);
2752 imgs = i_readgif_multi_scalar(data, length, &count);
2755 for (i = 0; i < count; ++i) {
2756 SV *sv = sv_newmortal();
2757 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2764 i_readgif_multi_callback(cb)
2772 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2775 for (i = 0; i < count; ++i) {
2776 SV *sv = sv_newmortal();
2777 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2784 i_readgif_multi_wiol(ig)
2791 imgs = i_readgif_multi_wiol(ig, &count);
2794 for (i = 0; i < count; ++i) {
2795 SV *sv = sv_newmortal();
2796 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2808 i_readpnm_wiol(ig, length)
2814 i_writeppm_wiol(im, ig)
2820 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2829 i_writeraw_wiol(im,ig)
2834 i_writebmp_wiol(im,ig)
2844 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2853 idlen = SvCUR(ST(4));
2854 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2860 i_readtga_wiol(ig, length)
2866 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2875 idlen = SvCUR(ST(4));
2876 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2882 i_readrgb_wiol(ig, length)
2889 i_scaleaxis(im,Value,Axis)
2895 i_scale_nn(im,scx,scy)
2905 i_count_colors(im,maxc)
2911 i_transform(im,opx,opy,parm)
2924 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2925 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2926 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2927 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2928 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2929 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2930 av=(AV*)SvRV(ST(1));
2932 opx=mymalloc( opxl*sizeof(int) );
2933 for(i=0;i<opxl;i++) {
2934 sv1=(*(av_fetch(av,i,0)));
2935 opx[i]=(int)SvIV(sv1);
2937 av=(AV*)SvRV(ST(2));
2939 opy=mymalloc( opyl*sizeof(int) );
2940 for(i=0;i<opyl;i++) {
2941 sv1=(*(av_fetch(av,i,0)));
2942 opy[i]=(int)SvIV(sv1);
2944 av=(AV*)SvRV(ST(3));
2945 parmlen=av_len(av)+1;
2946 parm=mymalloc( parmlen*sizeof(double) );
2947 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2948 sv1=(*(av_fetch(av,i,0)));
2949 parm[i]=(double)SvNV(sv1);
2951 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2955 ST(0) = sv_newmortal();
2956 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2957 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2960 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2985 in_imgs_count = av_len(av_in_imgs)+1;
2986 for (i = 0; i < in_imgs_count; ++i) {
2987 sv1 = *av_fetch(av_in_imgs, i, 0);
2988 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2989 croak("sv_in_img must contain only images");
2992 if (in_imgs_count > 0) {
2993 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2994 for (i = 0; i < in_imgs_count; ++i) {
2995 sv1 = *av_fetch(av_in_imgs,i,0);
2996 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2997 croak("Parameter 5 must contain only images");
2999 tmp = SvIV((SV*)SvRV(sv1));
3000 in_imgs[i] = INT2PTR(i_img*, tmp);
3004 /* no input images */
3007 /* default the output size from the first input if possible */
3009 width = SvIV(sv_width);
3010 else if (in_imgs_count)
3011 width = in_imgs[0]->xsize;
3013 croak("No output image width supplied");
3015 if (SvOK(sv_height))
3016 height = SvIV(sv_height);
3017 else if (in_imgs_count)
3018 height = in_imgs[0]->ysize;
3020 croak("No output image height supplied");
3022 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3023 if (ops_len % sizeof(struct rm_op))
3024 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3025 ops_count = ops_len / sizeof(struct rm_op);
3027 n_regs_count = av_len(av_n_regs)+1;
3028 n_regs = mymalloc(n_regs_count * sizeof(double));
3029 for (i = 0; i < n_regs_count; ++i) {
3030 sv1 = *av_fetch(av_n_regs,i,0);
3032 n_regs[i] = SvNV(sv1);
3034 c_regs_count = av_len(av_c_regs)+1;
3035 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3036 /* I don't bother initializing the colou?r registers */
3038 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3039 n_regs, n_regs_count,
3040 c_regs, c_regs_count, in_imgs, in_imgs_count);
3045 ST(0) = sv_newmortal();
3046 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3047 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3051 i_contrast(im,intensity)
3060 i_noise(im,amount,type)
3066 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3076 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3095 i_postlevels(im,levels)
3105 i_watermark(im,wmark,tx,ty,pixdiff)
3107 Imager::ImgRaw wmark
3114 i_autolevels(im,lsat,usat,skew)
3121 i_radnoise(im,xo,yo,rscale,ascale)
3129 i_turbnoise(im, xo, yo, scale)
3152 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3153 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3154 croak("i_gradgen: Second argument must be an array ref");
3155 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3156 croak("i_gradgen: Third argument must be an array ref");
3157 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3158 croak("i_gradgen: Fourth argument must be an array ref");
3159 axx = (AV *)SvRV(ST(1));
3160 ayy = (AV *)SvRV(ST(2));
3161 ac = (AV *)SvRV(ST(3));
3162 dmeasure = (int)SvIV(ST(4));
3164 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3165 num = num <= av_len(ac) ? num : av_len(ac);
3167 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3168 xo = mymalloc( sizeof(int) * num );
3169 yo = mymalloc( sizeof(int) * num );
3170 ival = mymalloc( sizeof(i_color) * num );
3171 for(i = 0; i<num; i++) {
3172 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3173 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3174 sv = *av_fetch(ac, i, 0);
3175 if ( !sv_derived_from(sv, "Imager::Color") ) {
3176 free(axx); free(ayy); free(ac);
3177 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3179 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3181 i_gradgen(im, num, xo, yo, ival, dmeasure);
3187 i_diff_image(im, im2, mindist=0)
3193 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3203 double ssample_param
3207 i_fountain_seg *segs;
3209 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3210 croak("i_fountain: argument 11 must be an array ref");
3212 asegs = (AV *)SvRV(ST(10));
3213 segs = load_fount_segs(asegs, &count);
3214 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3215 super_sample, ssample_param, count, segs);
3221 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3230 double ssample_param
3234 i_fountain_seg *segs;
3236 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3237 croak("i_fountain: argument 11 must be an array ref");
3239 asegs = (AV *)SvRV(ST(9));
3240 segs = load_fount_segs(asegs, &count);
3241 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3242 super_sample, ssample_param, count, segs);
3255 errors = i_errors();
3257 while (errors[i].msg) {
3259 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3260 if (!av_store(av, 0, sv)) {
3263 sv = newSViv(errors[i].code);
3264 if (!av_store(av, 1, sv)) {
3267 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3272 i_nearest_color(im, ...)
3287 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3288 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3289 croak("i_nearest_color: Second argument must be an array ref");
3290 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3291 croak("i_nearest_color: Third argument must be an array ref");
3292 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3293 croak("i_nearest_color: Fourth argument must be an array ref");
3294 axx = (AV *)SvRV(ST(1));
3295 ayy = (AV *)SvRV(ST(2));
3296 ac = (AV *)SvRV(ST(3));
3297 dmeasure = (int)SvIV(ST(4));
3299 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3300 num = num <= av_len(ac) ? num : av_len(ac);
3302 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3303 xo = mymalloc( sizeof(int) * num );
3304 yo = mymalloc( sizeof(int) * num );
3305 ival = mymalloc( sizeof(i_color) * num );
3306 for(i = 0; i<num; i++) {
3307 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3308 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3309 sv = *av_fetch(ac, i, 0);
3310 if ( !sv_derived_from(sv, "Imager::Color") ) {
3311 free(axx); free(ayy); free(ac);
3312 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3314 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3316 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3330 rc=DSO_open(filename,&evstr);
3334 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3335 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3338 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3344 DSO_close(dso_handle)
3348 DSO_funclist(dso_handle_v)
3352 DSO_handle *dso_handle;
3354 dso_handle=(DSO_handle*)dso_handle_v;
3356 while( dso_handle->function_list[i].name != NULL) {
3358 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3360 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3365 DSO_call(handle,func_index,hv)
3371 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3372 hv=(HV*)SvRV(ST(2));
3373 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3374 DSO_call( (DSO_handle *)handle,func_index,hv);
3379 i_get_pixel(im, x, y)
3386 color = (i_color *)mymalloc(sizeof(i_color));
3387 if (i_gpix(im, x, y, color) == 0) {
3388 RETVAL = NEWSV(0, 0);
3389 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3393 RETVAL = &PL_sv_undef;
3400 i_ppix(im, x, y, cl)
3407 i_img_pal_new(x, y, channels, maxpal)
3414 i_img_to_pal(src, quant)
3420 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3421 croak("i_img_to_pal: second argument must be a hash ref");
3422 hv = (HV *)SvRV(ST(1));
3423 memset(&quant, 0, sizeof(quant));
3424 quant.mc_size = 256;
3425 handle_quant_opts(&quant, hv);
3426 RETVAL = i_img_to_pal(src, &quant);
3428 copy_colors_back(hv, &quant);
3430 cleanup_quant_opts(&quant);
3449 work = mymalloc((r-l) * sizeof(i_palidx));
3450 count = i_gpal(im, l, r, y, work);
3451 if (GIMME_V == G_ARRAY) {
3453 for (i = 0; i < count; ++i) {
3454 PUSHs(sv_2mortal(newSViv(work[i])));
3459 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3464 if (GIMME_V != G_ARRAY) {
3466 PUSHs(&PL_sv_undef);
3471 i_ppal(im, l, y, ...)
3480 work = mymalloc(sizeof(i_palidx) * (items-3));
3481 for (i=0; i < items-3; ++i) {
3482 work[i] = SvIV(ST(i+3));
3484 RETVAL = i_ppal(im, l, l+items-3, y, work);
3494 i_addcolors(im, ...)
3502 croak("i_addcolors: no colors to add");
3503 colors = mymalloc((items-1) * sizeof(i_color));
3504 for (i=0; i < items-1; ++i) {
3505 if (sv_isobject(ST(i+1))
3506 && sv_derived_from(ST(i+1), "Imager::Color")) {
3507 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3508 colors[i] = *INT2PTR(i_color *, tmp);
3512 croak("i_addcolor: pixels must be Imager::Color objects");
3515 index = i_addcolors(im, colors, items-1);
3518 RETVAL = newSVpv("0 but true", 0);
3520 else if (index == -1) {
3521 RETVAL = &PL_sv_undef;
3524 RETVAL = newSViv(index);
3530 i_setcolors(im, index, ...)
3538 croak("i_setcolors: no colors to add");
3539 colors = mymalloc((items-2) * sizeof(i_color));
3540 for (i=0; i < items-2; ++i) {
3541 if (sv_isobject(ST(i+2))
3542 && sv_derived_from(ST(i+2), "Imager::Color")) {
3543 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3544 colors[i] = *INT2PTR(i_color *, tmp);
3548 croak("i_setcolors: pixels must be Imager::Color objects");
3551 RETVAL = i_setcolors(im, index, colors, items-2);
3557 i_getcolors(im, index, ...)
3566 croak("i_getcolors: too many arguments");
3568 count = SvIV(ST(2));
3570 croak("i_getcolors: count must be positive");
3571 colors = mymalloc(sizeof(i_color) * count);
3572 if (i_getcolors(im, index, colors, count)) {
3573 for (i = 0; i < count; ++i) {
3575 SV *sv = sv_newmortal();
3576 pv = mymalloc(sizeof(i_color));
3578 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3594 i_findcolor(im, color)
3600 if (i_findcolor(im, color, &index)) {
3601 RETVAL = newSViv(index);
3604 RETVAL = &PL_sv_undef;
3622 i_gsamp(im, l, r, y, ...)
3634 croak("No channel numbers supplied to g_samp()");
3636 chan_count = items - 4;
3637 chans = mymalloc(sizeof(int) * chan_count);
3638 for (i = 0; i < chan_count; ++i)
3639 chans[i] = SvIV(ST(i+4));
3640 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3641 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3643 if (GIMME_V == G_ARRAY) {
3645 for (i = 0; i < count; ++i)
3646 PUSHs(sv_2mortal(newSViv(data[i])));
3650 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3655 if (GIMME_V != G_ARRAY) {
3657 PUSHs(&PL_sv_undef);
3663 i_img_masked_new(targ, mask, x, y, w, h)
3673 if (!sv_isobject(ST(1))
3674 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3675 croak("i_img_masked_new: parameter 2 must undef or an image");
3677 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3681 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3686 i_plin(im, l, y, ...)
3697 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3698 /* supplied as a byte string */
3699 work = (i_color *)SvPV(ST(3), len);
3700 count = len / sizeof(i_color);
3701 if (count * sizeof(i_color) != len) {
3702 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3704 RETVAL = i_plin(im, l, l+count, y, work);
3707 work = mymalloc(sizeof(i_color) * (items-3));
3708 for (i=0; i < items-3; ++i) {
3709 if (sv_isobject(ST(i+3))
3710 && sv_derived_from(ST(i+3), "Imager::Color")) {
3711 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3712 work[i] = *INT2PTR(i_color *, tmp);
3716 croak("i_plin: pixels must be Imager::Color objects");
3719 RETVAL = i_plin(im, l, l+items-3, y, work);
3730 i_ppixf(im, x, y, cl)
3734 Imager::Color::Float cl
3737 i_gsampf(im, l, r, y, ...)
3749 croak("No channel numbers supplied to g_sampf()");
3751 chan_count = items - 4;
3752 chans = mymalloc(sizeof(int) * chan_count);
3753 for (i = 0; i < chan_count; ++i)
3754 chans[i] = SvIV(ST(i+4));
3755 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3756 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3758 if (GIMME_V == G_ARRAY) {
3760 for (i = 0; i < count; ++i)
3761 PUSHs(sv_2mortal(newSVnv(data[i])));
3765 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3770 if (GIMME_V != G_ARRAY) {
3772 PUSHs(&PL_sv_undef);
3777 i_plinf(im, l, y, ...)
3788 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3789 /* supplied as a byte string */
3790 work = (i_fcolor *)SvPV(ST(3), len);
3791 count = len / sizeof(i_fcolor);
3792 if (count * sizeof(i_fcolor) != len) {
3793 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3795 RETVAL = i_plinf(im, l, l+count, y, work);
3798 work = mymalloc(sizeof(i_fcolor) * (items-3));
3799 for (i=0; i < items-3; ++i) {
3800 if (sv_isobject(ST(i+3))
3801 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3802 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3803 work[i] = *INT2PTR(i_fcolor *, tmp);
3807 croak("i_plinf: pixels must be Imager::Color::Float objects");
3811 RETVAL = i_plinf(im, l, l+items-3, y, work);
3829 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3830 if (i_gpixf(im, x, y, color) == 0) {
3831 RETVAL = NEWSV(0,0);
3832 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3836 RETVAL = &PL_sv_undef;
3852 vals = mymalloc((r-l) * sizeof(i_color));
3853 count = i_glin(im, l, r, y, vals);
3854 if (GIMME_V == G_ARRAY) {
3856 for (i = 0; i < count; ++i) {
3858 i_color *col = mymalloc(sizeof(i_color));
3860 sv = sv_newmortal();
3861 sv_setref_pv(sv, "Imager::Color", (void *)col);
3867 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3873 i_glinf(im, l, r, y)
3883 vals = mymalloc((r-l) * sizeof(i_fcolor));
3884 count = i_glinf(im, l, r, y, vals);
3885 if (GIMME_V == G_ARRAY) {
3887 for (i = 0; i < count; ++i) {
3889 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3891 sv = sv_newmortal();
3892 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3898 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3904 i_img_16_new(x, y, ch)
3910 i_img_double_new(x, y, ch)
3916 i_tags_addn(im, name, code, idata)
3925 name = SvPV(ST(1), len);
3928 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3933 i_tags_add(im, name, code, data, idata)
3943 name = SvPV(ST(1), len);
3947 data = SvPV(ST(3), len);
3952 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3957 i_tags_find(im, name, start)
3964 if (i_tags_find(&im->tags, name, start, &entry)) {
3966 RETVAL = newSVpv("0 but true", 0);
3968 RETVAL = newSViv(entry);
3970 RETVAL = &PL_sv_undef;
3976 i_tags_findn(im, code, start)
3983 if (i_tags_findn(&im->tags, code, start, &entry)) {
3985 RETVAL = newSVpv("0 but true", 0);
3987 RETVAL = newSViv(entry);
3990 RETVAL = &PL_sv_undef;
3996 i_tags_delete(im, entry)
4000 RETVAL = i_tags_delete(&im->tags, entry);
4005 i_tags_delbyname(im, name)
4009 RETVAL = i_tags_delbyname(&im->tags, name);
4014 i_tags_delbycode(im, code)
4018 RETVAL = i_tags_delbycode(&im->tags, code);
4023 i_tags_get(im, index)
4027 if (index >= 0 && index < im->tags.count) {
4028 i_img_tag *entry = im->tags.tags + index;
4032 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4035 PUSHs(sv_2mortal(newSViv(entry->code)));
4038 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4041 PUSHs(sv_2mortal(newSViv(entry->idata)));
4046 i_tags_get_string(im, what_sv)
4050 char const *name = NULL;
4054 if (SvIOK(what_sv)) {
4055 code = SvIV(what_sv);
4059 name = SvPV_nolen(what_sv);
4062 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4064 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4071 RETVAL = im->tags.count;
4078 i_wf_bbox(face, size, text)
4083 int cords[BOUNDING_BOX_COUNT];
4086 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4088 for (i = 0; i < rc; ++i)
4089 PUSHs(sv_2mortal(newSViv(cords[i])));
4093 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4104 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4110 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4121 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4134 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4136 #define FT2_DESTROY(font) i_ft2_destroy(font)
4140 Imager::Font::FT2 font
4142 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4145 i_ft2_new(name, index)
4150 i_ft2_setdpi(font, xdpi, ydpi)
4151 Imager::Font::FT2 font
4157 Imager::Font::FT2 font
4161 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4163 PUSHs(sv_2mortal(newSViv(xdpi)));
4164 PUSHs(sv_2mortal(newSViv(ydpi)));
4168 i_ft2_sethinting(font, hinting)
4169 Imager::Font::FT2 font
4173 i_ft2_settransform(font, matrix)
4174 Imager::Font::FT2 font
4182 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4183 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4184 av=(AV*)SvRV(ST(1));
4188 for (i = 0; i < len; ++i) {
4189 sv1=(*(av_fetch(av,i,0)));
4190 matrix[i] = SvNV(sv1);
4194 RETVAL = i_ft2_settransform(font, matrix);
4199 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4200 Imager::Font::FT2 font
4206 int bbox[BOUNDING_BOX_COUNT];
4212 text = SvPV(text_sv, text_len);
4214 if (SvUTF8(text_sv))
4217 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4220 for (i = 0; i < rc; ++i)
4221 PUSHs(sv_2mortal(newSViv(bbox[i])));
4225 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4226 Imager::Font::FT2 font
4240 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4243 for (i = 0; i < 8; ++i)
4244 PUSHs(sv_2mortal(newSViv(bbox[i])));
4248 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4249 Imager::Font::FT2 font
4265 if (SvUTF8(ST(7))) {
4269 text = SvPV(ST(7), len);
4270 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4271 len, align, aa, vlayout, utf8);
4276 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4277 Imager::Font::FT2 font
4294 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4295 strlen(text), align, aa, vlayout, 1);
4300 ft2_transform_box(font, x0, x1, x2, x3)
4301 Imager::Font::FT2 font
4309 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4310 ft2_transform_box(font, box);
4312 PUSHs(sv_2mortal(newSViv(box[0])));
4313 PUSHs(sv_2mortal(newSViv(box[1])));
4314 PUSHs(sv_2mortal(newSViv(box[2])));
4315 PUSHs(sv_2mortal(newSViv(box[3])));
4318 i_ft2_has_chars(handle, text_sv, utf8)
4319 Imager::Font::FT2 handle
4330 if (SvUTF8(text_sv))
4333 text = SvPV(text_sv, len);
4334 work = mymalloc(len);
4335 count = i_ft2_has_chars(handle, text, len, utf8, work);
4336 if (GIMME_V == G_ARRAY) {
4338 for (i = 0; i < count; ++i) {
4339 PUSHs(sv_2mortal(newSViv(work[i])));
4344 PUSHs(sv_2mortal(newSVpv(work, count)));
4349 i_ft2_face_name(handle)
4350 Imager::Font::FT2 handle
4355 len = i_ft2_face_name(handle, name, sizeof(name));
4358 PUSHs(sv_2mortal(newSVpv(name, 0)));
4362 i_ft2_can_face_name()
4365 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4366 Imager::Font::FT2 handle
4377 if (SvUTF8(text_sv))
4380 text = SvPV(text_sv, work_len);
4385 ch = i_utf8_advance(&text, &len);
4387 i_push_error(0, "invalid UTF8 character");
4396 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4398 PUSHs(sv_2mortal(newSVpv(name, 0)));
4401 PUSHs(&PL_sv_undef);
4406 i_ft2_can_do_glyph_names()
4409 i_ft2_face_has_glyph_names(handle)
4410 Imager::Font::FT2 handle
4413 i_ft2_is_multiple_master(handle)
4414 Imager::Font::FT2 handle
4417 i_ft2_get_multiple_masters(handle)
4418 Imager::Font::FT2 handle
4423 if (i_ft2_get_multiple_masters(handle, &mm)) {
4424 EXTEND(SP, 2+mm.num_axis);
4425 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4426 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4427 for (i = 0; i < mm.num_axis; ++i) {
4431 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4433 av_store(av, 0, sv);
4434 sv = newSViv(mm.axis[i].minimum);
4436 av_store(av, 1, sv);
4437 sv = newSViv(mm.axis[i].maximum);
4439 av_store(av, 2, sv);
4440 PUSHs(newRV_noinc((SV *)av));
4445 i_ft2_set_mm_coords(handle, ...)
4446 Imager::Font::FT2 handle
4452 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4453 transfer the array manually */
4454 ix_coords = items-1;
4455 coords = mymalloc(sizeof(long) * ix_coords);
4456 for (i = 0; i < ix_coords; ++i) {
4457 coords[i] = (long)SvIV(ST(1+i));
4459 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4466 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4470 Imager::FillHandle fill
4472 MODULE = Imager PACKAGE = Imager
4475 i_new_fill_solid(cl, combine)
4480 i_new_fill_solidf(cl, combine)
4481 Imager::Color::Float cl
4485 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4493 unsigned char *cust_hatch;
4497 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4501 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4506 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4507 Imager::Color::Float fg
4508 Imager::Color::Float bg
4514 unsigned char *cust_hatch;
4518 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4522 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4527 i_new_fill_image(src, matrix, xoff, yoff, combine)
4544 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4545 croak("i_new_fill_image: parameter must be an arrayref");
4546 av=(AV*)SvRV(ST(1));
4550 for (i = 0; i < len; ++i) {
4551 sv1=(*(av_fetch(av,i,0)));
4552 matrix[i] = SvNV(sv1);
4558 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4562 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4564 # this class is only exposed for testing
4567 i_int_hlines_testing()
4569 #if i_int_hlines_testing()
4571 Imager::Internal::Hlines
4572 i_int_hlines_new(start_y, count_y, start_x, count_x)
4578 Imager::Internal::Hlines
4579 i_int_hlines_new_img(im)
4583 i_int_hlines_add(hlines, y, minx, width)
4584 Imager::Internal::Hlines hlines
4590 i_int_hlines_DESTROY(hlines)
4591 Imager::Internal::Hlines hlines
4594 i_int_hlines_dump(hlines)
4595 Imager::Internal::Hlines hlines
4600 PERL_SET_GLOBAL_CALLBACKS;