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;
23 typedef TT_Fonthandle* Imager__Font__TT;
27 typedef FT2_Fonthandle* Imager__Font__FT2;
30 /* These functions are all shared - then comes platform dependant code */
31 static int getstr(void *hv_t,char *key,char **store) {
35 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
37 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
39 svpp=hv_fetch(hv, key, strlen(key), 0);
40 *store=SvPV(*svpp, PL_na );
45 static int getint(void *hv_t,char *key,int *store) {
49 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
51 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
53 svpp=hv_fetch(hv, key, strlen(key), 0);
54 *store=(int)SvIV(*svpp);
58 static int getdouble(void *hv_t,char* key,double *store) {
62 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
64 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
65 svpp=hv_fetch(hv, key, strlen(key), 0);
66 *store=(float)SvNV(*svpp);
70 static int getvoid(void *hv_t,char* key,void **store) {
74 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
76 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
78 svpp=hv_fetch(hv, key, strlen(key), 0);
79 *store = INT2PTR(void*, SvIV(*svpp));
84 static int getobj(void *hv_t,char *key,char *type,void **store) {
88 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
90 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
92 svpp=hv_fetch(hv, key, strlen(key), 0);
94 if (sv_derived_from(*svpp,type)) {
95 IV tmp = SvIV((SV*)SvRV(*svpp));
96 *store = INT2PTR(void*, tmp);
98 mm_log((1,"getobj: key exists in hash but is not of correct type"));
105 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
107 void my_SvREFCNT_dec(void *p) {
108 SvREFCNT_dec((SV*)p);
113 log_entry(char *string, int level) {
114 mm_log((level, string));
118 typedef struct i_reader_data_tag
120 /* presumably a CODE ref or name of a sub */
124 /* used by functions that want callbacks */
125 static int read_callback(char *userdata, char *buffer, int need, int want) {
126 i_reader_data *rd = (i_reader_data *)userdata;
130 dSP; dTARG = sv_newmortal();
131 /* thanks to Simon Cozens for help with the dTARG above */
141 count = perl_call_sv(rd->sv, G_SCALAR);
146 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
152 char *ptr = SvPV(data, len);
154 croak("Too much data returned in reader callback");
156 memcpy(buffer, ptr, len);
172 SV *sv; /* a coderef or sub name */
175 /* used by functions that want callbacks */
176 static int write_callback(char *userdata, char const *data, int size) {
177 i_writer_data *wd = (i_writer_data *)userdata;
187 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
190 count = perl_call_sv(wd->sv, G_SCALAR);
195 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
198 success = SvTRUE(sv);
208 #define CBDATA_BUFSIZE 8192
211 /* the SVs we use to call back to Perl */
217 /* we need to remember whether the buffer contains write data or
223 /* how far we've read into the buffer (not used for writing) */
226 /* the amount of space used/data available in the buffer */
229 /* the maximum amount to fill the buffer before flushing
230 If any write is larger than this then the buffer is flushed and
231 the full write is performed. The write is _not_ split into
236 char buffer[CBDATA_BUFSIZE];
241 call_writer(cbd, buf, size)
243 Low-level function to call the perl writer callback.
247 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
253 if (!SvOK(cbd->writecb))
260 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
263 count = perl_call_sv(cbd->writecb, G_SCALAR);
267 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
270 success = SvTRUE(sv);
277 return success ? size : 0;
280 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
287 if (!SvOK(cbd->readcb))
294 PUSHs(sv_2mortal(newSViv(size)));
295 PUSHs(sv_2mortal(newSViv(maxread)));
298 count = perl_call_sv(cbd->readcb, G_SCALAR);
303 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
309 char *ptr = SvPV(data, len);
311 croak("Too much data returned in reader callback");
313 memcpy(buf, ptr, len);
327 static ssize_t write_flush(struct cbdata *cbd) {
330 result = call_writer(cbd, cbd->buffer, cbd->used);
335 static off_t io_seeker(void *p, off_t offset, int whence) {
336 struct cbdata *cbd = p;
341 if (!SvOK(cbd->seekcb))
345 if (cbd->used && write_flush(cbd) <= 0)
349 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
350 offset -= cbd->where - cbd->used;
353 cbd->where = cbd->used = 0;
359 PUSHs(sv_2mortal(newSViv(offset)));
360 PUSHs(sv_2mortal(newSViv(whence)));
363 count = perl_call_sv(cbd->seekcb, G_SCALAR);
368 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
379 static ssize_t io_writer(void *p, void const *data, size_t size) {
380 struct cbdata *cbd = p;
382 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
384 if (cbd->reading && cbd->where < cbd->used) {
385 /* we read past the place where the caller expected us to be
386 so adjust our position a bit */
388 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
393 cbd->where = cbd->used = 0;
396 if (cbd->used && cbd->used + size > cbd->maxlength) {
397 if (write_flush(cbd) <= 0) {
402 if (cbd->used+size <= cbd->maxlength) {
403 memcpy(cbd->buffer + cbd->used, data, size);
407 /* it doesn't fit - just pass it up */
408 return call_writer(cbd, data, size);
411 static ssize_t io_reader(void *p, void *data, size_t size) {
412 struct cbdata *cbd = p;
414 char *out = data; /* so we can do pointer arithmetic */
417 if (write_flush(cbd) <= 0)
423 if (size <= cbd->used - cbd->where) {
425 memcpy(data, cbd->buffer+cbd->where, size);
430 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
431 total += cbd->used - cbd->where;
432 size -= cbd->used - cbd->where;
433 out += cbd->used - cbd->where;
434 if (size < sizeof(cbd->buffer)) {
438 && (did_read = call_reader(cbd, cbd->buffer, size,
439 sizeof(cbd->buffer))) > 0) {
441 cbd->used = did_read;
443 copy_size = i_min(size, cbd->used);
444 memcpy(out, cbd->buffer, copy_size);
445 cbd->where += copy_size;
452 /* just read the rest - too big for our buffer*/
454 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
464 static void io_closer(void *p) {
465 struct cbdata *cbd = p;
467 if (cbd->writing && cbd->used > 0) {
472 if (SvOK(cbd->closecb)) {
480 perl_call_sv(cbd->closecb, G_VOID);
489 static void io_destroyer(void *p) {
490 struct cbdata *cbd = p;
492 SvREFCNT_dec(cbd->writecb);
493 SvREFCNT_dec(cbd->readcb);
494 SvREFCNT_dec(cbd->seekcb);
495 SvREFCNT_dec(cbd->closecb);
503 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
506 for (i = 0; i < count; ++i)
507 if (strEQ(names[i].name, name))
508 return names[i].value;
512 static struct value_name transp_names[] =
515 { "threshold", tr_threshold },
516 { "errdiff", tr_errdiff },
517 { "ordered", tr_ordered, },
520 static struct value_name make_color_names[] =
522 { "none", mc_none, },
523 { "webmap", mc_web_map, },
524 { "addi", mc_addi, },
525 { "mediancut", mc_median_cut, },
528 static struct value_name translate_names[] =
531 { "giflib", pt_giflib, },
533 { "closest", pt_closest, },
534 { "perturb", pt_perturb, },
535 { "errdiff", pt_errdiff, },
538 static struct value_name errdiff_names[] =
540 { "floyd", ed_floyd, },
541 { "jarvis", ed_jarvis, },
542 { "stucki", ed_stucki, },
543 { "custom", ed_custom, },
546 static struct value_name orddith_names[] =
548 { "random", od_random, },
549 { "dot8", od_dot8, },
550 { "dot4", od_dot4, },
551 { "hline", od_hline, },
552 { "vline", od_vline, },
553 { "/line", od_slashline, },
554 { "slashline", od_slashline, },
555 { "\\line", od_backline, },
556 { "backline", od_backline, },
557 { "tiny", od_tiny, },
558 { "custom", od_custom, },
562 hv_fetch_bool(HV *hv, char *name, int def) {
565 sv = hv_fetch(hv, name, strlen(name), 0);
574 hv_fetch_int(HV *hv, char *name, int def) {
577 sv = hv_fetch(hv, name, strlen(name), 0);
585 /* look through the hash for quantization options */
586 static void handle_quant_opts(i_quantize *quant, HV *hv)
588 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
594 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
596 sv = hv_fetch(hv, "transp", 6, 0);
597 if (sv && *sv && (str = SvPV(*sv, len))) {
599 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
601 if (quant->transp != tr_none) {
602 quant->tr_threshold = 127;
603 sv = hv_fetch(hv, "tr_threshold", 12, 0);
605 quant->tr_threshold = SvIV(*sv);
607 if (quant->transp == tr_errdiff) {
608 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
609 if (sv && *sv && (str = SvPV(*sv, len)))
610 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
612 if (quant->transp == tr_ordered) {
613 quant->tr_orddith = od_tiny;
614 sv = hv_fetch(hv, "tr_orddith", 10, 0);
615 if (sv && *sv && (str = SvPV(*sv, len)))
616 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
618 if (quant->tr_orddith == od_custom) {
619 sv = hv_fetch(hv, "tr_map", 6, 0);
620 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
621 AV *av = (AV*)SvRV(*sv);
622 len = av_len(av) + 1;
623 if (len > sizeof(quant->tr_custom))
624 len = sizeof(quant->tr_custom);
625 for (i = 0; i < len; ++i) {
626 SV **sv2 = av_fetch(av, i, 0);
628 quant->tr_custom[i] = SvIV(*sv2);
631 while (i < sizeof(quant->tr_custom))
632 quant->tr_custom[i++] = 0;
637 quant->make_colors = mc_addi;
638 sv = hv_fetch(hv, "make_colors", 11, 0);
639 if (sv && *sv && (str = SvPV(*sv, len))) {
641 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
643 sv = hv_fetch(hv, "colors", 6, 0);
644 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
645 /* needs to be an array of Imager::Color
646 note that the caller allocates the mc_color array and sets mc_size
648 AV *av = (AV *)SvRV(*sv);
649 quant->mc_count = av_len(av)+1;
650 if (quant->mc_count > quant->mc_size)
651 quant->mc_count = quant->mc_size;
652 for (i = 0; i < quant->mc_count; ++i) {
653 SV **sv1 = av_fetch(av, i, 0);
654 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
655 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
656 quant->mc_colors[i] = *col;
660 sv = hv_fetch(hv, "max_colors", 10, 0);
663 if (i <= quant->mc_size && i >= quant->mc_count)
667 quant->translate = pt_closest;
668 sv = hv_fetch(hv, "translate", 9, 0);
669 if (sv && *sv && (str = SvPV(*sv, len))) {
670 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
672 sv = hv_fetch(hv, "errdiff", 7, 0);
673 if (sv && *sv && (str = SvPV(*sv, len))) {
674 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
676 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
677 /* get the error diffusion map */
678 sv = hv_fetch(hv, "errdiff_width", 13, 0);
680 quant->ed_width = SvIV(*sv);
681 sv = hv_fetch(hv, "errdiff_height", 14, 0);
683 quant->ed_height = SvIV(*sv);
684 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
686 quant->ed_orig = SvIV(*sv);
687 if (quant->ed_width > 0 && quant->ed_height > 0) {
689 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
690 sv = hv_fetch(hv, "errdiff_map", 11, 0);
691 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
692 AV *av = (AV*)SvRV(*sv);
693 len = av_len(av) + 1;
694 if (len > quant->ed_width * quant->ed_height)
695 len = quant->ed_width * quant->ed_height;
696 for (i = 0; i < len; ++i) {
697 SV **sv2 = av_fetch(av, i, 0);
699 quant->ed_map[i] = SvIV(*sv2);
700 sum += quant->ed_map[i];
706 myfree(quant->ed_map);
708 quant->errdiff = ed_floyd;
712 sv = hv_fetch(hv, "perturb", 7, 0);
714 quant->perturb = SvIV(*sv);
717 static void cleanup_quant_opts(i_quantize *quant) {
718 myfree(quant->mc_colors);
720 myfree(quant->ed_map);
724 /* look through the hash for options to add to opts */
725 static void handle_gif_opts(i_gif_opts *opts, HV *hv)
729 /**((char *)0) = '\0';*/
730 opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
731 opts->interlace = hv_fetch_bool(hv, "interlace", 0);
733 sv = hv_fetch(hv, "gif_delays", 10, 0);
734 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
735 AV *av = (AV*)SvRV(*sv);
736 opts->delay_count = av_len(av)+1;
737 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
738 for (i = 0; i < opts->delay_count; ++i) {
739 SV *sv1 = *av_fetch(av, i, 0);
740 opts->delays[i] = SvIV(sv1);
743 sv = hv_fetch(hv, "gif_user_input", 14, 0);
744 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
745 AV *av = (AV*)SvRV(*sv);
746 opts->user_input_count = av_len(av)+1;
747 opts->user_input_flags = mymalloc(opts->user_input_count);
748 for (i = 0; i < opts->user_input_count; ++i) {
749 SV *sv1 = *av_fetch(av, i, 0);
750 opts->user_input_flags[i] = SvIV(sv1) != 0;
753 sv = hv_fetch(hv, "gif_disposal", 12, 0);
754 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
755 AV *av = (AV*)SvRV(*sv);
756 opts->disposal_count = av_len(av)+1;
757 opts->disposal = mymalloc(opts->disposal_count);
758 for (i = 0; i < opts->disposal_count; ++i) {
759 SV *sv1 = *av_fetch(av, i, 0);
760 opts->disposal[i] = SvIV(sv1);
763 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
764 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
765 i_color *col = INT2PTR(i_color *, SvIV((SV *)SvRV(*sv)));
766 opts->tran_color = *col;
768 sv = hv_fetch(hv, "gif_positions", 13, 0);
769 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
770 AV *av = (AV *)SvRV(*sv);
771 opts->position_count = av_len(av) + 1;
772 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
773 for (i = 0; i < opts->position_count; ++i) {
774 SV **sv2 = av_fetch(av, i, 0);
775 opts->positions[i].x = opts->positions[i].y = 0;
776 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
777 AV *av2 = (AV*)SvRV(*sv2);
779 sv3 = av_fetch(av2, 0, 0);
781 opts->positions[i].x = SvIV(*sv3);
782 sv3 = av_fetch(av2, 1, 0);
784 opts->positions[i].y = SvIV(*sv3);
788 /* Netscape2.0 loop count extension */
789 opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
791 opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
794 static void cleanup_gif_opts(i_gif_opts *opts) {
796 myfree(opts->delays);
797 if (opts->user_input_flags)
798 myfree(opts->user_input_flags);
800 myfree(opts->disposal);
802 myfree(opts->positions);
807 /* copies the color map from the hv into the colors member of the HV */
808 static void copy_colors_back(HV *hv, i_quantize *quant) {
814 sv = hv_fetch(hv, "colors", 6, 0);
815 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
818 ref = newRV_inc((SV*) av);
819 sv = hv_store(hv, "colors", 6, ref, 0);
822 av = (AV *)SvRV(*sv);
824 av_extend(av, quant->mc_count+1);
825 for (i = 0; i < quant->mc_count; ++i) {
826 i_color *in = quant->mc_colors+i;
827 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
828 work = sv_newmortal();
829 sv_setref_pv(work, "Imager::Color", (void *)c);
831 if (!av_store(av, i, work)) {
837 /* loads the segments of a fountain fill into an array */
838 static i_fountain_seg *
839 load_fount_segs(AV *asegs, int *count) {
840 /* Each element of segs must contain:
841 [ start, middle, end, c0, c1, segtype, colortrans ]
842 start, middle, end are doubles from 0 to 1
843 c0, c1 are Imager::Color::Float or Imager::Color objects
844 segtype, colortrans are ints
849 i_fountain_seg *segs;
853 *count = av_len(asegs)+1;
855 croak("i_fountain must have at least one segment");
856 segs = mymalloc(sizeof(i_fountain_seg) * *count);
857 for(i = 0; i < *count; i++) {
858 SV **sv1 = av_fetch(asegs, i, 0);
859 if (!sv1 || !*sv1 || !SvROK(*sv1)
860 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
862 croak("i_fountain: segs must be an arrayref of arrayrefs");
864 aseg = (AV *)SvRV(*sv1);
865 if (av_len(aseg) != 7-1) {
867 croak("i_fountain: a segment must have 7 members");
869 for (j = 0; j < 3; ++j) {
870 SV **sv2 = av_fetch(aseg, j, 0);
873 croak("i_fountain: XS error");
875 work[j] = SvNV(*sv2);
877 segs[i].start = work[0];
878 segs[i].middle = work[1];
879 segs[i].end = work[2];
880 for (j = 0; j < 2; ++j) {
881 SV **sv3 = av_fetch(aseg, 3+j, 0);
882 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
883 (!sv_derived_from(*sv3, "Imager::Color")
884 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
886 croak("i_fountain: segs must contain colors in elements 3 and 4");
888 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
889 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
892 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
894 for (ch = 0; ch < MAXCHANNELS; ++ch) {
895 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
899 for (j = 0; j < 2; ++j) {
900 SV **sv2 = av_fetch(aseg, j+5, 0);
903 croak("i_fountain: XS error");
905 worki[j] = SvIV(*sv2);
907 segs[i].type = worki[0];
908 segs[i].color = worki[1];
914 /* I don't think ICLF_* names belong at the C interface
915 this makes the XS code think we have them, to let us avoid
916 putting function bodies in the XS code
918 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
919 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
921 /* for the fill objects
922 Since a fill object may later have dependent images, (or fills!)
923 we need perl wrappers - oh well
925 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
926 typedef i_fill_t* Imager__FillHandle;
928 /* the m_init_log() function was called init_log(), renamed to reduce
929 potential naming conflicts */
930 #define init_log m_init_log
932 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
935 ICL_new_internal(r,g,b,a)
947 ICL_set_internal(cl,r,g,b,a)
954 ICL_set_internal(cl, r, g, b, a);
968 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
969 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
970 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
971 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
977 RETVAL = mymalloc(sizeof(i_color));
979 i_hsv_to_rgb(RETVAL);
987 RETVAL = mymalloc(sizeof(i_color));
989 i_rgb_to_hsv(RETVAL);
995 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
998 ICLF_new_internal(r, g, b, a)
1006 Imager::Color::Float cl
1010 Imager::Color::Float cl
1014 EXTEND(SP, MAXCHANNELS);
1015 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1016 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1017 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1021 ICLF_set_internal(cl,r,g,b,a)
1022 Imager::Color::Float cl
1035 Imager::Color::Float
1037 Imager::Color::Float c
1039 RETVAL = mymalloc(sizeof(i_fcolor));
1041 i_hsv_to_rgbf(RETVAL);
1045 Imager::Color::Float
1047 Imager::Color::Float c
1049 RETVAL = mymalloc(sizeof(i_fcolor));
1051 i_rgb_to_hsvf(RETVAL);
1056 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1070 MODULE = Imager PACKAGE = Imager
1089 SvPV(ST(0), length);
1090 SvREFCNT_inc(ST(0));
1091 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1096 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1105 cbd = mymalloc(sizeof(struct cbdata));
1106 SvREFCNT_inc(writecb);
1107 cbd->writecb = writecb;
1108 SvREFCNT_inc(readcb);
1109 cbd->readcb = readcb;
1110 SvREFCNT_inc(seekcb);
1111 cbd->seekcb = seekcb;
1112 SvREFCNT_inc(closecb);
1113 cbd->closecb = closecb;
1114 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1115 if (maxwrite > CBDATA_BUFSIZE)
1116 maxwrite = CBDATA_BUFSIZE;
1117 cbd->maxlength = maxwrite;
1118 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1127 unsigned char* data;
1131 tlength = io_slurp(ig, &data);
1133 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1137 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1144 MODULE = Imager PACKAGE = Imager
1157 while( (item=i_format_list[i++]) != NULL ) {
1159 PUSHs(sv_2mortal(newSVpv(item,0)));
1176 i_img_empty_ch(im,x,y,ch)
1183 i_sametype(im, x, y)
1189 i_sametype_chans(im, x, y, channels)
1196 m_init_log(name,level)
1201 log_entry(string,level)
1220 i_img_info(im,info);
1222 PUSHs(sv_2mortal(newSViv(info[0])));
1223 PUSHs(sv_2mortal(newSViv(info[1])));
1224 PUSHs(sv_2mortal(newSViv(info[2])));
1225 PUSHs(sv_2mortal(newSViv(info[3])));
1231 i_img_setmask(im,ch_mask)
1240 i_img_getchannels(im)
1249 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1254 i_line(im,x1,y1,x2,y2,val,endp)
1264 i_line_aa(im,x1,y1,x2,y2,val,endp)
1274 i_box(im,x1,y1,x2,y2,val)
1283 i_box_filled(im,x1,y1,x2,y2,val)
1292 i_box_cfill(im,x1,y1,x2,y2,fill)
1298 Imager::FillHandle fill
1301 i_arc(im,x,y,rad,d1,d2,val)
1311 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1318 Imager::FillHandle fill
1323 i_circle_aa(im,x,y,rad,val)
1333 i_bezier_multi(im,xc,yc,val)
1346 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1347 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1348 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1349 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1350 av1=(AV*)SvRV(ST(1));
1351 av2=(AV*)SvRV(ST(2));
1352 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1354 x=mymalloc( len*sizeof(double) );
1355 y=mymalloc( len*sizeof(double) );
1356 for(i=0;i<len;i++) {
1357 sv1=(*(av_fetch(av1,i,0)));
1358 sv2=(*(av_fetch(av2,i,0)));
1359 x[i]=(double)SvNV(sv1);
1360 y[i]=(double)SvNV(sv2);
1362 i_bezier_multi(im,len,x,y,val);
1368 i_poly_aa(im,xc,yc,val)
1381 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1382 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1383 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1384 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1385 av1=(AV*)SvRV(ST(1));
1386 av2=(AV*)SvRV(ST(2));
1387 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1389 x=mymalloc( len*sizeof(double) );
1390 y=mymalloc( len*sizeof(double) );
1391 for(i=0;i<len;i++) {
1392 sv1=(*(av_fetch(av1,i,0)));
1393 sv2=(*(av_fetch(av2,i,0)));
1394 x[i]=(double)SvNV(sv1);
1395 y[i]=(double)SvNV(sv2);
1397 i_poly_aa(im,len,x,y,val);
1402 i_poly_aa_cfill(im,xc,yc,fill)
1404 Imager::FillHandle fill
1414 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1415 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1416 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1417 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1418 av1=(AV*)SvRV(ST(1));
1419 av2=(AV*)SvRV(ST(2));
1420 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1422 x=mymalloc( len*sizeof(double) );
1423 y=mymalloc( len*sizeof(double) );
1424 for(i=0;i<len;i++) {
1425 sv1=(*(av_fetch(av1,i,0)));
1426 sv2=(*(av_fetch(av2,i,0)));
1427 x[i]=(double)SvNV(sv1);
1428 y[i]=(double)SvNV(sv2);
1430 i_poly_aa_cfill(im,len,x,y,fill);
1437 i_flood_fill(im,seedx,seedy,dcol)
1444 i_flood_cfill(im,seedx,seedy,fill)
1448 Imager::FillHandle fill
1452 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1464 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1482 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1494 i_flipxy(im, direction)
1499 i_rotate90(im, degrees)
1504 i_rotate_exact(im, amount, ...)
1508 i_color *backp = NULL;
1509 i_fcolor *fbackp = NULL;
1513 /* extract the bg colors if any */
1514 /* yes, this is kind of strange */
1515 for (i = 2; i < items; ++i) {
1517 if (sv_derived_from(sv1, "Imager::Color")) {
1518 IV tmp = SvIV((SV*)SvRV(sv1));
1519 backp = INT2PTR(i_color *, tmp);
1521 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1522 IV tmp = SvIV((SV*)SvRV(sv1));
1523 fbackp = INT2PTR(i_fcolor *, tmp);
1526 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1531 i_matrix_transform(im, xsize, ysize, matrix, ...)
1541 i_color *backp = NULL;
1542 i_fcolor *fbackp = NULL;
1544 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1545 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1546 av=(AV*)SvRV(ST(3));
1550 for (i = 0; i < len; ++i) {
1551 sv1=(*(av_fetch(av,i,0)));
1552 matrix[i] = SvNV(sv1);
1556 /* extract the bg colors if any */
1557 /* yes, this is kind of strange */
1558 for (i = 4; i < items; ++i) {
1560 if (sv_derived_from(sv1, "Imager::Color")) {
1561 IV tmp = SvIV((SV*)SvRV(sv1));
1562 backp = INT2PTR(i_color *, tmp);
1564 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1565 IV tmp = SvIV((SV*)SvRV(sv1));
1566 fbackp = INT2PTR(i_fcolor *, tmp);
1569 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1574 i_gaussian(im,stdev)
1579 i_unsharp_mask(im,stdev,scale)
1594 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1595 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1596 av=(AV*)SvRV(ST(1));
1598 coeff=mymalloc( len*sizeof(float) );
1599 for(i=0;i<len;i++) {
1600 sv1=(*(av_fetch(av,i,0)));
1601 coeff[i]=(float)SvNV(sv1);
1603 i_conv(im,coeff,len);
1607 i_convert(im, src, coeff)
1620 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1621 croak("i_convert: parameter 3 must be an arrayref\n");
1622 avmain = (AV*)SvRV(ST(2));
1623 outchan = av_len(avmain)+1;
1624 /* find the biggest */
1626 for (j=0; j < outchan; ++j) {
1627 temp = av_fetch(avmain, j, 0);
1628 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1629 avsub = (AV*)SvRV(*temp);
1630 len = av_len(avsub)+1;
1635 coeff = mymalloc(sizeof(float) * outchan * inchan);
1636 for (j = 0; j < outchan; ++j) {
1637 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1638 len = av_len(avsub)+1;
1639 for (i = 0; i < len; ++i) {
1640 temp = av_fetch(avsub, i, 0);
1642 coeff[i+j*inchan] = SvNV(*temp);
1644 coeff[i+j*inchan] = 0;
1647 coeff[i++ + j*inchan] = 0;
1649 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1659 unsigned int mask = 0;
1665 unsigned char (*maps)[256];
1667 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1668 croak("i_map: parameter 2 must be an arrayref\n");
1669 avmain = (AV*)SvRV(ST(1));
1670 len = av_len(avmain)+1;
1671 if (im->channels < len) len = im->channels;
1673 maps = mymalloc( len * sizeof(unsigned char [256]) );
1675 for (j=0; j<len ; j++) {
1676 temp = av_fetch(avmain, j, 0);
1677 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1678 avsub = (AV*)SvRV(*temp);
1679 if(av_len(avsub) != 255) continue;
1681 for (i=0; i<256 ; i++) {
1683 temp = av_fetch(avsub, i, 0);
1684 val = temp ? SvIV(*temp) : 0;
1686 if (val>255) val = 255;
1691 i_map(im, maps, mask);
1704 i_init_fonts(t1log=0)
1719 i_t1_destroy(font_id)
1724 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1743 str = SvPV(str_sv, len);
1744 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1751 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1760 int cords[BOUNDING_BOX_COUNT];
1768 str = SvPV(str_sv, len);
1769 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1772 for (i = 0; i < rc; ++i)
1773 PUSHs(sv_2mortal(newSViv(cords[i])));
1779 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1798 str = SvPV(str_sv, len);
1799 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1805 i_t1_has_chars(handle, text_sv, utf8 = 0)
1817 if (SvUTF8(text_sv))
1820 text = SvPV(text_sv, len);
1821 work = mymalloc(len);
1822 count = i_t1_has_chars(handle, text, len, utf8, work);
1823 if (GIMME_V == G_ARRAY) {
1825 for (i = 0; i < count; ++i) {
1826 PUSHs(sv_2mortal(newSViv(work[i])));
1831 PUSHs(sv_2mortal(newSVpv(work, count)));
1836 i_t1_face_name(handle)
1842 len = i_t1_face_name(handle, name, sizeof(name));
1845 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1849 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1861 if (SvUTF8(text_sv))
1864 text = SvPV(text_sv, work_len);
1869 ch = i_utf8_advance(&text, &len);
1871 i_push_error(0, "invalid UTF8 character");
1880 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1881 PUSHs(sv_2mortal(newSVpv(name, 0)));
1884 PUSHs(&PL_sv_undef);
1898 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1900 #define TT_DESTROY(handle) i_tt_destroy(handle)
1904 Imager::Font::TT handle
1907 MODULE = Imager PACKAGE = Imager
1911 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
1912 Imager::Font::TT handle
1930 str = SvPV(str_sv, len);
1931 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1938 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
1939 Imager::Font::TT handle
1957 str = SvPV(str_sv, len);
1958 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1965 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1966 Imager::Font::TT handle
1972 int cords[BOUNDING_BOX_COUNT],rc;
1981 str = SvPV(str_sv, len);
1982 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1984 for (i = 0; i < rc; ++i) {
1985 PUSHs(sv_2mortal(newSViv(cords[i])));
1990 i_tt_has_chars(handle, text_sv, utf8)
1991 Imager::Font::TT handle
2002 if (SvUTF8(text_sv))
2005 text = SvPV(text_sv, len);
2006 work = mymalloc(len);
2007 count = i_tt_has_chars(handle, text, len, utf8, work);
2008 if (GIMME_V == G_ARRAY) {
2010 for (i = 0; i < count; ++i) {
2011 PUSHs(sv_2mortal(newSViv(work[i])));
2016 PUSHs(sv_2mortal(newSVpv(work, count)));
2021 i_tt_dump_names(handle)
2022 Imager::Font::TT handle
2025 i_tt_face_name(handle)
2026 Imager::Font::TT handle
2031 len = i_tt_face_name(handle, name, sizeof(name));
2034 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2038 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2039 Imager::Font::TT handle
2050 if (SvUTF8(text_sv))
2053 text = SvPV(text_sv, work_len);
2058 ch = i_utf8_advance(&text, &len);
2060 i_push_error(0, "invalid UTF8 character");
2069 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2070 PUSHs(sv_2mortal(newSVpv(name, 0)));
2073 PUSHs(&PL_sv_undef);
2082 i_writejpeg_wiol(im, ig, qfactor)
2098 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2099 if (iptc_itext == NULL) {
2102 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2107 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2109 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2118 i_test_format_probe(ig, length)
2127 i_readtiff_wiol(ig, length)
2132 i_readtiff_multi_wiol(ig, length)
2140 imgs = i_readtiff_multi_wiol(ig, length, &count);
2143 for (i = 0; i < count; ++i) {
2144 SV *sv = sv_newmortal();
2145 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2153 i_writetiff_wiol(im, ig)
2158 i_writetiff_multi_wiol(ig, ...)
2166 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2167 img_count = items - 1;
2169 if (img_count < 1) {
2172 i_push_error(0, "You need to specify images to save");
2175 imgs = mymalloc(sizeof(i_img *) * img_count);
2176 for (i = 0; i < img_count; ++i) {
2179 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2180 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2184 i_push_error(0, "Only images can be saved");
2191 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2199 i_writetiff_wiol_faxable(im, ig, fine)
2205 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2214 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2215 img_count = items - 2;
2217 if (img_count < 1) {
2220 i_push_error(0, "You need to specify images to save");
2223 imgs = mymalloc(sizeof(i_img *) * img_count);
2224 for (i = 0; i < img_count; ++i) {
2227 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2228 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2232 i_push_error(0, "Only images can be saved");
2239 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2247 #endif /* HAVE_LIBTIFF */
2253 i_readpng_wiol(ig, length)
2259 i_writepng_wiol(im, ig)
2272 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2275 i_writegif(im,fd,colors,pixdev,fixed)
2282 Imager__Color fixed;
2289 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2290 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2291 av=(AV*)SvRV(ST(4));
2292 fixedlen=av_len(av)+1;
2293 fixed=mymalloc( fixedlen*sizeof(i_color) );
2294 for(i=0;i<fixedlen;i++) {
2295 sv1=(*(av_fetch(av,i,0)));
2296 if (sv_derived_from(sv1, "Imager::Color")) {
2297 Itmp = SvIV((SV*)SvRV(sv1));
2298 tmp = (i_color*) Itmp;
2299 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2302 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2304 ST(0) = sv_newmortal();
2305 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2306 else sv_setiv(ST(0), (IV)RETVAL);
2312 i_writegifmc(im,fd,colors)
2319 i_writegif_gen(fd, ...)
2324 i_img **imgs = NULL;
2330 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2331 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2332 croak("i_writegif_gen: Second argument must be a hash ref");
2333 hv = (HV *)SvRV(ST(1));
2334 memset(&quant, 0, sizeof(quant));
2335 quant.mc_size = 256;
2336 handle_quant_opts(&quant, hv);
2337 img_count = items - 2;
2339 if (img_count < 1) {
2342 i_push_error(0, "You need to specify images to save");
2345 imgs = mymalloc(sizeof(i_img *) * img_count);
2346 for (i = 0; i < img_count; ++i) {
2349 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2350 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2354 i_push_error(0, "Only images can be saved");
2360 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2364 copy_colors_back(hv, &quant);
2367 ST(0) = sv_newmortal();
2368 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2369 else sv_setiv(ST(0), (IV)RETVAL);
2370 cleanup_quant_opts(&quant);
2374 i_writegif_callback(cb, maxbuffer,...)
2378 i_img **imgs = NULL;
2385 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2386 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2387 croak("i_writegif_callback: Second argument must be a hash ref");
2388 hv = (HV *)SvRV(ST(2));
2389 memset(&quant, 0, sizeof(quant));
2390 quant.mc_size = 256;
2391 handle_quant_opts(&quant, hv);
2392 img_count = items - 3;
2394 if (img_count < 1) {
2398 imgs = mymalloc(sizeof(i_img *) * img_count);
2399 for (i = 0; i < img_count; ++i) {
2402 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2403 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2412 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2416 copy_colors_back(hv, &quant);
2419 ST(0) = sv_newmortal();
2420 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2421 else sv_setiv(ST(0), (IV)RETVAL);
2422 cleanup_quant_opts(&quant);
2425 i_writegif_wiol(ig, opts,...)
2429 i_img **imgs = NULL;
2435 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2436 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2437 croak("i_writegif_callback: Second argument must be a hash ref");
2438 hv = (HV *)SvRV(ST(1));
2439 memset(&quant, 0, sizeof(quant));
2440 quant.mc_size = 256;
2441 handle_quant_opts(&quant, hv);
2442 img_count = items - 2;
2444 if (img_count < 1) {
2448 imgs = mymalloc(sizeof(i_img *) * img_count);
2449 for (i = 0; i < img_count; ++i) {
2452 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2453 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2461 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2465 copy_colors_back(hv, &quant);
2468 ST(0) = sv_newmortal();
2469 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2470 else sv_setiv(ST(0), (IV)RETVAL);
2471 cleanup_quant_opts(&quant);
2484 colour_table = NULL;
2487 if(GIMME_V == G_ARRAY) {
2488 rimg = i_readgif(fd,&colour_table,&colours);
2490 /* don't waste time with colours if they aren't wanted */
2491 rimg = i_readgif(fd,NULL,NULL);
2494 if (colour_table == NULL) {
2497 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2500 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2501 /* I don't know if I have the reference counts right or not :( */
2502 /* Neither do I :-) */
2503 /* No Idea here either */
2506 av_extend(ct, colours);
2507 for(q=0; q<colours; q++) {
2509 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2510 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2512 myfree(colour_table);
2516 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2518 PUSHs(newRV_noinc((SV*)ct));
2532 colour_table = NULL;
2535 if(GIMME_V == G_ARRAY) {
2536 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2538 /* don't waste time with colours if they aren't wanted */
2539 rimg = i_readgif_wiol(ig,NULL,NULL);
2542 if (colour_table == NULL) {
2545 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2548 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2549 /* I don't know if I have the reference counts right or not :( */
2550 /* Neither do I :-) */
2551 /* No Idea here either */
2554 av_extend(ct, colours);
2555 for(q=0; q<colours; q++) {
2557 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2558 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2560 myfree(colour_table);
2564 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2566 PUSHs(newRV_noinc((SV*)ct));
2570 i_readgif_scalar(...)
2582 data = (char *)SvPV(ST(0), length);
2586 if(GIMME_V == G_ARRAY) {
2587 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2589 /* don't waste time with colours if they aren't wanted */
2590 rimg=i_readgif_scalar(data,length,NULL,NULL);
2593 if (colour_table == NULL) {
2596 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2599 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2600 /* I don't know if I have the reference counts right or not :( */
2601 /* Neither do I :-) */
2603 av_extend(ct, colours);
2604 for(q=0; q<colours; q++) {
2606 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2607 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2609 myfree(colour_table);
2613 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2615 PUSHs(newRV_noinc((SV*)ct));
2619 i_readgif_callback(...)
2636 if(GIMME_V == G_ARRAY) {
2637 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2639 /* don't waste time with colours if they aren't wanted */
2640 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2643 if (colour_table == NULL) {
2646 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2649 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2650 /* I don't know if I have the reference counts right or not :( */
2651 /* Neither do I :-) */
2652 /* Neither do I - maybe I'll move this somewhere */
2654 av_extend(ct, colours);
2655 for(q=0; q<colours; q++) {
2657 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2658 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2660 myfree(colour_table);
2664 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2666 PUSHs(newRV_noinc((SV*)ct));
2677 imgs = i_readgif_multi(fd, &count);
2680 for (i = 0; i < count; ++i) {
2681 SV *sv = sv_newmortal();
2682 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2689 i_readgif_multi_scalar(data)
2697 data = (char *)SvPV(ST(0), length);
2698 imgs = i_readgif_multi_scalar(data, length, &count);
2701 for (i = 0; i < count; ++i) {
2702 SV *sv = sv_newmortal();
2703 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2710 i_readgif_multi_callback(cb)
2718 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2721 for (i = 0; i < count; ++i) {
2722 SV *sv = sv_newmortal();
2723 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2730 i_readgif_multi_wiol(ig)
2737 imgs = i_readgif_multi_wiol(ig, &count);
2740 for (i = 0; i < count; ++i) {
2741 SV *sv = sv_newmortal();
2742 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2754 i_readpnm_wiol(ig, length)
2760 i_writeppm_wiol(im, ig)
2766 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2775 i_writeraw_wiol(im,ig)
2780 i_writebmp_wiol(im,ig)
2790 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2799 idlen = SvCUR(ST(4));
2800 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2806 i_readtga_wiol(ig, length)
2812 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2821 idlen = SvCUR(ST(4));
2822 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2828 i_readrgb_wiol(ig, length)
2835 i_scaleaxis(im,Value,Axis)
2841 i_scale_nn(im,scx,scy)
2851 i_count_colors(im,maxc)
2857 i_transform(im,opx,opy,parm)
2870 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2871 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2872 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2873 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2874 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2875 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2876 av=(AV*)SvRV(ST(1));
2878 opx=mymalloc( opxl*sizeof(int) );
2879 for(i=0;i<opxl;i++) {
2880 sv1=(*(av_fetch(av,i,0)));
2881 opx[i]=(int)SvIV(sv1);
2883 av=(AV*)SvRV(ST(2));
2885 opy=mymalloc( opyl*sizeof(int) );
2886 for(i=0;i<opyl;i++) {
2887 sv1=(*(av_fetch(av,i,0)));
2888 opy[i]=(int)SvIV(sv1);
2890 av=(AV*)SvRV(ST(3));
2891 parmlen=av_len(av)+1;
2892 parm=mymalloc( parmlen*sizeof(double) );
2893 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2894 sv1=(*(av_fetch(av,i,0)));
2895 parm[i]=(double)SvNV(sv1);
2897 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2901 ST(0) = sv_newmortal();
2902 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2903 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2906 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2931 in_imgs_count = av_len(av_in_imgs)+1;
2932 for (i = 0; i < in_imgs_count; ++i) {
2933 sv1 = *av_fetch(av_in_imgs, i, 0);
2934 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2935 croak("sv_in_img must contain only images");
2938 if (in_imgs_count > 0) {
2939 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2940 for (i = 0; i < in_imgs_count; ++i) {
2941 sv1 = *av_fetch(av_in_imgs,i,0);
2942 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2943 croak("Parameter 5 must contain only images");
2945 tmp = SvIV((SV*)SvRV(sv1));
2946 in_imgs[i] = INT2PTR(i_img*, tmp);
2950 /* no input images */
2953 /* default the output size from the first input if possible */
2955 width = SvIV(sv_width);
2956 else if (in_imgs_count)
2957 width = in_imgs[0]->xsize;
2959 croak("No output image width supplied");
2961 if (SvOK(sv_height))
2962 height = SvIV(sv_height);
2963 else if (in_imgs_count)
2964 height = in_imgs[0]->ysize;
2966 croak("No output image height supplied");
2968 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2969 if (ops_len % sizeof(struct rm_op))
2970 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2971 ops_count = ops_len / sizeof(struct rm_op);
2973 n_regs_count = av_len(av_n_regs)+1;
2974 n_regs = mymalloc(n_regs_count * sizeof(double));
2975 for (i = 0; i < n_regs_count; ++i) {
2976 sv1 = *av_fetch(av_n_regs,i,0);
2978 n_regs[i] = SvNV(sv1);
2980 c_regs_count = av_len(av_c_regs)+1;
2981 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2982 /* I don't bother initializing the colou?r registers */
2984 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2985 n_regs, n_regs_count,
2986 c_regs, c_regs_count, in_imgs, in_imgs_count);
2991 ST(0) = sv_newmortal();
2992 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2993 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2997 i_contrast(im,intensity)
3006 i_noise(im,amount,type)
3012 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3022 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3041 i_postlevels(im,levels)
3051 i_watermark(im,wmark,tx,ty,pixdiff)
3053 Imager::ImgRaw wmark
3060 i_autolevels(im,lsat,usat,skew)
3067 i_radnoise(im,xo,yo,rscale,ascale)
3075 i_turbnoise(im, xo, yo, scale)
3098 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3099 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3100 croak("i_gradgen: Second argument must be an array ref");
3101 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3102 croak("i_gradgen: Third argument must be an array ref");
3103 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3104 croak("i_gradgen: Fourth argument must be an array ref");
3105 axx = (AV *)SvRV(ST(1));
3106 ayy = (AV *)SvRV(ST(2));
3107 ac = (AV *)SvRV(ST(3));
3108 dmeasure = (int)SvIV(ST(4));
3110 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3111 num = num <= av_len(ac) ? num : av_len(ac);
3113 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3114 xo = mymalloc( sizeof(int) * num );
3115 yo = mymalloc( sizeof(int) * num );
3116 ival = mymalloc( sizeof(i_color) * num );
3117 for(i = 0; i<num; i++) {
3118 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3119 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3120 sv = *av_fetch(ac, i, 0);
3121 if ( !sv_derived_from(sv, "Imager::Color") ) {
3122 free(axx); free(ayy); free(ac);
3123 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3125 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3127 i_gradgen(im, num, xo, yo, ival, dmeasure);
3133 i_diff_image(im, im2, mindist=0)
3139 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3149 double ssample_param
3153 i_fountain_seg *segs;
3155 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3156 croak("i_fountain: argument 11 must be an array ref");
3158 asegs = (AV *)SvRV(ST(10));
3159 segs = load_fount_segs(asegs, &count);
3160 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3161 ssample_param, count, segs);
3165 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3174 double ssample_param
3178 i_fountain_seg *segs;
3180 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3181 croak("i_fountain: argument 11 must be an array ref");
3183 asegs = (AV *)SvRV(ST(9));
3184 segs = load_fount_segs(asegs, &count);
3185 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3186 super_sample, ssample_param, count, segs);
3199 errors = i_errors();
3201 while (errors[i].msg) {
3203 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3204 if (!av_store(av, 0, sv)) {
3207 sv = newSViv(errors[i].code);
3208 if (!av_store(av, 1, sv)) {
3211 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3216 i_nearest_color(im, ...)
3231 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3232 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3233 croak("i_nearest_color: Second argument must be an array ref");
3234 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3235 croak("i_nearest_color: Third argument must be an array ref");
3236 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3237 croak("i_nearest_color: Fourth argument must be an array ref");
3238 axx = (AV *)SvRV(ST(1));
3239 ayy = (AV *)SvRV(ST(2));
3240 ac = (AV *)SvRV(ST(3));
3241 dmeasure = (int)SvIV(ST(4));
3243 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3244 num = num <= av_len(ac) ? num : av_len(ac);
3246 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3247 xo = mymalloc( sizeof(int) * num );
3248 yo = mymalloc( sizeof(int) * num );
3249 ival = mymalloc( sizeof(i_color) * num );
3250 for(i = 0; i<num; i++) {
3251 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3252 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3253 sv = *av_fetch(ac, i, 0);
3254 if ( !sv_derived_from(sv, "Imager::Color") ) {
3255 free(axx); free(ayy); free(ac);
3256 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3258 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3260 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3274 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3275 hv=(HV*)SvRV(ST(0));
3276 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3277 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3278 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3287 rc=DSO_open(filename,&evstr);
3291 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3292 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3295 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3301 DSO_close(dso_handle)
3305 DSO_funclist(dso_handle_v)
3309 DSO_handle *dso_handle;
3311 dso_handle=(DSO_handle*)dso_handle_v;
3313 while( dso_handle->function_list[i].name != NULL) {
3315 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3317 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3322 DSO_call(handle,func_index,hv)
3328 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3329 hv=(HV*)SvRV(ST(2));
3330 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3331 DSO_call( (DSO_handle *)handle,func_index,hv);
3335 # this is mostly for testing...
3336 # this function results in 'RETVAL' : unreferenced local variable
3337 # in VC++, and might be subtley wrong
3338 # the most obvious change may result in a double free so I'm leaving it
3341 i_get_pixel(im, x, y)
3348 color = (i_color *)mymalloc(sizeof(i_color));
3349 if (i_gpix(im, x, y, color) == 0) {
3350 ST(0) = sv_newmortal();
3351 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3355 ST(0) = &PL_sv_undef;
3360 i_ppix(im, x, y, cl)
3367 i_img_pal_new(x, y, channels, maxpal)
3374 i_img_to_pal(src, quant)
3380 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3381 croak("i_img_to_pal: second argument must be a hash ref");
3382 hv = (HV *)SvRV(ST(1));
3383 memset(&quant, 0, sizeof(quant));
3384 quant.mc_size = 256;
3385 handle_quant_opts(&quant, hv);
3386 RETVAL = i_img_to_pal(src, &quant);
3388 copy_colors_back(hv, &quant);
3390 cleanup_quant_opts(&quant);
3409 work = mymalloc((r-l) * sizeof(i_palidx));
3410 count = i_gpal(im, l, r, y, work);
3411 if (GIMME_V == G_ARRAY) {
3413 for (i = 0; i < count; ++i) {
3414 PUSHs(sv_2mortal(newSViv(work[i])));
3419 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3424 if (GIMME_V != G_ARRAY) {
3426 PUSHs(&PL_sv_undef);
3431 i_ppal(im, l, y, ...)
3440 work = mymalloc(sizeof(i_palidx) * (items-3));
3441 for (i=0; i < items-3; ++i) {
3442 work[i] = SvIV(ST(i+3));
3444 RETVAL = i_ppal(im, l, l+items-3, y, work);
3454 i_addcolors(im, ...)
3462 croak("i_addcolors: no colors to add");
3463 colors = mymalloc((items-1) * sizeof(i_color));
3464 for (i=0; i < items-1; ++i) {
3465 if (sv_isobject(ST(i+1))
3466 && sv_derived_from(ST(i+1), "Imager::Color")) {
3467 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3468 colors[i] = *INT2PTR(i_color *, tmp);
3472 croak("i_plin: pixels must be Imager::Color objects");
3475 index = i_addcolors(im, colors, items-1);
3478 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3480 else if (index == -1) {
3481 ST(0) = &PL_sv_undef;
3484 ST(0) = sv_2mortal(newSViv(index));
3488 i_setcolors(im, index, ...)
3496 croak("i_setcolors: no colors to add");
3497 colors = mymalloc((items-2) * sizeof(i_color));
3498 for (i=0; i < items-2; ++i) {
3499 if (sv_isobject(ST(i+2))
3500 && sv_derived_from(ST(i+2), "Imager::Color")) {
3501 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3502 colors[i] = *INT2PTR(i_color *, tmp);
3506 croak("i_setcolors: pixels must be Imager::Color objects");
3509 RETVAL = i_setcolors(im, index, colors, items-2);
3515 i_getcolors(im, index, ...)
3524 croak("i_getcolors: too many arguments");
3526 count = SvIV(ST(2));
3528 croak("i_getcolors: count must be positive");
3529 colors = mymalloc(sizeof(i_color) * count);
3530 if (i_getcolors(im, index, colors, count)) {
3531 for (i = 0; i < count; ++i) {
3533 SV *sv = sv_newmortal();
3534 pv = mymalloc(sizeof(i_color));
3536 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3549 count = i_colorcount(im);
3551 ST(0) = sv_2mortal(newSViv(count));
3554 ST(0) = &PL_sv_undef;
3563 count = i_maxcolors(im);
3565 ST(0) = sv_2mortal(newSViv(count));
3568 ST(0) = &PL_sv_undef;
3572 i_findcolor(im, color)
3578 if (i_findcolor(im, color, &index)) {
3579 ST(0) = sv_2mortal(newSViv(index));
3582 ST(0) = &PL_sv_undef;
3598 i_gsamp(im, l, r, y, ...)
3610 croak("No channel numbers supplied to g_samp()");
3612 chan_count = items - 4;
3613 chans = mymalloc(sizeof(int) * chan_count);
3614 for (i = 0; i < chan_count; ++i)
3615 chans[i] = SvIV(ST(i+4));
3616 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3617 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3619 if (GIMME_V == G_ARRAY) {
3621 for (i = 0; i < count; ++i)
3622 PUSHs(sv_2mortal(newSViv(data[i])));
3626 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3631 if (GIMME_V != G_ARRAY) {
3633 PUSHs(&PL_sv_undef);
3639 i_img_masked_new(targ, mask, x, y, w, h)
3649 if (!sv_isobject(ST(1))
3650 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3651 croak("i_img_masked_new: parameter 2 must undef or an image");
3653 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3657 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3662 i_plin(im, l, y, ...)
3671 work = mymalloc(sizeof(i_color) * (items-3));
3672 for (i=0; i < items-3; ++i) {
3673 if (sv_isobject(ST(i+3))
3674 && sv_derived_from(ST(i+3), "Imager::Color")) {
3675 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3676 work[i] = *INT2PTR(i_color *, tmp);
3680 croak("i_plin: pixels must be Imager::Color objects");
3684 RETVAL = i_plin(im, l, l+items-3, y, work);
3694 i_ppixf(im, x, y, cl)
3698 Imager::Color::Float cl
3701 i_gsampf(im, l, r, y, ...)
3713 croak("No channel numbers supplied to g_sampf()");
3715 chan_count = items - 4;
3716 chans = mymalloc(sizeof(int) * chan_count);
3717 for (i = 0; i < chan_count; ++i)
3718 chans[i] = SvIV(ST(i+4));
3719 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3720 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3721 if (GIMME_V == G_ARRAY) {
3723 for (i = 0; i < count; ++i)
3724 PUSHs(sv_2mortal(newSVnv(data[i])));
3728 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3732 if (GIMME_V != G_ARRAY) {
3734 PUSHs(&PL_sv_undef);
3739 i_plinf(im, l, y, ...)
3748 work = mymalloc(sizeof(i_fcolor) * (items-3));
3749 for (i=0; i < items-3; ++i) {
3750 if (sv_isobject(ST(i+3))
3751 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3752 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3753 work[i] = *INT2PTR(i_fcolor *, tmp);
3757 croak("i_plin: pixels must be Imager::Color::Float objects");
3761 RETVAL = i_plinf(im, l, l+items-3, y, work);
3778 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3779 if (i_gpixf(im, x, y, color) == 0) {
3780 ST(0) = sv_newmortal();
3781 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3785 ST(0) = &PL_sv_undef;
3799 vals = mymalloc((r-l) * sizeof(i_color));
3800 count = i_glin(im, l, r, y, vals);
3802 for (i = 0; i < count; ++i) {
3804 i_color *col = mymalloc(sizeof(i_color));
3805 sv = sv_newmortal();
3806 sv_setref_pv(sv, "Imager::Color", (void *)col);
3813 i_glinf(im, l, r, y)
3823 vals = mymalloc((r-l) * sizeof(i_fcolor));
3824 count = i_glinf(im, l, r, y, vals);
3826 for (i = 0; i < count; ++i) {
3828 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3830 sv = sv_newmortal();
3831 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3838 i_img_16_new(x, y, ch)
3844 i_img_double_new(x, y, ch)
3850 i_tags_addn(im, name, code, idata)
3859 name = SvPV(ST(1), len);
3862 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3867 i_tags_add(im, name, code, data, idata)
3877 name = SvPV(ST(1), len);
3881 data = SvPV(ST(3), len);
3886 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3891 i_tags_find(im, name, start)
3898 if (i_tags_find(&im->tags, name, start, &entry)) {
3900 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3902 ST(0) = sv_2mortal(newSViv(entry));
3904 ST(0) = &PL_sv_undef;
3908 i_tags_findn(im, code, start)
3915 if (i_tags_findn(&im->tags, code, start, &entry)) {
3917 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3919 ST(0) = sv_2mortal(newSViv(entry));
3922 ST(0) = &PL_sv_undef;
3925 i_tags_delete(im, entry)
3929 RETVAL = i_tags_delete(&im->tags, entry);
3934 i_tags_delbyname(im, name)
3938 RETVAL = i_tags_delbyname(&im->tags, name);
3943 i_tags_delbycode(im, code)
3947 RETVAL = i_tags_delbycode(&im->tags, code);
3952 i_tags_get(im, index)
3956 if (index >= 0 && index < im->tags.count) {
3957 i_img_tag *entry = im->tags.tags + index;
3961 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3964 PUSHs(sv_2mortal(newSViv(entry->code)));
3967 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3970 PUSHs(sv_2mortal(newSViv(entry->idata)));
3978 RETVAL = im->tags.count;
3985 i_wf_bbox(face, size, text)
3990 int cords[BOUNDING_BOX_COUNT];
3993 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3995 for (i = 0; i < rc; ++i)
3996 PUSHs(sv_2mortal(newSViv(cords[i])));
4000 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4011 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4017 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4028 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4038 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4040 #define FT2_DESTROY(font) i_ft2_destroy(font)
4044 Imager::Font::FT2 font
4046 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4049 i_ft2_new(name, index)
4054 i_ft2_setdpi(font, xdpi, ydpi)
4055 Imager::Font::FT2 font
4061 Imager::Font::FT2 font
4065 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4067 PUSHs(sv_2mortal(newSViv(xdpi)));
4068 PUSHs(sv_2mortal(newSViv(ydpi)));
4072 i_ft2_sethinting(font, hinting)
4073 Imager::Font::FT2 font
4077 i_ft2_settransform(font, matrix)
4078 Imager::Font::FT2 font
4086 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4087 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4088 av=(AV*)SvRV(ST(1));
4092 for (i = 0; i < len; ++i) {
4093 sv1=(*(av_fetch(av,i,0)));
4094 matrix[i] = SvNV(sv1);
4098 RETVAL = i_ft2_settransform(font, matrix);
4103 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4104 Imager::Font::FT2 font
4110 int bbox[BOUNDING_BOX_COUNT];
4116 text = SvPV(text_sv, text_len);
4118 if (SvUTF8(text_sv))
4121 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4124 for (i = 0; i < rc; ++i)
4125 PUSHs(sv_2mortal(newSViv(bbox[i])));
4129 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4130 Imager::Font::FT2 font
4144 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4147 for (i = 0; i < 8; ++i)
4148 PUSHs(sv_2mortal(newSViv(bbox[i])));
4152 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4153 Imager::Font::FT2 font
4169 if (SvUTF8(ST(7))) {
4173 text = SvPV(ST(7), len);
4174 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4175 len, align, aa, vlayout, utf8);
4180 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4181 Imager::Font::FT2 font
4198 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4199 strlen(text), align, aa, vlayout, 1);
4204 ft2_transform_box(font, x0, x1, x2, x3)
4205 Imager::Font::FT2 font
4213 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4214 ft2_transform_box(font, box);
4216 PUSHs(sv_2mortal(newSViv(box[0])));
4217 PUSHs(sv_2mortal(newSViv(box[1])));
4218 PUSHs(sv_2mortal(newSViv(box[2])));
4219 PUSHs(sv_2mortal(newSViv(box[3])));
4222 i_ft2_has_chars(handle, text_sv, utf8)
4223 Imager::Font::FT2 handle
4234 if (SvUTF8(text_sv))
4237 text = SvPV(text_sv, len);
4238 work = mymalloc(len);
4239 count = i_ft2_has_chars(handle, text, len, utf8, work);
4240 if (GIMME_V == G_ARRAY) {
4242 for (i = 0; i < count; ++i) {
4243 PUSHs(sv_2mortal(newSViv(work[i])));
4248 PUSHs(sv_2mortal(newSVpv(work, count)));
4253 i_ft2_face_name(handle)
4254 Imager::Font::FT2 handle
4259 len = i_ft2_face_name(handle, name, sizeof(name));
4262 PUSHs(sv_2mortal(newSVpv(name, 0)));
4266 i_ft2_can_face_name()
4269 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4270 Imager::Font::FT2 handle
4282 if (SvUTF8(text_sv))
4285 text = SvPV(text_sv, work_len);
4290 ch = i_utf8_advance(&text, &len);
4292 i_push_error(0, "invalid UTF8 character");
4301 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4303 PUSHs(sv_2mortal(newSVpv(name, 0)));
4306 PUSHs(&PL_sv_undef);
4311 i_ft2_can_do_glyph_names()
4314 i_ft2_face_has_glyph_names(handle)
4315 Imager::Font::FT2 handle
4319 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4323 Imager::FillHandle fill
4325 MODULE = Imager PACKAGE = Imager
4328 i_new_fill_solid(cl, combine)
4333 i_new_fill_solidf(cl, combine)
4334 Imager::Color::Float cl
4338 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4346 unsigned char *cust_hatch;
4350 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4354 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4359 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4360 Imager::Color::Float fg
4361 Imager::Color::Float bg
4367 unsigned char *cust_hatch;
4371 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4375 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4380 i_new_fill_image(src, matrix, xoff, yoff, combine)
4397 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4398 croak("i_new_fill_image: parameter must be an arrayref");
4399 av=(AV*)SvRV(ST(1));
4403 for (i = 0; i < len; ++i) {
4404 sv1=(*(av_fetch(av,i,0)));
4405 matrix[i] = SvNV(sv1);
4411 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);