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(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)
1247 PUSHs(im->idata ? sv_2mortal(newSVpv(im->idata, im->bytes))
1252 i_draw(im,x1,y1,x2,y2,val)
1261 i_line_aa(im,x1,y1,x2,y2,val)
1270 i_box(im,x1,y1,x2,y2,val)
1279 i_box_filled(im,x1,y1,x2,y2,val)
1288 i_box_cfill(im,x1,y1,x2,y2,fill)
1294 Imager::FillHandle fill
1297 i_arc(im,x,y,rad,d1,d2,val)
1307 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1314 Imager::FillHandle fill
1319 i_circle_aa(im,x,y,rad,val)
1329 i_bezier_multi(im,xc,yc,val)
1342 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1343 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1344 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1345 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1346 av1=(AV*)SvRV(ST(1));
1347 av2=(AV*)SvRV(ST(2));
1348 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1350 x=mymalloc( len*sizeof(double) );
1351 y=mymalloc( len*sizeof(double) );
1352 for(i=0;i<len;i++) {
1353 sv1=(*(av_fetch(av1,i,0)));
1354 sv2=(*(av_fetch(av2,i,0)));
1355 x[i]=(double)SvNV(sv1);
1356 y[i]=(double)SvNV(sv2);
1358 i_bezier_multi(im,len,x,y,val);
1364 i_poly_aa(im,xc,yc,val)
1377 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1378 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1379 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1380 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1381 av1=(AV*)SvRV(ST(1));
1382 av2=(AV*)SvRV(ST(2));
1383 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1385 x=mymalloc( len*sizeof(double) );
1386 y=mymalloc( len*sizeof(double) );
1387 for(i=0;i<len;i++) {
1388 sv1=(*(av_fetch(av1,i,0)));
1389 sv2=(*(av_fetch(av2,i,0)));
1390 x[i]=(double)SvNV(sv1);
1391 y[i]=(double)SvNV(sv2);
1393 i_poly_aa(im,len,x,y,val);
1398 i_poly_aa_cfill(im,xc,yc,fill)
1400 Imager::FillHandle fill
1410 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1411 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1412 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1413 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1414 av1=(AV*)SvRV(ST(1));
1415 av2=(AV*)SvRV(ST(2));
1416 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1418 x=mymalloc( len*sizeof(double) );
1419 y=mymalloc( len*sizeof(double) );
1420 for(i=0;i<len;i++) {
1421 sv1=(*(av_fetch(av1,i,0)));
1422 sv2=(*(av_fetch(av2,i,0)));
1423 x[i]=(double)SvNV(sv1);
1424 y[i]=(double)SvNV(sv2);
1426 i_poly_aa_cfill(im,len,x,y,fill);
1433 i_flood_fill(im,seedx,seedy,dcol)
1440 i_flood_cfill(im,seedx,seedy,fill)
1444 Imager::FillHandle fill
1448 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1460 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1478 i_rubthru(im,src,tx,ty)
1485 i_flipxy(im, direction)
1490 i_rotate90(im, degrees)
1495 i_rotate_exact(im, amount)
1500 i_matrix_transform(im, xsize, ysize, matrix)
1511 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1512 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1513 av=(AV*)SvRV(ST(3));
1517 for (i = 0; i < len; ++i) {
1518 sv1=(*(av_fetch(av,i,0)));
1519 matrix[i] = SvNV(sv1);
1523 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1528 i_gaussian(im,stdev)
1533 i_unsharp_mask(im,stdev,scale)
1548 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1549 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1550 av=(AV*)SvRV(ST(1));
1552 coeff=mymalloc( len*sizeof(float) );
1553 for(i=0;i<len;i++) {
1554 sv1=(*(av_fetch(av,i,0)));
1555 coeff[i]=(float)SvNV(sv1);
1557 i_conv(im,coeff,len);
1561 i_convert(im, src, coeff)
1575 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1576 croak("i_convert: parameter 3 must be an arrayref\n");
1577 avmain = (AV*)SvRV(ST(2));
1578 outchan = av_len(avmain)+1;
1579 /* find the biggest */
1581 for (j=0; j < outchan; ++j) {
1582 temp = av_fetch(avmain, j, 0);
1583 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1584 avsub = (AV*)SvRV(*temp);
1585 len = av_len(avsub)+1;
1590 coeff = mymalloc(sizeof(float) * outchan * inchan);
1591 for (j = 0; j < outchan; ++j) {
1592 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1593 len = av_len(avsub)+1;
1594 for (i = 0; i < len; ++i) {
1595 temp = av_fetch(avsub, i, 0);
1597 coeff[i+j*inchan] = SvNV(*temp);
1599 coeff[i+j*inchan] = 0;
1602 coeff[i++ + j*inchan] = 0;
1604 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1614 unsigned int mask = 0;
1620 unsigned char (*maps)[256];
1622 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1623 croak("i_map: parameter 2 must be an arrayref\n");
1624 avmain = (AV*)SvRV(ST(1));
1625 len = av_len(avmain)+1;
1626 if (im->channels < len) len = im->channels;
1628 maps = mymalloc( len * sizeof(unsigned char [256]) );
1630 for (j=0; j<len ; j++) {
1631 temp = av_fetch(avmain, j, 0);
1632 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1633 avsub = (AV*)SvRV(*temp);
1634 if(av_len(avsub) != 255) continue;
1636 for (i=0; i<256 ; i++) {
1638 temp = av_fetch(avsub, i, 0);
1639 val = temp ? SvIV(*temp) : 0;
1641 if (val>255) val = 255;
1646 i_map(im, maps, mask);
1659 i_init_fonts(t1log=0)
1674 i_t1_destroy(font_id)
1679 i_t1_cp(im,xb,yb,channel,fontnum,points,str,len,align)
1691 i_t1_bbox(fontnum,point,str,len)
1699 i_t1_bbox(fontnum,point,str,len,cords);
1701 PUSHs(sv_2mortal(newSViv(cords[0])));
1702 PUSHs(sv_2mortal(newSViv(cords[1])));
1703 PUSHs(sv_2mortal(newSViv(cords[2])));
1704 PUSHs(sv_2mortal(newSViv(cords[3])));
1705 PUSHs(sv_2mortal(newSViv(cords[4])));
1706 PUSHs(sv_2mortal(newSViv(cords[5])));
1711 i_t1_text(im,xb,yb,cl,fontnum,points,str,len,align)
1732 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1734 #define TT_DESTROY(handle) i_tt_destroy(handle)
1738 Imager::Font::TT handle
1741 MODULE = Imager PACKAGE = Imager
1745 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
1746 Imager::Font::TT handle
1764 str = SvPV(str_sv, len);
1765 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1772 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
1773 Imager::Font::TT handle
1791 str = SvPV(str_sv, len);
1792 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1799 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1800 Imager::Font::TT handle
1814 str = SvPV(str_sv, len);
1815 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1817 PUSHs(sv_2mortal(newSViv(cords[0])));
1818 PUSHs(sv_2mortal(newSViv(cords[1])));
1819 PUSHs(sv_2mortal(newSViv(cords[2])));
1820 PUSHs(sv_2mortal(newSViv(cords[3])));
1821 PUSHs(sv_2mortal(newSViv(cords[4])));
1822 PUSHs(sv_2mortal(newSViv(cords[5])));
1833 i_writejpeg_wiol(im, ig, qfactor)
1849 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1850 if (iptc_itext == NULL) {
1853 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1858 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1860 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1873 i_readtiff_wiol(ig, length)
1878 i_readtiff_multi_wiol(ig, length)
1886 imgs = i_readtiff_multi_wiol(ig, length, &count);
1889 for (i = 0; i < count; ++i) {
1890 SV *sv = sv_newmortal();
1891 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1899 i_writetiff_wiol(im, ig)
1904 i_writetiff_multi_wiol(ig, ...)
1912 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
1913 img_count = items - 1;
1915 if (img_count < 1) {
1918 i_push_error(0, "You need to specify images to save");
1921 imgs = mymalloc(sizeof(i_img *) * img_count);
1922 for (i = 0; i < img_count; ++i) {
1925 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1926 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
1930 i_push_error(0, "Only images can be saved");
1937 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
1945 i_writetiff_wiol_faxable(im, ig, fine)
1951 i_writetiff_multi_wiol_faxable(ig, fine, ...)
1960 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
1961 img_count = items - 2;
1963 if (img_count < 1) {
1966 i_push_error(0, "You need to specify images to save");
1969 imgs = mymalloc(sizeof(i_img *) * img_count);
1970 for (i = 0; i < img_count; ++i) {
1973 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1974 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
1978 i_push_error(0, "Only images can be saved");
1985 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
1993 #endif /* HAVE_LIBTIFF */
1999 i_readpng_wiol(ig, length)
2005 i_writepng_wiol(im, ig)
2018 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2021 i_writegif(im,fd,colors,pixdev,fixed)
2028 Imager__Color fixed;
2035 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2036 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2037 av=(AV*)SvRV(ST(4));
2038 fixedlen=av_len(av)+1;
2039 fixed=mymalloc( fixedlen*sizeof(i_color) );
2040 for(i=0;i<fixedlen;i++) {
2041 sv1=(*(av_fetch(av,i,0)));
2042 if (sv_derived_from(sv1, "Imager::Color")) {
2043 Itmp = SvIV((SV*)SvRV(sv1));
2044 tmp = (i_color*) Itmp;
2045 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2048 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2050 ST(0) = sv_newmortal();
2051 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2052 else sv_setiv(ST(0), (IV)RETVAL);
2058 i_writegifmc(im,fd,colors)
2065 i_writegif_gen(fd, ...)
2070 i_img **imgs = NULL;
2076 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2077 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2078 croak("i_writegif_gen: Second argument must be a hash ref");
2079 hv = (HV *)SvRV(ST(1));
2080 memset(&quant, 0, sizeof(quant));
2081 quant.mc_size = 256;
2082 handle_quant_opts(&quant, hv);
2083 img_count = items - 2;
2085 if (img_count < 1) {
2088 i_push_error(0, "You need to specify images to save");
2091 imgs = mymalloc(sizeof(i_img *) * img_count);
2092 for (i = 0; i < img_count; ++i) {
2095 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2096 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2100 i_push_error(0, "Only images can be saved");
2106 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2110 copy_colors_back(hv, &quant);
2113 ST(0) = sv_newmortal();
2114 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2115 else sv_setiv(ST(0), (IV)RETVAL);
2116 cleanup_quant_opts(&quant);
2120 i_writegif_callback(cb, maxbuffer,...)
2124 i_img **imgs = NULL;
2131 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2132 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2133 croak("i_writegif_callback: Second argument must be a hash ref");
2134 hv = (HV *)SvRV(ST(2));
2135 memset(&quant, 0, sizeof(quant));
2136 quant.mc_size = 256;
2137 handle_quant_opts(&quant, hv);
2138 img_count = items - 3;
2140 if (img_count < 1) {
2144 imgs = mymalloc(sizeof(i_img *) * img_count);
2145 for (i = 0; i < img_count; ++i) {
2148 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2149 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2158 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2162 copy_colors_back(hv, &quant);
2165 ST(0) = sv_newmortal();
2166 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2167 else sv_setiv(ST(0), (IV)RETVAL);
2168 cleanup_quant_opts(&quant);
2171 i_writegif_wiol(ig, opts,...)
2175 i_img **imgs = NULL;
2181 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2182 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2183 croak("i_writegif_callback: Second argument must be a hash ref");
2184 hv = (HV *)SvRV(ST(1));
2185 memset(&quant, 0, sizeof(quant));
2186 quant.mc_size = 256;
2187 handle_quant_opts(&quant, hv);
2188 img_count = items - 2;
2190 if (img_count < 1) {
2194 imgs = mymalloc(sizeof(i_img *) * img_count);
2195 for (i = 0; i < img_count; ++i) {
2198 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2199 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2207 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2211 copy_colors_back(hv, &quant);
2214 ST(0) = sv_newmortal();
2215 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2216 else sv_setiv(ST(0), (IV)RETVAL);
2217 cleanup_quant_opts(&quant);
2230 colour_table = NULL;
2233 if(GIMME_V == G_ARRAY) {
2234 rimg = i_readgif(fd,&colour_table,&colours);
2236 /* don't waste time with colours if they aren't wanted */
2237 rimg = i_readgif(fd,NULL,NULL);
2240 if (colour_table == NULL) {
2243 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2246 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2247 /* I don't know if I have the reference counts right or not :( */
2248 /* Neither do I :-) */
2249 /* No Idea here either */
2252 av_extend(ct, colours);
2253 for(q=0; q<colours; q++) {
2255 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2256 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2258 myfree(colour_table);
2262 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2264 PUSHs(newRV_noinc((SV*)ct));
2278 colour_table = NULL;
2281 if(GIMME_V == G_ARRAY) {
2282 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2284 /* don't waste time with colours if they aren't wanted */
2285 rimg = i_readgif_wiol(ig,NULL,NULL);
2288 if (colour_table == NULL) {
2291 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2294 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2295 /* I don't know if I have the reference counts right or not :( */
2296 /* Neither do I :-) */
2297 /* No Idea here either */
2300 av_extend(ct, colours);
2301 for(q=0; q<colours; q++) {
2303 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2304 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2306 myfree(colour_table);
2310 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2312 PUSHs(newRV_noinc((SV*)ct));
2316 i_readgif_scalar(...)
2328 data = (char *)SvPV(ST(0), length);
2332 if(GIMME_V == G_ARRAY) {
2333 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2335 /* don't waste time with colours if they aren't wanted */
2336 rimg=i_readgif_scalar(data,length,NULL,NULL);
2339 if (colour_table == NULL) {
2342 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2345 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2346 /* I don't know if I have the reference counts right or not :( */
2347 /* Neither do I :-) */
2349 av_extend(ct, colours);
2350 for(q=0; q<colours; q++) {
2352 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2353 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2355 myfree(colour_table);
2359 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2361 PUSHs(newRV_noinc((SV*)ct));
2365 i_readgif_callback(...)
2382 if(GIMME_V == G_ARRAY) {
2383 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2385 /* don't waste time with colours if they aren't wanted */
2386 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2389 if (colour_table == NULL) {
2392 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2395 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2396 /* I don't know if I have the reference counts right or not :( */
2397 /* Neither do I :-) */
2398 /* Neither do I - maybe I'll move this somewhere */
2400 av_extend(ct, colours);
2401 for(q=0; q<colours; q++) {
2403 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2404 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2406 myfree(colour_table);
2410 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2412 PUSHs(newRV_noinc((SV*)ct));
2423 imgs = i_readgif_multi(fd, &count);
2426 for (i = 0; i < count; ++i) {
2427 SV *sv = sv_newmortal();
2428 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2435 i_readgif_multi_scalar(data)
2443 data = (char *)SvPV(ST(0), length);
2444 imgs = i_readgif_multi_scalar(data, length, &count);
2447 for (i = 0; i < count; ++i) {
2448 SV *sv = sv_newmortal();
2449 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2456 i_readgif_multi_callback(cb)
2464 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2467 for (i = 0; i < count; ++i) {
2468 SV *sv = sv_newmortal();
2469 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2476 i_readgif_multi_wiol(ig)
2483 imgs = i_readgif_multi_wiol(ig, &count);
2486 for (i = 0; i < count; ++i) {
2487 SV *sv = sv_newmortal();
2488 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2500 i_readpnm_wiol(ig, length)
2506 i_writeppm_wiol(im, ig)
2512 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2521 i_writeraw_wiol(im,ig)
2526 i_writebmp_wiol(im,ig)
2536 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2547 idlen = SvCUR(ST(4));
2548 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2554 i_readtga_wiol(ig, length)
2560 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2571 idlen = SvCUR(ST(4));
2572 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2578 i_readrgb_wiol(ig, length)
2585 i_scaleaxis(im,Value,Axis)
2591 i_scale_nn(im,scx,scy)
2601 i_count_colors(im,maxc)
2607 i_transform(im,opx,opy,parm)
2620 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2621 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2622 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2623 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2624 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2625 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2626 av=(AV*)SvRV(ST(1));
2628 opx=mymalloc( opxl*sizeof(int) );
2629 for(i=0;i<opxl;i++) {
2630 sv1=(*(av_fetch(av,i,0)));
2631 opx[i]=(int)SvIV(sv1);
2633 av=(AV*)SvRV(ST(2));
2635 opy=mymalloc( opyl*sizeof(int) );
2636 for(i=0;i<opyl;i++) {
2637 sv1=(*(av_fetch(av,i,0)));
2638 opy[i]=(int)SvIV(sv1);
2640 av=(AV*)SvRV(ST(3));
2641 parmlen=av_len(av)+1;
2642 parm=mymalloc( parmlen*sizeof(double) );
2643 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2644 sv1=(*(av_fetch(av,i,0)));
2645 parm[i]=(double)SvNV(sv1);
2647 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2651 ST(0) = sv_newmortal();
2652 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2653 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2656 i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
2675 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
2676 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
2677 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
2678 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2679 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2681 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2683 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2684 av = (AV*)SvRV(ST(5));
2685 in_imgs_count = av_len(av)+1;
2686 for (i = 0; i < in_imgs_count; ++i) {
2687 sv1 = *av_fetch(av, i, 0);
2688 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2689 croak("Parameter 5 must contain only images");
2696 if (in_imgs_count > 0) {
2697 av = (AV*)SvRV(ST(5));
2698 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2699 for (i = 0; i < in_imgs_count; ++i) {
2700 sv1 = *av_fetch(av,i,0);
2701 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2702 croak("Parameter 5 must contain only images");
2704 tmp = SvIV((SV*)SvRV(sv1));
2705 in_imgs[i] = INT2PTR(i_img*, tmp);
2709 /* no input images */
2712 /* default the output size from the first input if possible */
2714 width = SvIV(ST(0));
2715 else if (in_imgs_count)
2716 width = in_imgs[0]->xsize;
2718 croak("No output image width supplied");
2721 height = SvIV(ST(1));
2722 else if (in_imgs_count)
2723 height = in_imgs[0]->ysize;
2725 croak("No output image height supplied");
2727 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2728 if (ops_len % sizeof(struct rm_op))
2729 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2730 ops_count = ops_len / sizeof(struct rm_op);
2731 av = (AV*)SvRV(ST(3));
2732 n_regs_count = av_len(av)+1;
2733 n_regs = mymalloc(n_regs_count * sizeof(double));
2734 for (i = 0; i < n_regs_count; ++i) {
2735 sv1 = *av_fetch(av,i,0);
2737 n_regs[i] = SvNV(sv1);
2739 av = (AV*)SvRV(ST(4));
2740 c_regs_count = av_len(av)+1;
2741 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2742 /* I don't bother initializing the colou?r registers */
2744 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2745 n_regs, n_regs_count,
2746 c_regs, c_regs_count, in_imgs, in_imgs_count);
2751 ST(0) = sv_newmortal();
2752 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2753 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2757 i_contrast(im,intensity)
2766 i_noise(im,amount,type)
2772 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2782 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2801 i_postlevels(im,levels)
2811 i_watermark(im,wmark,tx,ty,pixdiff)
2813 Imager::ImgRaw wmark
2820 i_autolevels(im,lsat,usat,skew)
2827 i_radnoise(im,xo,yo,rscale,ascale)
2835 i_turbnoise(im, xo, yo, scale)
2858 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2859 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2860 croak("i_gradgen: Second argument must be an array ref");
2861 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2862 croak("i_gradgen: Third argument must be an array ref");
2863 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2864 croak("i_gradgen: Fourth argument must be an array ref");
2865 axx = (AV *)SvRV(ST(1));
2866 ayy = (AV *)SvRV(ST(2));
2867 ac = (AV *)SvRV(ST(3));
2868 dmeasure = (int)SvIV(ST(4));
2870 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2871 num = num <= av_len(ac) ? num : av_len(ac);
2873 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2874 xo = mymalloc( sizeof(int) * num );
2875 yo = mymalloc( sizeof(int) * num );
2876 ival = mymalloc( sizeof(i_color) * num );
2877 for(i = 0; i<num; i++) {
2878 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2879 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2880 sv = *av_fetch(ac, i, 0);
2881 if ( !sv_derived_from(sv, "Imager::Color") ) {
2882 free(axx); free(ayy); free(ac);
2883 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2885 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2887 i_gradgen(im, num, xo, yo, ival, dmeasure);
2893 i_diff_image(im, im2, mindist=0)
2899 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2909 double ssample_param
2913 i_fountain_seg *segs;
2915 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2916 croak("i_fountain: argument 11 must be an array ref");
2918 asegs = (AV *)SvRV(ST(10));
2919 segs = load_fount_segs(asegs, &count);
2920 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
2921 ssample_param, count, segs);
2925 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2934 double ssample_param
2938 i_fountain_seg *segs;
2940 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2941 croak("i_fountain: argument 11 must be an array ref");
2943 asegs = (AV *)SvRV(ST(9));
2944 segs = load_fount_segs(asegs, &count);
2945 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2946 super_sample, ssample_param, count, segs);
2960 errors = i_errors();
2962 while (errors[i].msg) {
2964 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2965 if (!av_store(av, 0, sv)) {
2968 sv = newSViv(errors[i].code);
2969 if (!av_store(av, 1, sv)) {
2972 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2977 i_nearest_color(im, ...)
2992 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2993 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2994 croak("i_nearest_color: Second argument must be an array ref");
2995 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2996 croak("i_nearest_color: Third argument must be an array ref");
2997 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2998 croak("i_nearest_color: Fourth argument must be an array ref");
2999 axx = (AV *)SvRV(ST(1));
3000 ayy = (AV *)SvRV(ST(2));
3001 ac = (AV *)SvRV(ST(3));
3002 dmeasure = (int)SvIV(ST(4));
3004 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3005 num = num <= av_len(ac) ? num : av_len(ac);
3007 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3008 xo = mymalloc( sizeof(int) * num );
3009 yo = mymalloc( sizeof(int) * num );
3010 ival = mymalloc( sizeof(i_color) * num );
3011 for(i = 0; i<num; i++) {
3012 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3013 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3014 sv = *av_fetch(ac, i, 0);
3015 if ( !sv_derived_from(sv, "Imager::Color") ) {
3016 free(axx); free(ayy); free(ac);
3017 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3019 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3021 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3035 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3036 hv=(HV*)SvRV(ST(0));
3037 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3038 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3039 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3048 rc=DSO_open(filename,&evstr);
3052 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3053 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3056 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3062 DSO_close(dso_handle)
3066 DSO_funclist(dso_handle_v)
3070 DSO_handle *dso_handle;
3072 dso_handle=(DSO_handle*)dso_handle_v;
3074 while( dso_handle->function_list[i].name != NULL) {
3076 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3078 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3083 DSO_call(handle,func_index,hv)
3089 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3090 hv=(HV*)SvRV(ST(2));
3091 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3092 DSO_call( (DSO_handle *)handle,func_index,hv);
3096 # this is mostly for testing...
3098 i_get_pixel(im, x, y)
3105 color = (i_color *)mymalloc(sizeof(i_color));
3106 if (i_gpix(im, x, y, color) == 0) {
3107 ST(0) = sv_newmortal();
3108 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3112 ST(0) = &PL_sv_undef;
3117 i_ppix(im, x, y, cl)
3124 i_img_pal_new(x, y, channels, maxpal)
3131 i_img_to_pal(src, quant)
3137 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3138 croak("i_img_to_pal: second argument must be a hash ref");
3139 hv = (HV *)SvRV(ST(1));
3140 memset(&quant, 0, sizeof(quant));
3141 quant.mc_size = 256;
3142 handle_quant_opts(&quant, hv);
3143 RETVAL = i_img_to_pal(src, &quant);
3145 copy_colors_back(hv, &quant);
3147 cleanup_quant_opts(&quant);
3166 work = mymalloc((r-l) * sizeof(i_palidx));
3167 count = i_gpal(im, l, r, y, work);
3168 if (GIMME_V == G_ARRAY) {
3170 for (i = 0; i < count; ++i) {
3171 PUSHs(sv_2mortal(newSViv(work[i])));
3176 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
3181 if (GIMME_V != G_ARRAY) {
3183 PUSHs(&PL_sv_undef);
3188 i_ppal(im, l, y, ...)
3197 work = mymalloc(sizeof(i_palidx) * (items-3));
3198 for (i=0; i < items-3; ++i) {
3199 work[i] = SvIV(ST(i+3));
3201 RETVAL = i_ppal(im, l, l+items-3, y, work);
3211 i_addcolors(im, ...)
3219 croak("i_addcolors: no colors to add");
3220 colors = mymalloc((items-1) * sizeof(i_color));
3221 for (i=0; i < items-1; ++i) {
3222 if (sv_isobject(ST(i+1))
3223 && sv_derived_from(ST(i+1), "Imager::Color")) {
3224 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3225 colors[i] = *INT2PTR(i_color *, tmp);
3229 croak("i_plin: pixels must be Imager::Color objects");
3232 index = i_addcolors(im, colors, items-1);
3235 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3237 else if (index == -1) {
3238 ST(0) = &PL_sv_undef;
3241 ST(0) = sv_2mortal(newSViv(index));
3245 i_setcolors(im, index, ...)
3253 croak("i_setcolors: no colors to add");
3254 colors = mymalloc((items-2) * sizeof(i_color));
3255 for (i=0; i < items-2; ++i) {
3256 if (sv_isobject(ST(i+2))
3257 && sv_derived_from(ST(i+2), "Imager::Color")) {
3258 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3259 colors[i] = *INT2PTR(i_color *, tmp);
3263 croak("i_setcolors: pixels must be Imager::Color objects");
3266 RETVAL = i_setcolors(im, index, colors, items-2);
3270 i_getcolors(im, index, ...)
3279 croak("i_getcolors: too many arguments");
3281 count = SvIV(ST(2));
3283 croak("i_getcolors: count must be positive");
3284 colors = mymalloc(sizeof(i_color) * count);
3285 if (i_getcolors(im, index, colors, count)) {
3286 for (i = 0; i < count; ++i) {
3288 SV *sv = sv_newmortal();
3289 pv = mymalloc(sizeof(i_color));
3291 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3304 count = i_colorcount(im);
3306 ST(0) = sv_2mortal(newSViv(count));
3309 ST(0) = &PL_sv_undef;
3318 count = i_maxcolors(im);
3320 ST(0) = sv_2mortal(newSViv(count));
3323 ST(0) = &PL_sv_undef;
3327 i_findcolor(im, color)
3333 if (i_findcolor(im, color, &index)) {
3334 ST(0) = sv_2mortal(newSViv(index));
3337 ST(0) = &PL_sv_undef;
3353 i_gsamp(im, l, r, y, ...)
3365 croak("No channel numbers supplied to g_samp()");
3367 chan_count = items - 4;
3368 chans = mymalloc(sizeof(int) * chan_count);
3369 for (i = 0; i < chan_count; ++i)
3370 chans[i] = SvIV(ST(i+4));
3371 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3372 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3374 if (GIMME_V == G_ARRAY) {
3376 for (i = 0; i < count; ++i)
3377 PUSHs(sv_2mortal(newSViv(data[i])));
3381 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
3386 if (GIMME_V != G_ARRAY) {
3388 PUSHs(&PL_sv_undef);
3394 i_img_masked_new(targ, mask, x, y, w, h)
3404 if (!sv_isobject(ST(1))
3405 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3406 croak("i_img_masked_new: parameter 2 must undef or an image");
3408 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3412 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3417 i_plin(im, l, y, ...)
3426 work = mymalloc(sizeof(i_color) * (items-3));
3427 for (i=0; i < items-3; ++i) {
3428 if (sv_isobject(ST(i+3))
3429 && sv_derived_from(ST(i+3), "Imager::Color")) {
3430 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3431 work[i] = *INT2PTR(i_color *, tmp);
3435 croak("i_plin: pixels must be Imager::Color objects");
3439 RETVAL = i_plin(im, l, l+items-3, y, work);
3449 i_ppixf(im, x, y, cl)
3453 Imager::Color::Float cl
3456 i_gsampf(im, l, r, y, ...)
3468 croak("No channel numbers supplied to g_sampf()");
3470 chan_count = items - 4;
3471 chans = mymalloc(sizeof(int) * chan_count);
3472 for (i = 0; i < chan_count; ++i)
3473 chans[i] = SvIV(ST(i+4));
3474 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3475 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3476 if (GIMME_V == G_ARRAY) {
3478 for (i = 0; i < count; ++i)
3479 PUSHs(sv_2mortal(newSVnv(data[i])));
3483 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3487 if (GIMME_V != G_ARRAY) {
3489 PUSHs(&PL_sv_undef);
3494 i_plinf(im, l, y, ...)
3503 work = mymalloc(sizeof(i_fcolor) * (items-3));
3504 for (i=0; i < items-3; ++i) {
3505 if (sv_isobject(ST(i+3))
3506 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3507 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3508 work[i] = *INT2PTR(i_fcolor *, tmp);
3512 croak("i_plin: pixels must be Imager::Color::Float objects");
3516 RETVAL = i_plinf(im, l, l+items-3, y, work);
3533 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3534 if (i_gpixf(im, x, y, color) == 0) {
3535 ST(0) = sv_newmortal();
3536 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3540 ST(0) = &PL_sv_undef;
3554 vals = mymalloc((r-l) * sizeof(i_color));
3555 count = i_glin(im, l, r, y, vals);
3557 for (i = 0; i < count; ++i) {
3559 i_color *col = mymalloc(sizeof(i_color));
3560 sv = sv_newmortal();
3561 sv_setref_pv(sv, "Imager::Color", (void *)col);
3568 i_glinf(im, l, r, y)
3578 vals = mymalloc((r-l) * sizeof(i_fcolor));
3579 count = i_glinf(im, l, r, y, vals);
3581 for (i = 0; i < count; ++i) {
3583 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3585 sv = sv_newmortal();
3586 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3593 i_img_16_new(x, y, ch)
3599 i_img_double_new(x, y, ch)
3605 i_tags_addn(im, name, code, idata)
3614 name = SvPV(ST(1), len);
3617 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3622 i_tags_add(im, name, code, data, idata)
3632 name = SvPV(ST(1), len);
3636 data = SvPV(ST(3), len);
3641 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3646 i_tags_find(im, name, start)
3653 if (i_tags_find(&im->tags, name, start, &entry)) {
3655 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3657 ST(0) = sv_2mortal(newSViv(entry));
3659 ST(0) = &PL_sv_undef;
3663 i_tags_findn(im, code, start)
3670 if (i_tags_findn(&im->tags, code, start, &entry)) {
3672 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3674 ST(0) = sv_2mortal(newSViv(entry));
3677 ST(0) = &PL_sv_undef;
3680 i_tags_delete(im, entry)
3684 RETVAL = i_tags_delete(&im->tags, entry);
3689 i_tags_delbyname(im, name)
3693 RETVAL = i_tags_delbyname(&im->tags, name);
3698 i_tags_delbycode(im, code)
3702 RETVAL = i_tags_delbycode(&im->tags, code);
3707 i_tags_get(im, index)
3711 if (index >= 0 && index < im->tags.count) {
3712 i_img_tag *entry = im->tags.tags + index;
3716 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3719 PUSHs(sv_2mortal(newSViv(entry->code)));
3722 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3725 PUSHs(sv_2mortal(newSViv(entry->idata)));
3733 RETVAL = im->tags.count;
3740 i_wf_bbox(face, size, text)
3747 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
3749 PUSHs(sv_2mortal(newSViv(cords[0])));
3750 PUSHs(sv_2mortal(newSViv(cords[1])));
3751 PUSHs(sv_2mortal(newSViv(cords[2])));
3752 PUSHs(sv_2mortal(newSViv(cords[3])));
3753 PUSHs(sv_2mortal(newSViv(cords[4])));
3754 PUSHs(sv_2mortal(newSViv(cords[5])));
3758 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3769 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3775 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3786 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3796 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3798 #define FT2_DESTROY(font) i_ft2_destroy(font)
3802 Imager::Font::FT2 font
3804 MODULE = Imager PACKAGE = Imager::Font::FreeType2
3807 i_ft2_new(name, index)
3812 i_ft2_setdpi(font, xdpi, ydpi)
3813 Imager::Font::FT2 font
3819 Imager::Font::FT2 font
3823 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3825 PUSHs(sv_2mortal(newSViv(xdpi)));
3826 PUSHs(sv_2mortal(newSViv(ydpi)));
3830 i_ft2_sethinting(font, hinting)
3831 Imager::Font::FT2 font
3835 i_ft2_settransform(font, matrix)
3836 Imager::Font::FT2 font
3844 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3845 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3846 av=(AV*)SvRV(ST(1));
3850 for (i = 0; i < len; ++i) {
3851 sv1=(*(av_fetch(av,i,0)));
3852 matrix[i] = SvNV(sv1);
3856 RETVAL = i_ft2_settransform(font, matrix);
3861 i_ft2_bbox(font, cheight, cwidth, text, utf8)
3862 Imager::Font::FT2 font
3875 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox, utf8)) {
3877 for (i = 0; i < 6; ++i)
3878 PUSHs(sv_2mortal(newSViv(bbox[i])));
3882 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
3883 Imager::Font::FT2 font
3897 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
3900 for (i = 0; i < 8; ++i)
3901 PUSHs(sv_2mortal(newSViv(bbox[i])));
3905 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
3906 Imager::Font::FT2 font
3922 if (SvUTF8(ST(7))) {
3926 text = SvPV(ST(7), len);
3927 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
3928 len, align, aa, vlayout, utf8);
3933 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
3934 Imager::Font::FT2 font
3951 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
3952 strlen(text), align, aa, vlayout, 1);
3957 ft2_transform_box(font, x0, x1, x2, x3)
3958 Imager::Font::FT2 font
3966 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
3967 ft2_transform_box(font, box);
3969 PUSHs(sv_2mortal(newSViv(box[0])));
3970 PUSHs(sv_2mortal(newSViv(box[1])));
3971 PUSHs(sv_2mortal(newSViv(box[2])));
3972 PUSHs(sv_2mortal(newSViv(box[3])));
3975 i_ft2_has_chars(handle, text, utf8)
3976 Imager::Font::FT2 handle
3989 text = SvPV(ST(1), len);
3990 work = mymalloc(len);
3991 count = i_ft2_has_chars(handle, text, len, utf8, work);
3992 if (GIMME_V == G_ARRAY) {
3994 for (i = 0; i < count; ++i) {
3995 PUSHs(sv_2mortal(newSViv(work[i])));
4000 PUSHs(sv_2mortal(newSVpv(work, count)));
4006 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4010 Imager::FillHandle fill
4012 MODULE = Imager PACKAGE = Imager
4015 i_new_fill_solid(cl, combine)
4020 i_new_fill_solidf(cl, combine)
4021 Imager::Color::Float cl
4025 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4033 unsigned char *cust_hatch;
4037 cust_hatch = SvPV(ST(4), len);
4041 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4046 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4047 Imager::Color::Float fg
4048 Imager::Color::Float bg
4054 unsigned char *cust_hatch;
4058 cust_hatch = SvPV(ST(4), len);
4062 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4067 i_new_fill_image(src, matrix, xoff, yoff, combine)
4084 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4085 croak("i_new_fill_image: parameter must be an arrayref");
4086 av=(AV*)SvRV(ST(1));
4090 for (i = 0; i < len; ++i) {
4091 sv1=(*(av_fetch(av,i,0)));
4092 matrix[i] = SvNV(sv1);
4098 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);