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);
948 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
962 MODULE = Imager PACKAGE = Imager
983 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
988 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
997 cbd = mymalloc(sizeof(struct cbdata));
998 SvREFCNT_inc(writecb);
999 cbd->writecb = writecb;
1000 SvREFCNT_inc(readcb);
1001 cbd->readcb = readcb;
1002 SvREFCNT_inc(seekcb);
1003 cbd->seekcb = seekcb;
1004 SvREFCNT_inc(closecb);
1005 cbd->closecb = closecb;
1006 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1007 if (maxwrite > CBDATA_BUFSIZE)
1008 maxwrite = CBDATA_BUFSIZE;
1009 cbd->maxlength = maxwrite;
1010 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1019 unsigned char* data;
1023 tlength = io_slurp(ig, &data);
1025 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1029 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1036 MODULE = Imager PACKAGE = Imager
1049 while( (item=i_format_list[i++]) != NULL ) {
1051 PUSHs(sv_2mortal(newSVpv(item,0)));
1068 i_img_empty_ch(im,x,y,ch)
1075 i_sametype(im, x, y)
1081 i_sametype_chans(im, x, y, channels)
1088 m_init_log(name,level)
1093 log_entry(string,level)
1112 i_img_info(im,info);
1114 PUSHs(sv_2mortal(newSViv(info[0])));
1115 PUSHs(sv_2mortal(newSViv(info[1])));
1116 PUSHs(sv_2mortal(newSViv(info[2])));
1117 PUSHs(sv_2mortal(newSViv(info[3])));
1123 i_img_setmask(im,ch_mask)
1132 i_img_getchannels(im)
1141 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1146 i_line(im,x1,y1,x2,y2,val,endp)
1156 i_line_aa(im,x1,y1,x2,y2,val,endp)
1166 i_box(im,x1,y1,x2,y2,val)
1175 i_box_filled(im,x1,y1,x2,y2,val)
1184 i_box_cfill(im,x1,y1,x2,y2,fill)
1190 Imager::FillHandle fill
1193 i_arc(im,x,y,rad,d1,d2,val)
1203 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1210 Imager::FillHandle fill
1215 i_circle_aa(im,x,y,rad,val)
1225 i_bezier_multi(im,xc,yc,val)
1238 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1239 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1240 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1241 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1242 av1=(AV*)SvRV(ST(1));
1243 av2=(AV*)SvRV(ST(2));
1244 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1246 x=mymalloc( len*sizeof(double) );
1247 y=mymalloc( len*sizeof(double) );
1248 for(i=0;i<len;i++) {
1249 sv1=(*(av_fetch(av1,i,0)));
1250 sv2=(*(av_fetch(av2,i,0)));
1251 x[i]=(double)SvNV(sv1);
1252 y[i]=(double)SvNV(sv2);
1254 i_bezier_multi(im,len,x,y,val);
1260 i_poly_aa(im,xc,yc,val)
1273 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1274 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1275 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1276 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1277 av1=(AV*)SvRV(ST(1));
1278 av2=(AV*)SvRV(ST(2));
1279 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1281 x=mymalloc( len*sizeof(double) );
1282 y=mymalloc( len*sizeof(double) );
1283 for(i=0;i<len;i++) {
1284 sv1=(*(av_fetch(av1,i,0)));
1285 sv2=(*(av_fetch(av2,i,0)));
1286 x[i]=(double)SvNV(sv1);
1287 y[i]=(double)SvNV(sv2);
1289 i_poly_aa(im,len,x,y,val);
1294 i_poly_aa_cfill(im,xc,yc,fill)
1296 Imager::FillHandle fill
1306 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1307 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1308 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1309 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1310 av1=(AV*)SvRV(ST(1));
1311 av2=(AV*)SvRV(ST(2));
1312 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1314 x=mymalloc( len*sizeof(double) );
1315 y=mymalloc( len*sizeof(double) );
1316 for(i=0;i<len;i++) {
1317 sv1=(*(av_fetch(av1,i,0)));
1318 sv2=(*(av_fetch(av2,i,0)));
1319 x[i]=(double)SvNV(sv1);
1320 y[i]=(double)SvNV(sv2);
1322 i_poly_aa_cfill(im,len,x,y,fill);
1329 i_flood_fill(im,seedx,seedy,dcol)
1336 i_flood_cfill(im,seedx,seedy,fill)
1340 Imager::FillHandle fill
1344 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1356 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1374 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1386 i_flipxy(im, direction)
1391 i_rotate90(im, degrees)
1396 i_rotate_exact(im, amount, ...)
1400 i_color *backp = NULL;
1401 i_fcolor *fbackp = NULL;
1405 /* extract the bg colors if any */
1406 /* yes, this is kind of strange */
1407 for (i = 2; i < items; ++i) {
1409 if (sv_derived_from(sv1, "Imager::Color")) {
1410 IV tmp = SvIV((SV*)SvRV(sv1));
1411 backp = INT2PTR(i_color *, tmp);
1413 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1414 IV tmp = SvIV((SV*)SvRV(sv1));
1415 fbackp = INT2PTR(i_fcolor *, tmp);
1418 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1423 i_matrix_transform(im, xsize, ysize, matrix, ...)
1433 i_color *backp = NULL;
1434 i_fcolor *fbackp = NULL;
1436 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1437 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1438 av=(AV*)SvRV(ST(3));
1442 for (i = 0; i < len; ++i) {
1443 sv1=(*(av_fetch(av,i,0)));
1444 matrix[i] = SvNV(sv1);
1448 /* extract the bg colors if any */
1449 /* yes, this is kind of strange */
1450 for (i = 4; i < items; ++i) {
1452 if (sv_derived_from(sv1, "Imager::Color")) {
1453 IV tmp = SvIV((SV*)SvRV(sv1));
1454 backp = INT2PTR(i_color *, tmp);
1456 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1457 IV tmp = SvIV((SV*)SvRV(sv1));
1458 fbackp = INT2PTR(i_fcolor *, tmp);
1461 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1466 i_gaussian(im,stdev)
1471 i_unsharp_mask(im,stdev,scale)
1486 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1487 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1488 av=(AV*)SvRV(ST(1));
1490 coeff=mymalloc( len*sizeof(float) );
1491 for(i=0;i<len;i++) {
1492 sv1=(*(av_fetch(av,i,0)));
1493 coeff[i]=(float)SvNV(sv1);
1495 i_conv(im,coeff,len);
1499 i_convert(im, src, coeff)
1512 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1513 croak("i_convert: parameter 3 must be an arrayref\n");
1514 avmain = (AV*)SvRV(ST(2));
1515 outchan = av_len(avmain)+1;
1516 /* find the biggest */
1518 for (j=0; j < outchan; ++j) {
1519 temp = av_fetch(avmain, j, 0);
1520 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1521 avsub = (AV*)SvRV(*temp);
1522 len = av_len(avsub)+1;
1527 coeff = mymalloc(sizeof(float) * outchan * inchan);
1528 for (j = 0; j < outchan; ++j) {
1529 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1530 len = av_len(avsub)+1;
1531 for (i = 0; i < len; ++i) {
1532 temp = av_fetch(avsub, i, 0);
1534 coeff[i+j*inchan] = SvNV(*temp);
1536 coeff[i+j*inchan] = 0;
1539 coeff[i++ + j*inchan] = 0;
1541 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1551 unsigned int mask = 0;
1557 unsigned char (*maps)[256];
1559 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1560 croak("i_map: parameter 2 must be an arrayref\n");
1561 avmain = (AV*)SvRV(ST(1));
1562 len = av_len(avmain)+1;
1563 if (im->channels < len) len = im->channels;
1565 maps = mymalloc( len * sizeof(unsigned char [256]) );
1567 for (j=0; j<len ; j++) {
1568 temp = av_fetch(avmain, j, 0);
1569 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1570 avsub = (AV*)SvRV(*temp);
1571 if(av_len(avsub) != 255) continue;
1573 for (i=0; i<256 ; i++) {
1575 temp = av_fetch(avsub, i, 0);
1576 val = temp ? SvIV(*temp) : 0;
1578 if (val>255) val = 255;
1583 i_map(im, maps, mask);
1596 i_init_fonts(t1log=0)
1611 i_t1_destroy(font_id)
1616 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1635 str = SvPV(str_sv, len);
1636 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1643 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1652 int cords[BOUNDING_BOX_COUNT];
1660 str = SvPV(str_sv, len);
1661 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1664 for (i = 0; i < rc; ++i)
1665 PUSHs(sv_2mortal(newSViv(cords[i])));
1671 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1690 str = SvPV(str_sv, len);
1691 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1697 i_t1_has_chars(handle, text_sv, utf8 = 0)
1709 if (SvUTF8(text_sv))
1712 text = SvPV(text_sv, len);
1713 work = mymalloc(len);
1714 count = i_t1_has_chars(handle, text, len, utf8, work);
1715 if (GIMME_V == G_ARRAY) {
1717 for (i = 0; i < count; ++i) {
1718 PUSHs(sv_2mortal(newSViv(work[i])));
1723 PUSHs(sv_2mortal(newSVpv(work, count)));
1728 i_t1_face_name(handle)
1734 len = i_t1_face_name(handle, name, sizeof(name));
1737 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1741 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1753 if (SvUTF8(text_sv))
1756 text = SvPV(text_sv, work_len);
1761 ch = i_utf8_advance(&text, &len);
1763 i_push_error(0, "invalid UTF8 character");
1772 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1773 PUSHs(sv_2mortal(newSVpv(name, 0)));
1776 PUSHs(&PL_sv_undef);
1790 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1792 #define TT_DESTROY(handle) i_tt_destroy(handle)
1796 Imager::Font::TT handle
1799 MODULE = Imager PACKAGE = Imager
1803 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1804 Imager::Font::TT handle
1823 str = SvPV(str_sv, len);
1824 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1825 len, smooth, utf8, align);
1831 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1832 Imager::Font::TT handle
1851 str = SvPV(str_sv, len);
1852 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1853 smooth, utf8, align);
1859 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1860 Imager::Font::TT handle
1866 int cords[BOUNDING_BOX_COUNT],rc;
1875 str = SvPV(str_sv, len);
1876 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1878 for (i = 0; i < rc; ++i) {
1879 PUSHs(sv_2mortal(newSViv(cords[i])));
1884 i_tt_has_chars(handle, text_sv, utf8)
1885 Imager::Font::TT handle
1896 if (SvUTF8(text_sv))
1899 text = SvPV(text_sv, len);
1900 work = mymalloc(len);
1901 count = i_tt_has_chars(handle, text, len, utf8, work);
1902 if (GIMME_V == G_ARRAY) {
1904 for (i = 0; i < count; ++i) {
1905 PUSHs(sv_2mortal(newSViv(work[i])));
1910 PUSHs(sv_2mortal(newSVpv(work, count)));
1915 i_tt_dump_names(handle)
1916 Imager::Font::TT handle
1919 i_tt_face_name(handle)
1920 Imager::Font::TT handle
1925 len = i_tt_face_name(handle, name, sizeof(name));
1928 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1932 i_tt_glyph_name(handle, text_sv, utf8 = 0)
1933 Imager::Font::TT handle
1944 if (SvUTF8(text_sv))
1947 text = SvPV(text_sv, work_len);
1952 ch = i_utf8_advance(&text, &len);
1954 i_push_error(0, "invalid UTF8 character");
1963 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
1964 PUSHs(sv_2mortal(newSVpv(name, 0)));
1967 PUSHs(&PL_sv_undef);
1976 i_writejpeg_wiol(im, ig, qfactor)
1992 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1993 if (iptc_itext == NULL) {
1996 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2001 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2003 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2012 i_test_format_probe(ig, length)
2021 i_readtiff_wiol(ig, length)
2026 i_readtiff_multi_wiol(ig, length)
2034 imgs = i_readtiff_multi_wiol(ig, length, &count);
2037 for (i = 0; i < count; ++i) {
2038 SV *sv = sv_newmortal();
2039 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2047 i_writetiff_wiol(im, ig)
2052 i_writetiff_multi_wiol(ig, ...)
2060 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2061 img_count = items - 1;
2063 if (img_count < 1) {
2066 i_push_error(0, "You need to specify images to save");
2069 imgs = mymalloc(sizeof(i_img *) * img_count);
2070 for (i = 0; i < img_count; ++i) {
2073 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2074 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2078 i_push_error(0, "Only images can be saved");
2085 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2093 i_writetiff_wiol_faxable(im, ig, fine)
2099 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2108 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2109 img_count = items - 2;
2111 if (img_count < 1) {
2114 i_push_error(0, "You need to specify images to save");
2117 imgs = mymalloc(sizeof(i_img *) * img_count);
2118 for (i = 0; i < img_count; ++i) {
2121 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2122 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2126 i_push_error(0, "Only images can be saved");
2133 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2141 #endif /* HAVE_LIBTIFF */
2147 i_readpng_wiol(ig, length)
2153 i_writepng_wiol(im, ig)
2166 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2169 i_writegif(im,fd,colors,pixdev,fixed)
2176 Imager__Color fixed;
2183 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2184 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2185 av=(AV*)SvRV(ST(4));
2186 fixedlen=av_len(av)+1;
2187 fixed=mymalloc( fixedlen*sizeof(i_color) );
2188 for(i=0;i<fixedlen;i++) {
2189 sv1=(*(av_fetch(av,i,0)));
2190 if (sv_derived_from(sv1, "Imager::Color")) {
2191 Itmp = SvIV((SV*)SvRV(sv1));
2192 tmp = INT2PTR(i_color*, Itmp);
2193 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2196 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2198 ST(0) = sv_newmortal();
2199 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2200 else sv_setiv(ST(0), (IV)RETVAL);
2206 i_writegifmc(im,fd,colors)
2213 i_writegif_gen(fd, ...)
2218 i_img **imgs = NULL;
2224 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2225 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2226 croak("i_writegif_gen: Second argument must be a hash ref");
2227 hv = (HV *)SvRV(ST(1));
2228 memset(&quant, 0, sizeof(quant));
2229 quant.mc_size = 256;
2230 handle_quant_opts(&quant, hv);
2231 img_count = items - 2;
2233 if (img_count < 1) {
2236 i_push_error(0, "You need to specify images to save");
2239 imgs = mymalloc(sizeof(i_img *) * img_count);
2240 for (i = 0; i < img_count; ++i) {
2243 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2244 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2248 i_push_error(0, "Only images can be saved");
2254 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2258 copy_colors_back(hv, &quant);
2261 ST(0) = sv_newmortal();
2262 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2263 else sv_setiv(ST(0), (IV)RETVAL);
2264 cleanup_quant_opts(&quant);
2268 i_writegif_callback(cb, maxbuffer,...)
2272 i_img **imgs = NULL;
2279 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2280 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2281 croak("i_writegif_callback: Second argument must be a hash ref");
2282 hv = (HV *)SvRV(ST(2));
2283 memset(&quant, 0, sizeof(quant));
2284 quant.mc_size = 256;
2285 handle_quant_opts(&quant, hv);
2286 img_count = items - 3;
2288 if (img_count < 1) {
2292 imgs = mymalloc(sizeof(i_img *) * img_count);
2293 for (i = 0; i < img_count; ++i) {
2296 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2297 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2306 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2310 copy_colors_back(hv, &quant);
2313 ST(0) = sv_newmortal();
2314 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2315 else sv_setiv(ST(0), (IV)RETVAL);
2316 cleanup_quant_opts(&quant);
2319 i_writegif_wiol(ig, opts,...)
2323 i_img **imgs = NULL;
2329 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2330 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2331 croak("i_writegif_callback: Second argument must be a hash ref");
2332 hv = (HV *)SvRV(ST(1));
2333 memset(&quant, 0, sizeof(quant));
2334 quant.mc_size = 256;
2335 handle_quant_opts(&quant, hv);
2336 img_count = items - 2;
2338 if (img_count < 1) {
2342 imgs = mymalloc(sizeof(i_img *) * img_count);
2343 for (i = 0; i < img_count; ++i) {
2346 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2347 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2355 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2359 copy_colors_back(hv, &quant);
2362 ST(0) = sv_newmortal();
2363 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2364 else sv_setiv(ST(0), (IV)RETVAL);
2365 cleanup_quant_opts(&quant);
2378 colour_table = NULL;
2381 if(GIMME_V == G_ARRAY) {
2382 rimg = i_readgif(fd,&colour_table,&colours);
2384 /* don't waste time with colours if they aren't wanted */
2385 rimg = i_readgif(fd,NULL,NULL);
2388 if (colour_table == NULL) {
2391 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2394 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2395 /* I don't know if I have the reference counts right or not :( */
2396 /* Neither do I :-) */
2397 /* No Idea here either */
2400 av_extend(ct, colours);
2401 for(q=0; q<colours; q++) {
2403 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2404 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2406 myfree(colour_table);
2410 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2412 PUSHs(newRV_noinc((SV*)ct));
2426 colour_table = NULL;
2429 if(GIMME_V == G_ARRAY) {
2430 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2432 /* don't waste time with colours if they aren't wanted */
2433 rimg = i_readgif_wiol(ig,NULL,NULL);
2436 if (colour_table == NULL) {
2439 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2442 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2443 /* I don't know if I have the reference counts right or not :( */
2444 /* Neither do I :-) */
2445 /* No Idea here either */
2448 av_extend(ct, colours);
2449 for(q=0; q<colours; q++) {
2451 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2452 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2454 myfree(colour_table);
2458 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2460 PUSHs(newRV_noinc((SV*)ct));
2464 i_readgif_scalar(...)
2476 data = (char *)SvPV(ST(0), length);
2480 if(GIMME_V == G_ARRAY) {
2481 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2483 /* don't waste time with colours if they aren't wanted */
2484 rimg=i_readgif_scalar(data,length,NULL,NULL);
2487 if (colour_table == NULL) {
2490 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2493 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2494 /* I don't know if I have the reference counts right or not :( */
2495 /* Neither do I :-) */
2497 av_extend(ct, colours);
2498 for(q=0; q<colours; q++) {
2500 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2501 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2503 myfree(colour_table);
2507 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2509 PUSHs(newRV_noinc((SV*)ct));
2513 i_readgif_callback(...)
2528 if(GIMME_V == G_ARRAY) {
2529 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2531 /* don't waste time with colours if they aren't wanted */
2532 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2535 if (colour_table == NULL) {
2538 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2541 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2542 /* I don't know if I have the reference counts right or not :( */
2543 /* Neither do I :-) */
2544 /* Neither do I - maybe I'll move this somewhere */
2546 av_extend(ct, colours);
2547 for(q=0; q<colours; q++) {
2549 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2550 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2552 myfree(colour_table);
2556 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2558 PUSHs(newRV_noinc((SV*)ct));
2569 imgs = i_readgif_multi(fd, &count);
2572 for (i = 0; i < count; ++i) {
2573 SV *sv = sv_newmortal();
2574 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2581 i_readgif_multi_scalar(data)
2589 data = (char *)SvPV(ST(0), length);
2590 imgs = i_readgif_multi_scalar(data, length, &count);
2593 for (i = 0; i < count; ++i) {
2594 SV *sv = sv_newmortal();
2595 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2602 i_readgif_multi_callback(cb)
2610 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2613 for (i = 0; i < count; ++i) {
2614 SV *sv = sv_newmortal();
2615 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2622 i_readgif_multi_wiol(ig)
2629 imgs = i_readgif_multi_wiol(ig, &count);
2632 for (i = 0; i < count; ++i) {
2633 SV *sv = sv_newmortal();
2634 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2646 i_readpnm_wiol(ig, length)
2652 i_writeppm_wiol(im, ig)
2658 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2667 i_writeraw_wiol(im,ig)
2672 i_writebmp_wiol(im,ig)
2682 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2691 idlen = SvCUR(ST(4));
2692 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2698 i_readtga_wiol(ig, length)
2704 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2713 idlen = SvCUR(ST(4));
2714 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2720 i_readrgb_wiol(ig, length)
2727 i_scaleaxis(im,Value,Axis)
2733 i_scale_nn(im,scx,scy)
2743 i_count_colors(im,maxc)
2749 i_transform(im,opx,opy,parm)
2762 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2763 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2764 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2765 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2766 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2767 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2768 av=(AV*)SvRV(ST(1));
2770 opx=mymalloc( opxl*sizeof(int) );
2771 for(i=0;i<opxl;i++) {
2772 sv1=(*(av_fetch(av,i,0)));
2773 opx[i]=(int)SvIV(sv1);
2775 av=(AV*)SvRV(ST(2));
2777 opy=mymalloc( opyl*sizeof(int) );
2778 for(i=0;i<opyl;i++) {
2779 sv1=(*(av_fetch(av,i,0)));
2780 opy[i]=(int)SvIV(sv1);
2782 av=(AV*)SvRV(ST(3));
2783 parmlen=av_len(av)+1;
2784 parm=mymalloc( parmlen*sizeof(double) );
2785 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2786 sv1=(*(av_fetch(av,i,0)));
2787 parm[i]=(double)SvNV(sv1);
2789 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2793 ST(0) = sv_newmortal();
2794 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2795 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2798 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2823 in_imgs_count = av_len(av_in_imgs)+1;
2824 for (i = 0; i < in_imgs_count; ++i) {
2825 sv1 = *av_fetch(av_in_imgs, i, 0);
2826 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2827 croak("sv_in_img must contain only images");
2830 if (in_imgs_count > 0) {
2831 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2832 for (i = 0; i < in_imgs_count; ++i) {
2833 sv1 = *av_fetch(av_in_imgs,i,0);
2834 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2835 croak("Parameter 5 must contain only images");
2837 tmp = SvIV((SV*)SvRV(sv1));
2838 in_imgs[i] = INT2PTR(i_img*, tmp);
2842 /* no input images */
2845 /* default the output size from the first input if possible */
2847 width = SvIV(sv_width);
2848 else if (in_imgs_count)
2849 width = in_imgs[0]->xsize;
2851 croak("No output image width supplied");
2853 if (SvOK(sv_height))
2854 height = SvIV(sv_height);
2855 else if (in_imgs_count)
2856 height = in_imgs[0]->ysize;
2858 croak("No output image height supplied");
2860 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2861 if (ops_len % sizeof(struct rm_op))
2862 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2863 ops_count = ops_len / sizeof(struct rm_op);
2865 n_regs_count = av_len(av_n_regs)+1;
2866 n_regs = mymalloc(n_regs_count * sizeof(double));
2867 for (i = 0; i < n_regs_count; ++i) {
2868 sv1 = *av_fetch(av_n_regs,i,0);
2870 n_regs[i] = SvNV(sv1);
2872 c_regs_count = av_len(av_c_regs)+1;
2873 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2874 /* I don't bother initializing the colou?r registers */
2876 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2877 n_regs, n_regs_count,
2878 c_regs, c_regs_count, in_imgs, in_imgs_count);
2883 ST(0) = sv_newmortal();
2884 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2885 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2889 i_contrast(im,intensity)
2898 i_noise(im,amount,type)
2904 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2914 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2933 i_postlevels(im,levels)
2943 i_watermark(im,wmark,tx,ty,pixdiff)
2945 Imager::ImgRaw wmark
2952 i_autolevels(im,lsat,usat,skew)
2959 i_radnoise(im,xo,yo,rscale,ascale)
2967 i_turbnoise(im, xo, yo, scale)
2990 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2991 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2992 croak("i_gradgen: Second argument must be an array ref");
2993 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2994 croak("i_gradgen: Third argument must be an array ref");
2995 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2996 croak("i_gradgen: Fourth argument must be an array ref");
2997 axx = (AV *)SvRV(ST(1));
2998 ayy = (AV *)SvRV(ST(2));
2999 ac = (AV *)SvRV(ST(3));
3000 dmeasure = (int)SvIV(ST(4));
3002 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3003 num = num <= av_len(ac) ? num : av_len(ac);
3005 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3006 xo = mymalloc( sizeof(int) * num );
3007 yo = mymalloc( sizeof(int) * num );
3008 ival = mymalloc( sizeof(i_color) * num );
3009 for(i = 0; i<num; i++) {
3010 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3011 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3012 sv = *av_fetch(ac, i, 0);
3013 if ( !sv_derived_from(sv, "Imager::Color") ) {
3014 free(axx); free(ayy); free(ac);
3015 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3017 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3019 i_gradgen(im, num, xo, yo, ival, dmeasure);
3025 i_diff_image(im, im2, mindist=0)
3031 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3041 double ssample_param
3045 i_fountain_seg *segs;
3047 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3048 croak("i_fountain: argument 11 must be an array ref");
3050 asegs = (AV *)SvRV(ST(10));
3051 segs = load_fount_segs(asegs, &count);
3052 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3053 ssample_param, count, segs);
3057 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3066 double ssample_param
3070 i_fountain_seg *segs;
3072 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3073 croak("i_fountain: argument 11 must be an array ref");
3075 asegs = (AV *)SvRV(ST(9));
3076 segs = load_fount_segs(asegs, &count);
3077 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3078 super_sample, ssample_param, count, segs);
3091 errors = i_errors();
3093 while (errors[i].msg) {
3095 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3096 if (!av_store(av, 0, sv)) {
3099 sv = newSViv(errors[i].code);
3100 if (!av_store(av, 1, sv)) {
3103 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3108 i_nearest_color(im, ...)
3123 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3124 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3125 croak("i_nearest_color: Second argument must be an array ref");
3126 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3127 croak("i_nearest_color: Third argument must be an array ref");
3128 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3129 croak("i_nearest_color: Fourth argument must be an array ref");
3130 axx = (AV *)SvRV(ST(1));
3131 ayy = (AV *)SvRV(ST(2));
3132 ac = (AV *)SvRV(ST(3));
3133 dmeasure = (int)SvIV(ST(4));
3135 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3136 num = num <= av_len(ac) ? num : av_len(ac);
3138 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3139 xo = mymalloc( sizeof(int) * num );
3140 yo = mymalloc( sizeof(int) * num );
3141 ival = mymalloc( sizeof(i_color) * num );
3142 for(i = 0; i<num; i++) {
3143 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3144 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3145 sv = *av_fetch(ac, i, 0);
3146 if ( !sv_derived_from(sv, "Imager::Color") ) {
3147 free(axx); free(ayy); free(ac);
3148 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3150 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3152 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3166 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3167 hv=(HV*)SvRV(ST(0));
3168 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3169 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3170 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3179 rc=DSO_open(filename,&evstr);
3183 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3184 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3187 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3193 DSO_close(dso_handle)
3197 DSO_funclist(dso_handle_v)
3201 DSO_handle *dso_handle;
3203 dso_handle=(DSO_handle*)dso_handle_v;
3205 while( dso_handle->function_list[i].name != NULL) {
3207 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3209 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3214 DSO_call(handle,func_index,hv)
3220 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3221 hv=(HV*)SvRV(ST(2));
3222 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3223 DSO_call( (DSO_handle *)handle,func_index,hv);
3228 i_get_pixel(im, x, y)
3235 color = (i_color *)mymalloc(sizeof(i_color));
3236 if (i_gpix(im, x, y, color) == 0) {
3237 RETVAL = NEWSV(0, 0);
3238 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3242 RETVAL = &PL_sv_undef;
3249 i_ppix(im, x, y, cl)
3256 i_img_pal_new(x, y, channels, maxpal)
3263 i_img_to_pal(src, quant)
3269 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3270 croak("i_img_to_pal: second argument must be a hash ref");
3271 hv = (HV *)SvRV(ST(1));
3272 memset(&quant, 0, sizeof(quant));
3273 quant.mc_size = 256;
3274 handle_quant_opts(&quant, hv);
3275 RETVAL = i_img_to_pal(src, &quant);
3277 copy_colors_back(hv, &quant);
3279 cleanup_quant_opts(&quant);
3298 work = mymalloc((r-l) * sizeof(i_palidx));
3299 count = i_gpal(im, l, r, y, work);
3300 if (GIMME_V == G_ARRAY) {
3302 for (i = 0; i < count; ++i) {
3303 PUSHs(sv_2mortal(newSViv(work[i])));
3308 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3313 if (GIMME_V != G_ARRAY) {
3315 PUSHs(&PL_sv_undef);
3320 i_ppal(im, l, y, ...)
3329 work = mymalloc(sizeof(i_palidx) * (items-3));
3330 for (i=0; i < items-3; ++i) {
3331 work[i] = SvIV(ST(i+3));
3333 RETVAL = i_ppal(im, l, l+items-3, y, work);
3343 i_addcolors(im, ...)
3351 croak("i_addcolors: no colors to add");
3352 colors = mymalloc((items-1) * sizeof(i_color));
3353 for (i=0; i < items-1; ++i) {
3354 if (sv_isobject(ST(i+1))
3355 && sv_derived_from(ST(i+1), "Imager::Color")) {
3356 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3357 colors[i] = *INT2PTR(i_color *, tmp);
3361 croak("i_plin: pixels must be Imager::Color objects");
3364 index = i_addcolors(im, colors, items-1);
3367 RETVAL = newSVpv("0 but true", 0);
3369 else if (index == -1) {
3370 RETVAL = &PL_sv_undef;
3373 RETVAL = newSViv(index);
3379 i_setcolors(im, index, ...)
3387 croak("i_setcolors: no colors to add");
3388 colors = mymalloc((items-2) * sizeof(i_color));
3389 for (i=0; i < items-2; ++i) {
3390 if (sv_isobject(ST(i+2))
3391 && sv_derived_from(ST(i+2), "Imager::Color")) {
3392 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3393 colors[i] = *INT2PTR(i_color *, tmp);
3397 croak("i_setcolors: pixels must be Imager::Color objects");
3400 RETVAL = i_setcolors(im, index, colors, items-2);
3406 i_getcolors(im, index, ...)
3415 croak("i_getcolors: too many arguments");
3417 count = SvIV(ST(2));
3419 croak("i_getcolors: count must be positive");
3420 colors = mymalloc(sizeof(i_color) * count);
3421 if (i_getcolors(im, index, colors, count)) {
3422 for (i = 0; i < count; ++i) {
3424 SV *sv = sv_newmortal();
3425 pv = mymalloc(sizeof(i_color));
3427 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3443 i_findcolor(im, color)
3449 if (i_findcolor(im, color, &index)) {
3450 RETVAL = newSViv(index);
3453 RETVAL = &PL_sv_undef;
3471 i_gsamp(im, l, r, y, ...)
3483 croak("No channel numbers supplied to g_samp()");
3485 chan_count = items - 4;
3486 chans = mymalloc(sizeof(int) * chan_count);
3487 for (i = 0; i < chan_count; ++i)
3488 chans[i] = SvIV(ST(i+4));
3489 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3490 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3492 if (GIMME_V == G_ARRAY) {
3494 for (i = 0; i < count; ++i)
3495 PUSHs(sv_2mortal(newSViv(data[i])));
3499 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3504 if (GIMME_V != G_ARRAY) {
3506 PUSHs(&PL_sv_undef);
3512 i_img_masked_new(targ, mask, x, y, w, h)
3522 if (!sv_isobject(ST(1))
3523 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3524 croak("i_img_masked_new: parameter 2 must undef or an image");
3526 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3530 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3535 i_plin(im, l, y, ...)
3544 work = mymalloc(sizeof(i_color) * (items-3));
3545 for (i=0; i < items-3; ++i) {
3546 if (sv_isobject(ST(i+3))
3547 && sv_derived_from(ST(i+3), "Imager::Color")) {
3548 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3549 work[i] = *INT2PTR(i_color *, tmp);
3553 croak("i_plin: pixels must be Imager::Color objects");
3557 RETVAL = i_plin(im, l, l+items-3, y, work);
3567 i_ppixf(im, x, y, cl)
3571 Imager::Color::Float cl
3574 i_gsampf(im, l, r, y, ...)
3586 croak("No channel numbers supplied to g_sampf()");
3588 chan_count = items - 4;
3589 chans = mymalloc(sizeof(int) * chan_count);
3590 for (i = 0; i < chan_count; ++i)
3591 chans[i] = SvIV(ST(i+4));
3592 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3593 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3594 if (GIMME_V == G_ARRAY) {
3596 for (i = 0; i < count; ++i)
3597 PUSHs(sv_2mortal(newSVnv(data[i])));
3601 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3605 if (GIMME_V != G_ARRAY) {
3607 PUSHs(&PL_sv_undef);
3612 i_plinf(im, l, y, ...)
3621 work = mymalloc(sizeof(i_fcolor) * (items-3));
3622 for (i=0; i < items-3; ++i) {
3623 if (sv_isobject(ST(i+3))
3624 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3625 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3626 work[i] = *INT2PTR(i_fcolor *, tmp);
3630 croak("i_plin: pixels must be Imager::Color::Float objects");
3634 RETVAL = i_plinf(im, l, l+items-3, y, work);
3651 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3652 if (i_gpixf(im, x, y, color) == 0) {
3653 RETVAL = NEWSV(0,0);
3654 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3658 RETVAL = &PL_sv_undef;
3674 vals = mymalloc((r-l) * sizeof(i_color));
3675 count = i_glin(im, l, r, y, vals);
3677 for (i = 0; i < count; ++i) {
3679 i_color *col = mymalloc(sizeof(i_color));
3681 sv = sv_newmortal();
3682 sv_setref_pv(sv, "Imager::Color", (void *)col);
3689 i_glinf(im, l, r, y)
3699 vals = mymalloc((r-l) * sizeof(i_fcolor));
3700 count = i_glinf(im, l, r, y, vals);
3702 for (i = 0; i < count; ++i) {
3704 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3706 sv = sv_newmortal();
3707 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3714 i_img_16_new(x, y, ch)
3720 i_img_double_new(x, y, ch)
3726 i_tags_addn(im, name, code, idata)
3735 name = SvPV(ST(1), len);
3738 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3743 i_tags_add(im, name, code, data, idata)
3753 name = SvPV(ST(1), len);
3757 data = SvPV(ST(3), len);
3762 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3767 i_tags_find(im, name, start)
3774 if (i_tags_find(&im->tags, name, start, &entry)) {
3776 RETVAL = newSVpv("0 but true", 0);
3778 RETVAL = newSViv(entry);
3780 RETVAL = &PL_sv_undef;
3786 i_tags_findn(im, code, start)
3793 if (i_tags_findn(&im->tags, code, start, &entry)) {
3795 RETVAL = newSVpv("0 but true", 0);
3797 RETVAL = newSViv(entry);
3800 RETVAL = &PL_sv_undef;
3806 i_tags_delete(im, entry)
3810 RETVAL = i_tags_delete(&im->tags, entry);
3815 i_tags_delbyname(im, name)
3819 RETVAL = i_tags_delbyname(&im->tags, name);
3824 i_tags_delbycode(im, code)
3828 RETVAL = i_tags_delbycode(&im->tags, code);
3833 i_tags_get(im, index)
3837 if (index >= 0 && index < im->tags.count) {
3838 i_img_tag *entry = im->tags.tags + index;
3842 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3845 PUSHs(sv_2mortal(newSViv(entry->code)));
3848 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3851 PUSHs(sv_2mortal(newSViv(entry->idata)));
3856 i_tags_get_string(im, what_sv)
3860 char const *name = NULL;
3864 if (SvIOK(what_sv)) {
3865 code = SvIV(what_sv);
3869 name = SvPV_nolen(what_sv);
3872 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3874 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3881 RETVAL = im->tags.count;
3888 i_wf_bbox(face, size, text)
3893 int cords[BOUNDING_BOX_COUNT];
3896 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3898 for (i = 0; i < rc; ++i)
3899 PUSHs(sv_2mortal(newSViv(cords[i])));
3903 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3914 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3920 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3931 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3944 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3946 #define FT2_DESTROY(font) i_ft2_destroy(font)
3950 Imager::Font::FT2 font
3952 MODULE = Imager PACKAGE = Imager::Font::FreeType2
3955 i_ft2_new(name, index)
3960 i_ft2_setdpi(font, xdpi, ydpi)
3961 Imager::Font::FT2 font
3967 Imager::Font::FT2 font
3971 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3973 PUSHs(sv_2mortal(newSViv(xdpi)));
3974 PUSHs(sv_2mortal(newSViv(ydpi)));
3978 i_ft2_sethinting(font, hinting)
3979 Imager::Font::FT2 font
3983 i_ft2_settransform(font, matrix)
3984 Imager::Font::FT2 font
3992 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3993 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3994 av=(AV*)SvRV(ST(1));
3998 for (i = 0; i < len; ++i) {
3999 sv1=(*(av_fetch(av,i,0)));
4000 matrix[i] = SvNV(sv1);
4004 RETVAL = i_ft2_settransform(font, matrix);
4009 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4010 Imager::Font::FT2 font
4016 int bbox[BOUNDING_BOX_COUNT];
4022 text = SvPV(text_sv, text_len);
4024 if (SvUTF8(text_sv))
4027 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4030 for (i = 0; i < rc; ++i)
4031 PUSHs(sv_2mortal(newSViv(bbox[i])));
4035 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4036 Imager::Font::FT2 font
4050 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4053 for (i = 0; i < 8; ++i)
4054 PUSHs(sv_2mortal(newSViv(bbox[i])));
4058 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4059 Imager::Font::FT2 font
4075 if (SvUTF8(ST(7))) {
4079 text = SvPV(ST(7), len);
4080 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4081 len, align, aa, vlayout, utf8);
4086 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4087 Imager::Font::FT2 font
4104 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4105 strlen(text), align, aa, vlayout, 1);
4110 ft2_transform_box(font, x0, x1, x2, x3)
4111 Imager::Font::FT2 font
4119 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4120 ft2_transform_box(font, box);
4122 PUSHs(sv_2mortal(newSViv(box[0])));
4123 PUSHs(sv_2mortal(newSViv(box[1])));
4124 PUSHs(sv_2mortal(newSViv(box[2])));
4125 PUSHs(sv_2mortal(newSViv(box[3])));
4128 i_ft2_has_chars(handle, text_sv, utf8)
4129 Imager::Font::FT2 handle
4140 if (SvUTF8(text_sv))
4143 text = SvPV(text_sv, len);
4144 work = mymalloc(len);
4145 count = i_ft2_has_chars(handle, text, len, utf8, work);
4146 if (GIMME_V == G_ARRAY) {
4148 for (i = 0; i < count; ++i) {
4149 PUSHs(sv_2mortal(newSViv(work[i])));
4154 PUSHs(sv_2mortal(newSVpv(work, count)));
4159 i_ft2_face_name(handle)
4160 Imager::Font::FT2 handle
4165 len = i_ft2_face_name(handle, name, sizeof(name));
4168 PUSHs(sv_2mortal(newSVpv(name, 0)));
4172 i_ft2_can_face_name()
4175 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4176 Imager::Font::FT2 handle
4188 if (SvUTF8(text_sv))
4191 text = SvPV(text_sv, work_len);
4196 ch = i_utf8_advance(&text, &len);
4198 i_push_error(0, "invalid UTF8 character");
4207 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4209 PUSHs(sv_2mortal(newSVpv(name, 0)));
4212 PUSHs(&PL_sv_undef);
4217 i_ft2_can_do_glyph_names()
4220 i_ft2_face_has_glyph_names(handle)
4221 Imager::Font::FT2 handle
4224 i_ft2_is_multiple_master(handle)
4225 Imager::Font::FT2 handle
4228 i_ft2_get_multiple_masters(handle)
4229 Imager::Font::FT2 handle
4234 if (i_ft2_get_multiple_masters(handle, &mm)) {
4235 EXTEND(SP, 2+mm.num_axis);
4236 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4237 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4238 for (i = 0; i < mm.num_axis; ++i) {
4242 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4244 av_store(av, 0, sv);
4245 sv = newSViv(mm.axis[i].minimum);
4247 av_store(av, 1, sv);
4248 sv = newSViv(mm.axis[i].maximum);
4250 av_store(av, 2, sv);
4251 PUSHs(newRV_noinc((SV *)av));
4256 i_ft2_set_mm_coords(handle, ...)
4257 Imager::Font::FT2 handle
4263 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4264 transfer the array manually */
4265 ix_coords = items-1;
4266 coords = mymalloc(sizeof(long) * ix_coords);
4267 for (i = 0; i < ix_coords; ++i) {
4268 coords[i] = (long)SvIV(ST(1+i));
4270 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4277 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4281 Imager::FillHandle fill
4283 MODULE = Imager PACKAGE = Imager
4286 i_new_fill_solid(cl, combine)
4291 i_new_fill_solidf(cl, combine)
4292 Imager::Color::Float cl
4296 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4304 unsigned char *cust_hatch;
4308 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4312 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4317 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4318 Imager::Color::Float fg
4319 Imager::Color::Float bg
4325 unsigned char *cust_hatch;
4329 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4333 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4338 i_new_fill_image(src, matrix, xoff, yoff, combine)
4355 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4356 croak("i_new_fill_image: parameter must be an arrayref");
4357 av=(AV*)SvRV(ST(1));
4361 for (i = 0; i < len; ++i) {
4362 sv1=(*(av_fetch(av,i,0)));
4363 matrix[i] = SvNV(sv1);
4369 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);