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"
26 #if i_int_hlines_testing()
34 Context object management
38 typedef im_context_t Imager__Context;
40 #define im_context_DESTROY(ctx) im_context_refdec((ctx), "DESTROY")
42 #ifdef PERL_IMPLICIT_CONTEXT
44 #define MY_CXT_KEY "Imager::_context" XS_VERSION
52 im_context_t fallback_context;
57 MY_CXT.ctx = im_context_new();
58 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
60 /* Ideally we'd free this reference, but the error message memory
61 was never released on exit, so the associated memory here is reasonable
63 With logging enabled we always need at least one context, since
64 objects may be released fairly late and attempt to get the log file.
66 im_context_refinc(MY_CXT.ctx, "start_context");
67 fallback_context = MY_CXT.ctx;
71 perl_get_context(void) {
75 return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
80 static im_context_t perl_context;
84 perl_context = im_context_new();
85 im_context_refinc(perl_context, "start_context");
89 perl_get_context(void) {
95 /* used to represent channel lists parameters */
96 typedef struct i_channel_list_tag {
103 const i_sample_t *samples;
108 const i_fsample_t *samples;
113 Allocate memory that will be discarded when mortals are discarded.
118 malloc_temp(pTHX_ size_t size) {
119 SV *sv = sv_2mortal(newSV(size));
124 /* These functions are all shared - then comes platform dependant code */
125 static int getstr(void *hv_t,char *key,char **store) {
130 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
132 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
134 svpp=hv_fetch(hv, key, strlen(key), 0);
135 *store=SvPV(*svpp, PL_na );
140 static int getint(void *hv_t,char *key,int *store) {
145 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
147 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
149 svpp=hv_fetch(hv, key, strlen(key), 0);
150 *store=(int)SvIV(*svpp);
154 static int getdouble(void *hv_t,char* key,double *store) {
159 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
161 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
162 svpp=hv_fetch(hv, key, strlen(key), 0);
163 *store=(double)SvNV(*svpp);
167 static int getvoid(void *hv_t,char* key,void **store) {
172 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
174 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
176 svpp=hv_fetch(hv, key, strlen(key), 0);
177 *store = INT2PTR(void*, SvIV(*svpp));
182 static int getobj(void *hv_t,char *key,char *type,void **store) {
187 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
189 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
191 svpp=hv_fetch(hv, key, strlen(key), 0);
193 if (sv_derived_from(*svpp,type)) {
194 IV tmp = SvIV((SV*)SvRV(*svpp));
195 *store = INT2PTR(void*, tmp);
197 mm_log((1,"getobj: key exists in hash but is not of correct type"));
204 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
206 void my_SvREFCNT_dec(void *p) {
208 SvREFCNT_dec((SV*)p);
213 i_log_entry(char *string, int level) {
214 mm_log((level, "%s", string));
218 make_i_color_sv(pTHX_ const i_color *c) {
220 i_color *col = mymalloc(sizeof(i_color));
223 sv_setref_pv(sv, "Imager::Color", (void *)col);
228 #define CBDATA_BUFSIZE 8192
231 /* the SVs we use to call back to Perl */
239 call_reader(struct cbdata *cbd, void *buf, size_t size,
247 if (!SvOK(cbd->readcb)) {
248 mm_log((1, "read callback called but no readcb supplied\n"));
249 i_push_error(0, "read callback called but no readcb supplied");
257 PUSHs(sv_2mortal(newSViv(size)));
258 PUSHs(sv_2mortal(newSViv(maxread)));
261 count = perl_call_sv(cbd->readcb, G_SCALAR);
266 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
272 char *ptr = SvPVbyte(data, len);
274 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
275 (int)size, (int)len, (int)maxread);
277 memcpy(buf, ptr, len);
292 io_seeker(void *p, off_t offset, int whence) {
294 struct cbdata *cbd = p;
299 if (!SvOK(cbd->seekcb)) {
300 mm_log((1, "seek callback called but no seekcb supplied\n"));
301 i_push_error(0, "seek callback called but no seekcb supplied");
309 PUSHs(sv_2mortal(newSViv(offset)));
310 PUSHs(sv_2mortal(newSViv(whence)));
313 count = perl_call_sv(cbd->seekcb, G_SCALAR);
318 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
330 io_writer(void *p, void const *data, size_t size) {
332 struct cbdata *cbd = p;
338 if (!SvOK(cbd->writecb)) {
339 mm_log((1, "write callback called but no writecb supplied\n"));
340 i_push_error(0, "write callback called but no writecb supplied");
348 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
351 count = perl_call_sv(cbd->writecb, G_SCALAR);
355 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
358 success = SvTRUE(sv);
365 return success ? size : -1;
369 io_reader(void *p, void *data, size_t size) {
370 struct cbdata *cbd = p;
372 return call_reader(cbd, data, size, size);
375 static int io_closer(void *p) {
377 struct cbdata *cbd = p;
380 if (SvOK(cbd->closecb)) {
390 count = perl_call_sv(cbd->closecb, G_SCALAR);
395 success = SvTRUE(sv);
402 return success ? 0 : -1;
405 static void io_destroyer(void *p) {
407 struct cbdata *cbd = p;
409 SvREFCNT_dec(cbd->writecb);
410 SvREFCNT_dec(cbd->readcb);
411 SvREFCNT_dec(cbd->seekcb);
412 SvREFCNT_dec(cbd->closecb);
417 do_io_new_buffer(pTHX_ SV *data_sv) {
421 data = SvPVbyte(data_sv, length);
422 SvREFCNT_inc(data_sv);
423 return io_new_buffer(data, length, my_SvREFCNT_dec, data_sv);
427 describe_sv(SV *sv) {
430 svtype type = SvTYPE(SvRV(sv));
432 case SVt_PVCV: return "CV";
433 case SVt_PVGV: return "GV";
434 case SVt_PVLV: return "LV";
435 default: return "some reference";
439 return "non-reference scalar";
448 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
451 cbd = mymalloc(sizeof(struct cbdata));
452 cbd->writecb = newSVsv(writecb);
453 cbd->readcb = newSVsv(readcb);
454 cbd->seekcb = newSVsv(seekcb);
455 cbd->closecb = newSVsv(closecb);
457 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)));
459 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
467 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
470 for (i = 0; i < count; ++i)
471 if (strEQ(names[i].name, name))
472 return names[i].value;
476 static struct value_name transp_names[] =
479 { "threshold", tr_threshold },
480 { "errdiff", tr_errdiff },
481 { "ordered", tr_ordered, },
484 static struct value_name make_color_names[] =
486 { "none", mc_none, },
487 { "webmap", mc_web_map, },
488 { "addi", mc_addi, },
489 { "mediancut", mc_median_cut, },
490 { "mono", mc_mono, },
491 { "monochrome", mc_mono, },
492 { "gray", mc_gray, },
493 { "gray4", mc_gray4, },
494 { "gray16", mc_gray16, },
497 static struct value_name translate_names[] =
499 { "giflib", pt_giflib, },
500 { "closest", pt_closest, },
501 { "perturb", pt_perturb, },
502 { "errdiff", pt_errdiff, },
505 static struct value_name errdiff_names[] =
507 { "floyd", ed_floyd, },
508 { "jarvis", ed_jarvis, },
509 { "stucki", ed_stucki, },
510 { "custom", ed_custom, },
513 static struct value_name orddith_names[] =
515 { "random", od_random, },
516 { "dot8", od_dot8, },
517 { "dot4", od_dot4, },
518 { "hline", od_hline, },
519 { "vline", od_vline, },
520 { "/line", od_slashline, },
521 { "slashline", od_slashline, },
522 { "\\line", od_backline, },
523 { "backline", od_backline, },
524 { "tiny", od_tiny, },
525 { "custom", od_custom, },
528 /* look through the hash for quantization options */
530 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
532 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
538 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
540 sv = hv_fetch(hv, "transp", 6, 0);
541 if (sv && *sv && (str = SvPV(*sv, len))) {
543 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
545 if (quant->transp != tr_none) {
546 quant->tr_threshold = 127;
547 sv = hv_fetch(hv, "tr_threshold", 12, 0);
549 quant->tr_threshold = SvIV(*sv);
551 if (quant->transp == tr_errdiff) {
552 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
553 if (sv && *sv && (str = SvPV(*sv, len)))
554 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
556 if (quant->transp == tr_ordered) {
557 quant->tr_orddith = od_tiny;
558 sv = hv_fetch(hv, "tr_orddith", 10, 0);
559 if (sv && *sv && (str = SvPV(*sv, len)))
560 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
562 if (quant->tr_orddith == od_custom) {
563 sv = hv_fetch(hv, "tr_map", 6, 0);
564 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
565 AV *av = (AV*)SvRV(*sv);
566 len = av_len(av) + 1;
567 if (len > sizeof(quant->tr_custom))
568 len = sizeof(quant->tr_custom);
569 for (i = 0; i < len; ++i) {
570 SV **sv2 = av_fetch(av, i, 0);
572 quant->tr_custom[i] = SvIV(*sv2);
575 while (i < sizeof(quant->tr_custom))
576 quant->tr_custom[i++] = 0;
581 quant->make_colors = mc_median_cut;
582 sv = hv_fetch(hv, "make_colors", 11, 0);
583 if (sv && *sv && (str = SvPV(*sv, len))) {
585 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
587 sv = hv_fetch(hv, "colors", 6, 0);
588 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
589 /* needs to be an array of Imager::Color
590 note that the caller allocates the mc_color array and sets mc_size
592 AV *av = (AV *)SvRV(*sv);
593 quant->mc_count = av_len(av)+1;
594 if (quant->mc_count > quant->mc_size)
595 quant->mc_count = quant->mc_size;
596 for (i = 0; i < quant->mc_count; ++i) {
597 SV **sv1 = av_fetch(av, i, 0);
598 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
599 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
600 quant->mc_colors[i] = *col;
604 sv = hv_fetch(hv, "max_colors", 10, 0);
607 if (i <= quant->mc_size && i >= quant->mc_count)
611 quant->translate = pt_closest;
612 sv = hv_fetch(hv, "translate", 9, 0);
613 if (sv && *sv && (str = SvPV(*sv, len))) {
614 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
616 sv = hv_fetch(hv, "errdiff", 7, 0);
617 if (sv && *sv && (str = SvPV(*sv, len))) {
618 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
620 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
621 /* get the error diffusion map */
622 sv = hv_fetch(hv, "errdiff_width", 13, 0);
624 quant->ed_width = SvIV(*sv);
625 sv = hv_fetch(hv, "errdiff_height", 14, 0);
627 quant->ed_height = SvIV(*sv);
628 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
630 quant->ed_orig = SvIV(*sv);
631 if (quant->ed_width > 0 && quant->ed_height > 0) {
633 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
634 sv = hv_fetch(hv, "errdiff_map", 11, 0);
635 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
636 AV *av = (AV*)SvRV(*sv);
637 len = av_len(av) + 1;
638 if (len > quant->ed_width * quant->ed_height)
639 len = quant->ed_width * quant->ed_height;
640 for (i = 0; i < len; ++i) {
641 SV **sv2 = av_fetch(av, i, 0);
643 quant->ed_map[i] = SvIV(*sv2);
644 sum += quant->ed_map[i];
650 myfree(quant->ed_map);
652 quant->errdiff = ed_floyd;
656 sv = hv_fetch(hv, "perturb", 7, 0);
658 quant->perturb = SvIV(*sv);
662 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
663 myfree(quant->mc_colors);
665 myfree(quant->ed_map);
668 /* copies the color map from the hv into the colors member of the HV */
670 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
676 sv = hv_fetch(hv, "colors", 6, 0);
677 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
682 av = (AV *)SvRV(*sv);
684 av_extend(av, quant->mc_count+1);
685 for (i = 0; i < quant->mc_count; ++i) {
686 i_color *in = quant->mc_colors+i;
687 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
688 work = sv_newmortal();
689 sv_setref_pv(work, "Imager::Color", (void *)c);
695 /* loads the segments of a fountain fill into an array */
696 static i_fountain_seg *
697 load_fount_segs(pTHX_ AV *asegs, int *count) {
698 /* Each element of segs must contain:
699 [ start, middle, end, c0, c1, segtype, colortrans ]
700 start, middle, end are doubles from 0 to 1
701 c0, c1 are Imager::Color::Float or Imager::Color objects
702 segtype, colortrans are ints
706 i_fountain_seg *segs;
710 *count = av_len(asegs)+1;
712 croak("i_fountain must have at least one segment");
713 segs = mymalloc(sizeof(i_fountain_seg) * *count);
714 for(i = 0; i < *count; i++) {
715 SV **sv1 = av_fetch(asegs, i, 0);
716 if (!sv1 || !*sv1 || !SvROK(*sv1)
717 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
719 croak("i_fountain: segs must be an arrayref of arrayrefs");
721 aseg = (AV *)SvRV(*sv1);
722 if (av_len(aseg) != 7-1) {
724 croak("i_fountain: a segment must have 7 members");
726 for (j = 0; j < 3; ++j) {
727 SV **sv2 = av_fetch(aseg, j, 0);
730 croak("i_fountain: XS error");
732 work[j] = SvNV(*sv2);
734 segs[i].start = work[0];
735 segs[i].middle = work[1];
736 segs[i].end = work[2];
737 for (j = 0; j < 2; ++j) {
738 SV **sv3 = av_fetch(aseg, 3+j, 0);
739 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
740 (!sv_derived_from(*sv3, "Imager::Color")
741 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
743 croak("i_fountain: segs must contain colors in elements 3 and 4");
745 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
746 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
749 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
751 for (ch = 0; ch < MAXCHANNELS; ++ch) {
752 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
756 for (j = 0; j < 2; ++j) {
757 SV **sv2 = av_fetch(aseg, j+5, 0);
760 croak("i_fountain: XS error");
762 worki[j] = SvIV(*sv2);
764 segs[i].type = worki[0];
765 segs[i].color = worki[1];
771 /* validates the indexes supplied to i_ppal
773 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
778 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
779 int color_count = i_colorcount(im);
782 if (color_count == -1)
783 croak("i_plin() called on direct color image");
785 for (i = 0; i < count; ++i) {
786 if (indexes[i] >= color_count) {
787 croak("i_plin() called with out of range color index %d (max %d)",
788 indexes[i], color_count-1);
793 /* I don't think ICLF_* names belong at the C interface
794 this makes the XS code think we have them, to let us avoid
795 putting function bodies in the XS code
797 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
798 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
801 #define i_log_enabled() 1
803 #define i_log_enabled() 0
806 #if i_int_hlines_testing()
808 typedef i_int_hlines *Imager__Internal__Hlines;
810 static i_int_hlines *
811 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
812 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
813 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
818 static i_int_hlines *
819 i_int_hlines_new_img(i_img *im) {
820 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
821 i_int_init_hlines_img(result, im);
827 i_int_hlines_DESTROY(i_int_hlines *hlines) {
828 i_int_hlines_destroy(hlines);
832 #define i_int_hlines_CLONE_SKIP(cls) 1
834 static int seg_compare(const void *vleft, const void *vright) {
835 const i_int_hline_seg *left = vleft;
836 const i_int_hline_seg *right = vright;
838 return left->minx - right->minx;
842 i_int_hlines_dump(i_int_hlines *hlines) {
844 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
845 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
848 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
849 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
852 /* sort the segments, if any */
854 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
856 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
857 for (i = 0; i < entry->count; ++i) {
858 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
859 i_DFc(entry->segs[i].x_limit));
861 sv_catpv(dump, "\n");
871 i_sv_off_t(pTHX_ SV *sv) {
872 #if LSEEKSIZE > IVSIZE
873 return (off_t)SvNV(sv);
875 return (off_t)SvIV(sv);
880 i_new_sv_off_t(pTHX_ off_t off) {
881 #if LSEEKSIZE > IVSIZE
888 static im_pl_ext_funcs im_perl_funcs =
890 IMAGER_PL_API_VERSION,
892 ip_handle_quant_opts,
893 ip_cleanup_quant_opts,
897 #define PERL_PL_SET_GLOBAL_CALLBACKS \
898 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
900 #define IIM_new i_img_8_new
901 #define IIM_DESTROY i_img_destroy
904 #define i_exif_enabled() 1
906 #define i_exif_enabled() 0
909 /* trying to use more C style names, map them here */
910 #define i_io_DESTROY(ig) io_glue_destroy(ig)
912 #define i_img_get_width(im) ((im)->xsize)
913 #define i_img_get_height(im) ((im)->ysize)
915 #define i_img_epsilonf() (DBL_EPSILON * 4)
917 /* avoid some xsubpp strangeness */
920 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
923 ICL_new_internal(r,g,b,a)
935 ICL_set_internal(cl,r,g,b,a)
942 ICL_set_internal(cl, r, g, b, a);
956 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
957 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
958 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
959 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
965 RETVAL = mymalloc(sizeof(i_color));
967 i_hsv_to_rgb(RETVAL);
975 RETVAL = mymalloc(sizeof(i_color));
977 i_rgb_to_hsv(RETVAL);
983 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
986 ICLF_new_internal(r, g, b, a)
994 Imager::Color::Float cl
998 Imager::Color::Float cl
1002 EXTEND(SP, MAXCHANNELS);
1003 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1004 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1005 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1009 ICLF_set_internal(cl,r,g,b,a)
1010 Imager::Color::Float cl
1023 Imager::Color::Float
1025 Imager::Color::Float c
1027 RETVAL = mymalloc(sizeof(i_fcolor));
1029 i_hsv_to_rgbf(RETVAL);
1033 Imager::Color::Float
1035 Imager::Color::Float c
1037 RETVAL = mymalloc(sizeof(i_fcolor));
1039 i_rgb_to_hsvf(RETVAL);
1043 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1057 MODULE = Imager PACKAGE = Imager
1071 io_new_buffer(data_sv)
1074 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1079 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1086 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1094 unsigned char* data;
1098 tlength = io_slurp(ig, &data);
1099 RETVAL = newSVpv((char *)data,tlength);
1106 i_set_image_file_limits(width, height, bytes)
1112 i_get_image_file_limits()
1114 i_img_dim width, height;
1117 if (i_get_image_file_limits(&width, &height, &bytes)) {
1119 PUSHs(sv_2mortal(newSViv(width)));
1120 PUSHs(sv_2mortal(newSViv(height)));
1121 PUSHs(sv_2mortal(newSVuv(bytes)));
1125 i_int_check_image_file_limits(width, height, channels, sample_size)
1132 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
1135 io_new_fd(class, fd)
1138 RETVAL = io_new_fd(fd);
1143 io_new_buffer(class, data_sv)
1146 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1151 io_new_cb(class, writecb, readcb, seekcb, closecb)
1157 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1162 io_new_bufchain(class)
1164 RETVAL = io_new_bufchain();
1172 unsigned char* data;
1176 tlength = io_slurp(ig, &data);
1177 RETVAL = newSVpv((char *)data,tlength);
1182 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1185 i_io_raw_write(ig, data_sv)
1193 if (SvUTF8(data_sv)) {
1194 data_sv = sv_2mortal(newSVsv(data_sv));
1195 /* yes, we want this to croak() if the SV can't be downgraded */
1196 sv_utf8_downgrade(data_sv, FALSE);
1199 data = SvPV(data_sv, size);
1200 RETVAL = i_io_raw_write(ig, data, size);
1205 i_io_raw_read(ig, buffer_sv, size)
1214 croak("size negative in call to i_io_raw_read()");
1215 /* prevent an undefined value warning if they supplied an
1217 Orginally conditional on !SvOK(), but this will prevent the
1218 downgrade from croaking */
1219 sv_setpvn(buffer_sv, "", 0);
1221 if (SvUTF8(buffer_sv))
1222 sv_utf8_downgrade(buffer_sv, FALSE);
1224 buffer = SvGROW(buffer_sv, size+1);
1225 result = i_io_raw_read(ig, buffer, size);
1227 SvCUR_set(buffer_sv, result);
1228 *SvEND(buffer_sv) = '\0';
1229 SvPOK_only(buffer_sv);
1231 PUSHs(sv_2mortal(newSViv(result)));
1237 i_io_raw_read2(ig, size)
1246 croak("size negative in call to i_io_read2()");
1247 buffer_sv = newSV(size);
1248 buffer = SvGROW(buffer_sv, size+1);
1249 result = i_io_raw_read(ig, buffer, size);
1251 SvCUR_set(buffer_sv, result);
1252 *SvEND(buffer_sv) = '\0';
1253 SvPOK_only(buffer_sv);
1255 PUSHs(sv_2mortal(buffer_sv));
1259 SvREFCNT_dec(buffer_sv);
1263 i_io_raw_seek(ig, position, whence)
1277 i_io_CLONE_SKIP(...)
1279 (void)items; /* avoid unused warning for XS variable */
1306 i_io_seek(ig, off, whence)
1312 i_io_peekn(ig, size)
1320 buffer_sv = newSV(size+1);
1321 buffer = SvGROW(buffer_sv, size+1);
1322 result = i_io_peekn(ig, buffer, size);
1324 SvCUR_set(buffer_sv, result);
1325 *SvEND(buffer_sv) = '\0';
1326 SvPOK_only(buffer_sv);
1328 PUSHs(sv_2mortal(buffer_sv));
1332 SvREFCNT_dec(buffer_sv);
1336 i_io_read(ig, buffer_sv, size)
1345 croak("size negative in call to i_io_read()");
1346 /* prevent an undefined value warning if they supplied an
1348 Orginally conditional on !SvOK(), but this will prevent the
1349 downgrade from croaking */
1350 sv_setpvn(buffer_sv, "", 0);
1352 if (SvUTF8(buffer_sv))
1353 sv_utf8_downgrade(buffer_sv, FALSE);
1355 buffer = SvGROW(buffer_sv, size+1);
1356 result = i_io_read(ig, buffer, size);
1358 SvCUR_set(buffer_sv, result);
1359 *SvEND(buffer_sv) = '\0';
1360 SvPOK_only(buffer_sv);
1362 PUSHs(sv_2mortal(newSViv(result)));
1368 i_io_read2(ig, size)
1377 croak("size zero in call to read2()");
1378 buffer_sv = newSV(size);
1379 buffer = SvGROW(buffer_sv, size+1);
1380 result = i_io_read(ig, buffer, size);
1382 SvCUR_set(buffer_sv, result);
1383 *SvEND(buffer_sv) = '\0';
1384 SvPOK_only(buffer_sv);
1386 PUSHs(sv_2mortal(buffer_sv));
1390 SvREFCNT_dec(buffer_sv);
1394 i_io_gets(ig, size = 8192, eol = NEWLINE)
1404 croak("size too small in call to gets()");
1405 buffer_sv = sv_2mortal(newSV(size+1));
1406 buffer = SvPVX(buffer_sv);
1407 result = i_io_gets(ig, buffer, size+1, eol);
1409 SvCUR_set(buffer_sv, result);
1410 *SvEND(buffer_sv) = '\0';
1411 SvPOK_only(buffer_sv);
1417 i_io_write(ig, data_sv)
1425 if (SvUTF8(data_sv)) {
1426 data_sv = sv_2mortal(newSVsv(data_sv));
1427 /* yes, we want this to croak() if the SV can't be downgraded */
1428 sv_utf8_downgrade(data_sv, FALSE);
1431 data = SvPV(data_sv, size);
1432 RETVAL = i_io_write(ig, data, size);
1437 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1442 i_io_set_buffered(ig, flag = 1)
1447 i_io_is_buffered(ig)
1458 MODULE = Imager PACKAGE = Imager
1469 while( (item=i_format_list[i++]) != NULL ) {
1471 PUSHs(sv_2mortal(newSVpv(item,0)));
1475 i_sametype(im, x, y)
1481 i_sametype_chans(im, x, y, channels)
1488 i_init_log(name_sv,level)
1492 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1494 RETVAL = i_init_log(name, level);
1499 i_log_entry(string,level)
1512 i_img_info(im,info);
1514 PUSHs(sv_2mortal(newSViv(info[0])));
1515 PUSHs(sv_2mortal(newSViv(info[1])));
1516 PUSHs(sv_2mortal(newSViv(info[2])));
1517 PUSHs(sv_2mortal(newSViv(info[3])));
1523 i_img_setmask(im,ch_mask)
1532 i_img_getchannels(im)
1541 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1549 i_img_get_height(im)
1554 i_img_is_monochrome(im)
1560 result = i_img_is_monochrome(im, &zero_is_white);
1562 if (GIMME_V == G_ARRAY) {
1565 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1574 i_line(im,x1,y1,x2,y2,val,endp)
1584 i_line_aa(im,x1,y1,x2,y2,val,endp)
1594 i_box(im,x1,y1,x2,y2,val)
1603 i_box_filled(im,x1,y1,x2,y2,val)
1612 i_box_filledf(im,x1,y1,x2,y2,val)
1618 Imager::Color::Float val
1621 i_box_cfill(im,x1,y1,x2,y2,fill)
1627 Imager::FillHandle fill
1630 i_arc(im,x,y,rad,d1,d2,val)
1640 i_arc_aa(im,x,y,rad,d1,d2,val)
1650 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1657 Imager::FillHandle fill
1660 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1667 Imager::FillHandle fill
1671 i_circle_aa(im,x,y,rad,val)
1679 i_circle_out(im,x,y,rad,val)
1687 i_circle_out_aa(im,x,y,rad,val)
1695 i_arc_out(im,x,y,rad,d1,d2,val)
1705 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1716 i_bezier_multi(im,xc,yc,val)
1729 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1730 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1731 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1732 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1733 av1=(AV*)SvRV(ST(1));
1734 av2=(AV*)SvRV(ST(2));
1735 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1737 x=mymalloc( len*sizeof(double) );
1738 y=mymalloc( len*sizeof(double) );
1739 for(i=0;i<len;i++) {
1740 sv1=(*(av_fetch(av1,i,0)));
1741 sv2=(*(av_fetch(av2,i,0)));
1742 x[i]=(double)SvNV(sv1);
1743 y[i]=(double)SvNV(sv2);
1745 i_bezier_multi(im,len,x,y,val);
1751 i_poly_aa(im,xc,yc,val)
1764 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1765 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1766 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1767 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1768 av1=(AV*)SvRV(ST(1));
1769 av2=(AV*)SvRV(ST(2));
1770 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1772 x=mymalloc( len*sizeof(double) );
1773 y=mymalloc( len*sizeof(double) );
1774 for(i=0;i<len;i++) {
1775 sv1=(*(av_fetch(av1,i,0)));
1776 sv2=(*(av_fetch(av2,i,0)));
1777 x[i]=(double)SvNV(sv1);
1778 y[i]=(double)SvNV(sv2);
1780 RETVAL = i_poly_aa(im,len,x,y,val);
1787 i_poly_aa_cfill(im,xc,yc,fill)
1789 Imager::FillHandle fill
1799 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1800 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1801 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1802 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1803 av1=(AV*)SvRV(ST(1));
1804 av2=(AV*)SvRV(ST(2));
1805 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1807 x=mymalloc( len*sizeof(double) );
1808 y=mymalloc( len*sizeof(double) );
1809 for(i=0;i<len;i++) {
1810 sv1=(*(av_fetch(av1,i,0)));
1811 sv2=(*(av_fetch(av2,i,0)));
1812 x[i]=(double)SvNV(sv1);
1813 y[i]=(double)SvNV(sv2);
1815 RETVAL = i_poly_aa_cfill(im,len,x,y,fill);
1824 i_flood_fill(im,seedx,seedy,dcol)
1831 i_flood_cfill(im,seedx,seedy,fill)
1835 Imager::FillHandle fill
1838 i_flood_fill_border(im,seedx,seedy,dcol, border)
1843 Imager::Color border
1846 i_flood_cfill_border(im,seedx,seedy,fill, border)
1850 Imager::FillHandle fill
1851 Imager::Color border
1855 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1867 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1884 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1895 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
1908 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)
1924 i_combine(src_av, channels_av = NULL)
1928 i_img **imgs = NULL;
1930 int *channels = NULL;
1935 in_count = av_len(src_av) + 1;
1937 imgs = mymalloc(sizeof(i_img*) * in_count);
1938 channels = mymalloc(sizeof(int) * in_count);
1939 for (i = 0; i < in_count; ++i) {
1940 psv = av_fetch(src_av, i, 0);
1941 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
1944 croak("imgs must contain only images");
1946 tmp = SvIV((SV*)SvRV(*psv));
1947 imgs[i] = INT2PTR(i_img*, tmp);
1949 (psv = av_fetch(channels_av, i, 0)) != NULL &&
1951 channels[i] = SvIV(*psv);
1958 RETVAL = i_combine(imgs, channels, in_count);
1965 i_flipxy(im, direction)
1970 i_rotate90(im, degrees)
1975 i_rotate_exact(im, amount, ...)
1979 i_color *backp = NULL;
1980 i_fcolor *fbackp = NULL;
1984 /* extract the bg colors if any */
1985 /* yes, this is kind of strange */
1986 for (i = 2; i < items; ++i) {
1988 if (sv_derived_from(sv1, "Imager::Color")) {
1989 IV tmp = SvIV((SV*)SvRV(sv1));
1990 backp = INT2PTR(i_color *, tmp);
1992 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1993 IV tmp = SvIV((SV*)SvRV(sv1));
1994 fbackp = INT2PTR(i_fcolor *, tmp);
1997 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
2002 i_matrix_transform(im, xsize, ysize, matrix, ...)
2012 i_color *backp = NULL;
2013 i_fcolor *fbackp = NULL;
2015 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
2016 croak("i_matrix_transform: parameter 4 must be an array ref\n");
2017 av=(AV*)SvRV(ST(3));
2021 for (i = 0; i < len; ++i) {
2022 sv1=(*(av_fetch(av,i,0)));
2023 matrix[i] = SvNV(sv1);
2027 /* extract the bg colors if any */
2028 /* yes, this is kind of strange */
2029 for (i = 4; i < items; ++i) {
2031 if (sv_derived_from(sv1, "Imager::Color")) {
2032 IV tmp = SvIV((SV*)SvRV(sv1));
2033 backp = INT2PTR(i_color *, tmp);
2035 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2036 IV tmp = SvIV((SV*)SvRV(sv1));
2037 fbackp = INT2PTR(i_fcolor *, tmp);
2040 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2045 i_gaussian(im,stdev)
2050 i_unsharp_mask(im,stdev,scale)
2065 len = av_len(coef) + 1;
2066 c_coef=mymalloc( len * sizeof(double) );
2067 for(i = 0; i < len; i++) {
2068 sv1 = (*(av_fetch(coef, i, 0)));
2069 c_coef[i] = (double)SvNV(sv1);
2071 RETVAL = i_conv(im, c_coef, len);
2077 i_convert(src, avmain)
2089 outchan = av_len(avmain)+1;
2090 /* find the biggest */
2092 for (j=0; j < outchan; ++j) {
2093 temp = av_fetch(avmain, j, 0);
2094 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2095 avsub = (AV*)SvRV(*temp);
2096 len = av_len(avsub)+1;
2101 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2105 coeff = mymalloc(sizeof(double) * outchan * inchan);
2106 for (j = 0; j < outchan; ++j) {
2107 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2108 len = av_len(avsub)+1;
2109 for (i = 0; i < len; ++i) {
2110 temp = av_fetch(avsub, i, 0);
2112 coeff[i+j*inchan] = SvNV(*temp);
2114 coeff[i+j*inchan] = 0;
2117 coeff[i++ + j*inchan] = 0;
2119 RETVAL = i_convert(src, coeff, outchan, inchan);
2129 unsigned int mask = 0;
2135 unsigned char (*maps)[256];
2137 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2138 croak("i_map: parameter 2 must be an arrayref\n");
2139 avmain = (AV*)SvRV(ST(1));
2140 len = av_len(avmain)+1;
2141 if (im->channels < len) len = im->channels;
2143 maps = mymalloc( len * sizeof(unsigned char [256]) );
2145 for (j=0; j<len ; j++) {
2146 temp = av_fetch(avmain, j, 0);
2147 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2148 avsub = (AV*)SvRV(*temp);
2149 if(av_len(avsub) != 255) continue;
2151 for (i=0; i<256 ; i++) {
2153 temp = av_fetch(avsub, i, 0);
2154 val = temp ? SvIV(*temp) : 0;
2156 if (val>255) val = 255;
2161 i_map(im, maps, mask);
2172 i_img_diffd(im1,im2)
2177 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2187 _is_color_object(sv)
2191 RETVAL = SvOK(sv) && SvROK(sv) &&
2192 (sv_derived_from(sv, "Imager::Color")
2193 || sv_derived_from(sv, "Imager::Color::Float"));
2205 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2207 #define TT_DESTROY(handle) i_tt_destroy(handle)
2211 Imager::Font::TT handle
2216 (void)items; /* avoid unused warning */
2222 MODULE = Imager PACKAGE = Imager
2226 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
2227 Imager::Font::TT handle
2245 str = SvPV(str_sv, len);
2246 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2247 len, smooth, utf8, align);
2253 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
2254 Imager::Font::TT handle
2272 str = SvPV(str_sv, len);
2273 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2274 smooth, utf8, align);
2280 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
2281 Imager::Font::TT handle
2286 i_img_dim cords[BOUNDING_BOX_COUNT];
2296 str = SvPV(str_sv, len);
2297 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2299 for (i = 0; i < rc; ++i) {
2300 PUSHs(sv_2mortal(newSViv(cords[i])));
2305 i_tt_has_chars(handle, text_sv, utf8)
2306 Imager::Font::TT handle
2317 if (SvUTF8(text_sv))
2320 text = SvPV(text_sv, len);
2321 work = mymalloc(len);
2322 count = i_tt_has_chars(handle, text, len, utf8, work);
2323 if (GIMME_V == G_ARRAY) {
2325 for (i = 0; i < count; ++i) {
2326 PUSHs(boolSV(work[i]));
2331 PUSHs(sv_2mortal(newSVpv(work, count)));
2336 i_tt_dump_names(handle)
2337 Imager::Font::TT handle
2340 i_tt_face_name(handle)
2341 Imager::Font::TT handle
2346 len = i_tt_face_name(handle, name, sizeof(name));
2349 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2353 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2354 Imager::Font::TT handle
2365 if (SvUTF8(text_sv))
2368 text = SvPV(text_sv, work_len);
2373 ch = i_utf8_advance(&text, &len);
2375 i_push_error(0, "invalid UTF8 character");
2384 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2385 PUSHs(sv_2mortal(newSVpv(name, 0)));
2388 PUSHs(&PL_sv_undef);
2395 i_test_format_probe(ig, length)
2400 i_readpnm_wiol(ig, allow_incomplete)
2402 int allow_incomplete
2406 i_readpnm_multi_wiol(ig, allow_incomplete)
2408 int allow_incomplete
2414 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2417 for (i = 0; i < count; ++i) {
2418 SV *sv = sv_newmortal();
2419 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2426 i_writeppm_wiol(im, ig)
2435 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2444 i_writeraw_wiol(im,ig)
2449 i_writebmp_wiol(im,ig)
2454 i_readbmp_wiol(ig, allow_incomplete=0)
2456 int allow_incomplete
2460 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2469 idlen = SvCUR(ST(4));
2470 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2476 i_readtga_wiol(ig, length)
2484 i_scaleaxis(im,Value,Axis)
2490 i_scale_nn(im,scx,scy)
2496 i_scale_mixing(im, width, height)
2506 i_count_colors(im,maxc)
2511 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2516 unsigned int * col_usage = NULL;
2519 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2520 EXTEND(SP, col_cnt);
2521 for (i = 0; i < col_cnt; i++) {
2522 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2529 i_transform(im,opx,opy,parm)
2543 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2544 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2545 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2546 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2547 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2548 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2549 av=(AV*)SvRV(ST(1));
2551 opx=mymalloc( opxl*sizeof(int) );
2552 for(i=0;i<opxl;i++) {
2553 sv1=(*(av_fetch(av,i,0)));
2554 opx[i]=(int)SvIV(sv1);
2556 av=(AV*)SvRV(ST(2));
2558 opy=mymalloc( opyl*sizeof(int) );
2559 for(i=0;i<opyl;i++) {
2560 sv1=(*(av_fetch(av,i,0)));
2561 opy[i]=(int)SvIV(sv1);
2563 av=(AV*)SvRV(ST(3));
2564 parmlen=av_len(av)+1;
2565 parm=mymalloc( parmlen*sizeof(double) );
2566 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2567 sv1=(*(av_fetch(av,i,0)));
2568 parm[i]=(double)SvNV(sv1);
2570 result=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2575 SV *result_sv = sv_newmortal();
2577 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2582 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2608 in_imgs_count = av_len(av_in_imgs)+1;
2609 for (i = 0; i < in_imgs_count; ++i) {
2610 sv1 = *av_fetch(av_in_imgs, i, 0);
2611 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2612 croak("sv_in_img must contain only images");
2615 if (in_imgs_count > 0) {
2616 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2617 for (i = 0; i < in_imgs_count; ++i) {
2618 sv1 = *av_fetch(av_in_imgs,i,0);
2619 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2620 croak("Parameter 5 must contain only images");
2622 tmp = SvIV((SV*)SvRV(sv1));
2623 in_imgs[i] = INT2PTR(i_img*, tmp);
2627 /* no input images */
2630 /* default the output size from the first input if possible */
2632 width = SvIV(sv_width);
2633 else if (in_imgs_count)
2634 width = in_imgs[0]->xsize;
2636 croak("No output image width supplied");
2638 if (SvOK(sv_height))
2639 height = SvIV(sv_height);
2640 else if (in_imgs_count)
2641 height = in_imgs[0]->ysize;
2643 croak("No output image height supplied");
2645 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2646 if (ops_len % sizeof(struct rm_op))
2647 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2648 ops_count = ops_len / sizeof(struct rm_op);
2650 n_regs_count = av_len(av_n_regs)+1;
2651 n_regs = mymalloc(n_regs_count * sizeof(double));
2652 for (i = 0; i < n_regs_count; ++i) {
2653 sv1 = *av_fetch(av_n_regs,i,0);
2655 n_regs[i] = SvNV(sv1);
2657 c_regs_count = av_len(av_c_regs)+1;
2658 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2659 /* I don't bother initializing the colou?r registers */
2661 result=i_transform2(width, height, channels, ops, ops_count,
2662 n_regs, n_regs_count,
2663 c_regs, c_regs_count, in_imgs, in_imgs_count);
2669 SV *result_sv = sv_newmortal();
2671 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2677 i_contrast(im,intensity)
2690 i_noise(im,amount,type)
2696 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2706 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2725 i_postlevels(im,levels)
2735 i_watermark(im,wmark,tx,ty,pixdiff)
2737 Imager::ImgRaw wmark
2744 i_autolevels(im,lsat,usat,skew)
2751 i_radnoise(im,xo,yo,rscale,ascale)
2759 i_turbnoise(im, xo, yo, scale)
2782 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2783 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2784 croak("i_gradgen: Second argument must be an array ref");
2785 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2786 croak("i_gradgen: Third argument must be an array ref");
2787 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2788 croak("i_gradgen: Fourth argument must be an array ref");
2789 axx = (AV *)SvRV(ST(1));
2790 ayy = (AV *)SvRV(ST(2));
2791 ac = (AV *)SvRV(ST(3));
2792 dmeasure = (int)SvIV(ST(4));
2794 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2795 num = num <= av_len(ac) ? num : av_len(ac);
2797 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2798 xo = mymalloc( sizeof(i_img_dim) * num );
2799 yo = mymalloc( sizeof(i_img_dim) * num );
2800 ival = mymalloc( sizeof(i_color) * num );
2801 for(i = 0; i<num; i++) {
2802 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2803 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2804 sv = *av_fetch(ac, i, 0);
2805 if ( !sv_derived_from(sv, "Imager::Color") ) {
2806 free(axx); free(ayy); free(ac);
2807 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2809 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2811 i_gradgen(im, num, xo, yo, ival, dmeasure);
2817 i_diff_image(im, im2, mindist=0)
2823 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2833 double ssample_param
2837 i_fountain_seg *segs;
2839 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2840 croak("i_fountain: argument 11 must be an array ref");
2842 asegs = (AV *)SvRV(ST(10));
2843 segs = load_fount_segs(aTHX_ asegs, &count);
2844 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2845 super_sample, ssample_param, count, segs);
2851 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2860 double ssample_param
2864 i_fountain_seg *segs;
2866 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2867 croak("i_fountain: argument 11 must be an array ref");
2869 asegs = (AV *)SvRV(ST(9));
2870 segs = load_fount_segs(aTHX_ asegs, &count);
2871 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2872 super_sample, ssample_param, count, segs);
2878 i_new_fill_opacity(other_fill, alpha_mult)
2879 Imager::FillHandle other_fill
2890 errors = i_errors();
2892 while (errors[i].msg) {
2894 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2895 if (!av_store(av, 0, sv)) {
2898 sv = newSViv(errors[i].code);
2899 if (!av_store(av, 1, sv)) {
2902 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2910 i_push_error(code, msg)
2915 i_nearest_color(im, ...)
2930 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2931 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2932 croak("i_nearest_color: Second argument must be an array ref");
2933 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2934 croak("i_nearest_color: Third argument must be an array ref");
2935 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2936 croak("i_nearest_color: Fourth argument must be an array ref");
2937 axx = (AV *)SvRV(ST(1));
2938 ayy = (AV *)SvRV(ST(2));
2939 ac = (AV *)SvRV(ST(3));
2940 dmeasure = (int)SvIV(ST(4));
2942 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2943 num = num <= av_len(ac) ? num : av_len(ac);
2945 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2946 xo = mymalloc( sizeof(i_img_dim) * num );
2947 yo = mymalloc( sizeof(i_img_dim) * num );
2948 ival = mymalloc( sizeof(i_color) * num );
2949 for(i = 0; i<num; i++) {
2950 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
2951 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
2952 sv = *av_fetch(ac, i, 0);
2953 if ( !sv_derived_from(sv, "Imager::Color") ) {
2954 free(axx); free(ayy); free(ac);
2955 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2957 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
2959 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
2973 rc=DSO_open(filename,&evstr);
2977 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2978 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2981 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
2987 DSO_close(dso_handle)
2991 DSO_funclist(dso_handle_v)
2995 DSO_handle *dso_handle;
2996 func_ptr *functions;
2998 dso_handle=(DSO_handle*)dso_handle_v;
2999 functions = DSO_funclist(dso_handle);
3001 while( functions[i].name != NULL) {
3003 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3005 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3009 DSO_call(handle,func_index,hv)
3015 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3016 hv=(HV*)SvRV(ST(2));
3017 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3018 DSO_call( (DSO_handle *)handle,func_index,hv);
3021 i_get_pixel(im, x, y)
3028 color = (i_color *)mymalloc(sizeof(i_color));
3029 if (i_gpix(im, x, y, color) == 0) {
3030 RETVAL = NEWSV(0, 0);
3031 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3035 RETVAL = &PL_sv_undef;
3042 i_ppix(im, x, y, cl)
3049 i_img_pal_new(x, y, channels, maxpal)
3056 i_img_to_pal(src, quant)
3062 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3063 croak("i_img_to_pal: second argument must be a hash ref");
3064 hv = (HV *)SvRV(ST(1));
3065 memset(&quant, 0, sizeof(quant));
3067 quant.mc_size = 256;
3068 ip_handle_quant_opts(aTHX_ &quant, hv);
3069 RETVAL = i_img_to_pal(src, &quant);
3071 ip_copy_colors_back(aTHX_ hv, &quant);
3073 ip_cleanup_quant_opts(aTHX_ &quant);
3082 i_img_make_palette(HV *quant_hv, ...)
3084 size_t count = items - 1;
3086 i_img **imgs = NULL;
3090 croak("Please supply at least one image (%d)", (int)count);
3091 imgs = mymalloc(sizeof(i_img *) * count);
3092 for (i = 0; i < count; ++i) {
3093 SV *img_sv = ST(i + 1);
3094 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3095 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3099 croak("Image %d is not an image object", (int)i+1);
3102 memset(&quant, 0, sizeof(quant));
3104 quant.mc_size = 256;
3105 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3106 i_quant_makemap(&quant, imgs, count);
3107 EXTEND(SP, quant.mc_count);
3108 for (i = 0; i < quant.mc_count; ++i) {
3109 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3112 ip_cleanup_quant_opts(aTHX_ &quant);
3126 work = mymalloc((r-l) * sizeof(i_palidx));
3127 count = i_gpal(im, l, r, y, work);
3128 if (GIMME_V == G_ARRAY) {
3130 for (i = 0; i < count; ++i) {
3131 PUSHs(sv_2mortal(newSViv(work[i])));
3136 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3141 if (GIMME_V != G_ARRAY) {
3143 PUSHs(&PL_sv_undef);
3148 i_ppal(im, l, y, ...)
3157 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3158 for (i=0; i < items-3; ++i) {
3159 work[i] = SvIV(ST(i+3));
3161 validate_i_ppal(im, work, items - 3);
3162 RETVAL = i_ppal(im, l, l+items-3, y, work);
3171 i_ppal_p(im, l, y, data)
3177 i_palidx const *work;
3180 work = (i_palidx const *)SvPV(data, len);
3181 len /= sizeof(i_palidx);
3183 validate_i_ppal(im, work, len);
3184 RETVAL = i_ppal(im, l, l+len, y, work);
3193 i_addcolors(im, ...)
3201 croak("i_addcolors: no colors to add");
3202 colors = mymalloc((items-1) * sizeof(i_color));
3203 for (i=0; i < items-1; ++i) {
3204 if (sv_isobject(ST(i+1))
3205 && sv_derived_from(ST(i+1), "Imager::Color")) {
3206 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3207 colors[i] = *INT2PTR(i_color *, tmp);
3211 croak("i_addcolor: pixels must be Imager::Color objects");
3214 index = i_addcolors(im, colors, items-1);
3217 RETVAL = newSVpv("0 but true", 0);
3219 else if (index == -1) {
3220 RETVAL = &PL_sv_undef;
3223 RETVAL = newSViv(index);
3229 i_setcolors(im, index, ...)
3237 croak("i_setcolors: no colors to add");
3238 colors = mymalloc((items-2) * sizeof(i_color));
3239 for (i=0; i < items-2; ++i) {
3240 if (sv_isobject(ST(i+2))
3241 && sv_derived_from(ST(i+2), "Imager::Color")) {
3242 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3243 colors[i] = *INT2PTR(i_color *, tmp);
3247 croak("i_setcolors: pixels must be Imager::Color objects");
3250 RETVAL = i_setcolors(im, index, colors, items-2);
3256 i_getcolors(im, index, ...)
3265 croak("i_getcolors: too many arguments");
3267 count = SvIV(ST(2));
3269 croak("i_getcolors: count must be positive");
3270 colors = mymalloc(sizeof(i_color) * count);
3271 if (i_getcolors(im, index, colors, count)) {
3272 for (i = 0; i < count; ++i) {
3273 SV *sv = make_i_color_sv(aTHX_ colors+i);
3289 i_findcolor(im, color)
3295 if (i_findcolor(im, color, &index)) {
3296 RETVAL = newSViv(index);
3299 RETVAL = &PL_sv_undef;
3317 i_gsamp(im, l, r, y, channels)
3322 i_channel_list channels
3328 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count); /* XXX: memleak? */
3329 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3330 if (GIMME_V == G_ARRAY) {
3332 for (i = 0; i < count; ++i)
3333 PUSHs(sv_2mortal(newSViv(data[i])));
3337 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3342 if (GIMME_V != G_ARRAY) {
3344 PUSHs(&PL_sv_undef);
3349 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3357 i_channel_list channels
3364 croak("No channel numbers supplied to g_samp()");
3366 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3367 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3368 for (i = 0; i < count; ++i) {
3369 av_store(target, i+offset, newSVuv(data[i]));
3381 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3386 i_channel_list channels
3388 i_img_dim data_offset
3389 i_img_dim pixel_count
3398 data_count = av_len(data_av) + 1;
3399 if (data_offset < 0) {
3400 croak("data_offset must be non-negative");
3402 if (data_offset > data_count) {
3403 croak("data_offset greater than number of samples supplied");
3405 if (pixel_count == -1 ||
3406 data_offset + pixel_count * channels.count > data_count) {
3407 pixel_count = (data_count - data_offset) / channels.count;
3410 data_used = pixel_count * channels.count;
3411 data = mymalloc(sizeof(unsigned) * data_count);
3412 for (i = 0; i < data_used; ++i)
3413 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3415 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3416 channels.count, bits);
3424 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3428 i_channel_list channels
3437 i_push_error(0, "offset must be non-negative");
3441 if (offset > data.count) {
3442 i_push_error(0, "offset greater than number of samples supplied");
3445 data.samples += offset;
3446 data.count -= offset;
3449 width * channels.count > data.count) {
3450 width = data.count / channels.count;
3453 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3458 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3462 i_channel_list channels
3471 i_push_error(0, "offset must be non-negative");
3475 if (offset > data.count) {
3476 i_push_error(0, "offset greater than number of samples supplied");
3479 data.samples += offset;
3480 data.count -= offset;
3483 width * channels.count > data.count) {
3484 width = data.count / channels.count;
3487 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3492 i_img_masked_new(targ, mask, x, y, w, h)
3502 if (!sv_isobject(ST(1))
3503 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3504 croak("i_img_masked_new: parameter 2 must undef or an image");
3506 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3510 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3515 i_plin(im, l, y, ...)
3526 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3527 /* supplied as a byte string */
3528 work = (i_color *)SvPV(ST(3), len);
3529 count = len / sizeof(i_color);
3530 if (count * sizeof(i_color) != len) {
3531 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3533 RETVAL = i_plin(im, l, l+count, y, work);
3536 work = mymalloc(sizeof(i_color) * (items-3));
3537 for (i=0; i < items-3; ++i) {
3538 if (sv_isobject(ST(i+3))
3539 && sv_derived_from(ST(i+3), "Imager::Color")) {
3540 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3541 work[i] = *INT2PTR(i_color *, tmp);
3545 croak("i_plin: pixels must be Imager::Color objects");
3548 RETVAL = i_plin(im, l, l+items-3, y, work);
3559 i_ppixf(im, x, y, cl)
3563 Imager::Color::Float cl
3566 i_gsampf(im, l, r, y, channels)
3571 i_channel_list channels
3577 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3578 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3579 if (GIMME_V == G_ARRAY) {
3581 for (i = 0; i < count; ++i)
3582 PUSHs(sv_2mortal(newSVnv(data[i])));
3586 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3591 if (GIMME_V != G_ARRAY) {
3593 PUSHs(&PL_sv_undef);
3598 i_plinf(im, l, y, ...)
3609 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3610 /* supplied as a byte string */
3611 work = (i_fcolor *)SvPV(ST(3), len);
3612 count = len / sizeof(i_fcolor);
3613 if (count * sizeof(i_fcolor) != len) {
3614 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3616 RETVAL = i_plinf(im, l, l+count, y, work);
3619 work = mymalloc(sizeof(i_fcolor) * (items-3));
3620 for (i=0; i < items-3; ++i) {
3621 if (sv_isobject(ST(i+3))
3622 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3623 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3624 work[i] = *INT2PTR(i_fcolor *, tmp);
3628 croak("i_plinf: pixels must be Imager::Color::Float objects");
3632 RETVAL = i_plinf(im, l, l+items-3, y, work);
3650 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3651 if (i_gpixf(im, x, y, color) == 0) {
3652 RETVAL = NEWSV(0,0);
3653 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3657 RETVAL = &PL_sv_undef;
3673 vals = mymalloc((r-l) * sizeof(i_color));
3674 memset(vals, 0, (r-l) * sizeof(i_color));
3675 count = i_glin(im, l, r, y, vals);
3676 if (GIMME_V == G_ARRAY) {
3678 for (i = 0; i < count; ++i) {
3679 SV *sv = make_i_color_sv(aTHX_ vals+i);
3685 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3691 i_glinf(im, l, r, y)
3701 for (i = 0; i < MAXCHANNELS; ++i)
3702 zero.channel[i] = 0;
3704 vals = mymalloc((r-l) * sizeof(i_fcolor));
3705 for (i = 0; i < r-l; ++i)
3707 count = i_glinf(im, l, r, y, vals);
3708 if (GIMME_V == G_ARRAY) {
3710 for (i = 0; i < count; ++i) {
3712 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3714 sv = sv_newmortal();
3715 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3721 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3727 i_img_8_new(x, y, ch)
3733 i_img_16_new(x, y, ch)
3743 i_img_double_new(x, y, ch)
3753 i_tags_addn(im, name, code, idata)
3762 name = SvPV(ST(1), len);
3765 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3770 i_tags_add(im, name, code, data, idata)
3780 name = SvPV(ST(1), len);
3784 data = SvPV(ST(3), len);
3789 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3794 i_tags_find(im, name, start)
3801 if (i_tags_find(&im->tags, name, start, &entry)) {
3803 RETVAL = newSVpv("0 but true", 0);
3805 RETVAL = newSViv(entry);
3807 RETVAL = &PL_sv_undef;
3813 i_tags_findn(im, code, start)
3820 if (i_tags_findn(&im->tags, code, start, &entry)) {
3822 RETVAL = newSVpv("0 but true", 0);
3824 RETVAL = newSViv(entry);
3827 RETVAL = &PL_sv_undef;
3833 i_tags_delete(im, entry)
3837 RETVAL = i_tags_delete(&im->tags, entry);
3842 i_tags_delbyname(im, name)
3846 RETVAL = i_tags_delbyname(&im->tags, name);
3851 i_tags_delbycode(im, code)
3855 RETVAL = i_tags_delbycode(&im->tags, code);
3860 i_tags_get(im, index)
3864 if (index >= 0 && index < im->tags.count) {
3865 i_img_tag *entry = im->tags.tags + index;
3869 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3872 PUSHs(sv_2mortal(newSViv(entry->code)));
3875 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3878 PUSHs(sv_2mortal(newSViv(entry->idata)));
3883 i_tags_get_string(im, what_sv)
3887 char const *name = NULL;
3891 if (SvIOK(what_sv)) {
3892 code = SvIV(what_sv);
3896 name = SvPV_nolen(what_sv);
3899 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3901 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3908 RETVAL = im->tags.count;
3914 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3918 Imager::FillHandle fill
3921 IFILL_CLONE_SKIP(...)
3923 (void)items; /* avoid unused warning for XS variable */
3928 MODULE = Imager PACKAGE = Imager
3931 i_new_fill_solid(cl, combine)
3936 i_new_fill_solidf(cl, combine)
3937 Imager::Color::Float cl
3941 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3949 unsigned char *cust_hatch;
3953 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3957 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3962 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3963 Imager::Color::Float fg
3964 Imager::Color::Float bg
3970 unsigned char *cust_hatch;
3974 cust_hatch = (unsigned char *)SvPV(ST(4), len);
3978 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3983 i_new_fill_image(src, matrix, xoff, yoff, combine)
4000 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4001 croak("i_new_fill_image: parameter must be an arrayref");
4002 av=(AV*)SvRV(ST(1));
4006 for (i = 0; i < len; ++i) {
4007 sv1=(*(av_fetch(av,i,0)));
4008 matrix[i] = SvNV(sv1);
4014 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4018 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4020 # this class is only exposed for testing
4023 i_int_hlines_testing()
4025 #if i_int_hlines_testing()
4027 Imager::Internal::Hlines
4028 i_int_hlines_new(start_y, count_y, start_x, count_x)
4034 Imager::Internal::Hlines
4035 i_int_hlines_new_img(im)
4039 i_int_hlines_add(hlines, y, minx, width)
4040 Imager::Internal::Hlines hlines
4046 i_int_hlines_DESTROY(hlines)
4047 Imager::Internal::Hlines hlines
4050 i_int_hlines_dump(hlines)
4051 Imager::Internal::Hlines hlines
4054 i_int_hlines_CLONE_SKIP(cls)
4058 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4061 im_context_DESTROY(ctx)
4064 #ifdef PERL_IMPLICIT_CONTEXT
4067 im_context_CLONE(...)
4071 /* the following sv_setref_pv() will free this inc */
4072 im_context_refinc(MY_CXT.ctx, "CLONE");
4073 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4074 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4079 PERL_SET_GLOBAL_CALLBACKS;
4080 PERL_PL_SET_GLOBAL_CALLBACKS;
4081 #ifdef PERL_IMPLICIT_CONTEXT
4087 start_context(aTHX);
4088 im_get_context = perl_get_context;