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;
22 /* later perls define this macro to prevent warning when converting
23 from IV to pointer types */
26 #define INT2PTR(type,value) (type)(value)
30 #define PTR2IV(p) INT2PTR(IV,p)
34 typedef TT_Fonthandle* Imager__Font__TT;
38 typedef FT2_Fonthandle* Imager__Font__FT2;
41 /* These functions are all shared - then comes platform dependant code */
42 static int getstr(void *hv_t,char *key,char **store) {
46 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
48 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
50 svpp=hv_fetch(hv, key, strlen(key), 0);
51 *store=SvPV(*svpp, PL_na );
56 static int getint(void *hv_t,char *key,int *store) {
60 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
62 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
64 svpp=hv_fetch(hv, key, strlen(key), 0);
65 *store=(int)SvIV(*svpp);
69 static int getdouble(void *hv_t,char* key,double *store) {
73 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
75 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
76 svpp=hv_fetch(hv, key, strlen(key), 0);
77 *store=(float)SvNV(*svpp);
81 static int getvoid(void *hv_t,char* key,void **store) {
85 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
87 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
89 svpp=hv_fetch(hv, key, strlen(key), 0);
90 *store = INT2PTR(void*, SvIV(*svpp));
95 static int getobj(void *hv_t,char *key,char *type,void **store) {
99 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
101 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
103 svpp=hv_fetch(hv, key, strlen(key), 0);
105 if (sv_derived_from(*svpp,type)) {
106 IV tmp = SvIV((SV*)SvRV(*svpp));
107 *store = INT2PTR(void*, tmp);
109 mm_log((1,"getobj: key exists in hash but is not of correct type"));
116 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
118 void my_SvREFCNT_dec(void *p) {
119 SvREFCNT_dec((SV*)p);
124 log_entry(char *string, int level) {
125 mm_log((level, string));
129 typedef struct i_reader_data_tag
131 /* presumably a CODE ref or name of a sub */
135 /* used by functions that want callbacks */
136 static int read_callback(char *userdata, char *buffer, int need, int want) {
137 i_reader_data *rd = (i_reader_data *)userdata;
141 dSP; dTARG = sv_newmortal();
142 /* thanks to Simon Cozens for help with the dTARG above */
152 count = perl_call_sv(rd->sv, G_SCALAR);
157 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
163 char *ptr = SvPV(data, len);
165 croak("Too much data returned in reader callback");
167 memcpy(buffer, ptr, len);
183 SV *sv; /* a coderef or sub name */
186 /* used by functions that want callbacks */
187 static int write_callback(char *userdata, char const *data, int size) {
188 i_writer_data *wd = (i_writer_data *)userdata;
198 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
201 count = perl_call_sv(wd->sv, G_SCALAR);
206 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
209 success = SvTRUE(sv);
219 #define CBDATA_BUFSIZE 8192
222 /* the SVs we use to call back to Perl */
228 /* we need to remember whether the buffer contains write data or
234 /* how far we've read into the buffer (not used for writing) */
237 /* the amount of space used/data available in the buffer */
240 /* the maximum amount to fill the buffer before flushing
241 If any write is larger than this then the buffer is flushed and
242 the full write is performed. The write is _not_ split into
247 char buffer[CBDATA_BUFSIZE];
252 call_writer(cbd, buf, size)
254 Low-level function to call the perl writer callback.
258 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
264 if (!SvOK(cbd->writecb))
271 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
274 count = perl_call_sv(cbd->writecb, G_SCALAR);
278 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
281 success = SvTRUE(sv);
288 return success ? size : 0;
291 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
298 if (!SvOK(cbd->readcb))
305 PUSHs(sv_2mortal(newSViv(size)));
306 PUSHs(sv_2mortal(newSViv(maxread)));
309 count = perl_call_sv(cbd->readcb, G_SCALAR);
314 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
320 char *ptr = SvPV(data, len);
322 croak("Too much data returned in reader callback");
324 memcpy(buf, ptr, len);
338 static ssize_t write_flush(struct cbdata *cbd) {
341 result = call_writer(cbd, cbd->buffer, cbd->used);
346 static off_t io_seeker(void *p, off_t offset, int whence) {
347 struct cbdata *cbd = p;
352 if (!SvOK(cbd->seekcb))
356 if (cbd->used && write_flush(cbd) <= 0)
360 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
361 offset -= cbd->where - cbd->used;
364 cbd->where = cbd->used = 0;
370 PUSHs(sv_2mortal(newSViv(offset)));
371 PUSHs(sv_2mortal(newSViv(whence)));
374 count = perl_call_sv(cbd->seekcb, G_SCALAR);
379 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
390 static ssize_t io_writer(void *p, void const *data, size_t size) {
391 struct cbdata *cbd = p;
393 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
395 if (cbd->reading && cbd->where < cbd->used) {
396 /* we read past the place where the caller expected us to be
397 so adjust our position a bit */
399 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
404 cbd->where = cbd->used = 0;
407 if (cbd->used && cbd->used + size > cbd->maxlength) {
408 if (write_flush(cbd) <= 0) {
413 if (cbd->used+size <= cbd->maxlength) {
414 memcpy(cbd->buffer + cbd->used, data, size);
418 /* it doesn't fit - just pass it up */
419 return call_writer(cbd, data, size);
422 static ssize_t io_reader(void *p, void *data, size_t size) {
423 struct cbdata *cbd = p;
425 char *out = data; /* so we can do pointer arithmetic */
429 if (write_flush(cbd) <= 0)
435 if (size <= cbd->used - cbd->where) {
437 memcpy(data, cbd->buffer+cbd->where, size);
442 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
443 total += cbd->used - cbd->where;
444 size -= cbd->used - cbd->where;
445 out += cbd->used - cbd->where;
446 if (size < sizeof(cbd->buffer)) {
450 && (did_read = call_reader(cbd, cbd->buffer, size,
451 sizeof(cbd->buffer))) > 0) {
453 cbd->used = did_read;
455 copy_size = i_min(size, cbd->used);
456 memcpy(out, cbd->buffer, copy_size);
457 cbd->where += copy_size;
464 /* just read the rest - too big for our buffer*/
466 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
476 static void io_closer(void *p) {
477 struct cbdata *cbd = p;
479 if (cbd->writing && cbd->used > 0) {
484 if (SvOK(cbd->closecb)) {
492 perl_call_sv(cbd->closecb, G_VOID);
501 static void io_destroyer(void *p) {
502 struct cbdata *cbd = p;
504 SvREFCNT_dec(cbd->writecb);
505 SvREFCNT_dec(cbd->readcb);
506 SvREFCNT_dec(cbd->seekcb);
507 SvREFCNT_dec(cbd->closecb);
514 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
517 for (i = 0; i < count; ++i)
518 if (strEQ(names[i].name, name))
519 return names[i].value;
523 static struct value_name transp_names[] =
526 { "threshold", tr_threshold },
527 { "errdiff", tr_errdiff },
528 { "ordered", tr_ordered, },
531 static struct value_name make_color_names[] =
533 { "none", mc_none, },
534 { "webmap", mc_web_map, },
535 { "addi", mc_addi, },
536 { "mediancut", mc_median_cut, },
539 static struct value_name translate_names[] =
542 { "giflib", pt_giflib, },
544 { "closest", pt_closest, },
545 { "perturb", pt_perturb, },
546 { "errdiff", pt_errdiff, },
549 static struct value_name errdiff_names[] =
551 { "floyd", ed_floyd, },
552 { "jarvis", ed_jarvis, },
553 { "stucki", ed_stucki, },
554 { "custom", ed_custom, },
557 static struct value_name orddith_names[] =
559 { "random", od_random, },
560 { "dot8", od_dot8, },
561 { "dot4", od_dot4, },
562 { "hline", od_hline, },
563 { "vline", od_vline, },
564 { "/line", od_slashline, },
565 { "slashline", od_slashline, },
566 { "\\line", od_backline, },
567 { "backline", od_backline, },
568 { "tiny", od_tiny, },
569 { "custom", od_custom, },
573 hv_fetch_bool(HV *hv, char *name, int def) {
576 sv = hv_fetch(hv, name, strlen(name), 0);
585 hv_fetch_int(HV *hv, char *name, int def) {
588 sv = hv_fetch(hv, name, strlen(name), 0);
596 /* look through the hash for quantization options */
597 static void handle_quant_opts(i_quantize *quant, HV *hv)
599 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
605 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
607 sv = hv_fetch(hv, "transp", 6, 0);
608 if (sv && *sv && (str = SvPV(*sv, len))) {
610 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
612 if (quant->transp != tr_none) {
613 quant->tr_threshold = 127;
614 sv = hv_fetch(hv, "tr_threshold", 12, 0);
616 quant->tr_threshold = SvIV(*sv);
618 if (quant->transp == tr_errdiff) {
619 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
620 if (sv && *sv && (str = SvPV(*sv, len)))
621 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
623 if (quant->transp == tr_ordered) {
624 quant->tr_orddith = od_tiny;
625 sv = hv_fetch(hv, "tr_orddith", 10, 0);
626 if (sv && *sv && (str = SvPV(*sv, len)))
627 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
629 if (quant->tr_orddith == od_custom) {
630 sv = hv_fetch(hv, "tr_map", 6, 0);
631 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
632 AV *av = (AV*)SvRV(*sv);
633 len = av_len(av) + 1;
634 if (len > sizeof(quant->tr_custom))
635 len = sizeof(quant->tr_custom);
636 for (i = 0; i < len; ++i) {
637 SV **sv2 = av_fetch(av, i, 0);
639 quant->tr_custom[i] = SvIV(*sv2);
642 while (i < sizeof(quant->tr_custom))
643 quant->tr_custom[i++] = 0;
648 quant->make_colors = mc_addi;
649 sv = hv_fetch(hv, "make_colors", 11, 0);
650 if (sv && *sv && (str = SvPV(*sv, len))) {
652 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
654 sv = hv_fetch(hv, "colors", 6, 0);
655 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
656 /* needs to be an array of Imager::Color
657 note that the caller allocates the mc_color array and sets mc_size
659 AV *av = (AV *)SvRV(*sv);
660 quant->mc_count = av_len(av)+1;
661 if (quant->mc_count > quant->mc_size)
662 quant->mc_count = quant->mc_size;
663 for (i = 0; i < quant->mc_count; ++i) {
664 SV **sv1 = av_fetch(av, i, 0);
665 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
666 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
667 quant->mc_colors[i] = *col;
671 sv = hv_fetch(hv, "max_colors", 10, 0);
674 if (i <= quant->mc_size && i >= quant->mc_count)
678 quant->translate = pt_closest;
679 sv = hv_fetch(hv, "translate", 9, 0);
680 if (sv && *sv && (str = SvPV(*sv, len))) {
681 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
683 sv = hv_fetch(hv, "errdiff", 7, 0);
684 if (sv && *sv && (str = SvPV(*sv, len))) {
685 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
687 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
688 /* get the error diffusion map */
689 sv = hv_fetch(hv, "errdiff_width", 13, 0);
691 quant->ed_width = SvIV(*sv);
692 sv = hv_fetch(hv, "errdiff_height", 14, 0);
694 quant->ed_height = SvIV(*sv);
695 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
697 quant->ed_orig = SvIV(*sv);
698 if (quant->ed_width > 0 && quant->ed_height > 0) {
700 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
701 sv = hv_fetch(hv, "errdiff_map", 11, 0);
702 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
703 AV *av = (AV*)SvRV(*sv);
704 len = av_len(av) + 1;
705 if (len > quant->ed_width * quant->ed_height)
706 len = quant->ed_width * quant->ed_height;
707 for (i = 0; i < len; ++i) {
708 SV **sv2 = av_fetch(av, i, 0);
710 quant->ed_map[i] = SvIV(*sv2);
711 sum += quant->ed_map[i];
717 myfree(quant->ed_map);
719 quant->errdiff = ed_floyd;
723 sv = hv_fetch(hv, "perturb", 7, 0);
725 quant->perturb = SvIV(*sv);
728 static void cleanup_quant_opts(i_quantize *quant) {
729 myfree(quant->mc_colors);
731 myfree(quant->ed_map);
735 /* look through the hash for options to add to opts */
736 static void handle_gif_opts(i_gif_opts *opts, HV *hv)
740 /**((char *)0) = '\0';*/
741 opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
742 opts->interlace = hv_fetch_bool(hv, "interlace", 0);
744 sv = hv_fetch(hv, "gif_delays", 10, 0);
745 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
746 AV *av = (AV*)SvRV(*sv);
747 opts->delay_count = av_len(av)+1;
748 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
749 for (i = 0; i < opts->delay_count; ++i) {
750 SV *sv1 = *av_fetch(av, i, 0);
751 opts->delays[i] = SvIV(sv1);
754 sv = hv_fetch(hv, "gif_user_input", 14, 0);
755 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
756 AV *av = (AV*)SvRV(*sv);
757 opts->user_input_count = av_len(av)+1;
758 opts->user_input_flags = mymalloc(opts->user_input_count);
759 for (i = 0; i < opts->user_input_count; ++i) {
760 SV *sv1 = *av_fetch(av, i, 0);
761 opts->user_input_flags[i] = SvIV(sv1) != 0;
764 sv = hv_fetch(hv, "gif_disposal", 12, 0);
765 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
766 AV *av = (AV*)SvRV(*sv);
767 opts->disposal_count = av_len(av)+1;
768 opts->disposal = mymalloc(opts->disposal_count);
769 for (i = 0; i < opts->disposal_count; ++i) {
770 SV *sv1 = *av_fetch(av, i, 0);
771 opts->disposal[i] = SvIV(sv1);
774 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
775 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
776 i_color *col = INT2PTR(i_color *, SvIV((SV *)SvRV(*sv)));
777 opts->tran_color = *col;
779 sv = hv_fetch(hv, "gif_positions", 13, 0);
780 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
781 AV *av = (AV *)SvRV(*sv);
782 opts->position_count = av_len(av) + 1;
783 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
784 for (i = 0; i < opts->position_count; ++i) {
785 SV **sv2 = av_fetch(av, i, 0);
786 opts->positions[i].x = opts->positions[i].y = 0;
787 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
788 AV *av2 = (AV*)SvRV(*sv2);
790 sv3 = av_fetch(av2, 0, 0);
792 opts->positions[i].x = SvIV(*sv3);
793 sv3 = av_fetch(av2, 1, 0);
795 opts->positions[i].y = SvIV(*sv3);
799 /* Netscape2.0 loop count extension */
800 opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
802 opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
805 static void cleanup_gif_opts(i_gif_opts *opts) {
807 myfree(opts->delays);
808 if (opts->user_input_flags)
809 myfree(opts->user_input_flags);
811 myfree(opts->disposal);
813 myfree(opts->positions);
818 /* copies the color map from the hv into the colors member of the HV */
819 static void copy_colors_back(HV *hv, i_quantize *quant) {
825 sv = hv_fetch(hv, "colors", 6, 0);
826 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
829 ref = newRV_inc((SV*) av);
830 sv = hv_store(hv, "colors", 6, ref, 0);
833 av = (AV *)SvRV(*sv);
835 av_extend(av, quant->mc_count+1);
836 for (i = 0; i < quant->mc_count; ++i) {
837 i_color *in = quant->mc_colors+i;
838 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
839 work = sv_newmortal();
840 sv_setref_pv(work, "Imager::Color", (void *)c);
842 if (!av_store(av, i, work)) {
848 /* loads the segments of a fountain fill into an array */
849 static i_fountain_seg *
850 load_fount_segs(AV *asegs, int *count) {
851 /* Each element of segs must contain:
852 [ start, middle, end, c0, c1, segtype, colortrans ]
853 start, middle, end are doubles from 0 to 1
854 c0, c1 are Imager::Color::Float or Imager::Color objects
855 segtype, colortrans are ints
860 i_fountain_seg *segs;
864 *count = av_len(asegs)+1;
866 croak("i_fountain must have at least one segment");
867 segs = mymalloc(sizeof(i_fountain_seg) * *count);
868 for(i = 0; i < *count; i++) {
869 SV **sv1 = av_fetch(asegs, i, 0);
870 if (!sv1 || !*sv1 || !SvROK(*sv1)
871 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
873 croak("i_fountain: segs must be an arrayref of arrayrefs");
875 aseg = (AV *)SvRV(*sv1);
876 if (av_len(aseg) != 7-1) {
878 croak("i_fountain: a segment must have 7 members");
880 for (j = 0; j < 3; ++j) {
881 SV **sv2 = av_fetch(aseg, j, 0);
884 croak("i_fountain: XS error");
886 work[j] = SvNV(*sv2);
888 segs[i].start = work[0];
889 segs[i].middle = work[1];
890 segs[i].end = work[2];
891 for (j = 0; j < 2; ++j) {
892 SV **sv3 = av_fetch(aseg, 3+j, 0);
893 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
894 (!sv_derived_from(*sv3, "Imager::Color")
895 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
897 croak("i_fountain: segs must contain colors in elements 3 and 4");
899 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
900 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
903 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
905 for (ch = 0; ch < MAXCHANNELS; ++ch) {
906 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
910 for (j = 0; j < 2; ++j) {
911 SV **sv2 = av_fetch(aseg, j+5, 0);
914 croak("i_fountain: XS error");
916 worki[j] = SvIV(*sv2);
918 segs[i].type = worki[0];
919 segs[i].color = worki[1];
925 /* I don't think ICLF_* names belong at the C interface
926 this makes the XS code think we have them, to let us avoid
927 putting function bodies in the XS code
929 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
930 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
932 /* for the fill objects
933 Since a fill object may later have dependent images, (or fills!)
934 we need perl wrappers - oh well
936 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
937 typedef i_fill_t* Imager__FillHandle;
939 /* the m_init_log() function was called init_log(), renamed to reduce
940 potential naming conflicts */
941 #define init_log m_init_log
943 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
946 ICL_new_internal(r,g,b,a)
958 ICL_set_internal(cl,r,g,b,a)
965 ICL_set_internal(cl, r, g, b, a);
979 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
980 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
981 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
982 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
988 RETVAL = mymalloc(sizeof(i_color));
990 i_hsv_to_rgb(RETVAL);
998 RETVAL = mymalloc(sizeof(i_color));
1000 i_rgb_to_hsv(RETVAL);
1006 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1008 Imager::Color::Float
1009 ICLF_new_internal(r, g, b, a)
1017 Imager::Color::Float cl
1021 Imager::Color::Float cl
1025 EXTEND(SP, MAXCHANNELS);
1026 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1027 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1028 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1032 ICLF_set_internal(cl,r,g,b,a)
1033 Imager::Color::Float cl
1046 Imager::Color::Float
1048 Imager::Color::Float c
1050 RETVAL = mymalloc(sizeof(i_fcolor));
1052 i_hsv_to_rgbf(RETVAL);
1056 Imager::Color::Float
1058 Imager::Color::Float c
1060 RETVAL = mymalloc(sizeof(i_fcolor));
1062 i_rgb_to_hsvf(RETVAL);
1067 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1081 MODULE = Imager PACKAGE = Imager
1101 SvPV(ST(0), length);
1102 SvREFCNT_inc(ST(0));
1103 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1108 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1117 cbd = mymalloc(sizeof(struct cbdata));
1118 SvREFCNT_inc(writecb);
1119 cbd->writecb = writecb;
1120 SvREFCNT_inc(readcb);
1121 cbd->readcb = readcb;
1122 SvREFCNT_inc(seekcb);
1123 cbd->seekcb = seekcb;
1124 SvREFCNT_inc(closecb);
1125 cbd->closecb = closecb;
1126 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1127 if (maxwrite > CBDATA_BUFSIZE)
1128 maxwrite = CBDATA_BUFSIZE;
1129 cbd->maxlength = maxwrite;
1130 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1139 unsigned char* data;
1143 tlength = io_slurp(ig, &data);
1145 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1149 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1156 MODULE = Imager PACKAGE = Imager
1169 while( (item=i_format_list[i++]) != NULL ) {
1171 PUSHs(sv_2mortal(newSVpv(item,0)));
1188 i_img_empty_ch(im,x,y,ch)
1195 m_init_log(name,level)
1200 log_entry(string,level)
1219 i_img_info(im,info);
1221 PUSHs(sv_2mortal(newSViv(info[0])));
1222 PUSHs(sv_2mortal(newSViv(info[1])));
1223 PUSHs(sv_2mortal(newSViv(info[2])));
1224 PUSHs(sv_2mortal(newSViv(info[3])));
1230 i_img_setmask(im,ch_mask)
1239 i_img_getchannels(im)
1248 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1253 i_line(im,x1,y1,x2,y2,val,endp)
1263 i_line_aa(im,x1,y1,x2,y2,val,endp)
1273 i_box(im,x1,y1,x2,y2,val)
1282 i_box_filled(im,x1,y1,x2,y2,val)
1291 i_box_cfill(im,x1,y1,x2,y2,fill)
1297 Imager::FillHandle fill
1300 i_arc(im,x,y,rad,d1,d2,val)
1310 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1317 Imager::FillHandle fill
1322 i_circle_aa(im,x,y,rad,val)
1332 i_bezier_multi(im,xc,yc,val)
1345 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1346 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1347 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1348 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1349 av1=(AV*)SvRV(ST(1));
1350 av2=(AV*)SvRV(ST(2));
1351 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1353 x=mymalloc( len*sizeof(double) );
1354 y=mymalloc( len*sizeof(double) );
1355 for(i=0;i<len;i++) {
1356 sv1=(*(av_fetch(av1,i,0)));
1357 sv2=(*(av_fetch(av2,i,0)));
1358 x[i]=(double)SvNV(sv1);
1359 y[i]=(double)SvNV(sv2);
1361 i_bezier_multi(im,len,x,y,val);
1367 i_poly_aa(im,xc,yc,val)
1380 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1381 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1382 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1383 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1384 av1=(AV*)SvRV(ST(1));
1385 av2=(AV*)SvRV(ST(2));
1386 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1388 x=mymalloc( len*sizeof(double) );
1389 y=mymalloc( len*sizeof(double) );
1390 for(i=0;i<len;i++) {
1391 sv1=(*(av_fetch(av1,i,0)));
1392 sv2=(*(av_fetch(av2,i,0)));
1393 x[i]=(double)SvNV(sv1);
1394 y[i]=(double)SvNV(sv2);
1396 i_poly_aa(im,len,x,y,val);
1401 i_poly_aa_cfill(im,xc,yc,fill)
1403 Imager::FillHandle fill
1413 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1414 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1415 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1416 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1417 av1=(AV*)SvRV(ST(1));
1418 av2=(AV*)SvRV(ST(2));
1419 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1421 x=mymalloc( len*sizeof(double) );
1422 y=mymalloc( len*sizeof(double) );
1423 for(i=0;i<len;i++) {
1424 sv1=(*(av_fetch(av1,i,0)));
1425 sv2=(*(av_fetch(av2,i,0)));
1426 x[i]=(double)SvNV(sv1);
1427 y[i]=(double)SvNV(sv2);
1429 i_poly_aa_cfill(im,len,x,y,fill);
1436 i_flood_fill(im,seedx,seedy,dcol)
1443 i_flood_cfill(im,seedx,seedy,fill)
1447 Imager::FillHandle fill
1451 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1463 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1481 i_rubthru(im,src,tx,ty)
1488 i_flipxy(im, direction)
1493 i_rotate90(im, degrees)
1498 i_rotate_exact(im, amount)
1503 i_matrix_transform(im, xsize, ysize, matrix)
1514 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1515 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1516 av=(AV*)SvRV(ST(3));
1520 for (i = 0; i < len; ++i) {
1521 sv1=(*(av_fetch(av,i,0)));
1522 matrix[i] = SvNV(sv1);
1526 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1531 i_gaussian(im,stdev)
1536 i_unsharp_mask(im,stdev,scale)
1551 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1552 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1553 av=(AV*)SvRV(ST(1));
1555 coeff=mymalloc( len*sizeof(float) );
1556 for(i=0;i<len;i++) {
1557 sv1=(*(av_fetch(av,i,0)));
1558 coeff[i]=(float)SvNV(sv1);
1560 i_conv(im,coeff,len);
1564 i_convert(im, src, coeff)
1578 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1579 croak("i_convert: parameter 3 must be an arrayref\n");
1580 avmain = (AV*)SvRV(ST(2));
1581 outchan = av_len(avmain)+1;
1582 /* find the biggest */
1584 for (j=0; j < outchan; ++j) {
1585 temp = av_fetch(avmain, j, 0);
1586 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1587 avsub = (AV*)SvRV(*temp);
1588 len = av_len(avsub)+1;
1593 coeff = mymalloc(sizeof(float) * outchan * inchan);
1594 for (j = 0; j < outchan; ++j) {
1595 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1596 len = av_len(avsub)+1;
1597 for (i = 0; i < len; ++i) {
1598 temp = av_fetch(avsub, i, 0);
1600 coeff[i+j*inchan] = SvNV(*temp);
1602 coeff[i+j*inchan] = 0;
1605 coeff[i++ + j*inchan] = 0;
1607 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1617 unsigned int mask = 0;
1623 unsigned char (*maps)[256];
1625 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1626 croak("i_map: parameter 2 must be an arrayref\n");
1627 avmain = (AV*)SvRV(ST(1));
1628 len = av_len(avmain)+1;
1629 if (im->channels < len) len = im->channels;
1631 maps = mymalloc( len * sizeof(unsigned char [256]) );
1633 for (j=0; j<len ; j++) {
1634 temp = av_fetch(avmain, j, 0);
1635 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1636 avsub = (AV*)SvRV(*temp);
1637 if(av_len(avsub) != 255) continue;
1639 for (i=0; i<256 ; i++) {
1641 temp = av_fetch(avsub, i, 0);
1642 val = temp ? SvIV(*temp) : 0;
1644 if (val>255) val = 255;
1649 i_map(im, maps, mask);
1662 i_init_fonts(t1log=0)
1677 i_t1_destroy(font_id)
1682 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1701 str = SvPV(str_sv, len);
1702 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1709 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1725 str = SvPV(str_sv, len);
1726 i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1728 for (i = 0; i < 6; ++i)
1729 PUSHs(sv_2mortal(newSViv(cords[i])));
1734 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1753 str = SvPV(str_sv, len);
1754 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1769 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1771 #define TT_DESTROY(handle) i_tt_destroy(handle)
1775 Imager::Font::TT handle
1778 MODULE = Imager PACKAGE = Imager
1782 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
1783 Imager::Font::TT handle
1801 str = SvPV(str_sv, len);
1802 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1809 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
1810 Imager::Font::TT handle
1828 str = SvPV(str_sv, len);
1829 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1836 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1837 Imager::Font::TT handle
1851 str = SvPV(str_sv, len);
1852 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1854 PUSHs(sv_2mortal(newSViv(cords[0])));
1855 PUSHs(sv_2mortal(newSViv(cords[1])));
1856 PUSHs(sv_2mortal(newSViv(cords[2])));
1857 PUSHs(sv_2mortal(newSViv(cords[3])));
1858 PUSHs(sv_2mortal(newSViv(cords[4])));
1859 PUSHs(sv_2mortal(newSViv(cords[5])));
1863 i_tt_has_chars(handle, text_sv, utf8)
1864 Imager::Font::TT handle
1875 if (SvUTF8(text_sv))
1878 text = SvPV(text_sv, len);
1879 work = mymalloc(len);
1880 count = i_tt_has_chars(handle, text, len, utf8, work);
1881 if (GIMME_V == G_ARRAY) {
1883 for (i = 0; i < count; ++i) {
1884 PUSHs(sv_2mortal(newSViv(work[i])));
1889 PUSHs(sv_2mortal(newSVpv(work, count)));
1900 i_writejpeg_wiol(im, ig, qfactor)
1916 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1917 if (iptc_itext == NULL) {
1920 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1925 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1927 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1940 i_readtiff_wiol(ig, length)
1945 i_readtiff_multi_wiol(ig, length)
1953 imgs = i_readtiff_multi_wiol(ig, length, &count);
1956 for (i = 0; i < count; ++i) {
1957 SV *sv = sv_newmortal();
1958 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1966 i_writetiff_wiol(im, ig)
1971 i_writetiff_multi_wiol(ig, ...)
1979 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
1980 img_count = items - 1;
1982 if (img_count < 1) {
1985 i_push_error(0, "You need to specify images to save");
1988 imgs = mymalloc(sizeof(i_img *) * img_count);
1989 for (i = 0; i < img_count; ++i) {
1992 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1993 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
1997 i_push_error(0, "Only images can be saved");
2004 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2012 i_writetiff_wiol_faxable(im, ig, fine)
2018 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2027 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2028 img_count = items - 2;
2030 if (img_count < 1) {
2033 i_push_error(0, "You need to specify images to save");
2036 imgs = mymalloc(sizeof(i_img *) * img_count);
2037 for (i = 0; i < img_count; ++i) {
2040 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2041 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2045 i_push_error(0, "Only images can be saved");
2052 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2060 #endif /* HAVE_LIBTIFF */
2066 i_readpng_wiol(ig, length)
2072 i_writepng_wiol(im, ig)
2085 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2088 i_writegif(im,fd,colors,pixdev,fixed)
2095 Imager__Color fixed;
2102 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2103 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2104 av=(AV*)SvRV(ST(4));
2105 fixedlen=av_len(av)+1;
2106 fixed=mymalloc( fixedlen*sizeof(i_color) );
2107 for(i=0;i<fixedlen;i++) {
2108 sv1=(*(av_fetch(av,i,0)));
2109 if (sv_derived_from(sv1, "Imager::Color")) {
2110 Itmp = SvIV((SV*)SvRV(sv1));
2111 tmp = (i_color*) Itmp;
2112 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2115 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2117 ST(0) = sv_newmortal();
2118 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2119 else sv_setiv(ST(0), (IV)RETVAL);
2125 i_writegifmc(im,fd,colors)
2132 i_writegif_gen(fd, ...)
2137 i_img **imgs = NULL;
2143 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2144 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2145 croak("i_writegif_gen: Second argument must be a hash ref");
2146 hv = (HV *)SvRV(ST(1));
2147 memset(&quant, 0, sizeof(quant));
2148 quant.mc_size = 256;
2149 handle_quant_opts(&quant, hv);
2150 img_count = items - 2;
2152 if (img_count < 1) {
2155 i_push_error(0, "You need to specify images to save");
2158 imgs = mymalloc(sizeof(i_img *) * img_count);
2159 for (i = 0; i < img_count; ++i) {
2162 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2163 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2167 i_push_error(0, "Only images can be saved");
2173 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2177 copy_colors_back(hv, &quant);
2180 ST(0) = sv_newmortal();
2181 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2182 else sv_setiv(ST(0), (IV)RETVAL);
2183 cleanup_quant_opts(&quant);
2187 i_writegif_callback(cb, maxbuffer,...)
2191 i_img **imgs = NULL;
2198 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2199 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2200 croak("i_writegif_callback: Second argument must be a hash ref");
2201 hv = (HV *)SvRV(ST(2));
2202 memset(&quant, 0, sizeof(quant));
2203 quant.mc_size = 256;
2204 handle_quant_opts(&quant, hv);
2205 img_count = items - 3;
2207 if (img_count < 1) {
2211 imgs = mymalloc(sizeof(i_img *) * img_count);
2212 for (i = 0; i < img_count; ++i) {
2215 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2216 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2225 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2229 copy_colors_back(hv, &quant);
2232 ST(0) = sv_newmortal();
2233 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2234 else sv_setiv(ST(0), (IV)RETVAL);
2235 cleanup_quant_opts(&quant);
2238 i_writegif_wiol(ig, opts,...)
2242 i_img **imgs = NULL;
2248 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2249 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2250 croak("i_writegif_callback: Second argument must be a hash ref");
2251 hv = (HV *)SvRV(ST(1));
2252 memset(&quant, 0, sizeof(quant));
2253 quant.mc_size = 256;
2254 handle_quant_opts(&quant, hv);
2255 img_count = items - 2;
2257 if (img_count < 1) {
2261 imgs = mymalloc(sizeof(i_img *) * img_count);
2262 for (i = 0; i < img_count; ++i) {
2265 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2266 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2274 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2278 copy_colors_back(hv, &quant);
2281 ST(0) = sv_newmortal();
2282 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2283 else sv_setiv(ST(0), (IV)RETVAL);
2284 cleanup_quant_opts(&quant);
2297 colour_table = NULL;
2300 if(GIMME_V == G_ARRAY) {
2301 rimg = i_readgif(fd,&colour_table,&colours);
2303 /* don't waste time with colours if they aren't wanted */
2304 rimg = i_readgif(fd,NULL,NULL);
2307 if (colour_table == NULL) {
2310 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2313 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2314 /* I don't know if I have the reference counts right or not :( */
2315 /* Neither do I :-) */
2316 /* No Idea here either */
2319 av_extend(ct, colours);
2320 for(q=0; q<colours; q++) {
2322 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2323 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2325 myfree(colour_table);
2329 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2331 PUSHs(newRV_noinc((SV*)ct));
2345 colour_table = NULL;
2348 if(GIMME_V == G_ARRAY) {
2349 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2351 /* don't waste time with colours if they aren't wanted */
2352 rimg = i_readgif_wiol(ig,NULL,NULL);
2355 if (colour_table == NULL) {
2358 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2361 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2362 /* I don't know if I have the reference counts right or not :( */
2363 /* Neither do I :-) */
2364 /* No Idea here either */
2367 av_extend(ct, colours);
2368 for(q=0; q<colours; q++) {
2370 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2371 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2373 myfree(colour_table);
2377 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2379 PUSHs(newRV_noinc((SV*)ct));
2383 i_readgif_scalar(...)
2395 data = (char *)SvPV(ST(0), length);
2399 if(GIMME_V == G_ARRAY) {
2400 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2402 /* don't waste time with colours if they aren't wanted */
2403 rimg=i_readgif_scalar(data,length,NULL,NULL);
2406 if (colour_table == NULL) {
2409 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2412 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2413 /* I don't know if I have the reference counts right or not :( */
2414 /* Neither do I :-) */
2416 av_extend(ct, colours);
2417 for(q=0; q<colours; q++) {
2419 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2420 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2422 myfree(colour_table);
2426 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2428 PUSHs(newRV_noinc((SV*)ct));
2432 i_readgif_callback(...)
2449 if(GIMME_V == G_ARRAY) {
2450 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2452 /* don't waste time with colours if they aren't wanted */
2453 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2456 if (colour_table == NULL) {
2459 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2462 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2463 /* I don't know if I have the reference counts right or not :( */
2464 /* Neither do I :-) */
2465 /* Neither do I - maybe I'll move this somewhere */
2467 av_extend(ct, colours);
2468 for(q=0; q<colours; q++) {
2470 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2471 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2473 myfree(colour_table);
2477 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2479 PUSHs(newRV_noinc((SV*)ct));
2490 imgs = i_readgif_multi(fd, &count);
2493 for (i = 0; i < count; ++i) {
2494 SV *sv = sv_newmortal();
2495 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2502 i_readgif_multi_scalar(data)
2510 data = (char *)SvPV(ST(0), length);
2511 imgs = i_readgif_multi_scalar(data, length, &count);
2514 for (i = 0; i < count; ++i) {
2515 SV *sv = sv_newmortal();
2516 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2523 i_readgif_multi_callback(cb)
2531 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2534 for (i = 0; i < count; ++i) {
2535 SV *sv = sv_newmortal();
2536 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2543 i_readgif_multi_wiol(ig)
2550 imgs = i_readgif_multi_wiol(ig, &count);
2553 for (i = 0; i < count; ++i) {
2554 SV *sv = sv_newmortal();
2555 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2567 i_readpnm_wiol(ig, length)
2573 i_writeppm_wiol(im, ig)
2579 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2588 i_writeraw_wiol(im,ig)
2593 i_writebmp_wiol(im,ig)
2603 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2614 idlen = SvCUR(ST(4));
2615 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2621 i_readtga_wiol(ig, length)
2627 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2638 idlen = SvCUR(ST(4));
2639 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2645 i_readrgb_wiol(ig, length)
2652 i_scaleaxis(im,Value,Axis)
2658 i_scale_nn(im,scx,scy)
2668 i_count_colors(im,maxc)
2674 i_transform(im,opx,opy,parm)
2687 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2688 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2689 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2690 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2691 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2692 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2693 av=(AV*)SvRV(ST(1));
2695 opx=mymalloc( opxl*sizeof(int) );
2696 for(i=0;i<opxl;i++) {
2697 sv1=(*(av_fetch(av,i,0)));
2698 opx[i]=(int)SvIV(sv1);
2700 av=(AV*)SvRV(ST(2));
2702 opy=mymalloc( opyl*sizeof(int) );
2703 for(i=0;i<opyl;i++) {
2704 sv1=(*(av_fetch(av,i,0)));
2705 opy[i]=(int)SvIV(sv1);
2707 av=(AV*)SvRV(ST(3));
2708 parmlen=av_len(av)+1;
2709 parm=mymalloc( parmlen*sizeof(double) );
2710 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2711 sv1=(*(av_fetch(av,i,0)));
2712 parm[i]=(double)SvNV(sv1);
2714 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2718 ST(0) = sv_newmortal();
2719 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2720 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2723 i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
2742 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
2743 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
2744 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
2745 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2746 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2748 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2750 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2751 av = (AV*)SvRV(ST(5));
2752 in_imgs_count = av_len(av)+1;
2753 for (i = 0; i < in_imgs_count; ++i) {
2754 sv1 = *av_fetch(av, i, 0);
2755 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2756 croak("Parameter 5 must contain only images");
2763 if (in_imgs_count > 0) {
2764 av = (AV*)SvRV(ST(5));
2765 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2766 for (i = 0; i < in_imgs_count; ++i) {
2767 sv1 = *av_fetch(av,i,0);
2768 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2769 croak("Parameter 5 must contain only images");
2771 tmp = SvIV((SV*)SvRV(sv1));
2772 in_imgs[i] = INT2PTR(i_img*, tmp);
2776 /* no input images */
2779 /* default the output size from the first input if possible */
2781 width = SvIV(ST(0));
2782 else if (in_imgs_count)
2783 width = in_imgs[0]->xsize;
2785 croak("No output image width supplied");
2788 height = SvIV(ST(1));
2789 else if (in_imgs_count)
2790 height = in_imgs[0]->ysize;
2792 croak("No output image height supplied");
2794 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2795 if (ops_len % sizeof(struct rm_op))
2796 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2797 ops_count = ops_len / sizeof(struct rm_op);
2798 av = (AV*)SvRV(ST(3));
2799 n_regs_count = av_len(av)+1;
2800 n_regs = mymalloc(n_regs_count * sizeof(double));
2801 for (i = 0; i < n_regs_count; ++i) {
2802 sv1 = *av_fetch(av,i,0);
2804 n_regs[i] = SvNV(sv1);
2806 av = (AV*)SvRV(ST(4));
2807 c_regs_count = av_len(av)+1;
2808 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2809 /* I don't bother initializing the colou?r registers */
2811 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2812 n_regs, n_regs_count,
2813 c_regs, c_regs_count, in_imgs, in_imgs_count);
2818 ST(0) = sv_newmortal();
2819 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2820 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2824 i_contrast(im,intensity)
2833 i_noise(im,amount,type)
2839 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2849 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2868 i_postlevels(im,levels)
2878 i_watermark(im,wmark,tx,ty,pixdiff)
2880 Imager::ImgRaw wmark
2887 i_autolevels(im,lsat,usat,skew)
2894 i_radnoise(im,xo,yo,rscale,ascale)
2902 i_turbnoise(im, xo, yo, scale)
2925 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2926 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2927 croak("i_gradgen: Second argument must be an array ref");
2928 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2929 croak("i_gradgen: Third argument must be an array ref");
2930 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2931 croak("i_gradgen: Fourth argument must be an array ref");
2932 axx = (AV *)SvRV(ST(1));
2933 ayy = (AV *)SvRV(ST(2));
2934 ac = (AV *)SvRV(ST(3));
2935 dmeasure = (int)SvIV(ST(4));
2937 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2938 num = num <= av_len(ac) ? num : av_len(ac);
2940 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2941 xo = mymalloc( sizeof(int) * num );
2942 yo = mymalloc( sizeof(int) * num );
2943 ival = mymalloc( sizeof(i_color) * num );
2944 for(i = 0; i<num; i++) {
2945 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2946 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2947 sv = *av_fetch(ac, i, 0);
2948 if ( !sv_derived_from(sv, "Imager::Color") ) {
2949 free(axx); free(ayy); free(ac);
2950 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2952 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2954 i_gradgen(im, num, xo, yo, ival, dmeasure);
2960 i_diff_image(im, im2, mindist=0)
2966 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2976 double ssample_param
2980 i_fountain_seg *segs;
2982 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2983 croak("i_fountain: argument 11 must be an array ref");
2985 asegs = (AV *)SvRV(ST(10));
2986 segs = load_fount_segs(asegs, &count);
2987 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
2988 ssample_param, count, segs);
2992 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3001 double ssample_param
3005 i_fountain_seg *segs;
3007 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3008 croak("i_fountain: argument 11 must be an array ref");
3010 asegs = (AV *)SvRV(ST(9));
3011 segs = load_fount_segs(asegs, &count);
3012 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3013 super_sample, ssample_param, count, segs);
3027 errors = i_errors();
3029 while (errors[i].msg) {
3031 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3032 if (!av_store(av, 0, sv)) {
3035 sv = newSViv(errors[i].code);
3036 if (!av_store(av, 1, sv)) {
3039 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3044 i_nearest_color(im, ...)
3059 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3060 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3061 croak("i_nearest_color: Second argument must be an array ref");
3062 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3063 croak("i_nearest_color: Third argument must be an array ref");
3064 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3065 croak("i_nearest_color: Fourth argument must be an array ref");
3066 axx = (AV *)SvRV(ST(1));
3067 ayy = (AV *)SvRV(ST(2));
3068 ac = (AV *)SvRV(ST(3));
3069 dmeasure = (int)SvIV(ST(4));
3071 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3072 num = num <= av_len(ac) ? num : av_len(ac);
3074 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3075 xo = mymalloc( sizeof(int) * num );
3076 yo = mymalloc( sizeof(int) * num );
3077 ival = mymalloc( sizeof(i_color) * num );
3078 for(i = 0; i<num; i++) {
3079 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3080 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3081 sv = *av_fetch(ac, i, 0);
3082 if ( !sv_derived_from(sv, "Imager::Color") ) {
3083 free(axx); free(ayy); free(ac);
3084 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3086 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3088 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3102 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3103 hv=(HV*)SvRV(ST(0));
3104 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3105 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3106 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3115 rc=DSO_open(filename,&evstr);
3119 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3120 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3123 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3129 DSO_close(dso_handle)
3133 DSO_funclist(dso_handle_v)
3137 DSO_handle *dso_handle;
3139 dso_handle=(DSO_handle*)dso_handle_v;
3141 while( dso_handle->function_list[i].name != NULL) {
3143 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3145 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3150 DSO_call(handle,func_index,hv)
3156 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3157 hv=(HV*)SvRV(ST(2));
3158 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3159 DSO_call( (DSO_handle *)handle,func_index,hv);
3163 # this is mostly for testing...
3165 i_get_pixel(im, x, y)
3172 color = (i_color *)mymalloc(sizeof(i_color));
3173 if (i_gpix(im, x, y, color) == 0) {
3174 ST(0) = sv_newmortal();
3175 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3179 ST(0) = &PL_sv_undef;
3184 i_ppix(im, x, y, cl)
3191 i_img_pal_new(x, y, channels, maxpal)
3198 i_img_to_pal(src, quant)
3204 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3205 croak("i_img_to_pal: second argument must be a hash ref");
3206 hv = (HV *)SvRV(ST(1));
3207 memset(&quant, 0, sizeof(quant));
3208 quant.mc_size = 256;
3209 handle_quant_opts(&quant, hv);
3210 RETVAL = i_img_to_pal(src, &quant);
3212 copy_colors_back(hv, &quant);
3214 cleanup_quant_opts(&quant);
3233 work = mymalloc((r-l) * sizeof(i_palidx));
3234 count = i_gpal(im, l, r, y, work);
3235 if (GIMME_V == G_ARRAY) {
3237 for (i = 0; i < count; ++i) {
3238 PUSHs(sv_2mortal(newSViv(work[i])));
3243 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3248 if (GIMME_V != G_ARRAY) {
3250 PUSHs(&PL_sv_undef);
3255 i_ppal(im, l, y, ...)
3264 work = mymalloc(sizeof(i_palidx) * (items-3));
3265 for (i=0; i < items-3; ++i) {
3266 work[i] = SvIV(ST(i+3));
3268 RETVAL = i_ppal(im, l, l+items-3, y, work);
3278 i_addcolors(im, ...)
3286 croak("i_addcolors: no colors to add");
3287 colors = mymalloc((items-1) * sizeof(i_color));
3288 for (i=0; i < items-1; ++i) {
3289 if (sv_isobject(ST(i+1))
3290 && sv_derived_from(ST(i+1), "Imager::Color")) {
3291 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3292 colors[i] = *INT2PTR(i_color *, tmp);
3296 croak("i_plin: pixels must be Imager::Color objects");
3299 index = i_addcolors(im, colors, items-1);
3302 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3304 else if (index == -1) {
3305 ST(0) = &PL_sv_undef;
3308 ST(0) = sv_2mortal(newSViv(index));
3312 i_setcolors(im, index, ...)
3320 croak("i_setcolors: no colors to add");
3321 colors = mymalloc((items-2) * sizeof(i_color));
3322 for (i=0; i < items-2; ++i) {
3323 if (sv_isobject(ST(i+2))
3324 && sv_derived_from(ST(i+2), "Imager::Color")) {
3325 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3326 colors[i] = *INT2PTR(i_color *, tmp);
3330 croak("i_setcolors: pixels must be Imager::Color objects");
3333 RETVAL = i_setcolors(im, index, colors, items-2);
3337 i_getcolors(im, index, ...)
3346 croak("i_getcolors: too many arguments");
3348 count = SvIV(ST(2));
3350 croak("i_getcolors: count must be positive");
3351 colors = mymalloc(sizeof(i_color) * count);
3352 if (i_getcolors(im, index, colors, count)) {
3353 for (i = 0; i < count; ++i) {
3355 SV *sv = sv_newmortal();
3356 pv = mymalloc(sizeof(i_color));
3358 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3371 count = i_colorcount(im);
3373 ST(0) = sv_2mortal(newSViv(count));
3376 ST(0) = &PL_sv_undef;
3385 count = i_maxcolors(im);
3387 ST(0) = sv_2mortal(newSViv(count));
3390 ST(0) = &PL_sv_undef;
3394 i_findcolor(im, color)
3400 if (i_findcolor(im, color, &index)) {
3401 ST(0) = sv_2mortal(newSViv(index));
3404 ST(0) = &PL_sv_undef;
3420 i_gsamp(im, l, r, y, ...)
3432 croak("No channel numbers supplied to g_samp()");
3434 chan_count = items - 4;
3435 chans = mymalloc(sizeof(int) * chan_count);
3436 for (i = 0; i < chan_count; ++i)
3437 chans[i] = SvIV(ST(i+4));
3438 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3439 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3441 if (GIMME_V == G_ARRAY) {
3443 for (i = 0; i < count; ++i)
3444 PUSHs(sv_2mortal(newSViv(data[i])));
3448 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3453 if (GIMME_V != G_ARRAY) {
3455 PUSHs(&PL_sv_undef);
3461 i_img_masked_new(targ, mask, x, y, w, h)
3471 if (!sv_isobject(ST(1))
3472 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3473 croak("i_img_masked_new: parameter 2 must undef or an image");
3475 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3479 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3484 i_plin(im, l, y, ...)
3493 work = mymalloc(sizeof(i_color) * (items-3));
3494 for (i=0; i < items-3; ++i) {
3495 if (sv_isobject(ST(i+3))
3496 && sv_derived_from(ST(i+3), "Imager::Color")) {
3497 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3498 work[i] = *INT2PTR(i_color *, tmp);
3502 croak("i_plin: pixels must be Imager::Color objects");
3506 RETVAL = i_plin(im, l, l+items-3, y, work);
3516 i_ppixf(im, x, y, cl)
3520 Imager::Color::Float cl
3523 i_gsampf(im, l, r, y, ...)
3535 croak("No channel numbers supplied to g_sampf()");
3537 chan_count = items - 4;
3538 chans = mymalloc(sizeof(int) * chan_count);
3539 for (i = 0; i < chan_count; ++i)
3540 chans[i] = SvIV(ST(i+4));
3541 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3542 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3543 if (GIMME_V == G_ARRAY) {
3545 for (i = 0; i < count; ++i)
3546 PUSHs(sv_2mortal(newSVnv(data[i])));
3550 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3554 if (GIMME_V != G_ARRAY) {
3556 PUSHs(&PL_sv_undef);
3561 i_plinf(im, l, y, ...)
3570 work = mymalloc(sizeof(i_fcolor) * (items-3));
3571 for (i=0; i < items-3; ++i) {
3572 if (sv_isobject(ST(i+3))
3573 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3574 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3575 work[i] = *INT2PTR(i_fcolor *, tmp);
3579 croak("i_plin: pixels must be Imager::Color::Float objects");
3583 RETVAL = i_plinf(im, l, l+items-3, y, work);
3600 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3601 if (i_gpixf(im, x, y, color) == 0) {
3602 ST(0) = sv_newmortal();
3603 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3607 ST(0) = &PL_sv_undef;
3621 vals = mymalloc((r-l) * sizeof(i_color));
3622 count = i_glin(im, l, r, y, vals);
3624 for (i = 0; i < count; ++i) {
3626 i_color *col = mymalloc(sizeof(i_color));
3627 sv = sv_newmortal();
3628 sv_setref_pv(sv, "Imager::Color", (void *)col);
3635 i_glinf(im, l, r, y)
3645 vals = mymalloc((r-l) * sizeof(i_fcolor));
3646 count = i_glinf(im, l, r, y, vals);
3648 for (i = 0; i < count; ++i) {
3650 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3652 sv = sv_newmortal();
3653 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3660 i_img_16_new(x, y, ch)
3666 i_img_double_new(x, y, ch)
3672 i_tags_addn(im, name, code, idata)
3681 name = SvPV(ST(1), len);
3684 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3689 i_tags_add(im, name, code, data, idata)
3699 name = SvPV(ST(1), len);
3703 data = SvPV(ST(3), len);
3708 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3713 i_tags_find(im, name, start)
3720 if (i_tags_find(&im->tags, name, start, &entry)) {
3722 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3724 ST(0) = sv_2mortal(newSViv(entry));
3726 ST(0) = &PL_sv_undef;
3730 i_tags_findn(im, code, start)
3737 if (i_tags_findn(&im->tags, code, start, &entry)) {
3739 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3741 ST(0) = sv_2mortal(newSViv(entry));
3744 ST(0) = &PL_sv_undef;
3747 i_tags_delete(im, entry)
3751 RETVAL = i_tags_delete(&im->tags, entry);
3756 i_tags_delbyname(im, name)
3760 RETVAL = i_tags_delbyname(&im->tags, name);
3765 i_tags_delbycode(im, code)
3769 RETVAL = i_tags_delbycode(&im->tags, code);
3774 i_tags_get(im, index)
3778 if (index >= 0 && index < im->tags.count) {
3779 i_img_tag *entry = im->tags.tags + index;
3783 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3786 PUSHs(sv_2mortal(newSViv(entry->code)));
3789 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3792 PUSHs(sv_2mortal(newSViv(entry->idata)));
3800 RETVAL = im->tags.count;
3807 i_wf_bbox(face, size, text)
3814 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
3816 PUSHs(sv_2mortal(newSViv(cords[0])));
3817 PUSHs(sv_2mortal(newSViv(cords[1])));
3818 PUSHs(sv_2mortal(newSViv(cords[2])));
3819 PUSHs(sv_2mortal(newSViv(cords[3])));
3820 PUSHs(sv_2mortal(newSViv(cords[4])));
3821 PUSHs(sv_2mortal(newSViv(cords[5])));
3825 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3836 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3842 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3853 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3863 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3865 #define FT2_DESTROY(font) i_ft2_destroy(font)
3869 Imager::Font::FT2 font
3871 MODULE = Imager PACKAGE = Imager::Font::FreeType2
3874 i_ft2_new(name, index)
3879 i_ft2_setdpi(font, xdpi, ydpi)
3880 Imager::Font::FT2 font
3886 Imager::Font::FT2 font
3890 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3892 PUSHs(sv_2mortal(newSViv(xdpi)));
3893 PUSHs(sv_2mortal(newSViv(ydpi)));
3897 i_ft2_sethinting(font, hinting)
3898 Imager::Font::FT2 font
3902 i_ft2_settransform(font, matrix)
3903 Imager::Font::FT2 font
3911 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3912 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3913 av=(AV*)SvRV(ST(1));
3917 for (i = 0; i < len; ++i) {
3918 sv1=(*(av_fetch(av,i,0)));
3919 matrix[i] = SvNV(sv1);
3923 RETVAL = i_ft2_settransform(font, matrix);
3928 i_ft2_bbox(font, cheight, cwidth, text, utf8)
3929 Imager::Font::FT2 font
3942 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox, utf8)) {
3944 for (i = 0; i < 6; ++i)
3945 PUSHs(sv_2mortal(newSViv(bbox[i])));
3949 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
3950 Imager::Font::FT2 font
3964 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
3967 for (i = 0; i < 8; ++i)
3968 PUSHs(sv_2mortal(newSViv(bbox[i])));
3972 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
3973 Imager::Font::FT2 font
3989 if (SvUTF8(ST(7))) {
3993 text = SvPV(ST(7), len);
3994 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
3995 len, align, aa, vlayout, utf8);
4000 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4001 Imager::Font::FT2 font
4018 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4019 strlen(text), align, aa, vlayout, 1);
4024 ft2_transform_box(font, x0, x1, x2, x3)
4025 Imager::Font::FT2 font
4033 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4034 ft2_transform_box(font, box);
4036 PUSHs(sv_2mortal(newSViv(box[0])));
4037 PUSHs(sv_2mortal(newSViv(box[1])));
4038 PUSHs(sv_2mortal(newSViv(box[2])));
4039 PUSHs(sv_2mortal(newSViv(box[3])));
4042 i_ft2_has_chars(handle, text_sv, utf8)
4043 Imager::Font::FT2 handle
4054 if (SvUTF8(text_sv))
4057 text = SvPV(text_sv, len);
4058 work = mymalloc(len);
4059 count = i_ft2_has_chars(handle, text, len, utf8, work);
4060 if (GIMME_V == G_ARRAY) {
4062 for (i = 0; i < count; ++i) {
4063 PUSHs(sv_2mortal(newSViv(work[i])));
4068 PUSHs(sv_2mortal(newSVpv(work, count)));
4074 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4078 Imager::FillHandle fill
4080 MODULE = Imager PACKAGE = Imager
4083 i_new_fill_solid(cl, combine)
4088 i_new_fill_solidf(cl, combine)
4089 Imager::Color::Float cl
4093 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4101 unsigned char *cust_hatch;
4105 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4109 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4114 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4115 Imager::Color::Float fg
4116 Imager::Color::Float bg
4122 unsigned char *cust_hatch;
4126 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4130 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4135 i_new_fill_image(src, matrix, xoff, yoff, combine)
4152 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4153 croak("i_new_fill_image: parameter must be an arrayref");
4154 av=(AV*)SvRV(ST(1));
4158 for (i = 0; i < len; ++i) {
4159 sv1=(*(av_fetch(av,i,0)));
4160 matrix[i] = SvNV(sv1);
4166 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);