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(newSVnv(cl->rgba.r)));
958 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
959 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
960 PUSHs(sv_2mortal(newSVnv(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,xc,yc,val)
1759 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1760 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1761 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1762 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1763 av1=(AV*)SvRV(ST(1));
1764 av2=(AV*)SvRV(ST(2));
1765 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1767 x=mymalloc( len*sizeof(double) );
1768 y=mymalloc( len*sizeof(double) );
1769 for(i=0;i<len;i++) {
1770 sv1=(*(av_fetch(av1,i,0)));
1771 sv2=(*(av_fetch(av2,i,0)));
1772 x[i]=(double)SvNV(sv1);
1773 y[i]=(double)SvNV(sv2);
1775 RETVAL = i_poly_aa(im,len,x,y,val);
1782 i_poly_aa_cfill(im,xc,yc,fill)
1784 Imager::FillHandle fill
1794 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1795 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1796 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1797 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1798 av1=(AV*)SvRV(ST(1));
1799 av2=(AV*)SvRV(ST(2));
1800 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1802 x=mymalloc( len*sizeof(double) );
1803 y=mymalloc( len*sizeof(double) );
1804 for(i=0;i<len;i++) {
1805 sv1=(*(av_fetch(av1,i,0)));
1806 sv2=(*(av_fetch(av2,i,0)));
1807 x[i]=(double)SvNV(sv1);
1808 y[i]=(double)SvNV(sv2);
1810 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1819 i_flood_fill(im,seedx,seedy,dcol)
1826 i_flood_cfill(im,seedx,seedy,fill)
1830 Imager::FillHandle fill
1833 i_flood_fill_border(im,seedx,seedy,dcol, border)
1838 Imager::Color border
1841 i_flood_cfill_border(im,seedx,seedy,fill, border)
1845 Imager::FillHandle fill
1846 Imager::Color border
1850 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1862 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1879 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1890 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1903 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)
1919 i_combine(src_av, channels_av = NULL)
1923 i_img **imgs = NULL;
1925 int *channels = NULL;
1930 in_count = av_len(src_av) + 1;
1932 imgs = mymalloc(sizeof(i_img*) * in_count);
1933 channels = mymalloc(sizeof(int) * in_count);
1934 for (i = 0; i < in_count; ++i) {
1935 psv = av_fetch(src_av, i, 0);
1936 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1939 croak("imgs must contain only images");
1941 tmp = SvIV((SV*)SvRV(*psv));
1942 imgs[i] = INT2PTR(i_img*, tmp);
1944 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1946 channels[i] = SvIV(*psv);
1953 RETVAL = i_combine(imgs, channels, in_count);
1960 i_flipxy(im, direction)
1965 i_rotate90(im, degrees)
1970 i_rotate_exact(im, amount, ...)
1974 i_color *backp = NULL;
1975 i_fcolor *fbackp = NULL;
1979 /* extract the bg colors if any */
1980 /* yes, this is kind of strange */
1981 for (i = 2; i < items; ++i) {
1983 if (sv_derived_from(sv1, "Imager::Color")) {
1984 IV tmp = SvIV((SV*)SvRV(sv1));
1985 backp = INT2PTR(i_color *, tmp);
1987 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1988 IV tmp = SvIV((SV*)SvRV(sv1));
1989 fbackp = INT2PTR(i_fcolor *, tmp);
1992 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1997 i_matrix_transform(im, xsize, ysize, matrix, ...)
2007 i_color *backp = NULL;
2008 i_fcolor *fbackp = NULL;
2010 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
2011 croak("i_matrix_transform: parameter 4 must be an array ref\n");
2012 av=(AV*)SvRV(ST(3));
2016 for (i = 0; i < len; ++i) {
2017 sv1=(*(av_fetch(av,i,0)));
2018 matrix[i] = SvNV(sv1);
2022 /* extract the bg colors if any */
2023 /* yes, this is kind of strange */
2024 for (i = 4; i < items; ++i) {
2026 if (sv_derived_from(sv1, "Imager::Color")) {
2027 IV tmp = SvIV((SV*)SvRV(sv1));
2028 backp = INT2PTR(i_color *, tmp);
2030 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2031 IV tmp = SvIV((SV*)SvRV(sv1));
2032 fbackp = INT2PTR(i_fcolor *, tmp);
2035 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2040 i_gaussian(im,stdev)
2045 i_unsharp_mask(im,stdev,scale)
2060 len = av_len(coef) + 1;
2061 c_coef=mymalloc( len * sizeof(double) );
2062 for(i = 0; i < len; i++) {
2063 sv1 = (*(av_fetch(coef, i, 0)));
2064 c_coef[i] = (double)SvNV(sv1);
2066 RETVAL = i_conv(im, c_coef, len);
2072 i_convert(src, avmain)
2084 outchan = av_len(avmain)+1;
2085 /* find the biggest */
2087 for (j=0; j < outchan; ++j) {
2088 temp = av_fetch(avmain, j, 0);
2089 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2090 avsub = (AV*)SvRV(*temp);
2091 len = av_len(avsub)+1;
2096 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2100 coeff = mymalloc(sizeof(double) * outchan * inchan);
2101 for (j = 0; j < outchan; ++j) {
2102 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2103 len = av_len(avsub)+1;
2104 for (i = 0; i < len; ++i) {
2105 temp = av_fetch(avsub, i, 0);
2107 coeff[i+j*inchan] = SvNV(*temp);
2109 coeff[i+j*inchan] = 0;
2112 coeff[i++ + j*inchan] = 0;
2114 RETVAL = i_convert(src, coeff, outchan, inchan);
2124 unsigned int mask = 0;
2130 unsigned char (*maps)[256];
2132 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2133 croak("i_map: parameter 2 must be an arrayref\n");
2134 avmain = (AV*)SvRV(ST(1));
2135 len = av_len(avmain)+1;
2136 if (im->channels < len) len = im->channels;
2138 maps = mymalloc( len * sizeof(unsigned char [256]) );
2140 for (j=0; j<len ; j++) {
2141 temp = av_fetch(avmain, j, 0);
2142 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2143 avsub = (AV*)SvRV(*temp);
2144 if(av_len(avsub) != 255) continue;
2146 for (i=0; i<256 ; i++) {
2148 temp = av_fetch(avsub, i, 0);
2149 val = temp ? SvIV(*temp) : 0;
2151 if (val>255) val = 255;
2156 i_map(im, maps, mask);
2170 i_img_diffd(im1,im2)
2175 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2185 _is_color_object(sv)
2189 RETVAL = SvOK(sv) && SvROK(sv) &&
2190 (sv_derived_from(sv, "Imager::Color")
2191 || sv_derived_from(sv, "Imager::Color::Float"));
2203 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2205 #define TT_DESTROY(handle) i_tt_destroy(handle)
2209 Imager::Font::TT handle
2214 (void)items; /* avoid unused warning */
2220 MODULE = Imager PACKAGE = Imager
2224 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2225 Imager::Font::TT handle
2239 str = SvPV(str_sv, len);
2244 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2245 len, smooth, utf8, align);
2251 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2252 Imager::Font::TT handle
2266 str = SvPV(str_sv, len);
2271 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2272 smooth, utf8, align);
2278 i_tt_bbox(handle,point,str_sv,utf8)
2279 Imager::Font::TT handle
2284 i_img_dim cords[BOUNDING_BOX_COUNT];
2290 str = SvPV(str_sv, len);
2295 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2297 for (i = 0; i < rc; ++i) {
2298 PUSHs(sv_2mortal(newSViv(cords[i])));
2303 i_tt_has_chars(handle, text_sv, utf8)
2304 Imager::Font::TT handle
2315 text = SvPV(text_sv, len);
2317 if (SvUTF8(text_sv))
2320 work = mymalloc(len);
2321 count = i_tt_has_chars(handle, text, len, utf8, work);
2322 if (GIMME_V == G_ARRAY) {
2324 for (i = 0; i < count; ++i) {
2325 PUSHs(boolSV(work[i]));
2330 PUSHs(sv_2mortal(newSVpv(work, count)));
2335 i_tt_dump_names(handle)
2336 Imager::Font::TT handle
2339 i_tt_face_name(handle)
2340 Imager::Font::TT handle
2345 len = i_tt_face_name(handle, name, sizeof(name));
2348 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2352 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2353 Imager::Font::TT handle
2365 text = SvPV(text_sv, work_len);
2367 if (SvUTF8(text_sv))
2374 ch = i_utf8_advance(&text, &len);
2376 i_push_error(0, "invalid UTF8 character");
2384 EXTEND(SP, count+1);
2385 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2386 ST(count) = sv_2mortal(newSVpv(name, 0));
2389 ST(count) = &PL_sv_undef;
2398 i_test_format_probe(ig, length)
2403 i_readpnm_wiol(ig, allow_incomplete)
2405 int allow_incomplete
2409 i_readpnm_multi_wiol(ig, allow_incomplete)
2411 int allow_incomplete
2417 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2420 for (i = 0; i < count; ++i) {
2421 SV *sv = sv_newmortal();
2422 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2429 i_writeppm_wiol(im, ig)
2438 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2447 i_writeraw_wiol(im,ig)
2452 i_writebmp_wiol(im,ig)
2457 i_readbmp_wiol(ig, allow_incomplete=0)
2459 int allow_incomplete
2463 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2472 idlen = SvCUR(ST(4));
2473 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2479 i_readtga_wiol(ig, length)
2487 i_scaleaxis(im,Value,Axis)
2493 i_scale_nn(im,scx,scy)
2499 i_scale_mixing(im, width, height)
2509 i_count_colors(im,maxc)
2514 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2519 unsigned int * col_usage = NULL;
2522 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2523 EXTEND(SP, col_cnt);
2524 for (i = 0; i < col_cnt; i++) {
2525 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2532 i_transform(im,opx,opy,parm)
2546 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2547 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2548 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2549 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2550 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2551 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2552 av=(AV*)SvRV(ST(1));
2554 opx=mymalloc( opxl*sizeof(int) );
2555 for(i=0;i<opxl;i++) {
2556 sv1=(*(av_fetch(av,i,0)));
2557 opx[i]=(int)SvIV(sv1);
2559 av=(AV*)SvRV(ST(2));
2561 opy=mymalloc( opyl*sizeof(int) );
2562 for(i=0;i<opyl;i++) {
2563 sv1=(*(av_fetch(av,i,0)));
2564 opy[i]=(int)SvIV(sv1);
2566 av=(AV*)SvRV(ST(3));
2567 parmlen=av_len(av)+1;
2568 parm=mymalloc( parmlen*sizeof(double) );
2569 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2570 sv1=(*(av_fetch(av,i,0)));
2571 parm[i]=(double)SvNV(sv1);
2573 result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2578 SV *result_sv = sv_newmortal();
2580 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2585 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2611 in_imgs_count = av_len(av_in_imgs)+1;
2612 for (i = 0; i < in_imgs_count; ++i) {
2613 sv1 = *av_fetch(av_in_imgs, i, 0);
2614 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2615 croak("sv_in_img must contain only images");
2618 if (in_imgs_count > 0) {
2619 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2620 for (i = 0; i < in_imgs_count; ++i) {
2621 sv1 = *av_fetch(av_in_imgs,i,0);
2622 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2623 croak("Parameter 5 must contain only images");
2625 tmp = SvIV((SV*)SvRV(sv1));
2626 in_imgs[i] = INT2PTR(i_img*, tmp);
2630 /* no input images */
2633 /* default the output size from the first input if possible */
2635 width = SvIV(sv_width);
2636 else if (in_imgs_count)
2637 width = in_imgs[0]->xsize;
2639 croak("No output image width supplied");
2641 if (SvOK(sv_height))
2642 height = SvIV(sv_height);
2643 else if (in_imgs_count)
2644 height = in_imgs[0]->ysize;
2646 croak("No output image height supplied");
2648 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2649 if (ops_len % sizeof(struct rm_op))
2650 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2651 ops_count = ops_len / sizeof(struct rm_op);
2653 n_regs_count = av_len(av_n_regs)+1;
2654 n_regs = mymalloc(n_regs_count * sizeof(double));
2655 for (i = 0; i < n_regs_count; ++i) {
2656 sv1 = *av_fetch(av_n_regs,i,0);
2658 n_regs[i] = SvNV(sv1);
2660 c_regs_count = av_len(av_c_regs)+1;
2661 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2662 /* I don't bother initializing the colou?r registers */
2664 result=i_transform2(width, height, channels, ops, ops_count,
2665 n_regs, n_regs_count,
2666 c_regs, c_regs_count, in_imgs, in_imgs_count);
2672 SV *result_sv = sv_newmortal();
2674 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2680 i_contrast(im,intensity)
2693 i_noise(im,amount,type)
2699 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2709 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2728 i_postlevels(im,levels)
2738 i_watermark(im,wmark,tx,ty,pixdiff)
2740 Imager::ImgRaw wmark
2747 i_autolevels(im,lsat,usat,skew)
2754 i_radnoise(im,xo,yo,rscale,ascale)
2762 i_turbnoise(im, xo, yo, scale)
2785 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2786 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2787 croak("i_gradgen: Second argument must be an array ref");
2788 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2789 croak("i_gradgen: Third argument must be an array ref");
2790 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2791 croak("i_gradgen: Fourth argument must be an array ref");
2792 axx = (AV *)SvRV(ST(1));
2793 ayy = (AV *)SvRV(ST(2));
2794 ac = (AV *)SvRV(ST(3));
2795 dmeasure = (int)SvIV(ST(4));
2797 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2798 num = num <= av_len(ac) ? num : av_len(ac);
2800 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2801 xo = mymalloc( sizeof(i_img_dim) * num );
2802 yo = mymalloc( sizeof(i_img_dim) * num );
2803 ival = mymalloc( sizeof(i_color) * num );
2804 for(i = 0; i<num; i++) {
2805 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2806 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2807 sv = *av_fetch(ac, i, 0);
2808 if ( !sv_derived_from(sv, "Imager::Color") ) {
2809 free(axx); free(ayy); free(ac);
2810 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2812 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2814 i_gradgen(im, num, xo, yo, ival, dmeasure);
2820 i_diff_image(im, im2, mindist=0)
2826 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2836 double ssample_param
2840 i_fountain_seg *segs;
2842 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2843 croak("i_fountain: argument 11 must be an array ref");
2845 asegs = (AV *)SvRV(ST(10));
2846 segs = load_fount_segs(aTHX_ asegs, &count);
2847 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2848 super_sample, ssample_param, count, segs);
2854 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2863 double ssample_param
2867 i_fountain_seg *segs;
2869 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2870 croak("i_fountain: argument 11 must be an array ref");
2872 asegs = (AV *)SvRV(ST(9));
2873 segs = load_fount_segs(aTHX_ asegs, &count);
2874 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2875 super_sample, ssample_param, count, segs);
2881 i_new_fill_opacity(other_fill, alpha_mult)
2882 Imager::FillHandle other_fill
2893 errors = i_errors();
2895 while (errors[i].msg) {
2897 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2898 if (!av_store(av, 0, sv)) {
2901 sv = newSViv(errors[i].code);
2902 if (!av_store(av, 1, sv)) {
2905 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2913 i_push_error(code, msg)
2918 i_nearest_color(im, ...)
2933 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2934 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2935 croak("i_nearest_color: Second argument must be an array ref");
2936 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2937 croak("i_nearest_color: Third argument must be an array ref");
2938 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2939 croak("i_nearest_color: Fourth argument must be an array ref");
2940 axx = (AV *)SvRV(ST(1));
2941 ayy = (AV *)SvRV(ST(2));
2942 ac = (AV *)SvRV(ST(3));
2943 dmeasure = (int)SvIV(ST(4));
2945 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2946 num = num <= av_len(ac) ? num : av_len(ac);
2948 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2949 xo = mymalloc( sizeof(i_img_dim) * num );
2950 yo = mymalloc( sizeof(i_img_dim) * num );
2951 ival = mymalloc( sizeof(i_color) * num );
2952 for(i = 0; i<num; i++) {
2953 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2954 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2955 sv = *av_fetch(ac, i, 0);
2956 if ( !sv_derived_from(sv, "Imager::Color") ) {
2957 free(axx); free(ayy); free(ac);
2958 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2960 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2962 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2976 rc=DSO_open(filename,&evstr);
2980 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2981 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2984 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2990 DSO_close(dso_handle)
2994 DSO_funclist(dso_handle_v)
2998 DSO_handle *dso_handle;
2999 func_ptr *functions;
3001 dso_handle=(DSO_handle*)dso_handle_v;
3002 functions = DSO_funclist(dso_handle);
3004 while( functions[i].name != NULL) {
3006 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3008 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3012 DSO_call(handle,func_index,hv)
3018 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3019 hv=(HV*)SvRV(ST(2));
3020 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3021 DSO_call( (DSO_handle *)handle,func_index,hv);
3024 i_get_pixel(im, x, y)
3031 color = (i_color *)mymalloc(sizeof(i_color));
3032 if (i_gpix(im, x, y, color) == 0) {
3033 RETVAL = NEWSV(0, 0);
3034 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3038 RETVAL = &PL_sv_undef;
3045 i_ppix(im, x, y, cl)
3052 i_img_pal_new(x, y, channels, maxpal)
3059 i_img_to_pal(src, quant)
3065 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3066 croak("i_img_to_pal: second argument must be a hash ref");
3067 hv = (HV *)SvRV(ST(1));
3068 memset(&quant, 0, sizeof(quant));
3070 quant.mc_size = 256;
3071 ip_handle_quant_opts(aTHX_ &quant, hv);
3072 RETVAL = i_img_to_pal(src, &quant);
3074 ip_copy_colors_back(aTHX_ hv, &quant);
3076 ip_cleanup_quant_opts(aTHX_ &quant);
3085 i_img_make_palette(HV *quant_hv, ...)
3087 size_t count = items - 1;
3089 i_img **imgs = NULL;
3093 croak("Please supply at least one image (%d)", (int)count);
3094 imgs = mymalloc(sizeof(i_img *) * count);
3095 for (i = 0; i < count; ++i) {
3096 SV *img_sv = ST(i + 1);
3097 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3098 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3102 croak("Image %d is not an image object", (int)i+1);
3105 memset(&quant, 0, sizeof(quant));
3107 quant.mc_size = 256;
3108 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3109 i_quant_makemap(&quant, imgs, count);
3110 EXTEND(SP, quant.mc_count);
3111 for (i = 0; i < quant.mc_count; ++i) {
3112 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3115 ip_cleanup_quant_opts(aTHX_ &quant);
3129 work = mymalloc((r-l) * sizeof(i_palidx));
3130 count = i_gpal(im, l, r, y, work);
3131 if (GIMME_V == G_ARRAY) {
3133 for (i = 0; i < count; ++i) {
3134 PUSHs(sv_2mortal(newSViv(work[i])));
3139 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3144 if (GIMME_V != G_ARRAY) {
3146 PUSHs(&PL_sv_undef);
3151 i_ppal(im, l, y, ...)
3160 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3161 for (i=0; i < items-3; ++i) {
3162 work[i] = SvIV(ST(i+3));
3164 validate_i_ppal(im, work, items - 3);
3165 RETVAL = i_ppal(im, l, l+items-3, y, work);
3174 i_ppal_p(im, l, y, data)
3180 i_palidx const *work;
3183 work = (i_palidx const *)SvPV(data, len);
3184 len /= sizeof(i_palidx);
3186 validate_i_ppal(im, work, len);
3187 RETVAL = i_ppal(im, l, l+len, y, work);
3196 i_addcolors(im, ...)
3204 croak("i_addcolors: no colors to add");
3205 colors = mymalloc((items-1) * sizeof(i_color));
3206 for (i=0; i < items-1; ++i) {
3207 if (sv_isobject(ST(i+1))
3208 && sv_derived_from(ST(i+1), "Imager::Color")) {
3209 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3210 colors[i] = *INT2PTR(i_color *, tmp);
3214 croak("i_addcolor: pixels must be Imager::Color objects");
3217 index = i_addcolors(im, colors, items-1);
3220 RETVAL = newSVpv("0 but true", 0);
3222 else if (index == -1) {
3223 RETVAL = &PL_sv_undef;
3226 RETVAL = newSViv(index);
3232 i_setcolors(im, index, ...)
3240 croak("i_setcolors: no colors to add");
3241 colors = mymalloc((items-2) * sizeof(i_color));
3242 for (i=0; i < items-2; ++i) {
3243 if (sv_isobject(ST(i+2))
3244 && sv_derived_from(ST(i+2), "Imager::Color")) {
3245 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3246 colors[i] = *INT2PTR(i_color *, tmp);
3250 croak("i_setcolors: pixels must be Imager::Color objects");
3253 RETVAL = i_setcolors(im, index, colors, items-2);
3259 i_getcolors(im, index, ...)
3268 croak("i_getcolors: too many arguments");
3270 count = SvIV(ST(2));
3272 croak("i_getcolors: count must be positive");
3273 colors = mymalloc(sizeof(i_color) * count);
3274 if (i_getcolors(im, index, colors, count)) {
3275 for (i = 0; i < count; ++i) {
3276 SV *sv = make_i_color_sv(aTHX_ colors+i);
3292 i_findcolor(im, color)
3298 if (i_findcolor(im, color, &index)) {
3299 RETVAL = newSViv(index);
3302 RETVAL = &PL_sv_undef;
3320 i_gsamp(im, l, r, y, channels)
3325 i_channel_list channels
3331 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
3332 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3333 if (GIMME_V == G_ARRAY) {
3335 for (i = 0; i < count; ++i)
3336 PUSHs(sv_2mortal(newSViv(data[i])));
3340 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3345 if (GIMME_V != G_ARRAY) {
3347 PUSHs(&PL_sv_undef);
3352 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3360 i_channel_list channels
3367 croak("No channel numbers supplied to g_samp()");
3369 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3370 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3371 for (i = 0; i < count; ++i) {
3372 av_store(target, i+offset, newSVuv(data[i]));
3384 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3389 i_channel_list channels
3391 i_img_dim data_offset
3392 i_img_dim pixel_count
3401 data_count = av_len(data_av) + 1;
3402 if (data_offset < 0) {
3403 croak("data_offset must be non-negative");
3405 if (data_offset > data_count) {
3406 croak("data_offset greater than number of samples supplied");
3408 if (pixel_count == -1 ||
3409 data_offset + pixel_count * channels.count > data_count) {
3410 pixel_count = (data_count - data_offset) / channels.count;
3413 data_used = pixel_count * channels.count;
3414 data = mymalloc(sizeof(unsigned) * data_count);
3415 for (i = 0; i < data_used; ++i)
3416 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3418 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3419 channels.count, bits);
3427 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3431 i_channel_list channels
3440 i_push_error(0, "offset must be non-negative");
3444 if (offset > data.count) {
3445 i_push_error(0, "offset greater than number of samples supplied");
3448 data.samples += offset;
3449 data.count -= offset;
3452 width * channels.count > data.count) {
3453 width = data.count / channels.count;
3456 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3461 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3465 i_channel_list channels
3474 i_push_error(0, "offset must be non-negative");
3478 if (offset > data.count) {
3479 i_push_error(0, "offset greater than number of samples supplied");
3482 data.samples += offset;
3483 data.count -= offset;
3486 width * channels.count > data.count) {
3487 width = data.count / channels.count;
3490 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3495 i_img_masked_new(targ, mask, x, y, w, h)
3505 if (!sv_isobject(ST(1))
3506 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3507 croak("i_img_masked_new: parameter 2 must undef or an image");
3509 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3513 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3518 i_plin(im, l, y, ...)
3529 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3530 /* supplied as a byte string */
3531 work = (i_color *)SvPV(ST(3), len);
3532 count = len / sizeof(i_color);
3533 if (count * sizeof(i_color) != len) {
3534 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3536 RETVAL = i_plin(im, l, l+count, y, work);
3539 work = mymalloc(sizeof(i_color) * (items-3));
3540 for (i=0; i < items-3; ++i) {
3541 if (sv_isobject(ST(i+3))
3542 && sv_derived_from(ST(i+3), "Imager::Color")) {
3543 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3544 work[i] = *INT2PTR(i_color *, tmp);
3548 croak("i_plin: pixels must be Imager::Color objects");
3551 RETVAL = i_plin(im, l, l+items-3, y, work);
3562 i_ppixf(im, x, y, cl)
3566 Imager::Color::Float cl
3569 i_gsampf(im, l, r, y, channels)
3574 i_channel_list channels
3580 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3581 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3582 if (GIMME_V == G_ARRAY) {
3584 for (i = 0; i < count; ++i)
3585 PUSHs(sv_2mortal(newSVnv(data[i])));
3589 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3594 if (GIMME_V != G_ARRAY) {
3596 PUSHs(&PL_sv_undef);
3601 i_plinf(im, l, y, ...)
3612 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3613 /* supplied as a byte string */
3614 work = (i_fcolor *)SvPV(ST(3), len);
3615 count = len / sizeof(i_fcolor);
3616 if (count * sizeof(i_fcolor) != len) {
3617 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3619 RETVAL = i_plinf(im, l, l+count, y, work);
3622 work = mymalloc(sizeof(i_fcolor) * (items-3));
3623 for (i=0; i < items-3; ++i) {
3624 if (sv_isobject(ST(i+3))
3625 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3626 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3627 work[i] = *INT2PTR(i_fcolor *, tmp);
3631 croak("i_plinf: pixels must be Imager::Color::Float objects");
3635 RETVAL = i_plinf(im, l, l+items-3, y, work);
3653 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3654 if (i_gpixf(im, x, y, color) == 0) {
3655 RETVAL = NEWSV(0,0);
3656 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3660 RETVAL = &PL_sv_undef;
3676 vals = mymalloc((r-l) * sizeof(i_color));
3677 memset(vals, 0, (r-l) * sizeof(i_color));
3678 count = i_glin(im, l, r, y, vals);
3679 if (GIMME_V == G_ARRAY) {
3681 for (i = 0; i < count; ++i) {
3682 SV *sv = make_i_color_sv(aTHX_ vals+i);
3688 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3694 i_glinf(im, l, r, y)
3704 for (i = 0; i < MAXCHANNELS; ++i)
3705 zero.channel[i] = 0;
3707 vals = mymalloc((r-l) * sizeof(i_fcolor));
3708 for (i = 0; i < r-l; ++i)
3710 count = i_glinf(im, l, r, y, vals);
3711 if (GIMME_V == G_ARRAY) {
3713 for (i = 0; i < count; ++i) {
3715 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3717 sv = sv_newmortal();
3718 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3724 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3730 i_img_8_new(x, y, ch)
3736 i_img_16_new(x, y, ch)
3746 i_img_double_new(x, y, ch)
3756 i_tags_addn(im, name, code, idata)
3765 name = SvPV(ST(1), len);
3768 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3773 i_tags_add(im, name, code, data, idata)
3783 name = SvPV(ST(1), len);
3787 data = SvPV(ST(3), len);
3792 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3797 i_tags_find(im, name, start)
3804 if (i_tags_find(&im->tags, name, start, &entry)) {
3806 RETVAL = newSVpv("0 but true", 0);
3808 RETVAL = newSViv(entry);
3810 RETVAL = &PL_sv_undef;
3816 i_tags_findn(im, code, start)
3823 if (i_tags_findn(&im->tags, code, start, &entry)) {
3825 RETVAL = newSVpv("0 but true", 0);
3827 RETVAL = newSViv(entry);
3830 RETVAL = &PL_sv_undef;
3836 i_tags_delete(im, entry)
3840 RETVAL = i_tags_delete(&im->tags, entry);
3845 i_tags_delbyname(im, name)
3849 RETVAL = i_tags_delbyname(&im->tags, name);
3854 i_tags_delbycode(im, code)
3858 RETVAL = i_tags_delbycode(&im->tags, code);
3863 i_tags_get(im, index)
3867 if (index >= 0 && index < im->tags.count) {
3868 i_img_tag *entry = im->tags.tags + index;
3872 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3875 PUSHs(sv_2mortal(newSViv(entry->code)));
3878 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3881 PUSHs(sv_2mortal(newSViv(entry->idata)));
3886 i_tags_get_string(im, what_sv)
3890 char const *name = NULL;
3894 if (SvIOK(what_sv)) {
3895 code = SvIV(what_sv);
3899 name = SvPV_nolen(what_sv);
3902 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3904 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3911 RETVAL = im->tags.count;
3917 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3921 Imager::FillHandle fill
3924 IFILL_CLONE_SKIP(...)
3926 (void)items; /* avoid unused warning for XS variable */
3931 MODULE = Imager PACKAGE = Imager
3934 i_new_fill_solid(cl, combine)
3939 i_new_fill_solidf(cl, combine)
3940 Imager::Color::Float cl
3944 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3952 unsigned char *cust_hatch;
3956 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3960 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3965 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3966 Imager::Color::Float fg
3967 Imager::Color::Float bg
3973 unsigned char *cust_hatch;
3977 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3981 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3986 i_new_fill_image(src, matrix, xoff, yoff, combine)
4003 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4004 croak("i_new_fill_image: parameter must be an arrayref");
4005 av=(AV*)SvRV(ST(1));
4009 for (i = 0; i < len; ++i) {
4010 sv1=(*(av_fetch(av,i,0)));
4011 matrix[i] = SvNV(sv1);
4017 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4021 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4023 # this class is only exposed for testing
4026 i_int_hlines_testing()
4028 #if i_int_hlines_testing()
4030 Imager::Internal::Hlines
4031 i_int_hlines_new(start_y, count_y, start_x, count_x)
4037 Imager::Internal::Hlines
4038 i_int_hlines_new_img(im)
4042 i_int_hlines_add(hlines, y, minx, width)
4043 Imager::Internal::Hlines hlines
4049 i_int_hlines_DESTROY(hlines)
4050 Imager::Internal::Hlines hlines
4053 i_int_hlines_dump(hlines)
4054 Imager::Internal::Hlines hlines
4057 i_int_hlines_CLONE_SKIP(cls)
4061 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4064 im_context_DESTROY(ctx)
4067 #ifdef PERL_IMPLICIT_CONTEXT
4070 im_context_CLONE(...)
4074 /* the following sv_setref_pv() will free this inc */
4075 im_context_refinc(MY_CXT.ctx, "CLONE");
4076 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4077 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4082 PERL_SET_GLOBAL_CALLBACKS;
4083 PERL_PL_SET_GLOBAL_CALLBACKS;
4084 #ifdef PERL_IMPLICIT_CONTEXT
4090 start_context(aTHX);
4091 im_get_context = perl_get_context;