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 /* for use with the T_AVARRAY typemap */
126 #define doublePtr(size) ((double *)malloc_temp(aTHX_ sizeof(double) * (size)))
127 #define SvDouble(sv) (SvNV(sv))
129 #define intPtr(size) ((int *)malloc_temp(aTHX_ sizeof(int) * (size)))
130 #define SvInt(sv) (SvIV(sv))
132 /* These functions are all shared - then comes platform dependant code */
133 static int getstr(void *hv_t,char *key,char **store) {
138 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
140 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
142 svpp=hv_fetch(hv, key, strlen(key), 0);
143 *store=SvPV(*svpp, PL_na );
148 static int getint(void *hv_t,char *key,int *store) {
153 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
155 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
157 svpp=hv_fetch(hv, key, strlen(key), 0);
158 *store=(int)SvIV(*svpp);
162 static int getdouble(void *hv_t,char* key,double *store) {
167 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
169 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
170 svpp=hv_fetch(hv, key, strlen(key), 0);
171 *store=(double)SvNV(*svpp);
175 static int getvoid(void *hv_t,char* key,void **store) {
180 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
182 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
184 svpp=hv_fetch(hv, key, strlen(key), 0);
185 *store = INT2PTR(void*, SvIV(*svpp));
190 static int getobj(void *hv_t,char *key,char *type,void **store) {
195 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
197 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
199 svpp=hv_fetch(hv, key, strlen(key), 0);
201 if (sv_derived_from(*svpp,type)) {
202 IV tmp = SvIV((SV*)SvRV(*svpp));
203 *store = INT2PTR(void*, tmp);
205 mm_log((1,"getobj: key exists in hash but is not of correct type"));
212 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
214 void my_SvREFCNT_dec(void *p) {
216 SvREFCNT_dec((SV*)p);
221 i_log_entry(char *string, int level) {
222 mm_log((level, "%s", string));
226 make_i_color_sv(pTHX_ const i_color *c) {
228 i_color *col = mymalloc(sizeof(i_color));
231 sv_setref_pv(sv, "Imager::Color", (void *)col);
236 #define CBDATA_BUFSIZE 8192
239 /* the SVs we use to call back to Perl */
247 call_reader(struct cbdata *cbd, void *buf, size_t size,
255 if (!SvOK(cbd->readcb)) {
256 mm_log((1, "read callback called but no readcb supplied\n"));
257 i_push_error(0, "read callback called but no readcb supplied");
265 PUSHs(sv_2mortal(newSViv(size)));
266 PUSHs(sv_2mortal(newSViv(maxread)));
269 count = perl_call_sv(cbd->readcb, G_SCALAR);
274 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
280 char *ptr = SvPVbyte(data, len);
282 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
283 (int)size, (int)len, (int)maxread);
285 memcpy(buf, ptr, len);
300 io_seeker(void *p, off_t offset, int whence) {
302 struct cbdata *cbd = p;
307 if (!SvOK(cbd->seekcb)) {
308 mm_log((1, "seek callback called but no seekcb supplied\n"));
309 i_push_error(0, "seek callback called but no seekcb supplied");
317 PUSHs(sv_2mortal(newSViv(offset)));
318 PUSHs(sv_2mortal(newSViv(whence)));
321 count = perl_call_sv(cbd->seekcb, G_SCALAR);
326 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
338 io_writer(void *p, void const *data, size_t size) {
340 struct cbdata *cbd = p;
346 if (!SvOK(cbd->writecb)) {
347 mm_log((1, "write callback called but no writecb supplied\n"));
348 i_push_error(0, "write callback called but no writecb supplied");
356 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
359 count = perl_call_sv(cbd->writecb, G_SCALAR);
363 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
366 success = SvTRUE(sv);
373 return success ? size : -1;
377 io_reader(void *p, void *data, size_t size) {
378 struct cbdata *cbd = p;
380 return call_reader(cbd, data, size, size);
383 static int io_closer(void *p) {
385 struct cbdata *cbd = p;
388 if (SvOK(cbd->closecb)) {
398 count = perl_call_sv(cbd->closecb, G_SCALAR);
403 success = SvTRUE(sv);
410 return success ? 0 : -1;
413 static void io_destroyer(void *p) {
415 struct cbdata *cbd = p;
417 SvREFCNT_dec(cbd->writecb);
418 SvREFCNT_dec(cbd->readcb);
419 SvREFCNT_dec(cbd->seekcb);
420 SvREFCNT_dec(cbd->closecb);
425 do_io_new_buffer(pTHX_ SV *data_sv) {
429 data = SvPVbyte(data_sv, length);
430 SvREFCNT_inc(data_sv);
431 return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
435 describe_sv(SV *sv) {
438 svtype type = SvTYPE(SvRV(sv));
440 case SVt_PVCV: return "CV";
441 case SVt_PVGV: return "GV";
442 case SVt_PVLV: return "LV";
443 default: return "some reference";
447 return "non-reference scalar";
456 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
459 cbd = mymalloc(sizeof(struct cbdata));
460 cbd->writecb = newSVsv(writecb);
461 cbd->readcb = newSVsv(readcb);
462 cbd->seekcb = newSVsv(seekcb);
463 cbd->closecb = newSVsv(closecb);
465 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)));
467 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
475 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
478 for (i = 0; i < count; ++i)
479 if (strEQ(names[i].name, name))
480 return names[i].value;
484 static struct value_name transp_names[] =
487 { "threshold", tr_threshold },
488 { "errdiff", tr_errdiff },
489 { "ordered", tr_ordered, },
492 static struct value_name make_color_names[] =
494 { "none", mc_none, },
495 { "webmap", mc_web_map, },
496 { "addi", mc_addi, },
497 { "mediancut", mc_median_cut, },
498 { "mono", mc_mono, },
499 { "monochrome", mc_mono, },
500 { "gray", mc_gray, },
501 { "gray4", mc_gray4, },
502 { "gray16", mc_gray16, },
505 static struct value_name translate_names[] =
507 { "giflib", pt_giflib, },
508 { "closest", pt_closest, },
509 { "perturb", pt_perturb, },
510 { "errdiff", pt_errdiff, },
513 static struct value_name errdiff_names[] =
515 { "floyd", ed_floyd, },
516 { "jarvis", ed_jarvis, },
517 { "stucki", ed_stucki, },
518 { "custom", ed_custom, },
521 static struct value_name orddith_names[] =
523 { "random", od_random, },
524 { "dot8", od_dot8, },
525 { "dot4", od_dot4, },
526 { "hline", od_hline, },
527 { "vline", od_vline, },
528 { "/line", od_slashline, },
529 { "slashline", od_slashline, },
530 { "\\line", od_backline, },
531 { "backline", od_backline, },
532 { "tiny", od_tiny, },
533 { "custom", od_custom, },
536 /* look through the hash for quantization options */
538 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
540 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
546 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
548 sv = hv_fetch(hv, "transp", 6, 0);
549 if (sv && *sv && (str = SvPV(*sv, len))) {
551 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
553 if (quant->transp != tr_none) {
554 quant->tr_threshold = 127;
555 sv = hv_fetch(hv, "tr_threshold", 12, 0);
557 quant->tr_threshold = SvIV(*sv);
559 if (quant->transp == tr_errdiff) {
560 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
561 if (sv && *sv && (str = SvPV(*sv, len)))
562 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
564 if (quant->transp == tr_ordered) {
565 quant->tr_orddith = od_tiny;
566 sv = hv_fetch(hv, "tr_orddith", 10, 0);
567 if (sv && *sv && (str = SvPV(*sv, len)))
568 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
570 if (quant->tr_orddith == od_custom) {
571 sv = hv_fetch(hv, "tr_map", 6, 0);
572 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
573 AV *av = (AV*)SvRV(*sv);
574 len = av_len(av) + 1;
575 if (len > sizeof(quant->tr_custom))
576 len = sizeof(quant->tr_custom);
577 for (i = 0; i < len; ++i) {
578 SV **sv2 = av_fetch(av, i, 0);
580 quant->tr_custom[i] = SvIV(*sv2);
583 while (i < sizeof(quant->tr_custom))
584 quant->tr_custom[i++] = 0;
589 quant->make_colors = mc_median_cut;
590 sv = hv_fetch(hv, "make_colors", 11, 0);
591 if (sv && *sv && (str = SvPV(*sv, len))) {
593 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
595 sv = hv_fetch(hv, "colors", 6, 0);
596 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
597 /* needs to be an array of Imager::Color
598 note that the caller allocates the mc_color array and sets mc_size
600 AV *av = (AV *)SvRV(*sv);
601 quant->mc_count = av_len(av)+1;
602 if (quant->mc_count > quant->mc_size)
603 quant->mc_count = quant->mc_size;
604 for (i = 0; i < quant->mc_count; ++i) {
605 SV **sv1 = av_fetch(av, i, 0);
606 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
607 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
608 quant->mc_colors[i] = *col;
612 sv = hv_fetch(hv, "max_colors", 10, 0);
615 if (i <= quant->mc_size && i >= quant->mc_count)
619 quant->translate = pt_closest;
620 sv = hv_fetch(hv, "translate", 9, 0);
621 if (sv && *sv && (str = SvPV(*sv, len))) {
622 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
624 sv = hv_fetch(hv, "errdiff", 7, 0);
625 if (sv && *sv && (str = SvPV(*sv, len))) {
626 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
628 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
629 /* get the error diffusion map */
630 sv = hv_fetch(hv, "errdiff_width", 13, 0);
632 quant->ed_width = SvIV(*sv);
633 sv = hv_fetch(hv, "errdiff_height", 14, 0);
635 quant->ed_height = SvIV(*sv);
636 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
638 quant->ed_orig = SvIV(*sv);
639 if (quant->ed_width > 0 && quant->ed_height > 0) {
641 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
642 sv = hv_fetch(hv, "errdiff_map", 11, 0);
643 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
644 AV *av = (AV*)SvRV(*sv);
645 len = av_len(av) + 1;
646 if (len > quant->ed_width * quant->ed_height)
647 len = quant->ed_width * quant->ed_height;
648 for (i = 0; i < len; ++i) {
649 SV **sv2 = av_fetch(av, i, 0);
651 quant->ed_map[i] = SvIV(*sv2);
652 sum += quant->ed_map[i];
658 myfree(quant->ed_map);
660 quant->errdiff = ed_floyd;
664 sv = hv_fetch(hv, "perturb", 7, 0);
666 quant->perturb = SvIV(*sv);
670 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
671 myfree(quant->mc_colors);
673 myfree(quant->ed_map);
676 /* copies the color map from the hv into the colors member of the HV */
678 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
684 sv = hv_fetch(hv, "colors", 6, 0);
685 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
690 av = (AV *)SvRV(*sv);
692 av_extend(av, quant->mc_count+1);
693 for (i = 0; i < quant->mc_count; ++i) {
694 i_color *in = quant->mc_colors+i;
695 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
696 work = sv_newmortal();
697 sv_setref_pv(work, "Imager::Color", (void *)c);
703 /* loads the segments of a fountain fill into an array */
704 static i_fountain_seg *
705 load_fount_segs(pTHX_ AV *asegs, int *count) {
706 /* Each element of segs must contain:
707 [ start, middle, end, c0, c1, segtype, colortrans ]
708 start, middle, end are doubles from 0 to 1
709 c0, c1 are Imager::Color::Float or Imager::Color objects
710 segtype, colortrans are ints
714 i_fountain_seg *segs;
718 *count = av_len(asegs)+1;
720 croak("i_fountain must have at least one segment");
721 segs = mymalloc(sizeof(i_fountain_seg) * *count);
722 for(i = 0; i < *count; i++) {
723 SV **sv1 = av_fetch(asegs, i, 0);
724 if (!sv1 || !*sv1 || !SvROK(*sv1)
725 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
727 croak("i_fountain: segs must be an arrayref of arrayrefs");
729 aseg = (AV *)SvRV(*sv1);
730 if (av_len(aseg) != 7-1) {
732 croak("i_fountain: a segment must have 7 members");
734 for (j = 0; j < 3; ++j) {
735 SV **sv2 = av_fetch(aseg, j, 0);
738 croak("i_fountain: XS error");
740 work[j] = SvNV(*sv2);
742 segs[i].start = work[0];
743 segs[i].middle = work[1];
744 segs[i].end = work[2];
745 for (j = 0; j < 2; ++j) {
746 SV **sv3 = av_fetch(aseg, 3+j, 0);
747 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
748 (!sv_derived_from(*sv3, "Imager::Color")
749 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
751 croak("i_fountain: segs must contain colors in elements 3 and 4");
753 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
754 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
757 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
759 for (ch = 0; ch < MAXCHANNELS; ++ch) {
760 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
764 for (j = 0; j < 2; ++j) {
765 SV **sv2 = av_fetch(aseg, j+5, 0);
768 croak("i_fountain: XS error");
770 worki[j] = SvIV(*sv2);
772 segs[i].type = worki[0];
773 segs[i].color = worki[1];
779 /* validates the indexes supplied to i_ppal
781 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
786 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
787 int color_count = i_colorcount(im);
790 if (color_count == -1)
791 croak("i_plin() called on direct color image");
793 for (i = 0; i < count; ++i) {
794 if (indexes[i] >= color_count) {
795 croak("i_plin() called with out of range color index %d (max %d)",
796 indexes[i], color_count-1);
801 /* I don't think ICLF_* names belong at the C interface
802 this makes the XS code think we have them, to let us avoid
803 putting function bodies in the XS code
805 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
806 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
809 #define i_log_enabled() 1
811 #define i_log_enabled() 0
814 #if i_int_hlines_testing()
816 typedef i_int_hlines *Imager__Internal__Hlines;
818 static i_int_hlines *
819 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
820 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
821 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
826 static i_int_hlines *
827 i_int_hlines_new_img(i_img *im) {
828 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
829 i_int_init_hlines_img(result, im);
835 i_int_hlines_DESTROY(i_int_hlines *hlines) {
836 i_int_hlines_destroy(hlines);
840 #define i_int_hlines_CLONE_SKIP(cls) 1
842 static int seg_compare(const void *vleft, const void *vright) {
843 const i_int_hline_seg *left = vleft;
844 const i_int_hline_seg *right = vright;
846 return left->minx - right->minx;
850 i_int_hlines_dump(i_int_hlines *hlines) {
852 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
853 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
856 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
857 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
860 /* sort the segments, if any */
862 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
864 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
865 for (i = 0; i < entry->count; ++i) {
866 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
867 i_DFc(entry->segs[i].x_limit));
869 sv_catpv(dump, "\n");
879 i_sv_off_t(pTHX_ SV *sv) {
880 #if LSEEKSIZE > IVSIZE
881 return (off_t)SvNV(sv);
883 return (off_t)SvIV(sv);
888 i_new_sv_off_t(pTHX_ off_t off) {
889 #if LSEEKSIZE > IVSIZE
896 static im_pl_ext_funcs im_perl_funcs =
898 IMAGER_PL_API_VERSION,
900 ip_handle_quant_opts,
901 ip_cleanup_quant_opts,
905 #define PERL_PL_SET_GLOBAL_CALLBACKS \
906 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
908 #define IIM_new i_img_8_new
909 #define IIM_DESTROY i_img_destroy
912 #define i_exif_enabled() 1
914 #define i_exif_enabled() 0
917 /* trying to use more C style names, map them here */
918 #define i_io_DESTROY(ig) io_glue_destroy(ig)
920 #define i_img_get_width(im) ((im)->xsize)
921 #define i_img_get_height(im) ((im)->ysize)
923 #define i_img_epsilonf() (DBL_EPSILON * 4)
925 /* avoid some xsubpp strangeness */
928 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
931 ICL_new_internal(r,g,b,a)
943 ICL_set_internal(cl,r,g,b,a)
950 ICL_set_internal(cl, r, g, b, a);
964 PUSHs(sv_2mortal(newSViv(cl->rgba.r)));
965 PUSHs(sv_2mortal(newSViv(cl->rgba.g)));
966 PUSHs(sv_2mortal(newSViv(cl->rgba.b)));
967 PUSHs(sv_2mortal(newSViv(cl->rgba.a)));
973 RETVAL = mymalloc(sizeof(i_color));
975 i_hsv_to_rgb(RETVAL);
983 RETVAL = mymalloc(sizeof(i_color));
985 i_rgb_to_hsv(RETVAL);
991 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
994 ICLF_new_internal(r, g, b, a)
1002 Imager::Color::Float cl
1006 Imager::Color::Float cl
1010 EXTEND(SP, MAXCHANNELS);
1011 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1012 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1013 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1017 ICLF_set_internal(cl,r,g,b,a)
1018 Imager::Color::Float cl
1031 Imager::Color::Float
1033 Imager::Color::Float c
1035 RETVAL = mymalloc(sizeof(i_fcolor));
1037 i_hsv_to_rgbf(RETVAL);
1041 Imager::Color::Float
1043 Imager::Color::Float c
1045 RETVAL = mymalloc(sizeof(i_fcolor));
1047 i_rgb_to_hsvf(RETVAL);
1051 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1065 MODULE = Imager PACKAGE = Imager
1079 io_new_buffer(data_sv)
1082 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1087 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1094 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1102 unsigned char* data;
1106 tlength = io_slurp(ig, &data);
1107 RETVAL = newSVpv((char *)data,tlength);
1114 i_set_image_file_limits(width, height, bytes)
1120 i_get_image_file_limits()
1122 i_img_dim width, height;
1125 if (i_get_image_file_limits(&width, &height, &bytes)) {
1127 PUSHs(sv_2mortal(newSViv(width)));
1128 PUSHs(sv_2mortal(newSViv(height)));
1129 PUSHs(sv_2mortal(newSVuv(bytes)));
1133 i_int_check_image_file_limits(width, height, channels, sample_size)
1140 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
1143 io_new_fd(class, fd)
1146 RETVAL = io_new_fd(fd);
1151 io_new_buffer(class, data_sv)
1154 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1159 io_new_cb(class, writecb, readcb, seekcb, closecb)
1165 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1170 io_new_bufchain(class)
1172 RETVAL = io_new_bufchain();
1177 io__new_perlio(class, io)
1180 RETVAL = im_io_new_perlio(aTHX_ io);
1188 unsigned char* data;
1192 tlength = io_slurp(ig, &data);
1193 RETVAL = newSVpv((char *)data,tlength);
1198 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1201 i_io_raw_write(ig, data_sv)
1208 data = SvPVbyte(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)
1433 data = SvPVbyte(data_sv, size);
1434 RETVAL = i_io_write(ig, data, size);
1439 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1444 i_io_set_buffered(ig, flag = 1)
1449 i_io_is_buffered(ig)
1460 MODULE = Imager PACKAGE = Imager
1471 while( (item=i_format_list[i++]) != NULL ) {
1473 PUSHs(sv_2mortal(newSVpv(item,0)));
1477 i_sametype(im, x, y)
1483 i_sametype_chans(im, x, y, channels)
1490 i_init_log(name_sv,level)
1494 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1496 RETVAL = i_init_log(name, level);
1501 i_log_entry(string,level)
1514 i_img_info(im,info);
1516 PUSHs(sv_2mortal(newSViv(info[0])));
1517 PUSHs(sv_2mortal(newSViv(info[1])));
1518 PUSHs(sv_2mortal(newSViv(info[2])));
1519 PUSHs(sv_2mortal(newSViv(info[3])));
1525 i_img_setmask(im,ch_mask)
1534 i_img_getchannels(im)
1543 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1551 i_img_get_height(im)
1556 i_img_is_monochrome(im)
1562 result = i_img_is_monochrome(im, &zero_is_white);
1564 if (GIMME_V == G_ARRAY) {
1567 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1576 i_line(im,x1,y1,x2,y2,val,endp)
1586 i_line_aa(im,x1,y1,x2,y2,val,endp)
1596 i_box(im,x1,y1,x2,y2,val)
1605 i_box_filled(im,x1,y1,x2,y2,val)
1614 i_box_filledf(im,x1,y1,x2,y2,val)
1620 Imager::Color::Float val
1623 i_box_cfill(im,x1,y1,x2,y2,fill)
1629 Imager::FillHandle fill
1632 i_arc(im,x,y,rad,d1,d2,val)
1642 i_arc_aa(im,x,y,rad,d1,d2,val)
1652 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1659 Imager::FillHandle fill
1662 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1669 Imager::FillHandle fill
1673 i_circle_aa(im,x,y,rad,val)
1681 i_circle_out(im,x,y,rad,val)
1689 i_circle_out_aa(im,x,y,rad,val)
1697 i_arc_out(im,x,y,rad,d1,d2,val)
1707 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1718 i_bezier_multi(im,xc,yc,val)
1731 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1732 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1733 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1734 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1735 av1=(AV*)SvRV(ST(1));
1736 av2=(AV*)SvRV(ST(2));
1737 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1739 x=mymalloc( len*sizeof(double) );
1740 y=mymalloc( len*sizeof(double) );
1741 for(i=0;i<len;i++) {
1742 sv1=(*(av_fetch(av1,i,0)));
1743 sv2=(*(av_fetch(av2,i,0)));
1744 x[i]=(double)SvNV(sv1);
1745 y[i]=(double)SvNV(sv2);
1747 i_bezier_multi(im,len,x,y,val);
1753 i_poly_aa(im,x,y,val)
1762 if (size_x != size_y)
1763 croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1764 RETVAL = i_poly_aa(im, size_x, x, y, val);
1769 i_poly_aa_cfill(im, x, y, fill)
1773 Imager::FillHandle fill
1778 if (size_x != size_y)
1779 croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1780 RETVAL = i_poly_aa_cfill(im, size_x, x, y, fill);
1785 i_flood_fill(im,seedx,seedy,dcol)
1792 i_flood_cfill(im,seedx,seedy,fill)
1796 Imager::FillHandle fill
1799 i_flood_fill_border(im,seedx,seedy,dcol, border)
1804 Imager::Color border
1807 i_flood_cfill_border(im,seedx,seedy,fill, border)
1811 Imager::FillHandle fill
1812 Imager::Color border
1816 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1828 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1845 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1856 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1869 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)
1885 i_combine(src_av, channels_av = NULL)
1889 i_img **imgs = NULL;
1891 int *channels = NULL;
1896 in_count = av_len(src_av) + 1;
1898 imgs = mymalloc(sizeof(i_img*) * in_count);
1899 channels = mymalloc(sizeof(int) * in_count);
1900 for (i = 0; i < in_count; ++i) {
1901 psv = av_fetch(src_av, i, 0);
1902 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1905 croak("imgs must contain only images");
1907 tmp = SvIV((SV*)SvRV(*psv));
1908 imgs[i] = INT2PTR(i_img*, tmp);
1910 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1912 channels[i] = SvIV(*psv);
1919 RETVAL = i_combine(imgs, channels, in_count);
1926 i_flipxy(im, direction)
1931 i_rotate90(im, degrees)
1936 i_rotate_exact(im, amount, ...)
1940 i_color *backp = NULL;
1941 i_fcolor *fbackp = NULL;
1945 /* extract the bg colors if any */
1946 /* yes, this is kind of strange */
1947 for (i = 2; i < items; ++i) {
1949 if (sv_derived_from(sv1, "Imager::Color")) {
1950 IV tmp = SvIV((SV*)SvRV(sv1));
1951 backp = INT2PTR(i_color *, tmp);
1953 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1954 IV tmp = SvIV((SV*)SvRV(sv1));
1955 fbackp = INT2PTR(i_fcolor *, tmp);
1958 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1963 i_matrix_transform(im, xsize, ysize, matrix_av, ...)
1973 i_color *backp = NULL;
1974 i_fcolor *fbackp = NULL;
1976 len=av_len(matrix_av)+1;
1979 for (i = 0; i < len; ++i) {
1980 sv1=(*(av_fetch(matrix_av,i,0)));
1981 matrix[i] = SvNV(sv1);
1985 /* extract the bg colors if any */
1986 /* yes, this is kind of strange */
1987 for (i = 4; i < items; ++i) {
1989 if (sv_derived_from(sv1, "Imager::Color")) {
1990 IV tmp = SvIV((SV*)SvRV(sv1));
1991 backp = INT2PTR(i_color *, tmp);
1993 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1994 IV tmp = SvIV((SV*)SvRV(sv1));
1995 fbackp = INT2PTR(i_fcolor *, tmp);
1998 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2003 i_gaussian(im,stdev)
2008 i_unsharp_mask(im,stdev,scale)
2023 len = av_len(coef) + 1;
2024 c_coef=mymalloc( len * sizeof(double) );
2025 for(i = 0; i < len; i++) {
2026 sv1 = (*(av_fetch(coef, i, 0)));
2027 c_coef[i] = (double)SvNV(sv1);
2029 RETVAL = i_conv(im, c_coef, len);
2035 i_convert(src, avmain)
2047 outchan = av_len(avmain)+1;
2048 /* find the biggest */
2050 for (j=0; j < outchan; ++j) {
2051 temp = av_fetch(avmain, j, 0);
2052 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2053 avsub = (AV*)SvRV(*temp);
2054 len = av_len(avsub)+1;
2059 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2063 coeff = mymalloc(sizeof(double) * outchan * inchan);
2064 for (j = 0; j < outchan; ++j) {
2065 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2066 len = av_len(avsub)+1;
2067 for (i = 0; i < len; ++i) {
2068 temp = av_fetch(avsub, i, 0);
2070 coeff[i+j*inchan] = SvNV(*temp);
2072 coeff[i+j*inchan] = 0;
2075 coeff[i++ + j*inchan] = 0;
2077 RETVAL = i_convert(src, coeff, outchan, inchan);
2088 unsigned int mask = 0;
2094 unsigned char (*maps)[256];
2096 len = av_len(pmaps_av)+1;
2097 if (im->channels < len)
2099 maps = mymalloc( len * sizeof(unsigned char [256]) );
2100 for (j=0; j<len ; j++) {
2101 temp = av_fetch(pmaps_av, j, 0);
2102 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2103 avsub = (AV*)SvRV(*temp);
2104 if(av_len(avsub) != 255)
2107 for (i=0; i<256 ; i++) {
2109 temp = av_fetch(avsub, i, 0);
2110 val = temp ? SvIV(*temp) : 0;
2112 if (val>255) val = 255;
2117 i_map(im, maps, mask);
2129 i_img_diffd(im1,im2)
2134 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2144 _is_color_object(sv)
2148 RETVAL = SvOK(sv) && SvROK(sv) &&
2149 (sv_derived_from(sv, "Imager::Color")
2150 || sv_derived_from(sv, "Imager::Color::Float"));
2162 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2164 #define TT_DESTROY(handle) i_tt_destroy(handle)
2168 Imager::Font::TT handle
2173 (void)items; /* avoid unused warning */
2179 MODULE = Imager PACKAGE = Imager
2183 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2184 Imager::Font::TT handle
2198 str = SvPV(str_sv, len);
2203 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2204 len, smooth, utf8, align);
2210 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2211 Imager::Font::TT handle
2225 str = SvPV(str_sv, len);
2230 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2231 smooth, utf8, align);
2237 i_tt_bbox(handle,point,str_sv,utf8)
2238 Imager::Font::TT handle
2243 i_img_dim cords[BOUNDING_BOX_COUNT];
2249 str = SvPV(str_sv, len);
2254 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2256 for (i = 0; i < rc; ++i) {
2257 PUSHs(sv_2mortal(newSViv(cords[i])));
2262 i_tt_has_chars(handle, text_sv, utf8)
2263 Imager::Font::TT handle
2274 text = SvPV(text_sv, len);
2276 if (SvUTF8(text_sv))
2279 work = mymalloc(len);
2280 count = i_tt_has_chars(handle, text, len, utf8, work);
2281 if (GIMME_V == G_ARRAY) {
2283 for (i = 0; i < count; ++i) {
2284 PUSHs(boolSV(work[i]));
2289 PUSHs(sv_2mortal(newSVpv(work, count)));
2294 i_tt_dump_names(handle)
2295 Imager::Font::TT handle
2298 i_tt_face_name(handle)
2299 Imager::Font::TT handle
2304 len = i_tt_face_name(handle, name, sizeof(name));
2307 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2311 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2312 Imager::Font::TT handle
2324 text = SvPV(text_sv, work_len);
2326 if (SvUTF8(text_sv))
2333 ch = i_utf8_advance(&text, &len);
2335 i_push_error(0, "invalid UTF8 character");
2343 EXTEND(SP, count+1);
2344 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2345 ST(count) = sv_2mortal(newSVpv(name, 0));
2348 ST(count) = &PL_sv_undef;
2357 i_test_format_probe(ig, length)
2362 i_readpnm_wiol(ig, allow_incomplete)
2364 int allow_incomplete
2368 i_readpnm_multi_wiol(ig, allow_incomplete)
2370 int allow_incomplete
2376 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2379 for (i = 0; i < count; ++i) {
2380 SV *sv = sv_newmortal();
2381 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2388 i_writeppm_wiol(im, ig)
2397 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2406 i_writeraw_wiol(im,ig)
2411 i_writebmp_wiol(im,ig)
2416 i_readbmp_wiol(ig, allow_incomplete=0)
2418 int allow_incomplete
2422 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2431 idlen = SvCUR(ST(4));
2432 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2438 i_readtga_wiol(ig, length)
2446 i_scaleaxis(im,Value,Axis)
2452 i_scale_nn(im,scx,scy)
2458 i_scale_mixing(im, width, height)
2468 i_count_colors(im,maxc)
2473 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2478 unsigned int * col_usage = NULL;
2481 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2482 EXTEND(SP, col_cnt);
2483 for (i = 0; i < col_cnt; i++) {
2484 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2491 i_transform(im, opx, opy, parm)
2497 STRLEN size_opx, size_opy, size_parm;
2500 result=i_transform(im,opx,size_opx,opy,size_opy,parm,size_parm);
2502 SV *result_sv = sv_newmortal();
2504 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2509 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2535 in_imgs_count = av_len(av_in_imgs)+1;
2536 for (i = 0; i < in_imgs_count; ++i) {
2537 sv1 = *av_fetch(av_in_imgs, i, 0);
2538 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2539 croak("sv_in_img must contain only images");
2542 if (in_imgs_count > 0) {
2543 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2544 for (i = 0; i < in_imgs_count; ++i) {
2545 sv1 = *av_fetch(av_in_imgs,i,0);
2546 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2547 croak("Parameter 5 must contain only images");
2549 tmp = SvIV((SV*)SvRV(sv1));
2550 in_imgs[i] = INT2PTR(i_img*, tmp);
2554 /* no input images */
2557 /* default the output size from the first input if possible */
2559 width = SvIV(sv_width);
2560 else if (in_imgs_count)
2561 width = in_imgs[0]->xsize;
2563 croak("No output image width supplied");
2565 if (SvOK(sv_height))
2566 height = SvIV(sv_height);
2567 else if (in_imgs_count)
2568 height = in_imgs[0]->ysize;
2570 croak("No output image height supplied");
2572 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2573 if (ops_len % sizeof(struct rm_op))
2574 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2575 ops_count = ops_len / sizeof(struct rm_op);
2577 n_regs_count = av_len(av_n_regs)+1;
2578 n_regs = mymalloc(n_regs_count * sizeof(double));
2579 for (i = 0; i < n_regs_count; ++i) {
2580 sv1 = *av_fetch(av_n_regs,i,0);
2582 n_regs[i] = SvNV(sv1);
2584 c_regs_count = av_len(av_c_regs)+1;
2585 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2586 /* I don't bother initializing the colou?r registers */
2588 result=i_transform2(width, height, channels, ops, ops_count,
2589 n_regs, n_regs_count,
2590 c_regs, c_regs_count, in_imgs, in_imgs_count);
2596 SV *result_sv = sv_newmortal();
2598 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2604 i_contrast(im,intensity)
2617 i_noise(im,amount,type)
2623 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2633 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2652 i_postlevels(im,levels)
2662 i_watermark(im,wmark,tx,ty,pixdiff)
2664 Imager::ImgRaw wmark
2671 i_autolevels(im,lsat,usat,skew)
2678 i_radnoise(im,xo,yo,rscale,ascale)
2686 i_turbnoise(im, xo, yo, scale)
2709 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2710 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2711 croak("i_gradgen: Second argument must be an array ref");
2712 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2713 croak("i_gradgen: Third argument must be an array ref");
2714 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2715 croak("i_gradgen: Fourth argument must be an array ref");
2716 axx = (AV *)SvRV(ST(1));
2717 ayy = (AV *)SvRV(ST(2));
2718 ac = (AV *)SvRV(ST(3));
2719 dmeasure = (int)SvIV(ST(4));
2721 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2722 num = num <= av_len(ac) ? num : av_len(ac);
2724 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2725 xo = mymalloc( sizeof(i_img_dim) * num );
2726 yo = mymalloc( sizeof(i_img_dim) * num );
2727 ival = mymalloc( sizeof(i_color) * num );
2728 for(i = 0; i<num; i++) {
2729 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2730 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2731 sv = *av_fetch(ac, i, 0);
2732 if ( !sv_derived_from(sv, "Imager::Color") ) {
2733 free(axx); free(ayy); free(ac);
2734 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2736 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2738 i_gradgen(im, num, xo, yo, ival, dmeasure);
2744 i_diff_image(im, im2, mindist=0)
2750 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2760 double ssample_param
2764 i_fountain_seg *segs;
2766 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2767 croak("i_fountain: argument 11 must be an array ref");
2769 asegs = (AV *)SvRV(ST(10));
2770 segs = load_fount_segs(aTHX_ asegs, &count);
2771 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2772 super_sample, ssample_param, count, segs);
2778 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2787 double ssample_param
2791 i_fountain_seg *segs;
2793 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2794 croak("i_fountain: argument 11 must be an array ref");
2796 asegs = (AV *)SvRV(ST(9));
2797 segs = load_fount_segs(aTHX_ asegs, &count);
2798 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2799 super_sample, ssample_param, count, segs);
2805 i_new_fill_opacity(other_fill, alpha_mult)
2806 Imager::FillHandle other_fill
2817 errors = i_errors();
2819 while (errors[i].msg) {
2821 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2822 if (!av_store(av, 0, sv)) {
2825 sv = newSViv(errors[i].code);
2826 if (!av_store(av, 1, sv)) {
2829 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2837 i_push_error(code, msg)
2842 i_nearest_color(im, ...)
2857 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2858 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2859 croak("i_nearest_color: Second argument must be an array ref");
2860 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2861 croak("i_nearest_color: Third argument must be an array ref");
2862 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2863 croak("i_nearest_color: Fourth argument must be an array ref");
2864 axx = (AV *)SvRV(ST(1));
2865 ayy = (AV *)SvRV(ST(2));
2866 ac = (AV *)SvRV(ST(3));
2867 dmeasure = (int)SvIV(ST(4));
2869 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2870 num = num <= av_len(ac) ? num : av_len(ac);
2872 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2873 xo = mymalloc( sizeof(i_img_dim) * num );
2874 yo = mymalloc( sizeof(i_img_dim) * num );
2875 ival = mymalloc( sizeof(i_color) * num );
2876 for(i = 0; i<num; i++) {
2877 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2878 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2879 sv = *av_fetch(ac, i, 0);
2880 if ( !sv_derived_from(sv, "Imager::Color") ) {
2881 free(axx); free(ayy); free(ac);
2882 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2884 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2886 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2900 rc=DSO_open(filename,&evstr);
2904 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2905 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2908 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2914 DSO_close(dso_handle)
2918 DSO_funclist(dso_handle_v)
2922 DSO_handle *dso_handle;
2923 func_ptr *functions;
2925 dso_handle=(DSO_handle*)dso_handle_v;
2926 functions = DSO_funclist(dso_handle);
2928 while( functions[i].name != NULL) {
2930 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
2932 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
2936 DSO_call(handle,func_index,hv)
2942 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2943 hv=(HV*)SvRV(ST(2));
2944 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2945 DSO_call( (DSO_handle *)handle,func_index,hv);
2948 i_get_pixel(im, x, y)
2955 color = (i_color *)mymalloc(sizeof(i_color));
2956 if (i_gpix(im, x, y, color) == 0) {
2957 RETVAL = NEWSV(0, 0);
2958 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
2962 RETVAL = &PL_sv_undef;
2969 i_ppix(im, x, y, cl)
2976 i_img_pal_new(x, y, channels, maxpal)
2983 i_img_to_pal(src, quant)
2989 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2990 croak("i_img_to_pal: second argument must be a hash ref");
2991 hv = (HV *)SvRV(ST(1));
2992 memset(&quant, 0, sizeof(quant));
2994 quant.mc_size = 256;
2995 ip_handle_quant_opts(aTHX_ &quant, hv);
2996 RETVAL = i_img_to_pal(src, &quant);
2998 ip_copy_colors_back(aTHX_ hv, &quant);
3000 ip_cleanup_quant_opts(aTHX_ &quant);
3009 i_img_make_palette(HV *quant_hv, ...)
3011 size_t count = items - 1;
3013 i_img **imgs = NULL;
3017 croak("Please supply at least one image (%d)", (int)count);
3018 imgs = mymalloc(sizeof(i_img *) * count);
3019 for (i = 0; i < count; ++i) {
3020 SV *img_sv = ST(i + 1);
3021 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3022 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3026 croak("Image %d is not an image object", (int)i+1);
3029 memset(&quant, 0, sizeof(quant));
3031 quant.mc_size = 256;
3032 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3033 i_quant_makemap(&quant, imgs, count);
3034 EXTEND(SP, quant.mc_count);
3035 for (i = 0; i < quant.mc_count; ++i) {
3036 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3039 ip_cleanup_quant_opts(aTHX_ &quant);
3053 work = mymalloc((r-l) * sizeof(i_palidx));
3054 count = i_gpal(im, l, r, y, work);
3055 if (GIMME_V == G_ARRAY) {
3057 for (i = 0; i < count; ++i) {
3058 PUSHs(sv_2mortal(newSViv(work[i])));
3063 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3068 if (GIMME_V != G_ARRAY) {
3070 PUSHs(&PL_sv_undef);
3075 i_ppal(im, l, y, ...)
3084 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3085 for (i=0; i < items-3; ++i) {
3086 work[i] = SvIV(ST(i+3));
3088 validate_i_ppal(im, work, items - 3);
3089 RETVAL = i_ppal(im, l, l+items-3, y, work);
3098 i_ppal_p(im, l, y, data)
3104 i_palidx const *work;
3107 work = (i_palidx const *)SvPV(data, len);
3108 len /= sizeof(i_palidx);
3110 validate_i_ppal(im, work, len);
3111 RETVAL = i_ppal(im, l, l+len, y, work);
3120 i_addcolors(im, ...)
3128 croak("i_addcolors: no colors to add");
3129 colors = mymalloc((items-1) * sizeof(i_color));
3130 for (i=0; i < items-1; ++i) {
3131 if (sv_isobject(ST(i+1))
3132 && sv_derived_from(ST(i+1), "Imager::Color")) {
3133 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3134 colors[i] = *INT2PTR(i_color *, tmp);
3138 croak("i_addcolor: pixels must be Imager::Color objects");
3141 index = i_addcolors(im, colors, items-1);
3144 RETVAL = newSVpv("0 but true", 0);
3146 else if (index == -1) {
3147 RETVAL = &PL_sv_undef;
3150 RETVAL = newSViv(index);
3156 i_setcolors(im, index, ...)
3164 croak("i_setcolors: no colors to add");
3165 colors = mymalloc((items-2) * sizeof(i_color));
3166 for (i=0; i < items-2; ++i) {
3167 if (sv_isobject(ST(i+2))
3168 && sv_derived_from(ST(i+2), "Imager::Color")) {
3169 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3170 colors[i] = *INT2PTR(i_color *, tmp);
3174 croak("i_setcolors: pixels must be Imager::Color objects");
3177 RETVAL = i_setcolors(im, index, colors, items-2);
3183 i_getcolors(im, index, ...)
3192 croak("i_getcolors: too many arguments");
3194 count = SvIV(ST(2));
3196 croak("i_getcolors: count must be positive");
3197 colors = mymalloc(sizeof(i_color) * count);
3198 if (i_getcolors(im, index, colors, count)) {
3199 for (i = 0; i < count; ++i) {
3200 SV *sv = make_i_color_sv(aTHX_ colors+i);
3216 i_findcolor(im, color)
3222 if (i_findcolor(im, color, &index)) {
3223 RETVAL = newSViv(index);
3226 RETVAL = &PL_sv_undef;
3244 i_gsamp(im, l, r, y, channels)
3249 i_channel_list channels
3255 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
3256 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3257 if (GIMME_V == G_ARRAY) {
3259 for (i = 0; i < count; ++i)
3260 PUSHs(sv_2mortal(newSViv(data[i])));
3264 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3269 if (GIMME_V != G_ARRAY) {
3271 PUSHs(&PL_sv_undef);
3276 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3284 i_channel_list channels
3291 croak("No channel numbers supplied to g_samp()");
3293 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3294 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3295 for (i = 0; i < count; ++i) {
3296 av_store(target, i+offset, newSVuv(data[i]));
3308 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3313 i_channel_list channels
3315 i_img_dim data_offset
3316 i_img_dim pixel_count
3325 data_count = av_len(data_av) + 1;
3326 if (data_offset < 0) {
3327 croak("data_offset must be non-negative");
3329 if (data_offset > data_count) {
3330 croak("data_offset greater than number of samples supplied");
3332 if (pixel_count == -1 ||
3333 data_offset + pixel_count * channels.count > data_count) {
3334 pixel_count = (data_count - data_offset) / channels.count;
3337 data_used = pixel_count * channels.count;
3338 data = mymalloc(sizeof(unsigned) * data_count);
3339 for (i = 0; i < data_used; ++i)
3340 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3342 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3343 channels.count, bits);
3351 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3355 i_channel_list channels
3364 i_push_error(0, "offset must be non-negative");
3368 if (offset > data.count) {
3369 i_push_error(0, "offset greater than number of samples supplied");
3372 data.samples += offset;
3373 data.count -= offset;
3376 width * channels.count > data.count) {
3377 width = data.count / channels.count;
3380 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3385 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3389 i_channel_list channels
3398 i_push_error(0, "offset must be non-negative");
3402 if (offset > data.count) {
3403 i_push_error(0, "offset greater than number of samples supplied");
3406 data.samples += offset;
3407 data.count -= offset;
3410 width * channels.count > data.count) {
3411 width = data.count / channels.count;
3414 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3419 i_img_masked_new(targ, mask, x, y, w, h)
3429 if (!sv_isobject(ST(1))
3430 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3431 croak("i_img_masked_new: parameter 2 must undef or an image");
3433 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3437 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3442 i_plin(im, l, y, ...)
3453 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3454 /* supplied as a byte string */
3455 work = (i_color *)SvPV(ST(3), len);
3456 count = len / sizeof(i_color);
3457 if (count * sizeof(i_color) != len) {
3458 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3460 RETVAL = i_plin(im, l, l+count, y, work);
3463 work = mymalloc(sizeof(i_color) * (items-3));
3464 for (i=0; i < items-3; ++i) {
3465 if (sv_isobject(ST(i+3))
3466 && sv_derived_from(ST(i+3), "Imager::Color")) {
3467 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3468 work[i] = *INT2PTR(i_color *, tmp);
3472 croak("i_plin: pixels must be Imager::Color objects");
3475 RETVAL = i_plin(im, l, l+items-3, y, work);
3486 i_ppixf(im, x, y, cl)
3490 Imager::Color::Float cl
3493 i_gsampf(im, l, r, y, channels)
3498 i_channel_list channels
3504 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3505 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3506 if (GIMME_V == G_ARRAY) {
3508 for (i = 0; i < count; ++i)
3509 PUSHs(sv_2mortal(newSVnv(data[i])));
3513 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3518 if (GIMME_V != G_ARRAY) {
3520 PUSHs(&PL_sv_undef);
3525 i_plinf(im, l, y, ...)
3536 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3537 /* supplied as a byte string */
3538 work = (i_fcolor *)SvPV(ST(3), len);
3539 count = len / sizeof(i_fcolor);
3540 if (count * sizeof(i_fcolor) != len) {
3541 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3543 RETVAL = i_plinf(im, l, l+count, y, work);
3546 work = mymalloc(sizeof(i_fcolor) * (items-3));
3547 for (i=0; i < items-3; ++i) {
3548 if (sv_isobject(ST(i+3))
3549 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3550 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3551 work[i] = *INT2PTR(i_fcolor *, tmp);
3555 croak("i_plinf: pixels must be Imager::Color::Float objects");
3559 RETVAL = i_plinf(im, l, l+items-3, y, work);
3577 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3578 if (i_gpixf(im, x, y, color) == 0) {
3579 RETVAL = NEWSV(0,0);
3580 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3584 RETVAL = &PL_sv_undef;
3600 vals = mymalloc((r-l) * sizeof(i_color));
3601 memset(vals, 0, (r-l) * sizeof(i_color));
3602 count = i_glin(im, l, r, y, vals);
3603 if (GIMME_V == G_ARRAY) {
3605 for (i = 0; i < count; ++i) {
3606 SV *sv = make_i_color_sv(aTHX_ vals+i);
3612 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3618 i_glinf(im, l, r, y)
3628 for (i = 0; i < MAXCHANNELS; ++i)
3629 zero.channel[i] = 0;
3631 vals = mymalloc((r-l) * sizeof(i_fcolor));
3632 for (i = 0; i < r-l; ++i)
3634 count = i_glinf(im, l, r, y, vals);
3635 if (GIMME_V == G_ARRAY) {
3637 for (i = 0; i < count; ++i) {
3639 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3641 sv = sv_newmortal();
3642 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3648 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3654 i_img_8_new(x, y, ch)
3660 i_img_16_new(x, y, ch)
3670 i_img_double_new(x, y, ch)
3680 i_tags_addn(im, name, code, idata)
3689 name = SvPV(ST(1), len);
3692 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3697 i_tags_add(im, name, code, data, idata)
3707 name = SvPV(ST(1), len);
3711 data = SvPV(ST(3), len);
3716 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3721 i_tags_find(im, name, start)
3728 if (i_tags_find(&im->tags, name, start, &entry)) {
3730 RETVAL = newSVpv("0 but true", 0);
3732 RETVAL = newSViv(entry);
3734 RETVAL = &PL_sv_undef;
3740 i_tags_findn(im, code, start)
3747 if (i_tags_findn(&im->tags, code, start, &entry)) {
3749 RETVAL = newSVpv("0 but true", 0);
3751 RETVAL = newSViv(entry);
3754 RETVAL = &PL_sv_undef;
3760 i_tags_delete(im, entry)
3764 RETVAL = i_tags_delete(&im->tags, entry);
3769 i_tags_delbyname(im, name)
3773 RETVAL = i_tags_delbyname(&im->tags, name);
3778 i_tags_delbycode(im, code)
3782 RETVAL = i_tags_delbycode(&im->tags, code);
3787 i_tags_get(im, index)
3791 if (index >= 0 && index < im->tags.count) {
3792 i_img_tag *entry = im->tags.tags + index;
3796 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3799 PUSHs(sv_2mortal(newSViv(entry->code)));
3802 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3805 PUSHs(sv_2mortal(newSViv(entry->idata)));
3810 i_tags_get_string(im, what_sv)
3814 char const *name = NULL;
3818 if (SvIOK(what_sv)) {
3819 code = SvIV(what_sv);
3823 name = SvPV_nolen(what_sv);
3826 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3828 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3835 RETVAL = im->tags.count;
3841 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3845 Imager::FillHandle fill
3848 IFILL_CLONE_SKIP(...)
3850 (void)items; /* avoid unused warning for XS variable */
3855 MODULE = Imager PACKAGE = Imager
3858 i_new_fill_solid(cl, combine)
3863 i_new_fill_solidf(cl, combine)
3864 Imager::Color::Float cl
3868 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3876 unsigned char *cust_hatch;
3880 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3884 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3889 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3890 Imager::Color::Float fg
3891 Imager::Color::Float bg
3897 unsigned char *cust_hatch;
3901 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3905 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3910 i_new_fill_image(src, matrix, xoff, yoff, combine)
3927 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3928 croak("i_new_fill_image: parameter must be an arrayref");
3929 av=(AV*)SvRV(ST(1));
3933 for (i = 0; i < len; ++i) {
3934 sv1=(*(av_fetch(av,i,0)));
3935 matrix[i] = SvNV(sv1);
3941 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3945 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
3947 # this class is only exposed for testing
3950 i_int_hlines_testing()
3952 #if i_int_hlines_testing()
3954 Imager::Internal::Hlines
3955 i_int_hlines_new(start_y, count_y, start_x, count_x)
3961 Imager::Internal::Hlines
3962 i_int_hlines_new_img(im)
3966 i_int_hlines_add(hlines, y, minx, width)
3967 Imager::Internal::Hlines hlines
3973 i_int_hlines_DESTROY(hlines)
3974 Imager::Internal::Hlines hlines
3977 i_int_hlines_dump(hlines)
3978 Imager::Internal::Hlines hlines
3981 i_int_hlines_CLONE_SKIP(cls)
3985 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
3988 im_context_DESTROY(ctx)
3991 #ifdef PERL_IMPLICIT_CONTEXT
3994 im_context_CLONE(...)
3998 /* the following sv_setref_pv() will free this inc */
3999 im_context_refinc(MY_CXT.ctx, "CLONE");
4000 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4001 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4006 PERL_SET_GLOBAL_CALLBACKS;
4007 PERL_PL_SET_GLOBAL_CALLBACKS;
4008 #ifdef PERL_IMPLICIT_CONTEXT
4014 start_context(aTHX);
4015 im_get_context = perl_get_context;