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 io_glue_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 = io_glue_
1114 MODULE = Imager PACKAGE = Imager
1127 while( (item=i_format_list[i++]) != NULL ) {
1129 PUSHs(sv_2mortal(newSVpv(item,0)));
1146 i_img_empty_ch(im,x,y,ch)
1153 i_sametype(im, x, y)
1159 i_sametype_chans(im, x, y, channels)
1166 i_init_log(name,level)
1171 i_log_entry(string,level)
1190 i_img_info(im,info);
1192 PUSHs(sv_2mortal(newSViv(info[0])));
1193 PUSHs(sv_2mortal(newSViv(info[1])));
1194 PUSHs(sv_2mortal(newSViv(info[2])));
1195 PUSHs(sv_2mortal(newSViv(info[3])));
1201 i_img_setmask(im,ch_mask)
1210 i_img_getchannels(im)
1219 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1224 i_line(im,x1,y1,x2,y2,val,endp)
1234 i_line_aa(im,x1,y1,x2,y2,val,endp)
1244 i_box(im,x1,y1,x2,y2,val)
1253 i_box_filled(im,x1,y1,x2,y2,val)
1262 i_box_cfill(im,x1,y1,x2,y2,fill)
1268 Imager::FillHandle fill
1271 i_arc(im,x,y,rad,d1,d2,val)
1281 i_arc_aa(im,x,y,rad,d1,d2,val)
1291 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1298 Imager::FillHandle fill
1301 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1308 Imager::FillHandle fill
1312 i_circle_aa(im,x,y,rad,val)
1322 i_bezier_multi(im,xc,yc,val)
1335 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1336 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1337 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1338 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1339 av1=(AV*)SvRV(ST(1));
1340 av2=(AV*)SvRV(ST(2));
1341 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1343 x=mymalloc( len*sizeof(double) );
1344 y=mymalloc( len*sizeof(double) );
1345 for(i=0;i<len;i++) {
1346 sv1=(*(av_fetch(av1,i,0)));
1347 sv2=(*(av_fetch(av2,i,0)));
1348 x[i]=(double)SvNV(sv1);
1349 y[i]=(double)SvNV(sv2);
1351 i_bezier_multi(im,len,x,y,val);
1357 i_poly_aa(im,xc,yc,val)
1370 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1371 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1372 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1373 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1374 av1=(AV*)SvRV(ST(1));
1375 av2=(AV*)SvRV(ST(2));
1376 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1378 x=mymalloc( len*sizeof(double) );
1379 y=mymalloc( len*sizeof(double) );
1380 for(i=0;i<len;i++) {
1381 sv1=(*(av_fetch(av1,i,0)));
1382 sv2=(*(av_fetch(av2,i,0)));
1383 x[i]=(double)SvNV(sv1);
1384 y[i]=(double)SvNV(sv2);
1386 i_poly_aa(im,len,x,y,val);
1391 i_poly_aa_cfill(im,xc,yc,fill)
1393 Imager::FillHandle fill
1403 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1404 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1405 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1406 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1407 av1=(AV*)SvRV(ST(1));
1408 av2=(AV*)SvRV(ST(2));
1409 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1411 x=mymalloc( len*sizeof(double) );
1412 y=mymalloc( len*sizeof(double) );
1413 for(i=0;i<len;i++) {
1414 sv1=(*(av_fetch(av1,i,0)));
1415 sv2=(*(av_fetch(av2,i,0)));
1416 x[i]=(double)SvNV(sv1);
1417 y[i]=(double)SvNV(sv2);
1419 i_poly_aa_cfill(im,len,x,y,fill);
1426 i_flood_fill(im,seedx,seedy,dcol)
1433 i_flood_cfill(im,seedx,seedy,fill)
1437 Imager::FillHandle fill
1441 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1453 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1470 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1482 i_flipxy(im, direction)
1487 i_rotate90(im, degrees)
1492 i_rotate_exact(im, amount, ...)
1496 i_color *backp = NULL;
1497 i_fcolor *fbackp = NULL;
1501 /* extract the bg colors if any */
1502 /* yes, this is kind of strange */
1503 for (i = 2; i < items; ++i) {
1505 if (sv_derived_from(sv1, "Imager::Color")) {
1506 IV tmp = SvIV((SV*)SvRV(sv1));
1507 backp = INT2PTR(i_color *, tmp);
1509 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1510 IV tmp = SvIV((SV*)SvRV(sv1));
1511 fbackp = INT2PTR(i_fcolor *, tmp);
1514 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1519 i_matrix_transform(im, xsize, ysize, matrix, ...)
1529 i_color *backp = NULL;
1530 i_fcolor *fbackp = NULL;
1532 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1533 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1534 av=(AV*)SvRV(ST(3));
1538 for (i = 0; i < len; ++i) {
1539 sv1=(*(av_fetch(av,i,0)));
1540 matrix[i] = SvNV(sv1);
1544 /* extract the bg colors if any */
1545 /* yes, this is kind of strange */
1546 for (i = 4; i < items; ++i) {
1548 if (sv_derived_from(sv1, "Imager::Color")) {
1549 IV tmp = SvIV((SV*)SvRV(sv1));
1550 backp = INT2PTR(i_color *, tmp);
1552 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1553 IV tmp = SvIV((SV*)SvRV(sv1));
1554 fbackp = INT2PTR(i_fcolor *, tmp);
1557 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1562 i_gaussian(im,stdev)
1567 i_unsharp_mask(im,stdev,scale)
1582 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1583 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1584 av=(AV*)SvRV(ST(1));
1586 coeff=mymalloc( len*sizeof(float) );
1587 for(i=0;i<len;i++) {
1588 sv1=(*(av_fetch(av,i,0)));
1589 coeff[i]=(float)SvNV(sv1);
1591 i_conv(im,coeff,len);
1595 i_convert(im, src, coeff)
1608 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1609 croak("i_convert: parameter 3 must be an arrayref\n");
1610 avmain = (AV*)SvRV(ST(2));
1611 outchan = av_len(avmain)+1;
1612 /* find the biggest */
1614 for (j=0; j < outchan; ++j) {
1615 temp = av_fetch(avmain, j, 0);
1616 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1617 avsub = (AV*)SvRV(*temp);
1618 len = av_len(avsub)+1;
1623 coeff = mymalloc(sizeof(float) * outchan * inchan);
1624 for (j = 0; j < outchan; ++j) {
1625 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1626 len = av_len(avsub)+1;
1627 for (i = 0; i < len; ++i) {
1628 temp = av_fetch(avsub, i, 0);
1630 coeff[i+j*inchan] = SvNV(*temp);
1632 coeff[i+j*inchan] = 0;
1635 coeff[i++ + j*inchan] = 0;
1637 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1647 unsigned int mask = 0;
1653 unsigned char (*maps)[256];
1655 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1656 croak("i_map: parameter 2 must be an arrayref\n");
1657 avmain = (AV*)SvRV(ST(1));
1658 len = av_len(avmain)+1;
1659 if (im->channels < len) len = im->channels;
1661 maps = mymalloc( len * sizeof(unsigned char [256]) );
1663 for (j=0; j<len ; j++) {
1664 temp = av_fetch(avmain, j, 0);
1665 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1666 avsub = (AV*)SvRV(*temp);
1667 if(av_len(avsub) != 255) continue;
1669 for (i=0; i<256 ; i++) {
1671 temp = av_fetch(avsub, i, 0);
1672 val = temp ? SvIV(*temp) : 0;
1674 if (val>255) val = 255;
1679 i_map(im, maps, mask);
1692 i_init_fonts(t1log=0)
1707 i_t1_destroy(font_id)
1712 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1731 str = SvPV(str_sv, len);
1732 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1739 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1748 int cords[BOUNDING_BOX_COUNT];
1756 str = SvPV(str_sv, len);
1757 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1760 for (i = 0; i < rc; ++i)
1761 PUSHs(sv_2mortal(newSViv(cords[i])));
1767 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1786 str = SvPV(str_sv, len);
1787 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1793 i_t1_has_chars(handle, text_sv, utf8 = 0)
1805 if (SvUTF8(text_sv))
1808 text = SvPV(text_sv, len);
1809 work = mymalloc(len);
1810 count = i_t1_has_chars(handle, text, len, utf8, work);
1811 if (GIMME_V == G_ARRAY) {
1813 for (i = 0; i < count; ++i) {
1814 PUSHs(sv_2mortal(newSViv(work[i])));
1819 PUSHs(sv_2mortal(newSVpv(work, count)));
1824 i_t1_face_name(handle)
1830 len = i_t1_face_name(handle, name, sizeof(name));
1833 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1837 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1848 if (SvUTF8(text_sv))
1851 text = SvPV(text_sv, work_len);
1856 ch = i_utf8_advance(&text, &len);
1858 i_push_error(0, "invalid UTF8 character");
1867 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1868 PUSHs(sv_2mortal(newSVpv(name, 0)));
1871 PUSHs(&PL_sv_undef);
1885 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1887 #define TT_DESTROY(handle) i_tt_destroy(handle)
1891 Imager::Font::TT handle
1894 MODULE = Imager PACKAGE = Imager
1898 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1899 Imager::Font::TT handle
1917 str = SvPV(str_sv, len);
1918 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1919 len, smooth, utf8, align);
1925 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1926 Imager::Font::TT handle
1944 str = SvPV(str_sv, len);
1945 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1946 smooth, utf8, align);
1952 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1953 Imager::Font::TT handle
1958 int cords[BOUNDING_BOX_COUNT],rc;
1967 str = SvPV(str_sv, len);
1968 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1970 for (i = 0; i < rc; ++i) {
1971 PUSHs(sv_2mortal(newSViv(cords[i])));
1976 i_tt_has_chars(handle, text_sv, utf8)
1977 Imager::Font::TT handle
1988 if (SvUTF8(text_sv))
1991 text = SvPV(text_sv, len);
1992 work = mymalloc(len);
1993 count = i_tt_has_chars(handle, text, len, utf8, work);
1994 if (GIMME_V == G_ARRAY) {
1996 for (i = 0; i < count; ++i) {
1997 PUSHs(sv_2mortal(newSViv(work[i])));
2002 PUSHs(sv_2mortal(newSVpv(work, count)));
2007 i_tt_dump_names(handle)
2008 Imager::Font::TT handle
2011 i_tt_face_name(handle)
2012 Imager::Font::TT handle
2017 len = i_tt_face_name(handle, name, sizeof(name));
2020 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2024 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2025 Imager::Font::TT handle
2036 if (SvUTF8(text_sv))
2039 text = SvPV(text_sv, work_len);
2044 ch = i_utf8_advance(&text, &len);
2046 i_push_error(0, "invalid UTF8 character");
2055 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2056 PUSHs(sv_2mortal(newSVpv(name, 0)));
2059 PUSHs(&PL_sv_undef);
2068 i_writejpeg_wiol(im, ig, qfactor)
2084 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2085 if (iptc_itext == NULL) {
2088 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2093 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2095 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2106 i_test_format_probe(ig, length)
2115 i_readtiff_wiol(ig, length, page=0)
2121 i_readtiff_multi_wiol(ig, length)
2129 imgs = i_readtiff_multi_wiol(ig, length, &count);
2132 for (i = 0; i < count; ++i) {
2133 SV *sv = sv_newmortal();
2134 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2142 i_writetiff_wiol(im, ig)
2147 i_writetiff_multi_wiol(ig, ...)
2155 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2156 img_count = items - 1;
2158 if (img_count < 1) {
2161 i_push_error(0, "You need to specify images to save");
2164 imgs = mymalloc(sizeof(i_img *) * img_count);
2165 for (i = 0; i < img_count; ++i) {
2168 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2169 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2173 i_push_error(0, "Only images can be saved");
2180 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2188 i_writetiff_wiol_faxable(im, ig, fine)
2194 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2203 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2204 img_count = items - 2;
2206 if (img_count < 1) {
2209 i_push_error(0, "You need to specify images to save");
2212 imgs = mymalloc(sizeof(i_img *) * img_count);
2213 for (i = 0; i < img_count; ++i) {
2216 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2217 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2221 i_push_error(0, "Only images can be saved");
2228 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2236 #endif /* HAVE_LIBTIFF */
2242 i_readpng_wiol(ig, length)
2248 i_writepng_wiol(im, ig)
2261 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2264 i_writegif(im,fd,colors,pixdev,fixed)
2271 Imager__Color fixed;
2278 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2279 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2280 av=(AV*)SvRV(ST(4));
2281 fixedlen=av_len(av)+1;
2282 fixed=mymalloc( fixedlen*sizeof(i_color) );
2283 for(i=0;i<fixedlen;i++) {
2284 sv1=(*(av_fetch(av,i,0)));
2285 if (sv_derived_from(sv1, "Imager::Color")) {
2286 Itmp = SvIV((SV*)SvRV(sv1));
2287 tmp = INT2PTR(i_color*, Itmp);
2288 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2291 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2293 ST(0) = sv_newmortal();
2294 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2295 else sv_setiv(ST(0), (IV)RETVAL);
2301 i_writegifmc(im,fd,colors)
2308 i_writegif_gen(fd, ...)
2313 i_img **imgs = NULL;
2319 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2320 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2321 croak("i_writegif_gen: Second argument must be a hash ref");
2322 hv = (HV *)SvRV(ST(1));
2323 memset(&quant, 0, sizeof(quant));
2324 quant.mc_size = 256;
2325 handle_quant_opts(&quant, hv);
2326 img_count = items - 2;
2328 if (img_count < 1) {
2331 i_push_error(0, "You need to specify images to save");
2334 imgs = mymalloc(sizeof(i_img *) * img_count);
2335 for (i = 0; i < img_count; ++i) {
2338 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2339 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2343 i_push_error(0, "Only images can be saved");
2349 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2353 copy_colors_back(hv, &quant);
2356 ST(0) = sv_newmortal();
2357 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2358 else sv_setiv(ST(0), (IV)RETVAL);
2359 cleanup_quant_opts(&quant);
2363 i_writegif_callback(cb, maxbuffer,...)
2367 i_img **imgs = NULL;
2374 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2375 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2376 croak("i_writegif_callback: Second argument must be a hash ref");
2377 hv = (HV *)SvRV(ST(2));
2378 memset(&quant, 0, sizeof(quant));
2379 quant.mc_size = 256;
2380 handle_quant_opts(&quant, hv);
2381 img_count = items - 3;
2383 if (img_count < 1) {
2387 imgs = mymalloc(sizeof(i_img *) * img_count);
2388 for (i = 0; i < img_count; ++i) {
2391 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2392 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2401 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2405 copy_colors_back(hv, &quant);
2408 ST(0) = sv_newmortal();
2409 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2410 else sv_setiv(ST(0), (IV)RETVAL);
2411 cleanup_quant_opts(&quant);
2414 i_writegif_wiol(ig, opts,...)
2418 i_img **imgs = NULL;
2424 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2425 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2426 croak("i_writegif_callback: Second argument must be a hash ref");
2427 hv = (HV *)SvRV(ST(1));
2428 memset(&quant, 0, sizeof(quant));
2429 quant.mc_size = 256;
2430 handle_quant_opts(&quant, hv);
2431 img_count = items - 2;
2433 if (img_count < 1) {
2437 imgs = mymalloc(sizeof(i_img *) * img_count);
2438 for (i = 0; i < img_count; ++i) {
2441 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2442 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2450 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2454 copy_colors_back(hv, &quant);
2457 ST(0) = sv_newmortal();
2458 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2459 else sv_setiv(ST(0), (IV)RETVAL);
2460 cleanup_quant_opts(&quant);
2473 colour_table = NULL;
2476 if(GIMME_V == G_ARRAY) {
2477 rimg = i_readgif(fd,&colour_table,&colours);
2479 /* don't waste time with colours if they aren't wanted */
2480 rimg = i_readgif(fd,NULL,NULL);
2483 if (colour_table == NULL) {
2486 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2489 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2490 /* I don't know if I have the reference counts right or not :( */
2491 /* Neither do I :-) */
2492 /* No Idea here either */
2495 av_extend(ct, colours);
2496 for(q=0; q<colours; q++) {
2498 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2499 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2501 myfree(colour_table);
2505 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2507 PUSHs(newRV_noinc((SV*)ct));
2521 colour_table = NULL;
2524 if(GIMME_V == G_ARRAY) {
2525 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2527 /* don't waste time with colours if they aren't wanted */
2528 rimg = i_readgif_wiol(ig,NULL,NULL);
2531 if (colour_table == NULL) {
2534 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2537 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2538 /* I don't know if I have the reference counts right or not :( */
2539 /* Neither do I :-) */
2540 /* No Idea here either */
2543 av_extend(ct, colours);
2544 for(q=0; q<colours; q++) {
2546 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2547 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2549 myfree(colour_table);
2553 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2555 PUSHs(newRV_noinc((SV*)ct));
2559 i_readgif_single_wiol(ig, page=0)
2564 i_readgif_scalar(...)
2576 data = (char *)SvPV(ST(0), length);
2580 if(GIMME_V == G_ARRAY) {
2581 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2583 /* don't waste time with colours if they aren't wanted */
2584 rimg=i_readgif_scalar(data,length,NULL,NULL);
2587 if (colour_table == NULL) {
2590 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2593 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2594 /* I don't know if I have the reference counts right or not :( */
2595 /* Neither do I :-) */
2597 av_extend(ct, colours);
2598 for(q=0; q<colours; q++) {
2600 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2601 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2603 myfree(colour_table);
2607 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2609 PUSHs(newRV_noinc((SV*)ct));
2613 i_readgif_callback(...)
2628 if(GIMME_V == G_ARRAY) {
2629 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2631 /* don't waste time with colours if they aren't wanted */
2632 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2635 if (colour_table == NULL) {
2638 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2641 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2642 /* I don't know if I have the reference counts right or not :( */
2643 /* Neither do I :-) */
2644 /* Neither do I - maybe I'll move this somewhere */
2646 av_extend(ct, colours);
2647 for(q=0; q<colours; q++) {
2649 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2650 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2652 myfree(colour_table);
2656 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2658 PUSHs(newRV_noinc((SV*)ct));
2669 imgs = i_readgif_multi(fd, &count);
2672 for (i = 0; i < count; ++i) {
2673 SV *sv = sv_newmortal();
2674 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2681 i_readgif_multi_scalar(data)
2689 data = (char *)SvPV(ST(0), length);
2690 imgs = i_readgif_multi_scalar(data, length, &count);
2693 for (i = 0; i < count; ++i) {
2694 SV *sv = sv_newmortal();
2695 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2702 i_readgif_multi_callback(cb)
2710 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2713 for (i = 0; i < count; ++i) {
2714 SV *sv = sv_newmortal();
2715 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2722 i_readgif_multi_wiol(ig)
2729 imgs = i_readgif_multi_wiol(ig, &count);
2732 for (i = 0; i < count; ++i) {
2733 SV *sv = sv_newmortal();
2734 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2746 i_readpnm_wiol(ig, length)
2752 i_writeppm_wiol(im, ig)
2758 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2767 i_writeraw_wiol(im,ig)
2772 i_writebmp_wiol(im,ig)
2782 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2791 idlen = SvCUR(ST(4));
2792 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2798 i_readtga_wiol(ig, length)
2804 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2813 idlen = SvCUR(ST(4));
2814 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2820 i_readrgb_wiol(ig, length)
2827 i_scaleaxis(im,Value,Axis)
2833 i_scale_nn(im,scx,scy)
2843 i_count_colors(im,maxc)
2849 i_transform(im,opx,opy,parm)
2862 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2863 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2864 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2865 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2866 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2867 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2868 av=(AV*)SvRV(ST(1));
2870 opx=mymalloc( opxl*sizeof(int) );
2871 for(i=0;i<opxl;i++) {
2872 sv1=(*(av_fetch(av,i,0)));
2873 opx[i]=(int)SvIV(sv1);
2875 av=(AV*)SvRV(ST(2));
2877 opy=mymalloc( opyl*sizeof(int) );
2878 for(i=0;i<opyl;i++) {
2879 sv1=(*(av_fetch(av,i,0)));
2880 opy[i]=(int)SvIV(sv1);
2882 av=(AV*)SvRV(ST(3));
2883 parmlen=av_len(av)+1;
2884 parm=mymalloc( parmlen*sizeof(double) );
2885 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2886 sv1=(*(av_fetch(av,i,0)));
2887 parm[i]=(double)SvNV(sv1);
2889 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2893 ST(0) = sv_newmortal();
2894 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2895 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2898 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2923 in_imgs_count = av_len(av_in_imgs)+1;
2924 for (i = 0; i < in_imgs_count; ++i) {
2925 sv1 = *av_fetch(av_in_imgs, i, 0);
2926 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2927 croak("sv_in_img must contain only images");
2930 if (in_imgs_count > 0) {
2931 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2932 for (i = 0; i < in_imgs_count; ++i) {
2933 sv1 = *av_fetch(av_in_imgs,i,0);
2934 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2935 croak("Parameter 5 must contain only images");
2937 tmp = SvIV((SV*)SvRV(sv1));
2938 in_imgs[i] = INT2PTR(i_img*, tmp);
2942 /* no input images */
2945 /* default the output size from the first input if possible */
2947 width = SvIV(sv_width);
2948 else if (in_imgs_count)
2949 width = in_imgs[0]->xsize;
2951 croak("No output image width supplied");
2953 if (SvOK(sv_height))
2954 height = SvIV(sv_height);
2955 else if (in_imgs_count)
2956 height = in_imgs[0]->ysize;
2958 croak("No output image height supplied");
2960 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2961 if (ops_len % sizeof(struct rm_op))
2962 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2963 ops_count = ops_len / sizeof(struct rm_op);
2965 n_regs_count = av_len(av_n_regs)+1;
2966 n_regs = mymalloc(n_regs_count * sizeof(double));
2967 for (i = 0; i < n_regs_count; ++i) {
2968 sv1 = *av_fetch(av_n_regs,i,0);
2970 n_regs[i] = SvNV(sv1);
2972 c_regs_count = av_len(av_c_regs)+1;
2973 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2974 /* I don't bother initializing the colou?r registers */
2976 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2977 n_regs, n_regs_count,
2978 c_regs, c_regs_count, in_imgs, in_imgs_count);
2983 ST(0) = sv_newmortal();
2984 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2985 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2989 i_contrast(im,intensity)
2998 i_noise(im,amount,type)
3004 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3014 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3033 i_postlevels(im,levels)
3043 i_watermark(im,wmark,tx,ty,pixdiff)
3045 Imager::ImgRaw wmark
3052 i_autolevels(im,lsat,usat,skew)
3059 i_radnoise(im,xo,yo,rscale,ascale)
3067 i_turbnoise(im, xo, yo, scale)
3090 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3091 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3092 croak("i_gradgen: Second argument must be an array ref");
3093 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3094 croak("i_gradgen: Third argument must be an array ref");
3095 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3096 croak("i_gradgen: Fourth argument must be an array ref");
3097 axx = (AV *)SvRV(ST(1));
3098 ayy = (AV *)SvRV(ST(2));
3099 ac = (AV *)SvRV(ST(3));
3100 dmeasure = (int)SvIV(ST(4));
3102 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3103 num = num <= av_len(ac) ? num : av_len(ac);
3105 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3106 xo = mymalloc( sizeof(int) * num );
3107 yo = mymalloc( sizeof(int) * num );
3108 ival = mymalloc( sizeof(i_color) * num );
3109 for(i = 0; i<num; i++) {
3110 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3111 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3112 sv = *av_fetch(ac, i, 0);
3113 if ( !sv_derived_from(sv, "Imager::Color") ) {
3114 free(axx); free(ayy); free(ac);
3115 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3117 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3119 i_gradgen(im, num, xo, yo, ival, dmeasure);
3125 i_diff_image(im, im2, mindist=0)
3131 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3141 double ssample_param
3145 i_fountain_seg *segs;
3147 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3148 croak("i_fountain: argument 11 must be an array ref");
3150 asegs = (AV *)SvRV(ST(10));
3151 segs = load_fount_segs(asegs, &count);
3152 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3153 super_sample, ssample_param, count, segs);
3159 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3168 double ssample_param
3172 i_fountain_seg *segs;
3174 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3175 croak("i_fountain: argument 11 must be an array ref");
3177 asegs = (AV *)SvRV(ST(9));
3178 segs = load_fount_segs(asegs, &count);
3179 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3180 super_sample, ssample_param, count, segs);
3193 errors = i_errors();
3195 while (errors[i].msg) {
3197 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3198 if (!av_store(av, 0, sv)) {
3201 sv = newSViv(errors[i].code);
3202 if (!av_store(av, 1, sv)) {
3205 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3210 i_nearest_color(im, ...)
3225 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3226 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3227 croak("i_nearest_color: Second argument must be an array ref");
3228 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3229 croak("i_nearest_color: Third argument must be an array ref");
3230 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3231 croak("i_nearest_color: Fourth argument must be an array ref");
3232 axx = (AV *)SvRV(ST(1));
3233 ayy = (AV *)SvRV(ST(2));
3234 ac = (AV *)SvRV(ST(3));
3235 dmeasure = (int)SvIV(ST(4));
3237 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3238 num = num <= av_len(ac) ? num : av_len(ac);
3240 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3241 xo = mymalloc( sizeof(int) * num );
3242 yo = mymalloc( sizeof(int) * num );
3243 ival = mymalloc( sizeof(i_color) * num );
3244 for(i = 0; i<num; i++) {
3245 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3246 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3247 sv = *av_fetch(ac, i, 0);
3248 if ( !sv_derived_from(sv, "Imager::Color") ) {
3249 free(axx); free(ayy); free(ac);
3250 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3252 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3254 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3268 rc=DSO_open(filename,&evstr);
3272 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3273 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3276 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3282 DSO_close(dso_handle)
3286 DSO_funclist(dso_handle_v)
3290 DSO_handle *dso_handle;
3292 dso_handle=(DSO_handle*)dso_handle_v;
3294 while( dso_handle->function_list[i].name != NULL) {
3296 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3298 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3303 DSO_call(handle,func_index,hv)
3309 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3310 hv=(HV*)SvRV(ST(2));
3311 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3312 DSO_call( (DSO_handle *)handle,func_index,hv);
3317 i_get_pixel(im, x, y)
3324 color = (i_color *)mymalloc(sizeof(i_color));
3325 if (i_gpix(im, x, y, color) == 0) {
3326 RETVAL = NEWSV(0, 0);
3327 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3331 RETVAL = &PL_sv_undef;
3338 i_ppix(im, x, y, cl)
3345 i_img_pal_new(x, y, channels, maxpal)
3352 i_img_to_pal(src, quant)
3358 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3359 croak("i_img_to_pal: second argument must be a hash ref");
3360 hv = (HV *)SvRV(ST(1));
3361 memset(&quant, 0, sizeof(quant));
3362 quant.mc_size = 256;
3363 handle_quant_opts(&quant, hv);
3364 RETVAL = i_img_to_pal(src, &quant);
3366 copy_colors_back(hv, &quant);
3368 cleanup_quant_opts(&quant);
3387 work = mymalloc((r-l) * sizeof(i_palidx));
3388 count = i_gpal(im, l, r, y, work);
3389 if (GIMME_V == G_ARRAY) {
3391 for (i = 0; i < count; ++i) {
3392 PUSHs(sv_2mortal(newSViv(work[i])));
3397 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3402 if (GIMME_V != G_ARRAY) {
3404 PUSHs(&PL_sv_undef);
3409 i_ppal(im, l, y, ...)
3418 work = mymalloc(sizeof(i_palidx) * (items-3));
3419 for (i=0; i < items-3; ++i) {
3420 work[i] = SvIV(ST(i+3));
3422 RETVAL = i_ppal(im, l, l+items-3, y, work);
3432 i_addcolors(im, ...)
3440 croak("i_addcolors: no colors to add");
3441 colors = mymalloc((items-1) * sizeof(i_color));
3442 for (i=0; i < items-1; ++i) {
3443 if (sv_isobject(ST(i+1))
3444 && sv_derived_from(ST(i+1), "Imager::Color")) {
3445 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3446 colors[i] = *INT2PTR(i_color *, tmp);
3450 croak("i_addcolor: pixels must be Imager::Color objects");
3453 index = i_addcolors(im, colors, items-1);
3456 RETVAL = newSVpv("0 but true", 0);
3458 else if (index == -1) {
3459 RETVAL = &PL_sv_undef;
3462 RETVAL = newSViv(index);
3468 i_setcolors(im, index, ...)
3476 croak("i_setcolors: no colors to add");
3477 colors = mymalloc((items-2) * sizeof(i_color));
3478 for (i=0; i < items-2; ++i) {
3479 if (sv_isobject(ST(i+2))
3480 && sv_derived_from(ST(i+2), "Imager::Color")) {
3481 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3482 colors[i] = *INT2PTR(i_color *, tmp);
3486 croak("i_setcolors: pixels must be Imager::Color objects");
3489 RETVAL = i_setcolors(im, index, colors, items-2);
3495 i_getcolors(im, index, ...)
3504 croak("i_getcolors: too many arguments");
3506 count = SvIV(ST(2));
3508 croak("i_getcolors: count must be positive");
3509 colors = mymalloc(sizeof(i_color) * count);
3510 if (i_getcolors(im, index, colors, count)) {
3511 for (i = 0; i < count; ++i) {
3513 SV *sv = sv_newmortal();
3514 pv = mymalloc(sizeof(i_color));
3516 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3532 i_findcolor(im, color)
3538 if (i_findcolor(im, color, &index)) {
3539 RETVAL = newSViv(index);
3542 RETVAL = &PL_sv_undef;
3560 i_gsamp(im, l, r, y, ...)
3572 croak("No channel numbers supplied to g_samp()");
3574 chan_count = items - 4;
3575 chans = mymalloc(sizeof(int) * chan_count);
3576 for (i = 0; i < chan_count; ++i)
3577 chans[i] = SvIV(ST(i+4));
3578 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3579 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3581 if (GIMME_V == G_ARRAY) {
3583 for (i = 0; i < count; ++i)
3584 PUSHs(sv_2mortal(newSViv(data[i])));
3588 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3593 if (GIMME_V != G_ARRAY) {
3595 PUSHs(&PL_sv_undef);
3601 i_img_masked_new(targ, mask, x, y, w, h)
3611 if (!sv_isobject(ST(1))
3612 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3613 croak("i_img_masked_new: parameter 2 must undef or an image");
3615 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3619 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3624 i_plin(im, l, y, ...)
3635 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3636 /* supplied as a byte string */
3637 work = (i_color *)SvPV(ST(3), len);
3638 count = len / sizeof(i_color);
3639 if (count * sizeof(i_color) != len) {
3640 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3642 RETVAL = i_plin(im, l, l+count, y, work);
3645 work = mymalloc(sizeof(i_color) * (items-3));
3646 for (i=0; i < items-3; ++i) {
3647 if (sv_isobject(ST(i+3))
3648 && sv_derived_from(ST(i+3), "Imager::Color")) {
3649 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3650 work[i] = *INT2PTR(i_color *, tmp);
3654 croak("i_plin: pixels must be Imager::Color objects");
3657 RETVAL = i_plin(im, l, l+items-3, y, work);
3668 i_ppixf(im, x, y, cl)
3672 Imager::Color::Float cl
3675 i_gsampf(im, l, r, y, ...)
3687 croak("No channel numbers supplied to g_sampf()");
3689 chan_count = items - 4;
3690 chans = mymalloc(sizeof(int) * chan_count);
3691 for (i = 0; i < chan_count; ++i)
3692 chans[i] = SvIV(ST(i+4));
3693 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3694 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3696 if (GIMME_V == G_ARRAY) {
3698 for (i = 0; i < count; ++i)
3699 PUSHs(sv_2mortal(newSVnv(data[i])));
3703 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3708 if (GIMME_V != G_ARRAY) {
3710 PUSHs(&PL_sv_undef);
3715 i_plinf(im, l, y, ...)
3726 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3727 /* supplied as a byte string */
3728 work = (i_fcolor *)SvPV(ST(3), len);
3729 count = len / sizeof(i_fcolor);
3730 if (count * sizeof(i_fcolor) != len) {
3731 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3733 RETVAL = i_plinf(im, l, l+count, y, work);
3736 work = mymalloc(sizeof(i_fcolor) * (items-3));
3737 for (i=0; i < items-3; ++i) {
3738 if (sv_isobject(ST(i+3))
3739 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3740 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3741 work[i] = *INT2PTR(i_fcolor *, tmp);
3745 croak("i_plinf: pixels must be Imager::Color::Float objects");
3749 RETVAL = i_plinf(im, l, l+items-3, y, work);
3767 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3768 if (i_gpixf(im, x, y, color) == 0) {
3769 RETVAL = NEWSV(0,0);
3770 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3774 RETVAL = &PL_sv_undef;
3790 vals = mymalloc((r-l) * sizeof(i_color));
3791 count = i_glin(im, l, r, y, vals);
3792 if (GIMME_V == G_ARRAY) {
3794 for (i = 0; i < count; ++i) {
3796 i_color *col = mymalloc(sizeof(i_color));
3798 sv = sv_newmortal();
3799 sv_setref_pv(sv, "Imager::Color", (void *)col);
3805 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3811 i_glinf(im, l, r, y)
3821 vals = mymalloc((r-l) * sizeof(i_fcolor));
3822 count = i_glinf(im, l, r, y, vals);
3823 if (GIMME_V == G_ARRAY) {
3825 for (i = 0; i < count; ++i) {
3827 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3829 sv = sv_newmortal();
3830 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3836 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3842 i_img_16_new(x, y, ch)
3848 i_img_double_new(x, y, ch)
3854 i_tags_addn(im, name, code, idata)
3863 name = SvPV(ST(1), len);
3866 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3871 i_tags_add(im, name, code, data, idata)
3881 name = SvPV(ST(1), len);
3885 data = SvPV(ST(3), len);
3890 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3895 i_tags_find(im, name, start)
3902 if (i_tags_find(&im->tags, name, start, &entry)) {
3904 RETVAL = newSVpv("0 but true", 0);
3906 RETVAL = newSViv(entry);
3908 RETVAL = &PL_sv_undef;
3914 i_tags_findn(im, code, start)
3921 if (i_tags_findn(&im->tags, code, start, &entry)) {
3923 RETVAL = newSVpv("0 but true", 0);
3925 RETVAL = newSViv(entry);
3928 RETVAL = &PL_sv_undef;
3934 i_tags_delete(im, entry)
3938 RETVAL = i_tags_delete(&im->tags, entry);
3943 i_tags_delbyname(im, name)
3947 RETVAL = i_tags_delbyname(&im->tags, name);
3952 i_tags_delbycode(im, code)
3956 RETVAL = i_tags_delbycode(&im->tags, code);
3961 i_tags_get(im, index)
3965 if (index >= 0 && index < im->tags.count) {
3966 i_img_tag *entry = im->tags.tags + index;
3970 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3973 PUSHs(sv_2mortal(newSViv(entry->code)));
3976 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3979 PUSHs(sv_2mortal(newSViv(entry->idata)));
3984 i_tags_get_string(im, what_sv)
3988 char const *name = NULL;
3992 if (SvIOK(what_sv)) {
3993 code = SvIV(what_sv);
3997 name = SvPV_nolen(what_sv);
4000 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4002 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4009 RETVAL = im->tags.count;
4016 i_wf_bbox(face, size, text)
4021 int cords[BOUNDING_BOX_COUNT];
4024 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4026 for (i = 0; i < rc; ++i)
4027 PUSHs(sv_2mortal(newSViv(cords[i])));
4031 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4042 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4048 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4059 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4072 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4074 #define FT2_DESTROY(font) i_ft2_destroy(font)
4078 Imager::Font::FT2 font
4080 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4083 i_ft2_new(name, index)
4088 i_ft2_setdpi(font, xdpi, ydpi)
4089 Imager::Font::FT2 font
4095 Imager::Font::FT2 font
4099 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4101 PUSHs(sv_2mortal(newSViv(xdpi)));
4102 PUSHs(sv_2mortal(newSViv(ydpi)));
4106 i_ft2_sethinting(font, hinting)
4107 Imager::Font::FT2 font
4111 i_ft2_settransform(font, matrix)
4112 Imager::Font::FT2 font
4120 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4121 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4122 av=(AV*)SvRV(ST(1));
4126 for (i = 0; i < len; ++i) {
4127 sv1=(*(av_fetch(av,i,0)));
4128 matrix[i] = SvNV(sv1);
4132 RETVAL = i_ft2_settransform(font, matrix);
4137 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4138 Imager::Font::FT2 font
4144 int bbox[BOUNDING_BOX_COUNT];
4150 text = SvPV(text_sv, text_len);
4152 if (SvUTF8(text_sv))
4155 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4158 for (i = 0; i < rc; ++i)
4159 PUSHs(sv_2mortal(newSViv(bbox[i])));
4163 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4164 Imager::Font::FT2 font
4178 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4181 for (i = 0; i < 8; ++i)
4182 PUSHs(sv_2mortal(newSViv(bbox[i])));
4186 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4187 Imager::Font::FT2 font
4203 if (SvUTF8(ST(7))) {
4207 text = SvPV(ST(7), len);
4208 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4209 len, align, aa, vlayout, utf8);
4214 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4215 Imager::Font::FT2 font
4232 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4233 strlen(text), align, aa, vlayout, 1);
4238 ft2_transform_box(font, x0, x1, x2, x3)
4239 Imager::Font::FT2 font
4247 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4248 ft2_transform_box(font, box);
4250 PUSHs(sv_2mortal(newSViv(box[0])));
4251 PUSHs(sv_2mortal(newSViv(box[1])));
4252 PUSHs(sv_2mortal(newSViv(box[2])));
4253 PUSHs(sv_2mortal(newSViv(box[3])));
4256 i_ft2_has_chars(handle, text_sv, utf8)
4257 Imager::Font::FT2 handle
4268 if (SvUTF8(text_sv))
4271 text = SvPV(text_sv, len);
4272 work = mymalloc(len);
4273 count = i_ft2_has_chars(handle, text, len, utf8, work);
4274 if (GIMME_V == G_ARRAY) {
4276 for (i = 0; i < count; ++i) {
4277 PUSHs(sv_2mortal(newSViv(work[i])));
4282 PUSHs(sv_2mortal(newSVpv(work, count)));
4287 i_ft2_face_name(handle)
4288 Imager::Font::FT2 handle
4293 len = i_ft2_face_name(handle, name, sizeof(name));
4296 PUSHs(sv_2mortal(newSVpv(name, 0)));
4300 i_ft2_can_face_name()
4303 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4304 Imager::Font::FT2 handle
4315 if (SvUTF8(text_sv))
4318 text = SvPV(text_sv, work_len);
4323 ch = i_utf8_advance(&text, &len);
4325 i_push_error(0, "invalid UTF8 character");
4334 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4336 PUSHs(sv_2mortal(newSVpv(name, 0)));
4339 PUSHs(&PL_sv_undef);
4344 i_ft2_can_do_glyph_names()
4347 i_ft2_face_has_glyph_names(handle)
4348 Imager::Font::FT2 handle
4351 i_ft2_is_multiple_master(handle)
4352 Imager::Font::FT2 handle
4355 i_ft2_get_multiple_masters(handle)
4356 Imager::Font::FT2 handle
4361 if (i_ft2_get_multiple_masters(handle, &mm)) {
4362 EXTEND(SP, 2+mm.num_axis);
4363 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4364 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4365 for (i = 0; i < mm.num_axis; ++i) {
4369 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4371 av_store(av, 0, sv);
4372 sv = newSViv(mm.axis[i].minimum);
4374 av_store(av, 1, sv);
4375 sv = newSViv(mm.axis[i].maximum);
4377 av_store(av, 2, sv);
4378 PUSHs(newRV_noinc((SV *)av));
4383 i_ft2_set_mm_coords(handle, ...)
4384 Imager::Font::FT2 handle
4390 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4391 transfer the array manually */
4392 ix_coords = items-1;
4393 coords = mymalloc(sizeof(long) * ix_coords);
4394 for (i = 0; i < ix_coords; ++i) {
4395 coords[i] = (long)SvIV(ST(1+i));
4397 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4404 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4408 Imager::FillHandle fill
4410 MODULE = Imager PACKAGE = Imager
4413 i_new_fill_solid(cl, combine)
4418 i_new_fill_solidf(cl, combine)
4419 Imager::Color::Float cl
4423 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4431 unsigned char *cust_hatch;
4435 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4439 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4444 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4445 Imager::Color::Float fg
4446 Imager::Color::Float bg
4452 unsigned char *cust_hatch;
4456 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4460 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4465 i_new_fill_image(src, matrix, xoff, yoff, combine)
4482 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4483 croak("i_new_fill_image: parameter must be an arrayref");
4484 av=(AV*)SvRV(ST(1));
4488 for (i = 0; i < len; ++i) {
4489 sv1=(*(av_fetch(av,i,0)));
4490 matrix[i] = SvNV(sv1);
4496 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4500 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4502 # this class is only exposed for testing
4505 i_int_hlines_testing()
4507 #if i_int_hlines_testing()
4509 Imager::Internal::Hlines
4510 i_int_hlines_new(start_y, count_y, start_x, count_x)
4516 Imager::Internal::Hlines
4517 i_int_hlines_new_img(im)
4521 i_int_hlines_add(hlines, y, minx, width)
4522 Imager::Internal::Hlines hlines
4528 i_int_hlines_DESTROY(hlines)
4529 Imager::Internal::Hlines hlines
4532 i_int_hlines_dump(hlines)
4533 Imager::Internal::Hlines hlines
4538 PERL_SET_GLOBAL_CALLBACKS;