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, },
564 hv_fetch_bool(HV *hv, char *name, int def) {
567 sv = hv_fetch(hv, name, strlen(name), 0);
576 hv_fetch_int(HV *hv, char *name, int def) {
579 sv = hv_fetch(hv, name, strlen(name), 0);
588 /* look through the hash for quantization options */
589 static void handle_quant_opts(i_quantize *quant, HV *hv)
591 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
597 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
599 sv = hv_fetch(hv, "transp", 6, 0);
600 if (sv && *sv && (str = SvPV(*sv, len))) {
602 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
604 if (quant->transp != tr_none) {
605 quant->tr_threshold = 127;
606 sv = hv_fetch(hv, "tr_threshold", 12, 0);
608 quant->tr_threshold = SvIV(*sv);
610 if (quant->transp == tr_errdiff) {
611 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
612 if (sv && *sv && (str = SvPV(*sv, len)))
613 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
615 if (quant->transp == tr_ordered) {
616 quant->tr_orddith = od_tiny;
617 sv = hv_fetch(hv, "tr_orddith", 10, 0);
618 if (sv && *sv && (str = SvPV(*sv, len)))
619 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
621 if (quant->tr_orddith == od_custom) {
622 sv = hv_fetch(hv, "tr_map", 6, 0);
623 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
624 AV *av = (AV*)SvRV(*sv);
625 len = av_len(av) + 1;
626 if (len > sizeof(quant->tr_custom))
627 len = sizeof(quant->tr_custom);
628 for (i = 0; i < len; ++i) {
629 SV **sv2 = av_fetch(av, i, 0);
631 quant->tr_custom[i] = SvIV(*sv2);
634 while (i < sizeof(quant->tr_custom))
635 quant->tr_custom[i++] = 0;
640 quant->make_colors = mc_addi;
641 sv = hv_fetch(hv, "make_colors", 11, 0);
642 if (sv && *sv && (str = SvPV(*sv, len))) {
644 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
646 sv = hv_fetch(hv, "colors", 6, 0);
647 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
648 /* needs to be an array of Imager::Color
649 note that the caller allocates the mc_color array and sets mc_size
651 AV *av = (AV *)SvRV(*sv);
652 quant->mc_count = av_len(av)+1;
653 if (quant->mc_count > quant->mc_size)
654 quant->mc_count = quant->mc_size;
655 for (i = 0; i < quant->mc_count; ++i) {
656 SV **sv1 = av_fetch(av, i, 0);
657 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
658 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
659 quant->mc_colors[i] = *col;
663 sv = hv_fetch(hv, "max_colors", 10, 0);
666 if (i <= quant->mc_size && i >= quant->mc_count)
670 quant->translate = pt_closest;
671 sv = hv_fetch(hv, "translate", 9, 0);
672 if (sv && *sv && (str = SvPV(*sv, len))) {
673 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
675 sv = hv_fetch(hv, "errdiff", 7, 0);
676 if (sv && *sv && (str = SvPV(*sv, len))) {
677 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
679 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
680 /* get the error diffusion map */
681 sv = hv_fetch(hv, "errdiff_width", 13, 0);
683 quant->ed_width = SvIV(*sv);
684 sv = hv_fetch(hv, "errdiff_height", 14, 0);
686 quant->ed_height = SvIV(*sv);
687 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
689 quant->ed_orig = SvIV(*sv);
690 if (quant->ed_width > 0 && quant->ed_height > 0) {
692 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
693 sv = hv_fetch(hv, "errdiff_map", 11, 0);
694 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
695 AV *av = (AV*)SvRV(*sv);
696 len = av_len(av) + 1;
697 if (len > quant->ed_width * quant->ed_height)
698 len = quant->ed_width * quant->ed_height;
699 for (i = 0; i < len; ++i) {
700 SV **sv2 = av_fetch(av, i, 0);
702 quant->ed_map[i] = SvIV(*sv2);
703 sum += quant->ed_map[i];
709 myfree(quant->ed_map);
711 quant->errdiff = ed_floyd;
715 sv = hv_fetch(hv, "perturb", 7, 0);
717 quant->perturb = SvIV(*sv);
720 static void cleanup_quant_opts(i_quantize *quant) {
721 myfree(quant->mc_colors);
723 myfree(quant->ed_map);
727 /* look through the hash for options to add to opts */
728 static void handle_gif_opts(i_gif_opts *opts, HV *hv)
732 /**((char *)0) = '\0';*/
733 opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
734 opts->interlace = hv_fetch_bool(hv, "interlace", 0);
736 sv = hv_fetch(hv, "gif_delays", 10, 0);
737 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
738 AV *av = (AV*)SvRV(*sv);
739 opts->delay_count = av_len(av)+1;
740 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
741 for (i = 0; i < opts->delay_count; ++i) {
742 SV *sv1 = *av_fetch(av, i, 0);
743 opts->delays[i] = SvIV(sv1);
746 sv = hv_fetch(hv, "gif_user_input", 14, 0);
747 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
748 AV *av = (AV*)SvRV(*sv);
749 opts->user_input_count = av_len(av)+1;
750 opts->user_input_flags = mymalloc(opts->user_input_count);
751 for (i = 0; i < opts->user_input_count; ++i) {
752 SV *sv1 = *av_fetch(av, i, 0);
753 opts->user_input_flags[i] = SvIV(sv1) != 0;
756 sv = hv_fetch(hv, "gif_disposal", 12, 0);
757 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
758 AV *av = (AV*)SvRV(*sv);
759 opts->disposal_count = av_len(av)+1;
760 opts->disposal = mymalloc(opts->disposal_count);
761 for (i = 0; i < opts->disposal_count; ++i) {
762 SV *sv1 = *av_fetch(av, i, 0);
763 opts->disposal[i] = SvIV(sv1);
766 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
767 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
768 i_color *col = INT2PTR(i_color *, SvIV((SV *)SvRV(*sv)));
769 opts->tran_color = *col;
771 sv = hv_fetch(hv, "gif_positions", 13, 0);
772 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
773 AV *av = (AV *)SvRV(*sv);
774 opts->position_count = av_len(av) + 1;
775 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
776 for (i = 0; i < opts->position_count; ++i) {
777 SV **sv2 = av_fetch(av, i, 0);
778 opts->positions[i].x = opts->positions[i].y = 0;
779 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
780 AV *av2 = (AV*)SvRV(*sv2);
782 sv3 = av_fetch(av2, 0, 0);
784 opts->positions[i].x = SvIV(*sv3);
785 sv3 = av_fetch(av2, 1, 0);
787 opts->positions[i].y = SvIV(*sv3);
791 /* Netscape2.0 loop count extension */
792 opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
794 opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
797 static void cleanup_gif_opts(i_gif_opts *opts) {
799 myfree(opts->delays);
800 if (opts->user_input_flags)
801 myfree(opts->user_input_flags);
803 myfree(opts->disposal);
805 myfree(opts->positions);
810 /* copies the color map from the hv into the colors member of the HV */
811 static void copy_colors_back(HV *hv, i_quantize *quant) {
817 sv = hv_fetch(hv, "colors", 6, 0);
818 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
821 ref = newRV_inc((SV*) av);
822 sv = hv_store(hv, "colors", 6, ref, 0);
825 av = (AV *)SvRV(*sv);
827 av_extend(av, quant->mc_count+1);
828 for (i = 0; i < quant->mc_count; ++i) {
829 i_color *in = quant->mc_colors+i;
830 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
831 work = sv_newmortal();
832 sv_setref_pv(work, "Imager::Color", (void *)c);
834 if (!av_store(av, i, work)) {
840 /* loads the segments of a fountain fill into an array */
841 static i_fountain_seg *
842 load_fount_segs(AV *asegs, int *count) {
843 /* Each element of segs must contain:
844 [ start, middle, end, c0, c1, segtype, colortrans ]
845 start, middle, end are doubles from 0 to 1
846 c0, c1 are Imager::Color::Float or Imager::Color objects
847 segtype, colortrans are ints
851 i_fountain_seg *segs;
855 *count = av_len(asegs)+1;
857 croak("i_fountain must have at least one segment");
858 segs = mymalloc(sizeof(i_fountain_seg) * *count);
859 for(i = 0; i < *count; i++) {
860 SV **sv1 = av_fetch(asegs, i, 0);
861 if (!sv1 || !*sv1 || !SvROK(*sv1)
862 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
864 croak("i_fountain: segs must be an arrayref of arrayrefs");
866 aseg = (AV *)SvRV(*sv1);
867 if (av_len(aseg) != 7-1) {
869 croak("i_fountain: a segment must have 7 members");
871 for (j = 0; j < 3; ++j) {
872 SV **sv2 = av_fetch(aseg, j, 0);
875 croak("i_fountain: XS error");
877 work[j] = SvNV(*sv2);
879 segs[i].start = work[0];
880 segs[i].middle = work[1];
881 segs[i].end = work[2];
882 for (j = 0; j < 2; ++j) {
883 SV **sv3 = av_fetch(aseg, 3+j, 0);
884 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
885 (!sv_derived_from(*sv3, "Imager::Color")
886 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
888 croak("i_fountain: segs must contain colors in elements 3 and 4");
890 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
891 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
894 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
896 for (ch = 0; ch < MAXCHANNELS; ++ch) {
897 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
901 for (j = 0; j < 2; ++j) {
902 SV **sv2 = av_fetch(aseg, j+5, 0);
905 croak("i_fountain: XS error");
907 worki[j] = SvIV(*sv2);
909 segs[i].type = worki[0];
910 segs[i].color = worki[1];
916 /* I don't think ICLF_* names belong at the C interface
917 this makes the XS code think we have them, to let us avoid
918 putting function bodies in the XS code
920 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
921 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
923 /* for the fill objects
924 Since a fill object may later have dependent images, (or fills!)
925 we need perl wrappers - oh well
927 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
928 typedef i_fill_t* Imager__FillHandle;
930 /* the m_init_log() function was called init_log(), renamed to reduce
931 potential naming conflicts */
932 #define init_log m_init_log
934 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
937 ICL_new_internal(r,g,b,a)
949 ICL_set_internal(cl,r,g,b,a)
956 ICL_set_internal(cl, r, g, b, a);
970 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
971 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
972 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
973 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
979 RETVAL = mymalloc(sizeof(i_color));
981 i_hsv_to_rgb(RETVAL);
989 RETVAL = mymalloc(sizeof(i_color));
991 i_rgb_to_hsv(RETVAL);
997 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1000 ICLF_new_internal(r, g, b, a)
1008 Imager::Color::Float cl
1012 Imager::Color::Float cl
1016 EXTEND(SP, MAXCHANNELS);
1017 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1018 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1019 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1023 ICLF_set_internal(cl,r,g,b,a)
1024 Imager::Color::Float cl
1037 Imager::Color::Float
1039 Imager::Color::Float c
1041 RETVAL = mymalloc(sizeof(i_fcolor));
1043 i_hsv_to_rgbf(RETVAL);
1047 Imager::Color::Float
1049 Imager::Color::Float c
1051 RETVAL = mymalloc(sizeof(i_fcolor));
1053 i_rgb_to_hsvf(RETVAL);
1058 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1072 MODULE = Imager PACKAGE = Imager
1091 SvPV(ST(0), length);
1092 SvREFCNT_inc(ST(0));
1093 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1098 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1107 cbd = mymalloc(sizeof(struct cbdata));
1108 SvREFCNT_inc(writecb);
1109 cbd->writecb = writecb;
1110 SvREFCNT_inc(readcb);
1111 cbd->readcb = readcb;
1112 SvREFCNT_inc(seekcb);
1113 cbd->seekcb = seekcb;
1114 SvREFCNT_inc(closecb);
1115 cbd->closecb = closecb;
1116 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1117 if (maxwrite > CBDATA_BUFSIZE)
1118 maxwrite = CBDATA_BUFSIZE;
1119 cbd->maxlength = maxwrite;
1120 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1129 unsigned char* data;
1133 tlength = io_slurp(ig, &data);
1135 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1139 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1146 MODULE = Imager PACKAGE = Imager
1159 while( (item=i_format_list[i++]) != NULL ) {
1161 PUSHs(sv_2mortal(newSVpv(item,0)));
1178 i_img_empty_ch(im,x,y,ch)
1185 i_sametype(im, x, y)
1191 i_sametype_chans(im, x, y, channels)
1198 m_init_log(name,level)
1203 log_entry(string,level)
1222 i_img_info(im,info);
1224 PUSHs(sv_2mortal(newSViv(info[0])));
1225 PUSHs(sv_2mortal(newSViv(info[1])));
1226 PUSHs(sv_2mortal(newSViv(info[2])));
1227 PUSHs(sv_2mortal(newSViv(info[3])));
1233 i_img_setmask(im,ch_mask)
1242 i_img_getchannels(im)
1251 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1256 i_line(im,x1,y1,x2,y2,val,endp)
1266 i_line_aa(im,x1,y1,x2,y2,val,endp)
1276 i_box(im,x1,y1,x2,y2,val)
1285 i_box_filled(im,x1,y1,x2,y2,val)
1294 i_box_cfill(im,x1,y1,x2,y2,fill)
1300 Imager::FillHandle fill
1303 i_arc(im,x,y,rad,d1,d2,val)
1313 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1320 Imager::FillHandle fill
1325 i_circle_aa(im,x,y,rad,val)
1335 i_bezier_multi(im,xc,yc,val)
1348 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1349 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1350 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1351 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1352 av1=(AV*)SvRV(ST(1));
1353 av2=(AV*)SvRV(ST(2));
1354 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1356 x=mymalloc( len*sizeof(double) );
1357 y=mymalloc( len*sizeof(double) );
1358 for(i=0;i<len;i++) {
1359 sv1=(*(av_fetch(av1,i,0)));
1360 sv2=(*(av_fetch(av2,i,0)));
1361 x[i]=(double)SvNV(sv1);
1362 y[i]=(double)SvNV(sv2);
1364 i_bezier_multi(im,len,x,y,val);
1370 i_poly_aa(im,xc,yc,val)
1383 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1384 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1385 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1386 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1387 av1=(AV*)SvRV(ST(1));
1388 av2=(AV*)SvRV(ST(2));
1389 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1391 x=mymalloc( len*sizeof(double) );
1392 y=mymalloc( len*sizeof(double) );
1393 for(i=0;i<len;i++) {
1394 sv1=(*(av_fetch(av1,i,0)));
1395 sv2=(*(av_fetch(av2,i,0)));
1396 x[i]=(double)SvNV(sv1);
1397 y[i]=(double)SvNV(sv2);
1399 i_poly_aa(im,len,x,y,val);
1404 i_poly_aa_cfill(im,xc,yc,fill)
1406 Imager::FillHandle fill
1416 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1417 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1418 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1419 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1420 av1=(AV*)SvRV(ST(1));
1421 av2=(AV*)SvRV(ST(2));
1422 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1424 x=mymalloc( len*sizeof(double) );
1425 y=mymalloc( len*sizeof(double) );
1426 for(i=0;i<len;i++) {
1427 sv1=(*(av_fetch(av1,i,0)));
1428 sv2=(*(av_fetch(av2,i,0)));
1429 x[i]=(double)SvNV(sv1);
1430 y[i]=(double)SvNV(sv2);
1432 i_poly_aa_cfill(im,len,x,y,fill);
1439 i_flood_fill(im,seedx,seedy,dcol)
1446 i_flood_cfill(im,seedx,seedy,fill)
1450 Imager::FillHandle fill
1454 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1466 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1484 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1496 i_flipxy(im, direction)
1501 i_rotate90(im, degrees)
1506 i_rotate_exact(im, amount, ...)
1510 i_color *backp = NULL;
1511 i_fcolor *fbackp = NULL;
1515 /* extract the bg colors if any */
1516 /* yes, this is kind of strange */
1517 for (i = 2; i < items; ++i) {
1519 if (sv_derived_from(sv1, "Imager::Color")) {
1520 IV tmp = SvIV((SV*)SvRV(sv1));
1521 backp = INT2PTR(i_color *, tmp);
1523 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1524 IV tmp = SvIV((SV*)SvRV(sv1));
1525 fbackp = INT2PTR(i_fcolor *, tmp);
1528 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1533 i_matrix_transform(im, xsize, ysize, matrix, ...)
1543 i_color *backp = NULL;
1544 i_fcolor *fbackp = NULL;
1546 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1547 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1548 av=(AV*)SvRV(ST(3));
1552 for (i = 0; i < len; ++i) {
1553 sv1=(*(av_fetch(av,i,0)));
1554 matrix[i] = SvNV(sv1);
1558 /* extract the bg colors if any */
1559 /* yes, this is kind of strange */
1560 for (i = 4; i < items; ++i) {
1562 if (sv_derived_from(sv1, "Imager::Color")) {
1563 IV tmp = SvIV((SV*)SvRV(sv1));
1564 backp = INT2PTR(i_color *, tmp);
1566 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1567 IV tmp = SvIV((SV*)SvRV(sv1));
1568 fbackp = INT2PTR(i_fcolor *, tmp);
1571 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1576 i_gaussian(im,stdev)
1581 i_unsharp_mask(im,stdev,scale)
1596 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1597 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1598 av=(AV*)SvRV(ST(1));
1600 coeff=mymalloc( len*sizeof(float) );
1601 for(i=0;i<len;i++) {
1602 sv1=(*(av_fetch(av,i,0)));
1603 coeff[i]=(float)SvNV(sv1);
1605 i_conv(im,coeff,len);
1609 i_convert(im, src, coeff)
1622 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1623 croak("i_convert: parameter 3 must be an arrayref\n");
1624 avmain = (AV*)SvRV(ST(2));
1625 outchan = av_len(avmain)+1;
1626 /* find the biggest */
1628 for (j=0; j < outchan; ++j) {
1629 temp = av_fetch(avmain, j, 0);
1630 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1631 avsub = (AV*)SvRV(*temp);
1632 len = av_len(avsub)+1;
1637 coeff = mymalloc(sizeof(float) * outchan * inchan);
1638 for (j = 0; j < outchan; ++j) {
1639 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1640 len = av_len(avsub)+1;
1641 for (i = 0; i < len; ++i) {
1642 temp = av_fetch(avsub, i, 0);
1644 coeff[i+j*inchan] = SvNV(*temp);
1646 coeff[i+j*inchan] = 0;
1649 coeff[i++ + j*inchan] = 0;
1651 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1661 unsigned int mask = 0;
1667 unsigned char (*maps)[256];
1669 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1670 croak("i_map: parameter 2 must be an arrayref\n");
1671 avmain = (AV*)SvRV(ST(1));
1672 len = av_len(avmain)+1;
1673 if (im->channels < len) len = im->channels;
1675 maps = mymalloc( len * sizeof(unsigned char [256]) );
1677 for (j=0; j<len ; j++) {
1678 temp = av_fetch(avmain, j, 0);
1679 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1680 avsub = (AV*)SvRV(*temp);
1681 if(av_len(avsub) != 255) continue;
1683 for (i=0; i<256 ; i++) {
1685 temp = av_fetch(avsub, i, 0);
1686 val = temp ? SvIV(*temp) : 0;
1688 if (val>255) val = 255;
1693 i_map(im, maps, mask);
1706 i_init_fonts(t1log=0)
1721 i_t1_destroy(font_id)
1726 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1745 str = SvPV(str_sv, len);
1746 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1753 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1762 int cords[BOUNDING_BOX_COUNT];
1770 str = SvPV(str_sv, len);
1771 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1774 for (i = 0; i < rc; ++i)
1775 PUSHs(sv_2mortal(newSViv(cords[i])));
1781 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1800 str = SvPV(str_sv, len);
1801 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1807 i_t1_has_chars(handle, text_sv, utf8 = 0)
1819 if (SvUTF8(text_sv))
1822 text = SvPV(text_sv, len);
1823 work = mymalloc(len);
1824 count = i_t1_has_chars(handle, text, len, utf8, work);
1825 if (GIMME_V == G_ARRAY) {
1827 for (i = 0; i < count; ++i) {
1828 PUSHs(sv_2mortal(newSViv(work[i])));
1833 PUSHs(sv_2mortal(newSVpv(work, count)));
1838 i_t1_face_name(handle)
1844 len = i_t1_face_name(handle, name, sizeof(name));
1847 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1851 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1863 if (SvUTF8(text_sv))
1866 text = SvPV(text_sv, work_len);
1871 ch = i_utf8_advance(&text, &len);
1873 i_push_error(0, "invalid UTF8 character");
1882 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1883 PUSHs(sv_2mortal(newSVpv(name, 0)));
1886 PUSHs(&PL_sv_undef);
1900 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1902 #define TT_DESTROY(handle) i_tt_destroy(handle)
1906 Imager::Font::TT handle
1909 MODULE = Imager PACKAGE = Imager
1913 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
1914 Imager::Font::TT handle
1932 str = SvPV(str_sv, len);
1933 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1940 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
1941 Imager::Font::TT handle
1959 str = SvPV(str_sv, len);
1960 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1967 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1968 Imager::Font::TT handle
1974 int cords[BOUNDING_BOX_COUNT],rc;
1983 str = SvPV(str_sv, len);
1984 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1986 for (i = 0; i < rc; ++i) {
1987 PUSHs(sv_2mortal(newSViv(cords[i])));
1992 i_tt_has_chars(handle, text_sv, utf8)
1993 Imager::Font::TT handle
2004 if (SvUTF8(text_sv))
2007 text = SvPV(text_sv, len);
2008 work = mymalloc(len);
2009 count = i_tt_has_chars(handle, text, len, utf8, work);
2010 if (GIMME_V == G_ARRAY) {
2012 for (i = 0; i < count; ++i) {
2013 PUSHs(sv_2mortal(newSViv(work[i])));
2018 PUSHs(sv_2mortal(newSVpv(work, count)));
2023 i_tt_dump_names(handle)
2024 Imager::Font::TT handle
2027 i_tt_face_name(handle)
2028 Imager::Font::TT handle
2033 len = i_tt_face_name(handle, name, sizeof(name));
2036 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2040 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2041 Imager::Font::TT handle
2052 if (SvUTF8(text_sv))
2055 text = SvPV(text_sv, work_len);
2060 ch = i_utf8_advance(&text, &len);
2062 i_push_error(0, "invalid UTF8 character");
2071 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2072 PUSHs(sv_2mortal(newSVpv(name, 0)));
2075 PUSHs(&PL_sv_undef);
2084 i_writejpeg_wiol(im, ig, qfactor)
2100 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2101 if (iptc_itext == NULL) {
2104 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2109 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2111 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2120 i_test_format_probe(ig, length)
2129 i_readtiff_wiol(ig, length)
2134 i_readtiff_multi_wiol(ig, length)
2142 imgs = i_readtiff_multi_wiol(ig, length, &count);
2145 for (i = 0; i < count; ++i) {
2146 SV *sv = sv_newmortal();
2147 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2155 i_writetiff_wiol(im, ig)
2160 i_writetiff_multi_wiol(ig, ...)
2168 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2169 img_count = items - 1;
2171 if (img_count < 1) {
2174 i_push_error(0, "You need to specify images to save");
2177 imgs = mymalloc(sizeof(i_img *) * img_count);
2178 for (i = 0; i < img_count; ++i) {
2181 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2182 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2186 i_push_error(0, "Only images can be saved");
2193 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2201 i_writetiff_wiol_faxable(im, ig, fine)
2207 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2216 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2217 img_count = items - 2;
2219 if (img_count < 1) {
2222 i_push_error(0, "You need to specify images to save");
2225 imgs = mymalloc(sizeof(i_img *) * img_count);
2226 for (i = 0; i < img_count; ++i) {
2229 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2230 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2234 i_push_error(0, "Only images can be saved");
2241 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2249 #endif /* HAVE_LIBTIFF */
2255 i_readpng_wiol(ig, length)
2261 i_writepng_wiol(im, ig)
2274 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2277 i_writegif(im,fd,colors,pixdev,fixed)
2284 Imager__Color fixed;
2291 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2292 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2293 av=(AV*)SvRV(ST(4));
2294 fixedlen=av_len(av)+1;
2295 fixed=mymalloc( fixedlen*sizeof(i_color) );
2296 for(i=0;i<fixedlen;i++) {
2297 sv1=(*(av_fetch(av,i,0)));
2298 if (sv_derived_from(sv1, "Imager::Color")) {
2299 Itmp = SvIV((SV*)SvRV(sv1));
2300 tmp = INT2PTR(i_color*, Itmp);
2301 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2304 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2306 ST(0) = sv_newmortal();
2307 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2308 else sv_setiv(ST(0), (IV)RETVAL);
2314 i_writegifmc(im,fd,colors)
2321 i_writegif_gen(fd, ...)
2326 i_img **imgs = NULL;
2332 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2333 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2334 croak("i_writegif_gen: Second argument must be a hash ref");
2335 hv = (HV *)SvRV(ST(1));
2336 memset(&quant, 0, sizeof(quant));
2337 quant.mc_size = 256;
2338 handle_quant_opts(&quant, hv);
2339 img_count = items - 2;
2341 if (img_count < 1) {
2344 i_push_error(0, "You need to specify images to save");
2347 imgs = mymalloc(sizeof(i_img *) * img_count);
2348 for (i = 0; i < img_count; ++i) {
2351 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2352 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2356 i_push_error(0, "Only images can be saved");
2362 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2366 copy_colors_back(hv, &quant);
2369 ST(0) = sv_newmortal();
2370 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2371 else sv_setiv(ST(0), (IV)RETVAL);
2372 cleanup_quant_opts(&quant);
2376 i_writegif_callback(cb, maxbuffer,...)
2380 i_img **imgs = NULL;
2387 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2388 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2389 croak("i_writegif_callback: Second argument must be a hash ref");
2390 hv = (HV *)SvRV(ST(2));
2391 memset(&quant, 0, sizeof(quant));
2392 quant.mc_size = 256;
2393 handle_quant_opts(&quant, hv);
2394 img_count = items - 3;
2396 if (img_count < 1) {
2400 imgs = mymalloc(sizeof(i_img *) * img_count);
2401 for (i = 0; i < img_count; ++i) {
2404 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2405 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2414 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2418 copy_colors_back(hv, &quant);
2421 ST(0) = sv_newmortal();
2422 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2423 else sv_setiv(ST(0), (IV)RETVAL);
2424 cleanup_quant_opts(&quant);
2427 i_writegif_wiol(ig, opts,...)
2431 i_img **imgs = NULL;
2437 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2438 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2439 croak("i_writegif_callback: Second argument must be a hash ref");
2440 hv = (HV *)SvRV(ST(1));
2441 memset(&quant, 0, sizeof(quant));
2442 quant.mc_size = 256;
2443 handle_quant_opts(&quant, hv);
2444 img_count = items - 2;
2446 if (img_count < 1) {
2450 imgs = mymalloc(sizeof(i_img *) * img_count);
2451 for (i = 0; i < img_count; ++i) {
2454 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2455 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2463 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2467 copy_colors_back(hv, &quant);
2470 ST(0) = sv_newmortal();
2471 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2472 else sv_setiv(ST(0), (IV)RETVAL);
2473 cleanup_quant_opts(&quant);
2486 colour_table = NULL;
2489 if(GIMME_V == G_ARRAY) {
2490 rimg = i_readgif(fd,&colour_table,&colours);
2492 /* don't waste time with colours if they aren't wanted */
2493 rimg = i_readgif(fd,NULL,NULL);
2496 if (colour_table == NULL) {
2499 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2502 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2503 /* I don't know if I have the reference counts right or not :( */
2504 /* Neither do I :-) */
2505 /* No Idea here either */
2508 av_extend(ct, colours);
2509 for(q=0; q<colours; q++) {
2511 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2512 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2514 myfree(colour_table);
2518 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2520 PUSHs(newRV_noinc((SV*)ct));
2534 colour_table = NULL;
2537 if(GIMME_V == G_ARRAY) {
2538 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2540 /* don't waste time with colours if they aren't wanted */
2541 rimg = i_readgif_wiol(ig,NULL,NULL);
2544 if (colour_table == NULL) {
2547 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2550 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2551 /* I don't know if I have the reference counts right or not :( */
2552 /* Neither do I :-) */
2553 /* No Idea here either */
2556 av_extend(ct, colours);
2557 for(q=0; q<colours; q++) {
2559 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2560 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2562 myfree(colour_table);
2566 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2568 PUSHs(newRV_noinc((SV*)ct));
2572 i_readgif_scalar(...)
2584 data = (char *)SvPV(ST(0), length);
2588 if(GIMME_V == G_ARRAY) {
2589 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2591 /* don't waste time with colours if they aren't wanted */
2592 rimg=i_readgif_scalar(data,length,NULL,NULL);
2595 if (colour_table == NULL) {
2598 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2601 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2602 /* I don't know if I have the reference counts right or not :( */
2603 /* Neither do I :-) */
2605 av_extend(ct, colours);
2606 for(q=0; q<colours; q++) {
2608 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2609 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2611 myfree(colour_table);
2615 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2617 PUSHs(newRV_noinc((SV*)ct));
2621 i_readgif_callback(...)
2636 if(GIMME_V == G_ARRAY) {
2637 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2639 /* don't waste time with colours if they aren't wanted */
2640 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2643 if (colour_table == NULL) {
2646 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2649 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2650 /* I don't know if I have the reference counts right or not :( */
2651 /* Neither do I :-) */
2652 /* Neither do I - maybe I'll move this somewhere */
2654 av_extend(ct, colours);
2655 for(q=0; q<colours; q++) {
2657 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2658 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2660 myfree(colour_table);
2664 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2666 PUSHs(newRV_noinc((SV*)ct));
2677 imgs = i_readgif_multi(fd, &count);
2680 for (i = 0; i < count; ++i) {
2681 SV *sv = sv_newmortal();
2682 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2689 i_readgif_multi_scalar(data)
2697 data = (char *)SvPV(ST(0), length);
2698 imgs = i_readgif_multi_scalar(data, length, &count);
2701 for (i = 0; i < count; ++i) {
2702 SV *sv = sv_newmortal();
2703 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2710 i_readgif_multi_callback(cb)
2718 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2721 for (i = 0; i < count; ++i) {
2722 SV *sv = sv_newmortal();
2723 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2730 i_readgif_multi_wiol(ig)
2737 imgs = i_readgif_multi_wiol(ig, &count);
2740 for (i = 0; i < count; ++i) {
2741 SV *sv = sv_newmortal();
2742 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2754 i_readpnm_wiol(ig, length)
2760 i_writeppm_wiol(im, ig)
2766 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2775 i_writeraw_wiol(im,ig)
2780 i_writebmp_wiol(im,ig)
2790 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2799 idlen = SvCUR(ST(4));
2800 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2806 i_readtga_wiol(ig, length)
2812 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2821 idlen = SvCUR(ST(4));
2822 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2828 i_readrgb_wiol(ig, length)
2835 i_scaleaxis(im,Value,Axis)
2841 i_scale_nn(im,scx,scy)
2851 i_count_colors(im,maxc)
2857 i_transform(im,opx,opy,parm)
2870 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2871 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2872 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2873 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2874 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2875 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2876 av=(AV*)SvRV(ST(1));
2878 opx=mymalloc( opxl*sizeof(int) );
2879 for(i=0;i<opxl;i++) {
2880 sv1=(*(av_fetch(av,i,0)));
2881 opx[i]=(int)SvIV(sv1);
2883 av=(AV*)SvRV(ST(2));
2885 opy=mymalloc( opyl*sizeof(int) );
2886 for(i=0;i<opyl;i++) {
2887 sv1=(*(av_fetch(av,i,0)));
2888 opy[i]=(int)SvIV(sv1);
2890 av=(AV*)SvRV(ST(3));
2891 parmlen=av_len(av)+1;
2892 parm=mymalloc( parmlen*sizeof(double) );
2893 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2894 sv1=(*(av_fetch(av,i,0)));
2895 parm[i]=(double)SvNV(sv1);
2897 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2901 ST(0) = sv_newmortal();
2902 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2903 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2906 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2931 in_imgs_count = av_len(av_in_imgs)+1;
2932 for (i = 0; i < in_imgs_count; ++i) {
2933 sv1 = *av_fetch(av_in_imgs, i, 0);
2934 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2935 croak("sv_in_img must contain only images");
2938 if (in_imgs_count > 0) {
2939 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2940 for (i = 0; i < in_imgs_count; ++i) {
2941 sv1 = *av_fetch(av_in_imgs,i,0);
2942 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2943 croak("Parameter 5 must contain only images");
2945 tmp = SvIV((SV*)SvRV(sv1));
2946 in_imgs[i] = INT2PTR(i_img*, tmp);
2950 /* no input images */
2953 /* default the output size from the first input if possible */
2955 width = SvIV(sv_width);
2956 else if (in_imgs_count)
2957 width = in_imgs[0]->xsize;
2959 croak("No output image width supplied");
2961 if (SvOK(sv_height))
2962 height = SvIV(sv_height);
2963 else if (in_imgs_count)
2964 height = in_imgs[0]->ysize;
2966 croak("No output image height supplied");
2968 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2969 if (ops_len % sizeof(struct rm_op))
2970 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2971 ops_count = ops_len / sizeof(struct rm_op);
2973 n_regs_count = av_len(av_n_regs)+1;
2974 n_regs = mymalloc(n_regs_count * sizeof(double));
2975 for (i = 0; i < n_regs_count; ++i) {
2976 sv1 = *av_fetch(av_n_regs,i,0);
2978 n_regs[i] = SvNV(sv1);
2980 c_regs_count = av_len(av_c_regs)+1;
2981 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2982 /* I don't bother initializing the colou?r registers */
2984 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2985 n_regs, n_regs_count,
2986 c_regs, c_regs_count, in_imgs, in_imgs_count);
2991 ST(0) = sv_newmortal();
2992 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2993 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2997 i_contrast(im,intensity)
3006 i_noise(im,amount,type)
3012 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3022 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3041 i_postlevels(im,levels)
3051 i_watermark(im,wmark,tx,ty,pixdiff)
3053 Imager::ImgRaw wmark
3060 i_autolevels(im,lsat,usat,skew)
3067 i_radnoise(im,xo,yo,rscale,ascale)
3075 i_turbnoise(im, xo, yo, scale)
3098 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3099 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3100 croak("i_gradgen: Second argument must be an array ref");
3101 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3102 croak("i_gradgen: Third argument must be an array ref");
3103 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3104 croak("i_gradgen: Fourth argument must be an array ref");
3105 axx = (AV *)SvRV(ST(1));
3106 ayy = (AV *)SvRV(ST(2));
3107 ac = (AV *)SvRV(ST(3));
3108 dmeasure = (int)SvIV(ST(4));
3110 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3111 num = num <= av_len(ac) ? num : av_len(ac);
3113 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3114 xo = mymalloc( sizeof(int) * num );
3115 yo = mymalloc( sizeof(int) * num );
3116 ival = mymalloc( sizeof(i_color) * num );
3117 for(i = 0; i<num; i++) {
3118 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3119 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3120 sv = *av_fetch(ac, i, 0);
3121 if ( !sv_derived_from(sv, "Imager::Color") ) {
3122 free(axx); free(ayy); free(ac);
3123 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3125 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3127 i_gradgen(im, num, xo, yo, ival, dmeasure);
3133 i_diff_image(im, im2, mindist=0)
3139 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3149 double ssample_param
3153 i_fountain_seg *segs;
3155 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3156 croak("i_fountain: argument 11 must be an array ref");
3158 asegs = (AV *)SvRV(ST(10));
3159 segs = load_fount_segs(asegs, &count);
3160 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3161 ssample_param, count, segs);
3165 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3174 double ssample_param
3178 i_fountain_seg *segs;
3180 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3181 croak("i_fountain: argument 11 must be an array ref");
3183 asegs = (AV *)SvRV(ST(9));
3184 segs = load_fount_segs(asegs, &count);
3185 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3186 super_sample, ssample_param, count, segs);
3199 errors = i_errors();
3201 while (errors[i].msg) {
3203 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3204 if (!av_store(av, 0, sv)) {
3207 sv = newSViv(errors[i].code);
3208 if (!av_store(av, 1, sv)) {
3211 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3216 i_nearest_color(im, ...)
3231 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3232 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3233 croak("i_nearest_color: Second argument must be an array ref");
3234 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3235 croak("i_nearest_color: Third argument must be an array ref");
3236 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3237 croak("i_nearest_color: Fourth argument must be an array ref");
3238 axx = (AV *)SvRV(ST(1));
3239 ayy = (AV *)SvRV(ST(2));
3240 ac = (AV *)SvRV(ST(3));
3241 dmeasure = (int)SvIV(ST(4));
3243 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3244 num = num <= av_len(ac) ? num : av_len(ac);
3246 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3247 xo = mymalloc( sizeof(int) * num );
3248 yo = mymalloc( sizeof(int) * num );
3249 ival = mymalloc( sizeof(i_color) * num );
3250 for(i = 0; i<num; i++) {
3251 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3252 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3253 sv = *av_fetch(ac, i, 0);
3254 if ( !sv_derived_from(sv, "Imager::Color") ) {
3255 free(axx); free(ayy); free(ac);
3256 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3258 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3260 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3274 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3275 hv=(HV*)SvRV(ST(0));
3276 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3277 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3278 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3287 rc=DSO_open(filename,&evstr);
3291 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3292 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3295 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3301 DSO_close(dso_handle)
3305 DSO_funclist(dso_handle_v)
3309 DSO_handle *dso_handle;
3311 dso_handle=(DSO_handle*)dso_handle_v;
3313 while( dso_handle->function_list[i].name != NULL) {
3315 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3317 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3322 DSO_call(handle,func_index,hv)
3328 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3329 hv=(HV*)SvRV(ST(2));
3330 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3331 DSO_call( (DSO_handle *)handle,func_index,hv);
3336 i_get_pixel(im, x, y)
3343 color = (i_color *)mymalloc(sizeof(i_color));
3344 if (i_gpix(im, x, y, color) == 0) {
3345 RETVAL = NEWSV(0, 0);
3346 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3350 RETVAL = &PL_sv_undef;
3357 i_ppix(im, x, y, cl)
3364 i_img_pal_new(x, y, channels, maxpal)
3371 i_img_to_pal(src, quant)
3377 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3378 croak("i_img_to_pal: second argument must be a hash ref");
3379 hv = (HV *)SvRV(ST(1));
3380 memset(&quant, 0, sizeof(quant));
3381 quant.mc_size = 256;
3382 handle_quant_opts(&quant, hv);
3383 RETVAL = i_img_to_pal(src, &quant);
3385 copy_colors_back(hv, &quant);
3387 cleanup_quant_opts(&quant);
3406 work = mymalloc((r-l) * sizeof(i_palidx));
3407 count = i_gpal(im, l, r, y, work);
3408 if (GIMME_V == G_ARRAY) {
3410 for (i = 0; i < count; ++i) {
3411 PUSHs(sv_2mortal(newSViv(work[i])));
3416 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3421 if (GIMME_V != G_ARRAY) {
3423 PUSHs(&PL_sv_undef);
3428 i_ppal(im, l, y, ...)
3437 work = mymalloc(sizeof(i_palidx) * (items-3));
3438 for (i=0; i < items-3; ++i) {
3439 work[i] = SvIV(ST(i+3));
3441 RETVAL = i_ppal(im, l, l+items-3, y, work);
3451 i_addcolors(im, ...)
3459 croak("i_addcolors: no colors to add");
3460 colors = mymalloc((items-1) * sizeof(i_color));
3461 for (i=0; i < items-1; ++i) {
3462 if (sv_isobject(ST(i+1))
3463 && sv_derived_from(ST(i+1), "Imager::Color")) {
3464 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3465 colors[i] = *INT2PTR(i_color *, tmp);
3469 croak("i_plin: pixels must be Imager::Color objects");
3472 index = i_addcolors(im, colors, items-1);
3475 RETVAL = newSVpv("0 but true", 0);
3477 else if (index == -1) {
3478 RETVAL = &PL_sv_undef;
3481 RETVAL = newSViv(index);
3487 i_setcolors(im, index, ...)
3495 croak("i_setcolors: no colors to add");
3496 colors = mymalloc((items-2) * sizeof(i_color));
3497 for (i=0; i < items-2; ++i) {
3498 if (sv_isobject(ST(i+2))
3499 && sv_derived_from(ST(i+2), "Imager::Color")) {
3500 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3501 colors[i] = *INT2PTR(i_color *, tmp);
3505 croak("i_setcolors: pixels must be Imager::Color objects");
3508 RETVAL = i_setcolors(im, index, colors, items-2);
3514 i_getcolors(im, index, ...)
3523 croak("i_getcolors: too many arguments");
3525 count = SvIV(ST(2));
3527 croak("i_getcolors: count must be positive");
3528 colors = mymalloc(sizeof(i_color) * count);
3529 if (i_getcolors(im, index, colors, count)) {
3530 for (i = 0; i < count; ++i) {
3532 SV *sv = sv_newmortal();
3533 pv = mymalloc(sizeof(i_color));
3535 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3551 i_findcolor(im, color)
3557 if (i_findcolor(im, color, &index)) {
3558 RETVAL = newSViv(index);
3561 RETVAL = &PL_sv_undef;
3579 i_gsamp(im, l, r, y, ...)
3591 croak("No channel numbers supplied to g_samp()");
3593 chan_count = items - 4;
3594 chans = mymalloc(sizeof(int) * chan_count);
3595 for (i = 0; i < chan_count; ++i)
3596 chans[i] = SvIV(ST(i+4));
3597 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3598 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3600 if (GIMME_V == G_ARRAY) {
3602 for (i = 0; i < count; ++i)
3603 PUSHs(sv_2mortal(newSViv(data[i])));
3607 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3612 if (GIMME_V != G_ARRAY) {
3614 PUSHs(&PL_sv_undef);
3620 i_img_masked_new(targ, mask, x, y, w, h)
3630 if (!sv_isobject(ST(1))
3631 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3632 croak("i_img_masked_new: parameter 2 must undef or an image");
3634 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3638 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3643 i_plin(im, l, y, ...)
3652 work = mymalloc(sizeof(i_color) * (items-3));
3653 for (i=0; i < items-3; ++i) {
3654 if (sv_isobject(ST(i+3))
3655 && sv_derived_from(ST(i+3), "Imager::Color")) {
3656 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3657 work[i] = *INT2PTR(i_color *, tmp);
3661 croak("i_plin: pixels must be Imager::Color objects");
3665 RETVAL = i_plin(im, l, l+items-3, y, work);
3675 i_ppixf(im, x, y, cl)
3679 Imager::Color::Float cl
3682 i_gsampf(im, l, r, y, ...)
3694 croak("No channel numbers supplied to g_sampf()");
3696 chan_count = items - 4;
3697 chans = mymalloc(sizeof(int) * chan_count);
3698 for (i = 0; i < chan_count; ++i)
3699 chans[i] = SvIV(ST(i+4));
3700 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3701 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3702 if (GIMME_V == G_ARRAY) {
3704 for (i = 0; i < count; ++i)
3705 PUSHs(sv_2mortal(newSVnv(data[i])));
3709 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3713 if (GIMME_V != G_ARRAY) {
3715 PUSHs(&PL_sv_undef);
3720 i_plinf(im, l, y, ...)
3729 work = mymalloc(sizeof(i_fcolor) * (items-3));
3730 for (i=0; i < items-3; ++i) {
3731 if (sv_isobject(ST(i+3))
3732 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3733 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3734 work[i] = *INT2PTR(i_fcolor *, tmp);
3738 croak("i_plin: pixels must be Imager::Color::Float objects");
3742 RETVAL = i_plinf(im, l, l+items-3, y, work);
3759 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3760 if (i_gpixf(im, x, y, color) == 0) {
3761 RETVAL = NEWSV(0,0);
3762 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3766 RETVAL = &PL_sv_undef;
3782 vals = mymalloc((r-l) * sizeof(i_color));
3783 count = i_glin(im, l, r, y, vals);
3785 for (i = 0; i < count; ++i) {
3787 i_color *col = mymalloc(sizeof(i_color));
3788 sv = sv_newmortal();
3789 sv_setref_pv(sv, "Imager::Color", (void *)col);
3796 i_glinf(im, l, r, y)
3806 vals = mymalloc((r-l) * sizeof(i_fcolor));
3807 count = i_glinf(im, l, r, y, vals);
3809 for (i = 0; i < count; ++i) {
3811 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3813 sv = sv_newmortal();
3814 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3821 i_img_16_new(x, y, ch)
3827 i_img_double_new(x, y, ch)
3833 i_tags_addn(im, name, code, idata)
3842 name = SvPV(ST(1), len);
3845 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3850 i_tags_add(im, name, code, data, idata)
3860 name = SvPV(ST(1), len);
3864 data = SvPV(ST(3), len);
3869 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3874 i_tags_find(im, name, start)
3881 if (i_tags_find(&im->tags, name, start, &entry)) {
3883 RETVAL = newSVpv("0 but true", 0);
3885 RETVAL = newSViv(entry);
3887 RETVAL = &PL_sv_undef;
3893 i_tags_findn(im, code, start)
3900 if (i_tags_findn(&im->tags, code, start, &entry)) {
3902 RETVAL = newSVpv("0 but true", 0);
3904 RETVAL = newSViv(entry);
3907 RETVAL = &PL_sv_undef;
3913 i_tags_delete(im, entry)
3917 RETVAL = i_tags_delete(&im->tags, entry);
3922 i_tags_delbyname(im, name)
3926 RETVAL = i_tags_delbyname(&im->tags, name);
3931 i_tags_delbycode(im, code)
3935 RETVAL = i_tags_delbycode(&im->tags, code);
3940 i_tags_get(im, index)
3944 if (index >= 0 && index < im->tags.count) {
3945 i_img_tag *entry = im->tags.tags + index;
3949 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3952 PUSHs(sv_2mortal(newSViv(entry->code)));
3955 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3958 PUSHs(sv_2mortal(newSViv(entry->idata)));
3966 RETVAL = im->tags.count;
3973 i_wf_bbox(face, size, text)
3978 int cords[BOUNDING_BOX_COUNT];
3981 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3983 for (i = 0; i < rc; ++i)
3984 PUSHs(sv_2mortal(newSViv(cords[i])));
3988 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3999 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4005 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4016 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4026 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4028 #define FT2_DESTROY(font) i_ft2_destroy(font)
4032 Imager::Font::FT2 font
4034 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4037 i_ft2_new(name, index)
4042 i_ft2_setdpi(font, xdpi, ydpi)
4043 Imager::Font::FT2 font
4049 Imager::Font::FT2 font
4053 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4055 PUSHs(sv_2mortal(newSViv(xdpi)));
4056 PUSHs(sv_2mortal(newSViv(ydpi)));
4060 i_ft2_sethinting(font, hinting)
4061 Imager::Font::FT2 font
4065 i_ft2_settransform(font, matrix)
4066 Imager::Font::FT2 font
4074 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4075 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4076 av=(AV*)SvRV(ST(1));
4080 for (i = 0; i < len; ++i) {
4081 sv1=(*(av_fetch(av,i,0)));
4082 matrix[i] = SvNV(sv1);
4086 RETVAL = i_ft2_settransform(font, matrix);
4091 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4092 Imager::Font::FT2 font
4098 int bbox[BOUNDING_BOX_COUNT];
4104 text = SvPV(text_sv, text_len);
4106 if (SvUTF8(text_sv))
4109 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4112 for (i = 0; i < rc; ++i)
4113 PUSHs(sv_2mortal(newSViv(bbox[i])));
4117 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4118 Imager::Font::FT2 font
4132 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4135 for (i = 0; i < 8; ++i)
4136 PUSHs(sv_2mortal(newSViv(bbox[i])));
4140 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4141 Imager::Font::FT2 font
4157 if (SvUTF8(ST(7))) {
4161 text = SvPV(ST(7), len);
4162 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4163 len, align, aa, vlayout, utf8);
4168 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4169 Imager::Font::FT2 font
4186 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4187 strlen(text), align, aa, vlayout, 1);
4192 ft2_transform_box(font, x0, x1, x2, x3)
4193 Imager::Font::FT2 font
4201 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4202 ft2_transform_box(font, box);
4204 PUSHs(sv_2mortal(newSViv(box[0])));
4205 PUSHs(sv_2mortal(newSViv(box[1])));
4206 PUSHs(sv_2mortal(newSViv(box[2])));
4207 PUSHs(sv_2mortal(newSViv(box[3])));
4210 i_ft2_has_chars(handle, text_sv, utf8)
4211 Imager::Font::FT2 handle
4222 if (SvUTF8(text_sv))
4225 text = SvPV(text_sv, len);
4226 work = mymalloc(len);
4227 count = i_ft2_has_chars(handle, text, len, utf8, work);
4228 if (GIMME_V == G_ARRAY) {
4230 for (i = 0; i < count; ++i) {
4231 PUSHs(sv_2mortal(newSViv(work[i])));
4236 PUSHs(sv_2mortal(newSVpv(work, count)));
4241 i_ft2_face_name(handle)
4242 Imager::Font::FT2 handle
4247 len = i_ft2_face_name(handle, name, sizeof(name));
4250 PUSHs(sv_2mortal(newSVpv(name, 0)));
4254 i_ft2_can_face_name()
4257 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4258 Imager::Font::FT2 handle
4270 if (SvUTF8(text_sv))
4273 text = SvPV(text_sv, work_len);
4278 ch = i_utf8_advance(&text, &len);
4280 i_push_error(0, "invalid UTF8 character");
4289 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4291 PUSHs(sv_2mortal(newSVpv(name, 0)));
4294 PUSHs(&PL_sv_undef);
4299 i_ft2_can_do_glyph_names()
4302 i_ft2_face_has_glyph_names(handle)
4303 Imager::Font::FT2 handle
4306 i_ft2_is_multiple_master(handle)
4307 Imager::Font::FT2 handle
4310 i_ft2_get_multiple_masters(handle)
4311 Imager::Font::FT2 handle
4316 if (i_ft2_get_multiple_masters(handle, &mm)) {
4317 EXTEND(SP, 2+mm.num_axis);
4318 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4319 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4320 for (i = 0; i < mm.num_axis; ++i) {
4324 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4326 av_store(av, 0, sv);
4327 sv = newSViv(mm.axis[i].minimum);
4329 av_store(av, 1, sv);
4330 sv = newSViv(mm.axis[i].maximum);
4332 av_store(av, 2, sv);
4333 PUSHs(newRV_noinc((SV *)av));
4338 i_ft2_set_mm_coords(handle, ...)
4339 Imager::Font::FT2 handle
4345 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4346 transfer the array manually */
4347 ix_coords = items-1;
4348 coords = mymalloc(sizeof(long) * ix_coords);
4349 for (i = 0; i < ix_coords; ++i) {
4350 coords[i] = (long)SvIV(ST(1+i));
4352 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4359 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4363 Imager::FillHandle fill
4365 MODULE = Imager PACKAGE = Imager
4368 i_new_fill_solid(cl, combine)
4373 i_new_fill_solidf(cl, combine)
4374 Imager::Color::Float cl
4378 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4386 unsigned char *cust_hatch;
4390 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4394 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4399 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4400 Imager::Color::Float fg
4401 Imager::Color::Float bg
4407 unsigned char *cust_hatch;
4411 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4415 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4420 i_new_fill_image(src, matrix, xoff, yoff, combine)
4437 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4438 croak("i_new_fill_image: parameter must be an arrayref");
4439 av=(AV*)SvRV(ST(1));
4443 for (i = 0; i < len; ++i) {
4444 sv1=(*(av_fetch(av,i,0)));
4445 matrix[i] = SvNV(sv1);
4451 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);