1 #define PERL_NO_GET_CONTEXT
8 #define NEED_newRV_noinc
9 #define NEED_sv_2pv_nolen
15 #define i_int_hlines_testing() 1
22 #include "imextpltypes.h"
24 #if i_int_hlines_testing()
30 /* These functions are all shared - then comes platform dependant code */
31 static int getstr(void *hv_t,char *key,char **store) {
36 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
38 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
40 svpp=hv_fetch(hv, key, strlen(key), 0);
41 *store=SvPV(*svpp, PL_na );
46 static int getint(void *hv_t,char *key,int *store) {
51 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
53 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
55 svpp=hv_fetch(hv, key, strlen(key), 0);
56 *store=(int)SvIV(*svpp);
60 static int getdouble(void *hv_t,char* key,double *store) {
65 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
67 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
68 svpp=hv_fetch(hv, key, strlen(key), 0);
69 *store=(float)SvNV(*svpp);
73 static int getvoid(void *hv_t,char* key,void **store) {
78 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
80 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
82 svpp=hv_fetch(hv, key, strlen(key), 0);
83 *store = INT2PTR(void*, SvIV(*svpp));
88 static int getobj(void *hv_t,char *key,char *type,void **store) {
93 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
95 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
97 svpp=hv_fetch(hv, key, strlen(key), 0);
99 if (sv_derived_from(*svpp,type)) {
100 IV tmp = SvIV((SV*)SvRV(*svpp));
101 *store = INT2PTR(void*, tmp);
103 mm_log((1,"getobj: key exists in hash but is not of correct type"));
110 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
112 void my_SvREFCNT_dec(void *p) {
114 SvREFCNT_dec((SV*)p);
119 i_log_entry(char *string, int level) {
120 mm_log((level, string));
124 typedef struct i_reader_data_tag
126 /* presumably a CODE ref or name of a sub */
130 /* used by functions that want callbacks */
131 static int read_callback(char *userdata, char *buffer, int need, int want) {
133 i_reader_data *rd = (i_reader_data *)userdata;
137 dSP; dTARG = sv_newmortal();
138 /* thanks to Simon Cozens for help with the dTARG above */
148 count = perl_call_sv(rd->sv, G_SCALAR);
153 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
159 char *ptr = SvPV(data, len);
161 croak("Too much data returned in reader callback");
163 memcpy(buffer, ptr, len);
179 SV *sv; /* a coderef or sub name */
182 /* used by functions that want callbacks */
183 static int write_callback(char *userdata, char const *data, int size) {
185 i_writer_data *wd = (i_writer_data *)userdata;
195 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
198 count = perl_call_sv(wd->sv, G_SCALAR);
203 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
206 success = SvTRUE(sv);
216 #define CBDATA_BUFSIZE 8192
219 /* the SVs we use to call back to Perl */
225 /* we need to remember whether the buffer contains write data or
231 /* how far we've read into the buffer (not used for writing) */
234 /* the amount of space used/data available in the buffer */
237 /* the maximum amount to fill the buffer before flushing
238 If any write is larger than this then the buffer is flushed and
239 the full write is performed. The write is _not_ split into
244 char buffer[CBDATA_BUFSIZE];
249 call_writer(cbd, buf, size)
251 Low-level function to call the perl writer callback.
255 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
262 if (!SvOK(cbd->writecb))
269 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
272 count = perl_call_sv(cbd->writecb, G_SCALAR);
276 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
279 success = SvTRUE(sv);
286 return success ? size : -1;
289 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
297 if (!SvOK(cbd->readcb))
304 PUSHs(sv_2mortal(newSViv(size)));
305 PUSHs(sv_2mortal(newSViv(maxread)));
308 count = perl_call_sv(cbd->readcb, G_SCALAR);
313 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
319 char *ptr = SvPV(data, len);
321 croak("Too much data returned in reader callback");
323 memcpy(buf, ptr, len);
337 static ssize_t write_flush(struct cbdata *cbd) {
342 result = call_writer(cbd, cbd->buffer, cbd->used);
347 return 1; /* success of some sort */
351 static off_t io_seeker(void *p, off_t offset, int whence) {
353 struct cbdata *cbd = p;
358 if (!SvOK(cbd->seekcb))
362 if (cbd->used && write_flush(cbd) <= 0)
366 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
367 offset -= cbd->where - cbd->used;
370 cbd->where = cbd->used = 0;
376 PUSHs(sv_2mortal(newSViv(offset)));
377 PUSHs(sv_2mortal(newSViv(whence)));
380 count = perl_call_sv(cbd->seekcb, G_SCALAR);
385 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
396 static ssize_t io_writer(void *p, void const *data, size_t size) {
398 struct cbdata *cbd = p;
400 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
402 if (cbd->reading && cbd->where < cbd->used) {
403 /* we read past the place where the caller expected us to be
404 so adjust our position a bit */
405 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
410 cbd->where = cbd->used = 0;
413 if (cbd->used && cbd->used + size > cbd->maxlength) {
414 int write_res = write_flush(cbd);
415 if (write_res <= 0) {
420 if (cbd->used+size <= cbd->maxlength) {
421 memcpy(cbd->buffer + cbd->used, data, size);
425 /* it doesn't fit - just pass it up */
426 return call_writer(cbd, data, size);
430 io_reader(void *p, void *data, size_t size) {
432 struct cbdata *cbd = p;
434 char *out = data; /* so we can do pointer arithmetic */
436 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
438 if (write_flush(cbd) <= 0)
444 if (size <= cbd->used - cbd->where) {
446 memcpy(data, cbd->buffer+cbd->where, size);
451 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
452 total += cbd->used - cbd->where;
453 size -= cbd->used - cbd->where;
454 out += cbd->used - cbd->where;
455 if (size < sizeof(cbd->buffer)) {
459 && (did_read = call_reader(cbd, cbd->buffer, size,
460 sizeof(cbd->buffer))) > 0) {
462 cbd->used = did_read;
464 copy_size = i_min(size, cbd->used);
465 memcpy(out, cbd->buffer, copy_size);
466 cbd->where += copy_size;
475 /* just read the rest - too big for our buffer*/
477 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
489 static int io_closer(void *p) {
491 struct cbdata *cbd = p;
493 if (cbd->writing && cbd->used > 0) {
494 if (write_flush(cbd) < 0)
499 if (SvOK(cbd->closecb)) {
507 perl_call_sv(cbd->closecb, G_VOID);
518 static void io_destroyer(void *p) {
520 struct cbdata *cbd = p;
522 SvREFCNT_dec(cbd->writecb);
523 SvREFCNT_dec(cbd->readcb);
524 SvREFCNT_dec(cbd->seekcb);
525 SvREFCNT_dec(cbd->closecb);
533 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
536 for (i = 0; i < count; ++i)
537 if (strEQ(names[i].name, name))
538 return names[i].value;
542 static struct value_name transp_names[] =
545 { "threshold", tr_threshold },
546 { "errdiff", tr_errdiff },
547 { "ordered", tr_ordered, },
550 static struct value_name make_color_names[] =
552 { "none", mc_none, },
553 { "webmap", mc_web_map, },
554 { "addi", mc_addi, },
555 { "mediancut", mc_median_cut, },
556 { "mono", mc_mono, },
557 { "monochrome", mc_mono, },
560 static struct value_name translate_names[] =
562 { "giflib", pt_giflib, },
563 { "closest", pt_closest, },
564 { "perturb", pt_perturb, },
565 { "errdiff", pt_errdiff, },
568 static struct value_name errdiff_names[] =
570 { "floyd", ed_floyd, },
571 { "jarvis", ed_jarvis, },
572 { "stucki", ed_stucki, },
573 { "custom", ed_custom, },
576 static struct value_name orddith_names[] =
578 { "random", od_random, },
579 { "dot8", od_dot8, },
580 { "dot4", od_dot4, },
581 { "hline", od_hline, },
582 { "vline", od_vline, },
583 { "/line", od_slashline, },
584 { "slashline", od_slashline, },
585 { "\\line", od_backline, },
586 { "backline", od_backline, },
587 { "tiny", od_tiny, },
588 { "custom", od_custom, },
591 /* look through the hash for quantization options */
593 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
595 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
601 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
603 sv = hv_fetch(hv, "transp", 6, 0);
604 if (sv && *sv && (str = SvPV(*sv, len))) {
606 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
608 if (quant->transp != tr_none) {
609 quant->tr_threshold = 127;
610 sv = hv_fetch(hv, "tr_threshold", 12, 0);
612 quant->tr_threshold = SvIV(*sv);
614 if (quant->transp == tr_errdiff) {
615 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
616 if (sv && *sv && (str = SvPV(*sv, len)))
617 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
619 if (quant->transp == tr_ordered) {
620 quant->tr_orddith = od_tiny;
621 sv = hv_fetch(hv, "tr_orddith", 10, 0);
622 if (sv && *sv && (str = SvPV(*sv, len)))
623 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
625 if (quant->tr_orddith == od_custom) {
626 sv = hv_fetch(hv, "tr_map", 6, 0);
627 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
628 AV *av = (AV*)SvRV(*sv);
629 len = av_len(av) + 1;
630 if (len > sizeof(quant->tr_custom))
631 len = sizeof(quant->tr_custom);
632 for (i = 0; i < len; ++i) {
633 SV **sv2 = av_fetch(av, i, 0);
635 quant->tr_custom[i] = SvIV(*sv2);
638 while (i < sizeof(quant->tr_custom))
639 quant->tr_custom[i++] = 0;
644 quant->make_colors = mc_median_cut;
645 sv = hv_fetch(hv, "make_colors", 11, 0);
646 if (sv && *sv && (str = SvPV(*sv, len))) {
648 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
650 sv = hv_fetch(hv, "colors", 6, 0);
651 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
652 /* needs to be an array of Imager::Color
653 note that the caller allocates the mc_color array and sets mc_size
655 AV *av = (AV *)SvRV(*sv);
656 quant->mc_count = av_len(av)+1;
657 if (quant->mc_count > quant->mc_size)
658 quant->mc_count = quant->mc_size;
659 for (i = 0; i < quant->mc_count; ++i) {
660 SV **sv1 = av_fetch(av, i, 0);
661 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
662 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
663 quant->mc_colors[i] = *col;
667 sv = hv_fetch(hv, "max_colors", 10, 0);
670 if (i <= quant->mc_size && i >= quant->mc_count)
674 quant->translate = pt_closest;
675 sv = hv_fetch(hv, "translate", 9, 0);
676 if (sv && *sv && (str = SvPV(*sv, len))) {
677 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
679 sv = hv_fetch(hv, "errdiff", 7, 0);
680 if (sv && *sv && (str = SvPV(*sv, len))) {
681 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
683 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
684 /* get the error diffusion map */
685 sv = hv_fetch(hv, "errdiff_width", 13, 0);
687 quant->ed_width = SvIV(*sv);
688 sv = hv_fetch(hv, "errdiff_height", 14, 0);
690 quant->ed_height = SvIV(*sv);
691 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
693 quant->ed_orig = SvIV(*sv);
694 if (quant->ed_width > 0 && quant->ed_height > 0) {
696 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
697 sv = hv_fetch(hv, "errdiff_map", 11, 0);
698 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
699 AV *av = (AV*)SvRV(*sv);
700 len = av_len(av) + 1;
701 if (len > quant->ed_width * quant->ed_height)
702 len = quant->ed_width * quant->ed_height;
703 for (i = 0; i < len; ++i) {
704 SV **sv2 = av_fetch(av, i, 0);
706 quant->ed_map[i] = SvIV(*sv2);
707 sum += quant->ed_map[i];
713 myfree(quant->ed_map);
715 quant->errdiff = ed_floyd;
719 sv = hv_fetch(hv, "perturb", 7, 0);
721 quant->perturb = SvIV(*sv);
725 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
726 myfree(quant->mc_colors);
728 myfree(quant->ed_map);
731 /* copies the color map from the hv into the colors member of the HV */
733 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
739 sv = hv_fetch(hv, "colors", 6, 0);
740 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
745 av = (AV *)SvRV(*sv);
747 av_extend(av, quant->mc_count+1);
748 for (i = 0; i < quant->mc_count; ++i) {
749 i_color *in = quant->mc_colors+i;
750 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
751 work = sv_newmortal();
752 sv_setref_pv(work, "Imager::Color", (void *)c);
758 /* loads the segments of a fountain fill into an array */
759 static i_fountain_seg *
760 load_fount_segs(pTHX_ AV *asegs, int *count) {
761 /* Each element of segs must contain:
762 [ start, middle, end, c0, c1, segtype, colortrans ]
763 start, middle, end are doubles from 0 to 1
764 c0, c1 are Imager::Color::Float or Imager::Color objects
765 segtype, colortrans are ints
769 i_fountain_seg *segs;
773 *count = av_len(asegs)+1;
775 croak("i_fountain must have at least one segment");
776 segs = mymalloc(sizeof(i_fountain_seg) * *count);
777 for(i = 0; i < *count; i++) {
778 SV **sv1 = av_fetch(asegs, i, 0);
779 if (!sv1 || !*sv1 || !SvROK(*sv1)
780 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
782 croak("i_fountain: segs must be an arrayref of arrayrefs");
784 aseg = (AV *)SvRV(*sv1);
785 if (av_len(aseg) != 7-1) {
787 croak("i_fountain: a segment must have 7 members");
789 for (j = 0; j < 3; ++j) {
790 SV **sv2 = av_fetch(aseg, j, 0);
793 croak("i_fountain: XS error");
795 work[j] = SvNV(*sv2);
797 segs[i].start = work[0];
798 segs[i].middle = work[1];
799 segs[i].end = work[2];
800 for (j = 0; j < 2; ++j) {
801 SV **sv3 = av_fetch(aseg, 3+j, 0);
802 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
803 (!sv_derived_from(*sv3, "Imager::Color")
804 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
806 croak("i_fountain: segs must contain colors in elements 3 and 4");
808 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
809 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
812 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
814 for (ch = 0; ch < MAXCHANNELS; ++ch) {
815 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
819 for (j = 0; j < 2; ++j) {
820 SV **sv2 = av_fetch(aseg, j+5, 0);
823 croak("i_fountain: XS error");
825 worki[j] = SvIV(*sv2);
827 segs[i].type = worki[0];
828 segs[i].color = worki[1];
834 /* validates the indexes supplied to i_ppal
836 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
841 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
842 int color_count = i_colorcount(im);
845 if (color_count == -1)
846 croak("i_plin() called on direct color image");
848 for (i = 0; i < count; ++i) {
849 if (indexes[i] >= color_count) {
850 croak("i_plin() called with out of range color index %d (max %d)",
851 indexes[i], color_count-1);
857 /* I don't think ICLF_* names belong at the C interface
858 this makes the XS code think we have them, to let us avoid
859 putting function bodies in the XS code
861 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
862 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
865 /* the m_init_log() function was called init_log(), renamed to reduce
866 potential naming conflicts */
867 #define init_log m_init_log
869 #if i_int_hlines_testing()
871 typedef i_int_hlines *Imager__Internal__Hlines;
873 static i_int_hlines *
874 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
875 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
876 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
881 static i_int_hlines *
882 i_int_hlines_new_img(i_img *im) {
883 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
884 i_int_init_hlines_img(result, im);
890 i_int_hlines_DESTROY(i_int_hlines *hlines) {
891 i_int_hlines_destroy(hlines);
895 #define i_int_hlines_CLONE_SKIP(cls) 1
897 static int seg_compare(const void *vleft, const void *vright) {
898 const i_int_hline_seg *left = vleft;
899 const i_int_hline_seg *right = vright;
901 return left->minx - right->minx;
905 i_int_hlines_dump(i_int_hlines *hlines) {
907 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
908 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
911 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
912 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
915 /* sort the segments, if any */
917 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
919 sv_catpvf(dump, " %d (%d):", y, entry->count);
920 for (i = 0; i < entry->count; ++i) {
921 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
922 entry->segs[i].x_limit);
924 sv_catpv(dump, "\n");
933 static im_pl_ext_funcs im_perl_funcs =
935 IMAGER_PL_API_VERSION,
937 ip_handle_quant_opts,
938 ip_cleanup_quant_opts,
942 #define PERL_PL_SET_GLOBAL_CALLBACKS \
943 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
946 #define i_exif_enabled() 1
948 #define i_exif_enabled() 0
951 /* trying to use more C style names, map them here */
952 #define i_io_DESTROY(ig) io_glue_destroy(ig)
954 #define i_img_get_width(im) ((im)->xsize)
955 #define i_img_get_height(im) ((im)->ysize)
957 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
960 ICL_new_internal(r,g,b,a)
972 ICL_set_internal(cl,r,g,b,a)
979 ICL_set_internal(cl, r, g, b, a);
993 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
994 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
995 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
996 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
1002 RETVAL = mymalloc(sizeof(i_color));
1004 i_hsv_to_rgb(RETVAL);
1012 RETVAL = mymalloc(sizeof(i_color));
1014 i_rgb_to_hsv(RETVAL);
1020 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1022 Imager::Color::Float
1023 ICLF_new_internal(r, g, b, a)
1031 Imager::Color::Float cl
1035 Imager::Color::Float cl
1039 EXTEND(SP, MAXCHANNELS);
1040 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1041 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1042 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1046 ICLF_set_internal(cl,r,g,b,a)
1047 Imager::Color::Float cl
1060 Imager::Color::Float
1062 Imager::Color::Float c
1064 RETVAL = mymalloc(sizeof(i_fcolor));
1066 i_hsv_to_rgbf(RETVAL);
1070 Imager::Color::Float
1072 Imager::Color::Float c
1074 RETVAL = mymalloc(sizeof(i_fcolor));
1076 i_rgb_to_hsvf(RETVAL);
1080 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1094 MODULE = Imager PACKAGE = Imager
1113 SvPV(ST(0), length);
1114 SvREFCNT_inc(ST(0));
1115 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1120 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1129 cbd = mymalloc(sizeof(struct cbdata));
1130 SvREFCNT_inc(writecb);
1131 cbd->writecb = writecb;
1132 SvREFCNT_inc(readcb);
1133 cbd->readcb = readcb;
1134 SvREFCNT_inc(seekcb);
1135 cbd->seekcb = seekcb;
1136 SvREFCNT_inc(closecb);
1137 cbd->closecb = closecb;
1138 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1139 if (maxwrite > CBDATA_BUFSIZE)
1140 maxwrite = CBDATA_BUFSIZE;
1141 cbd->maxlength = maxwrite;
1142 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1151 unsigned char* data;
1155 tlength = io_slurp(ig, &data);
1157 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1162 i_set_image_file_limits(width, height, bytes)
1168 i_get_image_file_limits()
1170 int width, height, bytes;
1172 if (i_get_image_file_limits(&width, &height, &bytes)) {
1174 PUSHs(sv_2mortal(newSViv(width)));
1175 PUSHs(sv_2mortal(newSViv(height)));
1176 PUSHs(sv_2mortal(newSViv(bytes)));
1179 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1182 i_io_write(ig, data_sv)
1190 if (SvUTF8(data_sv)) {
1191 data_sv = sv_2mortal(newSVsv(data_sv));
1192 /* yes, we want this to croak() if the SV can't be downgraded */
1193 sv_utf8_downgrade(data_sv, FALSE);
1196 data = SvPV(data_sv, size);
1197 RETVAL = i_io_write(ig, data, size);
1202 i_io_read(ig, buffer_sv, size)
1211 croak("size negative in call to i_io_read()");
1212 /* prevent an undefined value warning if they supplied an
1214 Orginally conditional on !SvOK(), but this will prevent the
1215 downgrade from croaking */
1216 sv_setpvn(buffer_sv, "", 0);
1218 if (SvUTF8(buffer_sv))
1219 sv_utf8_downgrade(buffer_sv, FALSE);
1221 buffer = SvGROW(buffer_sv, size+1);
1222 result = i_io_read(ig, buffer, size);
1224 SvCUR_set(buffer_sv, result);
1225 *SvEND(buffer_sv) = '\0';
1226 SvPOK_only(buffer_sv);
1228 PUSHs(sv_2mortal(newSViv(result)));
1234 i_io_read2(ig, size)
1243 croak("size negative in call to i_io_read2()");
1244 buffer_sv = newSV(size);
1245 buffer = SvGROW(buffer_sv, size+1);
1246 result = i_io_read(ig, buffer, size);
1248 SvCUR_set(buffer_sv, result);
1249 *SvEND(buffer_sv) = '\0';
1250 SvPOK_only(buffer_sv);
1252 PUSHs(sv_2mortal(buffer_sv));
1256 SvREFCNT_dec(buffer_sv);
1260 i_io_seek(ig, position, whence)
1274 i_io_CLONE_SKIP(...)
1280 MODULE = Imager PACKAGE = Imager
1291 while( (item=i_format_list[i++]) != NULL ) {
1293 PUSHs(sv_2mortal(newSVpv(item,0)));
1310 i_img_empty_ch(im,x,y,ch)
1317 i_sametype(im, x, y)
1323 i_sametype_chans(im, x, y, channels)
1330 i_init_log(name_sv,level)
1334 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1336 i_init_log(name, level);
1339 i_log_entry(string,level)
1358 i_img_info(im,info);
1360 PUSHs(sv_2mortal(newSViv(info[0])));
1361 PUSHs(sv_2mortal(newSViv(info[1])));
1362 PUSHs(sv_2mortal(newSViv(info[2])));
1363 PUSHs(sv_2mortal(newSViv(info[3])));
1369 i_img_setmask(im,ch_mask)
1378 i_img_getchannels(im)
1387 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1395 i_img_get_height(im)
1400 i_img_is_monochrome(im)
1406 result = i_img_is_monochrome(im, &zero_is_white);
1408 if (GIMME_V == G_ARRAY) {
1411 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1420 i_line(im,x1,y1,x2,y2,val,endp)
1430 i_line_aa(im,x1,y1,x2,y2,val,endp)
1440 i_box(im,x1,y1,x2,y2,val)
1449 i_box_filled(im,x1,y1,x2,y2,val)
1458 i_box_cfill(im,x1,y1,x2,y2,fill)
1464 Imager::FillHandle fill
1467 i_arc(im,x,y,rad,d1,d2,val)
1477 i_arc_aa(im,x,y,rad,d1,d2,val)
1487 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1494 Imager::FillHandle fill
1497 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1504 Imager::FillHandle fill
1508 i_circle_aa(im,x,y,rad,val)
1516 i_circle_out(im,x,y,rad,val)
1524 i_circle_out_aa(im,x,y,rad,val)
1532 i_arc_out(im,x,y,rad,d1,d2,val)
1542 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1553 i_bezier_multi(im,xc,yc,val)
1566 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1567 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1568 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1569 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1570 av1=(AV*)SvRV(ST(1));
1571 av2=(AV*)SvRV(ST(2));
1572 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1574 x=mymalloc( len*sizeof(double) );
1575 y=mymalloc( len*sizeof(double) );
1576 for(i=0;i<len;i++) {
1577 sv1=(*(av_fetch(av1,i,0)));
1578 sv2=(*(av_fetch(av2,i,0)));
1579 x[i]=(double)SvNV(sv1);
1580 y[i]=(double)SvNV(sv2);
1582 i_bezier_multi(im,len,x,y,val);
1588 i_poly_aa(im,xc,yc,val)
1601 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1602 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1603 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1604 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1605 av1=(AV*)SvRV(ST(1));
1606 av2=(AV*)SvRV(ST(2));
1607 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1609 x=mymalloc( len*sizeof(double) );
1610 y=mymalloc( len*sizeof(double) );
1611 for(i=0;i<len;i++) {
1612 sv1=(*(av_fetch(av1,i,0)));
1613 sv2=(*(av_fetch(av2,i,0)));
1614 x[i]=(double)SvNV(sv1);
1615 y[i]=(double)SvNV(sv2);
1617 RETVAL = i_poly_aa(im,len,x,y,val);
1624 i_poly_aa_cfill(im,xc,yc,fill)
1626 Imager::FillHandle fill
1636 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1637 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1638 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1639 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1640 av1=(AV*)SvRV(ST(1));
1641 av2=(AV*)SvRV(ST(2));
1642 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1644 x=mymalloc( len*sizeof(double) );
1645 y=mymalloc( len*sizeof(double) );
1646 for(i=0;i<len;i++) {
1647 sv1=(*(av_fetch(av1,i,0)));
1648 sv2=(*(av_fetch(av2,i,0)));
1649 x[i]=(double)SvNV(sv1);
1650 y[i]=(double)SvNV(sv2);
1652 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1661 i_flood_fill(im,seedx,seedy,dcol)
1668 i_flood_cfill(im,seedx,seedy,fill)
1672 Imager::FillHandle fill
1675 i_flood_fill_border(im,seedx,seedy,dcol, border)
1680 Imager::Color border
1683 i_flood_cfill_border(im,seedx,seedy,fill, border)
1687 Imager::FillHandle fill
1688 Imager::Color border
1692 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1704 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1721 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1732 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1745 i_compose_mask(out, src, mask, out_left, out_top, src_left, src_top, mask_left, mask_top, width, height, combine = ic_normal, opacity = 0.0)
1761 i_combine(src_av, channels_av = NULL)
1765 i_img **imgs = NULL;
1767 int *channels = NULL;
1772 in_count = av_len(src_av) + 1;
1774 imgs = mymalloc(sizeof(i_img*) * in_count);
1775 channels = mymalloc(sizeof(int) * in_count);
1776 for (i = 0; i < in_count; ++i) {
1777 psv = av_fetch(src_av, i, 0);
1778 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1781 croak("imgs must contain only images");
1783 tmp = SvIV((SV*)SvRV(*psv));
1784 imgs[i] = INT2PTR(i_img*, tmp);
1786 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1788 channels[i] = SvIV(*psv);
1795 RETVAL = i_combine(imgs, channels, in_count);
1802 i_flipxy(im, direction)
1807 i_rotate90(im, degrees)
1812 i_rotate_exact(im, amount, ...)
1816 i_color *backp = NULL;
1817 i_fcolor *fbackp = NULL;
1821 /* extract the bg colors if any */
1822 /* yes, this is kind of strange */
1823 for (i = 2; i < items; ++i) {
1825 if (sv_derived_from(sv1, "Imager::Color")) {
1826 IV tmp = SvIV((SV*)SvRV(sv1));
1827 backp = INT2PTR(i_color *, tmp);
1829 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1830 IV tmp = SvIV((SV*)SvRV(sv1));
1831 fbackp = INT2PTR(i_fcolor *, tmp);
1834 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1839 i_matrix_transform(im, xsize, ysize, matrix, ...)
1849 i_color *backp = NULL;
1850 i_fcolor *fbackp = NULL;
1852 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1853 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1854 av=(AV*)SvRV(ST(3));
1858 for (i = 0; i < len; ++i) {
1859 sv1=(*(av_fetch(av,i,0)));
1860 matrix[i] = SvNV(sv1);
1864 /* extract the bg colors if any */
1865 /* yes, this is kind of strange */
1866 for (i = 4; i < items; ++i) {
1868 if (sv_derived_from(sv1, "Imager::Color")) {
1869 IV tmp = SvIV((SV*)SvRV(sv1));
1870 backp = INT2PTR(i_color *, tmp);
1872 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1873 IV tmp = SvIV((SV*)SvRV(sv1));
1874 fbackp = INT2PTR(i_fcolor *, tmp);
1877 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1882 i_gaussian(im,stdev)
1887 i_unsharp_mask(im,stdev,scale)
1902 len = av_len(coef) + 1;
1903 c_coef=mymalloc( len * sizeof(double) );
1904 for(i = 0; i < len; i++) {
1905 sv1 = (*(av_fetch(coef, i, 0)));
1906 c_coef[i] = (double)SvNV(sv1);
1908 RETVAL = i_conv(im, c_coef, len);
1914 i_convert(src, avmain)
1926 outchan = av_len(avmain)+1;
1927 /* find the biggest */
1929 for (j=0; j < outchan; ++j) {
1930 temp = av_fetch(avmain, j, 0);
1931 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1932 avsub = (AV*)SvRV(*temp);
1933 len = av_len(avsub)+1;
1938 coeff = mymalloc(sizeof(double) * outchan * inchan);
1939 for (j = 0; j < outchan; ++j) {
1940 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1941 len = av_len(avsub)+1;
1942 for (i = 0; i < len; ++i) {
1943 temp = av_fetch(avsub, i, 0);
1945 coeff[i+j*inchan] = SvNV(*temp);
1947 coeff[i+j*inchan] = 0;
1950 coeff[i++ + j*inchan] = 0;
1952 RETVAL = i_convert(src, coeff, outchan, inchan);
1962 unsigned int mask = 0;
1968 unsigned char (*maps)[256];
1970 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1971 croak("i_map: parameter 2 must be an arrayref\n");
1972 avmain = (AV*)SvRV(ST(1));
1973 len = av_len(avmain)+1;
1974 if (im->channels < len) len = im->channels;
1976 maps = mymalloc( len * sizeof(unsigned char [256]) );
1978 for (j=0; j<len ; j++) {
1979 temp = av_fetch(avmain, j, 0);
1980 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1981 avsub = (AV*)SvRV(*temp);
1982 if(av_len(avsub) != 255) continue;
1984 for (i=0; i<256 ; i++) {
1986 temp = av_fetch(avsub, i, 0);
1987 val = temp ? SvIV(*temp) : 0;
1989 if (val>255) val = 255;
1994 i_map(im, maps, mask);
2005 i_img_diffd(im1,im2)
2010 i_init_fonts(t1log=0)
2014 _is_color_object(sv)
2018 RETVAL = SvOK(sv) && SvROK(sv) &&
2019 (sv_derived_from(sv, "Imager::Color")
2020 || sv_derived_from(sv, "Imager::Color::Float"));
2036 i_t1_destroy(font_id)
2041 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
2060 str = SvPV(str_sv, len);
2061 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
2068 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
2077 int cords[BOUNDING_BOX_COUNT];
2085 str = SvPV(str_sv, len);
2086 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
2089 for (i = 0; i < rc; ++i)
2090 PUSHs(sv_2mortal(newSViv(cords[i])));
2096 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
2115 str = SvPV(str_sv, len);
2116 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
2122 i_t1_has_chars(handle, text_sv, utf8 = 0)
2134 if (SvUTF8(text_sv))
2137 text = SvPV(text_sv, len);
2138 work = mymalloc(len);
2139 count = i_t1_has_chars(handle, text, len, utf8, work);
2140 if (GIMME_V == G_ARRAY) {
2142 for (i = 0; i < count; ++i) {
2143 PUSHs(sv_2mortal(newSViv(work[i])));
2148 PUSHs(sv_2mortal(newSVpv(work, count)));
2153 i_t1_face_name(handle)
2159 len = i_t1_face_name(handle, name, sizeof(name));
2162 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2166 i_t1_glyph_name(handle, text_sv, utf8 = 0)
2177 if (SvUTF8(text_sv))
2180 text = SvPV(text_sv, work_len);
2185 ch = i_utf8_advance(&text, &len);
2187 i_push_error(0, "invalid UTF8 character");
2196 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
2197 PUSHs(sv_2mortal(newSVpv(name, 0)));
2200 PUSHs(&PL_sv_undef);
2214 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2216 #define TT_DESTROY(handle) i_tt_destroy(handle)
2220 Imager::Font::TT handle
2230 MODULE = Imager PACKAGE = Imager
2234 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2235 Imager::Font::TT handle
2253 str = SvPV(str_sv, len);
2254 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2255 len, smooth, utf8, align);
2261 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2262 Imager::Font::TT handle
2280 str = SvPV(str_sv, len);
2281 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2282 smooth, utf8, align);
2288 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2289 Imager::Font::TT handle
2294 int cords[BOUNDING_BOX_COUNT],rc;
2303 str = SvPV(str_sv, len);
2304 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2306 for (i = 0; i < rc; ++i) {
2307 PUSHs(sv_2mortal(newSViv(cords[i])));
2312 i_tt_has_chars(handle, text_sv, utf8)
2313 Imager::Font::TT handle
2324 if (SvUTF8(text_sv))
2327 text = SvPV(text_sv, len);
2328 work = mymalloc(len);
2329 count = i_tt_has_chars(handle, text, len, utf8, work);
2330 if (GIMME_V == G_ARRAY) {
2332 for (i = 0; i < count; ++i) {
2333 PUSHs(sv_2mortal(newSViv(work[i])));
2338 PUSHs(sv_2mortal(newSVpv(work, count)));
2343 i_tt_dump_names(handle)
2344 Imager::Font::TT handle
2347 i_tt_face_name(handle)
2348 Imager::Font::TT handle
2353 len = i_tt_face_name(handle, name, sizeof(name));
2356 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2360 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2361 Imager::Font::TT handle
2372 if (SvUTF8(text_sv))
2375 text = SvPV(text_sv, work_len);
2380 ch = i_utf8_advance(&text, &len);
2382 i_push_error(0, "invalid UTF8 character");
2391 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2392 PUSHs(sv_2mortal(newSVpv(name, 0)));
2395 PUSHs(&PL_sv_undef);
2402 i_test_format_probe(ig, length)
2407 i_readpnm_wiol(ig, allow_incomplete)
2409 int allow_incomplete
2413 i_readpnm_multi_wiol(ig, allow_incomplete)
2415 int allow_incomplete
2421 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2424 for (i = 0; i < count; ++i) {
2425 SV *sv = sv_newmortal();
2426 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2433 i_writeppm_wiol(im, ig)
2442 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2451 i_writeraw_wiol(im,ig)
2456 i_writebmp_wiol(im,ig)
2461 i_readbmp_wiol(ig, allow_incomplete=0)
2463 int allow_incomplete
2467 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2476 idlen = SvCUR(ST(4));
2477 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2483 i_readtga_wiol(ig, length)
2491 i_scaleaxis(im,Value,Axis)
2497 i_scale_nn(im,scx,scy)
2503 i_scale_mixing(im, width, height)
2513 i_count_colors(im,maxc)
2518 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2523 unsigned int * col_usage = NULL;
2526 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2527 EXTEND(SP, col_cnt);
2528 for (i = 0; i < col_cnt; i++) {
2529 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2536 i_transform(im,opx,opy,parm)
2549 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2550 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2551 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2552 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2553 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2554 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2555 av=(AV*)SvRV(ST(1));
2557 opx=mymalloc( opxl*sizeof(int) );
2558 for(i=0;i<opxl;i++) {
2559 sv1=(*(av_fetch(av,i,0)));
2560 opx[i]=(int)SvIV(sv1);
2562 av=(AV*)SvRV(ST(2));
2564 opy=mymalloc( opyl*sizeof(int) );
2565 for(i=0;i<opyl;i++) {
2566 sv1=(*(av_fetch(av,i,0)));
2567 opy[i]=(int)SvIV(sv1);
2569 av=(AV*)SvRV(ST(3));
2570 parmlen=av_len(av)+1;
2571 parm=mymalloc( parmlen*sizeof(double) );
2572 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2573 sv1=(*(av_fetch(av,i,0)));
2574 parm[i]=(double)SvNV(sv1);
2576 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2580 ST(0) = sv_newmortal();
2581 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2582 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2585 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2610 in_imgs_count = av_len(av_in_imgs)+1;
2611 for (i = 0; i < in_imgs_count; ++i) {
2612 sv1 = *av_fetch(av_in_imgs, i, 0);
2613 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2614 croak("sv_in_img must contain only images");
2617 if (in_imgs_count > 0) {
2618 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2619 for (i = 0; i < in_imgs_count; ++i) {
2620 sv1 = *av_fetch(av_in_imgs,i,0);
2621 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2622 croak("Parameter 5 must contain only images");
2624 tmp = SvIV((SV*)SvRV(sv1));
2625 in_imgs[i] = INT2PTR(i_img*, tmp);
2629 /* no input images */
2632 /* default the output size from the first input if possible */
2634 width = SvIV(sv_width);
2635 else if (in_imgs_count)
2636 width = in_imgs[0]->xsize;
2638 croak("No output image width supplied");
2640 if (SvOK(sv_height))
2641 height = SvIV(sv_height);
2642 else if (in_imgs_count)
2643 height = in_imgs[0]->ysize;
2645 croak("No output image height supplied");
2647 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2648 if (ops_len % sizeof(struct rm_op))
2649 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2650 ops_count = ops_len / sizeof(struct rm_op);
2652 n_regs_count = av_len(av_n_regs)+1;
2653 n_regs = mymalloc(n_regs_count * sizeof(double));
2654 for (i = 0; i < n_regs_count; ++i) {
2655 sv1 = *av_fetch(av_n_regs,i,0);
2657 n_regs[i] = SvNV(sv1);
2659 c_regs_count = av_len(av_c_regs)+1;
2660 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2661 /* I don't bother initializing the colou?r registers */
2663 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2664 n_regs, n_regs_count,
2665 c_regs, c_regs_count, in_imgs, in_imgs_count);
2670 ST(0) = sv_newmortal();
2671 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2672 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2676 i_contrast(im,intensity)
2689 i_noise(im,amount,type)
2695 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2705 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2724 i_postlevels(im,levels)
2734 i_watermark(im,wmark,tx,ty,pixdiff)
2736 Imager::ImgRaw wmark
2743 i_autolevels(im,lsat,usat,skew)
2750 i_radnoise(im,xo,yo,rscale,ascale)
2758 i_turbnoise(im, xo, yo, scale)
2781 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2782 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2783 croak("i_gradgen: Second argument must be an array ref");
2784 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2785 croak("i_gradgen: Third argument must be an array ref");
2786 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2787 croak("i_gradgen: Fourth argument must be an array ref");
2788 axx = (AV *)SvRV(ST(1));
2789 ayy = (AV *)SvRV(ST(2));
2790 ac = (AV *)SvRV(ST(3));
2791 dmeasure = (int)SvIV(ST(4));
2793 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2794 num = num <= av_len(ac) ? num : av_len(ac);
2796 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2797 xo = mymalloc( sizeof(int) * num );
2798 yo = mymalloc( sizeof(int) * num );
2799 ival = mymalloc( sizeof(i_color) * num );
2800 for(i = 0; i<num; i++) {
2801 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2802 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2803 sv = *av_fetch(ac, i, 0);
2804 if ( !sv_derived_from(sv, "Imager::Color") ) {
2805 free(axx); free(ayy); free(ac);
2806 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2808 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2810 i_gradgen(im, num, xo, yo, ival, dmeasure);
2816 i_diff_image(im, im2, mindist=0)
2822 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2832 double ssample_param
2836 i_fountain_seg *segs;
2838 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2839 croak("i_fountain: argument 11 must be an array ref");
2841 asegs = (AV *)SvRV(ST(10));
2842 segs = load_fount_segs(aTHX_ asegs, &count);
2843 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2844 super_sample, ssample_param, count, segs);
2850 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2859 double ssample_param
2863 i_fountain_seg *segs;
2865 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2866 croak("i_fountain: argument 11 must be an array ref");
2868 asegs = (AV *)SvRV(ST(9));
2869 segs = load_fount_segs(aTHX_ asegs, &count);
2870 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2871 super_sample, ssample_param, count, segs);
2877 i_new_fill_opacity(other_fill, alpha_mult)
2878 Imager::FillHandle other_fill
2889 errors = i_errors();
2891 while (errors[i].msg) {
2893 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2894 if (!av_store(av, 0, sv)) {
2897 sv = newSViv(errors[i].code);
2898 if (!av_store(av, 1, sv)) {
2901 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2909 i_push_error(code, msg)
2914 i_nearest_color(im, ...)
2929 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2930 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2931 croak("i_nearest_color: Second argument must be an array ref");
2932 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2933 croak("i_nearest_color: Third argument must be an array ref");
2934 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2935 croak("i_nearest_color: Fourth argument must be an array ref");
2936 axx = (AV *)SvRV(ST(1));
2937 ayy = (AV *)SvRV(ST(2));
2938 ac = (AV *)SvRV(ST(3));
2939 dmeasure = (int)SvIV(ST(4));
2941 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2942 num = num <= av_len(ac) ? num : av_len(ac);
2944 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2945 xo = mymalloc( sizeof(int) * num );
2946 yo = mymalloc( sizeof(int) * num );
2947 ival = mymalloc( sizeof(i_color) * num );
2948 for(i = 0; i<num; i++) {
2949 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2950 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2951 sv = *av_fetch(ac, i, 0);
2952 if ( !sv_derived_from(sv, "Imager::Color") ) {
2953 free(axx); free(ayy); free(ac);
2954 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2956 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2958 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2972 rc=DSO_open(filename,&evstr);
2976 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2977 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2980 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2986 DSO_close(dso_handle)
2990 DSO_funclist(dso_handle_v)
2994 DSO_handle *dso_handle;
2995 func_ptr *functions;
2997 dso_handle=(DSO_handle*)dso_handle_v;
2998 functions = DSO_funclist(dso_handle);
3000 while( functions[i].name != NULL) {
3002 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3004 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3008 DSO_call(handle,func_index,hv)
3014 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3015 hv=(HV*)SvRV(ST(2));
3016 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3017 DSO_call( (DSO_handle *)handle,func_index,hv);
3020 i_get_pixel(im, x, y)
3027 color = (i_color *)mymalloc(sizeof(i_color));
3028 if (i_gpix(im, x, y, color) == 0) {
3029 RETVAL = NEWSV(0, 0);
3030 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3034 RETVAL = &PL_sv_undef;
3041 i_ppix(im, x, y, cl)
3048 i_img_pal_new(x, y, channels, maxpal)
3055 i_img_to_pal(src, quant)
3061 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3062 croak("i_img_to_pal: second argument must be a hash ref");
3063 hv = (HV *)SvRV(ST(1));
3064 memset(&quant, 0, sizeof(quant));
3066 quant.mc_size = 256;
3067 ip_handle_quant_opts(aTHX_ &quant, hv);
3068 RETVAL = i_img_to_pal(src, &quant);
3070 ip_copy_colors_back(aTHX_ hv, &quant);
3072 ip_cleanup_quant_opts(aTHX_ &quant);
3091 work = mymalloc((r-l) * sizeof(i_palidx));
3092 count = i_gpal(im, l, r, y, work);
3093 if (GIMME_V == G_ARRAY) {
3095 for (i = 0; i < count; ++i) {
3096 PUSHs(sv_2mortal(newSViv(work[i])));
3101 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3106 if (GIMME_V != G_ARRAY) {
3108 PUSHs(&PL_sv_undef);
3113 i_ppal(im, l, y, ...)
3122 work = mymalloc(sizeof(i_palidx) * (items-3));
3123 for (i=0; i < items-3; ++i) {
3124 work[i] = SvIV(ST(i+3));
3126 validate_i_ppal(im, work, items - 3);
3127 RETVAL = i_ppal(im, l, l+items-3, y, work);
3137 i_ppal_p(im, l, y, data)
3143 i_palidx const *work;
3146 work = (i_palidx const *)SvPV(data, len);
3147 len /= sizeof(i_palidx);
3149 validate_i_ppal(im, work, len);
3150 RETVAL = i_ppal(im, l, l+len, y, work);
3159 i_addcolors(im, ...)
3167 croak("i_addcolors: no colors to add");
3168 colors = mymalloc((items-1) * sizeof(i_color));
3169 for (i=0; i < items-1; ++i) {
3170 if (sv_isobject(ST(i+1))
3171 && sv_derived_from(ST(i+1), "Imager::Color")) {
3172 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3173 colors[i] = *INT2PTR(i_color *, tmp);
3177 croak("i_addcolor: pixels must be Imager::Color objects");
3180 index = i_addcolors(im, colors, items-1);
3183 RETVAL = newSVpv("0 but true", 0);
3185 else if (index == -1) {
3186 RETVAL = &PL_sv_undef;
3189 RETVAL = newSViv(index);
3195 i_setcolors(im, index, ...)
3203 croak("i_setcolors: no colors to add");
3204 colors = mymalloc((items-2) * sizeof(i_color));
3205 for (i=0; i < items-2; ++i) {
3206 if (sv_isobject(ST(i+2))
3207 && sv_derived_from(ST(i+2), "Imager::Color")) {
3208 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3209 colors[i] = *INT2PTR(i_color *, tmp);
3213 croak("i_setcolors: pixels must be Imager::Color objects");
3216 RETVAL = i_setcolors(im, index, colors, items-2);
3222 i_getcolors(im, index, ...)
3231 croak("i_getcolors: too many arguments");
3233 count = SvIV(ST(2));
3235 croak("i_getcolors: count must be positive");
3236 colors = mymalloc(sizeof(i_color) * count);
3237 if (i_getcolors(im, index, colors, count)) {
3238 for (i = 0; i < count; ++i) {
3240 SV *sv = sv_newmortal();
3241 pv = mymalloc(sizeof(i_color));
3243 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3259 i_findcolor(im, color)
3265 if (i_findcolor(im, color, &index)) {
3266 RETVAL = newSViv(index);
3269 RETVAL = &PL_sv_undef;
3287 i_gsamp(im, l, r, y, ...)
3299 croak("No channel numbers supplied to g_samp()");
3301 chan_count = items - 4;
3302 chans = mymalloc(sizeof(int) * chan_count);
3303 for (i = 0; i < chan_count; ++i)
3304 chans[i] = SvIV(ST(i+4));
3305 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3306 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3308 if (GIMME_V == G_ARRAY) {
3310 for (i = 0; i < count; ++i)
3311 PUSHs(sv_2mortal(newSViv(data[i])));
3315 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3320 if (GIMME_V != G_ARRAY) {
3322 PUSHs(&PL_sv_undef);
3327 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3343 croak("No channel numbers supplied to g_samp()");
3345 chan_count = items - 7;
3346 chans = mymalloc(sizeof(int) * chan_count);
3347 for (i = 0; i < chan_count; ++i)
3348 chans[i] = SvIV(ST(i+7));
3349 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3350 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3352 for (i = 0; i < count; ++i) {
3353 av_store(target, i+offset, newSVuv(data[i]));
3365 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3383 if (SvOK(channels_sv)) {
3385 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3386 croak("channels is not an array ref");
3388 channels_av = (AV *)SvRV(channels_sv);
3389 chan_count = av_len(channels_av) + 1;
3390 if (chan_count < 1) {
3391 croak("i_psamp_bits: no channels provided");
3393 channels = mymalloc(sizeof(int) * chan_count);
3394 for (i = 0; i < chan_count; ++i)
3395 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3398 chan_count = im->channels;
3402 data_count = av_len(data_av) + 1;
3403 if (data_offset < 0) {
3404 croak("data_offset must by non-negative");
3406 if (data_offset > data_count) {
3407 croak("data_offset greater than number of samples supplied");
3409 if (pixel_count == -1 ||
3410 data_offset + pixel_count * chan_count > data_count) {
3411 pixel_count = (data_count - data_offset) / chan_count;
3414 data_used = pixel_count * chan_count;
3415 data = mymalloc(sizeof(unsigned) * data_count);
3416 for (i = 0; i < data_used; ++i)
3417 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3419 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3430 i_img_masked_new(targ, mask, x, y, w, h)
3440 if (!sv_isobject(ST(1))
3441 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3442 croak("i_img_masked_new: parameter 2 must undef or an image");
3444 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3448 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3453 i_plin(im, l, y, ...)
3464 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3465 /* supplied as a byte string */
3466 work = (i_color *)SvPV(ST(3), len);
3467 count = len / sizeof(i_color);
3468 if (count * sizeof(i_color) != len) {
3469 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3471 RETVAL = i_plin(im, l, l+count, y, work);
3474 work = mymalloc(sizeof(i_color) * (items-3));
3475 for (i=0; i < items-3; ++i) {
3476 if (sv_isobject(ST(i+3))
3477 && sv_derived_from(ST(i+3), "Imager::Color")) {
3478 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3479 work[i] = *INT2PTR(i_color *, tmp);
3483 croak("i_plin: pixels must be Imager::Color objects");
3486 RETVAL = i_plin(im, l, l+items-3, y, work);
3497 i_ppixf(im, x, y, cl)
3501 Imager::Color::Float cl
3504 i_gsampf(im, l, r, y, ...)
3516 croak("No channel numbers supplied to g_sampf()");
3518 chan_count = items - 4;
3519 chans = mymalloc(sizeof(int) * chan_count);
3520 for (i = 0; i < chan_count; ++i)
3521 chans[i] = SvIV(ST(i+4));
3522 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3523 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3525 if (GIMME_V == G_ARRAY) {
3527 for (i = 0; i < count; ++i)
3528 PUSHs(sv_2mortal(newSVnv(data[i])));
3532 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3537 if (GIMME_V != G_ARRAY) {
3539 PUSHs(&PL_sv_undef);
3544 i_plinf(im, l, y, ...)
3555 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3556 /* supplied as a byte string */
3557 work = (i_fcolor *)SvPV(ST(3), len);
3558 count = len / sizeof(i_fcolor);
3559 if (count * sizeof(i_fcolor) != len) {
3560 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3562 RETVAL = i_plinf(im, l, l+count, y, work);
3565 work = mymalloc(sizeof(i_fcolor) * (items-3));
3566 for (i=0; i < items-3; ++i) {
3567 if (sv_isobject(ST(i+3))
3568 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3569 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3570 work[i] = *INT2PTR(i_fcolor *, tmp);
3574 croak("i_plinf: pixels must be Imager::Color::Float objects");
3578 RETVAL = i_plinf(im, l, l+items-3, y, work);
3596 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3597 if (i_gpixf(im, x, y, color) == 0) {
3598 RETVAL = NEWSV(0,0);
3599 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3603 RETVAL = &PL_sv_undef;
3619 vals = mymalloc((r-l) * sizeof(i_color));
3620 memset(vals, 0, (r-l) * sizeof(i_color));
3621 count = i_glin(im, l, r, y, vals);
3622 if (GIMME_V == G_ARRAY) {
3624 for (i = 0; i < count; ++i) {
3626 i_color *col = mymalloc(sizeof(i_color));
3628 sv = sv_newmortal();
3629 sv_setref_pv(sv, "Imager::Color", (void *)col);
3635 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3641 i_glinf(im, l, r, y)
3651 for (i = 0; i < MAXCHANNELS; ++i)
3652 zero.channel[i] = 0;
3654 vals = mymalloc((r-l) * sizeof(i_fcolor));
3655 for (i = 0; i < r-l; ++i)
3657 count = i_glinf(im, l, r, y, vals);
3658 if (GIMME_V == G_ARRAY) {
3660 for (i = 0; i < count; ++i) {
3662 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3664 sv = sv_newmortal();
3665 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3671 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3677 i_img_16_new(x, y, ch)
3687 i_img_double_new(x, y, ch)
3693 i_tags_addn(im, name, code, idata)
3702 name = SvPV(ST(1), len);
3705 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3710 i_tags_add(im, name, code, data, idata)
3720 name = SvPV(ST(1), len);
3724 data = SvPV(ST(3), len);
3729 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3734 i_tags_find(im, name, start)
3741 if (i_tags_find(&im->tags, name, start, &entry)) {
3743 RETVAL = newSVpv("0 but true", 0);
3745 RETVAL = newSViv(entry);
3747 RETVAL = &PL_sv_undef;
3753 i_tags_findn(im, code, start)
3760 if (i_tags_findn(&im->tags, code, start, &entry)) {
3762 RETVAL = newSVpv("0 but true", 0);
3764 RETVAL = newSViv(entry);
3767 RETVAL = &PL_sv_undef;
3773 i_tags_delete(im, entry)
3777 RETVAL = i_tags_delete(&im->tags, entry);
3782 i_tags_delbyname(im, name)
3786 RETVAL = i_tags_delbyname(&im->tags, name);
3791 i_tags_delbycode(im, code)
3795 RETVAL = i_tags_delbycode(&im->tags, code);
3800 i_tags_get(im, index)
3804 if (index >= 0 && index < im->tags.count) {
3805 i_img_tag *entry = im->tags.tags + index;
3809 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3812 PUSHs(sv_2mortal(newSViv(entry->code)));
3815 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3818 PUSHs(sv_2mortal(newSViv(entry->idata)));
3823 i_tags_get_string(im, what_sv)
3827 char const *name = NULL;
3831 if (SvIOK(what_sv)) {
3832 code = SvIV(what_sv);
3836 name = SvPV_nolen(what_sv);
3839 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3841 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3848 RETVAL = im->tags.count;
3854 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3858 Imager::FillHandle fill
3861 IFILL_CLONE_SKIP(...)
3867 MODULE = Imager PACKAGE = Imager
3870 i_new_fill_solid(cl, combine)
3875 i_new_fill_solidf(cl, combine)
3876 Imager::Color::Float cl
3880 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3888 unsigned char *cust_hatch;
3892 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3896 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3901 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3902 Imager::Color::Float fg
3903 Imager::Color::Float bg
3909 unsigned char *cust_hatch;
3913 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3917 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3922 i_new_fill_image(src, matrix, xoff, yoff, combine)
3939 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3940 croak("i_new_fill_image: parameter must be an arrayref");
3941 av=(AV*)SvRV(ST(1));
3945 for (i = 0; i < len; ++i) {
3946 sv1=(*(av_fetch(av,i,0)));
3947 matrix[i] = SvNV(sv1);
3953 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3957 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3959 # this class is only exposed for testing
3962 i_int_hlines_testing()
3964 #if i_int_hlines_testing()
3966 Imager::Internal::Hlines
3967 i_int_hlines_new(start_y, count_y, start_x, count_x)
3973 Imager::Internal::Hlines
3974 i_int_hlines_new_img(im)
3978 i_int_hlines_add(hlines, y, minx, width)
3979 Imager::Internal::Hlines hlines
3985 i_int_hlines_DESTROY(hlines)
3986 Imager::Internal::Hlines hlines
3989 i_int_hlines_dump(hlines)
3990 Imager::Internal::Hlines hlines
3993 i_int_hlines_CLONE_SKIP(cls)
3999 PERL_SET_GLOBAL_CALLBACKS;
4000 PERL_PL_SET_GLOBAL_CALLBACKS;