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"
25 #if i_int_hlines_testing()
33 Allocate memory that will be discarded when mortals are discarded.
38 malloc_temp(pTHX_ size_t size) {
39 SV *sv = sv_2mortal(newSV(size));
44 /* These functions are all shared - then comes platform dependant code */
45 static int getstr(void *hv_t,char *key,char **store) {
50 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
52 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
54 svpp=hv_fetch(hv, key, strlen(key), 0);
55 *store=SvPV(*svpp, PL_na );
60 static int getint(void *hv_t,char *key,int *store) {
65 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
67 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
69 svpp=hv_fetch(hv, key, strlen(key), 0);
70 *store=(int)SvIV(*svpp);
74 static int getdouble(void *hv_t,char* key,double *store) {
79 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
81 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
82 svpp=hv_fetch(hv, key, strlen(key), 0);
83 *store=(double)SvNV(*svpp);
87 static int getvoid(void *hv_t,char* key,void **store) {
92 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
94 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
96 svpp=hv_fetch(hv, key, strlen(key), 0);
97 *store = INT2PTR(void*, SvIV(*svpp));
102 static int getobj(void *hv_t,char *key,char *type,void **store) {
107 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
109 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
111 svpp=hv_fetch(hv, key, strlen(key), 0);
113 if (sv_derived_from(*svpp,type)) {
114 IV tmp = SvIV((SV*)SvRV(*svpp));
115 *store = INT2PTR(void*, tmp);
117 mm_log((1,"getobj: key exists in hash but is not of correct type"));
124 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
126 void my_SvREFCNT_dec(void *p) {
128 SvREFCNT_dec((SV*)p);
133 i_log_entry(char *string, int level) {
134 mm_log((level, string));
138 #define CBDATA_BUFSIZE 8192
141 /* the SVs we use to call back to Perl */
147 /* we need to remember whether the buffer contains write data or
153 /* how far we've read into the buffer (not used for writing) */
156 /* the amount of space used/data available in the buffer */
159 /* the maximum amount to fill the buffer before flushing
160 If any write is larger than this then the buffer is flushed and
161 the full write is performed. The write is _not_ split into
166 char buffer[CBDATA_BUFSIZE];
171 call_writer(cbd, buf, size)
173 Low-level function to call the perl writer callback.
177 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
184 if (!SvOK(cbd->writecb))
191 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
194 count = perl_call_sv(cbd->writecb, G_SCALAR);
198 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
201 success = SvTRUE(sv);
208 return success ? size : -1;
211 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
219 if (!SvOK(cbd->readcb))
226 PUSHs(sv_2mortal(newSViv(size)));
227 PUSHs(sv_2mortal(newSViv(maxread)));
230 count = perl_call_sv(cbd->readcb, G_SCALAR);
235 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
241 char *ptr = SvPV(data, len);
243 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
244 (int)size, (int)len, (int)maxread);
246 memcpy(buf, ptr, len);
260 static ssize_t write_flush(struct cbdata *cbd) {
265 result = call_writer(cbd, cbd->buffer, cbd->used);
270 return 1; /* success of some sort */
274 static off_t io_seeker(void *p, off_t offset, int whence) {
276 struct cbdata *cbd = p;
281 if (!SvOK(cbd->seekcb))
285 if (cbd->used && write_flush(cbd) <= 0)
289 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
290 offset -= cbd->where - cbd->used;
293 cbd->where = cbd->used = 0;
299 PUSHs(sv_2mortal(newSViv(offset)));
300 PUSHs(sv_2mortal(newSViv(whence)));
303 count = perl_call_sv(cbd->seekcb, G_SCALAR);
308 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
319 static ssize_t io_writer(void *p, void const *data, size_t size) {
321 struct cbdata *cbd = p;
323 /* printf("io_writer(%p, %p, %u)\n", p, data, size); */
325 if (cbd->reading && cbd->where < cbd->used) {
326 /* we read past the place where the caller expected us to be
327 so adjust our position a bit */
328 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
333 cbd->where = cbd->used = 0;
336 if (cbd->used && cbd->used + size > cbd->maxlength) {
337 int write_res = write_flush(cbd);
338 if (write_res <= 0) {
343 if (cbd->used+size <= cbd->maxlength) {
344 memcpy(cbd->buffer + cbd->used, data, size);
348 /* it doesn't fit - just pass it up */
349 return call_writer(cbd, data, size);
353 io_reader(void *p, void *data, size_t size) {
355 struct cbdata *cbd = p;
357 char *out = data; /* so we can do pointer arithmetic */
359 /* printf("io_reader(%p, %p, %d)\n", p, data, size); */
361 if (write_flush(cbd) <= 0)
367 if (size <= cbd->used - cbd->where) {
369 memcpy(data, cbd->buffer+cbd->where, size);
374 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
375 total += cbd->used - cbd->where;
376 size -= cbd->used - cbd->where;
377 out += cbd->used - cbd->where;
378 if (size < sizeof(cbd->buffer)) {
382 && (did_read = call_reader(cbd, cbd->buffer, size,
383 sizeof(cbd->buffer))) > 0) {
385 cbd->used = did_read;
387 copy_size = i_min(size, cbd->used);
388 memcpy(out, cbd->buffer, copy_size);
389 cbd->where += copy_size;
398 /* just read the rest - too big for our buffer*/
400 while (size > 0 && (did_read = call_reader(cbd, out, size, size)) > 0) {
412 static int io_closer(void *p) {
414 struct cbdata *cbd = p;
416 if (cbd->writing && cbd->used > 0) {
417 if (write_flush(cbd) < 0)
422 if (SvOK(cbd->closecb)) {
430 perl_call_sv(cbd->closecb, G_VOID);
441 static void io_destroyer(void *p) {
443 struct cbdata *cbd = p;
445 SvREFCNT_dec(cbd->writecb);
446 SvREFCNT_dec(cbd->readcb);
447 SvREFCNT_dec(cbd->seekcb);
448 SvREFCNT_dec(cbd->closecb);
456 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
459 for (i = 0; i < count; ++i)
460 if (strEQ(names[i].name, name))
461 return names[i].value;
465 static struct value_name transp_names[] =
468 { "threshold", tr_threshold },
469 { "errdiff", tr_errdiff },
470 { "ordered", tr_ordered, },
473 static struct value_name make_color_names[] =
475 { "none", mc_none, },
476 { "webmap", mc_web_map, },
477 { "addi", mc_addi, },
478 { "mediancut", mc_median_cut, },
479 { "mono", mc_mono, },
480 { "monochrome", mc_mono, },
483 static struct value_name translate_names[] =
485 { "giflib", pt_giflib, },
486 { "closest", pt_closest, },
487 { "perturb", pt_perturb, },
488 { "errdiff", pt_errdiff, },
491 static struct value_name errdiff_names[] =
493 { "floyd", ed_floyd, },
494 { "jarvis", ed_jarvis, },
495 { "stucki", ed_stucki, },
496 { "custom", ed_custom, },
499 static struct value_name orddith_names[] =
501 { "random", od_random, },
502 { "dot8", od_dot8, },
503 { "dot4", od_dot4, },
504 { "hline", od_hline, },
505 { "vline", od_vline, },
506 { "/line", od_slashline, },
507 { "slashline", od_slashline, },
508 { "\\line", od_backline, },
509 { "backline", od_backline, },
510 { "tiny", od_tiny, },
511 { "custom", od_custom, },
514 /* look through the hash for quantization options */
516 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
518 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
524 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
526 sv = hv_fetch(hv, "transp", 6, 0);
527 if (sv && *sv && (str = SvPV(*sv, len))) {
529 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
531 if (quant->transp != tr_none) {
532 quant->tr_threshold = 127;
533 sv = hv_fetch(hv, "tr_threshold", 12, 0);
535 quant->tr_threshold = SvIV(*sv);
537 if (quant->transp == tr_errdiff) {
538 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
539 if (sv && *sv && (str = SvPV(*sv, len)))
540 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
542 if (quant->transp == tr_ordered) {
543 quant->tr_orddith = od_tiny;
544 sv = hv_fetch(hv, "tr_orddith", 10, 0);
545 if (sv && *sv && (str = SvPV(*sv, len)))
546 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
548 if (quant->tr_orddith == od_custom) {
549 sv = hv_fetch(hv, "tr_map", 6, 0);
550 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
551 AV *av = (AV*)SvRV(*sv);
552 len = av_len(av) + 1;
553 if (len > sizeof(quant->tr_custom))
554 len = sizeof(quant->tr_custom);
555 for (i = 0; i < len; ++i) {
556 SV **sv2 = av_fetch(av, i, 0);
558 quant->tr_custom[i] = SvIV(*sv2);
561 while (i < sizeof(quant->tr_custom))
562 quant->tr_custom[i++] = 0;
567 quant->make_colors = mc_median_cut;
568 sv = hv_fetch(hv, "make_colors", 11, 0);
569 if (sv && *sv && (str = SvPV(*sv, len))) {
571 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
573 sv = hv_fetch(hv, "colors", 6, 0);
574 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
575 /* needs to be an array of Imager::Color
576 note that the caller allocates the mc_color array and sets mc_size
578 AV *av = (AV *)SvRV(*sv);
579 quant->mc_count = av_len(av)+1;
580 if (quant->mc_count > quant->mc_size)
581 quant->mc_count = quant->mc_size;
582 for (i = 0; i < quant->mc_count; ++i) {
583 SV **sv1 = av_fetch(av, i, 0);
584 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
585 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
586 quant->mc_colors[i] = *col;
590 sv = hv_fetch(hv, "max_colors", 10, 0);
593 if (i <= quant->mc_size && i >= quant->mc_count)
597 quant->translate = pt_closest;
598 sv = hv_fetch(hv, "translate", 9, 0);
599 if (sv && *sv && (str = SvPV(*sv, len))) {
600 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
602 sv = hv_fetch(hv, "errdiff", 7, 0);
603 if (sv && *sv && (str = SvPV(*sv, len))) {
604 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
606 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
607 /* get the error diffusion map */
608 sv = hv_fetch(hv, "errdiff_width", 13, 0);
610 quant->ed_width = SvIV(*sv);
611 sv = hv_fetch(hv, "errdiff_height", 14, 0);
613 quant->ed_height = SvIV(*sv);
614 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
616 quant->ed_orig = SvIV(*sv);
617 if (quant->ed_width > 0 && quant->ed_height > 0) {
619 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
620 sv = hv_fetch(hv, "errdiff_map", 11, 0);
621 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
622 AV *av = (AV*)SvRV(*sv);
623 len = av_len(av) + 1;
624 if (len > quant->ed_width * quant->ed_height)
625 len = quant->ed_width * quant->ed_height;
626 for (i = 0; i < len; ++i) {
627 SV **sv2 = av_fetch(av, i, 0);
629 quant->ed_map[i] = SvIV(*sv2);
630 sum += quant->ed_map[i];
636 myfree(quant->ed_map);
638 quant->errdiff = ed_floyd;
642 sv = hv_fetch(hv, "perturb", 7, 0);
644 quant->perturb = SvIV(*sv);
648 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
649 myfree(quant->mc_colors);
651 myfree(quant->ed_map);
654 /* copies the color map from the hv into the colors member of the HV */
656 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
662 sv = hv_fetch(hv, "colors", 6, 0);
663 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
668 av = (AV *)SvRV(*sv);
670 av_extend(av, quant->mc_count+1);
671 for (i = 0; i < quant->mc_count; ++i) {
672 i_color *in = quant->mc_colors+i;
673 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
674 work = sv_newmortal();
675 sv_setref_pv(work, "Imager::Color", (void *)c);
681 /* loads the segments of a fountain fill into an array */
682 static i_fountain_seg *
683 load_fount_segs(pTHX_ AV *asegs, int *count) {
684 /* Each element of segs must contain:
685 [ start, middle, end, c0, c1, segtype, colortrans ]
686 start, middle, end are doubles from 0 to 1
687 c0, c1 are Imager::Color::Float or Imager::Color objects
688 segtype, colortrans are ints
692 i_fountain_seg *segs;
696 *count = av_len(asegs)+1;
698 croak("i_fountain must have at least one segment");
699 segs = mymalloc(sizeof(i_fountain_seg) * *count);
700 for(i = 0; i < *count; i++) {
701 SV **sv1 = av_fetch(asegs, i, 0);
702 if (!sv1 || !*sv1 || !SvROK(*sv1)
703 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
705 croak("i_fountain: segs must be an arrayref of arrayrefs");
707 aseg = (AV *)SvRV(*sv1);
708 if (av_len(aseg) != 7-1) {
710 croak("i_fountain: a segment must have 7 members");
712 for (j = 0; j < 3; ++j) {
713 SV **sv2 = av_fetch(aseg, j, 0);
716 croak("i_fountain: XS error");
718 work[j] = SvNV(*sv2);
720 segs[i].start = work[0];
721 segs[i].middle = work[1];
722 segs[i].end = work[2];
723 for (j = 0; j < 2; ++j) {
724 SV **sv3 = av_fetch(aseg, 3+j, 0);
725 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
726 (!sv_derived_from(*sv3, "Imager::Color")
727 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
729 croak("i_fountain: segs must contain colors in elements 3 and 4");
731 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
732 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
735 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
737 for (ch = 0; ch < MAXCHANNELS; ++ch) {
738 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
742 for (j = 0; j < 2; ++j) {
743 SV **sv2 = av_fetch(aseg, j+5, 0);
746 croak("i_fountain: XS error");
748 worki[j] = SvIV(*sv2);
750 segs[i].type = worki[0];
751 segs[i].color = worki[1];
757 /* validates the indexes supplied to i_ppal
759 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
764 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
765 int color_count = i_colorcount(im);
768 if (color_count == -1)
769 croak("i_plin() called on direct color image");
771 for (i = 0; i < count; ++i) {
772 if (indexes[i] >= color_count) {
773 croak("i_plin() called with out of range color index %d (max %d)",
774 indexes[i], color_count-1);
780 /* I don't think ICLF_* names belong at the C interface
781 this makes the XS code think we have them, to let us avoid
782 putting function bodies in the XS code
784 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
785 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
788 #define i_log_enabled() 1
790 #define i_log_enabled() 0
793 #if i_int_hlines_testing()
795 typedef i_int_hlines *Imager__Internal__Hlines;
797 static i_int_hlines *
798 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
799 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
800 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
805 static i_int_hlines *
806 i_int_hlines_new_img(i_img *im) {
807 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
808 i_int_init_hlines_img(result, im);
814 i_int_hlines_DESTROY(i_int_hlines *hlines) {
815 i_int_hlines_destroy(hlines);
819 #define i_int_hlines_CLONE_SKIP(cls) 1
821 static int seg_compare(const void *vleft, const void *vright) {
822 const i_int_hline_seg *left = vleft;
823 const i_int_hline_seg *right = vright;
825 return left->minx - right->minx;
829 i_int_hlines_dump(i_int_hlines *hlines) {
831 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
832 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
835 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
836 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
839 /* sort the segments, if any */
841 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
843 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
844 for (i = 0; i < entry->count; ++i) {
845 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
846 i_DFc(entry->segs[i].x_limit));
848 sv_catpv(dump, "\n");
858 i_sv_off_t(pTHX_ SV *sv) {
859 #if LSEEKSIZE > IVSIZE
860 return (off_t)SvNV(sv);
862 return (off_t)SvIV(sv);
867 i_new_sv_off_t(pTHX_ off_t off) {
868 #if LSEEKSIZE > IVSIZE
875 static im_pl_ext_funcs im_perl_funcs =
877 IMAGER_PL_API_VERSION,
879 ip_handle_quant_opts,
880 ip_cleanup_quant_opts,
884 #define PERL_PL_SET_GLOBAL_CALLBACKS \
885 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
888 #define i_exif_enabled() 1
890 #define i_exif_enabled() 0
893 /* trying to use more C style names, map them here */
894 #define i_io_DESTROY(ig) io_glue_destroy(ig)
896 #define i_img_get_width(im) ((im)->xsize)
897 #define i_img_get_height(im) ((im)->ysize)
899 #define i_img_epsilonf() (DBL_EPSILON * 4)
901 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
904 ICL_new_internal(r,g,b,a)
916 ICL_set_internal(cl,r,g,b,a)
923 ICL_set_internal(cl, r, g, b, a);
937 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
938 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
939 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
940 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
946 RETVAL = mymalloc(sizeof(i_color));
948 i_hsv_to_rgb(RETVAL);
956 RETVAL = mymalloc(sizeof(i_color));
958 i_rgb_to_hsv(RETVAL);
964 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
967 ICLF_new_internal(r, g, b, a)
975 Imager::Color::Float cl
979 Imager::Color::Float cl
983 EXTEND(SP, MAXCHANNELS);
984 for (ch = 0; ch < MAXCHANNELS; ++ch) {
985 /* printf("%d: %g\n", ch, cl->channel[ch]); */
986 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
990 ICLF_set_internal(cl,r,g,b,a)
991 Imager::Color::Float cl
1004 Imager::Color::Float
1006 Imager::Color::Float c
1008 RETVAL = mymalloc(sizeof(i_fcolor));
1010 i_hsv_to_rgbf(RETVAL);
1014 Imager::Color::Float
1016 Imager::Color::Float c
1018 RETVAL = mymalloc(sizeof(i_fcolor));
1020 i_rgb_to_hsvf(RETVAL);
1024 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1038 MODULE = Imager PACKAGE = Imager
1057 SvPV(ST(0), length);
1058 SvREFCNT_inc(ST(0));
1059 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1064 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1073 cbd = mymalloc(sizeof(struct cbdata));
1074 SvREFCNT_inc(writecb);
1075 cbd->writecb = writecb;
1076 SvREFCNT_inc(readcb);
1077 cbd->readcb = readcb;
1078 SvREFCNT_inc(seekcb);
1079 cbd->seekcb = seekcb;
1080 SvREFCNT_inc(closecb);
1081 cbd->closecb = closecb;
1082 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1083 if (maxwrite > CBDATA_BUFSIZE)
1084 maxwrite = CBDATA_BUFSIZE;
1085 cbd->maxlength = maxwrite;
1086 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1095 unsigned char* data;
1099 tlength = io_slurp(ig, &data);
1101 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1106 i_set_image_file_limits(width, height, bytes)
1112 i_get_image_file_limits()
1114 i_img_dim width, height;
1117 if (i_get_image_file_limits(&width, &height, &bytes)) {
1119 PUSHs(sv_2mortal(newSViv(width)));
1120 PUSHs(sv_2mortal(newSViv(height)));
1121 PUSHs(sv_2mortal(newSVuv(bytes)));
1124 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1127 i_io_raw_write(ig, data_sv)
1135 if (SvUTF8(data_sv)) {
1136 data_sv = sv_2mortal(newSVsv(data_sv));
1137 /* yes, we want this to croak() if the SV can't be downgraded */
1138 sv_utf8_downgrade(data_sv, FALSE);
1141 data = SvPV(data_sv, size);
1142 RETVAL = i_io_raw_write(ig, data, size);
1147 i_io_raw_read(ig, buffer_sv, size)
1156 croak("size negative in call to i_io_read()");
1157 /* prevent an undefined value warning if they supplied an
1159 Orginally conditional on !SvOK(), but this will prevent the
1160 downgrade from croaking */
1161 sv_setpvn(buffer_sv, "", 0);
1163 if (SvUTF8(buffer_sv))
1164 sv_utf8_downgrade(buffer_sv, FALSE);
1166 buffer = SvGROW(buffer_sv, size+1);
1167 result = i_io_raw_read(ig, buffer, size);
1169 SvCUR_set(buffer_sv, result);
1170 *SvEND(buffer_sv) = '\0';
1171 SvPOK_only(buffer_sv);
1173 PUSHs(sv_2mortal(newSViv(result)));
1179 i_io_raw_read2(ig, size)
1188 croak("size negative in call to i_io_read2()");
1189 buffer_sv = newSV(size);
1190 buffer = SvGROW(buffer_sv, size+1);
1191 result = i_io_raw_read(ig, buffer, size);
1193 SvCUR_set(buffer_sv, result);
1194 *SvEND(buffer_sv) = '\0';
1195 SvPOK_only(buffer_sv);
1197 PUSHs(sv_2mortal(buffer_sv));
1201 SvREFCNT_dec(buffer_sv);
1205 i_io_raw_seek(ig, position, whence)
1219 i_io_CLONE_SKIP(...)
1221 (void)items; /* avoid unused warning for XS variable */
1248 i_io_seek(ig, off, whence)
1254 i_io_peekn(ig, size)
1263 croak("size zero in call to peekn()");
1264 buffer_sv = newSV(size);
1265 buffer = SvGROW(buffer_sv, size+1);
1266 result = i_io_peekn(ig, buffer, size);
1268 SvCUR_set(buffer_sv, result);
1269 *SvEND(buffer_sv) = '\0';
1270 SvPOK_only(buffer_sv);
1272 PUSHs(sv_2mortal(buffer_sv));
1276 SvREFCNT_dec(buffer_sv);
1280 i_io_read(ig, buffer_sv, size)
1289 croak("size negative in call to i_io_read()");
1290 /* prevent an undefined value warning if they supplied an
1292 Orginally conditional on !SvOK(), but this will prevent the
1293 downgrade from croaking */
1294 sv_setpvn(buffer_sv, "", 0);
1296 if (SvUTF8(buffer_sv))
1297 sv_utf8_downgrade(buffer_sv, FALSE);
1299 buffer = SvGROW(buffer_sv, size+1);
1300 result = i_io_read(ig, buffer, size);
1302 SvCUR_set(buffer_sv, result);
1303 *SvEND(buffer_sv) = '\0';
1304 SvPOK_only(buffer_sv);
1306 PUSHs(sv_2mortal(newSViv(result)));
1312 i_io_read2(ig, size)
1321 croak("size zero in call to bread()");
1322 buffer_sv = newSV(size);
1323 buffer = SvGROW(buffer_sv, size+1);
1324 result = i_io_read(ig, buffer, size);
1326 SvCUR_set(buffer_sv, result);
1327 *SvEND(buffer_sv) = '\0';
1328 SvPOK_only(buffer_sv);
1330 PUSHs(sv_2mortal(buffer_sv));
1334 SvREFCNT_dec(buffer_sv);
1338 i_io_write(ig, data_sv)
1346 if (SvUTF8(data_sv)) {
1347 data_sv = sv_2mortal(newSVsv(data_sv));
1348 /* yes, we want this to croak() if the SV can't be downgraded */
1349 sv_utf8_downgrade(data_sv, FALSE);
1352 data = SvPV(data_sv, size);
1353 RETVAL = i_io_write(ig, data, size);
1358 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1363 i_io_set_buffered(ig, flag = 1)
1367 MODULE = Imager PACKAGE = Imager
1378 while( (item=i_format_list[i++]) != NULL ) {
1380 PUSHs(sv_2mortal(newSVpv(item,0)));
1393 i_img_empty_ch(im,x,y,ch)
1400 i_sametype(im, x, y)
1406 i_sametype_chans(im, x, y, channels)
1413 i_init_log(name_sv,level)
1417 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1419 RETVAL = i_init_log(name, level);
1424 i_log_entry(string,level)
1445 i_img_info(im,info);
1447 PUSHs(sv_2mortal(newSViv(info[0])));
1448 PUSHs(sv_2mortal(newSViv(info[1])));
1449 PUSHs(sv_2mortal(newSViv(info[2])));
1450 PUSHs(sv_2mortal(newSViv(info[3])));
1456 i_img_setmask(im,ch_mask)
1465 i_img_getchannels(im)
1474 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1482 i_img_get_height(im)
1487 i_img_is_monochrome(im)
1493 result = i_img_is_monochrome(im, &zero_is_white);
1495 if (GIMME_V == G_ARRAY) {
1498 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1507 i_line(im,x1,y1,x2,y2,val,endp)
1517 i_line_aa(im,x1,y1,x2,y2,val,endp)
1527 i_box(im,x1,y1,x2,y2,val)
1536 i_box_filled(im,x1,y1,x2,y2,val)
1545 i_box_filledf(im,x1,y1,x2,y2,val)
1551 Imager::Color::Float val
1554 i_box_cfill(im,x1,y1,x2,y2,fill)
1560 Imager::FillHandle fill
1563 i_arc(im,x,y,rad,d1,d2,val)
1573 i_arc_aa(im,x,y,rad,d1,d2,val)
1583 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1590 Imager::FillHandle fill
1593 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1600 Imager::FillHandle fill
1604 i_circle_aa(im,x,y,rad,val)
1612 i_circle_out(im,x,y,rad,val)
1620 i_circle_out_aa(im,x,y,rad,val)
1628 i_arc_out(im,x,y,rad,d1,d2,val)
1638 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1649 i_bezier_multi(im,xc,yc,val)
1662 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1663 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1664 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1665 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1666 av1=(AV*)SvRV(ST(1));
1667 av2=(AV*)SvRV(ST(2));
1668 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1670 x=mymalloc( len*sizeof(double) );
1671 y=mymalloc( len*sizeof(double) );
1672 for(i=0;i<len;i++) {
1673 sv1=(*(av_fetch(av1,i,0)));
1674 sv2=(*(av_fetch(av2,i,0)));
1675 x[i]=(double)SvNV(sv1);
1676 y[i]=(double)SvNV(sv2);
1678 i_bezier_multi(im,len,x,y,val);
1684 i_poly_aa(im,xc,yc,val)
1697 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1698 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1699 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1700 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1701 av1=(AV*)SvRV(ST(1));
1702 av2=(AV*)SvRV(ST(2));
1703 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1705 x=mymalloc( len*sizeof(double) );
1706 y=mymalloc( len*sizeof(double) );
1707 for(i=0;i<len;i++) {
1708 sv1=(*(av_fetch(av1,i,0)));
1709 sv2=(*(av_fetch(av2,i,0)));
1710 x[i]=(double)SvNV(sv1);
1711 y[i]=(double)SvNV(sv2);
1713 RETVAL = i_poly_aa(im,len,x,y,val);
1720 i_poly_aa_cfill(im,xc,yc,fill)
1722 Imager::FillHandle fill
1732 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1733 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1734 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1735 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1736 av1=(AV*)SvRV(ST(1));
1737 av2=(AV*)SvRV(ST(2));
1738 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1740 x=mymalloc( len*sizeof(double) );
1741 y=mymalloc( len*sizeof(double) );
1742 for(i=0;i<len;i++) {
1743 sv1=(*(av_fetch(av1,i,0)));
1744 sv2=(*(av_fetch(av2,i,0)));
1745 x[i]=(double)SvNV(sv1);
1746 y[i]=(double)SvNV(sv2);
1748 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1757 i_flood_fill(im,seedx,seedy,dcol)
1764 i_flood_cfill(im,seedx,seedy,fill)
1768 Imager::FillHandle fill
1771 i_flood_fill_border(im,seedx,seedy,dcol, border)
1776 Imager::Color border
1779 i_flood_cfill_border(im,seedx,seedy,fill, border)
1783 Imager::FillHandle fill
1784 Imager::Color border
1788 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1800 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1817 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1828 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1841 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)
1857 i_combine(src_av, channels_av = NULL)
1861 i_img **imgs = NULL;
1863 int *channels = NULL;
1868 in_count = av_len(src_av) + 1;
1870 imgs = mymalloc(sizeof(i_img*) * in_count);
1871 channels = mymalloc(sizeof(int) * in_count);
1872 for (i = 0; i < in_count; ++i) {
1873 psv = av_fetch(src_av, i, 0);
1874 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1877 croak("imgs must contain only images");
1879 tmp = SvIV((SV*)SvRV(*psv));
1880 imgs[i] = INT2PTR(i_img*, tmp);
1882 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1884 channels[i] = SvIV(*psv);
1891 RETVAL = i_combine(imgs, channels, in_count);
1898 i_flipxy(im, direction)
1903 i_rotate90(im, degrees)
1908 i_rotate_exact(im, amount, ...)
1912 i_color *backp = NULL;
1913 i_fcolor *fbackp = NULL;
1917 /* extract the bg colors if any */
1918 /* yes, this is kind of strange */
1919 for (i = 2; i < items; ++i) {
1921 if (sv_derived_from(sv1, "Imager::Color")) {
1922 IV tmp = SvIV((SV*)SvRV(sv1));
1923 backp = INT2PTR(i_color *, tmp);
1925 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1926 IV tmp = SvIV((SV*)SvRV(sv1));
1927 fbackp = INT2PTR(i_fcolor *, tmp);
1930 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1935 i_matrix_transform(im, xsize, ysize, matrix, ...)
1945 i_color *backp = NULL;
1946 i_fcolor *fbackp = NULL;
1948 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1949 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1950 av=(AV*)SvRV(ST(3));
1954 for (i = 0; i < len; ++i) {
1955 sv1=(*(av_fetch(av,i,0)));
1956 matrix[i] = SvNV(sv1);
1960 /* extract the bg colors if any */
1961 /* yes, this is kind of strange */
1962 for (i = 4; i < items; ++i) {
1964 if (sv_derived_from(sv1, "Imager::Color")) {
1965 IV tmp = SvIV((SV*)SvRV(sv1));
1966 backp = INT2PTR(i_color *, tmp);
1968 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1969 IV tmp = SvIV((SV*)SvRV(sv1));
1970 fbackp = INT2PTR(i_fcolor *, tmp);
1973 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1978 i_gaussian(im,stdev)
1983 i_unsharp_mask(im,stdev,scale)
1998 len = av_len(coef) + 1;
1999 c_coef=mymalloc( len * sizeof(double) );
2000 for(i = 0; i < len; i++) {
2001 sv1 = (*(av_fetch(coef, i, 0)));
2002 c_coef[i] = (double)SvNV(sv1);
2004 RETVAL = i_conv(im, c_coef, len);
2010 i_convert(src, avmain)
2022 outchan = av_len(avmain)+1;
2023 /* find the biggest */
2025 for (j=0; j < outchan; ++j) {
2026 temp = av_fetch(avmain, j, 0);
2027 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2028 avsub = (AV*)SvRV(*temp);
2029 len = av_len(avsub)+1;
2034 coeff = mymalloc(sizeof(double) * outchan * inchan);
2035 for (j = 0; j < outchan; ++j) {
2036 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2037 len = av_len(avsub)+1;
2038 for (i = 0; i < len; ++i) {
2039 temp = av_fetch(avsub, i, 0);
2041 coeff[i+j*inchan] = SvNV(*temp);
2043 coeff[i+j*inchan] = 0;
2046 coeff[i++ + j*inchan] = 0;
2048 RETVAL = i_convert(src, coeff, outchan, inchan);
2058 unsigned int mask = 0;
2064 unsigned char (*maps)[256];
2066 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2067 croak("i_map: parameter 2 must be an arrayref\n");
2068 avmain = (AV*)SvRV(ST(1));
2069 len = av_len(avmain)+1;
2070 if (im->channels < len) len = im->channels;
2072 maps = mymalloc( len * sizeof(unsigned char [256]) );
2074 for (j=0; j<len ; j++) {
2075 temp = av_fetch(avmain, j, 0);
2076 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2077 avsub = (AV*)SvRV(*temp);
2078 if(av_len(avsub) != 255) continue;
2080 for (i=0; i<256 ; i++) {
2082 temp = av_fetch(avsub, i, 0);
2083 val = temp ? SvIV(*temp) : 0;
2085 if (val>255) val = 255;
2090 i_map(im, maps, mask);
2101 i_img_diffd(im1,im2)
2106 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2116 _is_color_object(sv)
2120 RETVAL = SvOK(sv) && SvROK(sv) &&
2121 (sv_derived_from(sv, "Imager::Color")
2122 || sv_derived_from(sv, "Imager::Color::Float"));
2134 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2136 #define TT_DESTROY(handle) i_tt_destroy(handle)
2140 Imager::Font::TT handle
2145 (void)items; /* avoid unused warning */
2151 MODULE = Imager PACKAGE = Imager
2155 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2156 Imager::Font::TT handle
2174 str = SvPV(str_sv, len);
2175 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2176 len, smooth, utf8, align);
2182 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2183 Imager::Font::TT handle
2201 str = SvPV(str_sv, len);
2202 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2203 smooth, utf8, align);
2209 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2210 Imager::Font::TT handle
2215 i_img_dim cords[BOUNDING_BOX_COUNT];
2225 str = SvPV(str_sv, len);
2226 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2228 for (i = 0; i < rc; ++i) {
2229 PUSHs(sv_2mortal(newSViv(cords[i])));
2234 i_tt_has_chars(handle, text_sv, utf8)
2235 Imager::Font::TT handle
2246 if (SvUTF8(text_sv))
2249 text = SvPV(text_sv, len);
2250 work = mymalloc(len);
2251 count = i_tt_has_chars(handle, text, len, utf8, work);
2252 if (GIMME_V == G_ARRAY) {
2254 for (i = 0; i < count; ++i) {
2255 PUSHs(sv_2mortal(newSViv(work[i])));
2260 PUSHs(sv_2mortal(newSVpv(work, count)));
2265 i_tt_dump_names(handle)
2266 Imager::Font::TT handle
2269 i_tt_face_name(handle)
2270 Imager::Font::TT handle
2275 len = i_tt_face_name(handle, name, sizeof(name));
2278 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2282 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2283 Imager::Font::TT handle
2294 if (SvUTF8(text_sv))
2297 text = SvPV(text_sv, work_len);
2302 ch = i_utf8_advance(&text, &len);
2304 i_push_error(0, "invalid UTF8 character");
2313 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2314 PUSHs(sv_2mortal(newSVpv(name, 0)));
2317 PUSHs(&PL_sv_undef);
2324 i_test_format_probe(ig, length)
2329 i_readpnm_wiol(ig, allow_incomplete)
2331 int allow_incomplete
2335 i_readpnm_multi_wiol(ig, allow_incomplete)
2337 int allow_incomplete
2343 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2346 for (i = 0; i < count; ++i) {
2347 SV *sv = sv_newmortal();
2348 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2355 i_writeppm_wiol(im, ig)
2364 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2373 i_writeraw_wiol(im,ig)
2378 i_writebmp_wiol(im,ig)
2383 i_readbmp_wiol(ig, allow_incomplete=0)
2385 int allow_incomplete
2389 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2398 idlen = SvCUR(ST(4));
2399 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2405 i_readtga_wiol(ig, length)
2413 i_scaleaxis(im,Value,Axis)
2419 i_scale_nn(im,scx,scy)
2425 i_scale_mixing(im, width, height)
2435 i_count_colors(im,maxc)
2440 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2445 unsigned int * col_usage = NULL;
2448 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2449 EXTEND(SP, col_cnt);
2450 for (i = 0; i < col_cnt; i++) {
2451 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2458 i_transform(im,opx,opy,parm)
2471 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2472 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2473 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2474 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2475 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2476 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2477 av=(AV*)SvRV(ST(1));
2479 opx=mymalloc( opxl*sizeof(int) );
2480 for(i=0;i<opxl;i++) {
2481 sv1=(*(av_fetch(av,i,0)));
2482 opx[i]=(int)SvIV(sv1);
2484 av=(AV*)SvRV(ST(2));
2486 opy=mymalloc( opyl*sizeof(int) );
2487 for(i=0;i<opyl;i++) {
2488 sv1=(*(av_fetch(av,i,0)));
2489 opy[i]=(int)SvIV(sv1);
2491 av=(AV*)SvRV(ST(3));
2492 parmlen=av_len(av)+1;
2493 parm=mymalloc( parmlen*sizeof(double) );
2494 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2495 sv1=(*(av_fetch(av,i,0)));
2496 parm[i]=(double)SvNV(sv1);
2498 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2502 ST(0) = sv_newmortal();
2503 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2504 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2507 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2532 in_imgs_count = av_len(av_in_imgs)+1;
2533 for (i = 0; i < in_imgs_count; ++i) {
2534 sv1 = *av_fetch(av_in_imgs, i, 0);
2535 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2536 croak("sv_in_img must contain only images");
2539 if (in_imgs_count > 0) {
2540 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2541 for (i = 0; i < in_imgs_count; ++i) {
2542 sv1 = *av_fetch(av_in_imgs,i,0);
2543 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2544 croak("Parameter 5 must contain only images");
2546 tmp = SvIV((SV*)SvRV(sv1));
2547 in_imgs[i] = INT2PTR(i_img*, tmp);
2551 /* no input images */
2554 /* default the output size from the first input if possible */
2556 width = SvIV(sv_width);
2557 else if (in_imgs_count)
2558 width = in_imgs[0]->xsize;
2560 croak("No output image width supplied");
2562 if (SvOK(sv_height))
2563 height = SvIV(sv_height);
2564 else if (in_imgs_count)
2565 height = in_imgs[0]->ysize;
2567 croak("No output image height supplied");
2569 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2570 if (ops_len % sizeof(struct rm_op))
2571 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2572 ops_count = ops_len / sizeof(struct rm_op);
2574 n_regs_count = av_len(av_n_regs)+1;
2575 n_regs = mymalloc(n_regs_count * sizeof(double));
2576 for (i = 0; i < n_regs_count; ++i) {
2577 sv1 = *av_fetch(av_n_regs,i,0);
2579 n_regs[i] = SvNV(sv1);
2581 c_regs_count = av_len(av_c_regs)+1;
2582 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2583 /* I don't bother initializing the colou?r registers */
2585 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2586 n_regs, n_regs_count,
2587 c_regs, c_regs_count, in_imgs, in_imgs_count);
2592 ST(0) = sv_newmortal();
2593 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2594 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2598 i_contrast(im,intensity)
2611 i_noise(im,amount,type)
2617 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2627 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2646 i_postlevels(im,levels)
2656 i_watermark(im,wmark,tx,ty,pixdiff)
2658 Imager::ImgRaw wmark
2665 i_autolevels(im,lsat,usat,skew)
2672 i_radnoise(im,xo,yo,rscale,ascale)
2680 i_turbnoise(im, xo, yo, scale)
2703 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2704 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2705 croak("i_gradgen: Second argument must be an array ref");
2706 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2707 croak("i_gradgen: Third argument must be an array ref");
2708 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2709 croak("i_gradgen: Fourth argument must be an array ref");
2710 axx = (AV *)SvRV(ST(1));
2711 ayy = (AV *)SvRV(ST(2));
2712 ac = (AV *)SvRV(ST(3));
2713 dmeasure = (int)SvIV(ST(4));
2715 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2716 num = num <= av_len(ac) ? num : av_len(ac);
2718 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2719 xo = mymalloc( sizeof(i_img_dim) * num );
2720 yo = mymalloc( sizeof(i_img_dim) * num );
2721 ival = mymalloc( sizeof(i_color) * num );
2722 for(i = 0; i<num; i++) {
2723 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2724 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2725 sv = *av_fetch(ac, i, 0);
2726 if ( !sv_derived_from(sv, "Imager::Color") ) {
2727 free(axx); free(ayy); free(ac);
2728 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2730 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2732 i_gradgen(im, num, xo, yo, ival, dmeasure);
2738 i_diff_image(im, im2, mindist=0)
2744 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2754 double ssample_param
2758 i_fountain_seg *segs;
2760 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2761 croak("i_fountain: argument 11 must be an array ref");
2763 asegs = (AV *)SvRV(ST(10));
2764 segs = load_fount_segs(aTHX_ asegs, &count);
2765 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2766 super_sample, ssample_param, count, segs);
2772 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2781 double ssample_param
2785 i_fountain_seg *segs;
2787 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2788 croak("i_fountain: argument 11 must be an array ref");
2790 asegs = (AV *)SvRV(ST(9));
2791 segs = load_fount_segs(aTHX_ asegs, &count);
2792 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2793 super_sample, ssample_param, count, segs);
2799 i_new_fill_opacity(other_fill, alpha_mult)
2800 Imager::FillHandle other_fill
2811 errors = i_errors();
2813 while (errors[i].msg) {
2815 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2816 if (!av_store(av, 0, sv)) {
2819 sv = newSViv(errors[i].code);
2820 if (!av_store(av, 1, sv)) {
2823 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2831 i_push_error(code, msg)
2836 i_nearest_color(im, ...)
2851 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2852 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2853 croak("i_nearest_color: Second argument must be an array ref");
2854 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2855 croak("i_nearest_color: Third argument must be an array ref");
2856 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2857 croak("i_nearest_color: Fourth argument must be an array ref");
2858 axx = (AV *)SvRV(ST(1));
2859 ayy = (AV *)SvRV(ST(2));
2860 ac = (AV *)SvRV(ST(3));
2861 dmeasure = (int)SvIV(ST(4));
2863 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2864 num = num <= av_len(ac) ? num : av_len(ac);
2866 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2867 xo = mymalloc( sizeof(i_img_dim) * num );
2868 yo = mymalloc( sizeof(i_img_dim) * num );
2869 ival = mymalloc( sizeof(i_color) * num );
2870 for(i = 0; i<num; i++) {
2871 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2872 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2873 sv = *av_fetch(ac, i, 0);
2874 if ( !sv_derived_from(sv, "Imager::Color") ) {
2875 free(axx); free(ayy); free(ac);
2876 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2878 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2880 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2894 rc=DSO_open(filename,&evstr);
2898 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2899 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2902 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2908 DSO_close(dso_handle)
2912 DSO_funclist(dso_handle_v)
2916 DSO_handle *dso_handle;
2917 func_ptr *functions;
2919 dso_handle=(DSO_handle*)dso_handle_v;
2920 functions = DSO_funclist(dso_handle);
2922 while( functions[i].name != NULL) {
2924 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2926 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2930 DSO_call(handle,func_index,hv)
2936 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2937 hv=(HV*)SvRV(ST(2));
2938 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2939 DSO_call( (DSO_handle *)handle,func_index,hv);
2942 i_get_pixel(im, x, y)
2949 color = (i_color *)mymalloc(sizeof(i_color));
2950 if (i_gpix(im, x, y, color) == 0) {
2951 RETVAL = NEWSV(0, 0);
2952 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2956 RETVAL = &PL_sv_undef;
2963 i_ppix(im, x, y, cl)
2970 i_img_pal_new(x, y, channels, maxpal)
2977 i_img_to_pal(src, quant)
2983 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2984 croak("i_img_to_pal: second argument must be a hash ref");
2985 hv = (HV *)SvRV(ST(1));
2986 memset(&quant, 0, sizeof(quant));
2988 quant.mc_size = 256;
2989 ip_handle_quant_opts(aTHX_ &quant, hv);
2990 RETVAL = i_img_to_pal(src, &quant);
2992 ip_copy_colors_back(aTHX_ hv, &quant);
2994 ip_cleanup_quant_opts(aTHX_ &quant);
3013 work = mymalloc((r-l) * sizeof(i_palidx));
3014 count = i_gpal(im, l, r, y, work);
3015 if (GIMME_V == G_ARRAY) {
3017 for (i = 0; i < count; ++i) {
3018 PUSHs(sv_2mortal(newSViv(work[i])));
3023 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3028 if (GIMME_V != G_ARRAY) {
3030 PUSHs(&PL_sv_undef);
3035 i_ppal(im, l, y, ...)
3044 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3045 for (i=0; i < items-3; ++i) {
3046 work[i] = SvIV(ST(i+3));
3048 validate_i_ppal(im, work, items - 3);
3049 RETVAL = i_ppal(im, l, l+items-3, y, work);
3058 i_ppal_p(im, l, y, data)
3064 i_palidx const *work;
3067 work = (i_palidx const *)SvPV(data, len);
3068 len /= sizeof(i_palidx);
3070 validate_i_ppal(im, work, len);
3071 RETVAL = i_ppal(im, l, l+len, y, work);
3080 i_addcolors(im, ...)
3088 croak("i_addcolors: no colors to add");
3089 colors = mymalloc((items-1) * sizeof(i_color));
3090 for (i=0; i < items-1; ++i) {
3091 if (sv_isobject(ST(i+1))
3092 && sv_derived_from(ST(i+1), "Imager::Color")) {
3093 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3094 colors[i] = *INT2PTR(i_color *, tmp);
3098 croak("i_addcolor: pixels must be Imager::Color objects");
3101 index = i_addcolors(im, colors, items-1);
3104 RETVAL = newSVpv("0 but true", 0);
3106 else if (index == -1) {
3107 RETVAL = &PL_sv_undef;
3110 RETVAL = newSViv(index);
3116 i_setcolors(im, index, ...)
3124 croak("i_setcolors: no colors to add");
3125 colors = mymalloc((items-2) * sizeof(i_color));
3126 for (i=0; i < items-2; ++i) {
3127 if (sv_isobject(ST(i+2))
3128 && sv_derived_from(ST(i+2), "Imager::Color")) {
3129 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3130 colors[i] = *INT2PTR(i_color *, tmp);
3134 croak("i_setcolors: pixels must be Imager::Color objects");
3137 RETVAL = i_setcolors(im, index, colors, items-2);
3143 i_getcolors(im, index, ...)
3152 croak("i_getcolors: too many arguments");
3154 count = SvIV(ST(2));
3156 croak("i_getcolors: count must be positive");
3157 colors = mymalloc(sizeof(i_color) * count);
3158 if (i_getcolors(im, index, colors, count)) {
3159 for (i = 0; i < count; ++i) {
3161 SV *sv = sv_newmortal();
3162 pv = mymalloc(sizeof(i_color));
3164 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3180 i_findcolor(im, color)
3186 if (i_findcolor(im, color, &index)) {
3187 RETVAL = newSViv(index);
3190 RETVAL = &PL_sv_undef;
3208 i_gsamp(im, l, r, y, ...)
3220 croak("No channel numbers supplied to g_samp()");
3222 chan_count = items - 4;
3223 chans = mymalloc(sizeof(int) * chan_count);
3224 for (i = 0; i < chan_count; ++i)
3225 chans[i] = SvIV(ST(i+4));
3226 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3227 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3229 if (GIMME_V == G_ARRAY) {
3231 for (i = 0; i < count; ++i)
3232 PUSHs(sv_2mortal(newSViv(data[i])));
3236 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3241 if (GIMME_V != G_ARRAY) {
3243 PUSHs(&PL_sv_undef);
3248 i_gsamp_bits(im, l, r, y, bits, target, offset, ...)
3264 croak("No channel numbers supplied to g_samp()");
3266 chan_count = items - 7;
3267 chans = mymalloc(sizeof(int) * chan_count);
3268 for (i = 0; i < chan_count; ++i)
3269 chans[i] = SvIV(ST(i+7));
3270 data = mymalloc(sizeof(unsigned) * (r-l) * chan_count);
3271 count = i_gsamp_bits(im, l, r, y, data, chans, chan_count, bits);
3273 for (i = 0; i < count; ++i) {
3274 av_store(target, i+offset, newSVuv(data[i]));
3286 i_psamp_bits(im, l, y, bits, channels_sv, data_av, data_offset = 0, pixel_count = -1)
3304 if (SvOK(channels_sv)) {
3306 if (!SvROK(channels_sv) || SvTYPE(SvRV(channels_sv)) != SVt_PVAV) {
3307 croak("channels is not an array ref");
3309 channels_av = (AV *)SvRV(channels_sv);
3310 chan_count = av_len(channels_av) + 1;
3311 if (chan_count < 1) {
3312 croak("i_psamp_bits: no channels provided");
3314 channels = mymalloc(sizeof(int) * chan_count);
3315 for (i = 0; i < chan_count; ++i)
3316 channels[i] = SvIV(*av_fetch(channels_av, i, 0));
3319 chan_count = im->channels;
3323 data_count = av_len(data_av) + 1;
3324 if (data_offset < 0) {
3325 croak("data_offset must by non-negative");
3327 if (data_offset > data_count) {
3328 croak("data_offset greater than number of samples supplied");
3330 if (pixel_count == -1 ||
3331 data_offset + pixel_count * chan_count > data_count) {
3332 pixel_count = (data_count - data_offset) / chan_count;
3335 data_used = pixel_count * chan_count;
3336 data = mymalloc(sizeof(unsigned) * data_count);
3337 for (i = 0; i < data_used; ++i)
3338 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3340 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels,
3351 i_img_masked_new(targ, mask, x, y, w, h)
3361 if (!sv_isobject(ST(1))
3362 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3363 croak("i_img_masked_new: parameter 2 must undef or an image");
3365 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3369 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3374 i_plin(im, l, y, ...)
3385 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3386 /* supplied as a byte string */
3387 work = (i_color *)SvPV(ST(3), len);
3388 count = len / sizeof(i_color);
3389 if (count * sizeof(i_color) != len) {
3390 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3392 RETVAL = i_plin(im, l, l+count, y, work);
3395 work = mymalloc(sizeof(i_color) * (items-3));
3396 for (i=0; i < items-3; ++i) {
3397 if (sv_isobject(ST(i+3))
3398 && sv_derived_from(ST(i+3), "Imager::Color")) {
3399 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3400 work[i] = *INT2PTR(i_color *, tmp);
3404 croak("i_plin: pixels must be Imager::Color objects");
3407 RETVAL = i_plin(im, l, l+items-3, y, work);
3418 i_ppixf(im, x, y, cl)
3422 Imager::Color::Float cl
3425 i_gsampf(im, l, r, y, ...)
3437 croak("No channel numbers supplied to g_sampf()");
3439 chan_count = items - 4;
3440 chans = mymalloc(sizeof(int) * chan_count);
3441 for (i = 0; i < chan_count; ++i)
3442 chans[i] = SvIV(ST(i+4));
3443 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3444 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3446 if (GIMME_V == G_ARRAY) {
3448 for (i = 0; i < count; ++i)
3449 PUSHs(sv_2mortal(newSVnv(data[i])));
3453 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3458 if (GIMME_V != G_ARRAY) {
3460 PUSHs(&PL_sv_undef);
3465 i_plinf(im, l, y, ...)
3476 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3477 /* supplied as a byte string */
3478 work = (i_fcolor *)SvPV(ST(3), len);
3479 count = len / sizeof(i_fcolor);
3480 if (count * sizeof(i_fcolor) != len) {
3481 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3483 RETVAL = i_plinf(im, l, l+count, y, work);
3486 work = mymalloc(sizeof(i_fcolor) * (items-3));
3487 for (i=0; i < items-3; ++i) {
3488 if (sv_isobject(ST(i+3))
3489 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3490 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3491 work[i] = *INT2PTR(i_fcolor *, tmp);
3495 croak("i_plinf: pixels must be Imager::Color::Float objects");
3499 RETVAL = i_plinf(im, l, l+items-3, y, work);
3517 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3518 if (i_gpixf(im, x, y, color) == 0) {
3519 RETVAL = NEWSV(0,0);
3520 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3524 RETVAL = &PL_sv_undef;
3540 vals = mymalloc((r-l) * sizeof(i_color));
3541 memset(vals, 0, (r-l) * sizeof(i_color));
3542 count = i_glin(im, l, r, y, vals);
3543 if (GIMME_V == G_ARRAY) {
3545 for (i = 0; i < count; ++i) {
3547 i_color *col = mymalloc(sizeof(i_color));
3549 sv = sv_newmortal();
3550 sv_setref_pv(sv, "Imager::Color", (void *)col);
3556 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3562 i_glinf(im, l, r, y)
3572 for (i = 0; i < MAXCHANNELS; ++i)
3573 zero.channel[i] = 0;
3575 vals = mymalloc((r-l) * sizeof(i_fcolor));
3576 for (i = 0; i < r-l; ++i)
3578 count = i_glinf(im, l, r, y, vals);
3579 if (GIMME_V == G_ARRAY) {
3581 for (i = 0; i < count; ++i) {
3583 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3585 sv = sv_newmortal();
3586 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3592 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3598 i_img_16_new(x, y, ch)
3608 i_img_double_new(x, y, ch)
3618 i_tags_addn(im, name, code, idata)
3627 name = SvPV(ST(1), len);
3630 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3635 i_tags_add(im, name, code, data, idata)
3645 name = SvPV(ST(1), len);
3649 data = SvPV(ST(3), len);
3654 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3659 i_tags_find(im, name, start)
3666 if (i_tags_find(&im->tags, name, start, &entry)) {
3668 RETVAL = newSVpv("0 but true", 0);
3670 RETVAL = newSViv(entry);
3672 RETVAL = &PL_sv_undef;
3678 i_tags_findn(im, code, start)
3685 if (i_tags_findn(&im->tags, code, start, &entry)) {
3687 RETVAL = newSVpv("0 but true", 0);
3689 RETVAL = newSViv(entry);
3692 RETVAL = &PL_sv_undef;
3698 i_tags_delete(im, entry)
3702 RETVAL = i_tags_delete(&im->tags, entry);
3707 i_tags_delbyname(im, name)
3711 RETVAL = i_tags_delbyname(&im->tags, name);
3716 i_tags_delbycode(im, code)
3720 RETVAL = i_tags_delbycode(&im->tags, code);
3725 i_tags_get(im, index)
3729 if (index >= 0 && index < im->tags.count) {
3730 i_img_tag *entry = im->tags.tags + index;
3734 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3737 PUSHs(sv_2mortal(newSViv(entry->code)));
3740 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3743 PUSHs(sv_2mortal(newSViv(entry->idata)));
3748 i_tags_get_string(im, what_sv)
3752 char const *name = NULL;
3756 if (SvIOK(what_sv)) {
3757 code = SvIV(what_sv);
3761 name = SvPV_nolen(what_sv);
3764 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3766 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3773 RETVAL = im->tags.count;
3779 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3783 Imager::FillHandle fill
3786 IFILL_CLONE_SKIP(...)
3788 (void)items; /* avoid unused warning for XS variable */
3793 MODULE = Imager PACKAGE = Imager
3796 i_new_fill_solid(cl, combine)
3801 i_new_fill_solidf(cl, combine)
3802 Imager::Color::Float cl
3806 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3814 unsigned char *cust_hatch;
3818 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3822 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3827 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3828 Imager::Color::Float fg
3829 Imager::Color::Float bg
3835 unsigned char *cust_hatch;
3839 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3843 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3848 i_new_fill_image(src, matrix, xoff, yoff, combine)
3865 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3866 croak("i_new_fill_image: parameter must be an arrayref");
3867 av=(AV*)SvRV(ST(1));
3871 for (i = 0; i < len; ++i) {
3872 sv1=(*(av_fetch(av,i,0)));
3873 matrix[i] = SvNV(sv1);
3879 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3883 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3885 # this class is only exposed for testing
3888 i_int_hlines_testing()
3890 #if i_int_hlines_testing()
3892 Imager::Internal::Hlines
3893 i_int_hlines_new(start_y, count_y, start_x, count_x)
3899 Imager::Internal::Hlines
3900 i_int_hlines_new_img(im)
3904 i_int_hlines_add(hlines, y, minx, width)
3905 Imager::Internal::Hlines hlines
3911 i_int_hlines_DESTROY(hlines)
3912 Imager::Internal::Hlines hlines
3915 i_int_hlines_dump(hlines)
3916 Imager::Internal::Hlines hlines
3919 i_int_hlines_CLONE_SKIP(cls)
3924 PERL_SET_GLOBAL_CALLBACKS;
3925 PERL_PL_SET_GLOBAL_CALLBACKS;