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)
1202 if (SvUTF8(data_sv)) {
1203 data_sv = sv_2mortal(newSVsv(data_sv));
1204 /* yes, we want this to croak() if the SV can't be downgraded */
1205 sv_utf8_downgrade(data_sv, FALSE);
1208 data = SvPV(data_sv, size);
1209 RETVAL = i_io_raw_write(ig, data, size);
1214 i_io_raw_read(ig, buffer_sv, size)
1223 croak("size negative in call to i_io_raw_read()");
1224 /* prevent an undefined value warning if they supplied an
1226 Orginally conditional on !SvOK(), but this will prevent the
1227 downgrade from croaking */
1228 sv_setpvn(buffer_sv, "", 0);
1230 if (SvUTF8(buffer_sv))
1231 sv_utf8_downgrade(buffer_sv, FALSE);
1233 buffer = SvGROW(buffer_sv, size+1);
1234 result = i_io_raw_read(ig, buffer, size);
1236 SvCUR_set(buffer_sv, result);
1237 *SvEND(buffer_sv) = '\0';
1238 SvPOK_only(buffer_sv);
1240 PUSHs(sv_2mortal(newSViv(result)));
1246 i_io_raw_read2(ig, size)
1255 croak("size negative in call to i_io_read2()");
1256 buffer_sv = newSV(size);
1257 buffer = SvGROW(buffer_sv, size+1);
1258 result = i_io_raw_read(ig, buffer, size);
1260 SvCUR_set(buffer_sv, result);
1261 *SvEND(buffer_sv) = '\0';
1262 SvPOK_only(buffer_sv);
1264 PUSHs(sv_2mortal(buffer_sv));
1268 SvREFCNT_dec(buffer_sv);
1272 i_io_raw_seek(ig, position, whence)
1286 i_io_CLONE_SKIP(...)
1288 (void)items; /* avoid unused warning for XS variable */
1315 i_io_seek(ig, off, whence)
1321 i_io_peekn(ig, size)
1329 buffer_sv = newSV(size+1);
1330 buffer = SvGROW(buffer_sv, size+1);
1331 result = i_io_peekn(ig, buffer, size);
1333 SvCUR_set(buffer_sv, result);
1334 *SvEND(buffer_sv) = '\0';
1335 SvPOK_only(buffer_sv);
1337 PUSHs(sv_2mortal(buffer_sv));
1341 SvREFCNT_dec(buffer_sv);
1345 i_io_read(ig, buffer_sv, size)
1354 croak("size negative in call to i_io_read()");
1355 /* prevent an undefined value warning if they supplied an
1357 Orginally conditional on !SvOK(), but this will prevent the
1358 downgrade from croaking */
1359 sv_setpvn(buffer_sv, "", 0);
1361 if (SvUTF8(buffer_sv))
1362 sv_utf8_downgrade(buffer_sv, FALSE);
1364 buffer = SvGROW(buffer_sv, size+1);
1365 result = i_io_read(ig, buffer, size);
1367 SvCUR_set(buffer_sv, result);
1368 *SvEND(buffer_sv) = '\0';
1369 SvPOK_only(buffer_sv);
1371 PUSHs(sv_2mortal(newSViv(result)));
1377 i_io_read2(ig, size)
1386 croak("size zero in call to read2()");
1387 buffer_sv = newSV(size);
1388 buffer = SvGROW(buffer_sv, size+1);
1389 result = i_io_read(ig, buffer, size);
1391 SvCUR_set(buffer_sv, result);
1392 *SvEND(buffer_sv) = '\0';
1393 SvPOK_only(buffer_sv);
1395 PUSHs(sv_2mortal(buffer_sv));
1399 SvREFCNT_dec(buffer_sv);
1403 i_io_gets(ig, size = 8192, eol = NEWLINE)
1413 croak("size too small in call to gets()");
1414 buffer_sv = sv_2mortal(newSV(size+1));
1415 buffer = SvPVX(buffer_sv);
1416 result = i_io_gets(ig, buffer, size+1, eol);
1418 SvCUR_set(buffer_sv, result);
1419 *SvEND(buffer_sv) = '\0';
1420 SvPOK_only(buffer_sv);
1426 i_io_write(ig, data_sv)
1434 if (SvUTF8(data_sv)) {
1435 data_sv = sv_2mortal(newSVsv(data_sv));
1436 /* yes, we want this to croak() if the SV can't be downgraded */
1437 sv_utf8_downgrade(data_sv, FALSE);
1440 data = SvPV(data_sv, size);
1441 RETVAL = i_io_write(ig, data, size);
1446 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1451 i_io_set_buffered(ig, flag = 1)
1456 i_io_is_buffered(ig)
1467 MODULE = Imager PACKAGE = Imager
1478 while( (item=i_format_list[i++]) != NULL ) {
1480 PUSHs(sv_2mortal(newSVpv(item,0)));
1484 i_sametype(im, x, y)
1490 i_sametype_chans(im, x, y, channels)
1497 i_init_log(name_sv,level)
1501 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1503 RETVAL = i_init_log(name, level);
1508 i_log_entry(string,level)
1521 i_img_info(im,info);
1523 PUSHs(sv_2mortal(newSViv(info[0])));
1524 PUSHs(sv_2mortal(newSViv(info[1])));
1525 PUSHs(sv_2mortal(newSViv(info[2])));
1526 PUSHs(sv_2mortal(newSViv(info[3])));
1532 i_img_setmask(im,ch_mask)
1541 i_img_getchannels(im)
1550 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1558 i_img_get_height(im)
1563 i_img_is_monochrome(im)
1569 result = i_img_is_monochrome(im, &zero_is_white);
1571 if (GIMME_V == G_ARRAY) {
1574 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1583 i_line(im,x1,y1,x2,y2,val,endp)
1593 i_line_aa(im,x1,y1,x2,y2,val,endp)
1603 i_box(im,x1,y1,x2,y2,val)
1612 i_box_filled(im,x1,y1,x2,y2,val)
1621 i_box_filledf(im,x1,y1,x2,y2,val)
1627 Imager::Color::Float val
1630 i_box_cfill(im,x1,y1,x2,y2,fill)
1636 Imager::FillHandle fill
1639 i_arc(im,x,y,rad,d1,d2,val)
1649 i_arc_aa(im,x,y,rad,d1,d2,val)
1659 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1666 Imager::FillHandle fill
1669 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1676 Imager::FillHandle fill
1680 i_circle_aa(im,x,y,rad,val)
1688 i_circle_out(im,x,y,rad,val)
1696 i_circle_out_aa(im,x,y,rad,val)
1704 i_arc_out(im,x,y,rad,d1,d2,val)
1714 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1725 i_bezier_multi(im,xc,yc,val)
1738 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1739 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1740 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1741 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1742 av1=(AV*)SvRV(ST(1));
1743 av2=(AV*)SvRV(ST(2));
1744 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1746 x=mymalloc( len*sizeof(double) );
1747 y=mymalloc( len*sizeof(double) );
1748 for(i=0;i<len;i++) {
1749 sv1=(*(av_fetch(av1,i,0)));
1750 sv2=(*(av_fetch(av2,i,0)));
1751 x[i]=(double)SvNV(sv1);
1752 y[i]=(double)SvNV(sv2);
1754 i_bezier_multi(im,len,x,y,val);
1760 i_poly_aa(im,xc,yc,val)
1773 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1774 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1775 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1776 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1777 av1=(AV*)SvRV(ST(1));
1778 av2=(AV*)SvRV(ST(2));
1779 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1781 x=mymalloc( len*sizeof(double) );
1782 y=mymalloc( len*sizeof(double) );
1783 for(i=0;i<len;i++) {
1784 sv1=(*(av_fetch(av1,i,0)));
1785 sv2=(*(av_fetch(av2,i,0)));
1786 x[i]=(double)SvNV(sv1);
1787 y[i]=(double)SvNV(sv2);
1789 RETVAL = i_poly_aa(im,len,x,y,val);
1796 i_poly_aa_cfill(im,xc,yc,fill)
1798 Imager::FillHandle fill
1808 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1809 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1810 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1811 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1812 av1=(AV*)SvRV(ST(1));
1813 av2=(AV*)SvRV(ST(2));
1814 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1816 x=mymalloc( len*sizeof(double) );
1817 y=mymalloc( len*sizeof(double) );
1818 for(i=0;i<len;i++) {
1819 sv1=(*(av_fetch(av1,i,0)));
1820 sv2=(*(av_fetch(av2,i,0)));
1821 x[i]=(double)SvNV(sv1);
1822 y[i]=(double)SvNV(sv2);
1824 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1833 i_flood_fill(im,seedx,seedy,dcol)
1840 i_flood_cfill(im,seedx,seedy,fill)
1844 Imager::FillHandle fill
1847 i_flood_fill_border(im,seedx,seedy,dcol, border)
1852 Imager::Color border
1855 i_flood_cfill_border(im,seedx,seedy,fill, border)
1859 Imager::FillHandle fill
1860 Imager::Color border
1864 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1876 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1893 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1904 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1917 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)
1933 i_combine(src_av, channels_av = NULL)
1937 i_img **imgs = NULL;
1939 int *channels = NULL;
1944 in_count = av_len(src_av) + 1;
1946 imgs = mymalloc(sizeof(i_img*) * in_count);
1947 channels = mymalloc(sizeof(int) * in_count);
1948 for (i = 0; i < in_count; ++i) {
1949 psv = av_fetch(src_av, i, 0);
1950 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1953 croak("imgs must contain only images");
1955 tmp = SvIV((SV*)SvRV(*psv));
1956 imgs[i] = INT2PTR(i_img*, tmp);
1958 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1960 channels[i] = SvIV(*psv);
1967 RETVAL = i_combine(imgs, channels, in_count);
1974 i_flipxy(im, direction)
1979 i_rotate90(im, degrees)
1984 i_rotate_exact(im, amount, ...)
1988 i_color *backp = NULL;
1989 i_fcolor *fbackp = NULL;
1993 /* extract the bg colors if any */
1994 /* yes, this is kind of strange */
1995 for (i = 2; i < items; ++i) {
1997 if (sv_derived_from(sv1, "Imager::Color")) {
1998 IV tmp = SvIV((SV*)SvRV(sv1));
1999 backp = INT2PTR(i_color *, tmp);
2001 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2002 IV tmp = SvIV((SV*)SvRV(sv1));
2003 fbackp = INT2PTR(i_fcolor *, tmp);
2006 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
2011 i_matrix_transform(im, xsize, ysize, matrix, ...)
2021 i_color *backp = NULL;
2022 i_fcolor *fbackp = NULL;
2024 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
2025 croak("i_matrix_transform: parameter 4 must be an array ref\n");
2026 av=(AV*)SvRV(ST(3));
2030 for (i = 0; i < len; ++i) {
2031 sv1=(*(av_fetch(av,i,0)));
2032 matrix[i] = SvNV(sv1);
2036 /* extract the bg colors if any */
2037 /* yes, this is kind of strange */
2038 for (i = 4; i < items; ++i) {
2040 if (sv_derived_from(sv1, "Imager::Color")) {
2041 IV tmp = SvIV((SV*)SvRV(sv1));
2042 backp = INT2PTR(i_color *, tmp);
2044 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2045 IV tmp = SvIV((SV*)SvRV(sv1));
2046 fbackp = INT2PTR(i_fcolor *, tmp);
2049 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2054 i_gaussian(im,stdev)
2059 i_unsharp_mask(im,stdev,scale)
2074 len = av_len(coef) + 1;
2075 c_coef=mymalloc( len * sizeof(double) );
2076 for(i = 0; i < len; i++) {
2077 sv1 = (*(av_fetch(coef, i, 0)));
2078 c_coef[i] = (double)SvNV(sv1);
2080 RETVAL = i_conv(im, c_coef, len);
2086 i_convert(src, avmain)
2098 outchan = av_len(avmain)+1;
2099 /* find the biggest */
2101 for (j=0; j < outchan; ++j) {
2102 temp = av_fetch(avmain, j, 0);
2103 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2104 avsub = (AV*)SvRV(*temp);
2105 len = av_len(avsub)+1;
2110 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2114 coeff = mymalloc(sizeof(double) * outchan * inchan);
2115 for (j = 0; j < outchan; ++j) {
2116 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2117 len = av_len(avsub)+1;
2118 for (i = 0; i < len; ++i) {
2119 temp = av_fetch(avsub, i, 0);
2121 coeff[i+j*inchan] = SvNV(*temp);
2123 coeff[i+j*inchan] = 0;
2126 coeff[i++ + j*inchan] = 0;
2128 RETVAL = i_convert(src, coeff, outchan, inchan);
2138 unsigned int mask = 0;
2144 unsigned char (*maps)[256];
2146 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2147 croak("i_map: parameter 2 must be an arrayref\n");
2148 avmain = (AV*)SvRV(ST(1));
2149 len = av_len(avmain)+1;
2150 if (im->channels < len) len = im->channels;
2152 maps = mymalloc( len * sizeof(unsigned char [256]) );
2154 for (j=0; j<len ; j++) {
2155 temp = av_fetch(avmain, j, 0);
2156 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2157 avsub = (AV*)SvRV(*temp);
2158 if(av_len(avsub) != 255) continue;
2160 for (i=0; i<256 ; i++) {
2162 temp = av_fetch(avsub, i, 0);
2163 val = temp ? SvIV(*temp) : 0;
2165 if (val>255) val = 255;
2170 i_map(im, maps, mask);
2184 i_img_diffd(im1,im2)
2189 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2199 _is_color_object(sv)
2203 RETVAL = SvOK(sv) && SvROK(sv) &&
2204 (sv_derived_from(sv, "Imager::Color")
2205 || sv_derived_from(sv, "Imager::Color::Float"));
2217 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2219 #define TT_DESTROY(handle) i_tt_destroy(handle)
2223 Imager::Font::TT handle
2228 (void)items; /* avoid unused warning */
2234 MODULE = Imager PACKAGE = Imager
2238 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2239 Imager::Font::TT handle
2253 str = SvPV(str_sv, len);
2258 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2259 len, smooth, utf8, align);
2265 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2266 Imager::Font::TT handle
2280 str = SvPV(str_sv, len);
2285 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2286 smooth, utf8, align);
2292 i_tt_bbox(handle,point,str_sv,utf8)
2293 Imager::Font::TT handle
2298 i_img_dim cords[BOUNDING_BOX_COUNT];
2304 str = SvPV(str_sv, len);
2309 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2311 for (i = 0; i < rc; ++i) {
2312 PUSHs(sv_2mortal(newSViv(cords[i])));
2317 i_tt_has_chars(handle, text_sv, utf8)
2318 Imager::Font::TT handle
2329 text = SvPV(text_sv, len);
2331 if (SvUTF8(text_sv))
2334 work = mymalloc(len);
2335 count = i_tt_has_chars(handle, text, len, utf8, work);
2336 if (GIMME_V == G_ARRAY) {
2338 for (i = 0; i < count; ++i) {
2339 PUSHs(boolSV(work[i]));
2344 PUSHs(sv_2mortal(newSVpv(work, count)));
2349 i_tt_dump_names(handle)
2350 Imager::Font::TT handle
2353 i_tt_face_name(handle)
2354 Imager::Font::TT handle
2359 len = i_tt_face_name(handle, name, sizeof(name));
2362 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2366 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2367 Imager::Font::TT handle
2379 text = SvPV(text_sv, work_len);
2381 if (SvUTF8(text_sv))
2388 ch = i_utf8_advance(&text, &len);
2390 i_push_error(0, "invalid UTF8 character");
2398 EXTEND(SP, count+1);
2399 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2400 ST(count) = sv_2mortal(newSVpv(name, 0));
2403 ST(count) = &PL_sv_undef;
2412 i_test_format_probe(ig, length)
2417 i_readpnm_wiol(ig, allow_incomplete)
2419 int allow_incomplete
2423 i_readpnm_multi_wiol(ig, allow_incomplete)
2425 int allow_incomplete
2431 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2434 for (i = 0; i < count; ++i) {
2435 SV *sv = sv_newmortal();
2436 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2443 i_writeppm_wiol(im, ig)
2452 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2461 i_writeraw_wiol(im,ig)
2466 i_writebmp_wiol(im,ig)
2471 i_readbmp_wiol(ig, allow_incomplete=0)
2473 int allow_incomplete
2477 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2486 idlen = SvCUR(ST(4));
2487 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2493 i_readtga_wiol(ig, length)
2501 i_scaleaxis(im,Value,Axis)
2507 i_scale_nn(im,scx,scy)
2513 i_scale_mixing(im, width, height)
2523 i_count_colors(im,maxc)
2528 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2533 unsigned int * col_usage = NULL;
2536 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2537 EXTEND(SP, col_cnt);
2538 for (i = 0; i < col_cnt; i++) {
2539 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2546 i_transform(im,opx,opy,parm)
2560 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2561 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2562 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2563 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2564 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2565 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2566 av=(AV*)SvRV(ST(1));
2568 opx=mymalloc( opxl*sizeof(int) );
2569 for(i=0;i<opxl;i++) {
2570 sv1=(*(av_fetch(av,i,0)));
2571 opx[i]=(int)SvIV(sv1);
2573 av=(AV*)SvRV(ST(2));
2575 opy=mymalloc( opyl*sizeof(int) );
2576 for(i=0;i<opyl;i++) {
2577 sv1=(*(av_fetch(av,i,0)));
2578 opy[i]=(int)SvIV(sv1);
2580 av=(AV*)SvRV(ST(3));
2581 parmlen=av_len(av)+1;
2582 parm=mymalloc( parmlen*sizeof(double) );
2583 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2584 sv1=(*(av_fetch(av,i,0)));
2585 parm[i]=(double)SvNV(sv1);
2587 result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2592 SV *result_sv = sv_newmortal();
2594 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2599 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2625 in_imgs_count = av_len(av_in_imgs)+1;
2626 for (i = 0; i < in_imgs_count; ++i) {
2627 sv1 = *av_fetch(av_in_imgs, i, 0);
2628 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2629 croak("sv_in_img must contain only images");
2632 if (in_imgs_count > 0) {
2633 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2634 for (i = 0; i < in_imgs_count; ++i) {
2635 sv1 = *av_fetch(av_in_imgs,i,0);
2636 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2637 croak("Parameter 5 must contain only images");
2639 tmp = SvIV((SV*)SvRV(sv1));
2640 in_imgs[i] = INT2PTR(i_img*, tmp);
2644 /* no input images */
2647 /* default the output size from the first input if possible */
2649 width = SvIV(sv_width);
2650 else if (in_imgs_count)
2651 width = in_imgs[0]->xsize;
2653 croak("No output image width supplied");
2655 if (SvOK(sv_height))
2656 height = SvIV(sv_height);
2657 else if (in_imgs_count)
2658 height = in_imgs[0]->ysize;
2660 croak("No output image height supplied");
2662 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2663 if (ops_len % sizeof(struct rm_op))
2664 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2665 ops_count = ops_len / sizeof(struct rm_op);
2667 n_regs_count = av_len(av_n_regs)+1;
2668 n_regs = mymalloc(n_regs_count * sizeof(double));
2669 for (i = 0; i < n_regs_count; ++i) {
2670 sv1 = *av_fetch(av_n_regs,i,0);
2672 n_regs[i] = SvNV(sv1);
2674 c_regs_count = av_len(av_c_regs)+1;
2675 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2676 /* I don't bother initializing the colou?r registers */
2678 result=i_transform2(width, height, channels, ops, ops_count,
2679 n_regs, n_regs_count,
2680 c_regs, c_regs_count, in_imgs, in_imgs_count);
2686 SV *result_sv = sv_newmortal();
2688 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2694 i_contrast(im,intensity)
2707 i_noise(im,amount,type)
2713 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2723 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2742 i_postlevels(im,levels)
2752 i_watermark(im,wmark,tx,ty,pixdiff)
2754 Imager::ImgRaw wmark
2761 i_autolevels(im,lsat,usat,skew)
2768 i_radnoise(im,xo,yo,rscale,ascale)
2776 i_turbnoise(im, xo, yo, scale)
2799 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2800 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2801 croak("i_gradgen: Second argument must be an array ref");
2802 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2803 croak("i_gradgen: Third argument must be an array ref");
2804 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2805 croak("i_gradgen: Fourth argument must be an array ref");
2806 axx = (AV *)SvRV(ST(1));
2807 ayy = (AV *)SvRV(ST(2));
2808 ac = (AV *)SvRV(ST(3));
2809 dmeasure = (int)SvIV(ST(4));
2811 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2812 num = num <= av_len(ac) ? num : av_len(ac);
2814 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2815 xo = mymalloc( sizeof(i_img_dim) * num );
2816 yo = mymalloc( sizeof(i_img_dim) * num );
2817 ival = mymalloc( sizeof(i_color) * num );
2818 for(i = 0; i<num; i++) {
2819 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2820 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2821 sv = *av_fetch(ac, i, 0);
2822 if ( !sv_derived_from(sv, "Imager::Color") ) {
2823 free(axx); free(ayy); free(ac);
2824 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2826 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2828 i_gradgen(im, num, xo, yo, ival, dmeasure);
2834 i_diff_image(im, im2, mindist=0)
2840 i_fountain(im, 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(10)) || ! SvTYPE(SvRV(ST(10))))
2857 croak("i_fountain: argument 11 must be an array ref");
2859 asegs = (AV *)SvRV(ST(10));
2860 segs = load_fount_segs(aTHX_ asegs, &count);
2861 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2862 super_sample, ssample_param, count, segs);
2868 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2877 double ssample_param
2881 i_fountain_seg *segs;
2883 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2884 croak("i_fountain: argument 11 must be an array ref");
2886 asegs = (AV *)SvRV(ST(9));
2887 segs = load_fount_segs(aTHX_ asegs, &count);
2888 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2889 super_sample, ssample_param, count, segs);
2895 i_new_fill_opacity(other_fill, alpha_mult)
2896 Imager::FillHandle other_fill
2907 errors = i_errors();
2909 while (errors[i].msg) {
2911 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2912 if (!av_store(av, 0, sv)) {
2915 sv = newSViv(errors[i].code);
2916 if (!av_store(av, 1, sv)) {
2919 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2927 i_push_error(code, msg)
2932 i_nearest_color(im, ...)
2947 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2948 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2949 croak("i_nearest_color: Second argument must be an array ref");
2950 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2951 croak("i_nearest_color: Third argument must be an array ref");
2952 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2953 croak("i_nearest_color: Fourth argument must be an array ref");
2954 axx = (AV *)SvRV(ST(1));
2955 ayy = (AV *)SvRV(ST(2));
2956 ac = (AV *)SvRV(ST(3));
2957 dmeasure = (int)SvIV(ST(4));
2959 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2960 num = num <= av_len(ac) ? num : av_len(ac);
2962 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2963 xo = mymalloc( sizeof(i_img_dim) * num );
2964 yo = mymalloc( sizeof(i_img_dim) * num );
2965 ival = mymalloc( sizeof(i_color) * num );
2966 for(i = 0; i<num; i++) {
2967 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2968 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2969 sv = *av_fetch(ac, i, 0);
2970 if ( !sv_derived_from(sv, "Imager::Color") ) {
2971 free(axx); free(ayy); free(ac);
2972 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2974 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2976 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2990 rc=DSO_open(filename,&evstr);
2994 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2995 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2998 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3004 DSO_close(dso_handle)
3008 DSO_funclist(dso_handle_v)
3012 DSO_handle *dso_handle;
3013 func_ptr *functions;
3015 dso_handle=(DSO_handle*)dso_handle_v;
3016 functions = DSO_funclist(dso_handle);
3018 while( functions[i].name != NULL) {
3020 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3022 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3026 DSO_call(handle,func_index,hv)
3032 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3033 hv=(HV*)SvRV(ST(2));
3034 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3035 DSO_call( (DSO_handle *)handle,func_index,hv);
3038 i_get_pixel(im, x, y)
3045 color = (i_color *)mymalloc(sizeof(i_color));
3046 if (i_gpix(im, x, y, color) == 0) {
3047 RETVAL = NEWSV(0, 0);
3048 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3052 RETVAL = &PL_sv_undef;
3059 i_ppix(im, x, y, cl)
3066 i_img_pal_new(x, y, channels, maxpal)
3073 i_img_to_pal(src, quant)
3079 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3080 croak("i_img_to_pal: second argument must be a hash ref");
3081 hv = (HV *)SvRV(ST(1));
3082 memset(&quant, 0, sizeof(quant));
3084 quant.mc_size = 256;
3085 ip_handle_quant_opts(aTHX_ &quant, hv);
3086 RETVAL = i_img_to_pal(src, &quant);
3088 ip_copy_colors_back(aTHX_ hv, &quant);
3090 ip_cleanup_quant_opts(aTHX_ &quant);
3099 i_img_make_palette(HV *quant_hv, ...)
3101 size_t count = items - 1;
3103 i_img **imgs = NULL;
3107 croak("Please supply at least one image (%d)", (int)count);
3108 imgs = mymalloc(sizeof(i_img *) * count);
3109 for (i = 0; i < count; ++i) {
3110 SV *img_sv = ST(i + 1);
3111 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3112 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3116 croak("Image %d is not an image object", (int)i+1);
3119 memset(&quant, 0, sizeof(quant));
3121 quant.mc_size = 256;
3122 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3123 i_quant_makemap(&quant, imgs, count);
3124 EXTEND(SP, quant.mc_count);
3125 for (i = 0; i < quant.mc_count; ++i) {
3126 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3129 ip_cleanup_quant_opts(aTHX_ &quant);
3143 work = mymalloc((r-l) * sizeof(i_palidx));
3144 count = i_gpal(im, l, r, y, work);
3145 if (GIMME_V == G_ARRAY) {
3147 for (i = 0; i < count; ++i) {
3148 PUSHs(sv_2mortal(newSViv(work[i])));
3153 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3158 if (GIMME_V != G_ARRAY) {
3160 PUSHs(&PL_sv_undef);
3165 i_ppal(im, l, y, ...)
3174 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3175 for (i=0; i < items-3; ++i) {
3176 work[i] = SvIV(ST(i+3));
3178 validate_i_ppal(im, work, items - 3);
3179 RETVAL = i_ppal(im, l, l+items-3, y, work);
3188 i_ppal_p(im, l, y, data)
3194 i_palidx const *work;
3197 work = (i_palidx const *)SvPV(data, len);
3198 len /= sizeof(i_palidx);
3200 validate_i_ppal(im, work, len);
3201 RETVAL = i_ppal(im, l, l+len, y, work);
3210 i_addcolors(im, ...)
3218 croak("i_addcolors: no colors to add");
3219 colors = mymalloc((items-1) * sizeof(i_color));
3220 for (i=0; i < items-1; ++i) {
3221 if (sv_isobject(ST(i+1))
3222 && sv_derived_from(ST(i+1), "Imager::Color")) {
3223 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3224 colors[i] = *INT2PTR(i_color *, tmp);
3228 croak("i_addcolor: pixels must be Imager::Color objects");
3231 index = i_addcolors(im, colors, items-1);
3234 RETVAL = newSVpv("0 but true", 0);
3236 else if (index == -1) {
3237 RETVAL = &PL_sv_undef;
3240 RETVAL = newSViv(index);
3246 i_setcolors(im, index, ...)
3254 croak("i_setcolors: no colors to add");
3255 colors = mymalloc((items-2) * sizeof(i_color));
3256 for (i=0; i < items-2; ++i) {
3257 if (sv_isobject(ST(i+2))
3258 && sv_derived_from(ST(i+2), "Imager::Color")) {
3259 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3260 colors[i] = *INT2PTR(i_color *, tmp);
3264 croak("i_setcolors: pixels must be Imager::Color objects");
3267 RETVAL = i_setcolors(im, index, colors, items-2);
3273 i_getcolors(im, index, ...)
3282 croak("i_getcolors: too many arguments");
3284 count = SvIV(ST(2));
3286 croak("i_getcolors: count must be positive");
3287 colors = mymalloc(sizeof(i_color) * count);
3288 if (i_getcolors(im, index, colors, count)) {
3289 for (i = 0; i < count; ++i) {
3290 SV *sv = make_i_color_sv(aTHX_ colors+i);
3306 i_findcolor(im, color)
3312 if (i_findcolor(im, color, &index)) {
3313 RETVAL = newSViv(index);
3316 RETVAL = &PL_sv_undef;
3334 i_gsamp(im, l, r, y, channels)
3339 i_channel_list channels
3345 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
3346 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3347 if (GIMME_V == G_ARRAY) {
3349 for (i = 0; i < count; ++i)
3350 PUSHs(sv_2mortal(newSViv(data[i])));
3354 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3359 if (GIMME_V != G_ARRAY) {
3361 PUSHs(&PL_sv_undef);
3366 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3374 i_channel_list channels
3381 croak("No channel numbers supplied to g_samp()");
3383 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3384 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3385 for (i = 0; i < count; ++i) {
3386 av_store(target, i+offset, newSVuv(data[i]));
3398 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3403 i_channel_list channels
3405 i_img_dim data_offset
3406 i_img_dim pixel_count
3415 data_count = av_len(data_av) + 1;
3416 if (data_offset < 0) {
3417 croak("data_offset must be non-negative");
3419 if (data_offset > data_count) {
3420 croak("data_offset greater than number of samples supplied");
3422 if (pixel_count == -1 ||
3423 data_offset + pixel_count * channels.count > data_count) {
3424 pixel_count = (data_count - data_offset) / channels.count;
3427 data_used = pixel_count * channels.count;
3428 data = mymalloc(sizeof(unsigned) * data_count);
3429 for (i = 0; i < data_used; ++i)
3430 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3432 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3433 channels.count, bits);
3441 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3445 i_channel_list channels
3454 i_push_error(0, "offset must be non-negative");
3458 if (offset > data.count) {
3459 i_push_error(0, "offset greater than number of samples supplied");
3462 data.samples += offset;
3463 data.count -= offset;
3466 width * channels.count > data.count) {
3467 width = data.count / channels.count;
3470 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3475 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3479 i_channel_list channels
3488 i_push_error(0, "offset must be non-negative");
3492 if (offset > data.count) {
3493 i_push_error(0, "offset greater than number of samples supplied");
3496 data.samples += offset;
3497 data.count -= offset;
3500 width * channels.count > data.count) {
3501 width = data.count / channels.count;
3504 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3509 i_img_masked_new(targ, mask, x, y, w, h)
3519 if (!sv_isobject(ST(1))
3520 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3521 croak("i_img_masked_new: parameter 2 must undef or an image");
3523 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3527 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3532 i_plin(im, l, y, ...)
3543 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3544 /* supplied as a byte string */
3545 work = (i_color *)SvPV(ST(3), len);
3546 count = len / sizeof(i_color);
3547 if (count * sizeof(i_color) != len) {
3548 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3550 RETVAL = i_plin(im, l, l+count, y, work);
3553 work = mymalloc(sizeof(i_color) * (items-3));
3554 for (i=0; i < items-3; ++i) {
3555 if (sv_isobject(ST(i+3))
3556 && sv_derived_from(ST(i+3), "Imager::Color")) {
3557 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3558 work[i] = *INT2PTR(i_color *, tmp);
3562 croak("i_plin: pixels must be Imager::Color objects");
3565 RETVAL = i_plin(im, l, l+items-3, y, work);
3576 i_ppixf(im, x, y, cl)
3580 Imager::Color::Float cl
3583 i_gsampf(im, l, r, y, channels)
3588 i_channel_list channels
3594 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3595 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3596 if (GIMME_V == G_ARRAY) {
3598 for (i = 0; i < count; ++i)
3599 PUSHs(sv_2mortal(newSVnv(data[i])));
3603 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3608 if (GIMME_V != G_ARRAY) {
3610 PUSHs(&PL_sv_undef);
3615 i_plinf(im, l, y, ...)
3626 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3627 /* supplied as a byte string */
3628 work = (i_fcolor *)SvPV(ST(3), len);
3629 count = len / sizeof(i_fcolor);
3630 if (count * sizeof(i_fcolor) != len) {
3631 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3633 RETVAL = i_plinf(im, l, l+count, y, work);
3636 work = mymalloc(sizeof(i_fcolor) * (items-3));
3637 for (i=0; i < items-3; ++i) {
3638 if (sv_isobject(ST(i+3))
3639 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3640 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3641 work[i] = *INT2PTR(i_fcolor *, tmp);
3645 croak("i_plinf: pixels must be Imager::Color::Float objects");
3649 RETVAL = i_plinf(im, l, l+items-3, y, work);
3667 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3668 if (i_gpixf(im, x, y, color) == 0) {
3669 RETVAL = NEWSV(0,0);
3670 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3674 RETVAL = &PL_sv_undef;
3690 vals = mymalloc((r-l) * sizeof(i_color));
3691 memset(vals, 0, (r-l) * sizeof(i_color));
3692 count = i_glin(im, l, r, y, vals);
3693 if (GIMME_V == G_ARRAY) {
3695 for (i = 0; i < count; ++i) {
3696 SV *sv = make_i_color_sv(aTHX_ vals+i);
3702 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3708 i_glinf(im, l, r, y)
3718 for (i = 0; i < MAXCHANNELS; ++i)
3719 zero.channel[i] = 0;
3721 vals = mymalloc((r-l) * sizeof(i_fcolor));
3722 for (i = 0; i < r-l; ++i)
3724 count = i_glinf(im, l, r, y, vals);
3725 if (GIMME_V == G_ARRAY) {
3727 for (i = 0; i < count; ++i) {
3729 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3731 sv = sv_newmortal();
3732 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3738 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3744 i_img_8_new(x, y, ch)
3750 i_img_16_new(x, y, ch)
3760 i_img_double_new(x, y, ch)
3770 i_tags_addn(im, name, code, idata)
3779 name = SvPV(ST(1), len);
3782 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3787 i_tags_add(im, name, code, data, idata)
3797 name = SvPV(ST(1), len);
3801 data = SvPV(ST(3), len);
3806 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3811 i_tags_find(im, name, start)
3818 if (i_tags_find(&im->tags, name, start, &entry)) {
3820 RETVAL = newSVpv("0 but true", 0);
3822 RETVAL = newSViv(entry);
3824 RETVAL = &PL_sv_undef;
3830 i_tags_findn(im, code, start)
3837 if (i_tags_findn(&im->tags, code, start, &entry)) {
3839 RETVAL = newSVpv("0 but true", 0);
3841 RETVAL = newSViv(entry);
3844 RETVAL = &PL_sv_undef;
3850 i_tags_delete(im, entry)
3854 RETVAL = i_tags_delete(&im->tags, entry);
3859 i_tags_delbyname(im, name)
3863 RETVAL = i_tags_delbyname(&im->tags, name);
3868 i_tags_delbycode(im, code)
3872 RETVAL = i_tags_delbycode(&im->tags, code);
3877 i_tags_get(im, index)
3881 if (index >= 0 && index < im->tags.count) {
3882 i_img_tag *entry = im->tags.tags + index;
3886 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3889 PUSHs(sv_2mortal(newSViv(entry->code)));
3892 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3895 PUSHs(sv_2mortal(newSViv(entry->idata)));
3900 i_tags_get_string(im, what_sv)
3904 char const *name = NULL;
3908 if (SvIOK(what_sv)) {
3909 code = SvIV(what_sv);
3913 name = SvPV_nolen(what_sv);
3916 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3918 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3925 RETVAL = im->tags.count;
3931 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3935 Imager::FillHandle fill
3938 IFILL_CLONE_SKIP(...)
3940 (void)items; /* avoid unused warning for XS variable */
3945 MODULE = Imager PACKAGE = Imager
3948 i_new_fill_solid(cl, combine)
3953 i_new_fill_solidf(cl, combine)
3954 Imager::Color::Float cl
3958 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3966 unsigned char *cust_hatch;
3970 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3974 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3979 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3980 Imager::Color::Float fg
3981 Imager::Color::Float bg
3987 unsigned char *cust_hatch;
3991 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3995 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4000 i_new_fill_image(src, matrix, xoff, yoff, combine)
4017 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4018 croak("i_new_fill_image: parameter must be an arrayref");
4019 av=(AV*)SvRV(ST(1));
4023 for (i = 0; i < len; ++i) {
4024 sv1=(*(av_fetch(av,i,0)));
4025 matrix[i] = SvNV(sv1);
4031 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4035 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4037 # this class is only exposed for testing
4040 i_int_hlines_testing()
4042 #if i_int_hlines_testing()
4044 Imager::Internal::Hlines
4045 i_int_hlines_new(start_y, count_y, start_x, count_x)
4051 Imager::Internal::Hlines
4052 i_int_hlines_new_img(im)
4056 i_int_hlines_add(hlines, y, minx, width)
4057 Imager::Internal::Hlines hlines
4063 i_int_hlines_DESTROY(hlines)
4064 Imager::Internal::Hlines hlines
4067 i_int_hlines_dump(hlines)
4068 Imager::Internal::Hlines hlines
4071 i_int_hlines_CLONE_SKIP(cls)
4075 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4078 im_context_DESTROY(ctx)
4081 #ifdef PERL_IMPLICIT_CONTEXT
4084 im_context_CLONE(...)
4088 /* the following sv_setref_pv() will free this inc */
4089 im_context_refinc(MY_CXT.ctx, "CLONE");
4090 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4091 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4096 PERL_SET_GLOBAL_CALLBACKS;
4097 PERL_PL_SET_GLOBAL_CALLBACKS;
4098 #ifdef PERL_IMPLICIT_CONTEXT
4104 start_context(aTHX);
4105 im_get_context = perl_get_context;