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 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 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
885 ICL_new_internal(r,g,b,a)
897 ICL_set_internal(cl,r,g,b,a)
904 ICL_set_internal(cl, r, g, b, a);
918 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
919 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
920 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
921 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
927 RETVAL = mymalloc(sizeof(i_color));
929 i_hsv_to_rgb(RETVAL);
937 RETVAL = mymalloc(sizeof(i_color));
939 i_rgb_to_hsv(RETVAL);
945 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
948 ICLF_new_internal(r, g, b, a)
956 Imager::Color::Float cl
960 Imager::Color::Float cl
964 EXTEND(SP, MAXCHANNELS);
965 for (ch = 0; ch < MAXCHANNELS; ++ch) {
966 /* printf("%d: %g\n", ch, cl->channel[ch]); */
967 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
971 ICLF_set_internal(cl,r,g,b,a)
972 Imager::Color::Float cl
987 Imager::Color::Float c
989 RETVAL = mymalloc(sizeof(i_fcolor));
991 i_hsv_to_rgbf(RETVAL);
997 Imager::Color::Float c
999 RETVAL = mymalloc(sizeof(i_fcolor));
1001 i_rgb_to_hsvf(RETVAL);
1005 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1019 MODULE = Imager PACKAGE = Imager
1038 SvPV(ST(0), length);
1039 SvREFCNT_inc(ST(0));
1040 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1045 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1054 cbd = mymalloc(sizeof(struct cbdata));
1055 SvREFCNT_inc(writecb);
1056 cbd->writecb = writecb;
1057 SvREFCNT_inc(readcb);
1058 cbd->readcb = readcb;
1059 SvREFCNT_inc(seekcb);
1060 cbd->seekcb = seekcb;
1061 SvREFCNT_inc(closecb);
1062 cbd->closecb = closecb;
1063 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1064 if (maxwrite > CBDATA_BUFSIZE)
1065 maxwrite = CBDATA_BUFSIZE;
1066 cbd->maxlength = maxwrite;
1067 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1076 unsigned char* data;
1080 tlength = io_slurp(ig, &data);
1082 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1087 i_set_image_file_limits(width, height, bytes)
1093 i_get_image_file_limits()
1095 int width, height, bytes;
1097 if (i_get_image_file_limits(&width, &height, &bytes)) {
1099 PUSHs(sv_2mortal(newSViv(width)));
1100 PUSHs(sv_2mortal(newSViv(height)));
1101 PUSHs(sv_2mortal(newSViv(bytes)));
1104 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1111 MODULE = Imager PACKAGE = Imager
1124 while( (item=i_format_list[i++]) != NULL ) {
1126 PUSHs(sv_2mortal(newSVpv(item,0)));
1143 i_img_empty_ch(im,x,y,ch)
1150 i_sametype(im, x, y)
1156 i_sametype_chans(im, x, y, channels)
1163 m_init_log(name,level)
1168 log_entry(string,level)
1187 i_img_info(im,info);
1189 PUSHs(sv_2mortal(newSViv(info[0])));
1190 PUSHs(sv_2mortal(newSViv(info[1])));
1191 PUSHs(sv_2mortal(newSViv(info[2])));
1192 PUSHs(sv_2mortal(newSViv(info[3])));
1198 i_img_setmask(im,ch_mask)
1207 i_img_getchannels(im)
1216 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1221 i_line(im,x1,y1,x2,y2,val,endp)
1231 i_line_aa(im,x1,y1,x2,y2,val,endp)
1241 i_box(im,x1,y1,x2,y2,val)
1250 i_box_filled(im,x1,y1,x2,y2,val)
1259 i_box_cfill(im,x1,y1,x2,y2,fill)
1265 Imager::FillHandle fill
1268 i_arc(im,x,y,rad,d1,d2,val)
1278 i_arc_aa(im,x,y,rad,d1,d2,val)
1288 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1295 Imager::FillHandle fill
1298 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1305 Imager::FillHandle fill
1309 i_circle_aa(im,x,y,rad,val)
1319 i_bezier_multi(im,xc,yc,val)
1332 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1333 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1334 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1335 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1336 av1=(AV*)SvRV(ST(1));
1337 av2=(AV*)SvRV(ST(2));
1338 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1340 x=mymalloc( len*sizeof(double) );
1341 y=mymalloc( len*sizeof(double) );
1342 for(i=0;i<len;i++) {
1343 sv1=(*(av_fetch(av1,i,0)));
1344 sv2=(*(av_fetch(av2,i,0)));
1345 x[i]=(double)SvNV(sv1);
1346 y[i]=(double)SvNV(sv2);
1348 i_bezier_multi(im,len,x,y,val);
1354 i_poly_aa(im,xc,yc,val)
1367 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1368 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1369 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1370 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1371 av1=(AV*)SvRV(ST(1));
1372 av2=(AV*)SvRV(ST(2));
1373 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1375 x=mymalloc( len*sizeof(double) );
1376 y=mymalloc( len*sizeof(double) );
1377 for(i=0;i<len;i++) {
1378 sv1=(*(av_fetch(av1,i,0)));
1379 sv2=(*(av_fetch(av2,i,0)));
1380 x[i]=(double)SvNV(sv1);
1381 y[i]=(double)SvNV(sv2);
1383 i_poly_aa(im,len,x,y,val);
1388 i_poly_aa_cfill(im,xc,yc,fill)
1390 Imager::FillHandle fill
1400 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1401 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1402 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1403 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1404 av1=(AV*)SvRV(ST(1));
1405 av2=(AV*)SvRV(ST(2));
1406 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1408 x=mymalloc( len*sizeof(double) );
1409 y=mymalloc( len*sizeof(double) );
1410 for(i=0;i<len;i++) {
1411 sv1=(*(av_fetch(av1,i,0)));
1412 sv2=(*(av_fetch(av2,i,0)));
1413 x[i]=(double)SvNV(sv1);
1414 y[i]=(double)SvNV(sv2);
1416 i_poly_aa_cfill(im,len,x,y,fill);
1423 i_flood_fill(im,seedx,seedy,dcol)
1430 i_flood_cfill(im,seedx,seedy,fill)
1434 Imager::FillHandle fill
1438 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1450 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1467 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1479 i_flipxy(im, direction)
1484 i_rotate90(im, degrees)
1489 i_rotate_exact(im, amount, ...)
1493 i_color *backp = NULL;
1494 i_fcolor *fbackp = NULL;
1498 /* extract the bg colors if any */
1499 /* yes, this is kind of strange */
1500 for (i = 2; i < items; ++i) {
1502 if (sv_derived_from(sv1, "Imager::Color")) {
1503 IV tmp = SvIV((SV*)SvRV(sv1));
1504 backp = INT2PTR(i_color *, tmp);
1506 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1507 IV tmp = SvIV((SV*)SvRV(sv1));
1508 fbackp = INT2PTR(i_fcolor *, tmp);
1511 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1516 i_matrix_transform(im, xsize, ysize, matrix, ...)
1526 i_color *backp = NULL;
1527 i_fcolor *fbackp = NULL;
1529 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1530 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1531 av=(AV*)SvRV(ST(3));
1535 for (i = 0; i < len; ++i) {
1536 sv1=(*(av_fetch(av,i,0)));
1537 matrix[i] = SvNV(sv1);
1541 /* extract the bg colors if any */
1542 /* yes, this is kind of strange */
1543 for (i = 4; i < items; ++i) {
1545 if (sv_derived_from(sv1, "Imager::Color")) {
1546 IV tmp = SvIV((SV*)SvRV(sv1));
1547 backp = INT2PTR(i_color *, tmp);
1549 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1550 IV tmp = SvIV((SV*)SvRV(sv1));
1551 fbackp = INT2PTR(i_fcolor *, tmp);
1554 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1559 i_gaussian(im,stdev)
1564 i_unsharp_mask(im,stdev,scale)
1579 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1580 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1581 av=(AV*)SvRV(ST(1));
1583 coeff=mymalloc( len*sizeof(float) );
1584 for(i=0;i<len;i++) {
1585 sv1=(*(av_fetch(av,i,0)));
1586 coeff[i]=(float)SvNV(sv1);
1588 i_conv(im,coeff,len);
1592 i_convert(im, src, coeff)
1605 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1606 croak("i_convert: parameter 3 must be an arrayref\n");
1607 avmain = (AV*)SvRV(ST(2));
1608 outchan = av_len(avmain)+1;
1609 /* find the biggest */
1611 for (j=0; j < outchan; ++j) {
1612 temp = av_fetch(avmain, j, 0);
1613 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1614 avsub = (AV*)SvRV(*temp);
1615 len = av_len(avsub)+1;
1620 coeff = mymalloc(sizeof(float) * outchan * inchan);
1621 for (j = 0; j < outchan; ++j) {
1622 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1623 len = av_len(avsub)+1;
1624 for (i = 0; i < len; ++i) {
1625 temp = av_fetch(avsub, i, 0);
1627 coeff[i+j*inchan] = SvNV(*temp);
1629 coeff[i+j*inchan] = 0;
1632 coeff[i++ + j*inchan] = 0;
1634 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1644 unsigned int mask = 0;
1650 unsigned char (*maps)[256];
1652 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1653 croak("i_map: parameter 2 must be an arrayref\n");
1654 avmain = (AV*)SvRV(ST(1));
1655 len = av_len(avmain)+1;
1656 if (im->channels < len) len = im->channels;
1658 maps = mymalloc( len * sizeof(unsigned char [256]) );
1660 for (j=0; j<len ; j++) {
1661 temp = av_fetch(avmain, j, 0);
1662 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1663 avsub = (AV*)SvRV(*temp);
1664 if(av_len(avsub) != 255) continue;
1666 for (i=0; i<256 ; i++) {
1668 temp = av_fetch(avsub, i, 0);
1669 val = temp ? SvIV(*temp) : 0;
1671 if (val>255) val = 255;
1676 i_map(im, maps, mask);
1689 i_init_fonts(t1log=0)
1704 i_t1_destroy(font_id)
1709 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1728 str = SvPV(str_sv, len);
1729 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1736 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1745 int cords[BOUNDING_BOX_COUNT];
1753 str = SvPV(str_sv, len);
1754 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1757 for (i = 0; i < rc; ++i)
1758 PUSHs(sv_2mortal(newSViv(cords[i])));
1764 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1783 str = SvPV(str_sv, len);
1784 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1790 i_t1_has_chars(handle, text_sv, utf8 = 0)
1802 if (SvUTF8(text_sv))
1805 text = SvPV(text_sv, len);
1806 work = mymalloc(len);
1807 count = i_t1_has_chars(handle, text, len, utf8, work);
1808 if (GIMME_V == G_ARRAY) {
1810 for (i = 0; i < count; ++i) {
1811 PUSHs(sv_2mortal(newSViv(work[i])));
1816 PUSHs(sv_2mortal(newSVpv(work, count)));
1821 i_t1_face_name(handle)
1827 len = i_t1_face_name(handle, name, sizeof(name));
1830 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1834 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1845 if (SvUTF8(text_sv))
1848 text = SvPV(text_sv, work_len);
1853 ch = i_utf8_advance(&text, &len);
1855 i_push_error(0, "invalid UTF8 character");
1864 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1865 PUSHs(sv_2mortal(newSVpv(name, 0)));
1868 PUSHs(&PL_sv_undef);
1882 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1884 #define TT_DESTROY(handle) i_tt_destroy(handle)
1888 Imager::Font::TT handle
1891 MODULE = Imager PACKAGE = Imager
1895 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1896 Imager::Font::TT handle
1914 str = SvPV(str_sv, len);
1915 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1916 len, smooth, utf8, align);
1922 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1923 Imager::Font::TT handle
1941 str = SvPV(str_sv, len);
1942 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1943 smooth, utf8, align);
1949 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1950 Imager::Font::TT handle
1955 int cords[BOUNDING_BOX_COUNT],rc;
1964 str = SvPV(str_sv, len);
1965 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1967 for (i = 0; i < rc; ++i) {
1968 PUSHs(sv_2mortal(newSViv(cords[i])));
1973 i_tt_has_chars(handle, text_sv, utf8)
1974 Imager::Font::TT handle
1985 if (SvUTF8(text_sv))
1988 text = SvPV(text_sv, len);
1989 work = mymalloc(len);
1990 count = i_tt_has_chars(handle, text, len, utf8, work);
1991 if (GIMME_V == G_ARRAY) {
1993 for (i = 0; i < count; ++i) {
1994 PUSHs(sv_2mortal(newSViv(work[i])));
1999 PUSHs(sv_2mortal(newSVpv(work, count)));
2004 i_tt_dump_names(handle)
2005 Imager::Font::TT handle
2008 i_tt_face_name(handle)
2009 Imager::Font::TT handle
2014 len = i_tt_face_name(handle, name, sizeof(name));
2017 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2021 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2022 Imager::Font::TT handle
2033 if (SvUTF8(text_sv))
2036 text = SvPV(text_sv, work_len);
2041 ch = i_utf8_advance(&text, &len);
2043 i_push_error(0, "invalid UTF8 character");
2052 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2053 PUSHs(sv_2mortal(newSVpv(name, 0)));
2056 PUSHs(&PL_sv_undef);
2065 i_writejpeg_wiol(im, ig, qfactor)
2081 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2082 if (iptc_itext == NULL) {
2085 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2090 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2092 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2103 i_test_format_probe(ig, length)
2112 i_readtiff_wiol(ig, length, page=0)
2118 i_readtiff_multi_wiol(ig, length)
2126 imgs = i_readtiff_multi_wiol(ig, length, &count);
2129 for (i = 0; i < count; ++i) {
2130 SV *sv = sv_newmortal();
2131 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2139 i_writetiff_wiol(im, ig)
2144 i_writetiff_multi_wiol(ig, ...)
2152 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2153 img_count = items - 1;
2155 if (img_count < 1) {
2158 i_push_error(0, "You need to specify images to save");
2161 imgs = mymalloc(sizeof(i_img *) * img_count);
2162 for (i = 0; i < img_count; ++i) {
2165 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2166 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2170 i_push_error(0, "Only images can be saved");
2177 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2185 i_writetiff_wiol_faxable(im, ig, fine)
2191 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2200 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2201 img_count = items - 2;
2203 if (img_count < 1) {
2206 i_push_error(0, "You need to specify images to save");
2209 imgs = mymalloc(sizeof(i_img *) * img_count);
2210 for (i = 0; i < img_count; ++i) {
2213 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2214 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2218 i_push_error(0, "Only images can be saved");
2225 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2233 #endif /* HAVE_LIBTIFF */
2239 i_readpng_wiol(ig, length)
2245 i_writepng_wiol(im, ig)
2258 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2261 i_writegif(im,fd,colors,pixdev,fixed)
2268 Imager__Color fixed;
2275 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2276 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2277 av=(AV*)SvRV(ST(4));
2278 fixedlen=av_len(av)+1;
2279 fixed=mymalloc( fixedlen*sizeof(i_color) );
2280 for(i=0;i<fixedlen;i++) {
2281 sv1=(*(av_fetch(av,i,0)));
2282 if (sv_derived_from(sv1, "Imager::Color")) {
2283 Itmp = SvIV((SV*)SvRV(sv1));
2284 tmp = INT2PTR(i_color*, Itmp);
2285 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2288 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2290 ST(0) = sv_newmortal();
2291 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2292 else sv_setiv(ST(0), (IV)RETVAL);
2298 i_writegifmc(im,fd,colors)
2305 i_writegif_gen(fd, ...)
2310 i_img **imgs = NULL;
2316 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2317 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2318 croak("i_writegif_gen: Second argument must be a hash ref");
2319 hv = (HV *)SvRV(ST(1));
2320 memset(&quant, 0, sizeof(quant));
2321 quant.mc_size = 256;
2322 handle_quant_opts(&quant, hv);
2323 img_count = items - 2;
2325 if (img_count < 1) {
2328 i_push_error(0, "You need to specify images to save");
2331 imgs = mymalloc(sizeof(i_img *) * img_count);
2332 for (i = 0; i < img_count; ++i) {
2335 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2336 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2340 i_push_error(0, "Only images can be saved");
2346 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2350 copy_colors_back(hv, &quant);
2353 ST(0) = sv_newmortal();
2354 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2355 else sv_setiv(ST(0), (IV)RETVAL);
2356 cleanup_quant_opts(&quant);
2360 i_writegif_callback(cb, maxbuffer,...)
2364 i_img **imgs = NULL;
2371 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2372 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2373 croak("i_writegif_callback: Second argument must be a hash ref");
2374 hv = (HV *)SvRV(ST(2));
2375 memset(&quant, 0, sizeof(quant));
2376 quant.mc_size = 256;
2377 handle_quant_opts(&quant, hv);
2378 img_count = items - 3;
2380 if (img_count < 1) {
2384 imgs = mymalloc(sizeof(i_img *) * img_count);
2385 for (i = 0; i < img_count; ++i) {
2388 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2389 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2398 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2402 copy_colors_back(hv, &quant);
2405 ST(0) = sv_newmortal();
2406 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2407 else sv_setiv(ST(0), (IV)RETVAL);
2408 cleanup_quant_opts(&quant);
2411 i_writegif_wiol(ig, opts,...)
2415 i_img **imgs = NULL;
2421 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2422 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2423 croak("i_writegif_callback: Second argument must be a hash ref");
2424 hv = (HV *)SvRV(ST(1));
2425 memset(&quant, 0, sizeof(quant));
2426 quant.mc_size = 256;
2427 handle_quant_opts(&quant, hv);
2428 img_count = items - 2;
2430 if (img_count < 1) {
2434 imgs = mymalloc(sizeof(i_img *) * img_count);
2435 for (i = 0; i < img_count; ++i) {
2438 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2439 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2447 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2451 copy_colors_back(hv, &quant);
2454 ST(0) = sv_newmortal();
2455 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2456 else sv_setiv(ST(0), (IV)RETVAL);
2457 cleanup_quant_opts(&quant);
2470 colour_table = NULL;
2473 if(GIMME_V == G_ARRAY) {
2474 rimg = i_readgif(fd,&colour_table,&colours);
2476 /* don't waste time with colours if they aren't wanted */
2477 rimg = i_readgif(fd,NULL,NULL);
2480 if (colour_table == NULL) {
2483 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2486 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2487 /* I don't know if I have the reference counts right or not :( */
2488 /* Neither do I :-) */
2489 /* No Idea here either */
2492 av_extend(ct, colours);
2493 for(q=0; q<colours; q++) {
2495 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2496 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2498 myfree(colour_table);
2502 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2504 PUSHs(newRV_noinc((SV*)ct));
2518 colour_table = NULL;
2521 if(GIMME_V == G_ARRAY) {
2522 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2524 /* don't waste time with colours if they aren't wanted */
2525 rimg = i_readgif_wiol(ig,NULL,NULL);
2528 if (colour_table == NULL) {
2531 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2534 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2535 /* I don't know if I have the reference counts right or not :( */
2536 /* Neither do I :-) */
2537 /* No Idea here either */
2540 av_extend(ct, colours);
2541 for(q=0; q<colours; q++) {
2543 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2544 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2546 myfree(colour_table);
2550 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2552 PUSHs(newRV_noinc((SV*)ct));
2556 i_readgif_single_wiol(ig, page=0)
2561 i_readgif_scalar(...)
2573 data = (char *)SvPV(ST(0), length);
2577 if(GIMME_V == G_ARRAY) {
2578 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2580 /* don't waste time with colours if they aren't wanted */
2581 rimg=i_readgif_scalar(data,length,NULL,NULL);
2584 if (colour_table == NULL) {
2587 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2590 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2591 /* I don't know if I have the reference counts right or not :( */
2592 /* Neither do I :-) */
2594 av_extend(ct, colours);
2595 for(q=0; q<colours; q++) {
2597 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2598 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2600 myfree(colour_table);
2604 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2606 PUSHs(newRV_noinc((SV*)ct));
2610 i_readgif_callback(...)
2625 if(GIMME_V == G_ARRAY) {
2626 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2628 /* don't waste time with colours if they aren't wanted */
2629 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2632 if (colour_table == NULL) {
2635 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2638 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2639 /* I don't know if I have the reference counts right or not :( */
2640 /* Neither do I :-) */
2641 /* Neither do I - maybe I'll move this somewhere */
2643 av_extend(ct, colours);
2644 for(q=0; q<colours; q++) {
2646 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2647 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2649 myfree(colour_table);
2653 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2655 PUSHs(newRV_noinc((SV*)ct));
2666 imgs = i_readgif_multi(fd, &count);
2669 for (i = 0; i < count; ++i) {
2670 SV *sv = sv_newmortal();
2671 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2678 i_readgif_multi_scalar(data)
2686 data = (char *)SvPV(ST(0), length);
2687 imgs = i_readgif_multi_scalar(data, length, &count);
2690 for (i = 0; i < count; ++i) {
2691 SV *sv = sv_newmortal();
2692 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2699 i_readgif_multi_callback(cb)
2707 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2710 for (i = 0; i < count; ++i) {
2711 SV *sv = sv_newmortal();
2712 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2719 i_readgif_multi_wiol(ig)
2726 imgs = i_readgif_multi_wiol(ig, &count);
2729 for (i = 0; i < count; ++i) {
2730 SV *sv = sv_newmortal();
2731 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2743 i_readpnm_wiol(ig, length)
2749 i_writeppm_wiol(im, ig)
2755 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2764 i_writeraw_wiol(im,ig)
2769 i_writebmp_wiol(im,ig)
2779 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2788 idlen = SvCUR(ST(4));
2789 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2795 i_readtga_wiol(ig, length)
2801 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2810 idlen = SvCUR(ST(4));
2811 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2817 i_readrgb_wiol(ig, length)
2824 i_scaleaxis(im,Value,Axis)
2830 i_scale_nn(im,scx,scy)
2840 i_count_colors(im,maxc)
2846 i_transform(im,opx,opy,parm)
2859 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2860 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2861 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2862 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2863 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2864 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2865 av=(AV*)SvRV(ST(1));
2867 opx=mymalloc( opxl*sizeof(int) );
2868 for(i=0;i<opxl;i++) {
2869 sv1=(*(av_fetch(av,i,0)));
2870 opx[i]=(int)SvIV(sv1);
2872 av=(AV*)SvRV(ST(2));
2874 opy=mymalloc( opyl*sizeof(int) );
2875 for(i=0;i<opyl;i++) {
2876 sv1=(*(av_fetch(av,i,0)));
2877 opy[i]=(int)SvIV(sv1);
2879 av=(AV*)SvRV(ST(3));
2880 parmlen=av_len(av)+1;
2881 parm=mymalloc( parmlen*sizeof(double) );
2882 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2883 sv1=(*(av_fetch(av,i,0)));
2884 parm[i]=(double)SvNV(sv1);
2886 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2890 ST(0) = sv_newmortal();
2891 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2892 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2895 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2920 in_imgs_count = av_len(av_in_imgs)+1;
2921 for (i = 0; i < in_imgs_count; ++i) {
2922 sv1 = *av_fetch(av_in_imgs, i, 0);
2923 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2924 croak("sv_in_img must contain only images");
2927 if (in_imgs_count > 0) {
2928 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2929 for (i = 0; i < in_imgs_count; ++i) {
2930 sv1 = *av_fetch(av_in_imgs,i,0);
2931 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2932 croak("Parameter 5 must contain only images");
2934 tmp = SvIV((SV*)SvRV(sv1));
2935 in_imgs[i] = INT2PTR(i_img*, tmp);
2939 /* no input images */
2942 /* default the output size from the first input if possible */
2944 width = SvIV(sv_width);
2945 else if (in_imgs_count)
2946 width = in_imgs[0]->xsize;
2948 croak("No output image width supplied");
2950 if (SvOK(sv_height))
2951 height = SvIV(sv_height);
2952 else if (in_imgs_count)
2953 height = in_imgs[0]->ysize;
2955 croak("No output image height supplied");
2957 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2958 if (ops_len % sizeof(struct rm_op))
2959 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2960 ops_count = ops_len / sizeof(struct rm_op);
2962 n_regs_count = av_len(av_n_regs)+1;
2963 n_regs = mymalloc(n_regs_count * sizeof(double));
2964 for (i = 0; i < n_regs_count; ++i) {
2965 sv1 = *av_fetch(av_n_regs,i,0);
2967 n_regs[i] = SvNV(sv1);
2969 c_regs_count = av_len(av_c_regs)+1;
2970 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2971 /* I don't bother initializing the colou?r registers */
2973 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2974 n_regs, n_regs_count,
2975 c_regs, c_regs_count, in_imgs, in_imgs_count);
2980 ST(0) = sv_newmortal();
2981 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2982 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2986 i_contrast(im,intensity)
2995 i_noise(im,amount,type)
3001 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3011 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3030 i_postlevels(im,levels)
3040 i_watermark(im,wmark,tx,ty,pixdiff)
3042 Imager::ImgRaw wmark
3049 i_autolevels(im,lsat,usat,skew)
3056 i_radnoise(im,xo,yo,rscale,ascale)
3064 i_turbnoise(im, xo, yo, scale)
3087 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3088 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3089 croak("i_gradgen: Second argument must be an array ref");
3090 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3091 croak("i_gradgen: Third argument must be an array ref");
3092 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3093 croak("i_gradgen: Fourth argument must be an array ref");
3094 axx = (AV *)SvRV(ST(1));
3095 ayy = (AV *)SvRV(ST(2));
3096 ac = (AV *)SvRV(ST(3));
3097 dmeasure = (int)SvIV(ST(4));
3099 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3100 num = num <= av_len(ac) ? num : av_len(ac);
3102 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3103 xo = mymalloc( sizeof(int) * num );
3104 yo = mymalloc( sizeof(int) * num );
3105 ival = mymalloc( sizeof(i_color) * num );
3106 for(i = 0; i<num; i++) {
3107 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3108 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3109 sv = *av_fetch(ac, i, 0);
3110 if ( !sv_derived_from(sv, "Imager::Color") ) {
3111 free(axx); free(ayy); free(ac);
3112 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3114 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3116 i_gradgen(im, num, xo, yo, ival, dmeasure);
3122 i_diff_image(im, im2, mindist=0)
3128 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3138 double ssample_param
3142 i_fountain_seg *segs;
3144 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3145 croak("i_fountain: argument 11 must be an array ref");
3147 asegs = (AV *)SvRV(ST(10));
3148 segs = load_fount_segs(asegs, &count);
3149 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3150 super_sample, ssample_param, count, segs);
3156 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3165 double ssample_param
3169 i_fountain_seg *segs;
3171 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3172 croak("i_fountain: argument 11 must be an array ref");
3174 asegs = (AV *)SvRV(ST(9));
3175 segs = load_fount_segs(asegs, &count);
3176 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3177 super_sample, ssample_param, count, segs);
3190 errors = i_errors();
3192 while (errors[i].msg) {
3194 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3195 if (!av_store(av, 0, sv)) {
3198 sv = newSViv(errors[i].code);
3199 if (!av_store(av, 1, sv)) {
3202 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3207 i_nearest_color(im, ...)
3222 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3223 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3224 croak("i_nearest_color: Second argument must be an array ref");
3225 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3226 croak("i_nearest_color: Third argument must be an array ref");
3227 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3228 croak("i_nearest_color: Fourth argument must be an array ref");
3229 axx = (AV *)SvRV(ST(1));
3230 ayy = (AV *)SvRV(ST(2));
3231 ac = (AV *)SvRV(ST(3));
3232 dmeasure = (int)SvIV(ST(4));
3234 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3235 num = num <= av_len(ac) ? num : av_len(ac);
3237 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3238 xo = mymalloc( sizeof(int) * num );
3239 yo = mymalloc( sizeof(int) * num );
3240 ival = mymalloc( sizeof(i_color) * num );
3241 for(i = 0; i<num; i++) {
3242 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3243 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3244 sv = *av_fetch(ac, i, 0);
3245 if ( !sv_derived_from(sv, "Imager::Color") ) {
3246 free(axx); free(ayy); free(ac);
3247 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3249 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3251 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3265 rc=DSO_open(filename,&evstr);
3269 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3270 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3273 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3279 DSO_close(dso_handle)
3283 DSO_funclist(dso_handle_v)
3287 DSO_handle *dso_handle;
3289 dso_handle=(DSO_handle*)dso_handle_v;
3291 while( dso_handle->function_list[i].name != NULL) {
3293 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3295 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3300 DSO_call(handle,func_index,hv)
3306 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3307 hv=(HV*)SvRV(ST(2));
3308 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3309 DSO_call( (DSO_handle *)handle,func_index,hv);
3314 i_get_pixel(im, x, y)
3321 color = (i_color *)mymalloc(sizeof(i_color));
3322 if (i_gpix(im, x, y, color) == 0) {
3323 RETVAL = NEWSV(0, 0);
3324 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3328 RETVAL = &PL_sv_undef;
3335 i_ppix(im, x, y, cl)
3342 i_img_pal_new(x, y, channels, maxpal)
3349 i_img_to_pal(src, quant)
3355 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3356 croak("i_img_to_pal: second argument must be a hash ref");
3357 hv = (HV *)SvRV(ST(1));
3358 memset(&quant, 0, sizeof(quant));
3359 quant.mc_size = 256;
3360 handle_quant_opts(&quant, hv);
3361 RETVAL = i_img_to_pal(src, &quant);
3363 copy_colors_back(hv, &quant);
3365 cleanup_quant_opts(&quant);
3384 work = mymalloc((r-l) * sizeof(i_palidx));
3385 count = i_gpal(im, l, r, y, work);
3386 if (GIMME_V == G_ARRAY) {
3388 for (i = 0; i < count; ++i) {
3389 PUSHs(sv_2mortal(newSViv(work[i])));
3394 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3399 if (GIMME_V != G_ARRAY) {
3401 PUSHs(&PL_sv_undef);
3406 i_ppal(im, l, y, ...)
3415 work = mymalloc(sizeof(i_palidx) * (items-3));
3416 for (i=0; i < items-3; ++i) {
3417 work[i] = SvIV(ST(i+3));
3419 RETVAL = i_ppal(im, l, l+items-3, y, work);
3429 i_addcolors(im, ...)
3437 croak("i_addcolors: no colors to add");
3438 colors = mymalloc((items-1) * sizeof(i_color));
3439 for (i=0; i < items-1; ++i) {
3440 if (sv_isobject(ST(i+1))
3441 && sv_derived_from(ST(i+1), "Imager::Color")) {
3442 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3443 colors[i] = *INT2PTR(i_color *, tmp);
3447 croak("i_addcolor: pixels must be Imager::Color objects");
3450 index = i_addcolors(im, colors, items-1);
3453 RETVAL = newSVpv("0 but true", 0);
3455 else if (index == -1) {
3456 RETVAL = &PL_sv_undef;
3459 RETVAL = newSViv(index);
3465 i_setcolors(im, index, ...)
3473 croak("i_setcolors: no colors to add");
3474 colors = mymalloc((items-2) * sizeof(i_color));
3475 for (i=0; i < items-2; ++i) {
3476 if (sv_isobject(ST(i+2))
3477 && sv_derived_from(ST(i+2), "Imager::Color")) {
3478 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3479 colors[i] = *INT2PTR(i_color *, tmp);
3483 croak("i_setcolors: pixels must be Imager::Color objects");
3486 RETVAL = i_setcolors(im, index, colors, items-2);
3492 i_getcolors(im, index, ...)
3501 croak("i_getcolors: too many arguments");
3503 count = SvIV(ST(2));
3505 croak("i_getcolors: count must be positive");
3506 colors = mymalloc(sizeof(i_color) * count);
3507 if (i_getcolors(im, index, colors, count)) {
3508 for (i = 0; i < count; ++i) {
3510 SV *sv = sv_newmortal();
3511 pv = mymalloc(sizeof(i_color));
3513 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3529 i_findcolor(im, color)
3535 if (i_findcolor(im, color, &index)) {
3536 RETVAL = newSViv(index);
3539 RETVAL = &PL_sv_undef;
3557 i_gsamp(im, l, r, y, ...)
3569 croak("No channel numbers supplied to g_samp()");
3571 chan_count = items - 4;
3572 chans = mymalloc(sizeof(int) * chan_count);
3573 for (i = 0; i < chan_count; ++i)
3574 chans[i] = SvIV(ST(i+4));
3575 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3576 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3578 if (GIMME_V == G_ARRAY) {
3580 for (i = 0; i < count; ++i)
3581 PUSHs(sv_2mortal(newSViv(data[i])));
3585 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3590 if (GIMME_V != G_ARRAY) {
3592 PUSHs(&PL_sv_undef);
3598 i_img_masked_new(targ, mask, x, y, w, h)
3608 if (!sv_isobject(ST(1))
3609 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3610 croak("i_img_masked_new: parameter 2 must undef or an image");
3612 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3616 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3621 i_plin(im, l, y, ...)
3632 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3633 /* supplied as a byte string */
3634 work = (i_color *)SvPV(ST(3), len);
3635 count = len / sizeof(i_color);
3636 if (count * sizeof(i_color) != len) {
3637 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3639 RETVAL = i_plin(im, l, l+count, y, work);
3642 work = mymalloc(sizeof(i_color) * (items-3));
3643 for (i=0; i < items-3; ++i) {
3644 if (sv_isobject(ST(i+3))
3645 && sv_derived_from(ST(i+3), "Imager::Color")) {
3646 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3647 work[i] = *INT2PTR(i_color *, tmp);
3651 croak("i_plin: pixels must be Imager::Color objects");
3654 RETVAL = i_plin(im, l, l+items-3, y, work);
3665 i_ppixf(im, x, y, cl)
3669 Imager::Color::Float cl
3672 i_gsampf(im, l, r, y, ...)
3684 croak("No channel numbers supplied to g_sampf()");
3686 chan_count = items - 4;
3687 chans = mymalloc(sizeof(int) * chan_count);
3688 for (i = 0; i < chan_count; ++i)
3689 chans[i] = SvIV(ST(i+4));
3690 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3691 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3693 if (GIMME_V == G_ARRAY) {
3695 for (i = 0; i < count; ++i)
3696 PUSHs(sv_2mortal(newSVnv(data[i])));
3700 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3705 if (GIMME_V != G_ARRAY) {
3707 PUSHs(&PL_sv_undef);
3712 i_plinf(im, l, y, ...)
3723 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3724 /* supplied as a byte string */
3725 work = (i_fcolor *)SvPV(ST(3), len);
3726 count = len / sizeof(i_fcolor);
3727 if (count * sizeof(i_fcolor) != len) {
3728 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3730 RETVAL = i_plinf(im, l, l+count, y, work);
3733 work = mymalloc(sizeof(i_fcolor) * (items-3));
3734 for (i=0; i < items-3; ++i) {
3735 if (sv_isobject(ST(i+3))
3736 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3737 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3738 work[i] = *INT2PTR(i_fcolor *, tmp);
3742 croak("i_plinf: pixels must be Imager::Color::Float objects");
3746 RETVAL = i_plinf(im, l, l+items-3, y, work);
3764 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3765 if (i_gpixf(im, x, y, color) == 0) {
3766 RETVAL = NEWSV(0,0);
3767 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3771 RETVAL = &PL_sv_undef;
3787 vals = mymalloc((r-l) * sizeof(i_color));
3788 count = i_glin(im, l, r, y, vals);
3789 if (GIMME_V == G_ARRAY) {
3791 for (i = 0; i < count; ++i) {
3793 i_color *col = mymalloc(sizeof(i_color));
3795 sv = sv_newmortal();
3796 sv_setref_pv(sv, "Imager::Color", (void *)col);
3802 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3808 i_glinf(im, l, r, y)
3818 vals = mymalloc((r-l) * sizeof(i_fcolor));
3819 count = i_glinf(im, l, r, y, vals);
3820 if (GIMME_V == G_ARRAY) {
3822 for (i = 0; i < count; ++i) {
3824 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3826 sv = sv_newmortal();
3827 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3833 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3839 i_img_16_new(x, y, ch)
3845 i_img_double_new(x, y, ch)
3851 i_tags_addn(im, name, code, idata)
3860 name = SvPV(ST(1), len);
3863 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3868 i_tags_add(im, name, code, data, idata)
3878 name = SvPV(ST(1), len);
3882 data = SvPV(ST(3), len);
3887 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3892 i_tags_find(im, name, start)
3899 if (i_tags_find(&im->tags, name, start, &entry)) {
3901 RETVAL = newSVpv("0 but true", 0);
3903 RETVAL = newSViv(entry);
3905 RETVAL = &PL_sv_undef;
3911 i_tags_findn(im, code, start)
3918 if (i_tags_findn(&im->tags, code, start, &entry)) {
3920 RETVAL = newSVpv("0 but true", 0);
3922 RETVAL = newSViv(entry);
3925 RETVAL = &PL_sv_undef;
3931 i_tags_delete(im, entry)
3935 RETVAL = i_tags_delete(&im->tags, entry);
3940 i_tags_delbyname(im, name)
3944 RETVAL = i_tags_delbyname(&im->tags, name);
3949 i_tags_delbycode(im, code)
3953 RETVAL = i_tags_delbycode(&im->tags, code);
3958 i_tags_get(im, index)
3962 if (index >= 0 && index < im->tags.count) {
3963 i_img_tag *entry = im->tags.tags + index;
3967 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3970 PUSHs(sv_2mortal(newSViv(entry->code)));
3973 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3976 PUSHs(sv_2mortal(newSViv(entry->idata)));
3981 i_tags_get_string(im, what_sv)
3985 char const *name = NULL;
3989 if (SvIOK(what_sv)) {
3990 code = SvIV(what_sv);
3994 name = SvPV_nolen(what_sv);
3997 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3999 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4006 RETVAL = im->tags.count;
4013 i_wf_bbox(face, size, text)
4018 int cords[BOUNDING_BOX_COUNT];
4021 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4023 for (i = 0; i < rc; ++i)
4024 PUSHs(sv_2mortal(newSViv(cords[i])));
4028 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4039 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4045 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4056 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4069 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4071 #define FT2_DESTROY(font) i_ft2_destroy(font)
4075 Imager::Font::FT2 font
4077 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4080 i_ft2_new(name, index)
4085 i_ft2_setdpi(font, xdpi, ydpi)
4086 Imager::Font::FT2 font
4092 Imager::Font::FT2 font
4096 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4098 PUSHs(sv_2mortal(newSViv(xdpi)));
4099 PUSHs(sv_2mortal(newSViv(ydpi)));
4103 i_ft2_sethinting(font, hinting)
4104 Imager::Font::FT2 font
4108 i_ft2_settransform(font, matrix)
4109 Imager::Font::FT2 font
4117 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4118 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4119 av=(AV*)SvRV(ST(1));
4123 for (i = 0; i < len; ++i) {
4124 sv1=(*(av_fetch(av,i,0)));
4125 matrix[i] = SvNV(sv1);
4129 RETVAL = i_ft2_settransform(font, matrix);
4134 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4135 Imager::Font::FT2 font
4141 int bbox[BOUNDING_BOX_COUNT];
4147 text = SvPV(text_sv, text_len);
4149 if (SvUTF8(text_sv))
4152 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4155 for (i = 0; i < rc; ++i)
4156 PUSHs(sv_2mortal(newSViv(bbox[i])));
4160 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4161 Imager::Font::FT2 font
4175 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4178 for (i = 0; i < 8; ++i)
4179 PUSHs(sv_2mortal(newSViv(bbox[i])));
4183 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4184 Imager::Font::FT2 font
4200 if (SvUTF8(ST(7))) {
4204 text = SvPV(ST(7), len);
4205 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4206 len, align, aa, vlayout, utf8);
4211 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4212 Imager::Font::FT2 font
4229 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4230 strlen(text), align, aa, vlayout, 1);
4235 ft2_transform_box(font, x0, x1, x2, x3)
4236 Imager::Font::FT2 font
4244 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4245 ft2_transform_box(font, box);
4247 PUSHs(sv_2mortal(newSViv(box[0])));
4248 PUSHs(sv_2mortal(newSViv(box[1])));
4249 PUSHs(sv_2mortal(newSViv(box[2])));
4250 PUSHs(sv_2mortal(newSViv(box[3])));
4253 i_ft2_has_chars(handle, text_sv, utf8)
4254 Imager::Font::FT2 handle
4265 if (SvUTF8(text_sv))
4268 text = SvPV(text_sv, len);
4269 work = mymalloc(len);
4270 count = i_ft2_has_chars(handle, text, len, utf8, work);
4271 if (GIMME_V == G_ARRAY) {
4273 for (i = 0; i < count; ++i) {
4274 PUSHs(sv_2mortal(newSViv(work[i])));
4279 PUSHs(sv_2mortal(newSVpv(work, count)));
4284 i_ft2_face_name(handle)
4285 Imager::Font::FT2 handle
4290 len = i_ft2_face_name(handle, name, sizeof(name));
4293 PUSHs(sv_2mortal(newSVpv(name, 0)));
4297 i_ft2_can_face_name()
4300 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4301 Imager::Font::FT2 handle
4312 if (SvUTF8(text_sv))
4315 text = SvPV(text_sv, work_len);
4320 ch = i_utf8_advance(&text, &len);
4322 i_push_error(0, "invalid UTF8 character");
4331 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4333 PUSHs(sv_2mortal(newSVpv(name, 0)));
4336 PUSHs(&PL_sv_undef);
4341 i_ft2_can_do_glyph_names()
4344 i_ft2_face_has_glyph_names(handle)
4345 Imager::Font::FT2 handle
4348 i_ft2_is_multiple_master(handle)
4349 Imager::Font::FT2 handle
4352 i_ft2_get_multiple_masters(handle)
4353 Imager::Font::FT2 handle
4358 if (i_ft2_get_multiple_masters(handle, &mm)) {
4359 EXTEND(SP, 2+mm.num_axis);
4360 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4361 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4362 for (i = 0; i < mm.num_axis; ++i) {
4366 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4368 av_store(av, 0, sv);
4369 sv = newSViv(mm.axis[i].minimum);
4371 av_store(av, 1, sv);
4372 sv = newSViv(mm.axis[i].maximum);
4374 av_store(av, 2, sv);
4375 PUSHs(newRV_noinc((SV *)av));
4380 i_ft2_set_mm_coords(handle, ...)
4381 Imager::Font::FT2 handle
4387 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4388 transfer the array manually */
4389 ix_coords = items-1;
4390 coords = mymalloc(sizeof(long) * ix_coords);
4391 for (i = 0; i < ix_coords; ++i) {
4392 coords[i] = (long)SvIV(ST(1+i));
4394 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4401 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4405 Imager::FillHandle fill
4407 MODULE = Imager PACKAGE = Imager
4410 i_new_fill_solid(cl, combine)
4415 i_new_fill_solidf(cl, combine)
4416 Imager::Color::Float cl
4420 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4428 unsigned char *cust_hatch;
4432 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4436 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4441 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4442 Imager::Color::Float fg
4443 Imager::Color::Float bg
4449 unsigned char *cust_hatch;
4453 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4457 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4462 i_new_fill_image(src, matrix, xoff, yoff, combine)
4479 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4480 croak("i_new_fill_image: parameter must be an arrayref");
4481 av=(AV*)SvRV(ST(1));
4485 for (i = 0; i < len; ++i) {
4486 sv1=(*(av_fetch(av,i,0)));
4487 matrix[i] = SvNV(sv1);
4493 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4497 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4499 # this class is only exposed for testing
4502 i_int_hlines_testing()
4504 #if i_int_hlines_testing()
4506 Imager::Internal::Hlines
4507 i_int_hlines_new(start_y, count_y, start_x, count_x)
4513 Imager::Internal::Hlines
4514 i_int_hlines_new_img(im)
4518 i_int_hlines_add(hlines, y, minx, width)
4519 Imager::Internal::Hlines hlines
4525 i_int_hlines_DESTROY(hlines)
4526 Imager::Internal::Hlines hlines
4529 i_int_hlines_dump(hlines)
4530 Imager::Internal::Hlines hlines
4535 PERL_SET_GLOBAL_CALLBACKS;