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,align=1)
1914 Imager::Font::TT handle
1933 str = SvPV(str_sv, len);
1934 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1935 len, smooth, utf8, align);
1941 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1942 Imager::Font::TT handle
1961 str = SvPV(str_sv, len);
1962 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1963 smooth, utf8, align);
1969 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1970 Imager::Font::TT handle
1976 int cords[BOUNDING_BOX_COUNT],rc;
1985 str = SvPV(str_sv, len);
1986 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1988 for (i = 0; i < rc; ++i) {
1989 PUSHs(sv_2mortal(newSViv(cords[i])));
1994 i_tt_has_chars(handle, text_sv, utf8)
1995 Imager::Font::TT handle
2006 if (SvUTF8(text_sv))
2009 text = SvPV(text_sv, len);
2010 work = mymalloc(len);
2011 count = i_tt_has_chars(handle, text, len, utf8, work);
2012 if (GIMME_V == G_ARRAY) {
2014 for (i = 0; i < count; ++i) {
2015 PUSHs(sv_2mortal(newSViv(work[i])));
2020 PUSHs(sv_2mortal(newSVpv(work, count)));
2025 i_tt_dump_names(handle)
2026 Imager::Font::TT handle
2029 i_tt_face_name(handle)
2030 Imager::Font::TT handle
2035 len = i_tt_face_name(handle, name, sizeof(name));
2038 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2042 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2043 Imager::Font::TT handle
2054 if (SvUTF8(text_sv))
2057 text = SvPV(text_sv, work_len);
2062 ch = i_utf8_advance(&text, &len);
2064 i_push_error(0, "invalid UTF8 character");
2073 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2074 PUSHs(sv_2mortal(newSVpv(name, 0)));
2077 PUSHs(&PL_sv_undef);
2086 i_writejpeg_wiol(im, ig, qfactor)
2102 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2103 if (iptc_itext == NULL) {
2106 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2111 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2113 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2122 i_test_format_probe(ig, length)
2131 i_readtiff_wiol(ig, length)
2136 i_readtiff_multi_wiol(ig, length)
2144 imgs = i_readtiff_multi_wiol(ig, length, &count);
2147 for (i = 0; i < count; ++i) {
2148 SV *sv = sv_newmortal();
2149 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2157 i_writetiff_wiol(im, ig)
2162 i_writetiff_multi_wiol(ig, ...)
2170 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2171 img_count = items - 1;
2173 if (img_count < 1) {
2176 i_push_error(0, "You need to specify images to save");
2179 imgs = mymalloc(sizeof(i_img *) * img_count);
2180 for (i = 0; i < img_count; ++i) {
2183 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2184 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2188 i_push_error(0, "Only images can be saved");
2195 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2203 i_writetiff_wiol_faxable(im, ig, fine)
2209 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2218 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2219 img_count = items - 2;
2221 if (img_count < 1) {
2224 i_push_error(0, "You need to specify images to save");
2227 imgs = mymalloc(sizeof(i_img *) * img_count);
2228 for (i = 0; i < img_count; ++i) {
2231 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2232 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2236 i_push_error(0, "Only images can be saved");
2243 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2251 #endif /* HAVE_LIBTIFF */
2257 i_readpng_wiol(ig, length)
2263 i_writepng_wiol(im, ig)
2276 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2279 i_writegif(im,fd,colors,pixdev,fixed)
2286 Imager__Color fixed;
2293 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2294 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2295 av=(AV*)SvRV(ST(4));
2296 fixedlen=av_len(av)+1;
2297 fixed=mymalloc( fixedlen*sizeof(i_color) );
2298 for(i=0;i<fixedlen;i++) {
2299 sv1=(*(av_fetch(av,i,0)));
2300 if (sv_derived_from(sv1, "Imager::Color")) {
2301 Itmp = SvIV((SV*)SvRV(sv1));
2302 tmp = INT2PTR(i_color*, Itmp);
2303 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2306 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2308 ST(0) = sv_newmortal();
2309 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2310 else sv_setiv(ST(0), (IV)RETVAL);
2316 i_writegifmc(im,fd,colors)
2323 i_writegif_gen(fd, ...)
2328 i_img **imgs = NULL;
2334 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2335 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2336 croak("i_writegif_gen: Second argument must be a hash ref");
2337 hv = (HV *)SvRV(ST(1));
2338 memset(&quant, 0, sizeof(quant));
2339 quant.mc_size = 256;
2340 handle_quant_opts(&quant, hv);
2341 img_count = items - 2;
2343 if (img_count < 1) {
2346 i_push_error(0, "You need to specify images to save");
2349 imgs = mymalloc(sizeof(i_img *) * img_count);
2350 for (i = 0; i < img_count; ++i) {
2353 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2354 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2358 i_push_error(0, "Only images can be saved");
2364 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2368 copy_colors_back(hv, &quant);
2371 ST(0) = sv_newmortal();
2372 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2373 else sv_setiv(ST(0), (IV)RETVAL);
2374 cleanup_quant_opts(&quant);
2378 i_writegif_callback(cb, maxbuffer,...)
2382 i_img **imgs = NULL;
2389 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2390 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2391 croak("i_writegif_callback: Second argument must be a hash ref");
2392 hv = (HV *)SvRV(ST(2));
2393 memset(&quant, 0, sizeof(quant));
2394 quant.mc_size = 256;
2395 handle_quant_opts(&quant, hv);
2396 img_count = items - 3;
2398 if (img_count < 1) {
2402 imgs = mymalloc(sizeof(i_img *) * img_count);
2403 for (i = 0; i < img_count; ++i) {
2406 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2407 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2416 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2420 copy_colors_back(hv, &quant);
2423 ST(0) = sv_newmortal();
2424 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2425 else sv_setiv(ST(0), (IV)RETVAL);
2426 cleanup_quant_opts(&quant);
2429 i_writegif_wiol(ig, opts,...)
2433 i_img **imgs = NULL;
2439 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2440 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2441 croak("i_writegif_callback: Second argument must be a hash ref");
2442 hv = (HV *)SvRV(ST(1));
2443 memset(&quant, 0, sizeof(quant));
2444 quant.mc_size = 256;
2445 handle_quant_opts(&quant, hv);
2446 img_count = items - 2;
2448 if (img_count < 1) {
2452 imgs = mymalloc(sizeof(i_img *) * img_count);
2453 for (i = 0; i < img_count; ++i) {
2456 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2457 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2465 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2469 copy_colors_back(hv, &quant);
2472 ST(0) = sv_newmortal();
2473 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2474 else sv_setiv(ST(0), (IV)RETVAL);
2475 cleanup_quant_opts(&quant);
2488 colour_table = NULL;
2491 if(GIMME_V == G_ARRAY) {
2492 rimg = i_readgif(fd,&colour_table,&colours);
2494 /* don't waste time with colours if they aren't wanted */
2495 rimg = i_readgif(fd,NULL,NULL);
2498 if (colour_table == NULL) {
2501 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2504 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2505 /* I don't know if I have the reference counts right or not :( */
2506 /* Neither do I :-) */
2507 /* No Idea here either */
2510 av_extend(ct, colours);
2511 for(q=0; q<colours; q++) {
2513 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2514 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2516 myfree(colour_table);
2520 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2522 PUSHs(newRV_noinc((SV*)ct));
2536 colour_table = NULL;
2539 if(GIMME_V == G_ARRAY) {
2540 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2542 /* don't waste time with colours if they aren't wanted */
2543 rimg = i_readgif_wiol(ig,NULL,NULL);
2546 if (colour_table == NULL) {
2549 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2552 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2553 /* I don't know if I have the reference counts right or not :( */
2554 /* Neither do I :-) */
2555 /* No Idea here either */
2558 av_extend(ct, colours);
2559 for(q=0; q<colours; q++) {
2561 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2562 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2564 myfree(colour_table);
2568 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2570 PUSHs(newRV_noinc((SV*)ct));
2574 i_readgif_scalar(...)
2586 data = (char *)SvPV(ST(0), length);
2590 if(GIMME_V == G_ARRAY) {
2591 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2593 /* don't waste time with colours if they aren't wanted */
2594 rimg=i_readgif_scalar(data,length,NULL,NULL);
2597 if (colour_table == NULL) {
2600 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2603 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2604 /* I don't know if I have the reference counts right or not :( */
2605 /* Neither do I :-) */
2607 av_extend(ct, colours);
2608 for(q=0; q<colours; q++) {
2610 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2611 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2613 myfree(colour_table);
2617 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2619 PUSHs(newRV_noinc((SV*)ct));
2623 i_readgif_callback(...)
2638 if(GIMME_V == G_ARRAY) {
2639 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2641 /* don't waste time with colours if they aren't wanted */
2642 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2645 if (colour_table == NULL) {
2648 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2651 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2652 /* I don't know if I have the reference counts right or not :( */
2653 /* Neither do I :-) */
2654 /* Neither do I - maybe I'll move this somewhere */
2656 av_extend(ct, colours);
2657 for(q=0; q<colours; q++) {
2659 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2660 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2662 myfree(colour_table);
2666 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2668 PUSHs(newRV_noinc((SV*)ct));
2679 imgs = i_readgif_multi(fd, &count);
2682 for (i = 0; i < count; ++i) {
2683 SV *sv = sv_newmortal();
2684 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2691 i_readgif_multi_scalar(data)
2699 data = (char *)SvPV(ST(0), length);
2700 imgs = i_readgif_multi_scalar(data, length, &count);
2703 for (i = 0; i < count; ++i) {
2704 SV *sv = sv_newmortal();
2705 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2712 i_readgif_multi_callback(cb)
2720 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2723 for (i = 0; i < count; ++i) {
2724 SV *sv = sv_newmortal();
2725 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2732 i_readgif_multi_wiol(ig)
2739 imgs = i_readgif_multi_wiol(ig, &count);
2742 for (i = 0; i < count; ++i) {
2743 SV *sv = sv_newmortal();
2744 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2756 i_readpnm_wiol(ig, length)
2762 i_writeppm_wiol(im, ig)
2768 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2777 i_writeraw_wiol(im,ig)
2782 i_writebmp_wiol(im,ig)
2792 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2801 idlen = SvCUR(ST(4));
2802 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2808 i_readtga_wiol(ig, length)
2814 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2823 idlen = SvCUR(ST(4));
2824 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2830 i_readrgb_wiol(ig, length)
2837 i_scaleaxis(im,Value,Axis)
2843 i_scale_nn(im,scx,scy)
2853 i_count_colors(im,maxc)
2859 i_transform(im,opx,opy,parm)
2872 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2873 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2874 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2875 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2876 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2877 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2878 av=(AV*)SvRV(ST(1));
2880 opx=mymalloc( opxl*sizeof(int) );
2881 for(i=0;i<opxl;i++) {
2882 sv1=(*(av_fetch(av,i,0)));
2883 opx[i]=(int)SvIV(sv1);
2885 av=(AV*)SvRV(ST(2));
2887 opy=mymalloc( opyl*sizeof(int) );
2888 for(i=0;i<opyl;i++) {
2889 sv1=(*(av_fetch(av,i,0)));
2890 opy[i]=(int)SvIV(sv1);
2892 av=(AV*)SvRV(ST(3));
2893 parmlen=av_len(av)+1;
2894 parm=mymalloc( parmlen*sizeof(double) );
2895 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2896 sv1=(*(av_fetch(av,i,0)));
2897 parm[i]=(double)SvNV(sv1);
2899 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2903 ST(0) = sv_newmortal();
2904 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2905 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2908 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2933 in_imgs_count = av_len(av_in_imgs)+1;
2934 for (i = 0; i < in_imgs_count; ++i) {
2935 sv1 = *av_fetch(av_in_imgs, i, 0);
2936 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2937 croak("sv_in_img must contain only images");
2940 if (in_imgs_count > 0) {
2941 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2942 for (i = 0; i < in_imgs_count; ++i) {
2943 sv1 = *av_fetch(av_in_imgs,i,0);
2944 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2945 croak("Parameter 5 must contain only images");
2947 tmp = SvIV((SV*)SvRV(sv1));
2948 in_imgs[i] = INT2PTR(i_img*, tmp);
2952 /* no input images */
2955 /* default the output size from the first input if possible */
2957 width = SvIV(sv_width);
2958 else if (in_imgs_count)
2959 width = in_imgs[0]->xsize;
2961 croak("No output image width supplied");
2963 if (SvOK(sv_height))
2964 height = SvIV(sv_height);
2965 else if (in_imgs_count)
2966 height = in_imgs[0]->ysize;
2968 croak("No output image height supplied");
2970 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2971 if (ops_len % sizeof(struct rm_op))
2972 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2973 ops_count = ops_len / sizeof(struct rm_op);
2975 n_regs_count = av_len(av_n_regs)+1;
2976 n_regs = mymalloc(n_regs_count * sizeof(double));
2977 for (i = 0; i < n_regs_count; ++i) {
2978 sv1 = *av_fetch(av_n_regs,i,0);
2980 n_regs[i] = SvNV(sv1);
2982 c_regs_count = av_len(av_c_regs)+1;
2983 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2984 /* I don't bother initializing the colou?r registers */
2986 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2987 n_regs, n_regs_count,
2988 c_regs, c_regs_count, in_imgs, in_imgs_count);
2993 ST(0) = sv_newmortal();
2994 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2995 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2999 i_contrast(im,intensity)
3008 i_noise(im,amount,type)
3014 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3024 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3043 i_postlevels(im,levels)
3053 i_watermark(im,wmark,tx,ty,pixdiff)
3055 Imager::ImgRaw wmark
3062 i_autolevels(im,lsat,usat,skew)
3069 i_radnoise(im,xo,yo,rscale,ascale)
3077 i_turbnoise(im, xo, yo, scale)
3100 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3101 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3102 croak("i_gradgen: Second argument must be an array ref");
3103 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3104 croak("i_gradgen: Third argument must be an array ref");
3105 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3106 croak("i_gradgen: Fourth argument must be an array ref");
3107 axx = (AV *)SvRV(ST(1));
3108 ayy = (AV *)SvRV(ST(2));
3109 ac = (AV *)SvRV(ST(3));
3110 dmeasure = (int)SvIV(ST(4));
3112 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3113 num = num <= av_len(ac) ? num : av_len(ac);
3115 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3116 xo = mymalloc( sizeof(int) * num );
3117 yo = mymalloc( sizeof(int) * num );
3118 ival = mymalloc( sizeof(i_color) * num );
3119 for(i = 0; i<num; i++) {
3120 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3121 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3122 sv = *av_fetch(ac, i, 0);
3123 if ( !sv_derived_from(sv, "Imager::Color") ) {
3124 free(axx); free(ayy); free(ac);
3125 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3127 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3129 i_gradgen(im, num, xo, yo, ival, dmeasure);
3135 i_diff_image(im, im2, mindist=0)
3141 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3151 double ssample_param
3155 i_fountain_seg *segs;
3157 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3158 croak("i_fountain: argument 11 must be an array ref");
3160 asegs = (AV *)SvRV(ST(10));
3161 segs = load_fount_segs(asegs, &count);
3162 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3163 ssample_param, count, segs);
3167 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3176 double ssample_param
3180 i_fountain_seg *segs;
3182 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3183 croak("i_fountain: argument 11 must be an array ref");
3185 asegs = (AV *)SvRV(ST(9));
3186 segs = load_fount_segs(asegs, &count);
3187 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3188 super_sample, ssample_param, count, segs);
3201 errors = i_errors();
3203 while (errors[i].msg) {
3205 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3206 if (!av_store(av, 0, sv)) {
3209 sv = newSViv(errors[i].code);
3210 if (!av_store(av, 1, sv)) {
3213 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3218 i_nearest_color(im, ...)
3233 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3234 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3235 croak("i_nearest_color: Second argument must be an array ref");
3236 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3237 croak("i_nearest_color: Third argument must be an array ref");
3238 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3239 croak("i_nearest_color: Fourth argument must be an array ref");
3240 axx = (AV *)SvRV(ST(1));
3241 ayy = (AV *)SvRV(ST(2));
3242 ac = (AV *)SvRV(ST(3));
3243 dmeasure = (int)SvIV(ST(4));
3245 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3246 num = num <= av_len(ac) ? num : av_len(ac);
3248 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3249 xo = mymalloc( sizeof(int) * num );
3250 yo = mymalloc( sizeof(int) * num );
3251 ival = mymalloc( sizeof(i_color) * num );
3252 for(i = 0; i<num; i++) {
3253 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3254 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3255 sv = *av_fetch(ac, i, 0);
3256 if ( !sv_derived_from(sv, "Imager::Color") ) {
3257 free(axx); free(ayy); free(ac);
3258 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3260 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3262 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3276 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3277 hv=(HV*)SvRV(ST(0));
3278 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3279 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3280 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3289 rc=DSO_open(filename,&evstr);
3293 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3294 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3297 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3303 DSO_close(dso_handle)
3307 DSO_funclist(dso_handle_v)
3311 DSO_handle *dso_handle;
3313 dso_handle=(DSO_handle*)dso_handle_v;
3315 while( dso_handle->function_list[i].name != NULL) {
3317 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3319 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3324 DSO_call(handle,func_index,hv)
3330 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3331 hv=(HV*)SvRV(ST(2));
3332 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3333 DSO_call( (DSO_handle *)handle,func_index,hv);
3338 i_get_pixel(im, x, y)
3345 color = (i_color *)mymalloc(sizeof(i_color));
3346 if (i_gpix(im, x, y, color) == 0) {
3347 RETVAL = NEWSV(0, 0);
3348 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3352 RETVAL = &PL_sv_undef;
3359 i_ppix(im, x, y, cl)
3366 i_img_pal_new(x, y, channels, maxpal)
3373 i_img_to_pal(src, quant)
3379 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3380 croak("i_img_to_pal: second argument must be a hash ref");
3381 hv = (HV *)SvRV(ST(1));
3382 memset(&quant, 0, sizeof(quant));
3383 quant.mc_size = 256;
3384 handle_quant_opts(&quant, hv);
3385 RETVAL = i_img_to_pal(src, &quant);
3387 copy_colors_back(hv, &quant);
3389 cleanup_quant_opts(&quant);
3408 work = mymalloc((r-l) * sizeof(i_palidx));
3409 count = i_gpal(im, l, r, y, work);
3410 if (GIMME_V == G_ARRAY) {
3412 for (i = 0; i < count; ++i) {
3413 PUSHs(sv_2mortal(newSViv(work[i])));
3418 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3423 if (GIMME_V != G_ARRAY) {
3425 PUSHs(&PL_sv_undef);
3430 i_ppal(im, l, y, ...)
3439 work = mymalloc(sizeof(i_palidx) * (items-3));
3440 for (i=0; i < items-3; ++i) {
3441 work[i] = SvIV(ST(i+3));
3443 RETVAL = i_ppal(im, l, l+items-3, y, work);
3453 i_addcolors(im, ...)
3461 croak("i_addcolors: no colors to add");
3462 colors = mymalloc((items-1) * sizeof(i_color));
3463 for (i=0; i < items-1; ++i) {
3464 if (sv_isobject(ST(i+1))
3465 && sv_derived_from(ST(i+1), "Imager::Color")) {
3466 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3467 colors[i] = *INT2PTR(i_color *, tmp);
3471 croak("i_plin: pixels must be Imager::Color objects");
3474 index = i_addcolors(im, colors, items-1);
3477 RETVAL = newSVpv("0 but true", 0);
3479 else if (index == -1) {
3480 RETVAL = &PL_sv_undef;
3483 RETVAL = newSViv(index);
3489 i_setcolors(im, index, ...)
3497 croak("i_setcolors: no colors to add");
3498 colors = mymalloc((items-2) * sizeof(i_color));
3499 for (i=0; i < items-2; ++i) {
3500 if (sv_isobject(ST(i+2))
3501 && sv_derived_from(ST(i+2), "Imager::Color")) {
3502 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3503 colors[i] = *INT2PTR(i_color *, tmp);
3507 croak("i_setcolors: pixels must be Imager::Color objects");
3510 RETVAL = i_setcolors(im, index, colors, items-2);
3516 i_getcolors(im, index, ...)
3525 croak("i_getcolors: too many arguments");
3527 count = SvIV(ST(2));
3529 croak("i_getcolors: count must be positive");
3530 colors = mymalloc(sizeof(i_color) * count);
3531 if (i_getcolors(im, index, colors, count)) {
3532 for (i = 0; i < count; ++i) {
3534 SV *sv = sv_newmortal();
3535 pv = mymalloc(sizeof(i_color));
3537 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3553 i_findcolor(im, color)
3559 if (i_findcolor(im, color, &index)) {
3560 RETVAL = newSViv(index);
3563 RETVAL = &PL_sv_undef;
3581 i_gsamp(im, l, r, y, ...)
3593 croak("No channel numbers supplied to g_samp()");
3595 chan_count = items - 4;
3596 chans = mymalloc(sizeof(int) * chan_count);
3597 for (i = 0; i < chan_count; ++i)
3598 chans[i] = SvIV(ST(i+4));
3599 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3600 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3602 if (GIMME_V == G_ARRAY) {
3604 for (i = 0; i < count; ++i)
3605 PUSHs(sv_2mortal(newSViv(data[i])));
3609 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3614 if (GIMME_V != G_ARRAY) {
3616 PUSHs(&PL_sv_undef);
3622 i_img_masked_new(targ, mask, x, y, w, h)
3632 if (!sv_isobject(ST(1))
3633 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3634 croak("i_img_masked_new: parameter 2 must undef or an image");
3636 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3640 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3645 i_plin(im, l, y, ...)
3654 work = mymalloc(sizeof(i_color) * (items-3));
3655 for (i=0; i < items-3; ++i) {
3656 if (sv_isobject(ST(i+3))
3657 && sv_derived_from(ST(i+3), "Imager::Color")) {
3658 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3659 work[i] = *INT2PTR(i_color *, tmp);
3663 croak("i_plin: pixels must be Imager::Color objects");
3667 RETVAL = i_plin(im, l, l+items-3, y, work);
3677 i_ppixf(im, x, y, cl)
3681 Imager::Color::Float cl
3684 i_gsampf(im, l, r, y, ...)
3696 croak("No channel numbers supplied to g_sampf()");
3698 chan_count = items - 4;
3699 chans = mymalloc(sizeof(int) * chan_count);
3700 for (i = 0; i < chan_count; ++i)
3701 chans[i] = SvIV(ST(i+4));
3702 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3703 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3704 if (GIMME_V == G_ARRAY) {
3706 for (i = 0; i < count; ++i)
3707 PUSHs(sv_2mortal(newSVnv(data[i])));
3711 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3715 if (GIMME_V != G_ARRAY) {
3717 PUSHs(&PL_sv_undef);
3722 i_plinf(im, l, y, ...)
3731 work = mymalloc(sizeof(i_fcolor) * (items-3));
3732 for (i=0; i < items-3; ++i) {
3733 if (sv_isobject(ST(i+3))
3734 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3735 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3736 work[i] = *INT2PTR(i_fcolor *, tmp);
3740 croak("i_plin: pixels must be Imager::Color::Float objects");
3744 RETVAL = i_plinf(im, l, l+items-3, y, work);
3761 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3762 if (i_gpixf(im, x, y, color) == 0) {
3763 RETVAL = NEWSV(0,0);
3764 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3768 RETVAL = &PL_sv_undef;
3784 vals = mymalloc((r-l) * sizeof(i_color));
3785 count = i_glin(im, l, r, y, vals);
3787 for (i = 0; i < count; ++i) {
3789 i_color *col = mymalloc(sizeof(i_color));
3791 sv = sv_newmortal();
3792 sv_setref_pv(sv, "Imager::Color", (void *)col);
3799 i_glinf(im, l, r, y)
3809 vals = mymalloc((r-l) * sizeof(i_fcolor));
3810 count = i_glinf(im, l, r, y, vals);
3812 for (i = 0; i < count; ++i) {
3814 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3816 sv = sv_newmortal();
3817 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3824 i_img_16_new(x, y, ch)
3830 i_img_double_new(x, y, ch)
3836 i_tags_addn(im, name, code, idata)
3845 name = SvPV(ST(1), len);
3848 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3853 i_tags_add(im, name, code, data, idata)
3863 name = SvPV(ST(1), len);
3867 data = SvPV(ST(3), len);
3872 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3877 i_tags_find(im, name, start)
3884 if (i_tags_find(&im->tags, name, start, &entry)) {
3886 RETVAL = newSVpv("0 but true", 0);
3888 RETVAL = newSViv(entry);
3890 RETVAL = &PL_sv_undef;
3896 i_tags_findn(im, code, start)
3903 if (i_tags_findn(&im->tags, code, start, &entry)) {
3905 RETVAL = newSVpv("0 but true", 0);
3907 RETVAL = newSViv(entry);
3910 RETVAL = &PL_sv_undef;
3916 i_tags_delete(im, entry)
3920 RETVAL = i_tags_delete(&im->tags, entry);
3925 i_tags_delbyname(im, name)
3929 RETVAL = i_tags_delbyname(&im->tags, name);
3934 i_tags_delbycode(im, code)
3938 RETVAL = i_tags_delbycode(&im->tags, code);
3943 i_tags_get(im, index)
3947 if (index >= 0 && index < im->tags.count) {
3948 i_img_tag *entry = im->tags.tags + index;
3952 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3955 PUSHs(sv_2mortal(newSViv(entry->code)));
3958 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3961 PUSHs(sv_2mortal(newSViv(entry->idata)));
3966 i_tags_get_string(im, what_sv)
3970 char const *name = NULL;
3974 if (SvIOK(what_sv)) {
3975 code = SvIV(what_sv);
3979 name = SvPV_nolen(what_sv);
3982 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3984 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3991 RETVAL = im->tags.count;
3998 i_wf_bbox(face, size, text)
4003 int cords[BOUNDING_BOX_COUNT];
4006 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4008 for (i = 0; i < rc; ++i)
4009 PUSHs(sv_2mortal(newSViv(cords[i])));
4013 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4024 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4030 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4041 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4054 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4056 #define FT2_DESTROY(font) i_ft2_destroy(font)
4060 Imager::Font::FT2 font
4062 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4065 i_ft2_new(name, index)
4070 i_ft2_setdpi(font, xdpi, ydpi)
4071 Imager::Font::FT2 font
4077 Imager::Font::FT2 font
4081 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4083 PUSHs(sv_2mortal(newSViv(xdpi)));
4084 PUSHs(sv_2mortal(newSViv(ydpi)));
4088 i_ft2_sethinting(font, hinting)
4089 Imager::Font::FT2 font
4093 i_ft2_settransform(font, matrix)
4094 Imager::Font::FT2 font
4102 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4103 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4104 av=(AV*)SvRV(ST(1));
4108 for (i = 0; i < len; ++i) {
4109 sv1=(*(av_fetch(av,i,0)));
4110 matrix[i] = SvNV(sv1);
4114 RETVAL = i_ft2_settransform(font, matrix);
4119 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4120 Imager::Font::FT2 font
4126 int bbox[BOUNDING_BOX_COUNT];
4132 text = SvPV(text_sv, text_len);
4134 if (SvUTF8(text_sv))
4137 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4140 for (i = 0; i < rc; ++i)
4141 PUSHs(sv_2mortal(newSViv(bbox[i])));
4145 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4146 Imager::Font::FT2 font
4160 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4163 for (i = 0; i < 8; ++i)
4164 PUSHs(sv_2mortal(newSViv(bbox[i])));
4168 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4169 Imager::Font::FT2 font
4185 if (SvUTF8(ST(7))) {
4189 text = SvPV(ST(7), len);
4190 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4191 len, align, aa, vlayout, utf8);
4196 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4197 Imager::Font::FT2 font
4214 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4215 strlen(text), align, aa, vlayout, 1);
4220 ft2_transform_box(font, x0, x1, x2, x3)
4221 Imager::Font::FT2 font
4229 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4230 ft2_transform_box(font, box);
4232 PUSHs(sv_2mortal(newSViv(box[0])));
4233 PUSHs(sv_2mortal(newSViv(box[1])));
4234 PUSHs(sv_2mortal(newSViv(box[2])));
4235 PUSHs(sv_2mortal(newSViv(box[3])));
4238 i_ft2_has_chars(handle, text_sv, utf8)
4239 Imager::Font::FT2 handle
4250 if (SvUTF8(text_sv))
4253 text = SvPV(text_sv, len);
4254 work = mymalloc(len);
4255 count = i_ft2_has_chars(handle, text, len, utf8, work);
4256 if (GIMME_V == G_ARRAY) {
4258 for (i = 0; i < count; ++i) {
4259 PUSHs(sv_2mortal(newSViv(work[i])));
4264 PUSHs(sv_2mortal(newSVpv(work, count)));
4269 i_ft2_face_name(handle)
4270 Imager::Font::FT2 handle
4275 len = i_ft2_face_name(handle, name, sizeof(name));
4278 PUSHs(sv_2mortal(newSVpv(name, 0)));
4282 i_ft2_can_face_name()
4285 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4286 Imager::Font::FT2 handle
4298 if (SvUTF8(text_sv))
4301 text = SvPV(text_sv, work_len);
4306 ch = i_utf8_advance(&text, &len);
4308 i_push_error(0, "invalid UTF8 character");
4317 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4319 PUSHs(sv_2mortal(newSVpv(name, 0)));
4322 PUSHs(&PL_sv_undef);
4327 i_ft2_can_do_glyph_names()
4330 i_ft2_face_has_glyph_names(handle)
4331 Imager::Font::FT2 handle
4334 i_ft2_is_multiple_master(handle)
4335 Imager::Font::FT2 handle
4338 i_ft2_get_multiple_masters(handle)
4339 Imager::Font::FT2 handle
4344 if (i_ft2_get_multiple_masters(handle, &mm)) {
4345 EXTEND(SP, 2+mm.num_axis);
4346 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4347 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4348 for (i = 0; i < mm.num_axis; ++i) {
4352 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4354 av_store(av, 0, sv);
4355 sv = newSViv(mm.axis[i].minimum);
4357 av_store(av, 1, sv);
4358 sv = newSViv(mm.axis[i].maximum);
4360 av_store(av, 2, sv);
4361 PUSHs(newRV_noinc((SV *)av));
4366 i_ft2_set_mm_coords(handle, ...)
4367 Imager::Font::FT2 handle
4373 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4374 transfer the array manually */
4375 ix_coords = items-1;
4376 coords = mymalloc(sizeof(long) * ix_coords);
4377 for (i = 0; i < ix_coords; ++i) {
4378 coords[i] = (long)SvIV(ST(1+i));
4380 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4387 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4391 Imager::FillHandle fill
4393 MODULE = Imager PACKAGE = Imager
4396 i_new_fill_solid(cl, combine)
4401 i_new_fill_solidf(cl, combine)
4402 Imager::Color::Float cl
4406 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4414 unsigned char *cust_hatch;
4418 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4422 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4427 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4428 Imager::Color::Float fg
4429 Imager::Color::Float bg
4435 unsigned char *cust_hatch;
4439 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4443 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4448 i_new_fill_image(src, matrix, xoff, yoff, combine)
4465 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4466 croak("i_new_fill_image: parameter must be an arrayref");
4467 av=(AV*)SvRV(ST(1));
4471 for (i = 0; i < len; ++i) {
4472 sv1=(*(av_fetch(av,i,0)));
4473 matrix[i] = SvNV(sv1);
4479 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);