17 typedef io_glue* Imager__IO;
18 typedef i_color* Imager__Color;
19 typedef i_fcolor* Imager__Color__Float;
20 typedef i_img* Imager__ImgRaw;
21 typedef int undef_neg_int;
24 typedef TT_Fonthandle* Imager__Font__TT;
28 typedef FT2_Fonthandle* Imager__Font__FT2;
31 /* These functions are all shared - then comes platform dependant code */
32 static int getstr(void *hv_t,char *key,char **store) {
36 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
38 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
40 svpp=hv_fetch(hv, key, strlen(key), 0);
41 *store=SvPV(*svpp, PL_na );
46 static int getint(void *hv_t,char *key,int *store) {
50 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
52 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
54 svpp=hv_fetch(hv, key, strlen(key), 0);
55 *store=(int)SvIV(*svpp);
59 static int getdouble(void *hv_t,char* key,double *store) {
63 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
65 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
66 svpp=hv_fetch(hv, key, strlen(key), 0);
67 *store=(float)SvNV(*svpp);
71 static int getvoid(void *hv_t,char* key,void **store) {
75 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
77 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
79 svpp=hv_fetch(hv, key, strlen(key), 0);
80 *store = INT2PTR(void*, SvIV(*svpp));
85 static int getobj(void *hv_t,char *key,char *type,void **store) {
89 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
91 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
93 svpp=hv_fetch(hv, key, strlen(key), 0);
95 if (sv_derived_from(*svpp,type)) {
96 IV tmp = SvIV((SV*)SvRV(*svpp));
97 *store = INT2PTR(void*, tmp);
99 mm_log((1,"getobj: key exists in hash but is not of correct type"));
106 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
108 void my_SvREFCNT_dec(void *p) {
109 SvREFCNT_dec((SV*)p);
114 log_entry(char *string, int level) {
115 mm_log((level, string));
119 typedef struct i_reader_data_tag
121 /* presumably a CODE ref or name of a sub */
125 /* used by functions that want callbacks */
126 static int read_callback(char *userdata, char *buffer, int need, int want) {
127 i_reader_data *rd = (i_reader_data *)userdata;
131 dSP; dTARG = sv_newmortal();
132 /* thanks to Simon Cozens for help with the dTARG above */
142 count = perl_call_sv(rd->sv, G_SCALAR);
147 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
153 char *ptr = SvPV(data, len);
155 croak("Too much data returned in reader callback");
157 memcpy(buffer, ptr, len);
173 SV *sv; /* a coderef or sub name */
176 /* used by functions that want callbacks */
177 static int write_callback(char *userdata, char const *data, int size) {
178 i_writer_data *wd = (i_writer_data *)userdata;
188 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
191 count = perl_call_sv(wd->sv, G_SCALAR);
196 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
199 success = SvTRUE(sv);
209 #define CBDATA_BUFSIZE 8192
212 /* the SVs we use to call back to Perl */
218 /* we need to remember whether the buffer contains write data or
224 /* how far we've read into the buffer (not used for writing) */
227 /* the amount of space used/data available in the buffer */
230 /* the maximum amount to fill the buffer before flushing
231 If any write is larger than this then the buffer is flushed and
232 the full write is performed. The write is _not_ split into
237 char buffer[CBDATA_BUFSIZE];
242 call_writer(cbd, buf, size)
244 Low-level function to call the perl writer callback.
248 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
254 if (!SvOK(cbd->writecb))
261 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
264 count = perl_call_sv(cbd->writecb, G_SCALAR);
268 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
271 success = SvTRUE(sv);
278 return success ? size : 0;
281 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
288 if (!SvOK(cbd->readcb))
295 PUSHs(sv_2mortal(newSViv(size)));
296 PUSHs(sv_2mortal(newSViv(maxread)));
299 count = perl_call_sv(cbd->readcb, G_SCALAR);
304 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
310 char *ptr = SvPV(data, len);
312 croak("Too much data returned in reader callback");
314 memcpy(buf, ptr, len);
328 static ssize_t write_flush(struct cbdata *cbd) {
331 result = call_writer(cbd, cbd->buffer, cbd->used);
336 static off_t io_seeker(void *p, off_t offset, int whence) {
337 struct cbdata *cbd = p;
342 if (!SvOK(cbd->seekcb))
346 if (cbd->used && write_flush(cbd) <= 0)
350 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
351 offset -= cbd->where - cbd->used;
354 cbd->where = cbd->used = 0;
360 PUSHs(sv_2mortal(newSViv(offset)));
361 PUSHs(sv_2mortal(newSViv(whence)));
364 count = perl_call_sv(cbd->seekcb, G_SCALAR);
369 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
380 static ssize_t io_writer(void *p, void const *data, size_t size) {
381 struct cbdata *cbd = p;
383 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
385 if (cbd->reading && cbd->where < cbd->used) {
386 /* we read past the place where the caller expected us to be
387 so adjust our position a bit */
389 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
394 cbd->where = cbd->used = 0;
397 if (cbd->used && cbd->used + size > cbd->maxlength) {
398 if (write_flush(cbd) <= 0) {
403 if (cbd->used+size <= cbd->maxlength) {
404 memcpy(cbd->buffer + cbd->used, data, size);
408 /* it doesn't fit - just pass it up */
409 return call_writer(cbd, data, size);
412 static ssize_t io_reader(void *p, void *data, size_t size) {
413 struct cbdata *cbd = p;
415 char *out = data; /* so we can do pointer arithmetic */
418 if (write_flush(cbd) <= 0)
424 if (size <= cbd->used - cbd->where) {
426 memcpy(data, cbd->buffer+cbd->where, size);
431 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
432 total += cbd->used - cbd->where;
433 size -= cbd->used - cbd->where;
434 out += cbd->used - cbd->where;
435 if (size < sizeof(cbd->buffer)) {
439 && (did_read = call_reader(cbd, cbd->buffer, size,
440 sizeof(cbd->buffer))) > 0) {
442 cbd->used = did_read;
444 copy_size = i_min(size, cbd->used);
445 memcpy(out, cbd->buffer, copy_size);
446 cbd->where += copy_size;
453 /* just read the rest - too big for our buffer*/
455 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
465 static void io_closer(void *p) {
466 struct cbdata *cbd = p;
468 if (cbd->writing && cbd->used > 0) {
473 if (SvOK(cbd->closecb)) {
481 perl_call_sv(cbd->closecb, G_VOID);
490 static void io_destroyer(void *p) {
491 struct cbdata *cbd = p;
493 SvREFCNT_dec(cbd->writecb);
494 SvREFCNT_dec(cbd->readcb);
495 SvREFCNT_dec(cbd->seekcb);
496 SvREFCNT_dec(cbd->closecb);
504 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
507 for (i = 0; i < count; ++i)
508 if (strEQ(names[i].name, name))
509 return names[i].value;
513 static struct value_name transp_names[] =
516 { "threshold", tr_threshold },
517 { "errdiff", tr_errdiff },
518 { "ordered", tr_ordered, },
521 static struct value_name make_color_names[] =
523 { "none", mc_none, },
524 { "webmap", mc_web_map, },
525 { "addi", mc_addi, },
526 { "mediancut", mc_median_cut, },
529 static struct value_name translate_names[] =
532 { "giflib", pt_giflib, },
534 { "closest", pt_closest, },
535 { "perturb", pt_perturb, },
536 { "errdiff", pt_errdiff, },
539 static struct value_name errdiff_names[] =
541 { "floyd", ed_floyd, },
542 { "jarvis", ed_jarvis, },
543 { "stucki", ed_stucki, },
544 { "custom", ed_custom, },
547 static struct value_name orddith_names[] =
549 { "random", od_random, },
550 { "dot8", od_dot8, },
551 { "dot4", od_dot4, },
552 { "hline", od_hline, },
553 { "vline", od_vline, },
554 { "/line", od_slashline, },
555 { "slashline", od_slashline, },
556 { "\\line", od_backline, },
557 { "backline", od_backline, },
558 { "tiny", od_tiny, },
559 { "custom", od_custom, },
562 /* look through the hash for quantization options */
563 static void handle_quant_opts(i_quantize *quant, HV *hv)
565 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
571 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
573 sv = hv_fetch(hv, "transp", 6, 0);
574 if (sv && *sv && (str = SvPV(*sv, len))) {
576 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
578 if (quant->transp != tr_none) {
579 quant->tr_threshold = 127;
580 sv = hv_fetch(hv, "tr_threshold", 12, 0);
582 quant->tr_threshold = SvIV(*sv);
584 if (quant->transp == tr_errdiff) {
585 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
586 if (sv && *sv && (str = SvPV(*sv, len)))
587 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
589 if (quant->transp == tr_ordered) {
590 quant->tr_orddith = od_tiny;
591 sv = hv_fetch(hv, "tr_orddith", 10, 0);
592 if (sv && *sv && (str = SvPV(*sv, len)))
593 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
595 if (quant->tr_orddith == od_custom) {
596 sv = hv_fetch(hv, "tr_map", 6, 0);
597 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
598 AV *av = (AV*)SvRV(*sv);
599 len = av_len(av) + 1;
600 if (len > sizeof(quant->tr_custom))
601 len = sizeof(quant->tr_custom);
602 for (i = 0; i < len; ++i) {
603 SV **sv2 = av_fetch(av, i, 0);
605 quant->tr_custom[i] = SvIV(*sv2);
608 while (i < sizeof(quant->tr_custom))
609 quant->tr_custom[i++] = 0;
614 quant->make_colors = mc_addi;
615 sv = hv_fetch(hv, "make_colors", 11, 0);
616 if (sv && *sv && (str = SvPV(*sv, len))) {
618 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
620 sv = hv_fetch(hv, "colors", 6, 0);
621 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
622 /* needs to be an array of Imager::Color
623 note that the caller allocates the mc_color array and sets mc_size
625 AV *av = (AV *)SvRV(*sv);
626 quant->mc_count = av_len(av)+1;
627 if (quant->mc_count > quant->mc_size)
628 quant->mc_count = quant->mc_size;
629 for (i = 0; i < quant->mc_count; ++i) {
630 SV **sv1 = av_fetch(av, i, 0);
631 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
632 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
633 quant->mc_colors[i] = *col;
637 sv = hv_fetch(hv, "max_colors", 10, 0);
640 if (i <= quant->mc_size && i >= quant->mc_count)
644 quant->translate = pt_closest;
645 sv = hv_fetch(hv, "translate", 9, 0);
646 if (sv && *sv && (str = SvPV(*sv, len))) {
647 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
649 sv = hv_fetch(hv, "errdiff", 7, 0);
650 if (sv && *sv && (str = SvPV(*sv, len))) {
651 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
653 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
654 /* get the error diffusion map */
655 sv = hv_fetch(hv, "errdiff_width", 13, 0);
657 quant->ed_width = SvIV(*sv);
658 sv = hv_fetch(hv, "errdiff_height", 14, 0);
660 quant->ed_height = SvIV(*sv);
661 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
663 quant->ed_orig = SvIV(*sv);
664 if (quant->ed_width > 0 && quant->ed_height > 0) {
666 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
667 sv = hv_fetch(hv, "errdiff_map", 11, 0);
668 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
669 AV *av = (AV*)SvRV(*sv);
670 len = av_len(av) + 1;
671 if (len > quant->ed_width * quant->ed_height)
672 len = quant->ed_width * quant->ed_height;
673 for (i = 0; i < len; ++i) {
674 SV **sv2 = av_fetch(av, i, 0);
676 quant->ed_map[i] = SvIV(*sv2);
677 sum += quant->ed_map[i];
683 myfree(quant->ed_map);
685 quant->errdiff = ed_floyd;
689 sv = hv_fetch(hv, "perturb", 7, 0);
691 quant->perturb = SvIV(*sv);
694 static void cleanup_quant_opts(i_quantize *quant) {
695 myfree(quant->mc_colors);
697 myfree(quant->ed_map);
700 /* copies the color map from the hv into the colors member of the HV */
701 static void copy_colors_back(HV *hv, i_quantize *quant) {
707 sv = hv_fetch(hv, "colors", 6, 0);
708 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
711 ref = newRV_inc((SV*) av);
712 sv = hv_store(hv, "colors", 6, ref, 0);
715 av = (AV *)SvRV(*sv);
717 av_extend(av, quant->mc_count+1);
718 for (i = 0; i < quant->mc_count; ++i) {
719 i_color *in = quant->mc_colors+i;
720 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
721 work = sv_newmortal();
722 sv_setref_pv(work, "Imager::Color", (void *)c);
724 if (!av_store(av, i, work)) {
730 /* loads the segments of a fountain fill into an array */
731 static i_fountain_seg *
732 load_fount_segs(AV *asegs, int *count) {
733 /* Each element of segs must contain:
734 [ start, middle, end, c0, c1, segtype, colortrans ]
735 start, middle, end are doubles from 0 to 1
736 c0, c1 are Imager::Color::Float or Imager::Color objects
737 segtype, colortrans are ints
741 i_fountain_seg *segs;
745 *count = av_len(asegs)+1;
747 croak("i_fountain must have at least one segment");
748 segs = mymalloc(sizeof(i_fountain_seg) * *count);
749 for(i = 0; i < *count; i++) {
750 SV **sv1 = av_fetch(asegs, i, 0);
751 if (!sv1 || !*sv1 || !SvROK(*sv1)
752 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
754 croak("i_fountain: segs must be an arrayref of arrayrefs");
756 aseg = (AV *)SvRV(*sv1);
757 if (av_len(aseg) != 7-1) {
759 croak("i_fountain: a segment must have 7 members");
761 for (j = 0; j < 3; ++j) {
762 SV **sv2 = av_fetch(aseg, j, 0);
765 croak("i_fountain: XS error");
767 work[j] = SvNV(*sv2);
769 segs[i].start = work[0];
770 segs[i].middle = work[1];
771 segs[i].end = work[2];
772 for (j = 0; j < 2; ++j) {
773 SV **sv3 = av_fetch(aseg, 3+j, 0);
774 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
775 (!sv_derived_from(*sv3, "Imager::Color")
776 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
778 croak("i_fountain: segs must contain colors in elements 3 and 4");
780 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
781 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
784 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
786 for (ch = 0; ch < MAXCHANNELS; ++ch) {
787 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
791 for (j = 0; j < 2; ++j) {
792 SV **sv2 = av_fetch(aseg, j+5, 0);
795 croak("i_fountain: XS error");
797 worki[j] = SvIV(*sv2);
799 segs[i].type = worki[0];
800 segs[i].color = worki[1];
806 /* I don't think ICLF_* names belong at the C interface
807 this makes the XS code think we have them, to let us avoid
808 putting function bodies in the XS code
810 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
811 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
813 /* for the fill objects
814 Since a fill object may later have dependent images, (or fills!)
815 we need perl wrappers - oh well
817 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
818 typedef i_fill_t* Imager__FillHandle;
820 /* the m_init_log() function was called init_log(), renamed to reduce
821 potential naming conflicts */
822 #define init_log m_init_log
824 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
827 ICL_new_internal(r,g,b,a)
839 ICL_set_internal(cl,r,g,b,a)
846 ICL_set_internal(cl, r, g, b, a);
860 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
861 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
862 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
863 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
869 RETVAL = mymalloc(sizeof(i_color));
871 i_hsv_to_rgb(RETVAL);
879 RETVAL = mymalloc(sizeof(i_color));
881 i_rgb_to_hsv(RETVAL);
887 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
890 ICLF_new_internal(r, g, b, a)
898 Imager::Color::Float cl
902 Imager::Color::Float cl
906 EXTEND(SP, MAXCHANNELS);
907 for (ch = 0; ch < MAXCHANNELS; ++ch) {
908 /* printf("%d: %g\n", ch, cl->channel[ch]); */
909 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
913 ICLF_set_internal(cl,r,g,b,a)
914 Imager::Color::Float cl
929 Imager::Color::Float c
931 RETVAL = mymalloc(sizeof(i_fcolor));
933 i_hsv_to_rgbf(RETVAL);
939 Imager::Color::Float c
941 RETVAL = mymalloc(sizeof(i_fcolor));
943 i_rgb_to_hsvf(RETVAL);
947 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
961 MODULE = Imager PACKAGE = Imager
982 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
987 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
996 cbd = mymalloc(sizeof(struct cbdata));
997 SvREFCNT_inc(writecb);
998 cbd->writecb = writecb;
999 SvREFCNT_inc(readcb);
1000 cbd->readcb = readcb;
1001 SvREFCNT_inc(seekcb);
1002 cbd->seekcb = seekcb;
1003 SvREFCNT_inc(closecb);
1004 cbd->closecb = closecb;
1005 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1006 if (maxwrite > CBDATA_BUFSIZE)
1007 maxwrite = CBDATA_BUFSIZE;
1008 cbd->maxlength = maxwrite;
1009 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1018 unsigned char* data;
1022 tlength = io_slurp(ig, &data);
1024 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1029 i_set_image_file_limits(width, height, bytes)
1035 i_get_image_file_limits()
1037 int width, height, bytes;
1039 if (i_get_image_file_limits(&width, &height, &bytes)) {
1041 PUSHs(sv_2mortal(newSViv(width)));
1042 PUSHs(sv_2mortal(newSViv(height)));
1043 PUSHs(sv_2mortal(newSViv(bytes)));
1046 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1053 MODULE = Imager PACKAGE = Imager
1066 while( (item=i_format_list[i++]) != NULL ) {
1068 PUSHs(sv_2mortal(newSVpv(item,0)));
1085 i_img_empty_ch(im,x,y,ch)
1092 i_sametype(im, x, y)
1098 i_sametype_chans(im, x, y, channels)
1105 m_init_log(name,level)
1110 log_entry(string,level)
1129 i_img_info(im,info);
1131 PUSHs(sv_2mortal(newSViv(info[0])));
1132 PUSHs(sv_2mortal(newSViv(info[1])));
1133 PUSHs(sv_2mortal(newSViv(info[2])));
1134 PUSHs(sv_2mortal(newSViv(info[3])));
1140 i_img_setmask(im,ch_mask)
1149 i_img_getchannels(im)
1158 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1163 i_line(im,x1,y1,x2,y2,val,endp)
1173 i_line_aa(im,x1,y1,x2,y2,val,endp)
1183 i_box(im,x1,y1,x2,y2,val)
1192 i_box_filled(im,x1,y1,x2,y2,val)
1201 i_box_cfill(im,x1,y1,x2,y2,fill)
1207 Imager::FillHandle fill
1210 i_arc(im,x,y,rad,d1,d2,val)
1220 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1227 Imager::FillHandle fill
1232 i_circle_aa(im,x,y,rad,val)
1242 i_bezier_multi(im,xc,yc,val)
1255 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1256 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1257 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1258 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1259 av1=(AV*)SvRV(ST(1));
1260 av2=(AV*)SvRV(ST(2));
1261 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1263 x=mymalloc( len*sizeof(double) );
1264 y=mymalloc( len*sizeof(double) );
1265 for(i=0;i<len;i++) {
1266 sv1=(*(av_fetch(av1,i,0)));
1267 sv2=(*(av_fetch(av2,i,0)));
1268 x[i]=(double)SvNV(sv1);
1269 y[i]=(double)SvNV(sv2);
1271 i_bezier_multi(im,len,x,y,val);
1277 i_poly_aa(im,xc,yc,val)
1290 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1291 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1292 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1293 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1294 av1=(AV*)SvRV(ST(1));
1295 av2=(AV*)SvRV(ST(2));
1296 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1298 x=mymalloc( len*sizeof(double) );
1299 y=mymalloc( len*sizeof(double) );
1300 for(i=0;i<len;i++) {
1301 sv1=(*(av_fetch(av1,i,0)));
1302 sv2=(*(av_fetch(av2,i,0)));
1303 x[i]=(double)SvNV(sv1);
1304 y[i]=(double)SvNV(sv2);
1306 i_poly_aa(im,len,x,y,val);
1311 i_poly_aa_cfill(im,xc,yc,fill)
1313 Imager::FillHandle fill
1323 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1324 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1325 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1326 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1327 av1=(AV*)SvRV(ST(1));
1328 av2=(AV*)SvRV(ST(2));
1329 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1331 x=mymalloc( len*sizeof(double) );
1332 y=mymalloc( len*sizeof(double) );
1333 for(i=0;i<len;i++) {
1334 sv1=(*(av_fetch(av1,i,0)));
1335 sv2=(*(av_fetch(av2,i,0)));
1336 x[i]=(double)SvNV(sv1);
1337 y[i]=(double)SvNV(sv2);
1339 i_poly_aa_cfill(im,len,x,y,fill);
1346 i_flood_fill(im,seedx,seedy,dcol)
1353 i_flood_cfill(im,seedx,seedy,fill)
1357 Imager::FillHandle fill
1361 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1373 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1391 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1403 i_flipxy(im, direction)
1408 i_rotate90(im, degrees)
1413 i_rotate_exact(im, amount, ...)
1417 i_color *backp = NULL;
1418 i_fcolor *fbackp = NULL;
1422 /* extract the bg colors if any */
1423 /* yes, this is kind of strange */
1424 for (i = 2; i < items; ++i) {
1426 if (sv_derived_from(sv1, "Imager::Color")) {
1427 IV tmp = SvIV((SV*)SvRV(sv1));
1428 backp = INT2PTR(i_color *, tmp);
1430 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1431 IV tmp = SvIV((SV*)SvRV(sv1));
1432 fbackp = INT2PTR(i_fcolor *, tmp);
1435 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1440 i_matrix_transform(im, xsize, ysize, matrix, ...)
1450 i_color *backp = NULL;
1451 i_fcolor *fbackp = NULL;
1453 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1454 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1455 av=(AV*)SvRV(ST(3));
1459 for (i = 0; i < len; ++i) {
1460 sv1=(*(av_fetch(av,i,0)));
1461 matrix[i] = SvNV(sv1);
1465 /* extract the bg colors if any */
1466 /* yes, this is kind of strange */
1467 for (i = 4; i < items; ++i) {
1469 if (sv_derived_from(sv1, "Imager::Color")) {
1470 IV tmp = SvIV((SV*)SvRV(sv1));
1471 backp = INT2PTR(i_color *, tmp);
1473 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1474 IV tmp = SvIV((SV*)SvRV(sv1));
1475 fbackp = INT2PTR(i_fcolor *, tmp);
1478 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1483 i_gaussian(im,stdev)
1488 i_unsharp_mask(im,stdev,scale)
1503 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1504 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1505 av=(AV*)SvRV(ST(1));
1507 coeff=mymalloc( len*sizeof(float) );
1508 for(i=0;i<len;i++) {
1509 sv1=(*(av_fetch(av,i,0)));
1510 coeff[i]=(float)SvNV(sv1);
1512 i_conv(im,coeff,len);
1516 i_convert(im, src, coeff)
1529 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1530 croak("i_convert: parameter 3 must be an arrayref\n");
1531 avmain = (AV*)SvRV(ST(2));
1532 outchan = av_len(avmain)+1;
1533 /* find the biggest */
1535 for (j=0; j < outchan; ++j) {
1536 temp = av_fetch(avmain, j, 0);
1537 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1538 avsub = (AV*)SvRV(*temp);
1539 len = av_len(avsub)+1;
1544 coeff = mymalloc(sizeof(float) * outchan * inchan);
1545 for (j = 0; j < outchan; ++j) {
1546 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1547 len = av_len(avsub)+1;
1548 for (i = 0; i < len; ++i) {
1549 temp = av_fetch(avsub, i, 0);
1551 coeff[i+j*inchan] = SvNV(*temp);
1553 coeff[i+j*inchan] = 0;
1556 coeff[i++ + j*inchan] = 0;
1558 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1568 unsigned int mask = 0;
1574 unsigned char (*maps)[256];
1576 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1577 croak("i_map: parameter 2 must be an arrayref\n");
1578 avmain = (AV*)SvRV(ST(1));
1579 len = av_len(avmain)+1;
1580 if (im->channels < len) len = im->channels;
1582 maps = mymalloc( len * sizeof(unsigned char [256]) );
1584 for (j=0; j<len ; j++) {
1585 temp = av_fetch(avmain, j, 0);
1586 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1587 avsub = (AV*)SvRV(*temp);
1588 if(av_len(avsub) != 255) continue;
1590 for (i=0; i<256 ; i++) {
1592 temp = av_fetch(avsub, i, 0);
1593 val = temp ? SvIV(*temp) : 0;
1595 if (val>255) val = 255;
1600 i_map(im, maps, mask);
1613 i_init_fonts(t1log=0)
1628 i_t1_destroy(font_id)
1633 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1652 str = SvPV(str_sv, len);
1653 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1660 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1669 int cords[BOUNDING_BOX_COUNT];
1677 str = SvPV(str_sv, len);
1678 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1681 for (i = 0; i < rc; ++i)
1682 PUSHs(sv_2mortal(newSViv(cords[i])));
1688 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1707 str = SvPV(str_sv, len);
1708 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1714 i_t1_has_chars(handle, text_sv, utf8 = 0)
1726 if (SvUTF8(text_sv))
1729 text = SvPV(text_sv, len);
1730 work = mymalloc(len);
1731 count = i_t1_has_chars(handle, text, len, utf8, work);
1732 if (GIMME_V == G_ARRAY) {
1734 for (i = 0; i < count; ++i) {
1735 PUSHs(sv_2mortal(newSViv(work[i])));
1740 PUSHs(sv_2mortal(newSVpv(work, count)));
1745 i_t1_face_name(handle)
1751 len = i_t1_face_name(handle, name, sizeof(name));
1754 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1758 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1770 if (SvUTF8(text_sv))
1773 text = SvPV(text_sv, work_len);
1778 ch = i_utf8_advance(&text, &len);
1780 i_push_error(0, "invalid UTF8 character");
1789 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1790 PUSHs(sv_2mortal(newSVpv(name, 0)));
1793 PUSHs(&PL_sv_undef);
1807 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1809 #define TT_DESTROY(handle) i_tt_destroy(handle)
1813 Imager::Font::TT handle
1816 MODULE = Imager PACKAGE = Imager
1820 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1821 Imager::Font::TT handle
1840 str = SvPV(str_sv, len);
1841 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1842 len, smooth, utf8, align);
1848 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1849 Imager::Font::TT handle
1868 str = SvPV(str_sv, len);
1869 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1870 smooth, utf8, align);
1876 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1877 Imager::Font::TT handle
1883 int cords[BOUNDING_BOX_COUNT],rc;
1892 str = SvPV(str_sv, len);
1893 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1895 for (i = 0; i < rc; ++i) {
1896 PUSHs(sv_2mortal(newSViv(cords[i])));
1901 i_tt_has_chars(handle, text_sv, utf8)
1902 Imager::Font::TT handle
1913 if (SvUTF8(text_sv))
1916 text = SvPV(text_sv, len);
1917 work = mymalloc(len);
1918 count = i_tt_has_chars(handle, text, len, utf8, work);
1919 if (GIMME_V == G_ARRAY) {
1921 for (i = 0; i < count; ++i) {
1922 PUSHs(sv_2mortal(newSViv(work[i])));
1927 PUSHs(sv_2mortal(newSVpv(work, count)));
1932 i_tt_dump_names(handle)
1933 Imager::Font::TT handle
1936 i_tt_face_name(handle)
1937 Imager::Font::TT handle
1942 len = i_tt_face_name(handle, name, sizeof(name));
1945 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1949 i_tt_glyph_name(handle, text_sv, utf8 = 0)
1950 Imager::Font::TT handle
1961 if (SvUTF8(text_sv))
1964 text = SvPV(text_sv, work_len);
1969 ch = i_utf8_advance(&text, &len);
1971 i_push_error(0, "invalid UTF8 character");
1980 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
1981 PUSHs(sv_2mortal(newSVpv(name, 0)));
1984 PUSHs(&PL_sv_undef);
1993 i_writejpeg_wiol(im, ig, qfactor)
2009 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2010 if (iptc_itext == NULL) {
2013 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2018 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2020 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2029 i_test_format_probe(ig, length)
2038 i_readtiff_wiol(ig, length, page=0)
2044 i_readtiff_multi_wiol(ig, length)
2052 imgs = i_readtiff_multi_wiol(ig, length, &count);
2055 for (i = 0; i < count; ++i) {
2056 SV *sv = sv_newmortal();
2057 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2065 i_writetiff_wiol(im, ig)
2070 i_writetiff_multi_wiol(ig, ...)
2078 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2079 img_count = items - 1;
2081 if (img_count < 1) {
2084 i_push_error(0, "You need to specify images to save");
2087 imgs = mymalloc(sizeof(i_img *) * img_count);
2088 for (i = 0; i < img_count; ++i) {
2091 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2092 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2096 i_push_error(0, "Only images can be saved");
2103 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2111 i_writetiff_wiol_faxable(im, ig, fine)
2117 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2126 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2127 img_count = items - 2;
2129 if (img_count < 1) {
2132 i_push_error(0, "You need to specify images to save");
2135 imgs = mymalloc(sizeof(i_img *) * img_count);
2136 for (i = 0; i < img_count; ++i) {
2139 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2140 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2144 i_push_error(0, "Only images can be saved");
2151 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2159 #endif /* HAVE_LIBTIFF */
2165 i_readpng_wiol(ig, length)
2171 i_writepng_wiol(im, ig)
2184 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2187 i_writegif(im,fd,colors,pixdev,fixed)
2194 Imager__Color fixed;
2201 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2202 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2203 av=(AV*)SvRV(ST(4));
2204 fixedlen=av_len(av)+1;
2205 fixed=mymalloc( fixedlen*sizeof(i_color) );
2206 for(i=0;i<fixedlen;i++) {
2207 sv1=(*(av_fetch(av,i,0)));
2208 if (sv_derived_from(sv1, "Imager::Color")) {
2209 Itmp = SvIV((SV*)SvRV(sv1));
2210 tmp = INT2PTR(i_color*, Itmp);
2211 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2214 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2216 ST(0) = sv_newmortal();
2217 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2218 else sv_setiv(ST(0), (IV)RETVAL);
2224 i_writegifmc(im,fd,colors)
2231 i_writegif_gen(fd, ...)
2236 i_img **imgs = NULL;
2242 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2243 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2244 croak("i_writegif_gen: Second argument must be a hash ref");
2245 hv = (HV *)SvRV(ST(1));
2246 memset(&quant, 0, sizeof(quant));
2247 quant.mc_size = 256;
2248 handle_quant_opts(&quant, hv);
2249 img_count = items - 2;
2251 if (img_count < 1) {
2254 i_push_error(0, "You need to specify images to save");
2257 imgs = mymalloc(sizeof(i_img *) * img_count);
2258 for (i = 0; i < img_count; ++i) {
2261 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2262 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2266 i_push_error(0, "Only images can be saved");
2272 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2276 copy_colors_back(hv, &quant);
2279 ST(0) = sv_newmortal();
2280 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2281 else sv_setiv(ST(0), (IV)RETVAL);
2282 cleanup_quant_opts(&quant);
2286 i_writegif_callback(cb, maxbuffer,...)
2290 i_img **imgs = NULL;
2297 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2298 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2299 croak("i_writegif_callback: Second argument must be a hash ref");
2300 hv = (HV *)SvRV(ST(2));
2301 memset(&quant, 0, sizeof(quant));
2302 quant.mc_size = 256;
2303 handle_quant_opts(&quant, hv);
2304 img_count = items - 3;
2306 if (img_count < 1) {
2310 imgs = mymalloc(sizeof(i_img *) * img_count);
2311 for (i = 0; i < img_count; ++i) {
2314 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2315 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2324 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2328 copy_colors_back(hv, &quant);
2331 ST(0) = sv_newmortal();
2332 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2333 else sv_setiv(ST(0), (IV)RETVAL);
2334 cleanup_quant_opts(&quant);
2337 i_writegif_wiol(ig, opts,...)
2341 i_img **imgs = NULL;
2347 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2348 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2349 croak("i_writegif_callback: Second argument must be a hash ref");
2350 hv = (HV *)SvRV(ST(1));
2351 memset(&quant, 0, sizeof(quant));
2352 quant.mc_size = 256;
2353 handle_quant_opts(&quant, hv);
2354 img_count = items - 2;
2356 if (img_count < 1) {
2360 imgs = mymalloc(sizeof(i_img *) * img_count);
2361 for (i = 0; i < img_count; ++i) {
2364 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2365 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2373 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2377 copy_colors_back(hv, &quant);
2380 ST(0) = sv_newmortal();
2381 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2382 else sv_setiv(ST(0), (IV)RETVAL);
2383 cleanup_quant_opts(&quant);
2396 colour_table = NULL;
2399 if(GIMME_V == G_ARRAY) {
2400 rimg = i_readgif(fd,&colour_table,&colours);
2402 /* don't waste time with colours if they aren't wanted */
2403 rimg = i_readgif(fd,NULL,NULL);
2406 if (colour_table == NULL) {
2409 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2412 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2413 /* I don't know if I have the reference counts right or not :( */
2414 /* Neither do I :-) */
2415 /* No Idea here either */
2418 av_extend(ct, colours);
2419 for(q=0; q<colours; q++) {
2421 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2422 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2424 myfree(colour_table);
2428 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2430 PUSHs(newRV_noinc((SV*)ct));
2444 colour_table = NULL;
2447 if(GIMME_V == G_ARRAY) {
2448 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2450 /* don't waste time with colours if they aren't wanted */
2451 rimg = i_readgif_wiol(ig,NULL,NULL);
2454 if (colour_table == NULL) {
2457 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2460 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2461 /* I don't know if I have the reference counts right or not :( */
2462 /* Neither do I :-) */
2463 /* No Idea here either */
2466 av_extend(ct, colours);
2467 for(q=0; q<colours; q++) {
2469 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2470 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2472 myfree(colour_table);
2476 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2478 PUSHs(newRV_noinc((SV*)ct));
2482 i_readgif_scalar(...)
2494 data = (char *)SvPV(ST(0), length);
2498 if(GIMME_V == G_ARRAY) {
2499 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2501 /* don't waste time with colours if they aren't wanted */
2502 rimg=i_readgif_scalar(data,length,NULL,NULL);
2505 if (colour_table == NULL) {
2508 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2511 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2512 /* I don't know if I have the reference counts right or not :( */
2513 /* Neither do I :-) */
2515 av_extend(ct, colours);
2516 for(q=0; q<colours; q++) {
2518 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2519 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2521 myfree(colour_table);
2525 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2527 PUSHs(newRV_noinc((SV*)ct));
2531 i_readgif_callback(...)
2546 if(GIMME_V == G_ARRAY) {
2547 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2549 /* don't waste time with colours if they aren't wanted */
2550 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2553 if (colour_table == NULL) {
2556 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2559 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2560 /* I don't know if I have the reference counts right or not :( */
2561 /* Neither do I :-) */
2562 /* Neither do I - maybe I'll move this somewhere */
2564 av_extend(ct, colours);
2565 for(q=0; q<colours; q++) {
2567 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2568 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2570 myfree(colour_table);
2574 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2576 PUSHs(newRV_noinc((SV*)ct));
2587 imgs = i_readgif_multi(fd, &count);
2590 for (i = 0; i < count; ++i) {
2591 SV *sv = sv_newmortal();
2592 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2599 i_readgif_multi_scalar(data)
2607 data = (char *)SvPV(ST(0), length);
2608 imgs = i_readgif_multi_scalar(data, length, &count);
2611 for (i = 0; i < count; ++i) {
2612 SV *sv = sv_newmortal();
2613 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2620 i_readgif_multi_callback(cb)
2628 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2631 for (i = 0; i < count; ++i) {
2632 SV *sv = sv_newmortal();
2633 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2640 i_readgif_multi_wiol(ig)
2647 imgs = i_readgif_multi_wiol(ig, &count);
2650 for (i = 0; i < count; ++i) {
2651 SV *sv = sv_newmortal();
2652 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2664 i_readpnm_wiol(ig, length)
2670 i_writeppm_wiol(im, ig)
2676 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2685 i_writeraw_wiol(im,ig)
2690 i_writebmp_wiol(im,ig)
2700 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2709 idlen = SvCUR(ST(4));
2710 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2716 i_readtga_wiol(ig, length)
2722 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2731 idlen = SvCUR(ST(4));
2732 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2738 i_readrgb_wiol(ig, length)
2745 i_scaleaxis(im,Value,Axis)
2751 i_scale_nn(im,scx,scy)
2761 i_count_colors(im,maxc)
2767 i_transform(im,opx,opy,parm)
2780 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2781 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2782 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2783 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2784 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2785 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2786 av=(AV*)SvRV(ST(1));
2788 opx=mymalloc( opxl*sizeof(int) );
2789 for(i=0;i<opxl;i++) {
2790 sv1=(*(av_fetch(av,i,0)));
2791 opx[i]=(int)SvIV(sv1);
2793 av=(AV*)SvRV(ST(2));
2795 opy=mymalloc( opyl*sizeof(int) );
2796 for(i=0;i<opyl;i++) {
2797 sv1=(*(av_fetch(av,i,0)));
2798 opy[i]=(int)SvIV(sv1);
2800 av=(AV*)SvRV(ST(3));
2801 parmlen=av_len(av)+1;
2802 parm=mymalloc( parmlen*sizeof(double) );
2803 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2804 sv1=(*(av_fetch(av,i,0)));
2805 parm[i]=(double)SvNV(sv1);
2807 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2811 ST(0) = sv_newmortal();
2812 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2813 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2816 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2841 in_imgs_count = av_len(av_in_imgs)+1;
2842 for (i = 0; i < in_imgs_count; ++i) {
2843 sv1 = *av_fetch(av_in_imgs, i, 0);
2844 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2845 croak("sv_in_img must contain only images");
2848 if (in_imgs_count > 0) {
2849 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2850 for (i = 0; i < in_imgs_count; ++i) {
2851 sv1 = *av_fetch(av_in_imgs,i,0);
2852 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2853 croak("Parameter 5 must contain only images");
2855 tmp = SvIV((SV*)SvRV(sv1));
2856 in_imgs[i] = INT2PTR(i_img*, tmp);
2860 /* no input images */
2863 /* default the output size from the first input if possible */
2865 width = SvIV(sv_width);
2866 else if (in_imgs_count)
2867 width = in_imgs[0]->xsize;
2869 croak("No output image width supplied");
2871 if (SvOK(sv_height))
2872 height = SvIV(sv_height);
2873 else if (in_imgs_count)
2874 height = in_imgs[0]->ysize;
2876 croak("No output image height supplied");
2878 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2879 if (ops_len % sizeof(struct rm_op))
2880 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2881 ops_count = ops_len / sizeof(struct rm_op);
2883 n_regs_count = av_len(av_n_regs)+1;
2884 n_regs = mymalloc(n_regs_count * sizeof(double));
2885 for (i = 0; i < n_regs_count; ++i) {
2886 sv1 = *av_fetch(av_n_regs,i,0);
2888 n_regs[i] = SvNV(sv1);
2890 c_regs_count = av_len(av_c_regs)+1;
2891 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2892 /* I don't bother initializing the colou?r registers */
2894 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2895 n_regs, n_regs_count,
2896 c_regs, c_regs_count, in_imgs, in_imgs_count);
2901 ST(0) = sv_newmortal();
2902 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2903 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2907 i_contrast(im,intensity)
2916 i_noise(im,amount,type)
2922 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2932 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2951 i_postlevels(im,levels)
2961 i_watermark(im,wmark,tx,ty,pixdiff)
2963 Imager::ImgRaw wmark
2970 i_autolevels(im,lsat,usat,skew)
2977 i_radnoise(im,xo,yo,rscale,ascale)
2985 i_turbnoise(im, xo, yo, scale)
3008 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3009 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3010 croak("i_gradgen: Second argument must be an array ref");
3011 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3012 croak("i_gradgen: Third argument must be an array ref");
3013 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3014 croak("i_gradgen: Fourth argument must be an array ref");
3015 axx = (AV *)SvRV(ST(1));
3016 ayy = (AV *)SvRV(ST(2));
3017 ac = (AV *)SvRV(ST(3));
3018 dmeasure = (int)SvIV(ST(4));
3020 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3021 num = num <= av_len(ac) ? num : av_len(ac);
3023 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3024 xo = mymalloc( sizeof(int) * num );
3025 yo = mymalloc( sizeof(int) * num );
3026 ival = mymalloc( sizeof(i_color) * num );
3027 for(i = 0; i<num; i++) {
3028 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3029 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3030 sv = *av_fetch(ac, i, 0);
3031 if ( !sv_derived_from(sv, "Imager::Color") ) {
3032 free(axx); free(ayy); free(ac);
3033 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3035 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3037 i_gradgen(im, num, xo, yo, ival, dmeasure);
3043 i_diff_image(im, im2, mindist=0)
3049 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3059 double ssample_param
3063 i_fountain_seg *segs;
3065 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3066 croak("i_fountain: argument 11 must be an array ref");
3068 asegs = (AV *)SvRV(ST(10));
3069 segs = load_fount_segs(asegs, &count);
3070 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3071 ssample_param, count, segs);
3075 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3084 double ssample_param
3088 i_fountain_seg *segs;
3090 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3091 croak("i_fountain: argument 11 must be an array ref");
3093 asegs = (AV *)SvRV(ST(9));
3094 segs = load_fount_segs(asegs, &count);
3095 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3096 super_sample, ssample_param, count, segs);
3109 errors = i_errors();
3111 while (errors[i].msg) {
3113 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3114 if (!av_store(av, 0, sv)) {
3117 sv = newSViv(errors[i].code);
3118 if (!av_store(av, 1, sv)) {
3121 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3126 i_nearest_color(im, ...)
3141 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3142 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3143 croak("i_nearest_color: Second argument must be an array ref");
3144 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3145 croak("i_nearest_color: Third argument must be an array ref");
3146 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3147 croak("i_nearest_color: Fourth argument must be an array ref");
3148 axx = (AV *)SvRV(ST(1));
3149 ayy = (AV *)SvRV(ST(2));
3150 ac = (AV *)SvRV(ST(3));
3151 dmeasure = (int)SvIV(ST(4));
3153 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3154 num = num <= av_len(ac) ? num : av_len(ac);
3156 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3157 xo = mymalloc( sizeof(int) * num );
3158 yo = mymalloc( sizeof(int) * num );
3159 ival = mymalloc( sizeof(i_color) * num );
3160 for(i = 0; i<num; i++) {
3161 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3162 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3163 sv = *av_fetch(ac, i, 0);
3164 if ( !sv_derived_from(sv, "Imager::Color") ) {
3165 free(axx); free(ayy); free(ac);
3166 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3168 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3170 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3184 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3185 hv=(HV*)SvRV(ST(0));
3186 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3187 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3188 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3197 rc=DSO_open(filename,&evstr);
3201 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3202 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3205 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3211 DSO_close(dso_handle)
3215 DSO_funclist(dso_handle_v)
3219 DSO_handle *dso_handle;
3221 dso_handle=(DSO_handle*)dso_handle_v;
3223 while( dso_handle->function_list[i].name != NULL) {
3225 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3227 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3232 DSO_call(handle,func_index,hv)
3238 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3239 hv=(HV*)SvRV(ST(2));
3240 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3241 DSO_call( (DSO_handle *)handle,func_index,hv);
3246 i_get_pixel(im, x, y)
3253 color = (i_color *)mymalloc(sizeof(i_color));
3254 if (i_gpix(im, x, y, color) == 0) {
3255 RETVAL = NEWSV(0, 0);
3256 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3260 RETVAL = &PL_sv_undef;
3267 i_ppix(im, x, y, cl)
3274 i_img_pal_new(x, y, channels, maxpal)
3281 i_img_to_pal(src, quant)
3287 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3288 croak("i_img_to_pal: second argument must be a hash ref");
3289 hv = (HV *)SvRV(ST(1));
3290 memset(&quant, 0, sizeof(quant));
3291 quant.mc_size = 256;
3292 handle_quant_opts(&quant, hv);
3293 RETVAL = i_img_to_pal(src, &quant);
3295 copy_colors_back(hv, &quant);
3297 cleanup_quant_opts(&quant);
3316 work = mymalloc((r-l) * sizeof(i_palidx));
3317 count = i_gpal(im, l, r, y, work);
3318 if (GIMME_V == G_ARRAY) {
3320 for (i = 0; i < count; ++i) {
3321 PUSHs(sv_2mortal(newSViv(work[i])));
3326 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3331 if (GIMME_V != G_ARRAY) {
3333 PUSHs(&PL_sv_undef);
3338 i_ppal(im, l, y, ...)
3347 work = mymalloc(sizeof(i_palidx) * (items-3));
3348 for (i=0; i < items-3; ++i) {
3349 work[i] = SvIV(ST(i+3));
3351 RETVAL = i_ppal(im, l, l+items-3, y, work);
3361 i_addcolors(im, ...)
3369 croak("i_addcolors: no colors to add");
3370 colors = mymalloc((items-1) * sizeof(i_color));
3371 for (i=0; i < items-1; ++i) {
3372 if (sv_isobject(ST(i+1))
3373 && sv_derived_from(ST(i+1), "Imager::Color")) {
3374 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3375 colors[i] = *INT2PTR(i_color *, tmp);
3379 croak("i_addcolor: pixels must be Imager::Color objects");
3382 index = i_addcolors(im, colors, items-1);
3385 RETVAL = newSVpv("0 but true", 0);
3387 else if (index == -1) {
3388 RETVAL = &PL_sv_undef;
3391 RETVAL = newSViv(index);
3397 i_setcolors(im, index, ...)
3405 croak("i_setcolors: no colors to add");
3406 colors = mymalloc((items-2) * sizeof(i_color));
3407 for (i=0; i < items-2; ++i) {
3408 if (sv_isobject(ST(i+2))
3409 && sv_derived_from(ST(i+2), "Imager::Color")) {
3410 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3411 colors[i] = *INT2PTR(i_color *, tmp);
3415 croak("i_setcolors: pixels must be Imager::Color objects");
3418 RETVAL = i_setcolors(im, index, colors, items-2);
3424 i_getcolors(im, index, ...)
3433 croak("i_getcolors: too many arguments");
3435 count = SvIV(ST(2));
3437 croak("i_getcolors: count must be positive");
3438 colors = mymalloc(sizeof(i_color) * count);
3439 if (i_getcolors(im, index, colors, count)) {
3440 for (i = 0; i < count; ++i) {
3442 SV *sv = sv_newmortal();
3443 pv = mymalloc(sizeof(i_color));
3445 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3461 i_findcolor(im, color)
3467 if (i_findcolor(im, color, &index)) {
3468 RETVAL = newSViv(index);
3471 RETVAL = &PL_sv_undef;
3489 i_gsamp(im, l, r, y, ...)
3501 croak("No channel numbers supplied to g_samp()");
3503 chan_count = items - 4;
3504 chans = mymalloc(sizeof(int) * chan_count);
3505 for (i = 0; i < chan_count; ++i)
3506 chans[i] = SvIV(ST(i+4));
3507 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3508 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3510 if (GIMME_V == G_ARRAY) {
3512 for (i = 0; i < count; ++i)
3513 PUSHs(sv_2mortal(newSViv(data[i])));
3517 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3522 if (GIMME_V != G_ARRAY) {
3524 PUSHs(&PL_sv_undef);
3530 i_img_masked_new(targ, mask, x, y, w, h)
3540 if (!sv_isobject(ST(1))
3541 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3542 croak("i_img_masked_new: parameter 2 must undef or an image");
3544 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3548 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3553 i_plin(im, l, y, ...)
3564 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3565 /* supplied as a byte string */
3566 work = (i_color *)SvPV(ST(3), len);
3567 count = len / sizeof(i_color);
3568 if (count * sizeof(i_color) != len) {
3569 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3571 RETVAL = i_plin(im, l, l+count, y, work);
3574 work = mymalloc(sizeof(i_color) * (items-3));
3575 for (i=0; i < items-3; ++i) {
3576 if (sv_isobject(ST(i+3))
3577 && sv_derived_from(ST(i+3), "Imager::Color")) {
3578 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3579 work[i] = *INT2PTR(i_color *, tmp);
3583 croak("i_plin: pixels must be Imager::Color objects");
3586 RETVAL = i_plin(im, l, l+items-3, y, work);
3597 i_ppixf(im, x, y, cl)
3601 Imager::Color::Float cl
3604 i_gsampf(im, l, r, y, ...)
3616 croak("No channel numbers supplied to g_sampf()");
3618 chan_count = items - 4;
3619 chans = mymalloc(sizeof(int) * chan_count);
3620 for (i = 0; i < chan_count; ++i)
3621 chans[i] = SvIV(ST(i+4));
3622 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3623 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3624 if (GIMME_V == G_ARRAY) {
3626 for (i = 0; i < count; ++i)
3627 PUSHs(sv_2mortal(newSVnv(data[i])));
3631 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3635 if (GIMME_V != G_ARRAY) {
3637 PUSHs(&PL_sv_undef);
3642 i_plinf(im, l, y, ...)
3653 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3654 /* supplied as a byte string */
3655 work = (i_fcolor *)SvPV(ST(3), len);
3656 count = len / sizeof(i_fcolor);
3657 if (count * sizeof(i_fcolor) != len) {
3658 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3660 RETVAL = i_plinf(im, l, l+count, y, work);
3663 work = mymalloc(sizeof(i_fcolor) * (items-3));
3664 for (i=0; i < items-3; ++i) {
3665 if (sv_isobject(ST(i+3))
3666 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3667 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3668 work[i] = *INT2PTR(i_fcolor *, tmp);
3672 croak("i_plinf: pixels must be Imager::Color::Float objects");
3676 RETVAL = i_plinf(im, l, l+items-3, y, work);
3694 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3695 if (i_gpixf(im, x, y, color) == 0) {
3696 RETVAL = NEWSV(0,0);
3697 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3701 RETVAL = &PL_sv_undef;
3717 vals = mymalloc((r-l) * sizeof(i_color));
3718 count = i_glin(im, l, r, y, vals);
3719 if (GIMME_V == G_ARRAY) {
3721 for (i = 0; i < count; ++i) {
3723 i_color *col = mymalloc(sizeof(i_color));
3725 sv = sv_newmortal();
3726 sv_setref_pv(sv, "Imager::Color", (void *)col);
3732 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3738 i_glinf(im, l, r, y)
3748 vals = mymalloc((r-l) * sizeof(i_fcolor));
3749 count = i_glinf(im, l, r, y, vals);
3750 if (GIMME_V == G_ARRAY) {
3752 for (i = 0; i < count; ++i) {
3754 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3756 sv = sv_newmortal();
3757 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3763 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3769 i_img_16_new(x, y, ch)
3775 i_img_double_new(x, y, ch)
3781 i_tags_addn(im, name, code, idata)
3790 name = SvPV(ST(1), len);
3793 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3798 i_tags_add(im, name, code, data, idata)
3808 name = SvPV(ST(1), len);
3812 data = SvPV(ST(3), len);
3817 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3822 i_tags_find(im, name, start)
3829 if (i_tags_find(&im->tags, name, start, &entry)) {
3831 RETVAL = newSVpv("0 but true", 0);
3833 RETVAL = newSViv(entry);
3835 RETVAL = &PL_sv_undef;
3841 i_tags_findn(im, code, start)
3848 if (i_tags_findn(&im->tags, code, start, &entry)) {
3850 RETVAL = newSVpv("0 but true", 0);
3852 RETVAL = newSViv(entry);
3855 RETVAL = &PL_sv_undef;
3861 i_tags_delete(im, entry)
3865 RETVAL = i_tags_delete(&im->tags, entry);
3870 i_tags_delbyname(im, name)
3874 RETVAL = i_tags_delbyname(&im->tags, name);
3879 i_tags_delbycode(im, code)
3883 RETVAL = i_tags_delbycode(&im->tags, code);
3888 i_tags_get(im, index)
3892 if (index >= 0 && index < im->tags.count) {
3893 i_img_tag *entry = im->tags.tags + index;
3897 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3900 PUSHs(sv_2mortal(newSViv(entry->code)));
3903 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3906 PUSHs(sv_2mortal(newSViv(entry->idata)));
3911 i_tags_get_string(im, what_sv)
3915 char const *name = NULL;
3919 if (SvIOK(what_sv)) {
3920 code = SvIV(what_sv);
3924 name = SvPV_nolen(what_sv);
3927 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3929 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3936 RETVAL = im->tags.count;
3943 i_wf_bbox(face, size, text)
3948 int cords[BOUNDING_BOX_COUNT];
3951 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3953 for (i = 0; i < rc; ++i)
3954 PUSHs(sv_2mortal(newSViv(cords[i])));
3958 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3969 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3975 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3986 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3999 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4001 #define FT2_DESTROY(font) i_ft2_destroy(font)
4005 Imager::Font::FT2 font
4007 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4010 i_ft2_new(name, index)
4015 i_ft2_setdpi(font, xdpi, ydpi)
4016 Imager::Font::FT2 font
4022 Imager::Font::FT2 font
4026 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4028 PUSHs(sv_2mortal(newSViv(xdpi)));
4029 PUSHs(sv_2mortal(newSViv(ydpi)));
4033 i_ft2_sethinting(font, hinting)
4034 Imager::Font::FT2 font
4038 i_ft2_settransform(font, matrix)
4039 Imager::Font::FT2 font
4047 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4048 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4049 av=(AV*)SvRV(ST(1));
4053 for (i = 0; i < len; ++i) {
4054 sv1=(*(av_fetch(av,i,0)));
4055 matrix[i] = SvNV(sv1);
4059 RETVAL = i_ft2_settransform(font, matrix);
4064 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4065 Imager::Font::FT2 font
4071 int bbox[BOUNDING_BOX_COUNT];
4077 text = SvPV(text_sv, text_len);
4079 if (SvUTF8(text_sv))
4082 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4085 for (i = 0; i < rc; ++i)
4086 PUSHs(sv_2mortal(newSViv(bbox[i])));
4090 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4091 Imager::Font::FT2 font
4105 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4108 for (i = 0; i < 8; ++i)
4109 PUSHs(sv_2mortal(newSViv(bbox[i])));
4113 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4114 Imager::Font::FT2 font
4130 if (SvUTF8(ST(7))) {
4134 text = SvPV(ST(7), len);
4135 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4136 len, align, aa, vlayout, utf8);
4141 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4142 Imager::Font::FT2 font
4159 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4160 strlen(text), align, aa, vlayout, 1);
4165 ft2_transform_box(font, x0, x1, x2, x3)
4166 Imager::Font::FT2 font
4174 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4175 ft2_transform_box(font, box);
4177 PUSHs(sv_2mortal(newSViv(box[0])));
4178 PUSHs(sv_2mortal(newSViv(box[1])));
4179 PUSHs(sv_2mortal(newSViv(box[2])));
4180 PUSHs(sv_2mortal(newSViv(box[3])));
4183 i_ft2_has_chars(handle, text_sv, utf8)
4184 Imager::Font::FT2 handle
4195 if (SvUTF8(text_sv))
4198 text = SvPV(text_sv, len);
4199 work = mymalloc(len);
4200 count = i_ft2_has_chars(handle, text, len, utf8, work);
4201 if (GIMME_V == G_ARRAY) {
4203 for (i = 0; i < count; ++i) {
4204 PUSHs(sv_2mortal(newSViv(work[i])));
4209 PUSHs(sv_2mortal(newSVpv(work, count)));
4214 i_ft2_face_name(handle)
4215 Imager::Font::FT2 handle
4220 len = i_ft2_face_name(handle, name, sizeof(name));
4223 PUSHs(sv_2mortal(newSVpv(name, 0)));
4227 i_ft2_can_face_name()
4230 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4231 Imager::Font::FT2 handle
4243 if (SvUTF8(text_sv))
4246 text = SvPV(text_sv, work_len);
4251 ch = i_utf8_advance(&text, &len);
4253 i_push_error(0, "invalid UTF8 character");
4262 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4264 PUSHs(sv_2mortal(newSVpv(name, 0)));
4267 PUSHs(&PL_sv_undef);
4272 i_ft2_can_do_glyph_names()
4275 i_ft2_face_has_glyph_names(handle)
4276 Imager::Font::FT2 handle
4279 i_ft2_is_multiple_master(handle)
4280 Imager::Font::FT2 handle
4283 i_ft2_get_multiple_masters(handle)
4284 Imager::Font::FT2 handle
4289 if (i_ft2_get_multiple_masters(handle, &mm)) {
4290 EXTEND(SP, 2+mm.num_axis);
4291 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4292 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4293 for (i = 0; i < mm.num_axis; ++i) {
4297 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4299 av_store(av, 0, sv);
4300 sv = newSViv(mm.axis[i].minimum);
4302 av_store(av, 1, sv);
4303 sv = newSViv(mm.axis[i].maximum);
4305 av_store(av, 2, sv);
4306 PUSHs(newRV_noinc((SV *)av));
4311 i_ft2_set_mm_coords(handle, ...)
4312 Imager::Font::FT2 handle
4318 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4319 transfer the array manually */
4320 ix_coords = items-1;
4321 coords = mymalloc(sizeof(long) * ix_coords);
4322 for (i = 0; i < ix_coords; ++i) {
4323 coords[i] = (long)SvIV(ST(1+i));
4325 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4332 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4336 Imager::FillHandle fill
4338 MODULE = Imager PACKAGE = Imager
4341 i_new_fill_solid(cl, combine)
4346 i_new_fill_solidf(cl, combine)
4347 Imager::Color::Float cl
4351 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4359 unsigned char *cust_hatch;
4363 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4367 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4372 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4373 Imager::Color::Float fg
4374 Imager::Color::Float bg
4380 unsigned char *cust_hatch;
4384 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4388 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4393 i_new_fill_image(src, matrix, xoff, yoff, combine)
4410 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4411 croak("i_new_fill_image: parameter must be an arrayref");
4412 av=(AV*)SvRV(ST(1));
4416 for (i = 0; i < len; ++i) {
4417 sv1=(*(av_fetch(av,i,0)));
4418 matrix[i] = SvNV(sv1);
4424 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);