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(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2900 in_imgs_count = av_len(av_in_imgs)+1;
2901 for (i = 0; i < in_imgs_count; ++i) {
2902 sv1 = *av_fetch(av_in_imgs, i, 0);
2903 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2904 croak("sv_in_img must contain only images");
2907 if (in_imgs_count > 0) {
2908 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2909 for (i = 0; i < in_imgs_count; ++i) {
2910 sv1 = *av_fetch(av_in_imgs,i,0);
2911 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2912 croak("Parameter 5 must contain only images");
2914 tmp = SvIV((SV*)SvRV(sv1));
2915 in_imgs[i] = INT2PTR(i_img*, tmp);
2919 /* no input images */
2922 /* default the output size from the first input if possible */
2924 width = SvIV(sv_width);
2925 else if (in_imgs_count)
2926 width = in_imgs[0]->xsize;
2928 croak("No output image width supplied");
2930 if (SvOK(sv_height))
2931 height = SvIV(sv_height);
2932 else if (in_imgs_count)
2933 height = in_imgs[0]->ysize;
2935 croak("No output image height supplied");
2937 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2938 if (ops_len % sizeof(struct rm_op))
2939 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2940 ops_count = ops_len / sizeof(struct rm_op);
2942 n_regs_count = av_len(av_n_regs)+1;
2943 n_regs = mymalloc(n_regs_count * sizeof(double));
2944 for (i = 0; i < n_regs_count; ++i) {
2945 sv1 = *av_fetch(av_n_regs,i,0);
2947 n_regs[i] = SvNV(sv1);
2949 c_regs_count = av_len(av_c_regs)+1;
2950 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2951 /* I don't bother initializing the colou?r registers */
2953 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2954 n_regs, n_regs_count,
2955 c_regs, c_regs_count, in_imgs, in_imgs_count);
2960 ST(0) = sv_newmortal();
2961 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2962 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2966 i_contrast(im,intensity)
2975 i_noise(im,amount,type)
2981 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2991 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3010 i_postlevels(im,levels)
3020 i_watermark(im,wmark,tx,ty,pixdiff)
3022 Imager::ImgRaw wmark
3029 i_autolevels(im,lsat,usat,skew)
3036 i_radnoise(im,xo,yo,rscale,ascale)
3044 i_turbnoise(im, xo, yo, scale)
3067 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3068 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3069 croak("i_gradgen: Second argument must be an array ref");
3070 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3071 croak("i_gradgen: Third argument must be an array ref");
3072 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3073 croak("i_gradgen: Fourth argument must be an array ref");
3074 axx = (AV *)SvRV(ST(1));
3075 ayy = (AV *)SvRV(ST(2));
3076 ac = (AV *)SvRV(ST(3));
3077 dmeasure = (int)SvIV(ST(4));
3079 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3080 num = num <= av_len(ac) ? num : av_len(ac);
3082 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3083 xo = mymalloc( sizeof(int) * num );
3084 yo = mymalloc( sizeof(int) * num );
3085 ival = mymalloc( sizeof(i_color) * num );
3086 for(i = 0; i<num; i++) {
3087 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3088 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3089 sv = *av_fetch(ac, i, 0);
3090 if ( !sv_derived_from(sv, "Imager::Color") ) {
3091 free(axx); free(ayy); free(ac);
3092 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3094 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3096 i_gradgen(im, num, xo, yo, ival, dmeasure);
3102 i_diff_image(im, im2, mindist=0)
3108 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3118 double ssample_param
3122 i_fountain_seg *segs;
3124 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3125 croak("i_fountain: argument 11 must be an array ref");
3127 asegs = (AV *)SvRV(ST(10));
3128 segs = load_fount_segs(asegs, &count);
3129 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3130 ssample_param, count, segs);
3134 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3143 double ssample_param
3147 i_fountain_seg *segs;
3149 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3150 croak("i_fountain: argument 11 must be an array ref");
3152 asegs = (AV *)SvRV(ST(9));
3153 segs = load_fount_segs(asegs, &count);
3154 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3155 super_sample, ssample_param, count, segs);
3169 errors = i_errors();
3171 while (errors[i].msg) {
3173 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3174 if (!av_store(av, 0, sv)) {
3177 sv = newSViv(errors[i].code);
3178 if (!av_store(av, 1, sv)) {
3181 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3186 i_nearest_color(im, ...)
3201 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3202 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3203 croak("i_nearest_color: Second argument must be an array ref");
3204 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3205 croak("i_nearest_color: Third argument must be an array ref");
3206 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3207 croak("i_nearest_color: Fourth argument must be an array ref");
3208 axx = (AV *)SvRV(ST(1));
3209 ayy = (AV *)SvRV(ST(2));
3210 ac = (AV *)SvRV(ST(3));
3211 dmeasure = (int)SvIV(ST(4));
3213 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3214 num = num <= av_len(ac) ? num : av_len(ac);
3216 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3217 xo = mymalloc( sizeof(int) * num );
3218 yo = mymalloc( sizeof(int) * num );
3219 ival = mymalloc( sizeof(i_color) * num );
3220 for(i = 0; i<num; i++) {
3221 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3222 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3223 sv = *av_fetch(ac, i, 0);
3224 if ( !sv_derived_from(sv, "Imager::Color") ) {
3225 free(axx); free(ayy); free(ac);
3226 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3228 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3230 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3244 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3245 hv=(HV*)SvRV(ST(0));
3246 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3247 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3248 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3257 rc=DSO_open(filename,&evstr);
3261 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3262 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3265 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3271 DSO_close(dso_handle)
3275 DSO_funclist(dso_handle_v)
3279 DSO_handle *dso_handle;
3281 dso_handle=(DSO_handle*)dso_handle_v;
3283 while( dso_handle->function_list[i].name != NULL) {
3285 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3287 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3292 DSO_call(handle,func_index,hv)
3298 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3299 hv=(HV*)SvRV(ST(2));
3300 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3301 DSO_call( (DSO_handle *)handle,func_index,hv);
3305 # this is mostly for testing...
3307 i_get_pixel(im, x, y)
3314 color = (i_color *)mymalloc(sizeof(i_color));
3315 if (i_gpix(im, x, y, color) == 0) {
3316 ST(0) = sv_newmortal();
3317 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3321 ST(0) = &PL_sv_undef;
3326 i_ppix(im, x, y, cl)
3333 i_img_pal_new(x, y, channels, maxpal)
3340 i_img_to_pal(src, quant)
3346 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3347 croak("i_img_to_pal: second argument must be a hash ref");
3348 hv = (HV *)SvRV(ST(1));
3349 memset(&quant, 0, sizeof(quant));
3350 quant.mc_size = 256;
3351 handle_quant_opts(&quant, hv);
3352 RETVAL = i_img_to_pal(src, &quant);
3354 copy_colors_back(hv, &quant);
3356 cleanup_quant_opts(&quant);
3375 work = mymalloc((r-l) * sizeof(i_palidx));
3376 count = i_gpal(im, l, r, y, work);
3377 if (GIMME_V == G_ARRAY) {
3379 for (i = 0; i < count; ++i) {
3380 PUSHs(sv_2mortal(newSViv(work[i])));
3385 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3390 if (GIMME_V != G_ARRAY) {
3392 PUSHs(&PL_sv_undef);
3397 i_ppal(im, l, y, ...)
3406 work = mymalloc(sizeof(i_palidx) * (items-3));
3407 for (i=0; i < items-3; ++i) {
3408 work[i] = SvIV(ST(i+3));
3410 RETVAL = i_ppal(im, l, l+items-3, y, work);
3420 i_addcolors(im, ...)
3428 croak("i_addcolors: no colors to add");
3429 colors = mymalloc((items-1) * sizeof(i_color));
3430 for (i=0; i < items-1; ++i) {
3431 if (sv_isobject(ST(i+1))
3432 && sv_derived_from(ST(i+1), "Imager::Color")) {
3433 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3434 colors[i] = *INT2PTR(i_color *, tmp);
3438 croak("i_plin: pixels must be Imager::Color objects");
3441 index = i_addcolors(im, colors, items-1);
3444 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3446 else if (index == -1) {
3447 ST(0) = &PL_sv_undef;
3450 ST(0) = sv_2mortal(newSViv(index));
3454 i_setcolors(im, index, ...)
3462 croak("i_setcolors: no colors to add");
3463 colors = mymalloc((items-2) * sizeof(i_color));
3464 for (i=0; i < items-2; ++i) {
3465 if (sv_isobject(ST(i+2))
3466 && sv_derived_from(ST(i+2), "Imager::Color")) {
3467 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3468 colors[i] = *INT2PTR(i_color *, tmp);
3472 croak("i_setcolors: pixels must be Imager::Color objects");
3475 RETVAL = i_setcolors(im, index, colors, items-2);
3479 i_getcolors(im, index, ...)
3488 croak("i_getcolors: too many arguments");
3490 count = SvIV(ST(2));
3492 croak("i_getcolors: count must be positive");
3493 colors = mymalloc(sizeof(i_color) * count);
3494 if (i_getcolors(im, index, colors, count)) {
3495 for (i = 0; i < count; ++i) {
3497 SV *sv = sv_newmortal();
3498 pv = mymalloc(sizeof(i_color));
3500 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3513 count = i_colorcount(im);
3515 ST(0) = sv_2mortal(newSViv(count));
3518 ST(0) = &PL_sv_undef;
3527 count = i_maxcolors(im);
3529 ST(0) = sv_2mortal(newSViv(count));
3532 ST(0) = &PL_sv_undef;
3536 i_findcolor(im, color)
3542 if (i_findcolor(im, color, &index)) {
3543 ST(0) = sv_2mortal(newSViv(index));
3546 ST(0) = &PL_sv_undef;
3562 i_gsamp(im, l, r, y, ...)
3574 croak("No channel numbers supplied to g_samp()");
3576 chan_count = items - 4;
3577 chans = mymalloc(sizeof(int) * chan_count);
3578 for (i = 0; i < chan_count; ++i)
3579 chans[i] = SvIV(ST(i+4));
3580 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3581 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3583 if (GIMME_V == G_ARRAY) {
3585 for (i = 0; i < count; ++i)
3586 PUSHs(sv_2mortal(newSViv(data[i])));
3590 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3595 if (GIMME_V != G_ARRAY) {
3597 PUSHs(&PL_sv_undef);
3603 i_img_masked_new(targ, mask, x, y, w, h)
3613 if (!sv_isobject(ST(1))
3614 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3615 croak("i_img_masked_new: parameter 2 must undef or an image");
3617 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3621 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3626 i_plin(im, l, y, ...)
3635 work = mymalloc(sizeof(i_color) * (items-3));
3636 for (i=0; i < items-3; ++i) {
3637 if (sv_isobject(ST(i+3))
3638 && sv_derived_from(ST(i+3), "Imager::Color")) {
3639 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3640 work[i] = *INT2PTR(i_color *, tmp);
3644 croak("i_plin: pixels must be Imager::Color objects");
3648 RETVAL = i_plin(im, l, l+items-3, y, work);
3658 i_ppixf(im, x, y, cl)
3662 Imager::Color::Float cl
3665 i_gsampf(im, l, r, y, ...)
3677 croak("No channel numbers supplied to g_sampf()");
3679 chan_count = items - 4;
3680 chans = mymalloc(sizeof(int) * chan_count);
3681 for (i = 0; i < chan_count; ++i)
3682 chans[i] = SvIV(ST(i+4));
3683 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3684 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3685 if (GIMME_V == G_ARRAY) {
3687 for (i = 0; i < count; ++i)
3688 PUSHs(sv_2mortal(newSVnv(data[i])));
3692 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3696 if (GIMME_V != G_ARRAY) {
3698 PUSHs(&PL_sv_undef);
3703 i_plinf(im, l, y, ...)
3712 work = mymalloc(sizeof(i_fcolor) * (items-3));
3713 for (i=0; i < items-3; ++i) {
3714 if (sv_isobject(ST(i+3))
3715 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3716 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3717 work[i] = *INT2PTR(i_fcolor *, tmp);
3721 croak("i_plin: pixels must be Imager::Color::Float objects");
3725 RETVAL = i_plinf(im, l, l+items-3, y, work);
3742 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3743 if (i_gpixf(im, x, y, color) == 0) {
3744 ST(0) = sv_newmortal();
3745 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3749 ST(0) = &PL_sv_undef;
3763 vals = mymalloc((r-l) * sizeof(i_color));
3764 count = i_glin(im, l, r, y, vals);
3766 for (i = 0; i < count; ++i) {
3768 i_color *col = mymalloc(sizeof(i_color));
3769 sv = sv_newmortal();
3770 sv_setref_pv(sv, "Imager::Color", (void *)col);
3777 i_glinf(im, l, r, y)
3787 vals = mymalloc((r-l) * sizeof(i_fcolor));
3788 count = i_glinf(im, l, r, y, vals);
3790 for (i = 0; i < count; ++i) {
3792 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3794 sv = sv_newmortal();
3795 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3802 i_img_16_new(x, y, ch)
3808 i_img_double_new(x, y, ch)
3814 i_tags_addn(im, name, code, idata)
3823 name = SvPV(ST(1), len);
3826 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3831 i_tags_add(im, name, code, data, idata)
3841 name = SvPV(ST(1), len);
3845 data = SvPV(ST(3), len);
3850 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3855 i_tags_find(im, name, start)
3862 if (i_tags_find(&im->tags, name, start, &entry)) {
3864 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3866 ST(0) = sv_2mortal(newSViv(entry));
3868 ST(0) = &PL_sv_undef;
3872 i_tags_findn(im, code, start)
3879 if (i_tags_findn(&im->tags, code, start, &entry)) {
3881 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3883 ST(0) = sv_2mortal(newSViv(entry));
3886 ST(0) = &PL_sv_undef;
3889 i_tags_delete(im, entry)
3893 RETVAL = i_tags_delete(&im->tags, entry);
3898 i_tags_delbyname(im, name)
3902 RETVAL = i_tags_delbyname(&im->tags, name);
3907 i_tags_delbycode(im, code)
3911 RETVAL = i_tags_delbycode(&im->tags, code);
3916 i_tags_get(im, index)
3920 if (index >= 0 && index < im->tags.count) {
3921 i_img_tag *entry = im->tags.tags + index;
3925 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3928 PUSHs(sv_2mortal(newSViv(entry->code)));
3931 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3934 PUSHs(sv_2mortal(newSViv(entry->idata)));
3942 RETVAL = im->tags.count;
3949 i_wf_bbox(face, size, text)
3955 int cords[BOUNDING_BOX_COUNT];
3957 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3959 for (i = 0; i < rc; ++i)
3960 PUSHs(sv_2mortal(newSViv(cords[i])));
3964 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3975 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3981 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3992 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4002 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4004 #define FT2_DESTROY(font) i_ft2_destroy(font)
4008 Imager::Font::FT2 font
4010 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4013 i_ft2_new(name, index)
4018 i_ft2_setdpi(font, xdpi, ydpi)
4019 Imager::Font::FT2 font
4025 Imager::Font::FT2 font
4029 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4031 PUSHs(sv_2mortal(newSViv(xdpi)));
4032 PUSHs(sv_2mortal(newSViv(ydpi)));
4036 i_ft2_sethinting(font, hinting)
4037 Imager::Font::FT2 font
4041 i_ft2_settransform(font, matrix)
4042 Imager::Font::FT2 font
4050 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4051 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4052 av=(AV*)SvRV(ST(1));
4056 for (i = 0; i < len; ++i) {
4057 sv1=(*(av_fetch(av,i,0)));
4058 matrix[i] = SvNV(sv1);
4062 RETVAL = i_ft2_settransform(font, matrix);
4067 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4068 Imager::Font::FT2 font
4074 int bbox[BOUNDING_BOX_COUNT];
4080 text = SvPV(text_sv, text_len);
4082 if (SvUTF8(text_sv))
4085 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4088 for (i = 0; i < rc; ++i)
4089 PUSHs(sv_2mortal(newSViv(bbox[i])));
4093 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4094 Imager::Font::FT2 font
4108 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4111 for (i = 0; i < 8; ++i)
4112 PUSHs(sv_2mortal(newSViv(bbox[i])));
4116 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4117 Imager::Font::FT2 font
4133 if (SvUTF8(ST(7))) {
4137 text = SvPV(ST(7), len);
4138 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4139 len, align, aa, vlayout, utf8);
4144 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4145 Imager::Font::FT2 font
4162 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4163 strlen(text), align, aa, vlayout, 1);
4168 ft2_transform_box(font, x0, x1, x2, x3)
4169 Imager::Font::FT2 font
4177 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4178 ft2_transform_box(font, box);
4180 PUSHs(sv_2mortal(newSViv(box[0])));
4181 PUSHs(sv_2mortal(newSViv(box[1])));
4182 PUSHs(sv_2mortal(newSViv(box[2])));
4183 PUSHs(sv_2mortal(newSViv(box[3])));
4186 i_ft2_has_chars(handle, text_sv, utf8)
4187 Imager::Font::FT2 handle
4198 if (SvUTF8(text_sv))
4201 text = SvPV(text_sv, len);
4202 work = mymalloc(len);
4203 count = i_ft2_has_chars(handle, text, len, utf8, work);
4204 if (GIMME_V == G_ARRAY) {
4206 for (i = 0; i < count; ++i) {
4207 PUSHs(sv_2mortal(newSViv(work[i])));
4212 PUSHs(sv_2mortal(newSVpv(work, count)));
4217 i_ft2_face_name(handle)
4218 Imager::Font::FT2 handle
4223 len = i_ft2_face_name(handle, name, sizeof(name));
4226 PUSHs(sv_2mortal(newSVpv(name, 0)));
4230 i_ft2_glyph_name(handle, text_sv, utf8 = 0)
4231 Imager::Font::FT2 handle
4242 if (SvUTF8(text_sv))
4245 text = SvPV(text_sv, work_len);
4250 ch = i_utf8_advance(&text, &len);
4252 i_push_error(0, "invalid UTF8 character");
4261 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name))) {
4262 PUSHs(sv_2mortal(newSVpv(name, 0)));
4265 PUSHs(&PL_sv_undef);
4270 i_ft2_can_do_glyph_names()
4273 i_ft2_face_has_glyph_names(handle)
4274 Imager::Font::FT2 handle
4278 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4282 Imager::FillHandle fill
4284 MODULE = Imager PACKAGE = Imager
4287 i_new_fill_solid(cl, combine)
4292 i_new_fill_solidf(cl, combine)
4293 Imager::Color::Float cl
4297 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4305 unsigned char *cust_hatch;
4309 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4313 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4318 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4319 Imager::Color::Float fg
4320 Imager::Color::Float bg
4326 unsigned char *cust_hatch;
4330 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4334 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4339 i_new_fill_image(src, matrix, xoff, yoff, combine)
4356 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4357 croak("i_new_fill_image: parameter must be an arrayref");
4358 av=(AV*)SvRV(ST(1));
4362 for (i = 0; i < len; ++i) {
4363 sv1=(*(av_fetch(av,i,0)));
4364 matrix[i] = SvNV(sv1);
4370 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);