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(src, avmain)
1747 outchan = av_len(avmain)+1;
1748 /* find the biggest */
1750 for (j=0; j < outchan; ++j) {
1751 temp = av_fetch(avmain, j, 0);
1752 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1753 avsub = (AV*)SvRV(*temp);
1754 len = av_len(avsub)+1;
1759 coeff = mymalloc(sizeof(float) * outchan * inchan);
1760 for (j = 0; j < outchan; ++j) {
1761 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1762 len = av_len(avsub)+1;
1763 for (i = 0; i < len; ++i) {
1764 temp = av_fetch(avsub, i, 0);
1766 coeff[i+j*inchan] = SvNV(*temp);
1768 coeff[i+j*inchan] = 0;
1771 coeff[i++ + j*inchan] = 0;
1773 RETVAL = i_convert(src, coeff, outchan, inchan);
1783 unsigned int mask = 0;
1789 unsigned char (*maps)[256];
1791 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1792 croak("i_map: parameter 2 must be an arrayref\n");
1793 avmain = (AV*)SvRV(ST(1));
1794 len = av_len(avmain)+1;
1795 if (im->channels < len) len = im->channels;
1797 maps = mymalloc( len * sizeof(unsigned char [256]) );
1799 for (j=0; j<len ; j++) {
1800 temp = av_fetch(avmain, j, 0);
1801 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1802 avsub = (AV*)SvRV(*temp);
1803 if(av_len(avsub) != 255) continue;
1805 for (i=0; i<256 ; i++) {
1807 temp = av_fetch(avsub, i, 0);
1808 val = temp ? SvIV(*temp) : 0;
1810 if (val>255) val = 255;
1815 i_map(im, maps, mask);
1828 i_init_fonts(t1log=0)
1843 i_t1_destroy(font_id)
1848 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1867 str = SvPV(str_sv, len);
1868 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1875 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1884 int cords[BOUNDING_BOX_COUNT];
1892 str = SvPV(str_sv, len);
1893 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1896 for (i = 0; i < rc; ++i)
1897 PUSHs(sv_2mortal(newSViv(cords[i])));
1903 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1922 str = SvPV(str_sv, len);
1923 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1929 i_t1_has_chars(handle, text_sv, utf8 = 0)
1941 if (SvUTF8(text_sv))
1944 text = SvPV(text_sv, len);
1945 work = mymalloc(len);
1946 count = i_t1_has_chars(handle, text, len, utf8, work);
1947 if (GIMME_V == G_ARRAY) {
1949 for (i = 0; i < count; ++i) {
1950 PUSHs(sv_2mortal(newSViv(work[i])));
1955 PUSHs(sv_2mortal(newSVpv(work, count)));
1960 i_t1_face_name(handle)
1966 len = i_t1_face_name(handle, name, sizeof(name));
1969 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1973 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1984 if (SvUTF8(text_sv))
1987 text = SvPV(text_sv, work_len);
1992 ch = i_utf8_advance(&text, &len);
1994 i_push_error(0, "invalid UTF8 character");
2003 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
2004 PUSHs(sv_2mortal(newSVpv(name, 0)));
2007 PUSHs(&PL_sv_undef);
2021 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2023 #define TT_DESTROY(handle) i_tt_destroy(handle)
2027 Imager::Font::TT handle
2030 MODULE = Imager PACKAGE = Imager
2034 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2035 Imager::Font::TT handle
2053 str = SvPV(str_sv, len);
2054 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2055 len, smooth, utf8, align);
2061 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2062 Imager::Font::TT handle
2080 str = SvPV(str_sv, len);
2081 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2082 smooth, utf8, align);
2088 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2089 Imager::Font::TT handle
2094 int cords[BOUNDING_BOX_COUNT],rc;
2103 str = SvPV(str_sv, len);
2104 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2106 for (i = 0; i < rc; ++i) {
2107 PUSHs(sv_2mortal(newSViv(cords[i])));
2112 i_tt_has_chars(handle, text_sv, utf8)
2113 Imager::Font::TT handle
2124 if (SvUTF8(text_sv))
2127 text = SvPV(text_sv, len);
2128 work = mymalloc(len);
2129 count = i_tt_has_chars(handle, text, len, utf8, work);
2130 if (GIMME_V == G_ARRAY) {
2132 for (i = 0; i < count; ++i) {
2133 PUSHs(sv_2mortal(newSViv(work[i])));
2138 PUSHs(sv_2mortal(newSVpv(work, count)));
2143 i_tt_dump_names(handle)
2144 Imager::Font::TT handle
2147 i_tt_face_name(handle)
2148 Imager::Font::TT handle
2153 len = i_tt_face_name(handle, name, sizeof(name));
2156 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2160 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2161 Imager::Font::TT handle
2172 if (SvUTF8(text_sv))
2175 text = SvPV(text_sv, work_len);
2180 ch = i_utf8_advance(&text, &len);
2182 i_push_error(0, "invalid UTF8 character");
2191 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2192 PUSHs(sv_2mortal(newSVpv(name, 0)));
2195 PUSHs(&PL_sv_undef);
2204 i_writejpeg_wiol(im, ig, qfactor)
2220 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2221 if (iptc_itext == NULL) {
2224 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2229 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2231 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2242 i_test_format_probe(ig, length)
2251 i_readtiff_wiol(ig, allow_incomplete, page=0)
2253 int allow_incomplete
2257 i_readtiff_multi_wiol(ig, length)
2265 imgs = i_readtiff_multi_wiol(ig, length, &count);
2268 for (i = 0; i < count; ++i) {
2269 SV *sv = sv_newmortal();
2270 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2278 i_writetiff_wiol(im, ig)
2283 i_writetiff_multi_wiol(ig, ...)
2291 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2292 img_count = items - 1;
2294 if (img_count < 1) {
2297 i_push_error(0, "You need to specify images to save");
2300 imgs = mymalloc(sizeof(i_img *) * img_count);
2301 for (i = 0; i < img_count; ++i) {
2304 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2305 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2309 i_push_error(0, "Only images can be saved");
2316 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2324 i_writetiff_wiol_faxable(im, ig, fine)
2330 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2339 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2340 img_count = items - 2;
2342 if (img_count < 1) {
2345 i_push_error(0, "You need to specify images to save");
2348 imgs = mymalloc(sizeof(i_img *) * img_count);
2349 for (i = 0; i < img_count; ++i) {
2352 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2353 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2357 i_push_error(0, "Only images can be saved");
2364 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2372 #endif /* HAVE_LIBTIFF */
2378 i_readpng_wiol(ig, length)
2384 i_writepng_wiol(im, ig)
2397 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2400 i_writegif(im,fd,colors,pixdev,fixed)
2407 Imager__Color fixed;
2414 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2415 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2416 av=(AV*)SvRV(ST(4));
2417 fixedlen=av_len(av)+1;
2418 fixed=mymalloc( fixedlen*sizeof(i_color) );
2419 for(i=0;i<fixedlen;i++) {
2420 sv1=(*(av_fetch(av,i,0)));
2421 if (sv_derived_from(sv1, "Imager::Color")) {
2422 Itmp = SvIV((SV*)SvRV(sv1));
2423 tmp = INT2PTR(i_color*, Itmp);
2424 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2427 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2429 ST(0) = sv_newmortal();
2430 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2431 else sv_setiv(ST(0), (IV)RETVAL);
2437 i_writegifmc(im,fd,colors)
2444 i_writegif_gen(fd, ...)
2449 i_img **imgs = NULL;
2455 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2456 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2457 croak("i_writegif_gen: Second argument must be a hash ref");
2458 hv = (HV *)SvRV(ST(1));
2459 memset(&quant, 0, sizeof(quant));
2460 quant.mc_size = 256;
2461 quant.transp = tr_threshold;
2462 quant.tr_threshold = 127;
2463 handle_quant_opts(&quant, hv);
2464 img_count = items - 2;
2466 if (img_count < 1) {
2469 i_push_error(0, "You need to specify images to save");
2472 imgs = mymalloc(sizeof(i_img *) * img_count);
2473 for (i = 0; i < img_count; ++i) {
2476 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2477 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2481 i_push_error(0, "Only images can be saved");
2487 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2491 copy_colors_back(hv, &quant);
2494 ST(0) = sv_newmortal();
2495 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2496 else sv_setiv(ST(0), (IV)RETVAL);
2497 cleanup_quant_opts(&quant);
2501 i_writegif_callback(cb, maxbuffer,...)
2505 i_img **imgs = NULL;
2512 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2513 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2514 croak("i_writegif_callback: Second argument must be a hash ref");
2515 hv = (HV *)SvRV(ST(2));
2516 memset(&quant, 0, sizeof(quant));
2517 quant.mc_size = 256;
2518 quant.transp = tr_threshold;
2519 quant.tr_threshold = 127;
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 quant.transp = tr_threshold;
2571 quant.tr_threshold = 127;
2572 handle_quant_opts(&quant, hv);
2573 img_count = items - 2;
2575 if (img_count < 1) {
2579 imgs = mymalloc(sizeof(i_img *) * img_count);
2580 for (i = 0; i < img_count; ++i) {
2583 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2584 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2592 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2596 copy_colors_back(hv, &quant);
2599 ST(0) = sv_newmortal();
2600 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2601 else sv_setiv(ST(0), (IV)RETVAL);
2602 cleanup_quant_opts(&quant);
2615 colour_table = NULL;
2618 if(GIMME_V == G_ARRAY) {
2619 rimg = i_readgif(fd,&colour_table,&colours);
2621 /* don't waste time with colours if they aren't wanted */
2622 rimg = i_readgif(fd,NULL,NULL);
2625 if (colour_table == NULL) {
2628 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2631 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2632 /* I don't know if I have the reference counts right or not :( */
2633 /* Neither do I :-) */
2634 /* No Idea here either */
2637 av_extend(ct, colours);
2638 for(q=0; q<colours; q++) {
2640 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2641 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2643 myfree(colour_table);
2647 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2649 PUSHs(newRV_noinc((SV*)ct));
2663 colour_table = NULL;
2666 if(GIMME_V == G_ARRAY) {
2667 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2669 /* don't waste time with colours if they aren't wanted */
2670 rimg = i_readgif_wiol(ig,NULL,NULL);
2673 if (colour_table == NULL) {
2676 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2679 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2680 /* I don't know if I have the reference counts right or not :( */
2681 /* Neither do I :-) */
2682 /* No Idea here either */
2685 av_extend(ct, colours);
2686 for(q=0; q<colours; q++) {
2688 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2689 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2691 myfree(colour_table);
2695 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2697 PUSHs(newRV_noinc((SV*)ct));
2701 i_readgif_single_wiol(ig, page=0)
2706 i_readgif_scalar(...)
2718 data = (char *)SvPV(ST(0), length);
2722 if(GIMME_V == G_ARRAY) {
2723 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2725 /* don't waste time with colours if they aren't wanted */
2726 rimg=i_readgif_scalar(data,length,NULL,NULL);
2729 if (colour_table == NULL) {
2732 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2735 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2736 /* I don't know if I have the reference counts right or not :( */
2737 /* Neither do I :-) */
2739 av_extend(ct, colours);
2740 for(q=0; q<colours; q++) {
2742 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2743 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2745 myfree(colour_table);
2749 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2751 PUSHs(newRV_noinc((SV*)ct));
2755 i_readgif_callback(...)
2770 if(GIMME_V == G_ARRAY) {
2771 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2773 /* don't waste time with colours if they aren't wanted */
2774 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2777 if (colour_table == NULL) {
2780 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2783 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2784 /* I don't know if I have the reference counts right or not :( */
2785 /* Neither do I :-) */
2786 /* Neither do I - maybe I'll move this somewhere */
2788 av_extend(ct, colours);
2789 for(q=0; q<colours; q++) {
2791 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2792 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2794 myfree(colour_table);
2798 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2800 PUSHs(newRV_noinc((SV*)ct));
2811 imgs = i_readgif_multi(fd, &count);
2814 for (i = 0; i < count; ++i) {
2815 SV *sv = sv_newmortal();
2816 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2823 i_readgif_multi_scalar(data)
2831 data = (char *)SvPV(ST(0), length);
2832 imgs = i_readgif_multi_scalar(data, length, &count);
2835 for (i = 0; i < count; ++i) {
2836 SV *sv = sv_newmortal();
2837 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2844 i_readgif_multi_callback(cb)
2852 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2855 for (i = 0; i < count; ++i) {
2856 SV *sv = sv_newmortal();
2857 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2864 i_readgif_multi_wiol(ig)
2871 imgs = i_readgif_multi_wiol(ig, &count);
2874 for (i = 0; i < count; ++i) {
2875 SV *sv = sv_newmortal();
2876 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2888 i_readpnm_wiol(ig, allow_incomplete)
2890 int allow_incomplete
2894 i_writeppm_wiol(im, ig)
2900 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2909 i_writeraw_wiol(im,ig)
2914 i_writebmp_wiol(im,ig)
2919 i_readbmp_wiol(ig, allow_incomplete=0)
2921 int allow_incomplete
2925 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2934 idlen = SvCUR(ST(4));
2935 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2941 i_readtga_wiol(ig, length)
2949 i_scaleaxis(im,Value,Axis)
2955 i_scale_nn(im,scx,scy)
2961 i_scale_mixing(im, width, height)
2971 i_count_colors(im,maxc)
2976 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2981 unsigned int * col_usage = NULL;
2984 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2985 EXTEND(SP, col_cnt);
2986 for (i = 0; i < col_cnt; i++) {
2987 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2994 i_transform(im,opx,opy,parm)
3007 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
3008 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
3009 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
3010 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
3011 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
3012 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
3013 av=(AV*)SvRV(ST(1));
3015 opx=mymalloc( opxl*sizeof(int) );
3016 for(i=0;i<opxl;i++) {
3017 sv1=(*(av_fetch(av,i,0)));
3018 opx[i]=(int)SvIV(sv1);
3020 av=(AV*)SvRV(ST(2));
3022 opy=mymalloc( opyl*sizeof(int) );
3023 for(i=0;i<opyl;i++) {
3024 sv1=(*(av_fetch(av,i,0)));
3025 opy[i]=(int)SvIV(sv1);
3027 av=(AV*)SvRV(ST(3));
3028 parmlen=av_len(av)+1;
3029 parm=mymalloc( parmlen*sizeof(double) );
3030 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
3031 sv1=(*(av_fetch(av,i,0)));
3032 parm[i]=(double)SvNV(sv1);
3034 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
3038 ST(0) = sv_newmortal();
3039 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3040 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3043 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
3068 in_imgs_count = av_len(av_in_imgs)+1;
3069 for (i = 0; i < in_imgs_count; ++i) {
3070 sv1 = *av_fetch(av_in_imgs, i, 0);
3071 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3072 croak("sv_in_img must contain only images");
3075 if (in_imgs_count > 0) {
3076 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
3077 for (i = 0; i < in_imgs_count; ++i) {
3078 sv1 = *av_fetch(av_in_imgs,i,0);
3079 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
3080 croak("Parameter 5 must contain only images");
3082 tmp = SvIV((SV*)SvRV(sv1));
3083 in_imgs[i] = INT2PTR(i_img*, tmp);
3087 /* no input images */
3090 /* default the output size from the first input if possible */
3092 width = SvIV(sv_width);
3093 else if (in_imgs_count)
3094 width = in_imgs[0]->xsize;
3096 croak("No output image width supplied");
3098 if (SvOK(sv_height))
3099 height = SvIV(sv_height);
3100 else if (in_imgs_count)
3101 height = in_imgs[0]->ysize;
3103 croak("No output image height supplied");
3105 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
3106 if (ops_len % sizeof(struct rm_op))
3107 croak("Imager: Parameter 3 must be a bitmap of regops\n");
3108 ops_count = ops_len / sizeof(struct rm_op);
3110 n_regs_count = av_len(av_n_regs)+1;
3111 n_regs = mymalloc(n_regs_count * sizeof(double));
3112 for (i = 0; i < n_regs_count; ++i) {
3113 sv1 = *av_fetch(av_n_regs,i,0);
3115 n_regs[i] = SvNV(sv1);
3117 c_regs_count = av_len(av_c_regs)+1;
3118 c_regs = mymalloc(c_regs_count * sizeof(i_color));
3119 /* I don't bother initializing the colou?r registers */
3121 RETVAL=i_transform2(width, height, channels, ops, ops_count,
3122 n_regs, n_regs_count,
3123 c_regs, c_regs_count, in_imgs, in_imgs_count);
3128 ST(0) = sv_newmortal();
3129 if (RETVAL == 0) ST(0)=&PL_sv_undef;
3130 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
3134 i_contrast(im,intensity)
3143 i_noise(im,amount,type)
3149 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3159 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3178 i_postlevels(im,levels)
3188 i_watermark(im,wmark,tx,ty,pixdiff)
3190 Imager::ImgRaw wmark
3197 i_autolevels(im,lsat,usat,skew)
3204 i_radnoise(im,xo,yo,rscale,ascale)
3212 i_turbnoise(im, xo, yo, scale)
3235 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3236 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3237 croak("i_gradgen: Second argument must be an array ref");
3238 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3239 croak("i_gradgen: Third argument must be an array ref");
3240 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3241 croak("i_gradgen: Fourth argument must be an array ref");
3242 axx = (AV *)SvRV(ST(1));
3243 ayy = (AV *)SvRV(ST(2));
3244 ac = (AV *)SvRV(ST(3));
3245 dmeasure = (int)SvIV(ST(4));
3247 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3248 num = num <= av_len(ac) ? num : av_len(ac);
3250 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3251 xo = mymalloc( sizeof(int) * num );
3252 yo = mymalloc( sizeof(int) * num );
3253 ival = mymalloc( sizeof(i_color) * num );
3254 for(i = 0; i<num; i++) {
3255 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3256 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3257 sv = *av_fetch(ac, i, 0);
3258 if ( !sv_derived_from(sv, "Imager::Color") ) {
3259 free(axx); free(ayy); free(ac);
3260 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3262 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3264 i_gradgen(im, num, xo, yo, ival, dmeasure);
3270 i_diff_image(im, im2, mindist=0)
3276 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3286 double ssample_param
3290 i_fountain_seg *segs;
3292 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3293 croak("i_fountain: argument 11 must be an array ref");
3295 asegs = (AV *)SvRV(ST(10));
3296 segs = load_fount_segs(asegs, &count);
3297 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3298 super_sample, ssample_param, count, segs);
3304 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3313 double ssample_param
3317 i_fountain_seg *segs;
3319 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3320 croak("i_fountain: argument 11 must be an array ref");
3322 asegs = (AV *)SvRV(ST(9));
3323 segs = load_fount_segs(asegs, &count);
3324 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3325 super_sample, ssample_param, count, segs);
3338 errors = i_errors();
3340 while (errors[i].msg) {
3342 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3343 if (!av_store(av, 0, sv)) {
3346 sv = newSViv(errors[i].code);
3347 if (!av_store(av, 1, sv)) {
3350 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3358 i_push_error(code, msg)
3363 i_nearest_color(im, ...)
3378 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3379 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3380 croak("i_nearest_color: Second argument must be an array ref");
3381 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3382 croak("i_nearest_color: Third argument must be an array ref");
3383 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3384 croak("i_nearest_color: Fourth argument must be an array ref");
3385 axx = (AV *)SvRV(ST(1));
3386 ayy = (AV *)SvRV(ST(2));
3387 ac = (AV *)SvRV(ST(3));
3388 dmeasure = (int)SvIV(ST(4));
3390 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3391 num = num <= av_len(ac) ? num : av_len(ac);
3393 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3394 xo = mymalloc( sizeof(int) * num );
3395 yo = mymalloc( sizeof(int) * num );
3396 ival = mymalloc( sizeof(i_color) * num );
3397 for(i = 0; i<num; i++) {
3398 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3399 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3400 sv = *av_fetch(ac, i, 0);
3401 if ( !sv_derived_from(sv, "Imager::Color") ) {
3402 free(axx); free(ayy); free(ac);
3403 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3405 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3407 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3421 rc=DSO_open(filename,&evstr);
3425 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3426 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3429 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3435 DSO_close(dso_handle)
3439 DSO_funclist(dso_handle_v)
3443 DSO_handle *dso_handle;
3445 dso_handle=(DSO_handle*)dso_handle_v;
3447 while( dso_handle->function_list[i].name != NULL) {
3449 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3451 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3456 DSO_call(handle,func_index,hv)
3462 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3463 hv=(HV*)SvRV(ST(2));
3464 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3465 DSO_call( (DSO_handle *)handle,func_index,hv);
3470 i_get_pixel(im, x, y)
3477 color = (i_color *)mymalloc(sizeof(i_color));
3478 if (i_gpix(im, x, y, color) == 0) {
3479 RETVAL = NEWSV(0, 0);
3480 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3484 RETVAL = &PL_sv_undef;
3491 i_ppix(im, x, y, cl)
3498 i_img_pal_new(x, y, channels, maxpal)
3505 i_img_to_pal(src, quant)
3511 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3512 croak("i_img_to_pal: second argument must be a hash ref");
3513 hv = (HV *)SvRV(ST(1));
3514 memset(&quant, 0, sizeof(quant));
3515 quant.mc_size = 256;
3516 handle_quant_opts(&quant, hv);
3517 RETVAL = i_img_to_pal(src, &quant);
3519 copy_colors_back(hv, &quant);
3521 cleanup_quant_opts(&quant);
3540 work = mymalloc((r-l) * sizeof(i_palidx));
3541 count = i_gpal(im, l, r, y, work);
3542 if (GIMME_V == G_ARRAY) {
3544 for (i = 0; i < count; ++i) {
3545 PUSHs(sv_2mortal(newSViv(work[i])));
3550 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3555 if (GIMME_V != G_ARRAY) {
3557 PUSHs(&PL_sv_undef);
3562 i_ppal(im, l, y, ...)
3571 work = mymalloc(sizeof(i_palidx) * (items-3));
3572 for (i=0; i < items-3; ++i) {
3573 work[i] = SvIV(ST(i+3));
3575 validate_i_ppal(im, work, items - 3);
3576 RETVAL = i_ppal(im, l, l+items-3, y, work);
3586 i_ppal_p(im, l, y, data)
3592 i_palidx const *work;
3595 work = (i_palidx const *)SvPV(data, len);
3596 len /= sizeof(i_palidx);
3598 validate_i_ppal(im, work, len);
3599 RETVAL = i_ppal(im, l, l+len, y, work);
3608 i_addcolors(im, ...)
3616 croak("i_addcolors: no colors to add");
3617 colors = mymalloc((items-1) * sizeof(i_color));
3618 for (i=0; i < items-1; ++i) {
3619 if (sv_isobject(ST(i+1))
3620 && sv_derived_from(ST(i+1), "Imager::Color")) {
3621 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3622 colors[i] = *INT2PTR(i_color *, tmp);
3626 croak("i_addcolor: pixels must be Imager::Color objects");
3629 index = i_addcolors(im, colors, items-1);
3632 RETVAL = newSVpv("0 but true", 0);
3634 else if (index == -1) {
3635 RETVAL = &PL_sv_undef;
3638 RETVAL = newSViv(index);
3644 i_setcolors(im, index, ...)
3652 croak("i_setcolors: no colors to add");
3653 colors = mymalloc((items-2) * sizeof(i_color));
3654 for (i=0; i < items-2; ++i) {
3655 if (sv_isobject(ST(i+2))
3656 && sv_derived_from(ST(i+2), "Imager::Color")) {
3657 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3658 colors[i] = *INT2PTR(i_color *, tmp);
3662 croak("i_setcolors: pixels must be Imager::Color objects");
3665 RETVAL = i_setcolors(im, index, colors, items-2);
3671 i_getcolors(im, index, ...)
3680 croak("i_getcolors: too many arguments");
3682 count = SvIV(ST(2));
3684 croak("i_getcolors: count must be positive");
3685 colors = mymalloc(sizeof(i_color) * count);
3686 if (i_getcolors(im, index, colors, count)) {
3687 for (i = 0; i < count; ++i) {
3689 SV *sv = sv_newmortal();
3690 pv = mymalloc(sizeof(i_color));
3692 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3708 i_findcolor(im, color)
3714 if (i_findcolor(im, color, &index)) {
3715 RETVAL = newSViv(index);
3718 RETVAL = &PL_sv_undef;
3736 i_gsamp(im, l, r, y, ...)
3748 croak("No channel numbers supplied to g_samp()");
3750 chan_count = items - 4;
3751 chans = mymalloc(sizeof(int) * chan_count);
3752 for (i = 0; i < chan_count; ++i)
3753 chans[i] = SvIV(ST(i+4));
3754 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3755 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3757 if (GIMME_V == G_ARRAY) {
3759 for (i = 0; i < count; ++i)
3760 PUSHs(sv_2mortal(newSViv(data[i])));
3764 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3769 if (GIMME_V != G_ARRAY) {
3771 PUSHs(&PL_sv_undef);
3777 i_img_masked_new(targ, mask, x, y, w, h)
3787 if (!sv_isobject(ST(1))
3788 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3789 croak("i_img_masked_new: parameter 2 must undef or an image");
3791 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3795 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3800 i_plin(im, l, y, ...)
3811 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3812 /* supplied as a byte string */
3813 work = (i_color *)SvPV(ST(3), len);
3814 count = len / sizeof(i_color);
3815 if (count * sizeof(i_color) != len) {
3816 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3818 RETVAL = i_plin(im, l, l+count, y, work);
3821 work = mymalloc(sizeof(i_color) * (items-3));
3822 for (i=0; i < items-3; ++i) {
3823 if (sv_isobject(ST(i+3))
3824 && sv_derived_from(ST(i+3), "Imager::Color")) {
3825 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3826 work[i] = *INT2PTR(i_color *, tmp);
3830 croak("i_plin: pixels must be Imager::Color objects");
3833 RETVAL = i_plin(im, l, l+items-3, y, work);
3844 i_ppixf(im, x, y, cl)
3848 Imager::Color::Float cl
3851 i_gsampf(im, l, r, y, ...)
3863 croak("No channel numbers supplied to g_sampf()");
3865 chan_count = items - 4;
3866 chans = mymalloc(sizeof(int) * chan_count);
3867 for (i = 0; i < chan_count; ++i)
3868 chans[i] = SvIV(ST(i+4));
3869 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3870 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3872 if (GIMME_V == G_ARRAY) {
3874 for (i = 0; i < count; ++i)
3875 PUSHs(sv_2mortal(newSVnv(data[i])));
3879 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3884 if (GIMME_V != G_ARRAY) {
3886 PUSHs(&PL_sv_undef);
3891 i_plinf(im, l, y, ...)
3902 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3903 /* supplied as a byte string */
3904 work = (i_fcolor *)SvPV(ST(3), len);
3905 count = len / sizeof(i_fcolor);
3906 if (count * sizeof(i_fcolor) != len) {
3907 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3909 RETVAL = i_plinf(im, l, l+count, y, work);
3912 work = mymalloc(sizeof(i_fcolor) * (items-3));
3913 for (i=0; i < items-3; ++i) {
3914 if (sv_isobject(ST(i+3))
3915 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3916 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3917 work[i] = *INT2PTR(i_fcolor *, tmp);
3921 croak("i_plinf: pixels must be Imager::Color::Float objects");
3925 RETVAL = i_plinf(im, l, l+items-3, y, work);
3943 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3944 if (i_gpixf(im, x, y, color) == 0) {
3945 RETVAL = NEWSV(0,0);
3946 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3950 RETVAL = &PL_sv_undef;
3966 vals = mymalloc((r-l) * sizeof(i_color));
3967 memset(vals, 0, (r-l) * sizeof(i_color));
3968 count = i_glin(im, l, r, y, vals);
3969 if (GIMME_V == G_ARRAY) {
3971 for (i = 0; i < count; ++i) {
3973 i_color *col = mymalloc(sizeof(i_color));
3975 sv = sv_newmortal();
3976 sv_setref_pv(sv, "Imager::Color", (void *)col);
3982 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3988 i_glinf(im, l, r, y)
3998 for (i = 0; i < MAXCHANNELS; ++i)
3999 zero.channel[i] = 0;
4001 vals = mymalloc((r-l) * sizeof(i_fcolor));
4002 for (i = 0; i < r-l; ++i)
4004 count = i_glinf(im, l, r, y, vals);
4005 if (GIMME_V == G_ARRAY) {
4007 for (i = 0; i < count; ++i) {
4009 i_fcolor *col = mymalloc(sizeof(i_fcolor));
4011 sv = sv_newmortal();
4012 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
4018 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
4024 i_img_16_new(x, y, ch)
4034 i_img_double_new(x, y, ch)
4040 i_tags_addn(im, name, code, idata)
4049 name = SvPV(ST(1), len);
4052 RETVAL = i_tags_addn(&im->tags, name, code, idata);
4057 i_tags_add(im, name, code, data, idata)
4067 name = SvPV(ST(1), len);
4071 data = SvPV(ST(3), len);
4076 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
4081 i_tags_find(im, name, start)
4088 if (i_tags_find(&im->tags, name, start, &entry)) {
4090 RETVAL = newSVpv("0 but true", 0);
4092 RETVAL = newSViv(entry);
4094 RETVAL = &PL_sv_undef;
4100 i_tags_findn(im, code, start)
4107 if (i_tags_findn(&im->tags, code, start, &entry)) {
4109 RETVAL = newSVpv("0 but true", 0);
4111 RETVAL = newSViv(entry);
4114 RETVAL = &PL_sv_undef;
4120 i_tags_delete(im, entry)
4124 RETVAL = i_tags_delete(&im->tags, entry);
4129 i_tags_delbyname(im, name)
4133 RETVAL = i_tags_delbyname(&im->tags, name);
4138 i_tags_delbycode(im, code)
4142 RETVAL = i_tags_delbycode(&im->tags, code);
4147 i_tags_get(im, index)
4151 if (index >= 0 && index < im->tags.count) {
4152 i_img_tag *entry = im->tags.tags + index;
4156 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
4159 PUSHs(sv_2mortal(newSViv(entry->code)));
4162 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
4165 PUSHs(sv_2mortal(newSViv(entry->idata)));
4170 i_tags_get_string(im, what_sv)
4174 char const *name = NULL;
4178 if (SvIOK(what_sv)) {
4179 code = SvIV(what_sv);
4183 name = SvPV_nolen(what_sv);
4186 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4188 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4195 RETVAL = im->tags.count;
4202 i_wf_bbox(face, size, text_sv, utf8=0)
4208 int cords[BOUNDING_BOX_COUNT];
4213 text = SvPV(text_sv, text_len);
4215 if (SvUTF8(text_sv))
4218 if (rc = i_wf_bbox(face, size, text, text_len, cords, utf8)) {
4220 for (i = 0; i < rc; ++i)
4221 PUSHs(sv_2mortal(newSViv(cords[i])));
4225 i_wf_text(face, im, tx, ty, cl, size, text_sv, align, aa, utf8 = 0)
4240 text = SvPV(text_sv, text_len);
4242 if (SvUTF8(text_sv))
4245 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, text_len,
4251 i_wf_cp(face, im, tx, ty, channel, size, text_sv, align, aa, utf8 = 0)
4266 text = SvPV(text_sv, text_len);
4268 if (SvUTF8(text_sv))
4271 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, text_len,
4288 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4290 #define FT2_DESTROY(font) i_ft2_destroy(font)
4294 Imager::Font::FT2 font
4296 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4299 i_ft2_new(name, index)
4304 i_ft2_setdpi(font, xdpi, ydpi)
4305 Imager::Font::FT2 font
4311 Imager::Font::FT2 font
4315 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4317 PUSHs(sv_2mortal(newSViv(xdpi)));
4318 PUSHs(sv_2mortal(newSViv(ydpi)));
4322 i_ft2_sethinting(font, hinting)
4323 Imager::Font::FT2 font
4327 i_ft2_settransform(font, matrix)
4328 Imager::Font::FT2 font
4336 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4337 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4338 av=(AV*)SvRV(ST(1));
4342 for (i = 0; i < len; ++i) {
4343 sv1=(*(av_fetch(av,i,0)));
4344 matrix[i] = SvNV(sv1);
4348 RETVAL = i_ft2_settransform(font, matrix);
4353 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4354 Imager::Font::FT2 font
4360 int bbox[BOUNDING_BOX_COUNT];
4366 text = SvPV(text_sv, text_len);
4368 if (SvUTF8(text_sv))
4371 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4374 for (i = 0; i < rc; ++i)
4375 PUSHs(sv_2mortal(newSViv(bbox[i])));
4379 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4380 Imager::Font::FT2 font
4394 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4397 for (i = 0; i < 8; ++i)
4398 PUSHs(sv_2mortal(newSViv(bbox[i])));
4402 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4403 Imager::Font::FT2 font
4419 if (SvUTF8(ST(7))) {
4423 text = SvPV(ST(7), len);
4424 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4425 len, align, aa, vlayout, utf8);
4430 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text_sv, align, aa, vlayout, utf8)
4431 Imager::Font::FT2 font
4451 text = SvPV(text_sv, len);
4452 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4453 len, align, aa, vlayout, 1);
4458 ft2_transform_box(font, x0, x1, x2, x3)
4459 Imager::Font::FT2 font
4467 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4468 ft2_transform_box(font, box);
4470 PUSHs(sv_2mortal(newSViv(box[0])));
4471 PUSHs(sv_2mortal(newSViv(box[1])));
4472 PUSHs(sv_2mortal(newSViv(box[2])));
4473 PUSHs(sv_2mortal(newSViv(box[3])));
4476 i_ft2_has_chars(handle, text_sv, utf8)
4477 Imager::Font::FT2 handle
4488 if (SvUTF8(text_sv))
4491 text = SvPV(text_sv, len);
4492 work = mymalloc(len);
4493 count = i_ft2_has_chars(handle, text, len, utf8, work);
4494 if (GIMME_V == G_ARRAY) {
4496 for (i = 0; i < count; ++i) {
4497 PUSHs(sv_2mortal(newSViv(work[i])));
4502 PUSHs(sv_2mortal(newSVpv(work, count)));
4507 i_ft2_face_name(handle)
4508 Imager::Font::FT2 handle
4513 len = i_ft2_face_name(handle, name, sizeof(name));
4516 PUSHs(sv_2mortal(newSVpv(name, 0)));
4520 i_ft2_can_face_name()
4523 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4524 Imager::Font::FT2 handle
4535 if (SvUTF8(text_sv))
4538 text = SvPV(text_sv, work_len);
4543 ch = i_utf8_advance(&text, &len);
4545 i_push_error(0, "invalid UTF8 character");
4554 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4556 PUSHs(sv_2mortal(newSVpv(name, 0)));
4559 PUSHs(&PL_sv_undef);
4564 i_ft2_can_do_glyph_names()
4567 i_ft2_face_has_glyph_names(handle)
4568 Imager::Font::FT2 handle
4571 i_ft2_is_multiple_master(handle)
4572 Imager::Font::FT2 handle
4575 i_ft2_get_multiple_masters(handle)
4576 Imager::Font::FT2 handle
4581 if (i_ft2_get_multiple_masters(handle, &mm)) {
4582 EXTEND(SP, 2+mm.num_axis);
4583 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4584 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4585 for (i = 0; i < mm.num_axis; ++i) {
4589 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4591 av_store(av, 0, sv);
4592 sv = newSViv(mm.axis[i].minimum);
4594 av_store(av, 1, sv);
4595 sv = newSViv(mm.axis[i].maximum);
4597 av_store(av, 2, sv);
4598 PUSHs(newRV_noinc((SV *)av));
4603 i_ft2_set_mm_coords(handle, ...)
4604 Imager::Font::FT2 handle
4610 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4611 transfer the array manually */
4612 ix_coords = items-1;
4613 coords = mymalloc(sizeof(long) * ix_coords);
4614 for (i = 0; i < ix_coords; ++i) {
4615 coords[i] = (long)SvIV(ST(1+i));
4617 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4624 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4628 Imager::FillHandle fill
4630 MODULE = Imager PACKAGE = Imager
4633 i_new_fill_solid(cl, combine)
4638 i_new_fill_solidf(cl, combine)
4639 Imager::Color::Float cl
4643 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4651 unsigned char *cust_hatch;
4655 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4659 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4664 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4665 Imager::Color::Float fg
4666 Imager::Color::Float bg
4672 unsigned char *cust_hatch;
4676 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4680 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4685 i_new_fill_image(src, matrix, xoff, yoff, combine)
4702 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4703 croak("i_new_fill_image: parameter must be an arrayref");
4704 av=(AV*)SvRV(ST(1));
4708 for (i = 0; i < len; ++i) {
4709 sv1=(*(av_fetch(av,i,0)));
4710 matrix[i] = SvNV(sv1);
4716 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4720 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4722 # this class is only exposed for testing
4725 i_int_hlines_testing()
4727 #if i_int_hlines_testing()
4729 Imager::Internal::Hlines
4730 i_int_hlines_new(start_y, count_y, start_x, count_x)
4736 Imager::Internal::Hlines
4737 i_int_hlines_new_img(im)
4741 i_int_hlines_add(hlines, y, minx, width)
4742 Imager::Internal::Hlines hlines
4748 i_int_hlines_DESTROY(hlines)
4749 Imager::Internal::Hlines hlines
4752 i_int_hlines_dump(hlines)
4753 Imager::Internal::Hlines hlines
4758 PERL_SET_GLOBAL_CALLBACKS;