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()
33 #define ARRAY_COUNT(array) (sizeof(array)/sizeof(*array))
37 Context object management
41 typedef im_context_t Imager__Context;
43 #define im_context_DESTROY(ctx) im_context_refdec((ctx), "DESTROY")
45 #ifdef PERL_IMPLICIT_CONTEXT
47 #define MY_CXT_KEY "Imager::_context" XS_VERSION
55 im_context_t fallback_context;
60 MY_CXT.ctx = im_context_new();
61 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
63 /* Ideally we'd free this reference, but the error message memory
64 was never released on exit, so the associated memory here is reasonable
66 With logging enabled we always need at least one context, since
67 objects may be released fairly late and attempt to get the log file.
69 im_context_refinc(MY_CXT.ctx, "start_context");
70 fallback_context = MY_CXT.ctx;
74 perl_get_context(void) {
78 return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
83 static im_context_t perl_context;
87 perl_context = im_context_new();
88 im_context_refinc(perl_context, "start_context");
92 perl_get_context(void) {
98 /* used to represent channel lists parameters */
99 typedef struct i_channel_list_tag {
106 const i_sample_t *samples;
111 const i_fsample_t *samples;
116 const i_polygon_t *polygons;
121 Allocate memory that will be discarded when mortals are discarded.
126 malloc_temp(pTHX_ size_t size) {
128 Newx(result, size, char);
135 calloc_temp(pTHX_ size_t size) {
137 Newxz(result, size, char);
143 /* for use with the T_AVARRAY typemap */
144 #define doublePtr(size) ((double *)calloc_temp(aTHX_ sizeof(double) * (size)))
145 #define SvDouble(sv, pname) (SvNV(sv))
147 #define intPtr(size) ((int *)calloc_temp(aTHX_ sizeof(int) * (size)))
148 #define SvInt(sv, pname) (SvIV(sv))
150 #define i_img_dimPtr(size) ((i_img_dim *)calloc_temp(aTHX_ sizeof(i_img_dim) * (size)))
151 #define SvI_img_dim(sv, pname) (SvIV(sv))
153 #define i_colorPtr(size) ((i_color *)calloc_temp(aTHX_ sizeof(i_color *) * (size)))
155 #define SvI_color(sv, pname) S_sv_to_i_color(aTHX_ sv, pname)
158 S_sv_to_i_color(pTHX_ SV *sv, const char *pname) {
159 if (!sv_derived_from(sv, "Imager::Color")) {
160 croak("%s: not a color object", pname);
162 return *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
165 /* These functions are all shared - then comes platform dependant code */
166 static int getstr(void *hv_t,char *key,char **store) {
171 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
173 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
175 svpp=hv_fetch(hv, key, strlen(key), 0);
176 *store=SvPV(*svpp, PL_na );
181 static int getint(void *hv_t,char *key,int *store) {
186 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
188 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
190 svpp=hv_fetch(hv, key, strlen(key), 0);
191 *store=(int)SvIV(*svpp);
195 static int getdouble(void *hv_t,char* key,double *store) {
200 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
202 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
203 svpp=hv_fetch(hv, key, strlen(key), 0);
204 *store=(double)SvNV(*svpp);
208 static int getvoid(void *hv_t,char* key,void **store) {
213 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
215 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
217 svpp=hv_fetch(hv, key, strlen(key), 0);
218 *store = INT2PTR(void*, SvIV(*svpp));
223 static int getobj(void *hv_t,char *key,char *type,void **store) {
228 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
230 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
232 svpp=hv_fetch(hv, key, strlen(key), 0);
234 if (sv_derived_from(*svpp,type)) {
235 IV tmp = SvIV((SV*)SvRV(*svpp));
236 *store = INT2PTR(void*, tmp);
238 mm_log((1,"getobj: key exists in hash but is not of correct type"));
245 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
248 free_buffer(void *p) {
254 i_log_entry(char *string, int level) {
255 mm_log((level, "%s", string));
259 make_i_color_sv(pTHX_ const i_color *c) {
261 i_color *col = mymalloc(sizeof(i_color));
264 sv_setref_pv(sv, "Imager::Color", (void *)col);
269 #define CBDATA_BUFSIZE 8192
272 /* the SVs we use to call back to Perl */
280 call_reader(struct cbdata *cbd, void *buf, size_t size,
288 if (!SvOK(cbd->readcb)) {
289 mm_log((1, "read callback called but no readcb supplied\n"));
290 i_push_error(0, "read callback called but no readcb supplied");
298 PUSHs(sv_2mortal(newSViv(size)));
299 PUSHs(sv_2mortal(newSViv(maxread)));
302 count = perl_call_sv(cbd->readcb, G_SCALAR);
307 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
313 char *ptr = SvPVbyte(data, len);
315 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
316 (int)size, (int)len, (int)maxread);
318 memcpy(buf, ptr, len);
333 io_seeker(void *p, off_t offset, int whence) {
335 struct cbdata *cbd = p;
340 if (!SvOK(cbd->seekcb)) {
341 mm_log((1, "seek callback called but no seekcb supplied\n"));
342 i_push_error(0, "seek callback called but no seekcb supplied");
350 PUSHs(sv_2mortal(newSViv(offset)));
351 PUSHs(sv_2mortal(newSViv(whence)));
354 count = perl_call_sv(cbd->seekcb, G_SCALAR);
359 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
371 io_writer(void *p, void const *data, size_t size) {
373 struct cbdata *cbd = p;
379 if (!SvOK(cbd->writecb)) {
380 mm_log((1, "write callback called but no writecb supplied\n"));
381 i_push_error(0, "write callback called but no writecb supplied");
389 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
392 count = perl_call_sv(cbd->writecb, G_SCALAR);
396 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
399 success = SvTRUE(sv);
406 return success ? size : -1;
410 io_reader(void *p, void *data, size_t size) {
411 struct cbdata *cbd = p;
413 return call_reader(cbd, data, size, size);
416 static int io_closer(void *p) {
418 struct cbdata *cbd = p;
421 if (SvOK(cbd->closecb)) {
430 count = perl_call_sv(cbd->closecb, G_SCALAR);
436 success = SvTRUE(sv);
446 return success ? 0 : -1;
449 static void io_destroyer(void *p) {
451 struct cbdata *cbd = p;
453 SvREFCNT_dec(cbd->writecb);
454 SvREFCNT_dec(cbd->readcb);
455 SvREFCNT_dec(cbd->seekcb);
456 SvREFCNT_dec(cbd->closecb);
461 im_SvREFSCALAR(SV *sv) {
462 svtype type = SvTYPE(sv);
472 #if PERL_VERSION > 10
483 describe_sv(SV *sv) {
486 svtype type = SvTYPE(SvRV(sv));
488 case SVt_PVCV: return "CV";
489 case SVt_PVGV: return "GV";
490 case SVt_PVLV: return "LV";
491 default: return "some reference";
495 return "non-reference scalar";
504 do_io_new_buffer(pTHX_ SV *data_sv) {
511 if (SvROK(data_sv)) {
512 if (im_SvREFSCALAR(SvRV(data_sv))) {
516 i_push_errorf(0, "data is not a scalar or a reference to scalar");
524 /* previously this would keep the SV around, but this is unsafe in
525 many ways, so always copy the bytes */
526 data = SvPVbyte(sv, length);
527 data_copy = mymalloc(length);
528 memcpy(data_copy, data, length);
529 return io_new_buffer(data_copy, length, free_buffer, data_copy);
533 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
536 cbd = mymalloc(sizeof(struct cbdata));
537 cbd->writecb = newSVsv(writecb);
538 cbd->readcb = newSVsv(readcb);
539 cbd->seekcb = newSVsv(seekcb);
540 cbd->closecb = newSVsv(closecb);
542 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)));
544 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
552 static int lookup_name(const struct value_name *names, int count, char *name, int def_value)
555 for (i = 0; i < count; ++i)
556 if (strEQ(names[i].name, name))
557 return names[i].value;
561 static struct value_name transp_names[] =
564 { "threshold", tr_threshold },
565 { "errdiff", tr_errdiff },
566 { "ordered", tr_ordered, },
569 static struct value_name make_color_names[] =
571 { "none", mc_none, },
572 { "webmap", mc_web_map, },
573 { "addi", mc_addi, },
574 { "mediancut", mc_median_cut, },
575 { "mono", mc_mono, },
576 { "monochrome", mc_mono, },
577 { "gray", mc_gray, },
578 { "gray4", mc_gray4, },
579 { "gray16", mc_gray16, },
582 static struct value_name translate_names[] =
584 { "giflib", pt_giflib, },
585 { "closest", pt_closest, },
586 { "perturb", pt_perturb, },
587 { "errdiff", pt_errdiff, },
590 static struct value_name errdiff_names[] =
592 { "floyd", ed_floyd, },
593 { "jarvis", ed_jarvis, },
594 { "stucki", ed_stucki, },
595 { "custom", ed_custom, },
598 static struct value_name orddith_names[] =
600 { "random", od_random, },
601 { "dot8", od_dot8, },
602 { "dot4", od_dot4, },
603 { "hline", od_hline, },
604 { "vline", od_vline, },
605 { "/line", od_slashline, },
606 { "slashline", od_slashline, },
607 { "\\line", od_backline, },
608 { "backline", od_backline, },
609 { "tiny", od_tiny, },
610 { "custom", od_custom, },
613 /* look through the hash for quantization options */
615 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
617 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
623 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
625 sv = hv_fetch(hv, "transp", 6, 0);
626 if (sv && *sv && (str = SvPV(*sv, len))) {
628 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
630 if (quant->transp != tr_none) {
631 quant->tr_threshold = 127;
632 sv = hv_fetch(hv, "tr_threshold", 12, 0);
634 quant->tr_threshold = SvIV(*sv);
636 if (quant->transp == tr_errdiff) {
637 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
638 if (sv && *sv && (str = SvPV(*sv, len)))
639 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
641 if (quant->transp == tr_ordered) {
642 quant->tr_orddith = od_tiny;
643 sv = hv_fetch(hv, "tr_orddith", 10, 0);
644 if (sv && *sv && (str = SvPV(*sv, len)))
645 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
647 if (quant->tr_orddith == od_custom) {
648 sv = hv_fetch(hv, "tr_map", 6, 0);
649 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
650 AV *av = (AV*)SvRV(*sv);
651 len = av_len(av) + 1;
652 if (len > sizeof(quant->tr_custom))
653 len = sizeof(quant->tr_custom);
654 for (i = 0; i < len; ++i) {
655 SV **sv2 = av_fetch(av, i, 0);
657 quant->tr_custom[i] = SvIV(*sv2);
660 while (i < sizeof(quant->tr_custom))
661 quant->tr_custom[i++] = 0;
666 quant->make_colors = mc_median_cut;
667 sv = hv_fetch(hv, "make_colors", 11, 0);
668 if (sv && *sv && (str = SvPV(*sv, len))) {
670 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
672 sv = hv_fetch(hv, "colors", 6, 0);
673 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
674 /* needs to be an array of Imager::Color
675 note that the caller allocates the mc_color array and sets mc_size
677 AV *av = (AV *)SvRV(*sv);
678 quant->mc_count = av_len(av)+1;
679 if (quant->mc_count > quant->mc_size)
680 quant->mc_count = quant->mc_size;
681 for (i = 0; i < quant->mc_count; ++i) {
682 SV **sv1 = av_fetch(av, i, 0);
683 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
684 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
685 quant->mc_colors[i] = *col;
689 sv = hv_fetch(hv, "max_colors", 10, 0);
692 if (i <= quant->mc_size && i >= quant->mc_count)
696 quant->translate = pt_closest;
697 sv = hv_fetch(hv, "translate", 9, 0);
698 if (sv && *sv && (str = SvPV(*sv, len))) {
699 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
701 sv = hv_fetch(hv, "errdiff", 7, 0);
702 if (sv && *sv && (str = SvPV(*sv, len))) {
703 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
705 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
706 /* get the error diffusion map */
707 sv = hv_fetch(hv, "errdiff_width", 13, 0);
709 quant->ed_width = SvIV(*sv);
710 sv = hv_fetch(hv, "errdiff_height", 14, 0);
712 quant->ed_height = SvIV(*sv);
713 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
715 quant->ed_orig = SvIV(*sv);
716 if (quant->ed_width > 0 && quant->ed_height > 0) {
718 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
719 sv = hv_fetch(hv, "errdiff_map", 11, 0);
720 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
721 AV *av = (AV*)SvRV(*sv);
722 len = av_len(av) + 1;
723 if (len > quant->ed_width * quant->ed_height)
724 len = quant->ed_width * quant->ed_height;
725 for (i = 0; i < len; ++i) {
726 SV **sv2 = av_fetch(av, i, 0);
728 quant->ed_map[i] = SvIV(*sv2);
729 sum += quant->ed_map[i];
735 myfree(quant->ed_map);
737 quant->errdiff = ed_floyd;
741 sv = hv_fetch(hv, "perturb", 7, 0);
743 quant->perturb = SvIV(*sv);
747 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
748 myfree(quant->mc_colors);
750 myfree(quant->ed_map);
753 /* copies the color map from the hv into the colors member of the HV */
755 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
761 sv = hv_fetch(hv, "colors", 6, 0);
762 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
767 av = (AV *)SvRV(*sv);
769 av_extend(av, quant->mc_count+1);
770 for (i = 0; i < quant->mc_count; ++i) {
771 i_color *in = quant->mc_colors+i;
772 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
773 work = sv_newmortal();
774 sv_setref_pv(work, "Imager::Color", (void *)c);
780 static struct value_name
781 poly_fill_mode_names[] =
783 { "evenodd", i_pfm_evenodd },
784 { "nonzero", i_pfm_nonzero }
787 static i_poly_fill_mode_t
788 S_get_poly_fill_mode(pTHX_ SV *sv) {
789 if (looks_like_number(sv)) {
791 if (work < (IV)i_pfm_evenodd || work > (IV)i_pfm_nonzero)
792 work = (IV)i_pfm_evenodd;
793 return (i_poly_fill_mode_t)work;
796 return (i_poly_fill_mode_t)lookup_name
797 (poly_fill_mode_names, ARRAY_COUNT(poly_fill_mode_names),
798 SvPV_nolen(sv), i_pfm_evenodd);
803 S_get_polygon_list(pTHX_ i_polygon_list *polys, SV *sv) {
809 if (!SvOK(sv) || !SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV)
810 croak("polys must be an arrayref");
813 polys->count = av_len(av) + 1;
814 if (polys->count < 1)
815 croak("polypolygon: no polygons provided");
816 s = malloc_temp(aTHX_ sizeof(i_polygon_t) * polys->count);
817 for (i = 0; i < polys->count; ++i) {
818 SV **poly_sv = av_fetch(av, i, 0);
822 double *x_data, *y_data;
827 croak("poly_polygon: nothing found for polygon %d", i);
828 /* needs to be another av */
829 SvGETMAGIC(*poly_sv);
830 if (!SvOK(*poly_sv) || !SvROK(*poly_sv) || SvTYPE(SvRV(*poly_sv)) != SVt_PVAV)
831 croak("poly_polygon: polygon %d isn't an arrayref", i);
832 poly_av = (AV*)SvRV(*poly_sv);
833 /* with two elements */
834 if (av_len(poly_av) != 1)
835 croak("poly_polygon: polygon %d should contain two arrays", i);
836 x_sv = av_fetch(poly_av, 0, 0);
837 y_sv = av_fetch(poly_av, 1, 0);
839 croak("poly_polygon: polygon %d has no x elements", i);
841 croak("poly_polygon: polygon %d has no y elements", i);
844 if (!SvOK(*x_sv) || !SvROK(*x_sv) || SvTYPE(SvRV(*x_sv)) != SVt_PVAV)
845 croak("poly_polygon: polygon %d x elements isn't an array", i);
846 if (!SvOK(*y_sv) || !SvROK(*y_sv) || SvTYPE(SvRV(*y_sv)) != SVt_PVAV)
847 croak("poly_polygon: polygon %d y elements isn't an array", i);
848 x_av = (AV*)SvRV(*x_sv);
849 y_av = (AV*)SvRV(*y_sv);
850 if (av_len(x_av) != av_len(y_av))
851 croak("poly_polygon: polygon %d x and y arrays different lengths", i+1);
852 point_count = av_len(x_av)+1;
853 x_data = malloc_temp(aTHX_ sizeof(double) * point_count * 2);
854 y_data = x_data + point_count;
856 for (j = 0; j < point_count; ++j) {
857 SV **x_item_sv = av_fetch(x_av, j, 0);
858 SV **y_item_sv = av_fetch(y_av, j, 0);
859 x_data[j] = x_item_sv ? SvNV(*x_item_sv) : 0;
860 y_data[j] = y_item_sv ? SvNV(*y_item_sv) : 0;
864 s[i].count = point_count;
869 /* loads the segments of a fountain fill into an array */
870 static i_fountain_seg *
871 load_fount_segs(pTHX_ AV *asegs, int *count) {
872 /* Each element of segs must contain:
873 [ start, middle, end, c0, c1, segtype, colortrans ]
874 start, middle, end are doubles from 0 to 1
875 c0, c1 are Imager::Color::Float or Imager::Color objects
876 segtype, colortrans are ints
880 i_fountain_seg *segs;
884 *count = av_len(asegs)+1;
886 croak("i_fountain must have at least one segment");
887 segs = mymalloc(sizeof(i_fountain_seg) * *count);
888 for(i = 0; i < *count; i++) {
889 SV **sv1 = av_fetch(asegs, i, 0);
890 if (!sv1 || !*sv1 || !SvROK(*sv1)
891 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
893 croak("i_fountain: segs must be an arrayref of arrayrefs");
895 aseg = (AV *)SvRV(*sv1);
896 if (av_len(aseg) != 7-1) {
898 croak("i_fountain: a segment must have 7 members");
900 for (j = 0; j < 3; ++j) {
901 SV **sv2 = av_fetch(aseg, j, 0);
904 croak("i_fountain: XS error");
906 work[j] = SvNV(*sv2);
908 segs[i].start = work[0];
909 segs[i].middle = work[1];
910 segs[i].end = work[2];
911 for (j = 0; j < 2; ++j) {
912 SV **sv3 = av_fetch(aseg, 3+j, 0);
913 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
914 (!sv_derived_from(*sv3, "Imager::Color")
915 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
917 croak("i_fountain: segs must contain colors in elements 3 and 4");
919 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
920 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
923 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
925 for (ch = 0; ch < MAXCHANNELS; ++ch) {
926 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
930 for (j = 0; j < 2; ++j) {
931 SV **sv2 = av_fetch(aseg, j+5, 0);
934 croak("i_fountain: XS error");
936 worki[j] = SvIV(*sv2);
938 segs[i].type = worki[0];
939 segs[i].color = worki[1];
945 /* validates the indexes supplied to i_ppal
947 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
952 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
953 int color_count = i_colorcount(im);
956 if (color_count == -1)
957 croak("i_plin() called on direct color image");
959 for (i = 0; i < count; ++i) {
960 if (indexes[i] >= color_count) {
961 croak("i_plin() called with out of range color index %d (max %d)",
962 indexes[i], color_count-1);
967 /* I don't think ICLF_* names belong at the C interface
968 this makes the XS code think we have them, to let us avoid
969 putting function bodies in the XS code
971 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
972 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
975 #define i_log_enabled() 1
977 #define i_log_enabled() 0
980 #if i_int_hlines_testing()
982 typedef i_int_hlines *Imager__Internal__Hlines;
984 static i_int_hlines *
985 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
986 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
987 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
992 static i_int_hlines *
993 i_int_hlines_new_img(i_img *im) {
994 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
995 i_int_init_hlines_img(result, im);
1001 i_int_hlines_DESTROY(i_int_hlines *hlines) {
1002 i_int_hlines_destroy(hlines);
1006 #define i_int_hlines_CLONE_SKIP(cls) 1
1008 static int seg_compare(const void *vleft, const void *vright) {
1009 const i_int_hline_seg *left = vleft;
1010 const i_int_hline_seg *right = vright;
1012 return left->minx - right->minx;
1016 i_int_hlines_dump(i_int_hlines *hlines) {
1018 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
1019 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
1022 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
1023 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
1026 /* sort the segments, if any */
1028 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
1030 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
1031 for (i = 0; i < entry->count; ++i) {
1032 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
1033 i_DFc(entry->segs[i].x_limit));
1035 sv_catpv(dump, "\n");
1045 i_sv_off_t(pTHX_ SV *sv) {
1046 #if LSEEKSIZE > IVSIZE
1047 return (off_t)SvNV(sv);
1049 return (off_t)SvIV(sv);
1054 i_new_sv_off_t(pTHX_ off_t off) {
1055 #if LSEEKSIZE > IVSIZE
1056 return newSVnv(off);
1058 return newSViv(off);
1062 static im_pl_ext_funcs im_perl_funcs =
1064 IMAGER_PL_API_VERSION,
1065 IMAGER_PL_API_LEVEL,
1066 ip_handle_quant_opts,
1067 ip_cleanup_quant_opts,
1071 #define PERL_PL_SET_GLOBAL_CALLBACKS \
1072 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
1074 #define IIM_new i_img_8_new
1075 #define IIM_DESTROY i_img_destroy
1078 #ifdef IMEXIF_ENABLE
1079 #define i_exif_enabled() 1
1081 #define i_exif_enabled() 0
1084 /* trying to use more C style names, map them here */
1085 #define i_io_DESTROY(ig) io_glue_destroy(ig)
1087 #define i_img_get_width(im) ((im)->xsize)
1088 #define i_img_get_height(im) ((im)->ysize)
1090 #define i_img_epsilonf() (DBL_EPSILON * 4)
1092 /* avoid some xsubpp strangeness */
1093 #define NEWLINE '\n'
1095 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
1098 ICL_new_internal(r,g,b,a)
1110 ICL_set_internal(cl,r,g,b,a)
1117 ICL_set_internal(cl, r, g, b, a);
1131 PUSHs(sv_2mortal(newSViv(cl->rgba.r)));
1132 PUSHs(sv_2mortal(newSViv(cl->rgba.g)));
1133 PUSHs(sv_2mortal(newSViv(cl->rgba.b)));
1134 PUSHs(sv_2mortal(newSViv(cl->rgba.a)));
1140 RETVAL = mymalloc(sizeof(i_color));
1142 i_hsv_to_rgb(RETVAL);
1150 RETVAL = mymalloc(sizeof(i_color));
1152 i_rgb_to_hsv(RETVAL);
1158 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1160 Imager::Color::Float
1161 ICLF_new_internal(r, g, b, a)
1169 Imager::Color::Float cl
1173 Imager::Color::Float cl
1177 EXTEND(SP, MAXCHANNELS);
1178 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1179 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1180 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1184 ICLF_set_internal(cl,r,g,b,a)
1185 Imager::Color::Float cl
1198 Imager::Color::Float
1200 Imager::Color::Float c
1202 RETVAL = mymalloc(sizeof(i_fcolor));
1204 i_hsv_to_rgbf(RETVAL);
1208 Imager::Color::Float
1210 Imager::Color::Float c
1212 RETVAL = mymalloc(sizeof(i_fcolor));
1214 i_rgb_to_hsvf(RETVAL);
1218 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1232 MODULE = Imager PACKAGE = Imager
1246 io_new_buffer(data_sv)
1250 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1257 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1263 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1271 unsigned char* data;
1275 tlength = io_slurp(ig, &data);
1276 RETVAL = newSVpv((char *)data,tlength);
1283 i_set_image_file_limits(width, height, bytes)
1289 i_get_image_file_limits()
1291 i_img_dim width, height;
1294 if (i_get_image_file_limits(&width, &height, &bytes)) {
1296 PUSHs(sv_2mortal(newSViv(width)));
1297 PUSHs(sv_2mortal(newSViv(height)));
1298 PUSHs(sv_2mortal(newSVuv(bytes)));
1302 i_int_check_image_file_limits(width, height, channels, sample_size)
1309 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
1312 io_new_fd(class, fd)
1315 RETVAL = io_new_fd(fd);
1320 io_new_buffer(class, data_sv)
1324 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1331 io_new_cb(class, writecb, readcb, seekcb, closecb)
1337 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1342 io_new_bufchain(class)
1344 RETVAL = io_new_bufchain();
1349 io__new_perlio(class, io)
1352 RETVAL = im_io_new_perlio(aTHX_ io);
1360 unsigned char* data;
1364 tlength = io_slurp(ig, &data);
1365 RETVAL = newSVpv((char *)data,tlength);
1370 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1373 i_io_raw_write(ig, data_sv)
1380 data = SvPVbyte(data_sv, size);
1381 RETVAL = i_io_raw_write(ig, data, size);
1386 i_io_raw_read(ig, buffer_sv, size)
1395 croak("size negative in call to i_io_raw_read()");
1396 /* prevent an undefined value warning if they supplied an
1398 Orginally conditional on !SvOK(), but this will prevent the
1399 downgrade from croaking */
1400 sv_setpvn(buffer_sv, "", 0);
1402 if (SvUTF8(buffer_sv))
1403 sv_utf8_downgrade(buffer_sv, FALSE);
1405 buffer = SvGROW(buffer_sv, size+1);
1406 result = i_io_raw_read(ig, buffer, size);
1408 SvCUR_set(buffer_sv, result);
1409 *SvEND(buffer_sv) = '\0';
1410 SvPOK_only(buffer_sv);
1412 PUSHs(sv_2mortal(newSViv(result)));
1418 i_io_raw_read2(ig, size)
1427 croak("size negative in call to i_io_read2()");
1428 buffer_sv = newSV(size);
1429 buffer = SvGROW(buffer_sv, size+1);
1430 result = i_io_raw_read(ig, buffer, size);
1432 SvCUR_set(buffer_sv, result);
1433 *SvEND(buffer_sv) = '\0';
1434 SvPOK_only(buffer_sv);
1436 PUSHs(sv_2mortal(buffer_sv));
1440 SvREFCNT_dec(buffer_sv);
1444 i_io_raw_seek(ig, position, whence)
1458 i_io_CLONE_SKIP(...)
1460 (void)items; /* avoid unused warning for XS variable */
1487 i_io_seek(ig, off, whence)
1493 i_io_peekn(ig, size)
1501 buffer_sv = newSV(size+1);
1502 buffer = SvGROW(buffer_sv, size+1);
1503 result = i_io_peekn(ig, buffer, size);
1505 SvCUR_set(buffer_sv, result);
1506 *SvEND(buffer_sv) = '\0';
1507 SvPOK_only(buffer_sv);
1509 PUSHs(sv_2mortal(buffer_sv));
1513 SvREFCNT_dec(buffer_sv);
1517 i_io_read(ig, buffer_sv, size)
1526 croak("size negative in call to i_io_read()");
1527 /* prevent an undefined value warning if they supplied an
1529 Orginally conditional on !SvOK(), but this will prevent the
1530 downgrade from croaking */
1531 sv_setpvn(buffer_sv, "", 0);
1533 if (SvUTF8(buffer_sv))
1534 sv_utf8_downgrade(buffer_sv, FALSE);
1536 buffer = SvGROW(buffer_sv, size+1);
1537 result = i_io_read(ig, buffer, size);
1539 SvCUR_set(buffer_sv, result);
1540 *SvEND(buffer_sv) = '\0';
1541 SvPOK_only(buffer_sv);
1543 PUSHs(sv_2mortal(newSViv(result)));
1549 i_io_read2(ig, size)
1558 croak("size zero in call to read2()");
1559 buffer_sv = newSV(size);
1560 buffer = SvGROW(buffer_sv, size+1);
1561 result = i_io_read(ig, buffer, size);
1563 SvCUR_set(buffer_sv, result);
1564 *SvEND(buffer_sv) = '\0';
1565 SvPOK_only(buffer_sv);
1567 PUSHs(sv_2mortal(buffer_sv));
1571 SvREFCNT_dec(buffer_sv);
1575 i_io_gets(ig, size = 8192, eol = NEWLINE)
1585 croak("size too small in call to gets()");
1586 buffer_sv = sv_2mortal(newSV(size+1));
1587 buffer = SvPVX(buffer_sv);
1588 result = i_io_gets(ig, buffer, size+1, eol);
1590 SvCUR_set(buffer_sv, result);
1591 *SvEND(buffer_sv) = '\0';
1592 SvPOK_only(buffer_sv);
1598 i_io_write(ig, data_sv)
1605 data = SvPVbyte(data_sv, size);
1606 RETVAL = i_io_write(ig, data, size);
1611 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1616 i_io_set_buffered(ig, flag = 1)
1621 i_io_is_buffered(ig)
1632 MODULE = Imager PACKAGE = Imager
1643 while( (item=i_format_list[i++]) != NULL ) {
1645 PUSHs(sv_2mortal(newSVpv(item,0)));
1649 i_sametype(im, x, y)
1655 i_sametype_chans(im, x, y, channels)
1662 i_init_log(name_sv,level)
1666 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1668 RETVAL = i_init_log(name, level);
1673 i_log_entry(string,level)
1686 i_img_info(im,info);
1688 PUSHs(sv_2mortal(newSViv(info[0])));
1689 PUSHs(sv_2mortal(newSViv(info[1])));
1690 PUSHs(sv_2mortal(newSViv(info[2])));
1691 PUSHs(sv_2mortal(newSViv(info[3])));
1697 i_img_setmask(im,ch_mask)
1706 i_img_getchannels(im)
1715 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1723 i_img_get_height(im)
1727 i_img_color_model(im)
1731 i_img_color_channels(im)
1735 i_img_alpha_channel(im)
1738 if (!i_img_alpha_channel(im, &RETVAL))
1744 i_img_is_monochrome(im)
1750 result = i_img_is_monochrome(im, &zero_is_white);
1752 if (GIMME_V == G_ARRAY) {
1755 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1764 i_line(im,x1,y1,x2,y2,val,endp)
1774 i_line_aa(im,x1,y1,x2,y2,val,endp)
1784 i_box(im,x1,y1,x2,y2,val)
1793 i_box_filled(im,x1,y1,x2,y2,val)
1802 i_box_filledf(im,x1,y1,x2,y2,val)
1808 Imager::Color::Float val
1811 i_box_cfill(im,x1,y1,x2,y2,fill)
1817 Imager::FillHandle fill
1820 i_arc(im,x,y,rad,d1,d2,val)
1830 i_arc_aa(im,x,y,rad,d1,d2,val)
1840 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1847 Imager::FillHandle fill
1850 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1857 Imager::FillHandle fill
1861 i_circle_aa(im,x,y,rad,val)
1869 i_circle_aa_fill(im,x,y,rad,fill)
1874 Imager::FillHandle fill
1877 i_circle_out(im,x,y,rad,val)
1885 i_circle_out_aa(im,x,y,rad,val)
1893 i_arc_out(im,x,y,rad,d1,d2,val)
1903 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1914 i_bezier_multi(im,x,y,val)
1923 if (size_x != size_y)
1924 croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1925 i_bezier_multi(im,size_x,x,y,val);
1928 i_poly_aa_m(im,x,y,mode,val)
1932 i_poly_fill_mode_t mode
1938 if (size_x != size_y)
1939 croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1940 RETVAL = i_poly_aa_m(im, size_x, x, y, mode, val);
1945 i_poly_aa_cfill_m(im, x, y, mode, fill)
1949 i_poly_fill_mode_t mode
1950 Imager::FillHandle fill
1955 if (size_x != size_y)
1956 croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1957 RETVAL = i_poly_aa_cfill_m(im, size_x, x, y, mode, fill);
1962 i_poly_poly_aa(im, polys, mode, color)
1964 i_polygon_list polys
1965 i_poly_fill_mode_t mode
1968 RETVAL = i_poly_poly_aa(im, polys.count, polys.polygons, mode, color);
1973 i_poly_poly_aa_cfill(im, polys, mode, fill)
1975 i_polygon_list polys
1976 i_poly_fill_mode_t mode
1977 Imager::FillHandle fill
1979 RETVAL = i_poly_poly_aa_cfill(im, polys.count, polys.polygons, mode, fill);
1984 i_flood_fill(im,seedx,seedy,dcol)
1991 i_flood_cfill(im,seedx,seedy,fill)
1995 Imager::FillHandle fill
1998 i_flood_fill_border(im,seedx,seedy,dcol, border)
2003 Imager::Color border
2006 i_flood_cfill_border(im,seedx,seedy,fill, border)
2010 Imager::FillHandle fill
2011 Imager::Color border
2015 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
2027 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
2044 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
2055 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
2068 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)
2084 i_combine(src_av, channels_av = NULL)
2088 i_img **imgs = NULL;
2090 int *channels = NULL;
2095 in_count = av_len(src_av) + 1;
2097 imgs = mymalloc(sizeof(i_img*) * in_count);
2098 channels = mymalloc(sizeof(int) * in_count);
2099 for (i = 0; i < in_count; ++i) {
2100 psv = av_fetch(src_av, i, 0);
2101 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
2104 croak("imgs must contain only images");
2106 tmp = SvIV((SV*)SvRV(*psv));
2107 imgs[i] = INT2PTR(i_img*, tmp);
2109 (psv = av_fetch(channels_av, i, 0)) != NULL &&
2111 channels[i] = SvIV(*psv);
2118 RETVAL = i_combine(imgs, channels, in_count);
2125 i_flipxy(im, direction)
2130 i_rotate90(im, degrees)
2135 i_rotate_exact(im, amount, ...)
2139 i_color *backp = NULL;
2140 i_fcolor *fbackp = NULL;
2144 /* extract the bg colors if any */
2145 /* yes, this is kind of strange */
2146 for (i = 2; i < items; ++i) {
2148 if (sv_derived_from(sv1, "Imager::Color")) {
2149 IV tmp = SvIV((SV*)SvRV(sv1));
2150 backp = INT2PTR(i_color *, tmp);
2152 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2153 IV tmp = SvIV((SV*)SvRV(sv1));
2154 fbackp = INT2PTR(i_fcolor *, tmp);
2157 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
2162 i_matrix_transform(im, xsize, ysize, matrix_av, ...)
2172 i_color *backp = NULL;
2173 i_fcolor *fbackp = NULL;
2175 len=av_len(matrix_av)+1;
2178 for (i = 0; i < len; ++i) {
2179 sv1=(*(av_fetch(matrix_av,i,0)));
2180 matrix[i] = SvNV(sv1);
2184 /* extract the bg colors if any */
2185 /* yes, this is kind of strange */
2186 for (i = 4; i < items; ++i) {
2188 if (sv_derived_from(sv1, "Imager::Color")) {
2189 IV tmp = SvIV((SV*)SvRV(sv1));
2190 backp = INT2PTR(i_color *, tmp);
2192 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2193 IV tmp = SvIV((SV*)SvRV(sv1));
2194 fbackp = INT2PTR(i_fcolor *, tmp);
2197 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2202 i_gaussian(im,stdev)
2207 i_unsharp_mask(im,stdev,scale)
2222 len = av_len(coef) + 1;
2223 c_coef=mymalloc( len * sizeof(double) );
2224 for(i = 0; i < len; i++) {
2225 sv1 = (*(av_fetch(coef, i, 0)));
2226 c_coef[i] = (double)SvNV(sv1);
2228 RETVAL = i_conv(im, c_coef, len);
2234 i_convert(src, avmain)
2246 outchan = av_len(avmain)+1;
2247 /* find the biggest */
2249 for (j=0; j < outchan; ++j) {
2250 temp = av_fetch(avmain, j, 0);
2251 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2252 avsub = (AV*)SvRV(*temp);
2253 len = av_len(avsub)+1;
2258 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2262 coeff = mymalloc(sizeof(double) * outchan * inchan);
2263 for (j = 0; j < outchan; ++j) {
2264 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2265 len = av_len(avsub)+1;
2266 for (i = 0; i < len; ++i) {
2267 temp = av_fetch(avsub, i, 0);
2269 coeff[i+j*inchan] = SvNV(*temp);
2271 coeff[i+j*inchan] = 0;
2274 coeff[i++ + j*inchan] = 0;
2276 RETVAL = i_convert(src, coeff, outchan, inchan);
2287 unsigned int mask = 0;
2292 unsigned char (*maps)[256];
2294 len = av_len(pmaps_av)+1;
2295 if (im->channels < len)
2297 maps = mymalloc( len * sizeof(unsigned char [256]) );
2298 for (j=0; j<len ; j++) {
2299 temp = av_fetch(pmaps_av, j, 0);
2300 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2301 avsub = (AV*)SvRV(*temp);
2302 if(av_len(avsub) != 255)
2305 for (i=0; i<256 ; i++) {
2307 temp = av_fetch(avsub, i, 0);
2308 val = temp ? SvIV(*temp) : 0;
2310 if (val>255) val = 255;
2315 i_map(im, maps, mask);
2327 i_img_diffd(im1,im2)
2332 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2342 _is_color_object(sv)
2346 RETVAL = SvOK(sv) && SvROK(sv) &&
2347 (sv_derived_from(sv, "Imager::Color")
2348 || sv_derived_from(sv, "Imager::Color::Float"));
2360 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2362 #define TT_DESTROY(handle) i_tt_destroy(handle)
2366 Imager::Font::TT handle
2371 (void)items; /* avoid unused warning */
2377 MODULE = Imager PACKAGE = Imager
2381 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2382 Imager::Font::TT handle
2396 str = SvPV(str_sv, len);
2401 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2402 len, smooth, utf8, align);
2408 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2409 Imager::Font::TT handle
2423 str = SvPV(str_sv, len);
2428 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2429 smooth, utf8, align);
2435 i_tt_bbox(handle,point,str_sv,utf8)
2436 Imager::Font::TT handle
2441 i_img_dim cords[BOUNDING_BOX_COUNT];
2447 str = SvPV(str_sv, len);
2452 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2454 for (i = 0; i < rc; ++i) {
2455 PUSHs(sv_2mortal(newSViv(cords[i])));
2460 i_tt_has_chars(handle, text_sv, utf8)
2461 Imager::Font::TT handle
2472 text = SvPV(text_sv, len);
2474 if (SvUTF8(text_sv))
2477 work = mymalloc(len);
2478 count = i_tt_has_chars(handle, text, len, utf8, work);
2479 if (GIMME_V == G_ARRAY) {
2481 for (i = 0; i < count; ++i) {
2482 PUSHs(boolSV(work[i]));
2487 PUSHs(sv_2mortal(newSVpv(work, count)));
2492 i_tt_dump_names(handle)
2493 Imager::Font::TT handle
2496 i_tt_face_name(handle)
2497 Imager::Font::TT handle
2502 len = i_tt_face_name(handle, name, sizeof(name));
2505 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2509 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2510 Imager::Font::TT handle
2522 text = SvPV(text_sv, work_len);
2524 if (SvUTF8(text_sv))
2531 ch = i_utf8_advance(&text, &len);
2533 i_push_error(0, "invalid UTF8 character");
2541 EXTEND(SP, count+1);
2542 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2543 ST(count) = sv_2mortal(newSVpv(name, 0));
2546 ST(count) = &PL_sv_undef;
2555 i_test_format_probe(ig, length)
2560 i_readpnm_wiol(ig, allow_incomplete)
2562 int allow_incomplete
2566 i_readpnm_multi_wiol(ig, allow_incomplete)
2568 int allow_incomplete
2574 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2577 for (i = 0; i < count; ++i) {
2578 SV *sv = sv_newmortal();
2579 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2586 i_writeppm_wiol(im, ig)
2595 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2604 i_writeraw_wiol(im,ig)
2609 i_writebmp_wiol(im,ig)
2614 i_readbmp_wiol(ig, allow_incomplete=0)
2616 int allow_incomplete
2620 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2629 idlen = SvCUR(ST(4));
2630 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2636 i_readtga_wiol(ig, length)
2644 i_scaleaxis(im,Value,Axis)
2650 i_scale_nn(im,scx,scy)
2656 i_scale_mixing(im, width, height)
2666 i_count_colors(im,maxc)
2671 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2676 unsigned int * col_usage = NULL;
2679 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2681 EXTEND(SP, col_cnt);
2682 for (i = 0; i < col_cnt; i++) {
2683 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2694 i_transform(im, opx, opy, parm)
2700 STRLEN size_opx, size_opy, size_parm;
2703 result=i_transform(im,opx,size_opx,opy,size_opy,parm,size_parm);
2705 SV *result_sv = sv_newmortal();
2707 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2712 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2738 in_imgs_count = av_len(av_in_imgs)+1;
2739 for (i = 0; i < in_imgs_count; ++i) {
2740 sv1 = *av_fetch(av_in_imgs, i, 0);
2741 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2742 croak("sv_in_img must contain only images");
2745 if (in_imgs_count > 0) {
2746 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2747 for (i = 0; i < in_imgs_count; ++i) {
2748 sv1 = *av_fetch(av_in_imgs,i,0);
2749 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2750 croak("Parameter 5 must contain only images");
2752 tmp = SvIV((SV*)SvRV(sv1));
2753 in_imgs[i] = INT2PTR(i_img*, tmp);
2757 /* no input images */
2760 /* default the output size from the first input if possible */
2762 width = SvIV(sv_width);
2763 else if (in_imgs_count)
2764 width = in_imgs[0]->xsize;
2766 croak("No output image width supplied");
2768 if (SvOK(sv_height))
2769 height = SvIV(sv_height);
2770 else if (in_imgs_count)
2771 height = in_imgs[0]->ysize;
2773 croak("No output image height supplied");
2775 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2776 if (ops_len % sizeof(struct rm_op))
2777 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2778 ops_count = ops_len / sizeof(struct rm_op);
2780 n_regs_count = av_len(av_n_regs)+1;
2781 n_regs = mymalloc(n_regs_count * sizeof(double));
2782 for (i = 0; i < n_regs_count; ++i) {
2783 sv1 = *av_fetch(av_n_regs,i,0);
2785 n_regs[i] = SvNV(sv1);
2787 c_regs_count = av_len(av_c_regs)+1;
2788 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2789 /* I don't bother initializing the colou?r registers */
2791 result=i_transform2(width, height, channels, ops, ops_count,
2792 n_regs, n_regs_count,
2793 c_regs, c_regs_count, in_imgs, in_imgs_count);
2799 SV *result_sv = sv_newmortal();
2801 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2807 i_contrast(im,intensity)
2820 i_noise(im,amount,type)
2826 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2836 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2855 i_postlevels(im,levels)
2865 i_watermark(im,wmark,tx,ty,pixdiff)
2867 Imager::ImgRaw wmark
2874 i_autolevels(im,lsat,usat,skew)
2881 i_autolevels_mono(im,lsat,usat)
2887 i_radnoise(im,xo,yo,rscale,ascale)
2895 i_turbnoise(im, xo, yo, scale)
2903 i_gradgen(im, xo, yo, ac, dmeasure)
2914 if (size_xo != size_yo || size_xo != size_ac)
2915 croak("i_gradgen: x, y and color arrays must be the same size");
2917 croak("Usage: i_gradgen array refs must have more than 1 entry each");
2918 i_gradgen(im, size_xo, xo, yo, ac, dmeasure);
2921 i_diff_image(im, im2, mindist=0)
2927 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2937 double ssample_param
2941 i_fountain_seg *segs;
2943 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2944 croak("i_fountain: argument 11 must be an array ref");
2946 asegs = (AV *)SvRV(ST(10));
2947 segs = load_fount_segs(aTHX_ asegs, &count);
2948 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2949 super_sample, ssample_param, count, segs);
2955 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2964 double ssample_param
2968 i_fountain_seg *segs;
2970 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2971 croak("i_fountain: argument 11 must be an array ref");
2973 asegs = (AV *)SvRV(ST(9));
2974 segs = load_fount_segs(aTHX_ asegs, &count);
2975 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2976 super_sample, ssample_param, count, segs);
2982 i_new_fill_opacity(other_fill, alpha_mult)
2983 Imager::FillHandle other_fill
2994 errors = i_errors();
2996 while (errors[i].msg) {
2998 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2999 if (!av_store(av, 0, sv)) {
3002 sv = newSViv(errors[i].code);
3003 if (!av_store(av, 1, sv)) {
3006 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3014 i_push_error(code, msg)
3019 i_nearest_color(im, ...)
3034 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3035 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3036 croak("i_nearest_color: Second argument must be an array ref");
3037 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3038 croak("i_nearest_color: Third argument must be an array ref");
3039 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3040 croak("i_nearest_color: Fourth argument must be an array ref");
3041 axx = (AV *)SvRV(ST(1));
3042 ayy = (AV *)SvRV(ST(2));
3043 ac = (AV *)SvRV(ST(3));
3044 dmeasure = (int)SvIV(ST(4));
3046 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3047 num = num <= av_len(ac) ? num : av_len(ac);
3049 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3050 xo = mymalloc( sizeof(i_img_dim) * num );
3051 yo = mymalloc( sizeof(i_img_dim) * num );
3052 ival = mymalloc( sizeof(i_color) * num );
3053 for(i = 0; i<num; i++) {
3054 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
3055 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
3056 sv = *av_fetch(ac, i, 0);
3057 if ( !sv_derived_from(sv, "Imager::Color") ) {
3058 free(axx); free(ayy); free(ac);
3059 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3061 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3063 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3077 rc=DSO_open(filename,&evstr);
3081 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3082 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3085 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3091 DSO_close(dso_handle)
3095 DSO_funclist(dso_handle_v)
3099 DSO_handle *dso_handle;
3100 func_ptr *functions;
3102 dso_handle=(DSO_handle*)dso_handle_v;
3103 functions = DSO_funclist(dso_handle);
3105 while( functions[i].name != NULL) {
3107 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3109 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3113 DSO_call(handle,func_index,hv)
3118 DSO_call( (DSO_handle *)handle,func_index,hv);
3121 i_get_pixel(im, x, y)
3126 RETVAL = (i_color *)mymalloc(sizeof(i_color));
3127 memset(RETVAL, 0, sizeof(*RETVAL));
3128 if (i_gpix(im, x, y, RETVAL) != 0) {
3137 i_ppix(im, x, y, cl)
3144 i_img_pal_new(x, y, channels, maxpal)
3151 i_img_to_pal(src, quant)
3157 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3158 croak("i_img_to_pal: second argument must be a hash ref");
3159 hv = (HV *)SvRV(ST(1));
3160 memset(&quant, 0, sizeof(quant));
3162 quant.mc_size = 256;
3163 ip_handle_quant_opts(aTHX_ &quant, hv);
3164 RETVAL = i_img_to_pal(src, &quant);
3166 ip_copy_colors_back(aTHX_ hv, &quant);
3168 ip_cleanup_quant_opts(aTHX_ &quant);
3177 i_img_make_palette(HV *quant_hv, ...)
3179 size_t count = items - 1;
3181 i_img **imgs = NULL;
3185 croak("Please supply at least one image (%d)", (int)count);
3186 imgs = mymalloc(sizeof(i_img *) * count);
3187 for (i = 0; i < count; ++i) {
3188 SV *img_sv = ST(i + 1);
3189 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3190 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3194 croak("Image %d is not an image object", (int)i+1);
3197 memset(&quant, 0, sizeof(quant));
3199 quant.mc_size = 256;
3200 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3201 i_quant_makemap(&quant, imgs, count);
3202 EXTEND(SP, quant.mc_count);
3203 for (i = 0; i < quant.mc_count; ++i) {
3204 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3207 ip_cleanup_quant_opts(aTHX_ &quant);
3221 work = mymalloc((r-l) * sizeof(i_palidx));
3222 count = i_gpal(im, l, r, y, work);
3223 if (GIMME_V == G_ARRAY) {
3225 for (i = 0; i < count; ++i) {
3226 PUSHs(sv_2mortal(newSViv(work[i])));
3231 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3236 if (GIMME_V != G_ARRAY) {
3238 PUSHs(&PL_sv_undef);
3243 i_ppal(im, l, y, ...)
3252 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3253 for (i=0; i < items-3; ++i) {
3254 work[i] = SvIV(ST(i+3));
3256 validate_i_ppal(im, work, items - 3);
3257 RETVAL = i_ppal(im, l, l+items-3, y, work);
3266 i_ppal_p(im, l, y, data)
3272 i_palidx const *work;
3275 work = (i_palidx const *)SvPV(data, len);
3276 len /= sizeof(i_palidx);
3278 validate_i_ppal(im, work, len);
3279 RETVAL = i_ppal(im, l, l+len, y, work);
3288 i_addcolors(im, ...)
3295 croak("i_addcolors: no colors to add");
3296 colors = mymalloc((items-1) * sizeof(i_color));
3297 for (i=0; i < items-1; ++i) {
3298 if (sv_isobject(ST(i+1))
3299 && sv_derived_from(ST(i+1), "Imager::Color")) {
3300 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3301 colors[i] = *INT2PTR(i_color *, tmp);
3305 croak("i_addcolor: pixels must be Imager::Color objects");
3308 RETVAL = i_addcolors(im, colors, items-1);
3314 i_setcolors(im, index, ...)
3322 croak("i_setcolors: no colors to add");
3323 colors = mymalloc((items-2) * sizeof(i_color));
3324 for (i=0; i < items-2; ++i) {
3325 if (sv_isobject(ST(i+2))
3326 && sv_derived_from(ST(i+2), "Imager::Color")) {
3327 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3328 colors[i] = *INT2PTR(i_color *, tmp);
3332 croak("i_setcolors: pixels must be Imager::Color objects");
3335 RETVAL = i_setcolors(im, index, colors, items-2);
3341 i_getcolors(im, index, count=1)
3350 croak("i_getcolors: count must be positive");
3351 colors = malloc_temp(aTHX_ sizeof(i_color) * count);
3352 if (i_getcolors(im, index, colors, count)) {
3354 for (i = 0; i < count; ++i) {
3355 SV *sv = make_i_color_sv(aTHX_ colors+i);
3369 i_findcolor(im, color)
3373 if (!i_findcolor(im, color, &RETVAL)) {
3392 i_gsamp(im, l, r, y, channels)
3397 i_channel_list channels
3403 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count);
3404 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3405 if (GIMME_V == G_ARRAY) {
3407 for (i = 0; i < count; ++i)
3408 PUSHs(sv_2mortal(newSViv(data[i])));
3412 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3417 if (GIMME_V != G_ARRAY) {
3423 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3431 i_channel_list channels
3438 croak("No channel numbers supplied to g_samp()");
3440 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3441 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3442 for (i = 0; i < count; ++i) {
3443 av_store(target, i+offset, newSVuv(data[i]));
3455 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3460 i_channel_list channels
3462 i_img_dim data_offset
3463 i_img_dim pixel_count
3472 data_count = av_len(data_av) + 1;
3473 if (data_offset < 0) {
3474 croak("data_offset must be non-negative");
3476 if (data_offset > data_count) {
3477 croak("data_offset greater than number of samples supplied");
3479 if (pixel_count == -1 ||
3480 data_offset + pixel_count * channels.count > data_count) {
3481 pixel_count = (data_count - data_offset) / channels.count;
3484 data_used = pixel_count * channels.count;
3485 data = mymalloc(sizeof(unsigned) * data_count);
3486 for (i = 0; i < data_used; ++i)
3487 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3489 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3490 channels.count, bits);
3498 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3502 i_channel_list channels
3511 i_push_error(0, "offset must be non-negative");
3515 if (offset > data.count) {
3516 i_push_error(0, "offset greater than number of samples supplied");
3519 data.samples += offset;
3520 data.count -= offset;
3523 width * channels.count > data.count) {
3524 width = data.count / channels.count;
3527 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3532 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3536 i_channel_list channels
3545 i_push_error(0, "offset must be non-negative");
3549 if (offset > data.count) {
3550 i_push_error(0, "offset greater than number of samples supplied");
3553 data.samples += offset;
3554 data.count -= offset;
3557 width * channels.count > data.count) {
3558 width = data.count / channels.count;
3561 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3566 i_img_masked_new(targ, mask, x, y, w, h)
3576 if (!sv_isobject(ST(1))
3577 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3578 croak("i_img_masked_new: parameter 2 must undef or an image");
3580 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3584 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3589 i_plin(im, l, y, ...)
3600 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3601 /* supplied as a byte string */
3602 work = (i_color *)SvPV(ST(3), len);
3603 count = len / sizeof(i_color);
3604 if (count * sizeof(i_color) != len) {
3605 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3607 RETVAL = i_plin(im, l, l+count, y, work);
3610 work = mymalloc(sizeof(i_color) * (items-3));
3611 for (i=0; i < items-3; ++i) {
3612 if (sv_isobject(ST(i+3))
3613 && sv_derived_from(ST(i+3), "Imager::Color")) {
3614 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3615 work[i] = *INT2PTR(i_color *, tmp);
3619 croak("i_plin: pixels must be Imager::Color objects");
3622 RETVAL = i_plin(im, l, l+items-3, y, work);
3633 i_ppixf(im, x, y, cl)
3637 Imager::Color::Float cl
3640 i_gsampf(im, l, r, y, channels)
3645 i_channel_list channels
3651 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3652 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3653 if (GIMME_V == G_ARRAY) {
3655 for (i = 0; i < count; ++i)
3656 PUSHs(sv_2mortal(newSVnv(data[i])));
3660 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3665 if (GIMME_V != G_ARRAY) {
3671 i_plinf(im, l, y, ...)
3682 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3683 /* supplied as a byte string */
3684 work = (i_fcolor *)SvPV(ST(3), len);
3685 count = len / sizeof(i_fcolor);
3686 if (count * sizeof(i_fcolor) != len) {
3687 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3689 RETVAL = i_plinf(im, l, l+count, y, work);
3692 work = mymalloc(sizeof(i_fcolor) * (items-3));
3693 for (i=0; i < items-3; ++i) {
3694 if (sv_isobject(ST(i+3))
3695 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3696 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3697 work[i] = *INT2PTR(i_fcolor *, tmp);
3701 croak("i_plinf: pixels must be Imager::Color::Float objects");
3705 RETVAL = i_plinf(im, l, l+items-3, y, work);
3715 Imager::Color::Float
3721 RETVAL = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3722 memset(RETVAL, 0, sizeof(*RETVAL));
3723 if (i_gpixf(im, x, y, RETVAL) != 0) {
3741 vals = mymalloc((r-l) * sizeof(i_color));
3742 memset(vals, 0, (r-l) * sizeof(i_color));
3743 count = i_glin(im, l, r, y, vals);
3744 if (GIMME_V == G_ARRAY) {
3746 for (i = 0; i < count; ++i) {
3747 SV *sv = make_i_color_sv(aTHX_ vals+i);
3753 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3759 i_glinf(im, l, r, y)
3769 for (i = 0; i < MAXCHANNELS; ++i)
3770 zero.channel[i] = 0;
3772 vals = mymalloc((r-l) * sizeof(i_fcolor));
3773 for (i = 0; i < r-l; ++i)
3775 count = i_glinf(im, l, r, y, vals);
3776 if (GIMME_V == G_ARRAY) {
3778 for (i = 0; i < count; ++i) {
3780 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3782 sv = sv_newmortal();
3783 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3789 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3795 i_img_8_new(x, y, ch)
3801 i_img_16_new(x, y, ch)
3811 i_img_double_new(x, y, ch)
3821 i_tags_addn(im, name_sv, code, idata)
3830 SvGETMAGIC(name_sv);
3832 name = SvPV_nomg(name_sv, len);
3835 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3840 i_tags_add(im, name_sv, code, data_sv, idata)
3851 SvGETMAGIC(name_sv);
3853 name = SvPV_nomg(name_sv, len);
3856 SvGETMAGIC(data_sv);
3858 data = SvPV(data_sv, len);
3863 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3868 i_tags_find(im, name, start)
3875 if (i_tags_find(&im->tags, name, start, &entry)) {
3884 i_tags_findn(im, code, start)
3891 if (i_tags_findn(&im->tags, code, start, &entry)) {
3901 i_tags_delete(im, entry)
3905 RETVAL = i_tags_delete(&im->tags, entry);
3910 i_tags_delbyname(im, name)
3914 RETVAL = i_tags_delbyname(&im->tags, name);
3919 i_tags_delbycode(im, code)
3923 RETVAL = i_tags_delbycode(&im->tags, code);
3928 i_tags_get(im, index)
3932 if (index >= 0 && index < im->tags.count) {
3933 i_img_tag *entry = im->tags.tags + index;
3937 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3940 PUSHs(sv_2mortal(newSViv(entry->code)));
3943 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3946 PUSHs(sv_2mortal(newSViv(entry->idata)));
3951 i_tags_get_string(im, what_sv)
3955 char const *name = NULL;
3959 if (SvIOK(what_sv)) {
3960 code = SvIV(what_sv);
3964 name = SvPV_nolen(what_sv);
3967 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3969 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3976 RETVAL = im->tags.count;
3982 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3986 Imager::FillHandle fill
3989 IFILL_CLONE_SKIP(...)
3991 (void)items; /* avoid unused warning for XS variable */
3996 MODULE = Imager PACKAGE = Imager
3999 i_new_fill_solid(cl, combine)
4004 i_new_fill_solidf(cl, combine)
4005 Imager::Color::Float cl
4009 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
4018 unsigned char *cust_hatch;
4021 SvGETMAGIC(cust_hatch_sv);
4022 if (SvOK(cust_hatch_sv)) {
4023 cust_hatch = (unsigned char *)SvPV_nomg(cust_hatch_sv, len);
4027 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4032 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
4033 Imager::Color::Float fg
4034 Imager::Color::Float bg
4041 unsigned char *cust_hatch;
4044 SvGETMAGIC(cust_hatch_sv);
4045 if (SvOK(cust_hatch_sv)) {
4046 cust_hatch = (unsigned char *)SvPV(cust_hatch_sv, len);
4050 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4055 i_new_fill_image(src, matrix_sv, xoff, yoff, combine)
4069 SvGETMAGIC(matrix_sv);
4070 if (!SvOK(matrix_sv)) {
4074 if (!SvROK(matrix_sv) || SvTYPE(SvRV(matrix_sv)) != SVt_PVAV)
4075 croak("i_new_fill_image: matrix parameter must be an arrayref or undef");
4076 av=(AV*)SvRV(matrix_sv);
4080 for (i = 0; i < len; ++i) {
4081 sv1=(*(av_fetch(av,i,0)));
4082 matrix[i] = SvNV(sv1);
4088 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4092 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4094 # this class is only exposed for testing
4097 i_int_hlines_testing()
4099 #if i_int_hlines_testing()
4101 Imager::Internal::Hlines
4102 i_int_hlines_new(start_y, count_y, start_x, count_x)
4108 Imager::Internal::Hlines
4109 i_int_hlines_new_img(im)
4113 i_int_hlines_add(hlines, y, minx, width)
4114 Imager::Internal::Hlines hlines
4120 i_int_hlines_DESTROY(hlines)
4121 Imager::Internal::Hlines hlines
4124 i_int_hlines_dump(hlines)
4125 Imager::Internal::Hlines hlines
4128 i_int_hlines_CLONE_SKIP(cls)
4132 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4135 im_context_DESTROY(ctx)
4138 #ifdef PERL_IMPLICIT_CONTEXT
4141 im_context_CLONE(...)
4145 /* the following sv_setref_pv() will free this inc */
4146 im_context_refinc(MY_CXT.ctx, "CLONE");
4147 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4148 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4153 PERL_SET_GLOBAL_CALLBACKS;
4154 PERL_PL_SET_GLOBAL_CALLBACKS;
4155 #ifdef PERL_IMPLICIT_CONTEXT
4161 start_context(aTHX);
4162 im_get_context = perl_get_context;