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,src_minx,src_miny,src_maxx,src_maxy)
1493 i_flipxy(im, direction)
1498 i_rotate90(im, degrees)
1503 i_rotate_exact(im, amount)
1508 i_matrix_transform(im, xsize, ysize, matrix)
1519 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1520 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1521 av=(AV*)SvRV(ST(3));
1525 for (i = 0; i < len; ++i) {
1526 sv1=(*(av_fetch(av,i,0)));
1527 matrix[i] = SvNV(sv1);
1531 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1536 i_gaussian(im,stdev)
1541 i_unsharp_mask(im,stdev,scale)
1556 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1557 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1558 av=(AV*)SvRV(ST(1));
1560 coeff=mymalloc( len*sizeof(float) );
1561 for(i=0;i<len;i++) {
1562 sv1=(*(av_fetch(av,i,0)));
1563 coeff[i]=(float)SvNV(sv1);
1565 i_conv(im,coeff,len);
1569 i_convert(im, src, coeff)
1583 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1584 croak("i_convert: parameter 3 must be an arrayref\n");
1585 avmain = (AV*)SvRV(ST(2));
1586 outchan = av_len(avmain)+1;
1587 /* find the biggest */
1589 for (j=0; j < outchan; ++j) {
1590 temp = av_fetch(avmain, j, 0);
1591 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1592 avsub = (AV*)SvRV(*temp);
1593 len = av_len(avsub)+1;
1598 coeff = mymalloc(sizeof(float) * outchan * inchan);
1599 for (j = 0; j < outchan; ++j) {
1600 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1601 len = av_len(avsub)+1;
1602 for (i = 0; i < len; ++i) {
1603 temp = av_fetch(avsub, i, 0);
1605 coeff[i+j*inchan] = SvNV(*temp);
1607 coeff[i+j*inchan] = 0;
1610 coeff[i++ + j*inchan] = 0;
1612 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1622 unsigned int mask = 0;
1628 unsigned char (*maps)[256];
1630 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1631 croak("i_map: parameter 2 must be an arrayref\n");
1632 avmain = (AV*)SvRV(ST(1));
1633 len = av_len(avmain)+1;
1634 if (im->channels < len) len = im->channels;
1636 maps = mymalloc( len * sizeof(unsigned char [256]) );
1638 for (j=0; j<len ; j++) {
1639 temp = av_fetch(avmain, j, 0);
1640 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1641 avsub = (AV*)SvRV(*temp);
1642 if(av_len(avsub) != 255) continue;
1644 for (i=0; i<256 ; i++) {
1646 temp = av_fetch(avsub, i, 0);
1647 val = temp ? SvIV(*temp) : 0;
1649 if (val>255) val = 255;
1654 i_map(im, maps, mask);
1667 i_init_fonts(t1log=0)
1682 i_t1_destroy(font_id)
1687 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1706 str = SvPV(str_sv, len);
1707 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1714 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1723 int cords[BOUNDING_BOX_COUNT];
1731 str = SvPV(str_sv, len);
1732 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1735 for (i = 0; i < rc; ++i)
1736 PUSHs(sv_2mortal(newSViv(cords[i])));
1742 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1761 str = SvPV(str_sv, len);
1762 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1768 i_t1_has_chars(handle, text_sv, utf8 = 0)
1780 if (SvUTF8(text_sv))
1783 text = SvPV(text_sv, len);
1784 work = mymalloc(len);
1785 count = i_t1_has_chars(handle, text, len, utf8, work);
1786 if (GIMME_V == G_ARRAY) {
1788 for (i = 0; i < count; ++i) {
1789 PUSHs(sv_2mortal(newSViv(work[i])));
1794 PUSHs(sv_2mortal(newSVpv(work, count)));
1799 i_t1_face_name(handle)
1805 len = i_t1_face_name(handle, name, sizeof(name));
1808 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1812 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1824 if (SvUTF8(text_sv))
1827 text = SvPV(text_sv, work_len);
1832 ch = i_utf8_advance(&text, &len);
1834 i_push_error(0, "invalid UTF8 character");
1843 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1844 PUSHs(sv_2mortal(newSVpv(name, 0)));
1847 PUSHs(&PL_sv_undef);
1861 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1863 #define TT_DESTROY(handle) i_tt_destroy(handle)
1867 Imager::Font::TT handle
1870 MODULE = Imager PACKAGE = Imager
1874 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
1875 Imager::Font::TT handle
1893 str = SvPV(str_sv, len);
1894 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1901 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
1902 Imager::Font::TT handle
1920 str = SvPV(str_sv, len);
1921 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1928 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1929 Imager::Font::TT handle
1935 int cords[BOUNDING_BOX_COUNT],rc;
1944 str = SvPV(str_sv, len);
1945 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1947 for (i = 0; i < rc; ++i) {
1948 PUSHs(sv_2mortal(newSViv(cords[i])));
1953 i_tt_has_chars(handle, text_sv, utf8)
1954 Imager::Font::TT handle
1965 if (SvUTF8(text_sv))
1968 text = SvPV(text_sv, len);
1969 work = mymalloc(len);
1970 count = i_tt_has_chars(handle, text, len, utf8, work);
1971 if (GIMME_V == G_ARRAY) {
1973 for (i = 0; i < count; ++i) {
1974 PUSHs(sv_2mortal(newSViv(work[i])));
1979 PUSHs(sv_2mortal(newSVpv(work, count)));
1984 i_tt_dump_names(handle)
1985 Imager::Font::TT handle
1988 i_tt_face_name(handle)
1989 Imager::Font::TT handle
1994 len = i_tt_face_name(handle, name, sizeof(name));
1997 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2001 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2002 Imager::Font::TT handle
2013 if (SvUTF8(text_sv))
2016 text = SvPV(text_sv, work_len);
2021 ch = i_utf8_advance(&text, &len);
2023 i_push_error(0, "invalid UTF8 character");
2032 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2033 PUSHs(sv_2mortal(newSVpv(name, 0)));
2036 PUSHs(&PL_sv_undef);
2045 i_writejpeg_wiol(im, ig, qfactor)
2061 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2062 if (iptc_itext == NULL) {
2065 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2070 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2072 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2081 i_test_format_probe(ig, length)
2090 i_readtiff_wiol(ig, length)
2095 i_readtiff_multi_wiol(ig, length)
2103 imgs = i_readtiff_multi_wiol(ig, length, &count);
2106 for (i = 0; i < count; ++i) {
2107 SV *sv = sv_newmortal();
2108 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2116 i_writetiff_wiol(im, ig)
2121 i_writetiff_multi_wiol(ig, ...)
2129 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2130 img_count = items - 1;
2132 if (img_count < 1) {
2135 i_push_error(0, "You need to specify images to save");
2138 imgs = mymalloc(sizeof(i_img *) * img_count);
2139 for (i = 0; i < img_count; ++i) {
2142 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2143 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2147 i_push_error(0, "Only images can be saved");
2154 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2162 i_writetiff_wiol_faxable(im, ig, fine)
2168 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2177 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2178 img_count = items - 2;
2180 if (img_count < 1) {
2183 i_push_error(0, "You need to specify images to save");
2186 imgs = mymalloc(sizeof(i_img *) * img_count);
2187 for (i = 0; i < img_count; ++i) {
2190 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2191 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2195 i_push_error(0, "Only images can be saved");
2202 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2210 #endif /* HAVE_LIBTIFF */
2216 i_readpng_wiol(ig, length)
2222 i_writepng_wiol(im, ig)
2235 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2238 i_writegif(im,fd,colors,pixdev,fixed)
2245 Imager__Color fixed;
2252 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2253 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2254 av=(AV*)SvRV(ST(4));
2255 fixedlen=av_len(av)+1;
2256 fixed=mymalloc( fixedlen*sizeof(i_color) );
2257 for(i=0;i<fixedlen;i++) {
2258 sv1=(*(av_fetch(av,i,0)));
2259 if (sv_derived_from(sv1, "Imager::Color")) {
2260 Itmp = SvIV((SV*)SvRV(sv1));
2261 tmp = (i_color*) Itmp;
2262 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2265 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2267 ST(0) = sv_newmortal();
2268 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2269 else sv_setiv(ST(0), (IV)RETVAL);
2275 i_writegifmc(im,fd,colors)
2282 i_writegif_gen(fd, ...)
2287 i_img **imgs = NULL;
2293 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2294 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2295 croak("i_writegif_gen: Second argument must be a hash ref");
2296 hv = (HV *)SvRV(ST(1));
2297 memset(&quant, 0, sizeof(quant));
2298 quant.mc_size = 256;
2299 handle_quant_opts(&quant, hv);
2300 img_count = items - 2;
2302 if (img_count < 1) {
2305 i_push_error(0, "You need to specify images to save");
2308 imgs = mymalloc(sizeof(i_img *) * img_count);
2309 for (i = 0; i < img_count; ++i) {
2312 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2313 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2317 i_push_error(0, "Only images can be saved");
2323 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2327 copy_colors_back(hv, &quant);
2330 ST(0) = sv_newmortal();
2331 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2332 else sv_setiv(ST(0), (IV)RETVAL);
2333 cleanup_quant_opts(&quant);
2337 i_writegif_callback(cb, maxbuffer,...)
2341 i_img **imgs = NULL;
2348 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2349 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2350 croak("i_writegif_callback: Second argument must be a hash ref");
2351 hv = (HV *)SvRV(ST(2));
2352 memset(&quant, 0, sizeof(quant));
2353 quant.mc_size = 256;
2354 handle_quant_opts(&quant, hv);
2355 img_count = items - 3;
2357 if (img_count < 1) {
2361 imgs = mymalloc(sizeof(i_img *) * img_count);
2362 for (i = 0; i < img_count; ++i) {
2365 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2366 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2375 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2379 copy_colors_back(hv, &quant);
2382 ST(0) = sv_newmortal();
2383 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2384 else sv_setiv(ST(0), (IV)RETVAL);
2385 cleanup_quant_opts(&quant);
2388 i_writegif_wiol(ig, opts,...)
2392 i_img **imgs = NULL;
2398 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2399 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2400 croak("i_writegif_callback: Second argument must be a hash ref");
2401 hv = (HV *)SvRV(ST(1));
2402 memset(&quant, 0, sizeof(quant));
2403 quant.mc_size = 256;
2404 handle_quant_opts(&quant, hv);
2405 img_count = items - 2;
2407 if (img_count < 1) {
2411 imgs = mymalloc(sizeof(i_img *) * img_count);
2412 for (i = 0; i < img_count; ++i) {
2415 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2416 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2424 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2428 copy_colors_back(hv, &quant);
2431 ST(0) = sv_newmortal();
2432 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2433 else sv_setiv(ST(0), (IV)RETVAL);
2434 cleanup_quant_opts(&quant);
2447 colour_table = NULL;
2450 if(GIMME_V == G_ARRAY) {
2451 rimg = i_readgif(fd,&colour_table,&colours);
2453 /* don't waste time with colours if they aren't wanted */
2454 rimg = i_readgif(fd,NULL,NULL);
2457 if (colour_table == NULL) {
2460 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2463 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2464 /* I don't know if I have the reference counts right or not :( */
2465 /* Neither do I :-) */
2466 /* No Idea here either */
2469 av_extend(ct, colours);
2470 for(q=0; q<colours; q++) {
2472 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2473 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2475 myfree(colour_table);
2479 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2481 PUSHs(newRV_noinc((SV*)ct));
2495 colour_table = NULL;
2498 if(GIMME_V == G_ARRAY) {
2499 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2501 /* don't waste time with colours if they aren't wanted */
2502 rimg = i_readgif_wiol(ig,NULL,NULL);
2505 if (colour_table == NULL) {
2508 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2511 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2512 /* I don't know if I have the reference counts right or not :( */
2513 /* Neither do I :-) */
2514 /* No Idea here either */
2517 av_extend(ct, colours);
2518 for(q=0; q<colours; q++) {
2520 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2521 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2523 myfree(colour_table);
2527 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2529 PUSHs(newRV_noinc((SV*)ct));
2533 i_readgif_scalar(...)
2545 data = (char *)SvPV(ST(0), length);
2549 if(GIMME_V == G_ARRAY) {
2550 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2552 /* don't waste time with colours if they aren't wanted */
2553 rimg=i_readgif_scalar(data,length,NULL,NULL);
2556 if (colour_table == NULL) {
2559 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2562 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2563 /* I don't know if I have the reference counts right or not :( */
2564 /* Neither do I :-) */
2566 av_extend(ct, colours);
2567 for(q=0; q<colours; q++) {
2569 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2570 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2572 myfree(colour_table);
2576 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2578 PUSHs(newRV_noinc((SV*)ct));
2582 i_readgif_callback(...)
2599 if(GIMME_V == G_ARRAY) {
2600 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2602 /* don't waste time with colours if they aren't wanted */
2603 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2606 if (colour_table == NULL) {
2609 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2612 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2613 /* I don't know if I have the reference counts right or not :( */
2614 /* Neither do I :-) */
2615 /* Neither do I - maybe I'll move this somewhere */
2617 av_extend(ct, colours);
2618 for(q=0; q<colours; q++) {
2620 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2621 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2623 myfree(colour_table);
2627 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2629 PUSHs(newRV_noinc((SV*)ct));
2640 imgs = i_readgif_multi(fd, &count);
2643 for (i = 0; i < count; ++i) {
2644 SV *sv = sv_newmortal();
2645 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2652 i_readgif_multi_scalar(data)
2660 data = (char *)SvPV(ST(0), length);
2661 imgs = i_readgif_multi_scalar(data, length, &count);
2664 for (i = 0; i < count; ++i) {
2665 SV *sv = sv_newmortal();
2666 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2673 i_readgif_multi_callback(cb)
2681 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2684 for (i = 0; i < count; ++i) {
2685 SV *sv = sv_newmortal();
2686 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2693 i_readgif_multi_wiol(ig)
2700 imgs = i_readgif_multi_wiol(ig, &count);
2703 for (i = 0; i < count; ++i) {
2704 SV *sv = sv_newmortal();
2705 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2717 i_readpnm_wiol(ig, length)
2723 i_writeppm_wiol(im, ig)
2729 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2738 i_writeraw_wiol(im,ig)
2743 i_writebmp_wiol(im,ig)
2753 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2764 idlen = SvCUR(ST(4));
2765 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2771 i_readtga_wiol(ig, length)
2777 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2788 idlen = SvCUR(ST(4));
2789 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2795 i_readrgb_wiol(ig, length)
2802 i_scaleaxis(im,Value,Axis)
2808 i_scale_nn(im,scx,scy)
2818 i_count_colors(im,maxc)
2824 i_transform(im,opx,opy,parm)
2837 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2838 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2839 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2840 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2841 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2842 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2843 av=(AV*)SvRV(ST(1));
2845 opx=mymalloc( opxl*sizeof(int) );
2846 for(i=0;i<opxl;i++) {
2847 sv1=(*(av_fetch(av,i,0)));
2848 opx[i]=(int)SvIV(sv1);
2850 av=(AV*)SvRV(ST(2));
2852 opy=mymalloc( opyl*sizeof(int) );
2853 for(i=0;i<opyl;i++) {
2854 sv1=(*(av_fetch(av,i,0)));
2855 opy[i]=(int)SvIV(sv1);
2857 av=(AV*)SvRV(ST(3));
2858 parmlen=av_len(av)+1;
2859 parm=mymalloc( parmlen*sizeof(double) );
2860 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2861 sv1=(*(av_fetch(av,i,0)));
2862 parm[i]=(double)SvNV(sv1);
2864 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2868 ST(0) = sv_newmortal();
2869 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2870 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2873 i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
2892 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
2893 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
2894 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
2895 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2896 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2898 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2900 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2901 av = (AV*)SvRV(ST(5));
2902 in_imgs_count = av_len(av)+1;
2903 for (i = 0; i < in_imgs_count; ++i) {
2904 sv1 = *av_fetch(av, i, 0);
2905 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2906 croak("Parameter 5 must contain only images");
2913 if (in_imgs_count > 0) {
2914 av = (AV*)SvRV(ST(5));
2915 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2916 for (i = 0; i < in_imgs_count; ++i) {
2917 sv1 = *av_fetch(av,i,0);
2918 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2919 croak("Parameter 5 must contain only images");
2921 tmp = SvIV((SV*)SvRV(sv1));
2922 in_imgs[i] = INT2PTR(i_img*, tmp);
2926 /* no input images */
2929 /* default the output size from the first input if possible */
2931 width = SvIV(ST(0));
2932 else if (in_imgs_count)
2933 width = in_imgs[0]->xsize;
2935 croak("No output image width supplied");
2938 height = SvIV(ST(1));
2939 else if (in_imgs_count)
2940 height = in_imgs[0]->ysize;
2942 croak("No output image height supplied");
2944 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2945 if (ops_len % sizeof(struct rm_op))
2946 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2947 ops_count = ops_len / sizeof(struct rm_op);
2948 av = (AV*)SvRV(ST(3));
2949 n_regs_count = av_len(av)+1;
2950 n_regs = mymalloc(n_regs_count * sizeof(double));
2951 for (i = 0; i < n_regs_count; ++i) {
2952 sv1 = *av_fetch(av,i,0);
2954 n_regs[i] = SvNV(sv1);
2956 av = (AV*)SvRV(ST(4));
2957 c_regs_count = av_len(av)+1;
2958 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2959 /* I don't bother initializing the colou?r registers */
2961 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2962 n_regs, n_regs_count,
2963 c_regs, c_regs_count, in_imgs, in_imgs_count);
2968 ST(0) = sv_newmortal();
2969 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2970 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2974 i_contrast(im,intensity)
2983 i_noise(im,amount,type)
2989 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2999 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3018 i_postlevels(im,levels)
3028 i_watermark(im,wmark,tx,ty,pixdiff)
3030 Imager::ImgRaw wmark
3037 i_autolevels(im,lsat,usat,skew)
3044 i_radnoise(im,xo,yo,rscale,ascale)
3052 i_turbnoise(im, xo, yo, scale)
3075 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3076 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3077 croak("i_gradgen: Second argument must be an array ref");
3078 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3079 croak("i_gradgen: Third argument must be an array ref");
3080 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3081 croak("i_gradgen: Fourth argument must be an array ref");
3082 axx = (AV *)SvRV(ST(1));
3083 ayy = (AV *)SvRV(ST(2));
3084 ac = (AV *)SvRV(ST(3));
3085 dmeasure = (int)SvIV(ST(4));
3087 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3088 num = num <= av_len(ac) ? num : av_len(ac);
3090 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3091 xo = mymalloc( sizeof(int) * num );
3092 yo = mymalloc( sizeof(int) * num );
3093 ival = mymalloc( sizeof(i_color) * num );
3094 for(i = 0; i<num; i++) {
3095 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3096 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3097 sv = *av_fetch(ac, i, 0);
3098 if ( !sv_derived_from(sv, "Imager::Color") ) {
3099 free(axx); free(ayy); free(ac);
3100 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3102 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3104 i_gradgen(im, num, xo, yo, ival, dmeasure);
3110 i_diff_image(im, im2, mindist=0)
3116 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3126 double ssample_param
3130 i_fountain_seg *segs;
3132 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3133 croak("i_fountain: argument 11 must be an array ref");
3135 asegs = (AV *)SvRV(ST(10));
3136 segs = load_fount_segs(asegs, &count);
3137 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3138 ssample_param, count, segs);
3142 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3151 double ssample_param
3155 i_fountain_seg *segs;
3157 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3158 croak("i_fountain: argument 11 must be an array ref");
3160 asegs = (AV *)SvRV(ST(9));
3161 segs = load_fount_segs(asegs, &count);
3162 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3163 super_sample, ssample_param, count, segs);
3177 errors = i_errors();
3179 while (errors[i].msg) {
3181 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3182 if (!av_store(av, 0, sv)) {
3185 sv = newSViv(errors[i].code);
3186 if (!av_store(av, 1, sv)) {
3189 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3194 i_nearest_color(im, ...)
3209 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3210 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3211 croak("i_nearest_color: Second argument must be an array ref");
3212 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3213 croak("i_nearest_color: Third argument must be an array ref");
3214 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3215 croak("i_nearest_color: Fourth argument must be an array ref");
3216 axx = (AV *)SvRV(ST(1));
3217 ayy = (AV *)SvRV(ST(2));
3218 ac = (AV *)SvRV(ST(3));
3219 dmeasure = (int)SvIV(ST(4));
3221 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3222 num = num <= av_len(ac) ? num : av_len(ac);
3224 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3225 xo = mymalloc( sizeof(int) * num );
3226 yo = mymalloc( sizeof(int) * num );
3227 ival = mymalloc( sizeof(i_color) * num );
3228 for(i = 0; i<num; i++) {
3229 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3230 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3231 sv = *av_fetch(ac, i, 0);
3232 if ( !sv_derived_from(sv, "Imager::Color") ) {
3233 free(axx); free(ayy); free(ac);
3234 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3236 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3238 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3252 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3253 hv=(HV*)SvRV(ST(0));
3254 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3255 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3256 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3265 rc=DSO_open(filename,&evstr);
3269 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3270 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3273 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3279 DSO_close(dso_handle)
3283 DSO_funclist(dso_handle_v)
3287 DSO_handle *dso_handle;
3289 dso_handle=(DSO_handle*)dso_handle_v;
3291 while( dso_handle->function_list[i].name != NULL) {
3293 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3295 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3300 DSO_call(handle,func_index,hv)
3306 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3307 hv=(HV*)SvRV(ST(2));
3308 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3309 DSO_call( (DSO_handle *)handle,func_index,hv);
3313 # this is mostly for testing...
3315 i_get_pixel(im, x, y)
3322 color = (i_color *)mymalloc(sizeof(i_color));
3323 if (i_gpix(im, x, y, color) == 0) {
3324 ST(0) = sv_newmortal();
3325 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3329 ST(0) = &PL_sv_undef;
3334 i_ppix(im, x, y, cl)
3341 i_img_pal_new(x, y, channels, maxpal)
3348 i_img_to_pal(src, quant)
3354 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3355 croak("i_img_to_pal: second argument must be a hash ref");
3356 hv = (HV *)SvRV(ST(1));
3357 memset(&quant, 0, sizeof(quant));
3358 quant.mc_size = 256;
3359 handle_quant_opts(&quant, hv);
3360 RETVAL = i_img_to_pal(src, &quant);
3362 copy_colors_back(hv, &quant);
3364 cleanup_quant_opts(&quant);
3383 work = mymalloc((r-l) * sizeof(i_palidx));
3384 count = i_gpal(im, l, r, y, work);
3385 if (GIMME_V == G_ARRAY) {
3387 for (i = 0; i < count; ++i) {
3388 PUSHs(sv_2mortal(newSViv(work[i])));
3393 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3398 if (GIMME_V != G_ARRAY) {
3400 PUSHs(&PL_sv_undef);
3405 i_ppal(im, l, y, ...)
3414 work = mymalloc(sizeof(i_palidx) * (items-3));
3415 for (i=0; i < items-3; ++i) {
3416 work[i] = SvIV(ST(i+3));
3418 RETVAL = i_ppal(im, l, l+items-3, y, work);
3428 i_addcolors(im, ...)
3436 croak("i_addcolors: no colors to add");
3437 colors = mymalloc((items-1) * sizeof(i_color));
3438 for (i=0; i < items-1; ++i) {
3439 if (sv_isobject(ST(i+1))
3440 && sv_derived_from(ST(i+1), "Imager::Color")) {
3441 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3442 colors[i] = *INT2PTR(i_color *, tmp);
3446 croak("i_plin: pixels must be Imager::Color objects");
3449 index = i_addcolors(im, colors, items-1);
3452 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3454 else if (index == -1) {
3455 ST(0) = &PL_sv_undef;
3458 ST(0) = sv_2mortal(newSViv(index));
3462 i_setcolors(im, index, ...)
3470 croak("i_setcolors: no colors to add");
3471 colors = mymalloc((items-2) * sizeof(i_color));
3472 for (i=0; i < items-2; ++i) {
3473 if (sv_isobject(ST(i+2))
3474 && sv_derived_from(ST(i+2), "Imager::Color")) {
3475 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3476 colors[i] = *INT2PTR(i_color *, tmp);
3480 croak("i_setcolors: pixels must be Imager::Color objects");
3483 RETVAL = i_setcolors(im, index, colors, items-2);
3487 i_getcolors(im, index, ...)
3496 croak("i_getcolors: too many arguments");
3498 count = SvIV(ST(2));
3500 croak("i_getcolors: count must be positive");
3501 colors = mymalloc(sizeof(i_color) * count);
3502 if (i_getcolors(im, index, colors, count)) {
3503 for (i = 0; i < count; ++i) {
3505 SV *sv = sv_newmortal();
3506 pv = mymalloc(sizeof(i_color));
3508 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3521 count = i_colorcount(im);
3523 ST(0) = sv_2mortal(newSViv(count));
3526 ST(0) = &PL_sv_undef;
3535 count = i_maxcolors(im);
3537 ST(0) = sv_2mortal(newSViv(count));
3540 ST(0) = &PL_sv_undef;
3544 i_findcolor(im, color)
3550 if (i_findcolor(im, color, &index)) {
3551 ST(0) = sv_2mortal(newSViv(index));
3554 ST(0) = &PL_sv_undef;
3570 i_gsamp(im, l, r, y, ...)
3582 croak("No channel numbers supplied to g_samp()");
3584 chan_count = items - 4;
3585 chans = mymalloc(sizeof(int) * chan_count);
3586 for (i = 0; i < chan_count; ++i)
3587 chans[i] = SvIV(ST(i+4));
3588 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3589 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3591 if (GIMME_V == G_ARRAY) {
3593 for (i = 0; i < count; ++i)
3594 PUSHs(sv_2mortal(newSViv(data[i])));
3598 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3603 if (GIMME_V != G_ARRAY) {
3605 PUSHs(&PL_sv_undef);
3611 i_img_masked_new(targ, mask, x, y, w, h)
3621 if (!sv_isobject(ST(1))
3622 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3623 croak("i_img_masked_new: parameter 2 must undef or an image");
3625 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3629 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3634 i_plin(im, l, y, ...)
3643 work = mymalloc(sizeof(i_color) * (items-3));
3644 for (i=0; i < items-3; ++i) {
3645 if (sv_isobject(ST(i+3))
3646 && sv_derived_from(ST(i+3), "Imager::Color")) {
3647 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3648 work[i] = *INT2PTR(i_color *, tmp);
3652 croak("i_plin: pixels must be Imager::Color objects");
3656 RETVAL = i_plin(im, l, l+items-3, y, work);
3666 i_ppixf(im, x, y, cl)
3670 Imager::Color::Float cl
3673 i_gsampf(im, l, r, y, ...)
3685 croak("No channel numbers supplied to g_sampf()");
3687 chan_count = items - 4;
3688 chans = mymalloc(sizeof(int) * chan_count);
3689 for (i = 0; i < chan_count; ++i)
3690 chans[i] = SvIV(ST(i+4));
3691 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3692 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3693 if (GIMME_V == G_ARRAY) {
3695 for (i = 0; i < count; ++i)
3696 PUSHs(sv_2mortal(newSVnv(data[i])));
3700 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3704 if (GIMME_V != G_ARRAY) {
3706 PUSHs(&PL_sv_undef);
3711 i_plinf(im, l, y, ...)
3720 work = mymalloc(sizeof(i_fcolor) * (items-3));
3721 for (i=0; i < items-3; ++i) {
3722 if (sv_isobject(ST(i+3))
3723 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3724 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3725 work[i] = *INT2PTR(i_fcolor *, tmp);
3729 croak("i_plin: pixels must be Imager::Color::Float objects");
3733 RETVAL = i_plinf(im, l, l+items-3, y, work);
3750 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3751 if (i_gpixf(im, x, y, color) == 0) {
3752 ST(0) = sv_newmortal();
3753 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3757 ST(0) = &PL_sv_undef;
3771 vals = mymalloc((r-l) * sizeof(i_color));
3772 count = i_glin(im, l, r, y, vals);
3774 for (i = 0; i < count; ++i) {
3776 i_color *col = mymalloc(sizeof(i_color));
3777 sv = sv_newmortal();
3778 sv_setref_pv(sv, "Imager::Color", (void *)col);
3785 i_glinf(im, l, r, y)
3795 vals = mymalloc((r-l) * sizeof(i_fcolor));
3796 count = i_glinf(im, l, r, y, vals);
3798 for (i = 0; i < count; ++i) {
3800 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3802 sv = sv_newmortal();
3803 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3810 i_img_16_new(x, y, ch)
3816 i_img_double_new(x, y, ch)
3822 i_tags_addn(im, name, code, idata)
3831 name = SvPV(ST(1), len);
3834 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3839 i_tags_add(im, name, code, data, idata)
3849 name = SvPV(ST(1), len);
3853 data = SvPV(ST(3), len);
3858 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3863 i_tags_find(im, name, start)
3870 if (i_tags_find(&im->tags, name, start, &entry)) {
3872 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3874 ST(0) = sv_2mortal(newSViv(entry));
3876 ST(0) = &PL_sv_undef;
3880 i_tags_findn(im, code, start)
3887 if (i_tags_findn(&im->tags, code, start, &entry)) {
3889 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3891 ST(0) = sv_2mortal(newSViv(entry));
3894 ST(0) = &PL_sv_undef;
3897 i_tags_delete(im, entry)
3901 RETVAL = i_tags_delete(&im->tags, entry);
3906 i_tags_delbyname(im, name)
3910 RETVAL = i_tags_delbyname(&im->tags, name);
3915 i_tags_delbycode(im, code)
3919 RETVAL = i_tags_delbycode(&im->tags, code);
3924 i_tags_get(im, index)
3928 if (index >= 0 && index < im->tags.count) {
3929 i_img_tag *entry = im->tags.tags + index;
3933 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3936 PUSHs(sv_2mortal(newSViv(entry->code)));
3939 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3942 PUSHs(sv_2mortal(newSViv(entry->idata)));
3950 RETVAL = im->tags.count;
3957 i_wf_bbox(face, size, text)
3963 int cords[BOUNDING_BOX_COUNT];
3965 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3967 for (i = 0; i < rc; ++i)
3968 PUSHs(sv_2mortal(newSViv(cords[i])));
3972 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3983 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3989 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4000 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4010 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4012 #define FT2_DESTROY(font) i_ft2_destroy(font)
4016 Imager::Font::FT2 font
4018 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4021 i_ft2_new(name, index)
4026 i_ft2_setdpi(font, xdpi, ydpi)
4027 Imager::Font::FT2 font
4033 Imager::Font::FT2 font
4037 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4039 PUSHs(sv_2mortal(newSViv(xdpi)));
4040 PUSHs(sv_2mortal(newSViv(ydpi)));
4044 i_ft2_sethinting(font, hinting)
4045 Imager::Font::FT2 font
4049 i_ft2_settransform(font, matrix)
4050 Imager::Font::FT2 font
4058 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4059 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4060 av=(AV*)SvRV(ST(1));
4064 for (i = 0; i < len; ++i) {
4065 sv1=(*(av_fetch(av,i,0)));
4066 matrix[i] = SvNV(sv1);
4070 RETVAL = i_ft2_settransform(font, matrix);
4075 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4076 Imager::Font::FT2 font
4082 int bbox[BOUNDING_BOX_COUNT];
4088 text = SvPV(text_sv, text_len);
4090 if (SvUTF8(text_sv))
4093 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4096 for (i = 0; i < rc; ++i)
4097 PUSHs(sv_2mortal(newSViv(bbox[i])));
4101 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4102 Imager::Font::FT2 font
4116 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4119 for (i = 0; i < 8; ++i)
4120 PUSHs(sv_2mortal(newSViv(bbox[i])));
4124 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4125 Imager::Font::FT2 font
4141 if (SvUTF8(ST(7))) {
4145 text = SvPV(ST(7), len);
4146 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4147 len, align, aa, vlayout, utf8);
4152 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4153 Imager::Font::FT2 font
4170 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4171 strlen(text), align, aa, vlayout, 1);
4176 ft2_transform_box(font, x0, x1, x2, x3)
4177 Imager::Font::FT2 font
4185 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4186 ft2_transform_box(font, box);
4188 PUSHs(sv_2mortal(newSViv(box[0])));
4189 PUSHs(sv_2mortal(newSViv(box[1])));
4190 PUSHs(sv_2mortal(newSViv(box[2])));
4191 PUSHs(sv_2mortal(newSViv(box[3])));
4194 i_ft2_has_chars(handle, text_sv, utf8)
4195 Imager::Font::FT2 handle
4206 if (SvUTF8(text_sv))
4209 text = SvPV(text_sv, len);
4210 work = mymalloc(len);
4211 count = i_ft2_has_chars(handle, text, len, utf8, work);
4212 if (GIMME_V == G_ARRAY) {
4214 for (i = 0; i < count; ++i) {
4215 PUSHs(sv_2mortal(newSViv(work[i])));
4220 PUSHs(sv_2mortal(newSVpv(work, count)));
4225 i_ft2_face_name(handle)
4226 Imager::Font::FT2 handle
4231 len = i_ft2_face_name(handle, name, sizeof(name));
4234 PUSHs(sv_2mortal(newSVpv(name, 0)));
4238 i_ft2_glyph_name(handle, text_sv, utf8 = 0)
4239 Imager::Font::FT2 handle
4250 if (SvUTF8(text_sv))
4253 text = SvPV(text_sv, work_len);
4258 ch = i_utf8_advance(&text, &len);
4260 i_push_error(0, "invalid UTF8 character");
4269 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name))) {
4270 PUSHs(sv_2mortal(newSVpv(name, 0)));
4273 PUSHs(&PL_sv_undef);
4278 i_ft2_can_do_glyph_names()
4281 i_ft2_face_has_glyph_names(handle)
4282 Imager::Font::FT2 handle
4286 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4290 Imager::FillHandle fill
4292 MODULE = Imager PACKAGE = Imager
4295 i_new_fill_solid(cl, combine)
4300 i_new_fill_solidf(cl, combine)
4301 Imager::Color::Float cl
4305 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4313 unsigned char *cust_hatch;
4317 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4321 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4326 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4327 Imager::Color::Float fg
4328 Imager::Color::Float bg
4334 unsigned char *cust_hatch;
4338 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4342 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4347 i_new_fill_image(src, matrix, xoff, yoff, combine)
4364 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4365 croak("i_new_fill_image: parameter must be an arrayref");
4366 av=(AV*)SvRV(ST(1));
4370 for (i = 0; i < len; ++i) {
4371 sv1=(*(av_fetch(av,i,0)));
4372 matrix[i] = SvNV(sv1);
4378 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);