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_sv,level)
1294 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1296 i_init_log(name, level);
1299 i_log_entry(string,level)
1318 i_img_info(im,info);
1320 PUSHs(sv_2mortal(newSViv(info[0])));
1321 PUSHs(sv_2mortal(newSViv(info[1])));
1322 PUSHs(sv_2mortal(newSViv(info[2])));
1323 PUSHs(sv_2mortal(newSViv(info[3])));
1329 i_img_setmask(im,ch_mask)
1338 i_img_getchannels(im)
1347 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1351 i_img_is_monochrome(im)
1357 result = i_img_is_monochrome(im, &zero_is_white);
1359 if (GIMME_V == G_ARRAY) {
1362 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1371 i_line(im,x1,y1,x2,y2,val,endp)
1381 i_line_aa(im,x1,y1,x2,y2,val,endp)
1391 i_box(im,x1,y1,x2,y2,val)
1400 i_box_filled(im,x1,y1,x2,y2,val)
1409 i_box_cfill(im,x1,y1,x2,y2,fill)
1415 Imager::FillHandle fill
1418 i_arc(im,x,y,rad,d1,d2,val)
1428 i_arc_aa(im,x,y,rad,d1,d2,val)
1438 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1445 Imager::FillHandle fill
1448 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1455 Imager::FillHandle fill
1459 i_circle_aa(im,x,y,rad,val)
1469 i_bezier_multi(im,xc,yc,val)
1482 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1483 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1484 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1485 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1486 av1=(AV*)SvRV(ST(1));
1487 av2=(AV*)SvRV(ST(2));
1488 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1490 x=mymalloc( len*sizeof(double) );
1491 y=mymalloc( len*sizeof(double) );
1492 for(i=0;i<len;i++) {
1493 sv1=(*(av_fetch(av1,i,0)));
1494 sv2=(*(av_fetch(av2,i,0)));
1495 x[i]=(double)SvNV(sv1);
1496 y[i]=(double)SvNV(sv2);
1498 i_bezier_multi(im,len,x,y,val);
1504 i_poly_aa(im,xc,yc,val)
1517 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1518 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1519 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1520 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1521 av1=(AV*)SvRV(ST(1));
1522 av2=(AV*)SvRV(ST(2));
1523 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1525 x=mymalloc( len*sizeof(double) );
1526 y=mymalloc( len*sizeof(double) );
1527 for(i=0;i<len;i++) {
1528 sv1=(*(av_fetch(av1,i,0)));
1529 sv2=(*(av_fetch(av2,i,0)));
1530 x[i]=(double)SvNV(sv1);
1531 y[i]=(double)SvNV(sv2);
1533 i_poly_aa(im,len,x,y,val);
1538 i_poly_aa_cfill(im,xc,yc,fill)
1540 Imager::FillHandle fill
1550 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1551 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1552 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1553 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1554 av1=(AV*)SvRV(ST(1));
1555 av2=(AV*)SvRV(ST(2));
1556 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1558 x=mymalloc( len*sizeof(double) );
1559 y=mymalloc( len*sizeof(double) );
1560 for(i=0;i<len;i++) {
1561 sv1=(*(av_fetch(av1,i,0)));
1562 sv2=(*(av_fetch(av2,i,0)));
1563 x[i]=(double)SvNV(sv1);
1564 y[i]=(double)SvNV(sv2);
1566 i_poly_aa_cfill(im,len,x,y,fill);
1573 i_flood_fill(im,seedx,seedy,dcol)
1580 i_flood_cfill(im,seedx,seedy,fill)
1584 Imager::FillHandle fill
1587 i_flood_fill_border(im,seedx,seedy,dcol, border)
1592 Imager::Color border
1595 i_flood_cfill_border(im,seedx,seedy,fill, border)
1599 Imager::FillHandle fill
1600 Imager::Color border
1604 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1616 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1633 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1645 i_flipxy(im, direction)
1650 i_rotate90(im, degrees)
1655 i_rotate_exact(im, amount, ...)
1659 i_color *backp = NULL;
1660 i_fcolor *fbackp = NULL;
1664 /* extract the bg colors if any */
1665 /* yes, this is kind of strange */
1666 for (i = 2; i < items; ++i) {
1668 if (sv_derived_from(sv1, "Imager::Color")) {
1669 IV tmp = SvIV((SV*)SvRV(sv1));
1670 backp = INT2PTR(i_color *, tmp);
1672 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1673 IV tmp = SvIV((SV*)SvRV(sv1));
1674 fbackp = INT2PTR(i_fcolor *, tmp);
1677 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1682 i_matrix_transform(im, xsize, ysize, matrix, ...)
1692 i_color *backp = NULL;
1693 i_fcolor *fbackp = NULL;
1695 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1696 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1697 av=(AV*)SvRV(ST(3));
1701 for (i = 0; i < len; ++i) {
1702 sv1=(*(av_fetch(av,i,0)));
1703 matrix[i] = SvNV(sv1);
1707 /* extract the bg colors if any */
1708 /* yes, this is kind of strange */
1709 for (i = 4; i < items; ++i) {
1711 if (sv_derived_from(sv1, "Imager::Color")) {
1712 IV tmp = SvIV((SV*)SvRV(sv1));
1713 backp = INT2PTR(i_color *, tmp);
1715 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1716 IV tmp = SvIV((SV*)SvRV(sv1));
1717 fbackp = INT2PTR(i_fcolor *, tmp);
1720 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1725 i_gaussian(im,stdev)
1730 i_unsharp_mask(im,stdev,scale)
1745 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1746 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1747 av=(AV*)SvRV(ST(1));
1749 coeff=mymalloc( len*sizeof(float) );
1750 for(i=0;i<len;i++) {
1751 sv1=(*(av_fetch(av,i,0)));
1752 coeff[i]=(float)SvNV(sv1);
1754 i_conv(im,coeff,len);
1758 i_convert(src, avmain)
1770 outchan = av_len(avmain)+1;
1771 /* find the biggest */
1773 for (j=0; j < outchan; ++j) {
1774 temp = av_fetch(avmain, j, 0);
1775 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1776 avsub = (AV*)SvRV(*temp);
1777 len = av_len(avsub)+1;
1782 coeff = mymalloc(sizeof(float) * outchan * inchan);
1783 for (j = 0; j < outchan; ++j) {
1784 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1785 len = av_len(avsub)+1;
1786 for (i = 0; i < len; ++i) {
1787 temp = av_fetch(avsub, i, 0);
1789 coeff[i+j*inchan] = SvNV(*temp);
1791 coeff[i+j*inchan] = 0;
1794 coeff[i++ + j*inchan] = 0;
1796 RETVAL = i_convert(src, coeff, outchan, inchan);
1806 unsigned int mask = 0;
1812 unsigned char (*maps)[256];
1814 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1815 croak("i_map: parameter 2 must be an arrayref\n");
1816 avmain = (AV*)SvRV(ST(1));
1817 len = av_len(avmain)+1;
1818 if (im->channels < len) len = im->channels;
1820 maps = mymalloc( len * sizeof(unsigned char [256]) );
1822 for (j=0; j<len ; j++) {
1823 temp = av_fetch(avmain, j, 0);
1824 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1825 avsub = (AV*)SvRV(*temp);
1826 if(av_len(avsub) != 255) continue;
1828 for (i=0; i<256 ; i++) {
1830 temp = av_fetch(avsub, i, 0);
1831 val = temp ? SvIV(*temp) : 0;
1833 if (val>255) val = 255;
1838 i_map(im, maps, mask);
1851 i_init_fonts(t1log=0)
1866 i_t1_destroy(font_id)
1871 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1890 str = SvPV(str_sv, len);
1891 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1898 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1907 int cords[BOUNDING_BOX_COUNT];
1915 str = SvPV(str_sv, len);
1916 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1919 for (i = 0; i < rc; ++i)
1920 PUSHs(sv_2mortal(newSViv(cords[i])));
1926 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1945 str = SvPV(str_sv, len);
1946 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1952 i_t1_has_chars(handle, text_sv, utf8 = 0)
1964 if (SvUTF8(text_sv))
1967 text = SvPV(text_sv, len);
1968 work = mymalloc(len);
1969 count = i_t1_has_chars(handle, text, len, utf8, work);
1970 if (GIMME_V == G_ARRAY) {
1972 for (i = 0; i < count; ++i) {
1973 PUSHs(sv_2mortal(newSViv(work[i])));
1978 PUSHs(sv_2mortal(newSVpv(work, count)));
1983 i_t1_face_name(handle)
1989 len = i_t1_face_name(handle, name, sizeof(name));
1992 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1996 i_t1_glyph_name(handle, text_sv, utf8 = 0)
2007 if (SvUTF8(text_sv))
2010 text = SvPV(text_sv, work_len);
2015 ch = i_utf8_advance(&text, &len);
2017 i_push_error(0, "invalid UTF8 character");
2026 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
2027 PUSHs(sv_2mortal(newSVpv(name, 0)));
2030 PUSHs(&PL_sv_undef);
2044 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2046 #define TT_DESTROY(handle) i_tt_destroy(handle)
2050 Imager::Font::TT handle
2053 MODULE = Imager PACKAGE = Imager
2057 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2058 Imager::Font::TT handle
2076 str = SvPV(str_sv, len);
2077 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2078 len, smooth, utf8, align);
2084 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2085 Imager::Font::TT handle
2103 str = SvPV(str_sv, len);
2104 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2105 smooth, utf8, align);
2111 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2112 Imager::Font::TT handle
2117 int cords[BOUNDING_BOX_COUNT],rc;
2126 str = SvPV(str_sv, len);
2127 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2129 for (i = 0; i < rc; ++i) {
2130 PUSHs(sv_2mortal(newSViv(cords[i])));
2135 i_tt_has_chars(handle, text_sv, utf8)
2136 Imager::Font::TT handle
2147 if (SvUTF8(text_sv))
2150 text = SvPV(text_sv, len);
2151 work = mymalloc(len);
2152 count = i_tt_has_chars(handle, text, len, utf8, work);
2153 if (GIMME_V == G_ARRAY) {
2155 for (i = 0; i < count; ++i) {
2156 PUSHs(sv_2mortal(newSViv(work[i])));
2161 PUSHs(sv_2mortal(newSVpv(work, count)));
2166 i_tt_dump_names(handle)
2167 Imager::Font::TT handle
2170 i_tt_face_name(handle)
2171 Imager::Font::TT handle
2176 len = i_tt_face_name(handle, name, sizeof(name));
2179 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2183 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2184 Imager::Font::TT handle
2195 if (SvUTF8(text_sv))
2198 text = SvPV(text_sv, work_len);
2203 ch = i_utf8_advance(&text, &len);
2205 i_push_error(0, "invalid UTF8 character");
2214 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2215 PUSHs(sv_2mortal(newSVpv(name, 0)));
2218 PUSHs(&PL_sv_undef);
2227 i_writejpeg_wiol(im, ig, qfactor)
2243 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2244 if (iptc_itext == NULL) {
2247 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2252 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2254 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2265 i_test_format_probe(ig, length)
2274 i_readtiff_wiol(ig, allow_incomplete, page=0)
2276 int allow_incomplete
2280 i_readtiff_multi_wiol(ig, length)
2288 imgs = i_readtiff_multi_wiol(ig, length, &count);
2291 for (i = 0; i < count; ++i) {
2292 SV *sv = sv_newmortal();
2293 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2301 i_writetiff_wiol(im, ig)
2306 i_writetiff_multi_wiol(ig, ...)
2314 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2315 img_count = items - 1;
2317 if (img_count < 1) {
2320 i_push_error(0, "You need to specify images to save");
2323 imgs = mymalloc(sizeof(i_img *) * img_count);
2324 for (i = 0; i < img_count; ++i) {
2327 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2328 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2332 i_push_error(0, "Only images can be saved");
2339 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2347 i_writetiff_wiol_faxable(im, ig, fine)
2353 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2362 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2363 img_count = items - 2;
2365 if (img_count < 1) {
2368 i_push_error(0, "You need to specify images to save");
2371 imgs = mymalloc(sizeof(i_img *) * img_count);
2372 for (i = 0; i < img_count; ++i) {
2375 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2376 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2380 i_push_error(0, "Only images can be saved");
2387 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2398 i_tiff_has_compression(name)
2401 #endif /* HAVE_LIBTIFF */
2407 i_readpng_wiol(ig, length)
2413 i_writepng_wiol(im, ig)
2426 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2429 i_writegif(im,fd,colors,pixdev,fixed)
2436 Imager__Color fixed;
2443 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2444 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2445 av=(AV*)SvRV(ST(4));
2446 fixedlen=av_len(av)+1;
2447 fixed=mymalloc( fixedlen*sizeof(i_color) );
2448 for(i=0;i<fixedlen;i++) {
2449 sv1=(*(av_fetch(av,i,0)));
2450 if (sv_derived_from(sv1, "Imager::Color")) {
2451 Itmp = SvIV((SV*)SvRV(sv1));
2452 tmp = INT2PTR(i_color*, Itmp);
2453 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2456 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2458 ST(0) = sv_newmortal();
2459 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2460 else sv_setiv(ST(0), (IV)RETVAL);
2466 i_writegifmc(im,fd,colors)
2473 i_writegif_gen(fd, ...)
2478 i_img **imgs = NULL;
2484 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2485 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2486 croak("i_writegif_gen: Second argument must be a hash ref");
2487 hv = (HV *)SvRV(ST(1));
2488 memset(&quant, 0, sizeof(quant));
2489 quant.mc_size = 256;
2490 quant.transp = tr_threshold;
2491 quant.tr_threshold = 127;
2492 handle_quant_opts(&quant, hv);
2493 img_count = items - 2;
2495 if (img_count < 1) {
2498 i_push_error(0, "You need to specify images to save");
2501 imgs = mymalloc(sizeof(i_img *) * img_count);
2502 for (i = 0; i < img_count; ++i) {
2505 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2506 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2510 i_push_error(0, "Only images can be saved");
2516 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2520 copy_colors_back(hv, &quant);
2523 ST(0) = sv_newmortal();
2524 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2525 else sv_setiv(ST(0), (IV)RETVAL);
2526 cleanup_quant_opts(&quant);
2530 i_writegif_callback(cb, maxbuffer,...)
2534 i_img **imgs = NULL;
2541 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2542 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2543 croak("i_writegif_callback: Second argument must be a hash ref");
2544 hv = (HV *)SvRV(ST(2));
2545 memset(&quant, 0, sizeof(quant));
2546 quant.mc_size = 256;
2547 quant.transp = tr_threshold;
2548 quant.tr_threshold = 127;
2549 handle_quant_opts(&quant, hv);
2550 img_count = items - 3;
2552 if (img_count < 1) {
2556 imgs = mymalloc(sizeof(i_img *) * img_count);
2557 for (i = 0; i < img_count; ++i) {
2560 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2561 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2570 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2574 copy_colors_back(hv, &quant);
2577 ST(0) = sv_newmortal();
2578 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2579 else sv_setiv(ST(0), (IV)RETVAL);
2580 cleanup_quant_opts(&quant);
2583 i_writegif_wiol(ig, opts,...)
2587 i_img **imgs = NULL;
2593 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2594 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2595 croak("i_writegif_callback: Second argument must be a hash ref");
2596 hv = (HV *)SvRV(ST(1));
2597 memset(&quant, 0, sizeof(quant));
2598 quant.mc_size = 256;
2599 quant.transp = tr_threshold;
2600 quant.tr_threshold = 127;
2601 handle_quant_opts(&quant, hv);
2602 img_count = items - 2;
2604 if (img_count < 1) {
2608 imgs = mymalloc(sizeof(i_img *) * img_count);
2609 for (i = 0; i < img_count; ++i) {
2612 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2613 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2621 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2625 copy_colors_back(hv, &quant);
2628 ST(0) = sv_newmortal();
2629 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2630 else sv_setiv(ST(0), (IV)RETVAL);
2631 cleanup_quant_opts(&quant);
2644 colour_table = NULL;
2647 if(GIMME_V == G_ARRAY) {
2648 rimg = i_readgif(fd,&colour_table,&colours);
2650 /* don't waste time with colours if they aren't wanted */
2651 rimg = i_readgif(fd,NULL,NULL);
2654 if (colour_table == NULL) {
2657 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2660 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2661 /* I don't know if I have the reference counts right or not :( */
2662 /* Neither do I :-) */
2663 /* No Idea here either */
2666 av_extend(ct, colours);
2667 for(q=0; q<colours; q++) {
2669 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2670 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2672 myfree(colour_table);
2676 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2678 PUSHs(newRV_noinc((SV*)ct));
2692 colour_table = NULL;
2695 if(GIMME_V == G_ARRAY) {
2696 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2698 /* don't waste time with colours if they aren't wanted */
2699 rimg = i_readgif_wiol(ig,NULL,NULL);
2702 if (colour_table == NULL) {
2705 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2708 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2709 /* I don't know if I have the reference counts right or not :( */
2710 /* Neither do I :-) */
2711 /* No Idea here either */
2714 av_extend(ct, colours);
2715 for(q=0; q<colours; q++) {
2717 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2718 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2720 myfree(colour_table);
2724 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2726 PUSHs(newRV_noinc((SV*)ct));
2730 i_readgif_single_wiol(ig, page=0)
2735 i_readgif_scalar(...)
2747 data = (char *)SvPV(ST(0), length);
2751 if(GIMME_V == G_ARRAY) {
2752 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2754 /* don't waste time with colours if they aren't wanted */
2755 rimg=i_readgif_scalar(data,length,NULL,NULL);
2758 if (colour_table == NULL) {
2761 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2764 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2765 /* I don't know if I have the reference counts right or not :( */
2766 /* Neither do I :-) */
2768 av_extend(ct, colours);
2769 for(q=0; q<colours; q++) {
2771 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2772 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2774 myfree(colour_table);
2778 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2780 PUSHs(newRV_noinc((SV*)ct));
2784 i_readgif_callback(...)
2799 if(GIMME_V == G_ARRAY) {
2800 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2802 /* don't waste time with colours if they aren't wanted */
2803 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2806 if (colour_table == NULL) {
2809 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2812 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2813 /* I don't know if I have the reference counts right or not :( */
2814 /* Neither do I :-) */
2815 /* Neither do I - maybe I'll move this somewhere */
2817 av_extend(ct, colours);
2818 for(q=0; q<colours; q++) {
2820 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2821 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2823 myfree(colour_table);
2827 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2829 PUSHs(newRV_noinc((SV*)ct));
2840 imgs = i_readgif_multi(fd, &count);
2843 for (i = 0; i < count; ++i) {
2844 SV *sv = sv_newmortal();
2845 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2852 i_readgif_multi_scalar(data)
2860 data = (char *)SvPV(ST(0), length);
2861 imgs = i_readgif_multi_scalar(data, length, &count);
2864 for (i = 0; i < count; ++i) {
2865 SV *sv = sv_newmortal();
2866 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2873 i_readgif_multi_callback(cb)
2881 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2884 for (i = 0; i < count; ++i) {
2885 SV *sv = sv_newmortal();
2886 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2893 i_readgif_multi_wiol(ig)
2900 imgs = i_readgif_multi_wiol(ig, &count);
2903 for (i = 0; i < count; ++i) {
2904 SV *sv = sv_newmortal();
2905 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2917 i_readpnm_wiol(ig, allow_incomplete)
2919 int allow_incomplete
2923 i_writeppm_wiol(im, ig)
2929 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2938 i_writeraw_wiol(im,ig)
2943 i_writebmp_wiol(im,ig)
2948 i_readbmp_wiol(ig, allow_incomplete=0)
2950 int allow_incomplete
2954 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2963 idlen = SvCUR(ST(4));
2964 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2970 i_readtga_wiol(ig, length)
2978 i_scaleaxis(im,Value,Axis)
2984 i_scale_nn(im,scx,scy)
2990 i_scale_mixing(im, width, height)
3000 i_count_colors(im,maxc)
3005 i_get_anonymous_color_histo(im, maxc = 0x40000000)
3010 unsigned int * col_usage = NULL;
3013 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
3014 EXTEND(SP, col_cnt);
3015 for (i = 0; i < col_cnt; i++) {
3016 PUSHs(sv_2mortal(newSViv( col_usage[i])));
3023 i_transform(im,opx,opy,parm)
3036 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
3037 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
3038 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
3039 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
3040 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
3041 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
3042 av=(AV*)SvRV(ST(1));
3044 opx=mymalloc( opxl*sizeof(int) );
3045 for(i=0;i<opxl;i++) {
3046 sv1=(*(av_fetch(av,i,0)));
3047 opx[i]=(int)SvIV(sv1);
3049 av=(AV*)SvRV(ST(2));
3051 opy=mymalloc( opyl*sizeof(int) );
3052 for(i=0;i<opyl;i++) {
3053 sv1=(*(av_fetch(av,i,0)));
3054 opy[i]=(int)SvIV(sv1);
3056 av=(AV*)SvRV(ST(3));
3057 parmlen=av_len(av)+1;
3058 parm=mymalloc( parmlen*sizeof(double) );
3059 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
3060 sv1=(*(av_fetch(av,i,0)));
3061 parm[i]=(double)SvNV(sv1);
3063 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
3067 ST(0) = sv_newmortal();
3068 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3069 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3072 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
3097 in_imgs_count = av_len(av_in_imgs)+1;
3098 for (i = 0; i < in_imgs_count; ++i) {
3099 sv1 = *av_fetch(av_in_imgs, i, 0);
3100 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3101 croak("sv_in_img must contain only images");
3104 if (in_imgs_count > 0) {
3105 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
3106 for (i = 0; i < in_imgs_count; ++i) {
3107 sv1 = *av_fetch(av_in_imgs,i,0);
3108 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3109 croak("Parameter 5 must contain only images");
3111 tmp = SvIV((SV*)SvRV(sv1));
3112 in_imgs[i] = INT2PTR(i_img*, tmp);
3116 /* no input images */
3119 /* default the output size from the first input if possible */
3121 width = SvIV(sv_width);
3122 else if (in_imgs_count)
3123 width = in_imgs[0]->xsize;
3125 croak("No output image width supplied");
3127 if (SvOK(sv_height))
3128 height = SvIV(sv_height);
3129 else if (in_imgs_count)
3130 height = in_imgs[0]->ysize;
3132 croak("No output image height supplied");
3134 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3135 if (ops_len % sizeof(struct rm_op))
3136 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3137 ops_count = ops_len / sizeof(struct rm_op);
3139 n_regs_count = av_len(av_n_regs)+1;
3140 n_regs = mymalloc(n_regs_count * sizeof(double));
3141 for (i = 0; i < n_regs_count; ++i) {
3142 sv1 = *av_fetch(av_n_regs,i,0);
3144 n_regs[i] = SvNV(sv1);
3146 c_regs_count = av_len(av_c_regs)+1;
3147 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3148 /* I don't bother initializing the colou?r registers */
3150 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3151 n_regs, n_regs_count,
3152 c_regs, c_regs_count, in_imgs, in_imgs_count);
3157 ST(0) = sv_newmortal();
3158 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3159 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3163 i_contrast(im,intensity)
3172 i_noise(im,amount,type)
3178 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3188 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3207 i_postlevels(im,levels)
3217 i_watermark(im,wmark,tx,ty,pixdiff)
3219 Imager::ImgRaw wmark
3226 i_autolevels(im,lsat,usat,skew)
3233 i_radnoise(im,xo,yo,rscale,ascale)
3241 i_turbnoise(im, xo, yo, scale)
3264 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3265 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3266 croak("i_gradgen: Second argument must be an array ref");
3267 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3268 croak("i_gradgen: Third argument must be an array ref");
3269 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3270 croak("i_gradgen: Fourth argument must be an array ref");
3271 axx = (AV *)SvRV(ST(1));
3272 ayy = (AV *)SvRV(ST(2));
3273 ac = (AV *)SvRV(ST(3));
3274 dmeasure = (int)SvIV(ST(4));
3276 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3277 num = num <= av_len(ac) ? num : av_len(ac);
3279 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3280 xo = mymalloc( sizeof(int) * num );
3281 yo = mymalloc( sizeof(int) * num );
3282 ival = mymalloc( sizeof(i_color) * num );
3283 for(i = 0; i<num; i++) {
3284 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3285 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3286 sv = *av_fetch(ac, i, 0);
3287 if ( !sv_derived_from(sv, "Imager::Color") ) {
3288 free(axx); free(ayy); free(ac);
3289 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3291 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3293 i_gradgen(im, num, xo, yo, ival, dmeasure);
3299 i_diff_image(im, im2, mindist=0)
3305 i_fountain(im, 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(10)) || ! SvTYPE(SvRV(ST(10))))
3322 croak("i_fountain: argument 11 must be an array ref");
3324 asegs = (AV *)SvRV(ST(10));
3325 segs = load_fount_segs(asegs, &count);
3326 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3327 super_sample, ssample_param, count, segs);
3333 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3342 double ssample_param
3346 i_fountain_seg *segs;
3348 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3349 croak("i_fountain: argument 11 must be an array ref");
3351 asegs = (AV *)SvRV(ST(9));
3352 segs = load_fount_segs(asegs, &count);
3353 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3354 super_sample, ssample_param, count, segs);
3367 errors = i_errors();
3369 while (errors[i].msg) {
3371 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3372 if (!av_store(av, 0, sv)) {
3375 sv = newSViv(errors[i].code);
3376 if (!av_store(av, 1, sv)) {
3379 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3387 i_push_error(code, msg)
3392 i_nearest_color(im, ...)
3407 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3408 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3409 croak("i_nearest_color: Second argument must be an array ref");
3410 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3411 croak("i_nearest_color: Third argument must be an array ref");
3412 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3413 croak("i_nearest_color: Fourth argument must be an array ref");
3414 axx = (AV *)SvRV(ST(1));
3415 ayy = (AV *)SvRV(ST(2));
3416 ac = (AV *)SvRV(ST(3));
3417 dmeasure = (int)SvIV(ST(4));
3419 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3420 num = num <= av_len(ac) ? num : av_len(ac);
3422 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3423 xo = mymalloc( sizeof(int) * num );
3424 yo = mymalloc( sizeof(int) * num );
3425 ival = mymalloc( sizeof(i_color) * num );
3426 for(i = 0; i<num; i++) {
3427 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3428 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3429 sv = *av_fetch(ac, i, 0);
3430 if ( !sv_derived_from(sv, "Imager::Color") ) {
3431 free(axx); free(ayy); free(ac);
3432 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3434 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3436 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3450 rc=DSO_open(filename,&evstr);
3454 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3455 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3458 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3464 DSO_close(dso_handle)
3468 DSO_funclist(dso_handle_v)
3472 DSO_handle *dso_handle;
3474 dso_handle=(DSO_handle*)dso_handle_v;
3476 while( dso_handle->function_list[i].name != NULL) {
3478 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3480 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3485 DSO_call(handle,func_index,hv)
3491 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3492 hv=(HV*)SvRV(ST(2));
3493 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3494 DSO_call( (DSO_handle *)handle,func_index,hv);
3499 i_get_pixel(im, x, y)
3506 color = (i_color *)mymalloc(sizeof(i_color));
3507 if (i_gpix(im, x, y, color) == 0) {
3508 RETVAL = NEWSV(0, 0);
3509 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3513 RETVAL = &PL_sv_undef;
3520 i_ppix(im, x, y, cl)
3527 i_img_pal_new(x, y, channels, maxpal)
3534 i_img_to_pal(src, quant)
3540 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3541 croak("i_img_to_pal: second argument must be a hash ref");
3542 hv = (HV *)SvRV(ST(1));
3543 memset(&quant, 0, sizeof(quant));
3544 quant.mc_size = 256;
3545 handle_quant_opts(&quant, hv);
3546 RETVAL = i_img_to_pal(src, &quant);
3548 copy_colors_back(hv, &quant);
3550 cleanup_quant_opts(&quant);
3569 work = mymalloc((r-l) * sizeof(i_palidx));
3570 count = i_gpal(im, l, r, y, work);
3571 if (GIMME_V == G_ARRAY) {
3573 for (i = 0; i < count; ++i) {
3574 PUSHs(sv_2mortal(newSViv(work[i])));
3579 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3584 if (GIMME_V != G_ARRAY) {
3586 PUSHs(&PL_sv_undef);
3591 i_ppal(im, l, y, ...)
3600 work = mymalloc(sizeof(i_palidx) * (items-3));
3601 for (i=0; i < items-3; ++i) {
3602 work[i] = SvIV(ST(i+3));
3604 validate_i_ppal(im, work, items - 3);
3605 RETVAL = i_ppal(im, l, l+items-3, y, work);
3615 i_ppal_p(im, l, y, data)
3621 i_palidx const *work;
3624 work = (i_palidx const *)SvPV(data, len);
3625 len /= sizeof(i_palidx);
3627 validate_i_ppal(im, work, len);
3628 RETVAL = i_ppal(im, l, l+len, y, work);
3637 i_addcolors(im, ...)
3645 croak("i_addcolors: no colors to add");
3646 colors = mymalloc((items-1) * sizeof(i_color));
3647 for (i=0; i < items-1; ++i) {
3648 if (sv_isobject(ST(i+1))
3649 && sv_derived_from(ST(i+1), "Imager::Color")) {
3650 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3651 colors[i] = *INT2PTR(i_color *, tmp);
3655 croak("i_addcolor: pixels must be Imager::Color objects");
3658 index = i_addcolors(im, colors, items-1);
3661 RETVAL = newSVpv("0 but true", 0);
3663 else if (index == -1) {
3664 RETVAL = &PL_sv_undef;
3667 RETVAL = newSViv(index);
3673 i_setcolors(im, index, ...)
3681 croak("i_setcolors: no colors to add");
3682 colors = mymalloc((items-2) * sizeof(i_color));
3683 for (i=0; i < items-2; ++i) {
3684 if (sv_isobject(ST(i+2))
3685 && sv_derived_from(ST(i+2), "Imager::Color")) {
3686 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3687 colors[i] = *INT2PTR(i_color *, tmp);
3691 croak("i_setcolors: pixels must be Imager::Color objects");
3694 RETVAL = i_setcolors(im, index, colors, items-2);
3700 i_getcolors(im, index, ...)
3709 croak("i_getcolors: too many arguments");
3711 count = SvIV(ST(2));
3713 croak("i_getcolors: count must be positive");
3714 colors = mymalloc(sizeof(i_color) * count);
3715 if (i_getcolors(im, index, colors, count)) {
3716 for (i = 0; i < count; ++i) {
3718 SV *sv = sv_newmortal();
3719 pv = mymalloc(sizeof(i_color));
3721 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3737 i_findcolor(im, color)
3743 if (i_findcolor(im, color, &index)) {
3744 RETVAL = newSViv(index);
3747 RETVAL = &PL_sv_undef;
3765 i_gsamp(im, l, r, y, ...)
3777 croak("No channel numbers supplied to g_samp()");
3779 chan_count = items - 4;
3780 chans = mymalloc(sizeof(int) * chan_count);
3781 for (i = 0; i < chan_count; ++i)
3782 chans[i] = SvIV(ST(i+4));
3783 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3784 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3786 if (GIMME_V == G_ARRAY) {
3788 for (i = 0; i < count; ++i)
3789 PUSHs(sv_2mortal(newSViv(data[i])));
3793 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3798 if (GIMME_V != G_ARRAY) {
3800 PUSHs(&PL_sv_undef);
3805 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3821 croak("No channel numbers supplied to g_samp()");
3823 chan_count = items - 7;
3824 chans = mymalloc(sizeof(int) * chan_count);
3825 for (i = 0; i < chan_count; ++i)
3826 chans[i] = SvIV(ST(i+7));
3827 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3828 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3830 for (i = 0; i < count; ++i) {
3831 av_store(target, i+offset, newSVuv(data[i]));
3843 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3861 if (SvOK(channels_sv)) {
3863 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3864 croak("channels is not an array ref");
3866 channels_av = (AV *)SvRV(channels_sv);
3867 chan_count = av_len(channels_av) + 1;
3868 if (chan_count < 1) {
3869 croak("i_psamp_bits: no channels provided");
3871 channels = mymalloc(sizeof(int) * chan_count);
3872 for (i = 0; i < chan_count; ++i)
3873 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3876 chan_count = im->channels;
3880 data_count = av_len(data_av) + 1;
3881 if (data_offset < 0) {
3882 croak("data_offset must by non-negative");
3884 if (data_offset > data_count) {
3885 croak("data_offset greater than number of samples supplied");
3887 if (pixel_count == -1 ||
3888 data_offset + pixel_count * chan_count > data_count) {
3889 pixel_count = (data_count - data_offset) / chan_count;
3892 data_used = pixel_count * chan_count;
3893 data = mymalloc(sizeof(unsigned) * data_count);
3894 for (i = 0; i < data_used; ++i)
3895 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3897 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3908 i_img_masked_new(targ, mask, x, y, w, h)
3918 if (!sv_isobject(ST(1))
3919 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3920 croak("i_img_masked_new: parameter 2 must undef or an image");
3922 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3926 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3931 i_plin(im, l, y, ...)
3942 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3943 /* supplied as a byte string */
3944 work = (i_color *)SvPV(ST(3), len);
3945 count = len / sizeof(i_color);
3946 if (count * sizeof(i_color) != len) {
3947 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3949 RETVAL = i_plin(im, l, l+count, y, work);
3952 work = mymalloc(sizeof(i_color) * (items-3));
3953 for (i=0; i < items-3; ++i) {
3954 if (sv_isobject(ST(i+3))
3955 && sv_derived_from(ST(i+3), "Imager::Color")) {
3956 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3957 work[i] = *INT2PTR(i_color *, tmp);
3961 croak("i_plin: pixels must be Imager::Color objects");
3964 RETVAL = i_plin(im, l, l+items-3, y, work);
3975 i_ppixf(im, x, y, cl)
3979 Imager::Color::Float cl
3982 i_gsampf(im, l, r, y, ...)
3994 croak("No channel numbers supplied to g_sampf()");
3996 chan_count = items - 4;
3997 chans = mymalloc(sizeof(int) * chan_count);
3998 for (i = 0; i < chan_count; ++i)
3999 chans[i] = SvIV(ST(i+4));
4000 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
4001 count = i_gsampf(im, l, r, y, data, chans, chan_count);
4003 if (GIMME_V == G_ARRAY) {
4005 for (i = 0; i < count; ++i)
4006 PUSHs(sv_2mortal(newSVnv(data[i])));
4010 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
4015 if (GIMME_V != G_ARRAY) {
4017 PUSHs(&PL_sv_undef);
4022 i_plinf(im, l, y, ...)
4033 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
4034 /* supplied as a byte string */
4035 work = (i_fcolor *)SvPV(ST(3), len);
4036 count = len / sizeof(i_fcolor);
4037 if (count * sizeof(i_fcolor) != len) {
4038 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
4040 RETVAL = i_plinf(im, l, l+count, y, work);
4043 work = mymalloc(sizeof(i_fcolor) * (items-3));
4044 for (i=0; i < items-3; ++i) {
4045 if (sv_isobject(ST(i+3))
4046 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
4047 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
4048 work[i] = *INT2PTR(i_fcolor *, tmp);
4052 croak("i_plinf: pixels must be Imager::Color::Float objects");
4056 RETVAL = i_plinf(im, l, l+items-3, y, work);
4074 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
4075 if (i_gpixf(im, x, y, color) == 0) {
4076 RETVAL = NEWSV(0,0);
4077 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
4081 RETVAL = &PL_sv_undef;
4097 vals = mymalloc((r-l) * sizeof(i_color));
4098 memset(vals, 0, (r-l) * sizeof(i_color));
4099 count = i_glin(im, l, r, y, vals);
4100 if (GIMME_V == G_ARRAY) {
4102 for (i = 0; i < count; ++i) {
4104 i_color *col = mymalloc(sizeof(i_color));
4106 sv = sv_newmortal();
4107 sv_setref_pv(sv, "Imager::Color", (void *)col);
4113 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
4119 i_glinf(im, l, r, y)
4129 for (i = 0; i < MAXCHANNELS; ++i)
4130 zero.channel[i] = 0;
4132 vals = mymalloc((r-l) * sizeof(i_fcolor));
4133 for (i = 0; i < r-l; ++i)
4135 count = i_glinf(im, l, r, y, vals);
4136 if (GIMME_V == G_ARRAY) {
4138 for (i = 0; i < count; ++i) {
4140 i_fcolor *col = mymalloc(sizeof(i_fcolor));
4142 sv = sv_newmortal();
4143 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
4149 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
4155 i_img_16_new(x, y, ch)
4165 i_img_double_new(x, y, ch)
4171 i_tags_addn(im, name, code, idata)
4180 name = SvPV(ST(1), len);
4183 RETVAL = i_tags_addn(&im->tags, name, code, idata);
4188 i_tags_add(im, name, code, data, idata)
4198 name = SvPV(ST(1), len);
4202 data = SvPV(ST(3), len);
4207 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
4212 i_tags_find(im, name, start)
4219 if (i_tags_find(&im->tags, name, start, &entry)) {
4221 RETVAL = newSVpv("0 but true", 0);
4223 RETVAL = newSViv(entry);
4225 RETVAL = &PL_sv_undef;
4231 i_tags_findn(im, code, start)
4238 if (i_tags_findn(&im->tags, code, start, &entry)) {
4240 RETVAL = newSVpv("0 but true", 0);
4242 RETVAL = newSViv(entry);
4245 RETVAL = &PL_sv_undef;
4251 i_tags_delete(im, entry)
4255 RETVAL = i_tags_delete(&im->tags, entry);
4260 i_tags_delbyname(im, name)
4264 RETVAL = i_tags_delbyname(&im->tags, name);
4269 i_tags_delbycode(im, code)
4273 RETVAL = i_tags_delbycode(&im->tags, code);
4278 i_tags_get(im, index)
4282 if (index >= 0 && index < im->tags.count) {
4283 i_img_tag *entry = im->tags.tags + index;
4287 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4290 PUSHs(sv_2mortal(newSViv(entry->code)));
4293 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4296 PUSHs(sv_2mortal(newSViv(entry->idata)));
4301 i_tags_get_string(im, what_sv)
4305 char const *name = NULL;
4309 if (SvIOK(what_sv)) {
4310 code = SvIV(what_sv);
4314 name = SvPV_nolen(what_sv);
4317 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4319 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4326 RETVAL = im->tags.count;
4333 i_wf_bbox(face, size, text_sv, utf8=0)
4339 int cords[BOUNDING_BOX_COUNT];
4344 text = SvPV(text_sv, text_len);
4346 if (SvUTF8(text_sv))
4349 if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) {
4351 for (i = 0; i < rc; ++i)
4352 PUSHs(sv_2mortal(newSViv(cords[i])));
4356 i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
4371 text = SvPV(text_sv, text_len);
4373 if (SvUTF8(text_sv))
4376 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len,
4382 i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
4397 text = SvPV(text_sv, text_len);
4399 if (SvUTF8(text_sv))
4402 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len,
4419 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4421 #define FT2_DESTROY(font) i_ft2_destroy(font)
4425 Imager::Font::FT2 font
4427 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4430 i_ft2_new(name, index)
4435 i_ft2_setdpi(font, xdpi, ydpi)
4436 Imager::Font::FT2 font
4442 Imager::Font::FT2 font
4446 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4448 PUSHs(sv_2mortal(newSViv(xdpi)));
4449 PUSHs(sv_2mortal(newSViv(ydpi)));
4453 i_ft2_sethinting(font, hinting)
4454 Imager::Font::FT2 font
4458 i_ft2_settransform(font, matrix)
4459 Imager::Font::FT2 font
4467 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4468 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4469 av=(AV*)SvRV(ST(1));
4473 for (i = 0; i < len; ++i) {
4474 sv1=(*(av_fetch(av,i,0)));
4475 matrix[i] = SvNV(sv1);
4479 RETVAL = i_ft2_settransform(font, matrix);
4484 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4485 Imager::Font::FT2 font
4491 int bbox[BOUNDING_BOX_COUNT];
4497 text = SvPV(text_sv, text_len);
4499 if (SvUTF8(text_sv))
4502 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4505 for (i = 0; i < rc; ++i)
4506 PUSHs(sv_2mortal(newSViv(bbox[i])));
4510 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4511 Imager::Font::FT2 font
4525 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4528 for (i = 0; i < 8; ++i)
4529 PUSHs(sv_2mortal(newSViv(bbox[i])));
4533 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4534 Imager::Font::FT2 font
4550 if (SvUTF8(ST(7))) {
4554 text = SvPV(ST(7), len);
4555 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4556 len, align, aa, vlayout, utf8);
4561 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
4562 Imager::Font::FT2 font
4582 text = SvPV(text_sv, len);
4583 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4584 len, align, aa, vlayout, 1);
4589 ft2_transform_box(font, x0, x1, x2, x3)
4590 Imager::Font::FT2 font
4598 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4599 ft2_transform_box(font, box);
4601 PUSHs(sv_2mortal(newSViv(box[0])));
4602 PUSHs(sv_2mortal(newSViv(box[1])));
4603 PUSHs(sv_2mortal(newSViv(box[2])));
4604 PUSHs(sv_2mortal(newSViv(box[3])));
4607 i_ft2_has_chars(handle, text_sv, utf8)
4608 Imager::Font::FT2 handle
4619 if (SvUTF8(text_sv))
4622 text = SvPV(text_sv, len);
4623 work = mymalloc(len);
4624 count = i_ft2_has_chars(handle, text, len, utf8, work);
4625 if (GIMME_V == G_ARRAY) {
4627 for (i = 0; i < count; ++i) {
4628 PUSHs(sv_2mortal(newSViv(work[i])));
4633 PUSHs(sv_2mortal(newSVpv(work, count)));
4638 i_ft2_face_name(handle)
4639 Imager::Font::FT2 handle
4644 len = i_ft2_face_name(handle, name, sizeof(name));
4647 PUSHs(sv_2mortal(newSVpv(name, 0)));
4651 i_ft2_can_face_name()
4654 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4655 Imager::Font::FT2 handle
4666 if (SvUTF8(text_sv))
4669 text = SvPV(text_sv, work_len);
4674 ch = i_utf8_advance(&text, &len);
4676 i_push_error(0, "invalid UTF8 character");
4685 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4687 PUSHs(sv_2mortal(newSVpv(name, 0)));
4690 PUSHs(&PL_sv_undef);
4695 i_ft2_can_do_glyph_names()
4698 i_ft2_face_has_glyph_names(handle)
4699 Imager::Font::FT2 handle
4702 i_ft2_is_multiple_master(handle)
4703 Imager::Font::FT2 handle
4706 i_ft2_get_multiple_masters(handle)
4707 Imager::Font::FT2 handle
4712 if (i_ft2_get_multiple_masters(handle, &mm)) {
4713 EXTEND(SP, 2+mm.num_axis);
4714 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4715 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4716 for (i = 0; i < mm.num_axis; ++i) {
4720 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4722 av_store(av, 0, sv);
4723 sv = newSViv(mm.axis[i].minimum);
4725 av_store(av, 1, sv);
4726 sv = newSViv(mm.axis[i].maximum);
4728 av_store(av, 2, sv);
4729 PUSHs(newRV_noinc((SV *)av));
4734 i_ft2_set_mm_coords(handle, ...)
4735 Imager::Font::FT2 handle
4741 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4742 transfer the array manually */
4743 ix_coords = items-1;
4744 coords = mymalloc(sizeof(long) * ix_coords);
4745 for (i = 0; i < ix_coords; ++i) {
4746 coords[i] = (long)SvIV(ST(1+i));
4748 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4755 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4759 Imager::FillHandle fill
4761 MODULE = Imager PACKAGE = Imager
4764 i_new_fill_solid(cl, combine)
4769 i_new_fill_solidf(cl, combine)
4770 Imager::Color::Float cl
4774 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4782 unsigned char *cust_hatch;
4786 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4790 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4795 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4796 Imager::Color::Float fg
4797 Imager::Color::Float bg
4803 unsigned char *cust_hatch;
4807 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4811 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4816 i_new_fill_image(src, matrix, xoff, yoff, combine)
4833 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4834 croak("i_new_fill_image: parameter must be an arrayref");
4835 av=(AV*)SvRV(ST(1));
4839 for (i = 0; i < len; ++i) {
4840 sv1=(*(av_fetch(av,i,0)));
4841 matrix[i] = SvNV(sv1);
4847 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4851 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4853 # this class is only exposed for testing
4856 i_int_hlines_testing()
4858 #if i_int_hlines_testing()
4860 Imager::Internal::Hlines
4861 i_int_hlines_new(start_y, count_y, start_x, count_x)
4867 Imager::Internal::Hlines
4868 i_int_hlines_new_img(im)
4872 i_int_hlines_add(hlines, y, minx, width)
4873 Imager::Internal::Hlines hlines
4879 i_int_hlines_DESTROY(hlines)
4880 Imager::Internal::Hlines hlines
4883 i_int_hlines_dump(hlines)
4884 Imager::Internal::Hlines hlines
4889 PERL_SET_GLOBAL_CALLBACKS;