1 #define PERL_NO_GET_CONTEXT
8 #define NEED_newRV_noinc
9 #define NEED_sv_2pv_nolen
10 #define NEED_sv_2pvbyte
16 #define i_int_hlines_testing() 1
23 #include "imextpltypes.h"
27 #if i_int_hlines_testing()
35 Context object management
39 typedef im_context_t Imager__Context;
41 #define im_context_DESTROY(ctx) im_context_refdec((ctx), "DESTROY")
43 #ifdef PERL_IMPLICIT_CONTEXT
45 #define MY_CXT_KEY "Imager::_context" XS_VERSION
53 im_context_t fallback_context;
58 MY_CXT.ctx = im_context_new();
59 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
61 /* Ideally we'd free this reference, but the error message memory
62 was never released on exit, so the associated memory here is reasonable
64 With logging enabled we always need at least one context, since
65 objects may be released fairly late and attempt to get the log file.
67 im_context_refinc(MY_CXT.ctx, "start_context");
68 fallback_context = MY_CXT.ctx;
72 perl_get_context(void) {
76 return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
81 static im_context_t perl_context;
85 perl_context = im_context_new();
86 im_context_refinc(perl_context, "start_context");
90 perl_get_context(void) {
96 /* used to represent channel lists parameters */
97 typedef struct i_channel_list_tag {
104 const i_sample_t *samples;
109 const i_fsample_t *samples;
114 Allocate memory that will be discarded when mortals are discarded.
119 malloc_temp(pTHX_ size_t size) {
120 SV *sv = sv_2mortal(newSV(size));
125 /* These functions are all shared - then comes platform dependant code */
126 static int getstr(void *hv_t,char *key,char **store) {
131 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
133 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
135 svpp=hv_fetch(hv, key, strlen(key), 0);
136 *store=SvPV(*svpp, PL_na );
141 static int getint(void *hv_t,char *key,int *store) {
146 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
148 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
150 svpp=hv_fetch(hv, key, strlen(key), 0);
151 *store=(int)SvIV(*svpp);
155 static int getdouble(void *hv_t,char* key,double *store) {
160 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
162 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
163 svpp=hv_fetch(hv, key, strlen(key), 0);
164 *store=(double)SvNV(*svpp);
168 static int getvoid(void *hv_t,char* key,void **store) {
173 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
175 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
177 svpp=hv_fetch(hv, key, strlen(key), 0);
178 *store = INT2PTR(void*, SvIV(*svpp));
183 static int getobj(void *hv_t,char *key,char *type,void **store) {
188 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
190 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
192 svpp=hv_fetch(hv, key, strlen(key), 0);
194 if (sv_derived_from(*svpp,type)) {
195 IV tmp = SvIV((SV*)SvRV(*svpp));
196 *store = INT2PTR(void*, tmp);
198 mm_log((1,"getobj: key exists in hash but is not of correct type"));
205 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
207 void my_SvREFCNT_dec(void *p) {
209 SvREFCNT_dec((SV*)p);
214 i_log_entry(char *string, int level) {
215 mm_log((level, "%s", string));
219 make_i_color_sv(pTHX_ const i_color *c) {
221 i_color *col = mymalloc(sizeof(i_color));
224 sv_setref_pv(sv, "Imager::Color", (void *)col);
229 #define CBDATA_BUFSIZE 8192
232 /* the SVs we use to call back to Perl */
240 call_reader(struct cbdata *cbd, void *buf, size_t size,
248 if (!SvOK(cbd->readcb)) {
249 mm_log((1, "read callback called but no readcb supplied\n"));
250 i_push_error(0, "read callback called but no readcb supplied");
258 PUSHs(sv_2mortal(newSViv(size)));
259 PUSHs(sv_2mortal(newSViv(maxread)));
262 count = perl_call_sv(cbd->readcb, G_SCALAR);
267 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
273 char *ptr = SvPVbyte(data, len);
275 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
276 (int)size, (int)len, (int)maxread);
278 memcpy(buf, ptr, len);
293 io_seeker(void *p, off_t offset, int whence) {
295 struct cbdata *cbd = p;
300 if (!SvOK(cbd->seekcb)) {
301 mm_log((1, "seek callback called but no seekcb supplied\n"));
302 i_push_error(0, "seek callback called but no seekcb supplied");
310 PUSHs(sv_2mortal(newSViv(offset)));
311 PUSHs(sv_2mortal(newSViv(whence)));
314 count = perl_call_sv(cbd->seekcb, G_SCALAR);
319 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
331 io_writer(void *p, void const *data, size_t size) {
333 struct cbdata *cbd = p;
339 if (!SvOK(cbd->writecb)) {
340 mm_log((1, "write callback called but no writecb supplied\n"));
341 i_push_error(0, "write callback called but no writecb supplied");
349 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
352 count = perl_call_sv(cbd->writecb, G_SCALAR);
356 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
359 success = SvTRUE(sv);
366 return success ? size : -1;
370 io_reader(void *p, void *data, size_t size) {
371 struct cbdata *cbd = p;
373 return call_reader(cbd, data, size, size);
376 static int io_closer(void *p) {
378 struct cbdata *cbd = p;
381 if (SvOK(cbd->closecb)) {
391 count = perl_call_sv(cbd->closecb, G_SCALAR);
396 success = SvTRUE(sv);
403 return success ? 0 : -1;
406 static void io_destroyer(void *p) {
408 struct cbdata *cbd = p;
410 SvREFCNT_dec(cbd->writecb);
411 SvREFCNT_dec(cbd->readcb);
412 SvREFCNT_dec(cbd->seekcb);
413 SvREFCNT_dec(cbd->closecb);
418 do_io_new_buffer(pTHX_ SV *data_sv) {
422 data = SvPVbyte(data_sv, length);
423 SvREFCNT_inc(data_sv);
424 return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
428 describe_sv(SV *sv) {
431 svtype type = SvTYPE(SvRV(sv));
433 case SVt_PVCV: return "CV";
434 case SVt_PVGV: return "GV";
435 case SVt_PVLV: return "LV";
436 default: return "some reference";
440 return "non-reference scalar";
449 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
452 cbd = mymalloc(sizeof(struct cbdata));
453 cbd->writecb = newSVsv(writecb);
454 cbd->readcb = newSVsv(readcb);
455 cbd->seekcb = newSVsv(seekcb);
456 cbd->closecb = newSVsv(closecb);
458 mm_log((1, "do_io_new_cb(writecb %p (%s), readcb %p (%s), seekcb %p (%s), closecb %p (%s))\n", writecb, describe_sv(writecb), readcb, describe_sv(readcb), seekcb, describe_sv(seekcb), closecb, describe_sv(closecb)));
460 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
468 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
471 for (i = 0; i < count; ++i)
472 if (strEQ(names[i].name, name))
473 return names[i].value;
477 static struct value_name transp_names[] =
480 { "threshold", tr_threshold },
481 { "errdiff", tr_errdiff },
482 { "ordered", tr_ordered, },
485 static struct value_name make_color_names[] =
487 { "none", mc_none, },
488 { "webmap", mc_web_map, },
489 { "addi", mc_addi, },
490 { "mediancut", mc_median_cut, },
491 { "mono", mc_mono, },
492 { "monochrome", mc_mono, },
493 { "gray", mc_gray, },
494 { "gray4", mc_gray4, },
495 { "gray16", mc_gray16, },
498 static struct value_name translate_names[] =
500 { "giflib", pt_giflib, },
501 { "closest", pt_closest, },
502 { "perturb", pt_perturb, },
503 { "errdiff", pt_errdiff, },
506 static struct value_name errdiff_names[] =
508 { "floyd", ed_floyd, },
509 { "jarvis", ed_jarvis, },
510 { "stucki", ed_stucki, },
511 { "custom", ed_custom, },
514 static struct value_name orddith_names[] =
516 { "random", od_random, },
517 { "dot8", od_dot8, },
518 { "dot4", od_dot4, },
519 { "hline", od_hline, },
520 { "vline", od_vline, },
521 { "/line", od_slashline, },
522 { "slashline", od_slashline, },
523 { "\\line", od_backline, },
524 { "backline", od_backline, },
525 { "tiny", od_tiny, },
526 { "custom", od_custom, },
529 /* look through the hash for quantization options */
531 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
533 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
539 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
541 sv = hv_fetch(hv, "transp", 6, 0);
542 if (sv && *sv && (str = SvPV(*sv, len))) {
544 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
546 if (quant->transp != tr_none) {
547 quant->tr_threshold = 127;
548 sv = hv_fetch(hv, "tr_threshold", 12, 0);
550 quant->tr_threshold = SvIV(*sv);
552 if (quant->transp == tr_errdiff) {
553 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
554 if (sv && *sv && (str = SvPV(*sv, len)))
555 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
557 if (quant->transp == tr_ordered) {
558 quant->tr_orddith = od_tiny;
559 sv = hv_fetch(hv, "tr_orddith", 10, 0);
560 if (sv && *sv && (str = SvPV(*sv, len)))
561 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
563 if (quant->tr_orddith == od_custom) {
564 sv = hv_fetch(hv, "tr_map", 6, 0);
565 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
566 AV *av = (AV*)SvRV(*sv);
567 len = av_len(av) + 1;
568 if (len > sizeof(quant->tr_custom))
569 len = sizeof(quant->tr_custom);
570 for (i = 0; i < len; ++i) {
571 SV **sv2 = av_fetch(av, i, 0);
573 quant->tr_custom[i] = SvIV(*sv2);
576 while (i < sizeof(quant->tr_custom))
577 quant->tr_custom[i++] = 0;
582 quant->make_colors = mc_median_cut;
583 sv = hv_fetch(hv, "make_colors", 11, 0);
584 if (sv && *sv && (str = SvPV(*sv, len))) {
586 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
588 sv = hv_fetch(hv, "colors", 6, 0);
589 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
590 /* needs to be an array of Imager::Color
591 note that the caller allocates the mc_color array and sets mc_size
593 AV *av = (AV *)SvRV(*sv);
594 quant->mc_count = av_len(av)+1;
595 if (quant->mc_count > quant->mc_size)
596 quant->mc_count = quant->mc_size;
597 for (i = 0; i < quant->mc_count; ++i) {
598 SV **sv1 = av_fetch(av, i, 0);
599 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
600 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
601 quant->mc_colors[i] = *col;
605 sv = hv_fetch(hv, "max_colors", 10, 0);
608 if (i <= quant->mc_size && i >= quant->mc_count)
612 quant->translate = pt_closest;
613 sv = hv_fetch(hv, "translate", 9, 0);
614 if (sv && *sv && (str = SvPV(*sv, len))) {
615 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
617 sv = hv_fetch(hv, "errdiff", 7, 0);
618 if (sv && *sv && (str = SvPV(*sv, len))) {
619 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
621 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
622 /* get the error diffusion map */
623 sv = hv_fetch(hv, "errdiff_width", 13, 0);
625 quant->ed_width = SvIV(*sv);
626 sv = hv_fetch(hv, "errdiff_height", 14, 0);
628 quant->ed_height = SvIV(*sv);
629 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
631 quant->ed_orig = SvIV(*sv);
632 if (quant->ed_width > 0 && quant->ed_height > 0) {
634 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
635 sv = hv_fetch(hv, "errdiff_map", 11, 0);
636 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
637 AV *av = (AV*)SvRV(*sv);
638 len = av_len(av) + 1;
639 if (len > quant->ed_width * quant->ed_height)
640 len = quant->ed_width * quant->ed_height;
641 for (i = 0; i < len; ++i) {
642 SV **sv2 = av_fetch(av, i, 0);
644 quant->ed_map[i] = SvIV(*sv2);
645 sum += quant->ed_map[i];
651 myfree(quant->ed_map);
653 quant->errdiff = ed_floyd;
657 sv = hv_fetch(hv, "perturb", 7, 0);
659 quant->perturb = SvIV(*sv);
663 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
664 myfree(quant->mc_colors);
666 myfree(quant->ed_map);
669 /* copies the color map from the hv into the colors member of the HV */
671 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
677 sv = hv_fetch(hv, "colors", 6, 0);
678 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
683 av = (AV *)SvRV(*sv);
685 av_extend(av, quant->mc_count+1);
686 for (i = 0; i < quant->mc_count; ++i) {
687 i_color *in = quant->mc_colors+i;
688 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
689 work = sv_newmortal();
690 sv_setref_pv(work, "Imager::Color", (void *)c);
696 /* loads the segments of a fountain fill into an array */
697 static i_fountain_seg *
698 load_fount_segs(pTHX_ AV *asegs, int *count) {
699 /* Each element of segs must contain:
700 [ start, middle, end, c0, c1, segtype, colortrans ]
701 start, middle, end are doubles from 0 to 1
702 c0, c1 are Imager::Color::Float or Imager::Color objects
703 segtype, colortrans are ints
707 i_fountain_seg *segs;
711 *count = av_len(asegs)+1;
713 croak("i_fountain must have at least one segment");
714 segs = mymalloc(sizeof(i_fountain_seg) * *count);
715 for(i = 0; i < *count; i++) {
716 SV **sv1 = av_fetch(asegs, i, 0);
717 if (!sv1 || !*sv1 || !SvROK(*sv1)
718 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
720 croak("i_fountain: segs must be an arrayref of arrayrefs");
722 aseg = (AV *)SvRV(*sv1);
723 if (av_len(aseg) != 7-1) {
725 croak("i_fountain: a segment must have 7 members");
727 for (j = 0; j < 3; ++j) {
728 SV **sv2 = av_fetch(aseg, j, 0);
731 croak("i_fountain: XS error");
733 work[j] = SvNV(*sv2);
735 segs[i].start = work[0];
736 segs[i].middle = work[1];
737 segs[i].end = work[2];
738 for (j = 0; j < 2; ++j) {
739 SV **sv3 = av_fetch(aseg, 3+j, 0);
740 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
741 (!sv_derived_from(*sv3, "Imager::Color")
742 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
744 croak("i_fountain: segs must contain colors in elements 3 and 4");
746 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
747 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
750 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
752 for (ch = 0; ch < MAXCHANNELS; ++ch) {
753 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
757 for (j = 0; j < 2; ++j) {
758 SV **sv2 = av_fetch(aseg, j+5, 0);
761 croak("i_fountain: XS error");
763 worki[j] = SvIV(*sv2);
765 segs[i].type = worki[0];
766 segs[i].color = worki[1];
772 /* validates the indexes supplied to i_ppal
774 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
779 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
780 int color_count = i_colorcount(im);
783 if (color_count == -1)
784 croak("i_plin() called on direct color image");
786 for (i = 0; i < count; ++i) {
787 if (indexes[i] >= color_count) {
788 croak("i_plin() called with out of range color index %d (max %d)",
789 indexes[i], color_count-1);
794 /* I don't think ICLF_* names belong at the C interface
795 this makes the XS code think we have them, to let us avoid
796 putting function bodies in the XS code
798 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
799 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
802 #define i_log_enabled() 1
804 #define i_log_enabled() 0
807 #if i_int_hlines_testing()
809 typedef i_int_hlines *Imager__Internal__Hlines;
811 static i_int_hlines *
812 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
813 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
814 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
819 static i_int_hlines *
820 i_int_hlines_new_img(i_img *im) {
821 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
822 i_int_init_hlines_img(result, im);
828 i_int_hlines_DESTROY(i_int_hlines *hlines) {
829 i_int_hlines_destroy(hlines);
833 #define i_int_hlines_CLONE_SKIP(cls) 1
835 static int seg_compare(const void *vleft, const void *vright) {
836 const i_int_hline_seg *left = vleft;
837 const i_int_hline_seg *right = vright;
839 return left->minx - right->minx;
843 i_int_hlines_dump(i_int_hlines *hlines) {
845 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
846 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
849 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
850 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
853 /* sort the segments, if any */
855 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
857 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
858 for (i = 0; i < entry->count; ++i) {
859 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
860 i_DFc(entry->segs[i].x_limit));
862 sv_catpv(dump, "\n");
872 i_sv_off_t(pTHX_ SV *sv) {
873 #if LSEEKSIZE > IVSIZE
874 return (off_t)SvNV(sv);
876 return (off_t)SvIV(sv);
881 i_new_sv_off_t(pTHX_ off_t off) {
882 #if LSEEKSIZE > IVSIZE
889 static im_pl_ext_funcs im_perl_funcs =
891 IMAGER_PL_API_VERSION,
893 ip_handle_quant_opts,
894 ip_cleanup_quant_opts,
898 #define PERL_PL_SET_GLOBAL_CALLBACKS \
899 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
901 #define IIM_new i_img_8_new
902 #define IIM_DESTROY i_img_destroy
905 #define i_exif_enabled() 1
907 #define i_exif_enabled() 0
910 /* trying to use more C style names, map them here */
911 #define i_io_DESTROY(ig) io_glue_destroy(ig)
913 #define i_img_get_width(im) ((im)->xsize)
914 #define i_img_get_height(im) ((im)->ysize)
916 #define i_img_epsilonf() (DBL_EPSILON * 4)
918 /* avoid some xsubpp strangeness */
921 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
924 ICL_new_internal(r,g,b,a)
936 ICL_set_internal(cl,r,g,b,a)
943 ICL_set_internal(cl, r, g, b, a);
957 PUSHs(sv_2mortal(newSViv(cl->rgba.r)));
958 PUSHs(sv_2mortal(newSViv(cl->rgba.g)));
959 PUSHs(sv_2mortal(newSViv(cl->rgba.b)));
960 PUSHs(sv_2mortal(newSViv(cl->rgba.a)));
966 RETVAL = mymalloc(sizeof(i_color));
968 i_hsv_to_rgb(RETVAL);
976 RETVAL = mymalloc(sizeof(i_color));
978 i_rgb_to_hsv(RETVAL);
984 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
987 ICLF_new_internal(r, g, b, a)
995 Imager::Color::Float cl
999 Imager::Color::Float cl
1003 EXTEND(SP, MAXCHANNELS);
1004 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1005 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1006 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1010 ICLF_set_internal(cl,r,g,b,a)
1011 Imager::Color::Float cl
1024 Imager::Color::Float
1026 Imager::Color::Float c
1028 RETVAL = mymalloc(sizeof(i_fcolor));
1030 i_hsv_to_rgbf(RETVAL);
1034 Imager::Color::Float
1036 Imager::Color::Float c
1038 RETVAL = mymalloc(sizeof(i_fcolor));
1040 i_rgb_to_hsvf(RETVAL);
1044 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1058 MODULE = Imager PACKAGE = Imager
1072 io_new_buffer(data_sv)
1075 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1080 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1087 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1095 unsigned char* data;
1099 tlength = io_slurp(ig, &data);
1100 RETVAL = newSVpv((char *)data,tlength);
1107 i_set_image_file_limits(width, height, bytes)
1113 i_get_image_file_limits()
1115 i_img_dim width, height;
1118 if (i_get_image_file_limits(&width, &height, &bytes)) {
1120 PUSHs(sv_2mortal(newSViv(width)));
1121 PUSHs(sv_2mortal(newSViv(height)));
1122 PUSHs(sv_2mortal(newSVuv(bytes)));
1126 i_int_check_image_file_limits(width, height, channels, sample_size)
1133 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
1136 io_new_fd(class, fd)
1139 RETVAL = io_new_fd(fd);
1144 io_new_buffer(class, data_sv)
1147 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1152 io_new_cb(class, writecb, readcb, seekcb, closecb)
1158 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1163 io_new_bufchain(class)
1165 RETVAL = io_new_bufchain();
1170 io__new_perlio(class, io)
1173 RETVAL = im_io_new_perlio(aTHX_ io);
1181 unsigned char* data;
1185 tlength = io_slurp(ig, &data);
1186 RETVAL = newSVpv((char *)data,tlength);
1191 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1194 i_io_raw_write(ig, data_sv)
1201 data = SvPVbyte(data_sv, size);
1202 RETVAL = i_io_raw_write(ig, data, size);
1207 i_io_raw_read(ig, buffer_sv, size)
1216 croak("size negative in call to i_io_raw_read()");
1217 /* prevent an undefined value warning if they supplied an
1219 Orginally conditional on !SvOK(), but this will prevent the
1220 downgrade from croaking */
1221 sv_setpvn(buffer_sv, "", 0);
1223 if (SvUTF8(buffer_sv))
1224 sv_utf8_downgrade(buffer_sv, FALSE);
1226 buffer = SvGROW(buffer_sv, size+1);
1227 result = i_io_raw_read(ig, buffer, size);
1229 SvCUR_set(buffer_sv, result);
1230 *SvEND(buffer_sv) = '\0';
1231 SvPOK_only(buffer_sv);
1233 PUSHs(sv_2mortal(newSViv(result)));
1239 i_io_raw_read2(ig, size)
1248 croak("size negative in call to i_io_read2()");
1249 buffer_sv = newSV(size);
1250 buffer = SvGROW(buffer_sv, size+1);
1251 result = i_io_raw_read(ig, buffer, size);
1253 SvCUR_set(buffer_sv, result);
1254 *SvEND(buffer_sv) = '\0';
1255 SvPOK_only(buffer_sv);
1257 PUSHs(sv_2mortal(buffer_sv));
1261 SvREFCNT_dec(buffer_sv);
1265 i_io_raw_seek(ig, position, whence)
1279 i_io_CLONE_SKIP(...)
1281 (void)items; /* avoid unused warning for XS variable */
1308 i_io_seek(ig, off, whence)
1314 i_io_peekn(ig, size)
1322 buffer_sv = newSV(size+1);
1323 buffer = SvGROW(buffer_sv, size+1);
1324 result = i_io_peekn(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_read(ig, buffer_sv, size)
1347 croak("size negative in call to i_io_read()");
1348 /* prevent an undefined value warning if they supplied an
1350 Orginally conditional on !SvOK(), but this will prevent the
1351 downgrade from croaking */
1352 sv_setpvn(buffer_sv, "", 0);
1354 if (SvUTF8(buffer_sv))
1355 sv_utf8_downgrade(buffer_sv, FALSE);
1357 buffer = SvGROW(buffer_sv, size+1);
1358 result = i_io_read(ig, buffer, size);
1360 SvCUR_set(buffer_sv, result);
1361 *SvEND(buffer_sv) = '\0';
1362 SvPOK_only(buffer_sv);
1364 PUSHs(sv_2mortal(newSViv(result)));
1370 i_io_read2(ig, size)
1379 croak("size zero in call to read2()");
1380 buffer_sv = newSV(size);
1381 buffer = SvGROW(buffer_sv, size+1);
1382 result = i_io_read(ig, buffer, size);
1384 SvCUR_set(buffer_sv, result);
1385 *SvEND(buffer_sv) = '\0';
1386 SvPOK_only(buffer_sv);
1388 PUSHs(sv_2mortal(buffer_sv));
1392 SvREFCNT_dec(buffer_sv);
1396 i_io_gets(ig, size = 8192, eol = NEWLINE)
1406 croak("size too small in call to gets()");
1407 buffer_sv = sv_2mortal(newSV(size+1));
1408 buffer = SvPVX(buffer_sv);
1409 result = i_io_gets(ig, buffer, size+1, eol);
1411 SvCUR_set(buffer_sv, result);
1412 *SvEND(buffer_sv) = '\0';
1413 SvPOK_only(buffer_sv);
1419 i_io_write(ig, data_sv)
1426 data = SvPVbyte(data_sv, size);
1427 RETVAL = i_io_write(ig, data, size);
1432 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1437 i_io_set_buffered(ig, flag = 1)
1442 i_io_is_buffered(ig)
1453 MODULE = Imager PACKAGE = Imager
1464 while( (item=i_format_list[i++]) != NULL ) {
1466 PUSHs(sv_2mortal(newSVpv(item,0)));
1470 i_sametype(im, x, y)
1476 i_sametype_chans(im, x, y, channels)
1483 i_init_log(name_sv,level)
1487 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1489 RETVAL = i_init_log(name, level);
1494 i_log_entry(string,level)
1507 i_img_info(im,info);
1509 PUSHs(sv_2mortal(newSViv(info[0])));
1510 PUSHs(sv_2mortal(newSViv(info[1])));
1511 PUSHs(sv_2mortal(newSViv(info[2])));
1512 PUSHs(sv_2mortal(newSViv(info[3])));
1518 i_img_setmask(im,ch_mask)
1527 i_img_getchannels(im)
1536 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1544 i_img_get_height(im)
1549 i_img_is_monochrome(im)
1555 result = i_img_is_monochrome(im, &zero_is_white);
1557 if (GIMME_V == G_ARRAY) {
1560 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1569 i_line(im,x1,y1,x2,y2,val,endp)
1579 i_line_aa(im,x1,y1,x2,y2,val,endp)
1589 i_box(im,x1,y1,x2,y2,val)
1598 i_box_filled(im,x1,y1,x2,y2,val)
1607 i_box_filledf(im,x1,y1,x2,y2,val)
1613 Imager::Color::Float val
1616 i_box_cfill(im,x1,y1,x2,y2,fill)
1622 Imager::FillHandle fill
1625 i_arc(im,x,y,rad,d1,d2,val)
1635 i_arc_aa(im,x,y,rad,d1,d2,val)
1645 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1652 Imager::FillHandle fill
1655 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1662 Imager::FillHandle fill
1666 i_circle_aa(im,x,y,rad,val)
1674 i_circle_out(im,x,y,rad,val)
1682 i_circle_out_aa(im,x,y,rad,val)
1690 i_arc_out(im,x,y,rad,d1,d2,val)
1700 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1711 i_bezier_multi(im,xc,yc,val)
1724 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1725 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1726 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1727 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1728 av1=(AV*)SvRV(ST(1));
1729 av2=(AV*)SvRV(ST(2));
1730 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1732 x=mymalloc( len*sizeof(double) );
1733 y=mymalloc( len*sizeof(double) );
1734 for(i=0;i<len;i++) {
1735 sv1=(*(av_fetch(av1,i,0)));
1736 sv2=(*(av_fetch(av2,i,0)));
1737 x[i]=(double)SvNV(sv1);
1738 y[i]=(double)SvNV(sv2);
1740 i_bezier_multi(im,len,x,y,val);
1746 i_poly_aa(im,x_av,y_av,val)
1758 if (av_len(x_av) != av_len(y_av))
1759 croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1761 x=mymalloc( len*sizeof(double) );
1762 y=mymalloc( len*sizeof(double) );
1763 for(i=0;i<len;i++) {
1764 x_sv=(*(av_fetch(x_av,i,0)));
1765 y_sv=(*(av_fetch(y_av,i,0)));
1766 x[i]=(double)SvNV(x_sv);
1767 y[i]=(double)SvNV(y_sv);
1769 RETVAL = i_poly_aa(im,len,x,y,val);
1776 i_poly_aa_cfill(im,x_av,y_av,fill)
1780 Imager::FillHandle fill
1788 if (av_len(x_av) != av_len(y_av))
1789 croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1791 x=mymalloc( len*sizeof(double) );
1792 y=mymalloc( len*sizeof(double) );
1793 for(i=0;i<len;i++) {
1794 x_sv=(*(av_fetch(x_av,i,0)));
1795 y_sv=(*(av_fetch(y_av,i,0)));
1796 x[i]=(double)SvNV(x_sv);
1797 y[i]=(double)SvNV(y_sv);
1799 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1806 i_flood_fill(im,seedx,seedy,dcol)
1813 i_flood_cfill(im,seedx,seedy,fill)
1817 Imager::FillHandle fill
1820 i_flood_fill_border(im,seedx,seedy,dcol, border)
1825 Imager::Color border
1828 i_flood_cfill_border(im,seedx,seedy,fill, border)
1832 Imager::FillHandle fill
1833 Imager::Color border
1837 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1849 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1866 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1877 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1890 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)
1906 i_combine(src_av, channels_av = NULL)
1910 i_img **imgs = NULL;
1912 int *channels = NULL;
1917 in_count = av_len(src_av) + 1;
1919 imgs = mymalloc(sizeof(i_img*) * in_count);
1920 channels = mymalloc(sizeof(int) * in_count);
1921 for (i = 0; i < in_count; ++i) {
1922 psv = av_fetch(src_av, i, 0);
1923 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1926 croak("imgs must contain only images");
1928 tmp = SvIV((SV*)SvRV(*psv));
1929 imgs[i] = INT2PTR(i_img*, tmp);
1931 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1933 channels[i] = SvIV(*psv);
1940 RETVAL = i_combine(imgs, channels, in_count);
1947 i_flipxy(im, direction)
1952 i_rotate90(im, degrees)
1957 i_rotate_exact(im, amount, ...)
1961 i_color *backp = NULL;
1962 i_fcolor *fbackp = NULL;
1966 /* extract the bg colors if any */
1967 /* yes, this is kind of strange */
1968 for (i = 2; i < items; ++i) {
1970 if (sv_derived_from(sv1, "Imager::Color")) {
1971 IV tmp = SvIV((SV*)SvRV(sv1));
1972 backp = INT2PTR(i_color *, tmp);
1974 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1975 IV tmp = SvIV((SV*)SvRV(sv1));
1976 fbackp = INT2PTR(i_fcolor *, tmp);
1979 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1984 i_matrix_transform(im, xsize, ysize, matrix, ...)
1994 i_color *backp = NULL;
1995 i_fcolor *fbackp = NULL;
1997 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1998 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1999 av=(AV*)SvRV(ST(3));
2003 for (i = 0; i < len; ++i) {
2004 sv1=(*(av_fetch(av,i,0)));
2005 matrix[i] = SvNV(sv1);
2009 /* extract the bg colors if any */
2010 /* yes, this is kind of strange */
2011 for (i = 4; i < items; ++i) {
2013 if (sv_derived_from(sv1, "Imager::Color")) {
2014 IV tmp = SvIV((SV*)SvRV(sv1));
2015 backp = INT2PTR(i_color *, tmp);
2017 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2018 IV tmp = SvIV((SV*)SvRV(sv1));
2019 fbackp = INT2PTR(i_fcolor *, tmp);
2022 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2027 i_gaussian(im,stdev)
2032 i_unsharp_mask(im,stdev,scale)
2047 len = av_len(coef) + 1;
2048 c_coef=mymalloc( len * sizeof(double) );
2049 for(i = 0; i < len; i++) {
2050 sv1 = (*(av_fetch(coef, i, 0)));
2051 c_coef[i] = (double)SvNV(sv1);
2053 RETVAL = i_conv(im, c_coef, len);
2059 i_convert(src, avmain)
2071 outchan = av_len(avmain)+1;
2072 /* find the biggest */
2074 for (j=0; j < outchan; ++j) {
2075 temp = av_fetch(avmain, j, 0);
2076 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2077 avsub = (AV*)SvRV(*temp);
2078 len = av_len(avsub)+1;
2083 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2087 coeff = mymalloc(sizeof(double) * outchan * inchan);
2088 for (j = 0; j < outchan; ++j) {
2089 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2090 len = av_len(avsub)+1;
2091 for (i = 0; i < len; ++i) {
2092 temp = av_fetch(avsub, i, 0);
2094 coeff[i+j*inchan] = SvNV(*temp);
2096 coeff[i+j*inchan] = 0;
2099 coeff[i++ + j*inchan] = 0;
2101 RETVAL = i_convert(src, coeff, outchan, inchan);
2111 unsigned int mask = 0;
2117 unsigned char (*maps)[256];
2119 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2120 croak("i_map: parameter 2 must be an arrayref\n");
2121 avmain = (AV*)SvRV(ST(1));
2122 len = av_len(avmain)+1;
2123 if (im->channels < len) len = im->channels;
2125 maps = mymalloc( len * sizeof(unsigned char [256]) );
2127 for (j=0; j<len ; j++) {
2128 temp = av_fetch(avmain, j, 0);
2129 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2130 avsub = (AV*)SvRV(*temp);
2131 if(av_len(avsub) != 255) continue;
2133 for (i=0; i<256 ; i++) {
2135 temp = av_fetch(avsub, i, 0);
2136 val = temp ? SvIV(*temp) : 0;
2138 if (val>255) val = 255;
2143 i_map(im, maps, mask);
2157 i_img_diffd(im1,im2)
2162 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2172 _is_color_object(sv)
2176 RETVAL = SvOK(sv) && SvROK(sv) &&
2177 (sv_derived_from(sv, "Imager::Color")
2178 || sv_derived_from(sv, "Imager::Color::Float"));
2190 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2192 #define TT_DESTROY(handle) i_tt_destroy(handle)
2196 Imager::Font::TT handle
2201 (void)items; /* avoid unused warning */
2207 MODULE = Imager PACKAGE = Imager
2211 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2212 Imager::Font::TT handle
2226 str = SvPV(str_sv, len);
2231 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2232 len, smooth, utf8, align);
2238 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2239 Imager::Font::TT handle
2253 str = SvPV(str_sv, len);
2258 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2259 smooth, utf8, align);
2265 i_tt_bbox(handle,point,str_sv,utf8)
2266 Imager::Font::TT handle
2271 i_img_dim cords[BOUNDING_BOX_COUNT];
2277 str = SvPV(str_sv, len);
2282 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2284 for (i = 0; i < rc; ++i) {
2285 PUSHs(sv_2mortal(newSViv(cords[i])));
2290 i_tt_has_chars(handle, text_sv, utf8)
2291 Imager::Font::TT handle
2302 text = SvPV(text_sv, len);
2304 if (SvUTF8(text_sv))
2307 work = mymalloc(len);
2308 count = i_tt_has_chars(handle, text, len, utf8, work);
2309 if (GIMME_V == G_ARRAY) {
2311 for (i = 0; i < count; ++i) {
2312 PUSHs(boolSV(work[i]));
2317 PUSHs(sv_2mortal(newSVpv(work, count)));
2322 i_tt_dump_names(handle)
2323 Imager::Font::TT handle
2326 i_tt_face_name(handle)
2327 Imager::Font::TT handle
2332 len = i_tt_face_name(handle, name, sizeof(name));
2335 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2339 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2340 Imager::Font::TT handle
2352 text = SvPV(text_sv, work_len);
2354 if (SvUTF8(text_sv))
2361 ch = i_utf8_advance(&text, &len);
2363 i_push_error(0, "invalid UTF8 character");
2371 EXTEND(SP, count+1);
2372 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2373 ST(count) = sv_2mortal(newSVpv(name, 0));
2376 ST(count) = &PL_sv_undef;
2385 i_test_format_probe(ig, length)
2390 i_readpnm_wiol(ig, allow_incomplete)
2392 int allow_incomplete
2396 i_readpnm_multi_wiol(ig, allow_incomplete)
2398 int allow_incomplete
2404 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2407 for (i = 0; i < count; ++i) {
2408 SV *sv = sv_newmortal();
2409 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2416 i_writeppm_wiol(im, ig)
2425 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2434 i_writeraw_wiol(im,ig)
2439 i_writebmp_wiol(im,ig)
2444 i_readbmp_wiol(ig, allow_incomplete=0)
2446 int allow_incomplete
2450 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2459 idlen = SvCUR(ST(4));
2460 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2466 i_readtga_wiol(ig, length)
2474 i_scaleaxis(im,Value,Axis)
2480 i_scale_nn(im,scx,scy)
2486 i_scale_mixing(im, width, height)
2496 i_count_colors(im,maxc)
2501 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2506 unsigned int * col_usage = NULL;
2509 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2510 EXTEND(SP, col_cnt);
2511 for (i = 0; i < col_cnt; i++) {
2512 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2519 i_transform(im,opx,opy,parm)
2533 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2534 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2535 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2536 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2537 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2538 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2539 av=(AV*)SvRV(ST(1));
2541 opx=mymalloc( opxl*sizeof(int) );
2542 for(i=0;i<opxl;i++) {
2543 sv1=(*(av_fetch(av,i,0)));
2544 opx[i]=(int)SvIV(sv1);
2546 av=(AV*)SvRV(ST(2));
2548 opy=mymalloc( opyl*sizeof(int) );
2549 for(i=0;i<opyl;i++) {
2550 sv1=(*(av_fetch(av,i,0)));
2551 opy[i]=(int)SvIV(sv1);
2553 av=(AV*)SvRV(ST(3));
2554 parmlen=av_len(av)+1;
2555 parm=mymalloc( parmlen*sizeof(double) );
2556 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2557 sv1=(*(av_fetch(av,i,0)));
2558 parm[i]=(double)SvNV(sv1);
2560 result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2565 SV *result_sv = sv_newmortal();
2567 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2572 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2598 in_imgs_count = av_len(av_in_imgs)+1;
2599 for (i = 0; i < in_imgs_count; ++i) {
2600 sv1 = *av_fetch(av_in_imgs, i, 0);
2601 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2602 croak("sv_in_img must contain only images");
2605 if (in_imgs_count > 0) {
2606 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2607 for (i = 0; i < in_imgs_count; ++i) {
2608 sv1 = *av_fetch(av_in_imgs,i,0);
2609 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2610 croak("Parameter 5 must contain only images");
2612 tmp = SvIV((SV*)SvRV(sv1));
2613 in_imgs[i] = INT2PTR(i_img*, tmp);
2617 /* no input images */
2620 /* default the output size from the first input if possible */
2622 width = SvIV(sv_width);
2623 else if (in_imgs_count)
2624 width = in_imgs[0]->xsize;
2626 croak("No output image width supplied");
2628 if (SvOK(sv_height))
2629 height = SvIV(sv_height);
2630 else if (in_imgs_count)
2631 height = in_imgs[0]->ysize;
2633 croak("No output image height supplied");
2635 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2636 if (ops_len % sizeof(struct rm_op))
2637 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2638 ops_count = ops_len / sizeof(struct rm_op);
2640 n_regs_count = av_len(av_n_regs)+1;
2641 n_regs = mymalloc(n_regs_count * sizeof(double));
2642 for (i = 0; i < n_regs_count; ++i) {
2643 sv1 = *av_fetch(av_n_regs,i,0);
2645 n_regs[i] = SvNV(sv1);
2647 c_regs_count = av_len(av_c_regs)+1;
2648 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2649 /* I don't bother initializing the colou?r registers */
2651 result=i_transform2(width, height, channels, ops, ops_count,
2652 n_regs, n_regs_count,
2653 c_regs, c_regs_count, in_imgs, in_imgs_count);
2659 SV *result_sv = sv_newmortal();
2661 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2667 i_contrast(im,intensity)
2680 i_noise(im,amount,type)
2686 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2696 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2715 i_postlevels(im,levels)
2725 i_watermark(im,wmark,tx,ty,pixdiff)
2727 Imager::ImgRaw wmark
2734 i_autolevels(im,lsat,usat,skew)
2741 i_radnoise(im,xo,yo,rscale,ascale)
2749 i_turbnoise(im, xo, yo, scale)
2772 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2773 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2774 croak("i_gradgen: Second argument must be an array ref");
2775 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2776 croak("i_gradgen: Third argument must be an array ref");
2777 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2778 croak("i_gradgen: Fourth argument must be an array ref");
2779 axx = (AV *)SvRV(ST(1));
2780 ayy = (AV *)SvRV(ST(2));
2781 ac = (AV *)SvRV(ST(3));
2782 dmeasure = (int)SvIV(ST(4));
2784 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2785 num = num <= av_len(ac) ? num : av_len(ac);
2787 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2788 xo = mymalloc( sizeof(i_img_dim) * num );
2789 yo = mymalloc( sizeof(i_img_dim) * num );
2790 ival = mymalloc( sizeof(i_color) * num );
2791 for(i = 0; i<num; i++) {
2792 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2793 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2794 sv = *av_fetch(ac, i, 0);
2795 if ( !sv_derived_from(sv, "Imager::Color") ) {
2796 free(axx); free(ayy); free(ac);
2797 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2799 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2801 i_gradgen(im, num, xo, yo, ival, dmeasure);
2807 i_diff_image(im, im2, mindist=0)
2813 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2823 double ssample_param
2827 i_fountain_seg *segs;
2829 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2830 croak("i_fountain: argument 11 must be an array ref");
2832 asegs = (AV *)SvRV(ST(10));
2833 segs = load_fount_segs(aTHX_ asegs, &count);
2834 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2835 super_sample, ssample_param, count, segs);
2841 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2850 double ssample_param
2854 i_fountain_seg *segs;
2856 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2857 croak("i_fountain: argument 11 must be an array ref");
2859 asegs = (AV *)SvRV(ST(9));
2860 segs = load_fount_segs(aTHX_ asegs, &count);
2861 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2862 super_sample, ssample_param, count, segs);
2868 i_new_fill_opacity(other_fill, alpha_mult)
2869 Imager::FillHandle other_fill
2880 errors = i_errors();
2882 while (errors[i].msg) {
2884 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2885 if (!av_store(av, 0, sv)) {
2888 sv = newSViv(errors[i].code);
2889 if (!av_store(av, 1, sv)) {
2892 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2900 i_push_error(code, msg)
2905 i_nearest_color(im, ...)
2920 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2921 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2922 croak("i_nearest_color: Second argument must be an array ref");
2923 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2924 croak("i_nearest_color: Third argument must be an array ref");
2925 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2926 croak("i_nearest_color: Fourth argument must be an array ref");
2927 axx = (AV *)SvRV(ST(1));
2928 ayy = (AV *)SvRV(ST(2));
2929 ac = (AV *)SvRV(ST(3));
2930 dmeasure = (int)SvIV(ST(4));
2932 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2933 num = num <= av_len(ac) ? num : av_len(ac);
2935 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2936 xo = mymalloc( sizeof(i_img_dim) * num );
2937 yo = mymalloc( sizeof(i_img_dim) * num );
2938 ival = mymalloc( sizeof(i_color) * num );
2939 for(i = 0; i<num; i++) {
2940 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2941 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2942 sv = *av_fetch(ac, i, 0);
2943 if ( !sv_derived_from(sv, "Imager::Color") ) {
2944 free(axx); free(ayy); free(ac);
2945 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2947 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2949 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2963 rc=DSO_open(filename,&evstr);
2967 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2968 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2971 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2977 DSO_close(dso_handle)
2981 DSO_funclist(dso_handle_v)
2985 DSO_handle *dso_handle;
2986 func_ptr *functions;
2988 dso_handle=(DSO_handle*)dso_handle_v;
2989 functions = DSO_funclist(dso_handle);
2991 while( functions[i].name != NULL) {
2993 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2995 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2999 DSO_call(handle,func_index,hv)
3005 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3006 hv=(HV*)SvRV(ST(2));
3007 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3008 DSO_call( (DSO_handle *)handle,func_index,hv);
3011 i_get_pixel(im, x, y)
3018 color = (i_color *)mymalloc(sizeof(i_color));
3019 if (i_gpix(im, x, y, color) == 0) {
3020 RETVAL = NEWSV(0, 0);
3021 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3025 RETVAL = &PL_sv_undef;
3032 i_ppix(im, x, y, cl)
3039 i_img_pal_new(x, y, channels, maxpal)
3046 i_img_to_pal(src, quant)
3052 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3053 croak("i_img_to_pal: second argument must be a hash ref");
3054 hv = (HV *)SvRV(ST(1));
3055 memset(&quant, 0, sizeof(quant));
3057 quant.mc_size = 256;
3058 ip_handle_quant_opts(aTHX_ &quant, hv);
3059 RETVAL = i_img_to_pal(src, &quant);
3061 ip_copy_colors_back(aTHX_ hv, &quant);
3063 ip_cleanup_quant_opts(aTHX_ &quant);
3072 i_img_make_palette(HV *quant_hv, ...)
3074 size_t count = items - 1;
3076 i_img **imgs = NULL;
3080 croak("Please supply at least one image (%d)", (int)count);
3081 imgs = mymalloc(sizeof(i_img *) * count);
3082 for (i = 0; i < count; ++i) {
3083 SV *img_sv = ST(i + 1);
3084 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3085 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3089 croak("Image %d is not an image object", (int)i+1);
3092 memset(&quant, 0, sizeof(quant));
3094 quant.mc_size = 256;
3095 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3096 i_quant_makemap(&quant, imgs, count);
3097 EXTEND(SP, quant.mc_count);
3098 for (i = 0; i < quant.mc_count; ++i) {
3099 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3102 ip_cleanup_quant_opts(aTHX_ &quant);
3116 work = mymalloc((r-l) * sizeof(i_palidx));
3117 count = i_gpal(im, l, r, y, work);
3118 if (GIMME_V == G_ARRAY) {
3120 for (i = 0; i < count; ++i) {
3121 PUSHs(sv_2mortal(newSViv(work[i])));
3126 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3131 if (GIMME_V != G_ARRAY) {
3133 PUSHs(&PL_sv_undef);
3138 i_ppal(im, l, y, ...)
3147 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3148 for (i=0; i < items-3; ++i) {
3149 work[i] = SvIV(ST(i+3));
3151 validate_i_ppal(im, work, items - 3);
3152 RETVAL = i_ppal(im, l, l+items-3, y, work);
3161 i_ppal_p(im, l, y, data)
3167 i_palidx const *work;
3170 work = (i_palidx const *)SvPV(data, len);
3171 len /= sizeof(i_palidx);
3173 validate_i_ppal(im, work, len);
3174 RETVAL = i_ppal(im, l, l+len, y, work);
3183 i_addcolors(im, ...)
3191 croak("i_addcolors: no colors to add");
3192 colors = mymalloc((items-1) * sizeof(i_color));
3193 for (i=0; i < items-1; ++i) {
3194 if (sv_isobject(ST(i+1))
3195 && sv_derived_from(ST(i+1), "Imager::Color")) {
3196 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3197 colors[i] = *INT2PTR(i_color *, tmp);
3201 croak("i_addcolor: pixels must be Imager::Color objects");
3204 index = i_addcolors(im, colors, items-1);
3207 RETVAL = newSVpv("0 but true", 0);
3209 else if (index == -1) {
3210 RETVAL = &PL_sv_undef;
3213 RETVAL = newSViv(index);
3219 i_setcolors(im, index, ...)
3227 croak("i_setcolors: no colors to add");
3228 colors = mymalloc((items-2) * sizeof(i_color));
3229 for (i=0; i < items-2; ++i) {
3230 if (sv_isobject(ST(i+2))
3231 && sv_derived_from(ST(i+2), "Imager::Color")) {
3232 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3233 colors[i] = *INT2PTR(i_color *, tmp);
3237 croak("i_setcolors: pixels must be Imager::Color objects");
3240 RETVAL = i_setcolors(im, index, colors, items-2);
3246 i_getcolors(im, index, ...)
3255 croak("i_getcolors: too many arguments");
3257 count = SvIV(ST(2));
3259 croak("i_getcolors: count must be positive");
3260 colors = mymalloc(sizeof(i_color) * count);
3261 if (i_getcolors(im, index, colors, count)) {
3262 for (i = 0; i < count; ++i) {
3263 SV *sv = make_i_color_sv(aTHX_ colors+i);
3279 i_findcolor(im, color)
3285 if (i_findcolor(im, color, &index)) {
3286 RETVAL = newSViv(index);
3289 RETVAL = &PL_sv_undef;
3307 i_gsamp(im, l, r, y, channels)
3312 i_channel_list channels
3318 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
3319 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3320 if (GIMME_V == G_ARRAY) {
3322 for (i = 0; i < count; ++i)
3323 PUSHs(sv_2mortal(newSViv(data[i])));
3327 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3332 if (GIMME_V != G_ARRAY) {
3334 PUSHs(&PL_sv_undef);
3339 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3347 i_channel_list channels
3354 croak("No channel numbers supplied to g_samp()");
3356 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3357 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3358 for (i = 0; i < count; ++i) {
3359 av_store(target, i+offset, newSVuv(data[i]));
3371 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3376 i_channel_list channels
3378 i_img_dim data_offset
3379 i_img_dim pixel_count
3388 data_count = av_len(data_av) + 1;
3389 if (data_offset < 0) {
3390 croak("data_offset must be non-negative");
3392 if (data_offset > data_count) {
3393 croak("data_offset greater than number of samples supplied");
3395 if (pixel_count == -1 ||
3396 data_offset + pixel_count * channels.count > data_count) {
3397 pixel_count = (data_count - data_offset) / channels.count;
3400 data_used = pixel_count * channels.count;
3401 data = mymalloc(sizeof(unsigned) * data_count);
3402 for (i = 0; i < data_used; ++i)
3403 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3405 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3406 channels.count, bits);
3414 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3418 i_channel_list channels
3427 i_push_error(0, "offset must be non-negative");
3431 if (offset > data.count) {
3432 i_push_error(0, "offset greater than number of samples supplied");
3435 data.samples += offset;
3436 data.count -= offset;
3439 width * channels.count > data.count) {
3440 width = data.count / channels.count;
3443 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3448 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3452 i_channel_list channels
3461 i_push_error(0, "offset must be non-negative");
3465 if (offset > data.count) {
3466 i_push_error(0, "offset greater than number of samples supplied");
3469 data.samples += offset;
3470 data.count -= offset;
3473 width * channels.count > data.count) {
3474 width = data.count / channels.count;
3477 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3482 i_img_masked_new(targ, mask, x, y, w, h)
3492 if (!sv_isobject(ST(1))
3493 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3494 croak("i_img_masked_new: parameter 2 must undef or an image");
3496 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3500 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3505 i_plin(im, l, y, ...)
3516 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3517 /* supplied as a byte string */
3518 work = (i_color *)SvPV(ST(3), len);
3519 count = len / sizeof(i_color);
3520 if (count * sizeof(i_color) != len) {
3521 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3523 RETVAL = i_plin(im, l, l+count, y, work);
3526 work = mymalloc(sizeof(i_color) * (items-3));
3527 for (i=0; i < items-3; ++i) {
3528 if (sv_isobject(ST(i+3))
3529 && sv_derived_from(ST(i+3), "Imager::Color")) {
3530 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3531 work[i] = *INT2PTR(i_color *, tmp);
3535 croak("i_plin: pixels must be Imager::Color objects");
3538 RETVAL = i_plin(im, l, l+items-3, y, work);
3549 i_ppixf(im, x, y, cl)
3553 Imager::Color::Float cl
3556 i_gsampf(im, l, r, y, channels)
3561 i_channel_list channels
3567 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3568 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3569 if (GIMME_V == G_ARRAY) {
3571 for (i = 0; i < count; ++i)
3572 PUSHs(sv_2mortal(newSVnv(data[i])));
3576 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3581 if (GIMME_V != G_ARRAY) {
3583 PUSHs(&PL_sv_undef);
3588 i_plinf(im, l, y, ...)
3599 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3600 /* supplied as a byte string */
3601 work = (i_fcolor *)SvPV(ST(3), len);
3602 count = len / sizeof(i_fcolor);
3603 if (count * sizeof(i_fcolor) != len) {
3604 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3606 RETVAL = i_plinf(im, l, l+count, y, work);
3609 work = mymalloc(sizeof(i_fcolor) * (items-3));
3610 for (i=0; i < items-3; ++i) {
3611 if (sv_isobject(ST(i+3))
3612 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3613 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3614 work[i] = *INT2PTR(i_fcolor *, tmp);
3618 croak("i_plinf: pixels must be Imager::Color::Float objects");
3622 RETVAL = i_plinf(im, l, l+items-3, y, work);
3640 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3641 if (i_gpixf(im, x, y, color) == 0) {
3642 RETVAL = NEWSV(0,0);
3643 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3647 RETVAL = &PL_sv_undef;
3663 vals = mymalloc((r-l) * sizeof(i_color));
3664 memset(vals, 0, (r-l) * sizeof(i_color));
3665 count = i_glin(im, l, r, y, vals);
3666 if (GIMME_V == G_ARRAY) {
3668 for (i = 0; i < count; ++i) {
3669 SV *sv = make_i_color_sv(aTHX_ vals+i);
3675 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3681 i_glinf(im, l, r, y)
3691 for (i = 0; i < MAXCHANNELS; ++i)
3692 zero.channel[i] = 0;
3694 vals = mymalloc((r-l) * sizeof(i_fcolor));
3695 for (i = 0; i < r-l; ++i)
3697 count = i_glinf(im, l, r, y, vals);
3698 if (GIMME_V == G_ARRAY) {
3700 for (i = 0; i < count; ++i) {
3702 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3704 sv = sv_newmortal();
3705 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3711 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3717 i_img_8_new(x, y, ch)
3723 i_img_16_new(x, y, ch)
3733 i_img_double_new(x, y, ch)
3743 i_tags_addn(im, name, code, idata)
3752 name = SvPV(ST(1), len);
3755 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3760 i_tags_add(im, name, code, data, idata)
3770 name = SvPV(ST(1), len);
3774 data = SvPV(ST(3), len);
3779 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3784 i_tags_find(im, name, start)
3791 if (i_tags_find(&im->tags, name, start, &entry)) {
3793 RETVAL = newSVpv("0 but true", 0);
3795 RETVAL = newSViv(entry);
3797 RETVAL = &PL_sv_undef;
3803 i_tags_findn(im, code, start)
3810 if (i_tags_findn(&im->tags, code, start, &entry)) {
3812 RETVAL = newSVpv("0 but true", 0);
3814 RETVAL = newSViv(entry);
3817 RETVAL = &PL_sv_undef;
3823 i_tags_delete(im, entry)
3827 RETVAL = i_tags_delete(&im->tags, entry);
3832 i_tags_delbyname(im, name)
3836 RETVAL = i_tags_delbyname(&im->tags, name);
3841 i_tags_delbycode(im, code)
3845 RETVAL = i_tags_delbycode(&im->tags, code);
3850 i_tags_get(im, index)
3854 if (index >= 0 && index < im->tags.count) {
3855 i_img_tag *entry = im->tags.tags + index;
3859 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3862 PUSHs(sv_2mortal(newSViv(entry->code)));
3865 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3868 PUSHs(sv_2mortal(newSViv(entry->idata)));
3873 i_tags_get_string(im, what_sv)
3877 char const *name = NULL;
3881 if (SvIOK(what_sv)) {
3882 code = SvIV(what_sv);
3886 name = SvPV_nolen(what_sv);
3889 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3891 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3898 RETVAL = im->tags.count;
3904 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3908 Imager::FillHandle fill
3911 IFILL_CLONE_SKIP(...)
3913 (void)items; /* avoid unused warning for XS variable */
3918 MODULE = Imager PACKAGE = Imager
3921 i_new_fill_solid(cl, combine)
3926 i_new_fill_solidf(cl, combine)
3927 Imager::Color::Float cl
3931 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3939 unsigned char *cust_hatch;
3943 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3947 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3952 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3953 Imager::Color::Float fg
3954 Imager::Color::Float bg
3960 unsigned char *cust_hatch;
3964 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3968 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3973 i_new_fill_image(src, matrix, xoff, yoff, combine)
3990 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3991 croak("i_new_fill_image: parameter must be an arrayref");
3992 av=(AV*)SvRV(ST(1));
3996 for (i = 0; i < len; ++i) {
3997 sv1=(*(av_fetch(av,i,0)));
3998 matrix[i] = SvNV(sv1);
4004 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4008 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4010 # this class is only exposed for testing
4013 i_int_hlines_testing()
4015 #if i_int_hlines_testing()
4017 Imager::Internal::Hlines
4018 i_int_hlines_new(start_y, count_y, start_x, count_x)
4024 Imager::Internal::Hlines
4025 i_int_hlines_new_img(im)
4029 i_int_hlines_add(hlines, y, minx, width)
4030 Imager::Internal::Hlines hlines
4036 i_int_hlines_DESTROY(hlines)
4037 Imager::Internal::Hlines hlines
4040 i_int_hlines_dump(hlines)
4041 Imager::Internal::Hlines hlines
4044 i_int_hlines_CLONE_SKIP(cls)
4048 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4051 im_context_DESTROY(ctx)
4054 #ifdef PERL_IMPLICIT_CONTEXT
4057 im_context_CLONE(...)
4061 /* the following sv_setref_pv() will free this inc */
4062 im_context_refinc(MY_CXT.ctx, "CLONE");
4063 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4064 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4069 PERL_SET_GLOBAL_CALLBACKS;
4070 PERL_PL_SET_GLOBAL_CALLBACKS;
4071 #ifdef PERL_IMPLICIT_CONTEXT
4077 start_context(aTHX);
4078 im_get_context = perl_get_context;