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)
2043 i_readtiff_multi_wiol(ig, length)
2051 imgs = i_readtiff_multi_wiol(ig, length, &count);
2054 for (i = 0; i < count; ++i) {
2055 SV *sv = sv_newmortal();
2056 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2064 i_writetiff_wiol(im, ig)
2069 i_writetiff_multi_wiol(ig, ...)
2077 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2078 img_count = items - 1;
2080 if (img_count < 1) {
2083 i_push_error(0, "You need to specify images to save");
2086 imgs = mymalloc(sizeof(i_img *) * img_count);
2087 for (i = 0; i < img_count; ++i) {
2090 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2091 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2095 i_push_error(0, "Only images can be saved");
2102 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2110 i_writetiff_wiol_faxable(im, ig, fine)
2116 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2125 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2126 img_count = items - 2;
2128 if (img_count < 1) {
2131 i_push_error(0, "You need to specify images to save");
2134 imgs = mymalloc(sizeof(i_img *) * img_count);
2135 for (i = 0; i < img_count; ++i) {
2138 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2139 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2143 i_push_error(0, "Only images can be saved");
2150 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2158 #endif /* HAVE_LIBTIFF */
2164 i_readpng_wiol(ig, length)
2170 i_writepng_wiol(im, ig)
2183 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2186 i_writegif(im,fd,colors,pixdev,fixed)
2193 Imager__Color fixed;
2200 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2201 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2202 av=(AV*)SvRV(ST(4));
2203 fixedlen=av_len(av)+1;
2204 fixed=mymalloc( fixedlen*sizeof(i_color) );
2205 for(i=0;i<fixedlen;i++) {
2206 sv1=(*(av_fetch(av,i,0)));
2207 if (sv_derived_from(sv1, "Imager::Color")) {
2208 Itmp = SvIV((SV*)SvRV(sv1));
2209 tmp = INT2PTR(i_color*, Itmp);
2210 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2213 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2215 ST(0) = sv_newmortal();
2216 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2217 else sv_setiv(ST(0), (IV)RETVAL);
2223 i_writegifmc(im,fd,colors)
2230 i_writegif_gen(fd, ...)
2235 i_img **imgs = NULL;
2241 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2242 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2243 croak("i_writegif_gen: Second argument must be a hash ref");
2244 hv = (HV *)SvRV(ST(1));
2245 memset(&quant, 0, sizeof(quant));
2246 quant.mc_size = 256;
2247 handle_quant_opts(&quant, hv);
2248 img_count = items - 2;
2250 if (img_count < 1) {
2253 i_push_error(0, "You need to specify images to save");
2256 imgs = mymalloc(sizeof(i_img *) * img_count);
2257 for (i = 0; i < img_count; ++i) {
2260 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2261 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2265 i_push_error(0, "Only images can be saved");
2271 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2275 copy_colors_back(hv, &quant);
2278 ST(0) = sv_newmortal();
2279 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2280 else sv_setiv(ST(0), (IV)RETVAL);
2281 cleanup_quant_opts(&quant);
2285 i_writegif_callback(cb, maxbuffer,...)
2289 i_img **imgs = NULL;
2296 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2297 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2298 croak("i_writegif_callback: Second argument must be a hash ref");
2299 hv = (HV *)SvRV(ST(2));
2300 memset(&quant, 0, sizeof(quant));
2301 quant.mc_size = 256;
2302 handle_quant_opts(&quant, hv);
2303 img_count = items - 3;
2305 if (img_count < 1) {
2309 imgs = mymalloc(sizeof(i_img *) * img_count);
2310 for (i = 0; i < img_count; ++i) {
2313 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2314 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2323 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2327 copy_colors_back(hv, &quant);
2330 ST(0) = sv_newmortal();
2331 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2332 else sv_setiv(ST(0), (IV)RETVAL);
2333 cleanup_quant_opts(&quant);
2336 i_writegif_wiol(ig, opts,...)
2340 i_img **imgs = NULL;
2346 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2347 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2348 croak("i_writegif_callback: Second argument must be a hash ref");
2349 hv = (HV *)SvRV(ST(1));
2350 memset(&quant, 0, sizeof(quant));
2351 quant.mc_size = 256;
2352 handle_quant_opts(&quant, hv);
2353 img_count = items - 2;
2355 if (img_count < 1) {
2359 imgs = mymalloc(sizeof(i_img *) * img_count);
2360 for (i = 0; i < img_count; ++i) {
2363 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2364 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2372 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2376 copy_colors_back(hv, &quant);
2379 ST(0) = sv_newmortal();
2380 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2381 else sv_setiv(ST(0), (IV)RETVAL);
2382 cleanup_quant_opts(&quant);
2395 colour_table = NULL;
2398 if(GIMME_V == G_ARRAY) {
2399 rimg = i_readgif(fd,&colour_table,&colours);
2401 /* don't waste time with colours if they aren't wanted */
2402 rimg = i_readgif(fd,NULL,NULL);
2405 if (colour_table == NULL) {
2408 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2411 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2412 /* I don't know if I have the reference counts right or not :( */
2413 /* Neither do I :-) */
2414 /* No Idea here either */
2417 av_extend(ct, colours);
2418 for(q=0; q<colours; q++) {
2420 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2421 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2423 myfree(colour_table);
2427 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2429 PUSHs(newRV_noinc((SV*)ct));
2443 colour_table = NULL;
2446 if(GIMME_V == G_ARRAY) {
2447 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2449 /* don't waste time with colours if they aren't wanted */
2450 rimg = i_readgif_wiol(ig,NULL,NULL);
2453 if (colour_table == NULL) {
2456 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2459 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2460 /* I don't know if I have the reference counts right or not :( */
2461 /* Neither do I :-) */
2462 /* No Idea here either */
2465 av_extend(ct, colours);
2466 for(q=0; q<colours; q++) {
2468 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2469 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2471 myfree(colour_table);
2475 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2477 PUSHs(newRV_noinc((SV*)ct));
2481 i_readgif_scalar(...)
2493 data = (char *)SvPV(ST(0), length);
2497 if(GIMME_V == G_ARRAY) {
2498 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2500 /* don't waste time with colours if they aren't wanted */
2501 rimg=i_readgif_scalar(data,length,NULL,NULL);
2504 if (colour_table == NULL) {
2507 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2510 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2511 /* I don't know if I have the reference counts right or not :( */
2512 /* Neither do I :-) */
2514 av_extend(ct, colours);
2515 for(q=0; q<colours; q++) {
2517 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2518 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2520 myfree(colour_table);
2524 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2526 PUSHs(newRV_noinc((SV*)ct));
2530 i_readgif_callback(...)
2545 if(GIMME_V == G_ARRAY) {
2546 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2548 /* don't waste time with colours if they aren't wanted */
2549 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2552 if (colour_table == NULL) {
2555 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2558 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2559 /* I don't know if I have the reference counts right or not :( */
2560 /* Neither do I :-) */
2561 /* Neither do I - maybe I'll move this somewhere */
2563 av_extend(ct, colours);
2564 for(q=0; q<colours; q++) {
2566 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2567 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2569 myfree(colour_table);
2573 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2575 PUSHs(newRV_noinc((SV*)ct));
2586 imgs = i_readgif_multi(fd, &count);
2589 for (i = 0; i < count; ++i) {
2590 SV *sv = sv_newmortal();
2591 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2598 i_readgif_multi_scalar(data)
2606 data = (char *)SvPV(ST(0), length);
2607 imgs = i_readgif_multi_scalar(data, length, &count);
2610 for (i = 0; i < count; ++i) {
2611 SV *sv = sv_newmortal();
2612 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2619 i_readgif_multi_callback(cb)
2627 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2630 for (i = 0; i < count; ++i) {
2631 SV *sv = sv_newmortal();
2632 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2639 i_readgif_multi_wiol(ig)
2646 imgs = i_readgif_multi_wiol(ig, &count);
2649 for (i = 0; i < count; ++i) {
2650 SV *sv = sv_newmortal();
2651 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2663 i_readpnm_wiol(ig, length)
2669 i_writeppm_wiol(im, ig)
2675 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2684 i_writeraw_wiol(im,ig)
2689 i_writebmp_wiol(im,ig)
2699 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2708 idlen = SvCUR(ST(4));
2709 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2715 i_readtga_wiol(ig, length)
2721 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2730 idlen = SvCUR(ST(4));
2731 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2737 i_readrgb_wiol(ig, length)
2744 i_scaleaxis(im,Value,Axis)
2750 i_scale_nn(im,scx,scy)
2760 i_count_colors(im,maxc)
2766 i_transform(im,opx,opy,parm)
2779 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2780 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2781 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2782 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2783 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2784 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2785 av=(AV*)SvRV(ST(1));
2787 opx=mymalloc( opxl*sizeof(int) );
2788 for(i=0;i<opxl;i++) {
2789 sv1=(*(av_fetch(av,i,0)));
2790 opx[i]=(int)SvIV(sv1);
2792 av=(AV*)SvRV(ST(2));
2794 opy=mymalloc( opyl*sizeof(int) );
2795 for(i=0;i<opyl;i++) {
2796 sv1=(*(av_fetch(av,i,0)));
2797 opy[i]=(int)SvIV(sv1);
2799 av=(AV*)SvRV(ST(3));
2800 parmlen=av_len(av)+1;
2801 parm=mymalloc( parmlen*sizeof(double) );
2802 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2803 sv1=(*(av_fetch(av,i,0)));
2804 parm[i]=(double)SvNV(sv1);
2806 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2810 ST(0) = sv_newmortal();
2811 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2812 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2815 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2840 in_imgs_count = av_len(av_in_imgs)+1;
2841 for (i = 0; i < in_imgs_count; ++i) {
2842 sv1 = *av_fetch(av_in_imgs, i, 0);
2843 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2844 croak("sv_in_img must contain only images");
2847 if (in_imgs_count > 0) {
2848 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2849 for (i = 0; i < in_imgs_count; ++i) {
2850 sv1 = *av_fetch(av_in_imgs,i,0);
2851 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2852 croak("Parameter 5 must contain only images");
2854 tmp = SvIV((SV*)SvRV(sv1));
2855 in_imgs[i] = INT2PTR(i_img*, tmp);
2859 /* no input images */
2862 /* default the output size from the first input if possible */
2864 width = SvIV(sv_width);
2865 else if (in_imgs_count)
2866 width = in_imgs[0]->xsize;
2868 croak("No output image width supplied");
2870 if (SvOK(sv_height))
2871 height = SvIV(sv_height);
2872 else if (in_imgs_count)
2873 height = in_imgs[0]->ysize;
2875 croak("No output image height supplied");
2877 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2878 if (ops_len % sizeof(struct rm_op))
2879 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2880 ops_count = ops_len / sizeof(struct rm_op);
2882 n_regs_count = av_len(av_n_regs)+1;
2883 n_regs = mymalloc(n_regs_count * sizeof(double));
2884 for (i = 0; i < n_regs_count; ++i) {
2885 sv1 = *av_fetch(av_n_regs,i,0);
2887 n_regs[i] = SvNV(sv1);
2889 c_regs_count = av_len(av_c_regs)+1;
2890 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2891 /* I don't bother initializing the colou?r registers */
2893 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2894 n_regs, n_regs_count,
2895 c_regs, c_regs_count, in_imgs, in_imgs_count);
2900 ST(0) = sv_newmortal();
2901 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2902 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2906 i_contrast(im,intensity)
2915 i_noise(im,amount,type)
2921 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2931 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2950 i_postlevels(im,levels)
2960 i_watermark(im,wmark,tx,ty,pixdiff)
2962 Imager::ImgRaw wmark
2969 i_autolevels(im,lsat,usat,skew)
2976 i_radnoise(im,xo,yo,rscale,ascale)
2984 i_turbnoise(im, xo, yo, scale)
3007 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3008 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3009 croak("i_gradgen: Second argument must be an array ref");
3010 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3011 croak("i_gradgen: Third argument must be an array ref");
3012 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3013 croak("i_gradgen: Fourth argument must be an array ref");
3014 axx = (AV *)SvRV(ST(1));
3015 ayy = (AV *)SvRV(ST(2));
3016 ac = (AV *)SvRV(ST(3));
3017 dmeasure = (int)SvIV(ST(4));
3019 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3020 num = num <= av_len(ac) ? num : av_len(ac);
3022 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3023 xo = mymalloc( sizeof(int) * num );
3024 yo = mymalloc( sizeof(int) * num );
3025 ival = mymalloc( sizeof(i_color) * num );
3026 for(i = 0; i<num; i++) {
3027 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3028 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3029 sv = *av_fetch(ac, i, 0);
3030 if ( !sv_derived_from(sv, "Imager::Color") ) {
3031 free(axx); free(ayy); free(ac);
3032 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3034 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3036 i_gradgen(im, num, xo, yo, ival, dmeasure);
3042 i_diff_image(im, im2, mindist=0)
3048 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3058 double ssample_param
3062 i_fountain_seg *segs;
3064 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3065 croak("i_fountain: argument 11 must be an array ref");
3067 asegs = (AV *)SvRV(ST(10));
3068 segs = load_fount_segs(asegs, &count);
3069 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3070 ssample_param, count, segs);
3074 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3083 double ssample_param
3087 i_fountain_seg *segs;
3089 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3090 croak("i_fountain: argument 11 must be an array ref");
3092 asegs = (AV *)SvRV(ST(9));
3093 segs = load_fount_segs(asegs, &count);
3094 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3095 super_sample, ssample_param, count, segs);
3108 errors = i_errors();
3110 while (errors[i].msg) {
3112 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3113 if (!av_store(av, 0, sv)) {
3116 sv = newSViv(errors[i].code);
3117 if (!av_store(av, 1, sv)) {
3120 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3125 i_nearest_color(im, ...)
3140 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3141 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3142 croak("i_nearest_color: Second argument must be an array ref");
3143 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3144 croak("i_nearest_color: Third argument must be an array ref");
3145 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3146 croak("i_nearest_color: Fourth argument must be an array ref");
3147 axx = (AV *)SvRV(ST(1));
3148 ayy = (AV *)SvRV(ST(2));
3149 ac = (AV *)SvRV(ST(3));
3150 dmeasure = (int)SvIV(ST(4));
3152 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3153 num = num <= av_len(ac) ? num : av_len(ac);
3155 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3156 xo = mymalloc( sizeof(int) * num );
3157 yo = mymalloc( sizeof(int) * num );
3158 ival = mymalloc( sizeof(i_color) * num );
3159 for(i = 0; i<num; i++) {
3160 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3161 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3162 sv = *av_fetch(ac, i, 0);
3163 if ( !sv_derived_from(sv, "Imager::Color") ) {
3164 free(axx); free(ayy); free(ac);
3165 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3167 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3169 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3183 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3184 hv=(HV*)SvRV(ST(0));
3185 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3186 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3187 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3196 rc=DSO_open(filename,&evstr);
3200 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3201 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3204 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3210 DSO_close(dso_handle)
3214 DSO_funclist(dso_handle_v)
3218 DSO_handle *dso_handle;
3220 dso_handle=(DSO_handle*)dso_handle_v;
3222 while( dso_handle->function_list[i].name != NULL) {
3224 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3226 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3231 DSO_call(handle,func_index,hv)
3237 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3238 hv=(HV*)SvRV(ST(2));
3239 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3240 DSO_call( (DSO_handle *)handle,func_index,hv);
3245 i_get_pixel(im, x, y)
3252 color = (i_color *)mymalloc(sizeof(i_color));
3253 if (i_gpix(im, x, y, color) == 0) {
3254 RETVAL = NEWSV(0, 0);
3255 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3259 RETVAL = &PL_sv_undef;
3266 i_ppix(im, x, y, cl)
3273 i_img_pal_new(x, y, channels, maxpal)
3280 i_img_to_pal(src, quant)
3286 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3287 croak("i_img_to_pal: second argument must be a hash ref");
3288 hv = (HV *)SvRV(ST(1));
3289 memset(&quant, 0, sizeof(quant));
3290 quant.mc_size = 256;
3291 handle_quant_opts(&quant, hv);
3292 RETVAL = i_img_to_pal(src, &quant);
3294 copy_colors_back(hv, &quant);
3296 cleanup_quant_opts(&quant);
3315 work = mymalloc((r-l) * sizeof(i_palidx));
3316 count = i_gpal(im, l, r, y, work);
3317 if (GIMME_V == G_ARRAY) {
3319 for (i = 0; i < count; ++i) {
3320 PUSHs(sv_2mortal(newSViv(work[i])));
3325 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3330 if (GIMME_V != G_ARRAY) {
3332 PUSHs(&PL_sv_undef);
3337 i_ppal(im, l, y, ...)
3346 work = mymalloc(sizeof(i_palidx) * (items-3));
3347 for (i=0; i < items-3; ++i) {
3348 work[i] = SvIV(ST(i+3));
3350 RETVAL = i_ppal(im, l, l+items-3, y, work);
3360 i_addcolors(im, ...)
3368 croak("i_addcolors: no colors to add");
3369 colors = mymalloc((items-1) * sizeof(i_color));
3370 for (i=0; i < items-1; ++i) {
3371 if (sv_isobject(ST(i+1))
3372 && sv_derived_from(ST(i+1), "Imager::Color")) {
3373 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3374 colors[i] = *INT2PTR(i_color *, tmp);
3378 croak("i_addcolor: pixels must be Imager::Color objects");
3381 index = i_addcolors(im, colors, items-1);
3384 RETVAL = newSVpv("0 but true", 0);
3386 else if (index == -1) {
3387 RETVAL = &PL_sv_undef;
3390 RETVAL = newSViv(index);
3396 i_setcolors(im, index, ...)
3404 croak("i_setcolors: no colors to add");
3405 colors = mymalloc((items-2) * sizeof(i_color));
3406 for (i=0; i < items-2; ++i) {
3407 if (sv_isobject(ST(i+2))
3408 && sv_derived_from(ST(i+2), "Imager::Color")) {
3409 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3410 colors[i] = *INT2PTR(i_color *, tmp);
3414 croak("i_setcolors: pixels must be Imager::Color objects");
3417 RETVAL = i_setcolors(im, index, colors, items-2);
3423 i_getcolors(im, index, ...)
3432 croak("i_getcolors: too many arguments");
3434 count = SvIV(ST(2));
3436 croak("i_getcolors: count must be positive");
3437 colors = mymalloc(sizeof(i_color) * count);
3438 if (i_getcolors(im, index, colors, count)) {
3439 for (i = 0; i < count; ++i) {
3441 SV *sv = sv_newmortal();
3442 pv = mymalloc(sizeof(i_color));
3444 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3460 i_findcolor(im, color)
3466 if (i_findcolor(im, color, &index)) {
3467 RETVAL = newSViv(index);
3470 RETVAL = &PL_sv_undef;
3488 i_gsamp(im, l, r, y, ...)
3500 croak("No channel numbers supplied to g_samp()");
3502 chan_count = items - 4;
3503 chans = mymalloc(sizeof(int) * chan_count);
3504 for (i = 0; i < chan_count; ++i)
3505 chans[i] = SvIV(ST(i+4));
3506 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3507 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3509 if (GIMME_V == G_ARRAY) {
3511 for (i = 0; i < count; ++i)
3512 PUSHs(sv_2mortal(newSViv(data[i])));
3516 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3521 if (GIMME_V != G_ARRAY) {
3523 PUSHs(&PL_sv_undef);
3529 i_img_masked_new(targ, mask, x, y, w, h)
3539 if (!sv_isobject(ST(1))
3540 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3541 croak("i_img_masked_new: parameter 2 must undef or an image");
3543 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3547 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3552 i_plin(im, l, y, ...)
3563 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3564 /* supplied as a byte string */
3565 work = (i_color *)SvPV(ST(3), len);
3566 count = len / sizeof(i_color);
3567 if (count * sizeof(i_color) != len) {
3568 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3570 RETVAL = i_plin(im, l, l+count, y, work);
3573 work = mymalloc(sizeof(i_color) * (items-3));
3574 for (i=0; i < items-3; ++i) {
3575 if (sv_isobject(ST(i+3))
3576 && sv_derived_from(ST(i+3), "Imager::Color")) {
3577 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3578 work[i] = *INT2PTR(i_color *, tmp);
3582 croak("i_plin: pixels must be Imager::Color objects");
3585 RETVAL = i_plin(im, l, l+items-3, y, work);
3596 i_ppixf(im, x, y, cl)
3600 Imager::Color::Float cl
3603 i_gsampf(im, l, r, y, ...)
3615 croak("No channel numbers supplied to g_sampf()");
3617 chan_count = items - 4;
3618 chans = mymalloc(sizeof(int) * chan_count);
3619 for (i = 0; i < chan_count; ++i)
3620 chans[i] = SvIV(ST(i+4));
3621 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3622 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3623 if (GIMME_V == G_ARRAY) {
3625 for (i = 0; i < count; ++i)
3626 PUSHs(sv_2mortal(newSVnv(data[i])));
3630 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3634 if (GIMME_V != G_ARRAY) {
3636 PUSHs(&PL_sv_undef);
3641 i_plinf(im, l, y, ...)
3652 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3653 /* supplied as a byte string */
3654 work = (i_fcolor *)SvPV(ST(3), len);
3655 count = len / sizeof(i_fcolor);
3656 if (count * sizeof(i_fcolor) != len) {
3657 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3659 RETVAL = i_plinf(im, l, l+count, y, work);
3662 work = mymalloc(sizeof(i_fcolor) * (items-3));
3663 for (i=0; i < items-3; ++i) {
3664 if (sv_isobject(ST(i+3))
3665 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3666 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3667 work[i] = *INT2PTR(i_fcolor *, tmp);
3671 croak("i_plinf: pixels must be Imager::Color::Float objects");
3675 RETVAL = i_plinf(im, l, l+items-3, y, work);
3693 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3694 if (i_gpixf(im, x, y, color) == 0) {
3695 RETVAL = NEWSV(0,0);
3696 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3700 RETVAL = &PL_sv_undef;
3716 vals = mymalloc((r-l) * sizeof(i_color));
3717 count = i_glin(im, l, r, y, vals);
3718 if (GIMME_V == G_ARRAY) {
3720 for (i = 0; i < count; ++i) {
3722 i_color *col = mymalloc(sizeof(i_color));
3724 sv = sv_newmortal();
3725 sv_setref_pv(sv, "Imager::Color", (void *)col);
3731 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3737 i_glinf(im, l, r, y)
3747 vals = mymalloc((r-l) * sizeof(i_fcolor));
3748 count = i_glinf(im, l, r, y, vals);
3749 if (GIMME_V == G_ARRAY) {
3751 for (i = 0; i < count; ++i) {
3753 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3755 sv = sv_newmortal();
3756 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3762 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3768 i_img_16_new(x, y, ch)
3774 i_img_double_new(x, y, ch)
3780 i_tags_addn(im, name, code, idata)
3789 name = SvPV(ST(1), len);
3792 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3797 i_tags_add(im, name, code, data, idata)
3807 name = SvPV(ST(1), len);
3811 data = SvPV(ST(3), len);
3816 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3821 i_tags_find(im, name, start)
3828 if (i_tags_find(&im->tags, name, start, &entry)) {
3830 RETVAL = newSVpv("0 but true", 0);
3832 RETVAL = newSViv(entry);
3834 RETVAL = &PL_sv_undef;
3840 i_tags_findn(im, code, start)
3847 if (i_tags_findn(&im->tags, code, start, &entry)) {
3849 RETVAL = newSVpv("0 but true", 0);
3851 RETVAL = newSViv(entry);
3854 RETVAL = &PL_sv_undef;
3860 i_tags_delete(im, entry)
3864 RETVAL = i_tags_delete(&im->tags, entry);
3869 i_tags_delbyname(im, name)
3873 RETVAL = i_tags_delbyname(&im->tags, name);
3878 i_tags_delbycode(im, code)
3882 RETVAL = i_tags_delbycode(&im->tags, code);
3887 i_tags_get(im, index)
3891 if (index >= 0 && index < im->tags.count) {
3892 i_img_tag *entry = im->tags.tags + index;
3896 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3899 PUSHs(sv_2mortal(newSViv(entry->code)));
3902 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3905 PUSHs(sv_2mortal(newSViv(entry->idata)));
3910 i_tags_get_string(im, what_sv)
3914 char const *name = NULL;
3918 if (SvIOK(what_sv)) {
3919 code = SvIV(what_sv);
3923 name = SvPV_nolen(what_sv);
3926 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3928 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3935 RETVAL = im->tags.count;
3942 i_wf_bbox(face, size, text)
3947 int cords[BOUNDING_BOX_COUNT];
3950 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3952 for (i = 0; i < rc; ++i)
3953 PUSHs(sv_2mortal(newSViv(cords[i])));
3957 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3968 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3974 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3985 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3998 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4000 #define FT2_DESTROY(font) i_ft2_destroy(font)
4004 Imager::Font::FT2 font
4006 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4009 i_ft2_new(name, index)
4014 i_ft2_setdpi(font, xdpi, ydpi)
4015 Imager::Font::FT2 font
4021 Imager::Font::FT2 font
4025 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4027 PUSHs(sv_2mortal(newSViv(xdpi)));
4028 PUSHs(sv_2mortal(newSViv(ydpi)));
4032 i_ft2_sethinting(font, hinting)
4033 Imager::Font::FT2 font
4037 i_ft2_settransform(font, matrix)
4038 Imager::Font::FT2 font
4046 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4047 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4048 av=(AV*)SvRV(ST(1));
4052 for (i = 0; i < len; ++i) {
4053 sv1=(*(av_fetch(av,i,0)));
4054 matrix[i] = SvNV(sv1);
4058 RETVAL = i_ft2_settransform(font, matrix);
4063 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4064 Imager::Font::FT2 font
4070 int bbox[BOUNDING_BOX_COUNT];
4076 text = SvPV(text_sv, text_len);
4078 if (SvUTF8(text_sv))
4081 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4084 for (i = 0; i < rc; ++i)
4085 PUSHs(sv_2mortal(newSViv(bbox[i])));
4089 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4090 Imager::Font::FT2 font
4104 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4107 for (i = 0; i < 8; ++i)
4108 PUSHs(sv_2mortal(newSViv(bbox[i])));
4112 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4113 Imager::Font::FT2 font
4129 if (SvUTF8(ST(7))) {
4133 text = SvPV(ST(7), len);
4134 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4135 len, align, aa, vlayout, utf8);
4140 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4141 Imager::Font::FT2 font
4158 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4159 strlen(text), align, aa, vlayout, 1);
4164 ft2_transform_box(font, x0, x1, x2, x3)
4165 Imager::Font::FT2 font
4173 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4174 ft2_transform_box(font, box);
4176 PUSHs(sv_2mortal(newSViv(box[0])));
4177 PUSHs(sv_2mortal(newSViv(box[1])));
4178 PUSHs(sv_2mortal(newSViv(box[2])));
4179 PUSHs(sv_2mortal(newSViv(box[3])));
4182 i_ft2_has_chars(handle, text_sv, utf8)
4183 Imager::Font::FT2 handle
4194 if (SvUTF8(text_sv))
4197 text = SvPV(text_sv, len);
4198 work = mymalloc(len);
4199 count = i_ft2_has_chars(handle, text, len, utf8, work);
4200 if (GIMME_V == G_ARRAY) {
4202 for (i = 0; i < count; ++i) {
4203 PUSHs(sv_2mortal(newSViv(work[i])));
4208 PUSHs(sv_2mortal(newSVpv(work, count)));
4213 i_ft2_face_name(handle)
4214 Imager::Font::FT2 handle
4219 len = i_ft2_face_name(handle, name, sizeof(name));
4222 PUSHs(sv_2mortal(newSVpv(name, 0)));
4226 i_ft2_can_face_name()
4229 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4230 Imager::Font::FT2 handle
4242 if (SvUTF8(text_sv))
4245 text = SvPV(text_sv, work_len);
4250 ch = i_utf8_advance(&text, &len);
4252 i_push_error(0, "invalid UTF8 character");
4261 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4263 PUSHs(sv_2mortal(newSVpv(name, 0)));
4266 PUSHs(&PL_sv_undef);
4271 i_ft2_can_do_glyph_names()
4274 i_ft2_face_has_glyph_names(handle)
4275 Imager::Font::FT2 handle
4278 i_ft2_is_multiple_master(handle)
4279 Imager::Font::FT2 handle
4282 i_ft2_get_multiple_masters(handle)
4283 Imager::Font::FT2 handle
4288 if (i_ft2_get_multiple_masters(handle, &mm)) {
4289 EXTEND(SP, 2+mm.num_axis);
4290 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4291 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4292 for (i = 0; i < mm.num_axis; ++i) {
4296 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4298 av_store(av, 0, sv);
4299 sv = newSViv(mm.axis[i].minimum);
4301 av_store(av, 1, sv);
4302 sv = newSViv(mm.axis[i].maximum);
4304 av_store(av, 2, sv);
4305 PUSHs(newRV_noinc((SV *)av));
4310 i_ft2_set_mm_coords(handle, ...)
4311 Imager::Font::FT2 handle
4317 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4318 transfer the array manually */
4319 ix_coords = items-1;
4320 coords = mymalloc(sizeof(long) * ix_coords);
4321 for (i = 0; i < ix_coords; ++i) {
4322 coords[i] = (long)SvIV(ST(1+i));
4324 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4331 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4335 Imager::FillHandle fill
4337 MODULE = Imager PACKAGE = Imager
4340 i_new_fill_solid(cl, combine)
4345 i_new_fill_solidf(cl, combine)
4346 Imager::Color::Float cl
4350 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4358 unsigned char *cust_hatch;
4362 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4366 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4371 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4372 Imager::Color::Float fg
4373 Imager::Color::Float bg
4379 unsigned char *cust_hatch;
4383 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4387 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4392 i_new_fill_image(src, matrix, xoff, yoff, combine)
4409 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4410 croak("i_new_fill_image: parameter must be an arrayref");
4411 av=(AV*)SvRV(ST(1));
4415 for (i = 0; i < len; ++i) {
4416 sv1=(*(av_fetch(av,i,0)));
4417 matrix[i] = SvNV(sv1);
4423 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);