7 #define NEED_newRV_noinc
8 #define NEED_sv_2pv_nolen
14 #define i_int_hlines_testing() 1
22 #if i_int_hlines_testing()
28 /* These functions are all shared - then comes platform dependant code */
29 static int getstr(void *hv_t,char *key,char **store) {
33 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
35 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
37 svpp=hv_fetch(hv, key, strlen(key), 0);
38 *store=SvPV(*svpp, PL_na );
43 static int getint(void *hv_t,char *key,int *store) {
47 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
49 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
51 svpp=hv_fetch(hv, key, strlen(key), 0);
52 *store=(int)SvIV(*svpp);
56 static int getdouble(void *hv_t,char* key,double *store) {
60 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
62 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
63 svpp=hv_fetch(hv, key, strlen(key), 0);
64 *store=(float)SvNV(*svpp);
68 static int getvoid(void *hv_t,char* key,void **store) {
72 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
74 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
76 svpp=hv_fetch(hv, key, strlen(key), 0);
77 *store = INT2PTR(void*, SvIV(*svpp));
82 static int getobj(void *hv_t,char *key,char *type,void **store) {
86 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
88 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
90 svpp=hv_fetch(hv, key, strlen(key), 0);
92 if (sv_derived_from(*svpp,type)) {
93 IV tmp = SvIV((SV*)SvRV(*svpp));
94 *store = INT2PTR(void*, tmp);
96 mm_log((1,"getobj: key exists in hash but is not of correct type"));
103 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
105 void my_SvREFCNT_dec(void *p) {
106 SvREFCNT_dec((SV*)p);
111 i_log_entry(char *string, int level) {
112 mm_log((level, string));
116 typedef struct i_reader_data_tag
118 /* presumably a CODE ref or name of a sub */
122 /* used by functions that want callbacks */
123 static int read_callback(char *userdata, char *buffer, int need, int want) {
124 i_reader_data *rd = (i_reader_data *)userdata;
128 dSP; dTARG = sv_newmortal();
129 /* thanks to Simon Cozens for help with the dTARG above */
139 count = perl_call_sv(rd->sv, G_SCALAR);
144 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
150 char *ptr = SvPV(data, len);
152 croak("Too much data returned in reader callback");
154 memcpy(buffer, ptr, len);
170 SV *sv; /* a coderef or sub name */
173 /* used by functions that want callbacks */
174 static int write_callback(char *userdata, char const *data, int size) {
175 i_writer_data *wd = (i_writer_data *)userdata;
185 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
188 count = perl_call_sv(wd->sv, G_SCALAR);
193 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
196 success = SvTRUE(sv);
206 #define CBDATA_BUFSIZE 8192
209 /* the SVs we use to call back to Perl */
215 /* we need to remember whether the buffer contains write data or
221 /* how far we've read into the buffer (not used for writing) */
224 /* the amount of space used/data available in the buffer */
227 /* the maximum amount to fill the buffer before flushing
228 If any write is larger than this then the buffer is flushed and
229 the full write is performed. The write is _not_ split into
234 char buffer[CBDATA_BUFSIZE];
239 call_writer(cbd, buf, size)
241 Low-level function to call the perl writer callback.
245 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
251 if (!SvOK(cbd->writecb))
258 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
261 count = perl_call_sv(cbd->writecb, G_SCALAR);
265 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
268 success = SvTRUE(sv);
275 return success ? size : -1;
278 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
285 if (!SvOK(cbd->readcb))
292 PUSHs(sv_2mortal(newSViv(size)));
293 PUSHs(sv_2mortal(newSViv(maxread)));
296 count = perl_call_sv(cbd->readcb, G_SCALAR);
301 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
307 char *ptr = SvPV(data, len);
309 croak("Too much data returned in reader callback");
311 memcpy(buf, ptr, len);
325 static ssize_t write_flush(struct cbdata *cbd) {
329 result = call_writer(cbd, cbd->buffer, cbd->used);
334 return 1; /* success of some sort */
338 static off_t io_seeker(void *p, off_t offset, int whence) {
339 struct cbdata *cbd = p;
344 if (!SvOK(cbd->seekcb))
348 if (cbd->used && write_flush(cbd) <= 0)
352 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
353 offset -= cbd->where - cbd->used;
356 cbd->where = cbd->used = 0;
362 PUSHs(sv_2mortal(newSViv(offset)));
363 PUSHs(sv_2mortal(newSViv(whence)));
366 count = perl_call_sv(cbd->seekcb, G_SCALAR);
371 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
382 static ssize_t io_writer(void *p, void const *data, size_t size) {
383 struct cbdata *cbd = p;
385 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
387 if (cbd->reading && cbd->where < cbd->used) {
388 /* we read past the place where the caller expected us to be
389 so adjust our position a bit */
390 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
395 cbd->where = cbd->used = 0;
398 if (cbd->used && cbd->used + size > cbd->maxlength) {
399 int write_res = write_flush(cbd);
400 if (write_res <= 0) {
405 if (cbd->used+size <= cbd->maxlength) {
406 memcpy(cbd->buffer + cbd->used, data, size);
410 /* it doesn't fit - just pass it up */
411 return call_writer(cbd, data, size);
415 io_reader(void *p, void *data, size_t size) {
416 struct cbdata *cbd = p;
418 char *out = data; /* so we can do pointer arithmetic */
420 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
422 if (write_flush(cbd) <= 0)
428 if (size <= cbd->used - cbd->where) {
430 memcpy(data, cbd->buffer+cbd->where, size);
435 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
436 total += cbd->used - cbd->where;
437 size -= cbd->used - cbd->where;
438 out += cbd->used - cbd->where;
439 if (size < sizeof(cbd->buffer)) {
443 && (did_read = call_reader(cbd, cbd->buffer, size,
444 sizeof(cbd->buffer))) > 0) {
446 cbd->used = did_read;
448 copy_size = i_min(size, cbd->used);
449 memcpy(out, cbd->buffer, copy_size);
450 cbd->where += copy_size;
459 /* just read the rest - too big for our buffer*/
461 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
473 static int io_closer(void *p) {
474 struct cbdata *cbd = p;
476 if (cbd->writing && cbd->used > 0) {
477 if (write_flush(cbd) < 0)
482 if (SvOK(cbd->closecb)) {
490 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);
515 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
518 for (i = 0; i < count; ++i)
519 if (strEQ(names[i].name, name))
520 return names[i].value;
524 static struct value_name transp_names[] =
527 { "threshold", tr_threshold },
528 { "errdiff", tr_errdiff },
529 { "ordered", tr_ordered, },
532 static struct value_name make_color_names[] =
534 { "none", mc_none, },
535 { "webmap", mc_web_map, },
536 { "addi", mc_addi, },
537 { "mediancut", mc_median_cut, },
538 { "mono", mc_mono, },
539 { "monochrome", mc_mono, },
542 static struct value_name translate_names[] =
545 { "giflib", pt_giflib, },
547 { "closest", pt_closest, },
548 { "perturb", pt_perturb, },
549 { "errdiff", pt_errdiff, },
552 static struct value_name errdiff_names[] =
554 { "floyd", ed_floyd, },
555 { "jarvis", ed_jarvis, },
556 { "stucki", ed_stucki, },
557 { "custom", ed_custom, },
560 static struct value_name orddith_names[] =
562 { "random", od_random, },
563 { "dot8", od_dot8, },
564 { "dot4", od_dot4, },
565 { "hline", od_hline, },
566 { "vline", od_vline, },
567 { "/line", od_slashline, },
568 { "slashline", od_slashline, },
569 { "\\line", od_backline, },
570 { "backline", od_backline, },
571 { "tiny", od_tiny, },
572 { "custom", od_custom, },
575 /* look through the hash for quantization options */
576 static void handle_quant_opts(i_quantize *quant, HV *hv)
578 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
584 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
586 sv = hv_fetch(hv, "transp", 6, 0);
587 if (sv && *sv && (str = SvPV(*sv, len))) {
589 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
591 if (quant->transp != tr_none) {
592 quant->tr_threshold = 127;
593 sv = hv_fetch(hv, "tr_threshold", 12, 0);
595 quant->tr_threshold = SvIV(*sv);
597 if (quant->transp == tr_errdiff) {
598 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
599 if (sv && *sv && (str = SvPV(*sv, len)))
600 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
602 if (quant->transp == tr_ordered) {
603 quant->tr_orddith = od_tiny;
604 sv = hv_fetch(hv, "tr_orddith", 10, 0);
605 if (sv && *sv && (str = SvPV(*sv, len)))
606 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
608 if (quant->tr_orddith == od_custom) {
609 sv = hv_fetch(hv, "tr_map", 6, 0);
610 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
611 AV *av = (AV*)SvRV(*sv);
612 len = av_len(av) + 1;
613 if (len > sizeof(quant->tr_custom))
614 len = sizeof(quant->tr_custom);
615 for (i = 0; i < len; ++i) {
616 SV **sv2 = av_fetch(av, i, 0);
618 quant->tr_custom[i] = SvIV(*sv2);
621 while (i < sizeof(quant->tr_custom))
622 quant->tr_custom[i++] = 0;
627 quant->make_colors = mc_addi;
628 sv = hv_fetch(hv, "make_colors", 11, 0);
629 if (sv && *sv && (str = SvPV(*sv, len))) {
631 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
633 sv = hv_fetch(hv, "colors", 6, 0);
634 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
635 /* needs to be an array of Imager::Color
636 note that the caller allocates the mc_color array and sets mc_size
638 AV *av = (AV *)SvRV(*sv);
639 quant->mc_count = av_len(av)+1;
640 if (quant->mc_count > quant->mc_size)
641 quant->mc_count = quant->mc_size;
642 for (i = 0; i < quant->mc_count; ++i) {
643 SV **sv1 = av_fetch(av, i, 0);
644 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
645 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
646 quant->mc_colors[i] = *col;
650 sv = hv_fetch(hv, "max_colors", 10, 0);
653 if (i <= quant->mc_size && i >= quant->mc_count)
657 quant->translate = pt_closest;
658 sv = hv_fetch(hv, "translate", 9, 0);
659 if (sv && *sv && (str = SvPV(*sv, len))) {
660 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
662 sv = hv_fetch(hv, "errdiff", 7, 0);
663 if (sv && *sv && (str = SvPV(*sv, len))) {
664 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
666 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
667 /* get the error diffusion map */
668 sv = hv_fetch(hv, "errdiff_width", 13, 0);
670 quant->ed_width = SvIV(*sv);
671 sv = hv_fetch(hv, "errdiff_height", 14, 0);
673 quant->ed_height = SvIV(*sv);
674 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
676 quant->ed_orig = SvIV(*sv);
677 if (quant->ed_width > 0 && quant->ed_height > 0) {
679 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
680 sv = hv_fetch(hv, "errdiff_map", 11, 0);
681 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
682 AV *av = (AV*)SvRV(*sv);
683 len = av_len(av) + 1;
684 if (len > quant->ed_width * quant->ed_height)
685 len = quant->ed_width * quant->ed_height;
686 for (i = 0; i < len; ++i) {
687 SV **sv2 = av_fetch(av, i, 0);
689 quant->ed_map[i] = SvIV(*sv2);
690 sum += quant->ed_map[i];
696 myfree(quant->ed_map);
698 quant->errdiff = ed_floyd;
702 sv = hv_fetch(hv, "perturb", 7, 0);
704 quant->perturb = SvIV(*sv);
707 static void cleanup_quant_opts(i_quantize *quant) {
708 myfree(quant->mc_colors);
710 myfree(quant->ed_map);
713 /* copies the color map from the hv into the colors member of the HV */
714 static void copy_colors_back(HV *hv, i_quantize *quant) {
720 sv = hv_fetch(hv, "colors", 6, 0);
721 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
724 ref = newRV_inc((SV*) av);
725 sv = hv_store(hv, "colors", 6, ref, 0);
728 av = (AV *)SvRV(*sv);
730 av_extend(av, quant->mc_count+1);
731 for (i = 0; i < quant->mc_count; ++i) {
732 i_color *in = quant->mc_colors+i;
733 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
734 work = sv_newmortal();
735 sv_setref_pv(work, "Imager::Color", (void *)c);
737 if (!av_store(av, i, work)) {
743 /* loads the segments of a fountain fill into an array */
744 static i_fountain_seg *
745 load_fount_segs(AV *asegs, int *count) {
746 /* Each element of segs must contain:
747 [ start, middle, end, c0, c1, segtype, colortrans ]
748 start, middle, end are doubles from 0 to 1
749 c0, c1 are Imager::Color::Float or Imager::Color objects
750 segtype, colortrans are ints
754 i_fountain_seg *segs;
758 *count = av_len(asegs)+1;
760 croak("i_fountain must have at least one segment");
761 segs = mymalloc(sizeof(i_fountain_seg) * *count);
762 for(i = 0; i < *count; i++) {
763 SV **sv1 = av_fetch(asegs, i, 0);
764 if (!sv1 || !*sv1 || !SvROK(*sv1)
765 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
767 croak("i_fountain: segs must be an arrayref of arrayrefs");
769 aseg = (AV *)SvRV(*sv1);
770 if (av_len(aseg) != 7-1) {
772 croak("i_fountain: a segment must have 7 members");
774 for (j = 0; j < 3; ++j) {
775 SV **sv2 = av_fetch(aseg, j, 0);
778 croak("i_fountain: XS error");
780 work[j] = SvNV(*sv2);
782 segs[i].start = work[0];
783 segs[i].middle = work[1];
784 segs[i].end = work[2];
785 for (j = 0; j < 2; ++j) {
786 SV **sv3 = av_fetch(aseg, 3+j, 0);
787 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
788 (!sv_derived_from(*sv3, "Imager::Color")
789 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
791 croak("i_fountain: segs must contain colors in elements 3 and 4");
793 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
794 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
797 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
799 for (ch = 0; ch < MAXCHANNELS; ++ch) {
800 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
804 for (j = 0; j < 2; ++j) {
805 SV **sv2 = av_fetch(aseg, j+5, 0);
808 croak("i_fountain: XS error");
810 worki[j] = SvIV(*sv2);
812 segs[i].type = worki[0];
813 segs[i].color = worki[1];
819 /* validates the indexes supplied to i_ppal
821 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
826 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
827 int color_count = i_colorcount(im);
830 if (color_count == -1)
831 croak("i_plin() called on direct color image");
833 for (i = 0; i < count; ++i) {
834 if (indexes[i] >= color_count) {
835 croak("i_plin() called with out of range color index %d (max %d)",
836 indexes[i], color_count-1);
842 /* I don't think ICLF_* names belong at the C interface
843 this makes the XS code think we have them, to let us avoid
844 putting function bodies in the XS code
846 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
847 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
850 /* the m_init_log() function was called init_log(), renamed to reduce
851 potential naming conflicts */
852 #define init_log m_init_log
854 #if i_int_hlines_testing()
856 typedef i_int_hlines *Imager__Internal__Hlines;
858 static i_int_hlines *
859 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
860 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
861 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
866 static i_int_hlines *
867 i_int_hlines_new_img(i_img *im) {
868 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
869 i_int_init_hlines_img(result, im);
875 i_int_hlines_DESTROY(i_int_hlines *hlines) {
876 i_int_hlines_destroy(hlines);
880 static int seg_compare(const void *vleft, const void *vright) {
881 const i_int_hline_seg *left = vleft;
882 const i_int_hline_seg *right = vright;
884 return left->minx - right->minx;
888 i_int_hlines_dump(i_int_hlines *hlines) {
889 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
890 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
893 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
894 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
897 /* sort the segments, if any */
899 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
901 sv_catpvf(dump, " %d (%d):", y, entry->count);
902 for (i = 0; i < entry->count; ++i) {
903 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
904 entry->segs[i].x_limit);
906 sv_catpv(dump, "\n");
916 #define i_exif_enabled() 1
918 #define i_exif_enabled() 0
921 /* trying to use more C style names, map them here */
922 #define i_io_DESTROY(ig) io_glue_destroy(ig)
924 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
927 ICL_new_internal(r,g,b,a)
939 ICL_set_internal(cl,r,g,b,a)
946 ICL_set_internal(cl, r, g, b, a);
960 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
961 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
962 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
963 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
969 RETVAL = mymalloc(sizeof(i_color));
971 i_hsv_to_rgb(RETVAL);
979 RETVAL = mymalloc(sizeof(i_color));
981 i_rgb_to_hsv(RETVAL);
987 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
990 ICLF_new_internal(r, g, b, a)
998 Imager::Color::Float cl
1002 Imager::Color::Float cl
1006 EXTEND(SP, MAXCHANNELS);
1007 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1008 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1009 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1013 ICLF_set_internal(cl,r,g,b,a)
1014 Imager::Color::Float cl
1027 Imager::Color::Float
1029 Imager::Color::Float c
1031 RETVAL = mymalloc(sizeof(i_fcolor));
1033 i_hsv_to_rgbf(RETVAL);
1037 Imager::Color::Float
1039 Imager::Color::Float c
1041 RETVAL = mymalloc(sizeof(i_fcolor));
1043 i_rgb_to_hsvf(RETVAL);
1047 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1061 MODULE = Imager PACKAGE = Imager
1080 SvPV(ST(0), length);
1081 SvREFCNT_inc(ST(0));
1082 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1087 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1096 cbd = mymalloc(sizeof(struct cbdata));
1097 SvREFCNT_inc(writecb);
1098 cbd->writecb = writecb;
1099 SvREFCNT_inc(readcb);
1100 cbd->readcb = readcb;
1101 SvREFCNT_inc(seekcb);
1102 cbd->seekcb = seekcb;
1103 SvREFCNT_inc(closecb);
1104 cbd->closecb = closecb;
1105 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1106 if (maxwrite > CBDATA_BUFSIZE)
1107 maxwrite = CBDATA_BUFSIZE;
1108 cbd->maxlength = maxwrite;
1109 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1118 unsigned char* data;
1122 tlength = io_slurp(ig, &data);
1124 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1129 i_set_image_file_limits(width, height, bytes)
1135 i_get_image_file_limits()
1137 int width, height, bytes;
1139 if (i_get_image_file_limits(&width, &height, &bytes)) {
1141 PUSHs(sv_2mortal(newSViv(width)));
1142 PUSHs(sv_2mortal(newSViv(height)));
1143 PUSHs(sv_2mortal(newSViv(bytes)));
1146 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1149 i_io_write(ig, data_sv)
1157 if (SvUTF8(data_sv)) {
1158 data_sv = sv_2mortal(newSVsv(data_sv));
1159 /* yes, we want this to croak() if the SV can't be downgraded */
1160 sv_utf8_downgrade(data_sv, FALSE);
1163 data = SvPV(data_sv, size);
1164 RETVAL = i_io_write(ig, data, size);
1169 i_io_read(ig, buffer_sv, size)
1178 croak("size negative in call to i_io_read()");
1179 /* prevent an undefined value warning if they supplied an
1181 Orginally conditional on !SvOK(), but this will prevent the
1182 downgrade from croaking */
1183 sv_setpvn(buffer_sv, "", 0);
1185 if (SvUTF8(buffer_sv))
1186 sv_utf8_downgrade(buffer_sv, FALSE);
1188 buffer = SvGROW(buffer_sv, size+1);
1189 result = i_io_read(ig, buffer, size);
1191 SvCUR_set(buffer_sv, result);
1192 *SvEND(buffer_sv) = '\0';
1193 SvPOK_only(buffer_sv);
1195 PUSHs(sv_2mortal(newSViv(result)));
1201 i_io_read2(ig, size)
1210 croak("size negative in call to i_io_read2()");
1211 buffer_sv = newSV(size);
1212 buffer = SvGROW(buffer_sv, size+1);
1213 result = i_io_read(ig, buffer, size);
1215 SvCUR_set(buffer_sv, result);
1216 *SvEND(buffer_sv) = '\0';
1217 SvPOK_only(buffer_sv);
1219 PUSHs(sv_2mortal(buffer_sv));
1223 SvREFCNT_dec(buffer_sv);
1227 i_io_seek(ig, position, whence)
1240 MODULE = Imager PACKAGE = Imager
1251 while( (item=i_format_list[i++]) != NULL ) {
1253 PUSHs(sv_2mortal(newSVpv(item,0)));
1270 i_img_empty_ch(im,x,y,ch)
1277 i_sametype(im, x, y)
1283 i_sametype_chans(im, x, y, channels)
1290 i_init_log(name,level)
1295 i_log_entry(string,level)
1314 i_img_info(im,info);
1316 PUSHs(sv_2mortal(newSViv(info[0])));
1317 PUSHs(sv_2mortal(newSViv(info[1])));
1318 PUSHs(sv_2mortal(newSViv(info[2])));
1319 PUSHs(sv_2mortal(newSViv(info[3])));
1325 i_img_setmask(im,ch_mask)
1334 i_img_getchannels(im)
1343 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1348 i_line(im,x1,y1,x2,y2,val,endp)
1358 i_line_aa(im,x1,y1,x2,y2,val,endp)
1368 i_box(im,x1,y1,x2,y2,val)
1377 i_box_filled(im,x1,y1,x2,y2,val)
1386 i_box_cfill(im,x1,y1,x2,y2,fill)
1392 Imager::FillHandle fill
1395 i_arc(im,x,y,rad,d1,d2,val)
1405 i_arc_aa(im,x,y,rad,d1,d2,val)
1415 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1422 Imager::FillHandle fill
1425 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1432 Imager::FillHandle fill
1436 i_circle_aa(im,x,y,rad,val)
1446 i_bezier_multi(im,xc,yc,val)
1459 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1460 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1461 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1462 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1463 av1=(AV*)SvRV(ST(1));
1464 av2=(AV*)SvRV(ST(2));
1465 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1467 x=mymalloc( len*sizeof(double) );
1468 y=mymalloc( len*sizeof(double) );
1469 for(i=0;i<len;i++) {
1470 sv1=(*(av_fetch(av1,i,0)));
1471 sv2=(*(av_fetch(av2,i,0)));
1472 x[i]=(double)SvNV(sv1);
1473 y[i]=(double)SvNV(sv2);
1475 i_bezier_multi(im,len,x,y,val);
1481 i_poly_aa(im,xc,yc,val)
1494 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1495 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1496 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1497 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1498 av1=(AV*)SvRV(ST(1));
1499 av2=(AV*)SvRV(ST(2));
1500 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1502 x=mymalloc( len*sizeof(double) );
1503 y=mymalloc( len*sizeof(double) );
1504 for(i=0;i<len;i++) {
1505 sv1=(*(av_fetch(av1,i,0)));
1506 sv2=(*(av_fetch(av2,i,0)));
1507 x[i]=(double)SvNV(sv1);
1508 y[i]=(double)SvNV(sv2);
1510 i_poly_aa(im,len,x,y,val);
1515 i_poly_aa_cfill(im,xc,yc,fill)
1517 Imager::FillHandle fill
1527 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1528 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1529 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1530 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1531 av1=(AV*)SvRV(ST(1));
1532 av2=(AV*)SvRV(ST(2));
1533 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1535 x=mymalloc( len*sizeof(double) );
1536 y=mymalloc( len*sizeof(double) );
1537 for(i=0;i<len;i++) {
1538 sv1=(*(av_fetch(av1,i,0)));
1539 sv2=(*(av_fetch(av2,i,0)));
1540 x[i]=(double)SvNV(sv1);
1541 y[i]=(double)SvNV(sv2);
1543 i_poly_aa_cfill(im,len,x,y,fill);
1550 i_flood_fill(im,seedx,seedy,dcol)
1557 i_flood_cfill(im,seedx,seedy,fill)
1561 Imager::FillHandle fill
1564 i_flood_fill_border(im,seedx,seedy,dcol, border)
1569 Imager::Color border
1572 i_flood_cfill_border(im,seedx,seedy,fill, border)
1576 Imager::FillHandle fill
1577 Imager::Color border
1581 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1593 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1610 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1622 i_flipxy(im, direction)
1627 i_rotate90(im, degrees)
1632 i_rotate_exact(im, amount, ...)
1636 i_color *backp = NULL;
1637 i_fcolor *fbackp = NULL;
1641 /* extract the bg colors if any */
1642 /* yes, this is kind of strange */
1643 for (i = 2; i < items; ++i) {
1645 if (sv_derived_from(sv1, "Imager::Color")) {
1646 IV tmp = SvIV((SV*)SvRV(sv1));
1647 backp = INT2PTR(i_color *, tmp);
1649 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1650 IV tmp = SvIV((SV*)SvRV(sv1));
1651 fbackp = INT2PTR(i_fcolor *, tmp);
1654 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1659 i_matrix_transform(im, xsize, ysize, matrix, ...)
1669 i_color *backp = NULL;
1670 i_fcolor *fbackp = NULL;
1672 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1673 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1674 av=(AV*)SvRV(ST(3));
1678 for (i = 0; i < len; ++i) {
1679 sv1=(*(av_fetch(av,i,0)));
1680 matrix[i] = SvNV(sv1);
1684 /* extract the bg colors if any */
1685 /* yes, this is kind of strange */
1686 for (i = 4; i < items; ++i) {
1688 if (sv_derived_from(sv1, "Imager::Color")) {
1689 IV tmp = SvIV((SV*)SvRV(sv1));
1690 backp = INT2PTR(i_color *, tmp);
1692 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1693 IV tmp = SvIV((SV*)SvRV(sv1));
1694 fbackp = INT2PTR(i_fcolor *, tmp);
1697 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1702 i_gaussian(im,stdev)
1707 i_unsharp_mask(im,stdev,scale)
1722 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1723 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1724 av=(AV*)SvRV(ST(1));
1726 coeff=mymalloc( len*sizeof(float) );
1727 for(i=0;i<len;i++) {
1728 sv1=(*(av_fetch(av,i,0)));
1729 coeff[i]=(float)SvNV(sv1);
1731 i_conv(im,coeff,len);
1735 i_convert(im, src, coeff)
1748 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1749 croak("i_convert: parameter 3 must be an arrayref\n");
1750 avmain = (AV*)SvRV(ST(2));
1751 outchan = av_len(avmain)+1;
1752 /* find the biggest */
1754 for (j=0; j < outchan; ++j) {
1755 temp = av_fetch(avmain, j, 0);
1756 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1757 avsub = (AV*)SvRV(*temp);
1758 len = av_len(avsub)+1;
1763 coeff = mymalloc(sizeof(float) * outchan * inchan);
1764 for (j = 0; j < outchan; ++j) {
1765 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1766 len = av_len(avsub)+1;
1767 for (i = 0; i < len; ++i) {
1768 temp = av_fetch(avsub, i, 0);
1770 coeff[i+j*inchan] = SvNV(*temp);
1772 coeff[i+j*inchan] = 0;
1775 coeff[i++ + j*inchan] = 0;
1777 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1787 unsigned int mask = 0;
1793 unsigned char (*maps)[256];
1795 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1796 croak("i_map: parameter 2 must be an arrayref\n");
1797 avmain = (AV*)SvRV(ST(1));
1798 len = av_len(avmain)+1;
1799 if (im->channels < len) len = im->channels;
1801 maps = mymalloc( len * sizeof(unsigned char [256]) );
1803 for (j=0; j<len ; j++) {
1804 temp = av_fetch(avmain, j, 0);
1805 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1806 avsub = (AV*)SvRV(*temp);
1807 if(av_len(avsub) != 255) continue;
1809 for (i=0; i<256 ; i++) {
1811 temp = av_fetch(avsub, i, 0);
1812 val = temp ? SvIV(*temp) : 0;
1814 if (val>255) val = 255;
1819 i_map(im, maps, mask);
1832 i_init_fonts(t1log=0)
1847 i_t1_destroy(font_id)
1852 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1871 str = SvPV(str_sv, len);
1872 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1879 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1888 int cords[BOUNDING_BOX_COUNT];
1896 str = SvPV(str_sv, len);
1897 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1900 for (i = 0; i < rc; ++i)
1901 PUSHs(sv_2mortal(newSViv(cords[i])));
1907 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1926 str = SvPV(str_sv, len);
1927 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1933 i_t1_has_chars(handle, text_sv, utf8 = 0)
1945 if (SvUTF8(text_sv))
1948 text = SvPV(text_sv, len);
1949 work = mymalloc(len);
1950 count = i_t1_has_chars(handle, text, len, utf8, work);
1951 if (GIMME_V == G_ARRAY) {
1953 for (i = 0; i < count; ++i) {
1954 PUSHs(sv_2mortal(newSViv(work[i])));
1959 PUSHs(sv_2mortal(newSVpv(work, count)));
1964 i_t1_face_name(handle)
1970 len = i_t1_face_name(handle, name, sizeof(name));
1973 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1977 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1988 if (SvUTF8(text_sv))
1991 text = SvPV(text_sv, work_len);
1996 ch = i_utf8_advance(&text, &len);
1998 i_push_error(0, "invalid UTF8 character");
2007 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
2008 PUSHs(sv_2mortal(newSVpv(name, 0)));
2011 PUSHs(&PL_sv_undef);
2025 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2027 #define TT_DESTROY(handle) i_tt_destroy(handle)
2031 Imager::Font::TT handle
2034 MODULE = Imager PACKAGE = Imager
2038 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2039 Imager::Font::TT handle
2057 str = SvPV(str_sv, len);
2058 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2059 len, smooth, utf8, align);
2065 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2066 Imager::Font::TT handle
2084 str = SvPV(str_sv, len);
2085 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2086 smooth, utf8, align);
2092 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2093 Imager::Font::TT handle
2098 int cords[BOUNDING_BOX_COUNT],rc;
2107 str = SvPV(str_sv, len);
2108 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2110 for (i = 0; i < rc; ++i) {
2111 PUSHs(sv_2mortal(newSViv(cords[i])));
2116 i_tt_has_chars(handle, text_sv, utf8)
2117 Imager::Font::TT handle
2128 if (SvUTF8(text_sv))
2131 text = SvPV(text_sv, len);
2132 work = mymalloc(len);
2133 count = i_tt_has_chars(handle, text, len, utf8, work);
2134 if (GIMME_V == G_ARRAY) {
2136 for (i = 0; i < count; ++i) {
2137 PUSHs(sv_2mortal(newSViv(work[i])));
2142 PUSHs(sv_2mortal(newSVpv(work, count)));
2147 i_tt_dump_names(handle)
2148 Imager::Font::TT handle
2151 i_tt_face_name(handle)
2152 Imager::Font::TT handle
2157 len = i_tt_face_name(handle, name, sizeof(name));
2160 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2164 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2165 Imager::Font::TT handle
2176 if (SvUTF8(text_sv))
2179 text = SvPV(text_sv, work_len);
2184 ch = i_utf8_advance(&text, &len);
2186 i_push_error(0, "invalid UTF8 character");
2195 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2196 PUSHs(sv_2mortal(newSVpv(name, 0)));
2199 PUSHs(&PL_sv_undef);
2208 i_writejpeg_wiol(im, ig, qfactor)
2224 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2225 if (iptc_itext == NULL) {
2228 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2233 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2235 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2246 i_test_format_probe(ig, length)
2255 i_readtiff_wiol(ig, allow_incomplete, page=0)
2257 int allow_incomplete
2261 i_readtiff_multi_wiol(ig, length)
2269 imgs = i_readtiff_multi_wiol(ig, length, &count);
2272 for (i = 0; i < count; ++i) {
2273 SV *sv = sv_newmortal();
2274 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2282 i_writetiff_wiol(im, ig)
2287 i_writetiff_multi_wiol(ig, ...)
2295 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2296 img_count = items - 1;
2298 if (img_count < 1) {
2301 i_push_error(0, "You need to specify images to save");
2304 imgs = mymalloc(sizeof(i_img *) * img_count);
2305 for (i = 0; i < img_count; ++i) {
2308 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2309 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2313 i_push_error(0, "Only images can be saved");
2320 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2328 i_writetiff_wiol_faxable(im, ig, fine)
2334 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2343 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2344 img_count = items - 2;
2346 if (img_count < 1) {
2349 i_push_error(0, "You need to specify images to save");
2352 imgs = mymalloc(sizeof(i_img *) * img_count);
2353 for (i = 0; i < img_count; ++i) {
2356 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2357 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2361 i_push_error(0, "Only images can be saved");
2368 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2376 #endif /* HAVE_LIBTIFF */
2382 i_readpng_wiol(ig, length)
2388 i_writepng_wiol(im, ig)
2401 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2404 i_writegif(im,fd,colors,pixdev,fixed)
2411 Imager__Color fixed;
2418 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2419 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2420 av=(AV*)SvRV(ST(4));
2421 fixedlen=av_len(av)+1;
2422 fixed=mymalloc( fixedlen*sizeof(i_color) );
2423 for(i=0;i<fixedlen;i++) {
2424 sv1=(*(av_fetch(av,i,0)));
2425 if (sv_derived_from(sv1, "Imager::Color")) {
2426 Itmp = SvIV((SV*)SvRV(sv1));
2427 tmp = INT2PTR(i_color*, Itmp);
2428 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2431 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2433 ST(0) = sv_newmortal();
2434 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2435 else sv_setiv(ST(0), (IV)RETVAL);
2441 i_writegifmc(im,fd,colors)
2448 i_writegif_gen(fd, ...)
2453 i_img **imgs = NULL;
2459 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2460 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2461 croak("i_writegif_gen: Second argument must be a hash ref");
2462 hv = (HV *)SvRV(ST(1));
2463 memset(&quant, 0, sizeof(quant));
2464 quant.mc_size = 256;
2465 handle_quant_opts(&quant, hv);
2466 img_count = items - 2;
2468 if (img_count < 1) {
2471 i_push_error(0, "You need to specify images to save");
2474 imgs = mymalloc(sizeof(i_img *) * img_count);
2475 for (i = 0; i < img_count; ++i) {
2478 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2479 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2483 i_push_error(0, "Only images can be saved");
2489 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2493 copy_colors_back(hv, &quant);
2496 ST(0) = sv_newmortal();
2497 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2498 else sv_setiv(ST(0), (IV)RETVAL);
2499 cleanup_quant_opts(&quant);
2503 i_writegif_callback(cb, maxbuffer,...)
2507 i_img **imgs = NULL;
2514 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2515 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2516 croak("i_writegif_callback: Second argument must be a hash ref");
2517 hv = (HV *)SvRV(ST(2));
2518 memset(&quant, 0, sizeof(quant));
2519 quant.mc_size = 256;
2520 handle_quant_opts(&quant, hv);
2521 img_count = items - 3;
2523 if (img_count < 1) {
2527 imgs = mymalloc(sizeof(i_img *) * img_count);
2528 for (i = 0; i < img_count; ++i) {
2531 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2532 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2541 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2545 copy_colors_back(hv, &quant);
2548 ST(0) = sv_newmortal();
2549 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2550 else sv_setiv(ST(0), (IV)RETVAL);
2551 cleanup_quant_opts(&quant);
2554 i_writegif_wiol(ig, opts,...)
2558 i_img **imgs = NULL;
2564 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2565 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2566 croak("i_writegif_callback: Second argument must be a hash ref");
2567 hv = (HV *)SvRV(ST(1));
2568 memset(&quant, 0, sizeof(quant));
2569 quant.mc_size = 256;
2570 handle_quant_opts(&quant, hv);
2571 img_count = items - 2;
2573 if (img_count < 1) {
2577 imgs = mymalloc(sizeof(i_img *) * img_count);
2578 for (i = 0; i < img_count; ++i) {
2581 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2582 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2590 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2594 copy_colors_back(hv, &quant);
2597 ST(0) = sv_newmortal();
2598 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2599 else sv_setiv(ST(0), (IV)RETVAL);
2600 cleanup_quant_opts(&quant);
2613 colour_table = NULL;
2616 if(GIMME_V == G_ARRAY) {
2617 rimg = i_readgif(fd,&colour_table,&colours);
2619 /* don't waste time with colours if they aren't wanted */
2620 rimg = i_readgif(fd,NULL,NULL);
2623 if (colour_table == NULL) {
2626 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2629 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2630 /* I don't know if I have the reference counts right or not :( */
2631 /* Neither do I :-) */
2632 /* No Idea here either */
2635 av_extend(ct, colours);
2636 for(q=0; q<colours; q++) {
2638 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2639 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2641 myfree(colour_table);
2645 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2647 PUSHs(newRV_noinc((SV*)ct));
2661 colour_table = NULL;
2664 if(GIMME_V == G_ARRAY) {
2665 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2667 /* don't waste time with colours if they aren't wanted */
2668 rimg = i_readgif_wiol(ig,NULL,NULL);
2671 if (colour_table == NULL) {
2674 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2677 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2678 /* I don't know if I have the reference counts right or not :( */
2679 /* Neither do I :-) */
2680 /* No Idea here either */
2683 av_extend(ct, colours);
2684 for(q=0; q<colours; q++) {
2686 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2687 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2689 myfree(colour_table);
2693 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2695 PUSHs(newRV_noinc((SV*)ct));
2699 i_readgif_single_wiol(ig, page=0)
2704 i_readgif_scalar(...)
2716 data = (char *)SvPV(ST(0), length);
2720 if(GIMME_V == G_ARRAY) {
2721 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2723 /* don't waste time with colours if they aren't wanted */
2724 rimg=i_readgif_scalar(data,length,NULL,NULL);
2727 if (colour_table == NULL) {
2730 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2733 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2734 /* I don't know if I have the reference counts right or not :( */
2735 /* Neither do I :-) */
2737 av_extend(ct, colours);
2738 for(q=0; q<colours; q++) {
2740 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2741 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2743 myfree(colour_table);
2747 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2749 PUSHs(newRV_noinc((SV*)ct));
2753 i_readgif_callback(...)
2768 if(GIMME_V == G_ARRAY) {
2769 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2771 /* don't waste time with colours if they aren't wanted */
2772 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2775 if (colour_table == NULL) {
2778 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2781 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2782 /* I don't know if I have the reference counts right or not :( */
2783 /* Neither do I :-) */
2784 /* Neither do I - maybe I'll move this somewhere */
2786 av_extend(ct, colours);
2787 for(q=0; q<colours; q++) {
2789 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2790 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2792 myfree(colour_table);
2796 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2798 PUSHs(newRV_noinc((SV*)ct));
2809 imgs = i_readgif_multi(fd, &count);
2812 for (i = 0; i < count; ++i) {
2813 SV *sv = sv_newmortal();
2814 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2821 i_readgif_multi_scalar(data)
2829 data = (char *)SvPV(ST(0), length);
2830 imgs = i_readgif_multi_scalar(data, length, &count);
2833 for (i = 0; i < count; ++i) {
2834 SV *sv = sv_newmortal();
2835 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2842 i_readgif_multi_callback(cb)
2850 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2853 for (i = 0; i < count; ++i) {
2854 SV *sv = sv_newmortal();
2855 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2862 i_readgif_multi_wiol(ig)
2869 imgs = i_readgif_multi_wiol(ig, &count);
2872 for (i = 0; i < count; ++i) {
2873 SV *sv = sv_newmortal();
2874 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2886 i_readpnm_wiol(ig, allow_incomplete)
2888 int allow_incomplete
2892 i_writeppm_wiol(im, ig)
2898 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2907 i_writeraw_wiol(im,ig)
2912 i_writebmp_wiol(im,ig)
2917 i_readbmp_wiol(ig, allow_incomplete=0)
2919 int allow_incomplete
2923 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2932 idlen = SvCUR(ST(4));
2933 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2939 i_readtga_wiol(ig, length)
2945 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2954 idlen = SvCUR(ST(4));
2955 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2961 i_readrgb_wiol(ig, length)
2968 i_scaleaxis(im,Value,Axis)
2974 i_scale_nn(im,scx,scy)
2980 i_scale_mixing(im, width, height)
2990 i_count_colors(im,maxc)
2996 i_transform(im,opx,opy,parm)
3009 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
3010 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
3011 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
3012 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
3013 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
3014 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
3015 av=(AV*)SvRV(ST(1));
3017 opx=mymalloc( opxl*sizeof(int) );
3018 for(i=0;i<opxl;i++) {
3019 sv1=(*(av_fetch(av,i,0)));
3020 opx[i]=(int)SvIV(sv1);
3022 av=(AV*)SvRV(ST(2));
3024 opy=mymalloc( opyl*sizeof(int) );
3025 for(i=0;i<opyl;i++) {
3026 sv1=(*(av_fetch(av,i,0)));
3027 opy[i]=(int)SvIV(sv1);
3029 av=(AV*)SvRV(ST(3));
3030 parmlen=av_len(av)+1;
3031 parm=mymalloc( parmlen*sizeof(double) );
3032 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
3033 sv1=(*(av_fetch(av,i,0)));
3034 parm[i]=(double)SvNV(sv1);
3036 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
3040 ST(0) = sv_newmortal();
3041 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3042 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3045 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
3070 in_imgs_count = av_len(av_in_imgs)+1;
3071 for (i = 0; i < in_imgs_count; ++i) {
3072 sv1 = *av_fetch(av_in_imgs, i, 0);
3073 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3074 croak("sv_in_img must contain only images");
3077 if (in_imgs_count > 0) {
3078 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
3079 for (i = 0; i < in_imgs_count; ++i) {
3080 sv1 = *av_fetch(av_in_imgs,i,0);
3081 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3082 croak("Parameter 5 must contain only images");
3084 tmp = SvIV((SV*)SvRV(sv1));
3085 in_imgs[i] = INT2PTR(i_img*, tmp);
3089 /* no input images */
3092 /* default the output size from the first input if possible */
3094 width = SvIV(sv_width);
3095 else if (in_imgs_count)
3096 width = in_imgs[0]->xsize;
3098 croak("No output image width supplied");
3100 if (SvOK(sv_height))
3101 height = SvIV(sv_height);
3102 else if (in_imgs_count)
3103 height = in_imgs[0]->ysize;
3105 croak("No output image height supplied");
3107 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3108 if (ops_len % sizeof(struct rm_op))
3109 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3110 ops_count = ops_len / sizeof(struct rm_op);
3112 n_regs_count = av_len(av_n_regs)+1;
3113 n_regs = mymalloc(n_regs_count * sizeof(double));
3114 for (i = 0; i < n_regs_count; ++i) {
3115 sv1 = *av_fetch(av_n_regs,i,0);
3117 n_regs[i] = SvNV(sv1);
3119 c_regs_count = av_len(av_c_regs)+1;
3120 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3121 /* I don't bother initializing the colou?r registers */
3123 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3124 n_regs, n_regs_count,
3125 c_regs, c_regs_count, in_imgs, in_imgs_count);
3130 ST(0) = sv_newmortal();
3131 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3132 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3136 i_contrast(im,intensity)
3145 i_noise(im,amount,type)
3151 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3161 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3180 i_postlevels(im,levels)
3190 i_watermark(im,wmark,tx,ty,pixdiff)
3192 Imager::ImgRaw wmark
3199 i_autolevels(im,lsat,usat,skew)
3206 i_radnoise(im,xo,yo,rscale,ascale)
3214 i_turbnoise(im, xo, yo, scale)
3237 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3238 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3239 croak("i_gradgen: Second argument must be an array ref");
3240 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3241 croak("i_gradgen: Third argument must be an array ref");
3242 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3243 croak("i_gradgen: Fourth argument must be an array ref");
3244 axx = (AV *)SvRV(ST(1));
3245 ayy = (AV *)SvRV(ST(2));
3246 ac = (AV *)SvRV(ST(3));
3247 dmeasure = (int)SvIV(ST(4));
3249 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3250 num = num <= av_len(ac) ? num : av_len(ac);
3252 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3253 xo = mymalloc( sizeof(int) * num );
3254 yo = mymalloc( sizeof(int) * num );
3255 ival = mymalloc( sizeof(i_color) * num );
3256 for(i = 0; i<num; i++) {
3257 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3258 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3259 sv = *av_fetch(ac, i, 0);
3260 if ( !sv_derived_from(sv, "Imager::Color") ) {
3261 free(axx); free(ayy); free(ac);
3262 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3264 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3266 i_gradgen(im, num, xo, yo, ival, dmeasure);
3272 i_diff_image(im, im2, mindist=0)
3278 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3288 double ssample_param
3292 i_fountain_seg *segs;
3294 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3295 croak("i_fountain: argument 11 must be an array ref");
3297 asegs = (AV *)SvRV(ST(10));
3298 segs = load_fount_segs(asegs, &count);
3299 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3300 super_sample, ssample_param, count, segs);
3306 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3315 double ssample_param
3319 i_fountain_seg *segs;
3321 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3322 croak("i_fountain: argument 11 must be an array ref");
3324 asegs = (AV *)SvRV(ST(9));
3325 segs = load_fount_segs(asegs, &count);
3326 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3327 super_sample, ssample_param, count, segs);
3340 errors = i_errors();
3342 while (errors[i].msg) {
3344 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3345 if (!av_store(av, 0, sv)) {
3348 sv = newSViv(errors[i].code);
3349 if (!av_store(av, 1, sv)) {
3352 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3360 i_push_error(code, msg)
3365 i_nearest_color(im, ...)
3380 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3381 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3382 croak("i_nearest_color: Second argument must be an array ref");
3383 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3384 croak("i_nearest_color: Third argument must be an array ref");
3385 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3386 croak("i_nearest_color: Fourth argument must be an array ref");
3387 axx = (AV *)SvRV(ST(1));
3388 ayy = (AV *)SvRV(ST(2));
3389 ac = (AV *)SvRV(ST(3));
3390 dmeasure = (int)SvIV(ST(4));
3392 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3393 num = num <= av_len(ac) ? num : av_len(ac);
3395 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3396 xo = mymalloc( sizeof(int) * num );
3397 yo = mymalloc( sizeof(int) * num );
3398 ival = mymalloc( sizeof(i_color) * num );
3399 for(i = 0; i<num; i++) {
3400 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3401 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3402 sv = *av_fetch(ac, i, 0);
3403 if ( !sv_derived_from(sv, "Imager::Color") ) {
3404 free(axx); free(ayy); free(ac);
3405 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3407 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3409 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3423 rc=DSO_open(filename,&evstr);
3427 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3428 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3431 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3437 DSO_close(dso_handle)
3441 DSO_funclist(dso_handle_v)
3445 DSO_handle *dso_handle;
3447 dso_handle=(DSO_handle*)dso_handle_v;
3449 while( dso_handle->function_list[i].name != NULL) {
3451 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3453 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3458 DSO_call(handle,func_index,hv)
3464 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3465 hv=(HV*)SvRV(ST(2));
3466 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3467 DSO_call( (DSO_handle *)handle,func_index,hv);
3472 i_get_pixel(im, x, y)
3479 color = (i_color *)mymalloc(sizeof(i_color));
3480 if (i_gpix(im, x, y, color) == 0) {
3481 RETVAL = NEWSV(0, 0);
3482 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3486 RETVAL = &PL_sv_undef;
3493 i_ppix(im, x, y, cl)
3500 i_img_pal_new(x, y, channels, maxpal)
3507 i_img_to_pal(src, quant)
3513 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3514 croak("i_img_to_pal: second argument must be a hash ref");
3515 hv = (HV *)SvRV(ST(1));
3516 memset(&quant, 0, sizeof(quant));
3517 quant.mc_size = 256;
3518 handle_quant_opts(&quant, hv);
3519 RETVAL = i_img_to_pal(src, &quant);
3521 copy_colors_back(hv, &quant);
3523 cleanup_quant_opts(&quant);
3542 work = mymalloc((r-l) * sizeof(i_palidx));
3543 count = i_gpal(im, l, r, y, work);
3544 if (GIMME_V == G_ARRAY) {
3546 for (i = 0; i < count; ++i) {
3547 PUSHs(sv_2mortal(newSViv(work[i])));
3552 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3557 if (GIMME_V != G_ARRAY) {
3559 PUSHs(&PL_sv_undef);
3564 i_ppal(im, l, y, ...)
3573 work = mymalloc(sizeof(i_palidx) * (items-3));
3574 for (i=0; i < items-3; ++i) {
3575 work[i] = SvIV(ST(i+3));
3577 validate_i_ppal(im, work, items - 3);
3578 RETVAL = i_ppal(im, l, l+items-3, y, work);
3588 i_ppal_p(im, l, y, data)
3594 i_palidx const *work;
3597 work = (i_palidx const *)SvPV(data, len);
3598 len /= sizeof(i_palidx);
3600 validate_i_ppal(im, work, len);
3601 RETVAL = i_ppal(im, l, l+len, y, work);
3610 i_addcolors(im, ...)
3618 croak("i_addcolors: no colors to add");
3619 colors = mymalloc((items-1) * sizeof(i_color));
3620 for (i=0; i < items-1; ++i) {
3621 if (sv_isobject(ST(i+1))
3622 && sv_derived_from(ST(i+1), "Imager::Color")) {
3623 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3624 colors[i] = *INT2PTR(i_color *, tmp);
3628 croak("i_addcolor: pixels must be Imager::Color objects");
3631 index = i_addcolors(im, colors, items-1);
3634 RETVAL = newSVpv("0 but true", 0);
3636 else if (index == -1) {
3637 RETVAL = &PL_sv_undef;
3640 RETVAL = newSViv(index);
3646 i_setcolors(im, index, ...)
3654 croak("i_setcolors: no colors to add");
3655 colors = mymalloc((items-2) * sizeof(i_color));
3656 for (i=0; i < items-2; ++i) {
3657 if (sv_isobject(ST(i+2))
3658 && sv_derived_from(ST(i+2), "Imager::Color")) {
3659 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3660 colors[i] = *INT2PTR(i_color *, tmp);
3664 croak("i_setcolors: pixels must be Imager::Color objects");
3667 RETVAL = i_setcolors(im, index, colors, items-2);
3673 i_getcolors(im, index, ...)
3682 croak("i_getcolors: too many arguments");
3684 count = SvIV(ST(2));
3686 croak("i_getcolors: count must be positive");
3687 colors = mymalloc(sizeof(i_color) * count);
3688 if (i_getcolors(im, index, colors, count)) {
3689 for (i = 0; i < count; ++i) {
3691 SV *sv = sv_newmortal();
3692 pv = mymalloc(sizeof(i_color));
3694 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3710 i_findcolor(im, color)
3716 if (i_findcolor(im, color, &index)) {
3717 RETVAL = newSViv(index);
3720 RETVAL = &PL_sv_undef;
3738 i_gsamp(im, l, r, y, ...)
3750 croak("No channel numbers supplied to g_samp()");
3752 chan_count = items - 4;
3753 chans = mymalloc(sizeof(int) * chan_count);
3754 for (i = 0; i < chan_count; ++i)
3755 chans[i] = SvIV(ST(i+4));
3756 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3757 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3759 if (GIMME_V == G_ARRAY) {
3761 for (i = 0; i < count; ++i)
3762 PUSHs(sv_2mortal(newSViv(data[i])));
3766 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3771 if (GIMME_V != G_ARRAY) {
3773 PUSHs(&PL_sv_undef);
3779 i_img_masked_new(targ, mask, x, y, w, h)
3789 if (!sv_isobject(ST(1))
3790 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3791 croak("i_img_masked_new: parameter 2 must undef or an image");
3793 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3797 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3802 i_plin(im, l, y, ...)
3813 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3814 /* supplied as a byte string */
3815 work = (i_color *)SvPV(ST(3), len);
3816 count = len / sizeof(i_color);
3817 if (count * sizeof(i_color) != len) {
3818 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3820 RETVAL = i_plin(im, l, l+count, y, work);
3823 work = mymalloc(sizeof(i_color) * (items-3));
3824 for (i=0; i < items-3; ++i) {
3825 if (sv_isobject(ST(i+3))
3826 && sv_derived_from(ST(i+3), "Imager::Color")) {
3827 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3828 work[i] = *INT2PTR(i_color *, tmp);
3832 croak("i_plin: pixels must be Imager::Color objects");
3835 RETVAL = i_plin(im, l, l+items-3, y, work);
3846 i_ppixf(im, x, y, cl)
3850 Imager::Color::Float cl
3853 i_gsampf(im, l, r, y, ...)
3865 croak("No channel numbers supplied to g_sampf()");
3867 chan_count = items - 4;
3868 chans = mymalloc(sizeof(int) * chan_count);
3869 for (i = 0; i < chan_count; ++i)
3870 chans[i] = SvIV(ST(i+4));
3871 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3872 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3874 if (GIMME_V == G_ARRAY) {
3876 for (i = 0; i < count; ++i)
3877 PUSHs(sv_2mortal(newSVnv(data[i])));
3881 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3886 if (GIMME_V != G_ARRAY) {
3888 PUSHs(&PL_sv_undef);
3893 i_plinf(im, l, y, ...)
3904 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3905 /* supplied as a byte string */
3906 work = (i_fcolor *)SvPV(ST(3), len);
3907 count = len / sizeof(i_fcolor);
3908 if (count * sizeof(i_fcolor) != len) {
3909 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3911 RETVAL = i_plinf(im, l, l+count, y, work);
3914 work = mymalloc(sizeof(i_fcolor) * (items-3));
3915 for (i=0; i < items-3; ++i) {
3916 if (sv_isobject(ST(i+3))
3917 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3918 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3919 work[i] = *INT2PTR(i_fcolor *, tmp);
3923 croak("i_plinf: pixels must be Imager::Color::Float objects");
3927 RETVAL = i_plinf(im, l, l+items-3, y, work);
3945 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3946 if (i_gpixf(im, x, y, color) == 0) {
3947 RETVAL = NEWSV(0,0);
3948 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3952 RETVAL = &PL_sv_undef;
3968 vals = mymalloc((r-l) * sizeof(i_color));
3969 count = i_glin(im, l, r, y, vals);
3970 if (GIMME_V == G_ARRAY) {
3972 for (i = 0; i < count; ++i) {
3974 i_color *col = mymalloc(sizeof(i_color));
3976 sv = sv_newmortal();
3977 sv_setref_pv(sv, "Imager::Color", (void *)col);
3983 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3989 i_glinf(im, l, r, y)
3999 vals = mymalloc((r-l) * sizeof(i_fcolor));
4000 count = i_glinf(im, l, r, y, vals);
4001 if (GIMME_V == G_ARRAY) {
4003 for (i = 0; i < count; ++i) {
4005 i_fcolor *col = mymalloc(sizeof(i_fcolor));
4007 sv = sv_newmortal();
4008 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
4014 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
4020 i_img_16_new(x, y, ch)
4030 i_img_double_new(x, y, ch)
4036 i_tags_addn(im, name, code, idata)
4045 name = SvPV(ST(1), len);
4048 RETVAL = i_tags_addn(&im->tags, name, code, idata);
4053 i_tags_add(im, name, code, data, idata)
4063 name = SvPV(ST(1), len);
4067 data = SvPV(ST(3), len);
4072 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
4077 i_tags_find(im, name, start)
4084 if (i_tags_find(&im->tags, name, start, &entry)) {
4086 RETVAL = newSVpv("0 but true", 0);
4088 RETVAL = newSViv(entry);
4090 RETVAL = &PL_sv_undef;
4096 i_tags_findn(im, code, start)
4103 if (i_tags_findn(&im->tags, code, start, &entry)) {
4105 RETVAL = newSVpv("0 but true", 0);
4107 RETVAL = newSViv(entry);
4110 RETVAL = &PL_sv_undef;
4116 i_tags_delete(im, entry)
4120 RETVAL = i_tags_delete(&im->tags, entry);
4125 i_tags_delbyname(im, name)
4129 RETVAL = i_tags_delbyname(&im->tags, name);
4134 i_tags_delbycode(im, code)
4138 RETVAL = i_tags_delbycode(&im->tags, code);
4143 i_tags_get(im, index)
4147 if (index >= 0 && index < im->tags.count) {
4148 i_img_tag *entry = im->tags.tags + index;
4152 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4155 PUSHs(sv_2mortal(newSViv(entry->code)));
4158 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4161 PUSHs(sv_2mortal(newSViv(entry->idata)));
4166 i_tags_get_string(im, what_sv)
4170 char const *name = NULL;
4174 if (SvIOK(what_sv)) {
4175 code = SvIV(what_sv);
4179 name = SvPV_nolen(what_sv);
4182 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4184 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4191 RETVAL = im->tags.count;
4198 i_wf_bbox(face, size, text_sv, utf8=0)
4204 int cords[BOUNDING_BOX_COUNT];
4209 text = SvPV(text_sv, text_len);
4211 if (SvUTF8(text_sv))
4214 if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) {
4216 for (i = 0; i < rc; ++i)
4217 PUSHs(sv_2mortal(newSViv(cords[i])));
4221 i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
4236 text = SvPV(text_sv, text_len);
4238 if (SvUTF8(text_sv))
4241 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len,
4247 i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
4262 text = SvPV(text_sv, text_len);
4264 if (SvUTF8(text_sv))
4267 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len,
4280 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4282 #define FT2_DESTROY(font) i_ft2_destroy(font)
4286 Imager::Font::FT2 font
4288 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4291 i_ft2_new(name, index)
4296 i_ft2_setdpi(font, xdpi, ydpi)
4297 Imager::Font::FT2 font
4303 Imager::Font::FT2 font
4307 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4309 PUSHs(sv_2mortal(newSViv(xdpi)));
4310 PUSHs(sv_2mortal(newSViv(ydpi)));
4314 i_ft2_sethinting(font, hinting)
4315 Imager::Font::FT2 font
4319 i_ft2_settransform(font, matrix)
4320 Imager::Font::FT2 font
4328 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4329 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4330 av=(AV*)SvRV(ST(1));
4334 for (i = 0; i < len; ++i) {
4335 sv1=(*(av_fetch(av,i,0)));
4336 matrix[i] = SvNV(sv1);
4340 RETVAL = i_ft2_settransform(font, matrix);
4345 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4346 Imager::Font::FT2 font
4352 int bbox[BOUNDING_BOX_COUNT];
4358 text = SvPV(text_sv, text_len);
4360 if (SvUTF8(text_sv))
4363 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4366 for (i = 0; i < rc; ++i)
4367 PUSHs(sv_2mortal(newSViv(bbox[i])));
4371 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4372 Imager::Font::FT2 font
4386 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4389 for (i = 0; i < 8; ++i)
4390 PUSHs(sv_2mortal(newSViv(bbox[i])));
4394 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4395 Imager::Font::FT2 font
4411 if (SvUTF8(ST(7))) {
4415 text = SvPV(ST(7), len);
4416 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4417 len, align, aa, vlayout, utf8);
4422 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
4423 Imager::Font::FT2 font
4443 text = SvPV(text_sv, len);
4444 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4445 len, align, aa, vlayout, 1);
4450 ft2_transform_box(font, x0, x1, x2, x3)
4451 Imager::Font::FT2 font
4459 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4460 ft2_transform_box(font, box);
4462 PUSHs(sv_2mortal(newSViv(box[0])));
4463 PUSHs(sv_2mortal(newSViv(box[1])));
4464 PUSHs(sv_2mortal(newSViv(box[2])));
4465 PUSHs(sv_2mortal(newSViv(box[3])));
4468 i_ft2_has_chars(handle, text_sv, utf8)
4469 Imager::Font::FT2 handle
4480 if (SvUTF8(text_sv))
4483 text = SvPV(text_sv, len);
4484 work = mymalloc(len);
4485 count = i_ft2_has_chars(handle, text, len, utf8, work);
4486 if (GIMME_V == G_ARRAY) {
4488 for (i = 0; i < count; ++i) {
4489 PUSHs(sv_2mortal(newSViv(work[i])));
4494 PUSHs(sv_2mortal(newSVpv(work, count)));
4499 i_ft2_face_name(handle)
4500 Imager::Font::FT2 handle
4505 len = i_ft2_face_name(handle, name, sizeof(name));
4508 PUSHs(sv_2mortal(newSVpv(name, 0)));
4512 i_ft2_can_face_name()
4515 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4516 Imager::Font::FT2 handle
4527 if (SvUTF8(text_sv))
4530 text = SvPV(text_sv, work_len);
4535 ch = i_utf8_advance(&text, &len);
4537 i_push_error(0, "invalid UTF8 character");
4546 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4548 PUSHs(sv_2mortal(newSVpv(name, 0)));
4551 PUSHs(&PL_sv_undef);
4556 i_ft2_can_do_glyph_names()
4559 i_ft2_face_has_glyph_names(handle)
4560 Imager::Font::FT2 handle
4563 i_ft2_is_multiple_master(handle)
4564 Imager::Font::FT2 handle
4567 i_ft2_get_multiple_masters(handle)
4568 Imager::Font::FT2 handle
4573 if (i_ft2_get_multiple_masters(handle, &mm)) {
4574 EXTEND(SP, 2+mm.num_axis);
4575 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4576 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4577 for (i = 0; i < mm.num_axis; ++i) {
4581 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4583 av_store(av, 0, sv);
4584 sv = newSViv(mm.axis[i].minimum);
4586 av_store(av, 1, sv);
4587 sv = newSViv(mm.axis[i].maximum);
4589 av_store(av, 2, sv);
4590 PUSHs(newRV_noinc((SV *)av));
4595 i_ft2_set_mm_coords(handle, ...)
4596 Imager::Font::FT2 handle
4602 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4603 transfer the array manually */
4604 ix_coords = items-1;
4605 coords = mymalloc(sizeof(long) * ix_coords);
4606 for (i = 0; i < ix_coords; ++i) {
4607 coords[i] = (long)SvIV(ST(1+i));
4609 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4616 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4620 Imager::FillHandle fill
4622 MODULE = Imager PACKAGE = Imager
4625 i_new_fill_solid(cl, combine)
4630 i_new_fill_solidf(cl, combine)
4631 Imager::Color::Float cl
4635 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4643 unsigned char *cust_hatch;
4647 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4651 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4656 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4657 Imager::Color::Float fg
4658 Imager::Color::Float bg
4664 unsigned char *cust_hatch;
4668 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4672 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4677 i_new_fill_image(src, matrix, xoff, yoff, combine)
4694 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4695 croak("i_new_fill_image: parameter must be an arrayref");
4696 av=(AV*)SvRV(ST(1));
4700 for (i = 0; i < len; ++i) {
4701 sv1=(*(av_fetch(av,i,0)));
4702 matrix[i] = SvNV(sv1);
4708 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4712 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4714 # this class is only exposed for testing
4717 i_int_hlines_testing()
4719 #if i_int_hlines_testing()
4721 Imager::Internal::Hlines
4722 i_int_hlines_new(start_y, count_y, start_x, count_x)
4728 Imager::Internal::Hlines
4729 i_int_hlines_new_img(im)
4733 i_int_hlines_add(hlines, y, minx, width)
4734 Imager::Internal::Hlines hlines
4740 i_int_hlines_DESTROY(hlines)
4741 Imager::Internal::Hlines hlines
4744 i_int_hlines_dump(hlines)
4745 Imager::Internal::Hlines hlines
4750 PERL_SET_GLOBAL_CALLBACKS;