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) {
127 SV *sv = sv_2mortal(newSV(size));
133 calloc_temp(pTHX_ size_t size) {
134 void *result = malloc_temp(aTHX_ size);
135 memset(result, 0, size);
140 /* for use with the T_AVARRAY typemap */
141 #define doublePtr(size) ((double *)calloc_temp(aTHX_ sizeof(double) * (size)))
142 #define SvDouble(sv, pname) (SvNV(sv))
144 #define intPtr(size) ((int *)calloc_temp(aTHX_ sizeof(int) * (size)))
145 #define SvInt(sv, pname) (SvIV(sv))
147 #define i_img_dimPtr(size) ((i_img_dim *)calloc_temp(aTHX_ sizeof(i_img_dim) * (size)))
148 #define SvI_img_dim(sv, pname) (SvIV(sv))
150 #define i_colorPtr(size) ((i_color *)calloc_temp(aTHX_ sizeof(i_color *) * (size)))
152 #define SvI_color(sv, pname) S_sv_to_i_color(aTHX_ sv, pname)
155 S_sv_to_i_color(pTHX_ SV *sv, const char *pname) {
156 if (!sv_derived_from(sv, "Imager::Color")) {
157 croak("%s: not a color object", pname);
159 return *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
162 /* These functions are all shared - then comes platform dependant code */
163 static int getstr(void *hv_t,char *key,char **store) {
168 mm_log((1,"getstr(hv_t %p, key %s, store %p)\n",hv_t,key,store));
170 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
172 svpp=hv_fetch(hv, key, strlen(key), 0);
173 *store=SvPV(*svpp, PL_na );
178 static int getint(void *hv_t,char *key,int *store) {
183 mm_log((1,"getint(hv_t %p, key %s, store %p)\n",hv_t,key,store));
185 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
187 svpp=hv_fetch(hv, key, strlen(key), 0);
188 *store=(int)SvIV(*svpp);
192 static int getdouble(void *hv_t,char* key,double *store) {
197 mm_log((1,"getdouble(hv_t %p, key %s, store %p)\n",hv_t,key,store));
199 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
200 svpp=hv_fetch(hv, key, strlen(key), 0);
201 *store=(double)SvNV(*svpp);
205 static int getvoid(void *hv_t,char* key,void **store) {
210 mm_log((1,"getvoid(hv_t %p, key %s, store %p)\n",hv_t,key,store));
212 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
214 svpp=hv_fetch(hv, key, strlen(key), 0);
215 *store = INT2PTR(void*, SvIV(*svpp));
220 static int getobj(void *hv_t,char *key,char *type,void **store) {
225 mm_log((1,"getobj(hv_t %p, key %s,type %s, store %p)\n",hv_t,key,type,store));
227 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
229 svpp=hv_fetch(hv, key, strlen(key), 0);
231 if (sv_derived_from(*svpp,type)) {
232 IV tmp = SvIV((SV*)SvRV(*svpp));
233 *store = INT2PTR(void*, tmp);
235 mm_log((1,"getobj: key exists in hash but is not of correct type"));
242 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
245 free_buffer(void *p) {
251 i_log_entry(char *string, int level) {
252 mm_log((level, "%s", string));
256 make_i_color_sv(pTHX_ const i_color *c) {
258 i_color *col = mymalloc(sizeof(i_color));
261 sv_setref_pv(sv, "Imager::Color", (void *)col);
266 #define CBDATA_BUFSIZE 8192
269 /* the SVs we use to call back to Perl */
277 call_reader(struct cbdata *cbd, void *buf, size_t size,
285 if (!SvOK(cbd->readcb)) {
286 mm_log((1, "read callback called but no readcb supplied\n"));
287 i_push_error(0, "read callback called but no readcb supplied");
295 PUSHs(sv_2mortal(newSViv(size)));
296 PUSHs(sv_2mortal(newSViv(maxread)));
299 count = perl_call_sv(cbd->readcb, G_SCALAR);
304 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
310 char *ptr = SvPVbyte(data, len);
312 croak("Too much data returned in reader callback (wanted %d, got %d, expected %d)",
313 (int)size, (int)len, (int)maxread);
315 memcpy(buf, ptr, len);
330 io_seeker(void *p, off_t offset, int whence) {
332 struct cbdata *cbd = p;
337 if (!SvOK(cbd->seekcb)) {
338 mm_log((1, "seek callback called but no seekcb supplied\n"));
339 i_push_error(0, "seek callback called but no seekcb supplied");
347 PUSHs(sv_2mortal(newSViv(offset)));
348 PUSHs(sv_2mortal(newSViv(whence)));
351 count = perl_call_sv(cbd->seekcb, G_SCALAR);
356 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
368 io_writer(void *p, void const *data, size_t size) {
370 struct cbdata *cbd = p;
376 if (!SvOK(cbd->writecb)) {
377 mm_log((1, "write callback called but no writecb supplied\n"));
378 i_push_error(0, "write callback called but no writecb supplied");
386 PUSHs(sv_2mortal(newSVpv((char *)data, size)));
389 count = perl_call_sv(cbd->writecb, G_SCALAR);
393 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
396 success = SvTRUE(sv);
403 return success ? size : -1;
407 io_reader(void *p, void *data, size_t size) {
408 struct cbdata *cbd = p;
410 return call_reader(cbd, data, size, size);
413 static int io_closer(void *p) {
415 struct cbdata *cbd = p;
418 if (SvOK(cbd->closecb)) {
427 count = perl_call_sv(cbd->closecb, G_SCALAR);
433 success = SvTRUE(sv);
443 return success ? 0 : -1;
446 static void io_destroyer(void *p) {
448 struct cbdata *cbd = p;
450 SvREFCNT_dec(cbd->writecb);
451 SvREFCNT_dec(cbd->readcb);
452 SvREFCNT_dec(cbd->seekcb);
453 SvREFCNT_dec(cbd->closecb);
458 im_SvREFSCALAR(SV *sv) {
459 svtype type = SvTYPE(sv);
469 #if PERL_VERSION > 10
480 describe_sv(SV *sv) {
483 svtype type = SvTYPE(SvRV(sv));
485 case SVt_PVCV: return "CV";
486 case SVt_PVGV: return "GV";
487 case SVt_PVLV: return "LV";
488 default: return "some reference";
492 return "non-reference scalar";
501 do_io_new_buffer(pTHX_ SV *data_sv) {
508 if (SvROK(data_sv)) {
509 if (im_SvREFSCALAR(SvRV(data_sv))) {
513 i_push_errorf(0, "data is not a scalar or a reference to scalar");
521 /* previously this would keep the SV around, but this is unsafe in
522 many ways, so always copy the bytes */
523 data = SvPVbyte(sv, length);
524 data_copy = mymalloc(length);
525 memcpy(data_copy, data, length);
526 return io_new_buffer(data_copy, length, free_buffer, data_copy);
530 do_io_new_cb(pTHX_ SV *writecb, SV *readcb, SV *seekcb, SV *closecb) {
533 cbd = mymalloc(sizeof(struct cbdata));
534 cbd->writecb = newSVsv(writecb);
535 cbd->readcb = newSVsv(readcb);
536 cbd->seekcb = newSVsv(seekcb);
537 cbd->closecb = newSVsv(closecb);
539 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)));
541 return io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
549 static int lookup_name(const struct value_name *names, int count, char *name, int def_value)
552 for (i = 0; i < count; ++i)
553 if (strEQ(names[i].name, name))
554 return names[i].value;
558 static struct value_name transp_names[] =
561 { "threshold", tr_threshold },
562 { "errdiff", tr_errdiff },
563 { "ordered", tr_ordered, },
566 static struct value_name make_color_names[] =
568 { "none", mc_none, },
569 { "webmap", mc_web_map, },
570 { "addi", mc_addi, },
571 { "mediancut", mc_median_cut, },
572 { "mono", mc_mono, },
573 { "monochrome", mc_mono, },
574 { "gray", mc_gray, },
575 { "gray4", mc_gray4, },
576 { "gray16", mc_gray16, },
579 static struct value_name translate_names[] =
581 { "giflib", pt_giflib, },
582 { "closest", pt_closest, },
583 { "perturb", pt_perturb, },
584 { "errdiff", pt_errdiff, },
587 static struct value_name errdiff_names[] =
589 { "floyd", ed_floyd, },
590 { "jarvis", ed_jarvis, },
591 { "stucki", ed_stucki, },
592 { "custom", ed_custom, },
595 static struct value_name orddith_names[] =
597 { "random", od_random, },
598 { "dot8", od_dot8, },
599 { "dot4", od_dot4, },
600 { "hline", od_hline, },
601 { "vline", od_vline, },
602 { "/line", od_slashline, },
603 { "slashline", od_slashline, },
604 { "\\line", od_backline, },
605 { "backline", od_backline, },
606 { "tiny", od_tiny, },
607 { "custom", od_custom, },
610 /* look through the hash for quantization options */
612 ip_handle_quant_opts(pTHX_ i_quantize *quant, HV *hv)
614 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
620 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
622 sv = hv_fetch(hv, "transp", 6, 0);
623 if (sv && *sv && (str = SvPV(*sv, len))) {
625 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
627 if (quant->transp != tr_none) {
628 quant->tr_threshold = 127;
629 sv = hv_fetch(hv, "tr_threshold", 12, 0);
631 quant->tr_threshold = SvIV(*sv);
633 if (quant->transp == tr_errdiff) {
634 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
635 if (sv && *sv && (str = SvPV(*sv, len)))
636 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
638 if (quant->transp == tr_ordered) {
639 quant->tr_orddith = od_tiny;
640 sv = hv_fetch(hv, "tr_orddith", 10, 0);
641 if (sv && *sv && (str = SvPV(*sv, len)))
642 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
644 if (quant->tr_orddith == od_custom) {
645 sv = hv_fetch(hv, "tr_map", 6, 0);
646 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
647 AV *av = (AV*)SvRV(*sv);
648 len = av_len(av) + 1;
649 if (len > sizeof(quant->tr_custom))
650 len = sizeof(quant->tr_custom);
651 for (i = 0; i < len; ++i) {
652 SV **sv2 = av_fetch(av, i, 0);
654 quant->tr_custom[i] = SvIV(*sv2);
657 while (i < sizeof(quant->tr_custom))
658 quant->tr_custom[i++] = 0;
663 quant->make_colors = mc_median_cut;
664 sv = hv_fetch(hv, "make_colors", 11, 0);
665 if (sv && *sv && (str = SvPV(*sv, len))) {
667 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_median_cut);
669 sv = hv_fetch(hv, "colors", 6, 0);
670 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
671 /* needs to be an array of Imager::Color
672 note that the caller allocates the mc_color array and sets mc_size
674 AV *av = (AV *)SvRV(*sv);
675 quant->mc_count = av_len(av)+1;
676 if (quant->mc_count > quant->mc_size)
677 quant->mc_count = quant->mc_size;
678 for (i = 0; i < quant->mc_count; ++i) {
679 SV **sv1 = av_fetch(av, i, 0);
680 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
681 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
682 quant->mc_colors[i] = *col;
686 sv = hv_fetch(hv, "max_colors", 10, 0);
689 if (i <= quant->mc_size && i >= quant->mc_count)
693 quant->translate = pt_closest;
694 sv = hv_fetch(hv, "translate", 9, 0);
695 if (sv && *sv && (str = SvPV(*sv, len))) {
696 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
698 sv = hv_fetch(hv, "errdiff", 7, 0);
699 if (sv && *sv && (str = SvPV(*sv, len))) {
700 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
702 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
703 /* get the error diffusion map */
704 sv = hv_fetch(hv, "errdiff_width", 13, 0);
706 quant->ed_width = SvIV(*sv);
707 sv = hv_fetch(hv, "errdiff_height", 14, 0);
709 quant->ed_height = SvIV(*sv);
710 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
712 quant->ed_orig = SvIV(*sv);
713 if (quant->ed_width > 0 && quant->ed_height > 0) {
715 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
716 sv = hv_fetch(hv, "errdiff_map", 11, 0);
717 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
718 AV *av = (AV*)SvRV(*sv);
719 len = av_len(av) + 1;
720 if (len > quant->ed_width * quant->ed_height)
721 len = quant->ed_width * quant->ed_height;
722 for (i = 0; i < len; ++i) {
723 SV **sv2 = av_fetch(av, i, 0);
725 quant->ed_map[i] = SvIV(*sv2);
726 sum += quant->ed_map[i];
732 myfree(quant->ed_map);
734 quant->errdiff = ed_floyd;
738 sv = hv_fetch(hv, "perturb", 7, 0);
740 quant->perturb = SvIV(*sv);
744 ip_cleanup_quant_opts(pTHX_ i_quantize *quant) {
745 myfree(quant->mc_colors);
747 myfree(quant->ed_map);
750 /* copies the color map from the hv into the colors member of the HV */
752 ip_copy_colors_back(pTHX_ HV *hv, i_quantize *quant) {
758 sv = hv_fetch(hv, "colors", 6, 0);
759 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
764 av = (AV *)SvRV(*sv);
766 av_extend(av, quant->mc_count+1);
767 for (i = 0; i < quant->mc_count; ++i) {
768 i_color *in = quant->mc_colors+i;
769 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
770 work = sv_newmortal();
771 sv_setref_pv(work, "Imager::Color", (void *)c);
777 static struct value_name
778 poly_fill_mode_names[] =
780 { "evenodd", i_pfm_evenodd },
781 { "nonzero", i_pfm_nonzero }
784 static i_poly_fill_mode_t
785 S_get_poly_fill_mode(pTHX_ SV *sv) {
786 if (looks_like_number(sv)) {
788 if (work < (IV)i_pfm_evenodd || work > (IV)i_pfm_nonzero)
789 work = (IV)i_pfm_evenodd;
790 return (i_poly_fill_mode_t)work;
793 return (i_poly_fill_mode_t)lookup_name
794 (poly_fill_mode_names, ARRAY_COUNT(poly_fill_mode_names),
795 SvPV_nolen(sv), i_pfm_evenodd);
800 S_get_polygon_list(pTHX_ i_polygon_list *polys, SV *sv) {
806 if (!SvOK(sv) || !SvROK(sv) || SvTYPE(SvRV(sv)) != SVt_PVAV)
807 croak("polys must be an arrayref");
810 polys->count = av_len(av) + 1;
811 if (polys->count < 1)
812 croak("polypolygon: no polygons provided");
813 s = malloc_temp(aTHX_ sizeof(i_polygon_t) * polys->count);
814 for (i = 0; i < polys->count; ++i) {
815 SV **poly_sv = av_fetch(av, i, 0);
819 double *x_data, *y_data;
824 croak("poly_polygon: nothing found for polygon %d", i);
825 /* needs to be another av */
826 SvGETMAGIC(*poly_sv);
827 if (!SvOK(*poly_sv) || !SvROK(*poly_sv) || SvTYPE(SvRV(*poly_sv)) != SVt_PVAV)
828 croak("poly_polygon: polygon %d isn't an arrayref", i);
829 poly_av = (AV*)SvRV(*poly_sv);
830 /* with two elements */
831 if (av_len(poly_av) != 1)
832 croak("poly_polygon: polygon %d should contain two arrays", i);
833 x_sv = av_fetch(poly_av, 0, 0);
834 y_sv = av_fetch(poly_av, 1, 0);
836 croak("poly_polygon: polygon %d has no x elements", i);
838 croak("poly_polygon: polygon %d has no y elements", i);
841 if (!SvOK(*x_sv) || !SvROK(*x_sv) || SvTYPE(SvRV(*x_sv)) != SVt_PVAV)
842 croak("poly_polygon: polygon %d x elements isn't an array", i);
843 if (!SvOK(*y_sv) || !SvROK(*y_sv) || SvTYPE(SvRV(*y_sv)) != SVt_PVAV)
844 croak("poly_polygon: polygon %d y elements isn't an array", i);
845 x_av = (AV*)SvRV(*x_sv);
846 y_av = (AV*)SvRV(*y_sv);
847 if (av_len(x_av) != av_len(y_av))
848 croak("poly_polygon: polygon %d x and y arrays different lengths", i+1);
849 point_count = av_len(x_av)+1;
850 x_data = malloc_temp(aTHX_ sizeof(double) * point_count * 2);
851 y_data = x_data + point_count;
853 for (j = 0; j < point_count; ++j) {
854 SV **x_item_sv = av_fetch(x_av, j, 0);
855 SV **y_item_sv = av_fetch(y_av, j, 0);
856 x_data[j] = x_item_sv ? SvNV(*x_item_sv) : 0;
857 y_data[j] = y_item_sv ? SvNV(*y_item_sv) : 0;
861 s[i].count = point_count;
866 /* loads the segments of a fountain fill into an array */
867 static i_fountain_seg *
868 load_fount_segs(pTHX_ AV *asegs, int *count) {
869 /* Each element of segs must contain:
870 [ start, middle, end, c0, c1, segtype, colortrans ]
871 start, middle, end are doubles from 0 to 1
872 c0, c1 are Imager::Color::Float or Imager::Color objects
873 segtype, colortrans are ints
877 i_fountain_seg *segs;
881 *count = av_len(asegs)+1;
883 croak("i_fountain must have at least one segment");
884 segs = mymalloc(sizeof(i_fountain_seg) * *count);
885 for(i = 0; i < *count; i++) {
886 SV **sv1 = av_fetch(asegs, i, 0);
887 if (!sv1 || !*sv1 || !SvROK(*sv1)
888 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
890 croak("i_fountain: segs must be an arrayref of arrayrefs");
892 aseg = (AV *)SvRV(*sv1);
893 if (av_len(aseg) != 7-1) {
895 croak("i_fountain: a segment must have 7 members");
897 for (j = 0; j < 3; ++j) {
898 SV **sv2 = av_fetch(aseg, j, 0);
901 croak("i_fountain: XS error");
903 work[j] = SvNV(*sv2);
905 segs[i].start = work[0];
906 segs[i].middle = work[1];
907 segs[i].end = work[2];
908 for (j = 0; j < 2; ++j) {
909 SV **sv3 = av_fetch(aseg, 3+j, 0);
910 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
911 (!sv_derived_from(*sv3, "Imager::Color")
912 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
914 croak("i_fountain: segs must contain colors in elements 3 and 4");
916 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
917 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
920 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
922 for (ch = 0; ch < MAXCHANNELS; ++ch) {
923 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
927 for (j = 0; j < 2; ++j) {
928 SV **sv2 = av_fetch(aseg, j+5, 0);
931 croak("i_fountain: XS error");
933 worki[j] = SvIV(*sv2);
935 segs[i].type = worki[0];
936 segs[i].color = worki[1];
942 /* validates the indexes supplied to i_ppal
944 i_ppal() doesn't do that for speed, but I'm not comfortable doing that
949 validate_i_ppal(i_img *im, i_palidx const *indexes, int count) {
950 int color_count = i_colorcount(im);
953 if (color_count == -1)
954 croak("i_plin() called on direct color image");
956 for (i = 0; i < count; ++i) {
957 if (indexes[i] >= color_count) {
958 croak("i_plin() called with out of range color index %d (max %d)",
959 indexes[i], color_count-1);
964 /* I don't think ICLF_* names belong at the C interface
965 this makes the XS code think we have them, to let us avoid
966 putting function bodies in the XS code
968 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
969 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
972 #define i_log_enabled() 1
974 #define i_log_enabled() 0
977 #if i_int_hlines_testing()
979 typedef i_int_hlines *Imager__Internal__Hlines;
981 static i_int_hlines *
982 i_int_hlines_new(i_img_dim start_y, i_img_dim count_y, i_img_dim start_x, i_img_dim count_x) {
983 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
984 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
989 static i_int_hlines *
990 i_int_hlines_new_img(i_img *im) {
991 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
992 i_int_init_hlines_img(result, im);
998 i_int_hlines_DESTROY(i_int_hlines *hlines) {
999 i_int_hlines_destroy(hlines);
1003 #define i_int_hlines_CLONE_SKIP(cls) 1
1005 static int seg_compare(const void *vleft, const void *vright) {
1006 const i_int_hline_seg *left = vleft;
1007 const i_int_hline_seg *right = vright;
1009 return left->minx - right->minx;
1013 i_int_hlines_dump(i_int_hlines *hlines) {
1015 SV *dump = newSVpvf("start_y: %" i_DF " limit_y: %" i_DF " start_x: %" i_DF " limit_x: %" i_DF"\n",
1016 i_DFc(hlines->start_y), i_DFc(hlines->limit_y), i_DFc(hlines->start_x), i_DFc(hlines->limit_x));
1019 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
1020 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
1023 /* sort the segments, if any */
1025 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
1027 sv_catpvf(dump, " %" i_DF " (%" i_DF "):", i_DFc(y), i_DFc(entry->count));
1028 for (i = 0; i < entry->count; ++i) {
1029 sv_catpvf(dump, " [%" i_DF ", %" i_DF ")", i_DFc(entry->segs[i].minx),
1030 i_DFc(entry->segs[i].x_limit));
1032 sv_catpv(dump, "\n");
1042 i_sv_off_t(pTHX_ SV *sv) {
1043 #if LSEEKSIZE > IVSIZE
1044 return (off_t)SvNV(sv);
1046 return (off_t)SvIV(sv);
1051 i_new_sv_off_t(pTHX_ off_t off) {
1052 #if LSEEKSIZE > IVSIZE
1053 return newSVnv(off);
1055 return newSViv(off);
1059 static im_pl_ext_funcs im_perl_funcs =
1061 IMAGER_PL_API_VERSION,
1062 IMAGER_PL_API_LEVEL,
1063 ip_handle_quant_opts,
1064 ip_cleanup_quant_opts,
1068 #define PERL_PL_SET_GLOBAL_CALLBACKS \
1069 sv_setiv(get_sv(PERL_PL_FUNCTION_TABLE_NAME, 1), PTR2IV(&im_perl_funcs));
1071 #define IIM_new i_img_8_new
1072 #define IIM_DESTROY i_img_destroy
1075 #ifdef IMEXIF_ENABLE
1076 #define i_exif_enabled() 1
1078 #define i_exif_enabled() 0
1081 /* trying to use more C style names, map them here */
1082 #define i_io_DESTROY(ig) io_glue_destroy(ig)
1084 #define i_img_get_width(im) ((im)->xsize)
1085 #define i_img_get_height(im) ((im)->ysize)
1087 #define i_img_epsilonf() (DBL_EPSILON * 4)
1089 /* avoid some xsubpp strangeness */
1090 #define NEWLINE '\n'
1092 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
1095 ICL_new_internal(r,g,b,a)
1107 ICL_set_internal(cl,r,g,b,a)
1114 ICL_set_internal(cl, r, g, b, a);
1128 PUSHs(sv_2mortal(newSViv(cl->rgba.r)));
1129 PUSHs(sv_2mortal(newSViv(cl->rgba.g)));
1130 PUSHs(sv_2mortal(newSViv(cl->rgba.b)));
1131 PUSHs(sv_2mortal(newSViv(cl->rgba.a)));
1137 RETVAL = mymalloc(sizeof(i_color));
1139 i_hsv_to_rgb(RETVAL);
1147 RETVAL = mymalloc(sizeof(i_color));
1149 i_rgb_to_hsv(RETVAL);
1155 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
1157 Imager::Color::Float
1158 ICLF_new_internal(r, g, b, a)
1166 Imager::Color::Float cl
1170 Imager::Color::Float cl
1174 EXTEND(SP, MAXCHANNELS);
1175 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1176 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1177 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1181 ICLF_set_internal(cl,r,g,b,a)
1182 Imager::Color::Float cl
1195 Imager::Color::Float
1197 Imager::Color::Float c
1199 RETVAL = mymalloc(sizeof(i_fcolor));
1201 i_hsv_to_rgbf(RETVAL);
1205 Imager::Color::Float
1207 Imager::Color::Float c
1209 RETVAL = mymalloc(sizeof(i_fcolor));
1211 i_rgb_to_hsvf(RETVAL);
1215 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1229 MODULE = Imager PACKAGE = Imager
1243 io_new_buffer(data_sv)
1247 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1254 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1260 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1268 unsigned char* data;
1272 tlength = io_slurp(ig, &data);
1273 RETVAL = newSVpv((char *)data,tlength);
1280 i_set_image_file_limits(width, height, bytes)
1286 i_get_image_file_limits()
1288 i_img_dim width, height;
1291 if (i_get_image_file_limits(&width, &height, &bytes)) {
1293 PUSHs(sv_2mortal(newSViv(width)));
1294 PUSHs(sv_2mortal(newSViv(height)));
1295 PUSHs(sv_2mortal(newSVuv(bytes)));
1299 i_int_check_image_file_limits(width, height, channels, sample_size)
1306 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_
1309 io_new_fd(class, fd)
1312 RETVAL = io_new_fd(fd);
1317 io_new_buffer(class, data_sv)
1321 RETVAL = do_io_new_buffer(aTHX_ data_sv);
1328 io_new_cb(class, writecb, readcb, seekcb, closecb)
1334 RETVAL = do_io_new_cb(aTHX_ writecb, readcb, seekcb, closecb);
1339 io_new_bufchain(class)
1341 RETVAL = io_new_bufchain();
1346 io__new_perlio(class, io)
1349 RETVAL = im_io_new_perlio(aTHX_ io);
1357 unsigned char* data;
1361 tlength = io_slurp(ig, &data);
1362 RETVAL = newSVpv((char *)data,tlength);
1367 MODULE = Imager PACKAGE = Imager::IO PREFIX = i_io_
1370 i_io_raw_write(ig, data_sv)
1377 data = SvPVbyte(data_sv, size);
1378 RETVAL = i_io_raw_write(ig, data, size);
1383 i_io_raw_read(ig, buffer_sv, size)
1392 croak("size negative in call to i_io_raw_read()");
1393 /* prevent an undefined value warning if they supplied an
1395 Orginally conditional on !SvOK(), but this will prevent the
1396 downgrade from croaking */
1397 sv_setpvn(buffer_sv, "", 0);
1399 if (SvUTF8(buffer_sv))
1400 sv_utf8_downgrade(buffer_sv, FALSE);
1402 buffer = SvGROW(buffer_sv, size+1);
1403 result = i_io_raw_read(ig, buffer, size);
1405 SvCUR_set(buffer_sv, result);
1406 *SvEND(buffer_sv) = '\0';
1407 SvPOK_only(buffer_sv);
1409 PUSHs(sv_2mortal(newSViv(result)));
1415 i_io_raw_read2(ig, size)
1424 croak("size negative in call to i_io_read2()");
1425 buffer_sv = newSV(size);
1426 buffer = SvGROW(buffer_sv, size+1);
1427 result = i_io_raw_read(ig, buffer, size);
1429 SvCUR_set(buffer_sv, result);
1430 *SvEND(buffer_sv) = '\0';
1431 SvPOK_only(buffer_sv);
1433 PUSHs(sv_2mortal(buffer_sv));
1437 SvREFCNT_dec(buffer_sv);
1441 i_io_raw_seek(ig, position, whence)
1455 i_io_CLONE_SKIP(...)
1457 (void)items; /* avoid unused warning for XS variable */
1484 i_io_seek(ig, off, whence)
1490 i_io_peekn(ig, size)
1498 buffer_sv = newSV(size+1);
1499 buffer = SvGROW(buffer_sv, size+1);
1500 result = i_io_peekn(ig, buffer, size);
1502 SvCUR_set(buffer_sv, result);
1503 *SvEND(buffer_sv) = '\0';
1504 SvPOK_only(buffer_sv);
1506 PUSHs(sv_2mortal(buffer_sv));
1510 SvREFCNT_dec(buffer_sv);
1514 i_io_read(ig, buffer_sv, size)
1523 croak("size negative in call to i_io_read()");
1524 /* prevent an undefined value warning if they supplied an
1526 Orginally conditional on !SvOK(), but this will prevent the
1527 downgrade from croaking */
1528 sv_setpvn(buffer_sv, "", 0);
1530 if (SvUTF8(buffer_sv))
1531 sv_utf8_downgrade(buffer_sv, FALSE);
1533 buffer = SvGROW(buffer_sv, size+1);
1534 result = i_io_read(ig, buffer, size);
1536 SvCUR_set(buffer_sv, result);
1537 *SvEND(buffer_sv) = '\0';
1538 SvPOK_only(buffer_sv);
1540 PUSHs(sv_2mortal(newSViv(result)));
1546 i_io_read2(ig, size)
1555 croak("size zero in call to read2()");
1556 buffer_sv = newSV(size);
1557 buffer = SvGROW(buffer_sv, size+1);
1558 result = i_io_read(ig, buffer, size);
1560 SvCUR_set(buffer_sv, result);
1561 *SvEND(buffer_sv) = '\0';
1562 SvPOK_only(buffer_sv);
1564 PUSHs(sv_2mortal(buffer_sv));
1568 SvREFCNT_dec(buffer_sv);
1572 i_io_gets(ig, size = 8192, eol = NEWLINE)
1582 croak("size too small in call to gets()");
1583 buffer_sv = sv_2mortal(newSV(size+1));
1584 buffer = SvPVX(buffer_sv);
1585 result = i_io_gets(ig, buffer, size+1, eol);
1587 SvCUR_set(buffer_sv, result);
1588 *SvEND(buffer_sv) = '\0';
1589 SvPOK_only(buffer_sv);
1595 i_io_write(ig, data_sv)
1602 data = SvPVbyte(data_sv, size);
1603 RETVAL = i_io_write(ig, data, size);
1608 i_io_dump(ig, flags = I_IO_DUMP_DEFAULT)
1613 i_io_set_buffered(ig, flag = 1)
1618 i_io_is_buffered(ig)
1629 MODULE = Imager PACKAGE = Imager
1640 while( (item=i_format_list[i++]) != NULL ) {
1642 PUSHs(sv_2mortal(newSVpv(item,0)));
1646 i_sametype(im, x, y)
1652 i_sametype_chans(im, x, y, channels)
1659 i_init_log(name_sv,level)
1663 const char *name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
1665 RETVAL = i_init_log(name, level);
1670 i_log_entry(string,level)
1683 i_img_info(im,info);
1685 PUSHs(sv_2mortal(newSViv(info[0])));
1686 PUSHs(sv_2mortal(newSViv(info[1])));
1687 PUSHs(sv_2mortal(newSViv(info[2])));
1688 PUSHs(sv_2mortal(newSViv(info[3])));
1694 i_img_setmask(im,ch_mask)
1703 i_img_getchannels(im)
1712 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1720 i_img_get_height(im)
1724 i_img_color_model(im)
1728 i_img_color_channels(im)
1732 i_img_alpha_channel(im)
1735 if (!i_img_alpha_channel(im, &RETVAL))
1741 i_img_is_monochrome(im)
1747 result = i_img_is_monochrome(im, &zero_is_white);
1749 if (GIMME_V == G_ARRAY) {
1752 PUSHs(sv_2mortal(newSViv(zero_is_white)));
1761 i_line(im,x1,y1,x2,y2,val,endp)
1771 i_line_aa(im,x1,y1,x2,y2,val,endp)
1781 i_box(im,x1,y1,x2,y2,val)
1790 i_box_filled(im,x1,y1,x2,y2,val)
1799 i_box_filledf(im,x1,y1,x2,y2,val)
1805 Imager::Color::Float val
1808 i_box_cfill(im,x1,y1,x2,y2,fill)
1814 Imager::FillHandle fill
1817 i_arc(im,x,y,rad,d1,d2,val)
1827 i_arc_aa(im,x,y,rad,d1,d2,val)
1837 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1844 Imager::FillHandle fill
1847 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1854 Imager::FillHandle fill
1858 i_circle_aa(im,x,y,rad,val)
1866 i_circle_aa_fill(im,x,y,rad,fill)
1871 Imager::FillHandle fill
1874 i_circle_out(im,x,y,rad,val)
1882 i_circle_out_aa(im,x,y,rad,val)
1890 i_arc_out(im,x,y,rad,d1,d2,val)
1900 i_arc_out_aa(im,x,y,rad,d1,d2,val)
1911 i_bezier_multi(im,x,y,val)
1920 if (size_x != size_y)
1921 croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1922 i_bezier_multi(im,size_x,x,y,val);
1925 i_poly_aa_m(im,x,y,mode,val)
1929 i_poly_fill_mode_t mode
1935 if (size_x != size_y)
1936 croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1937 RETVAL = i_poly_aa_m(im, size_x, x, y, mode, val);
1942 i_poly_aa_cfill_m(im, x, y, mode, fill)
1946 i_poly_fill_mode_t mode
1947 Imager::FillHandle fill
1952 if (size_x != size_y)
1953 croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1954 RETVAL = i_poly_aa_cfill_m(im, size_x, x, y, mode, fill);
1959 i_poly_poly_aa(im, polys, mode, color)
1961 i_polygon_list polys
1962 i_poly_fill_mode_t mode
1965 RETVAL = i_poly_poly_aa(im, polys.count, polys.polygons, mode, color);
1970 i_poly_poly_aa_cfill(im, polys, mode, fill)
1972 i_polygon_list polys
1973 i_poly_fill_mode_t mode
1974 Imager::FillHandle fill
1976 RETVAL = i_poly_poly_aa_cfill(im, polys.count, polys.polygons, mode, fill);
1981 i_flood_fill(im,seedx,seedy,dcol)
1988 i_flood_cfill(im,seedx,seedy,fill)
1992 Imager::FillHandle fill
1995 i_flood_fill_border(im,seedx,seedy,dcol, border)
2000 Imager::Color border
2003 i_flood_cfill_border(im,seedx,seedy,fill, border)
2007 Imager::FillHandle fill
2008 Imager::Color border
2012 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
2024 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
2041 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
2052 i_compose(out, src, out_left, out_top, src_left, src_top, width, height, combine = ic_normal, opacity = 0.0)
2065 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)
2081 i_combine(src_av, channels_av = NULL)
2085 i_img **imgs = NULL;
2087 int *channels = NULL;
2092 in_count = av_len(src_av) + 1;
2094 imgs = mymalloc(sizeof(i_img*) * in_count);
2095 channels = mymalloc(sizeof(int) * in_count);
2096 for (i = 0; i < in_count; ++i) {
2097 psv = av_fetch(src_av, i, 0);
2098 if (!psv || !*psv || !sv_derived_from(*psv, "Imager::ImgRaw")) {
2101 croak("imgs must contain only images");
2103 tmp = SvIV((SV*)SvRV(*psv));
2104 imgs[i] = INT2PTR(i_img*, tmp);
2106 (psv = av_fetch(channels_av, i, 0)) != NULL &&
2108 channels[i] = SvIV(*psv);
2115 RETVAL = i_combine(imgs, channels, in_count);
2122 i_flipxy(im, direction)
2127 i_rotate90(im, degrees)
2132 i_rotate_exact(im, amount, ...)
2136 i_color *backp = NULL;
2137 i_fcolor *fbackp = NULL;
2141 /* extract the bg colors if any */
2142 /* yes, this is kind of strange */
2143 for (i = 2; i < items; ++i) {
2145 if (sv_derived_from(sv1, "Imager::Color")) {
2146 IV tmp = SvIV((SV*)SvRV(sv1));
2147 backp = INT2PTR(i_color *, tmp);
2149 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2150 IV tmp = SvIV((SV*)SvRV(sv1));
2151 fbackp = INT2PTR(i_fcolor *, tmp);
2154 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
2159 i_matrix_transform(im, xsize, ysize, matrix_av, ...)
2169 i_color *backp = NULL;
2170 i_fcolor *fbackp = NULL;
2172 len=av_len(matrix_av)+1;
2175 for (i = 0; i < len; ++i) {
2176 sv1=(*(av_fetch(matrix_av,i,0)));
2177 matrix[i] = SvNV(sv1);
2181 /* extract the bg colors if any */
2182 /* yes, this is kind of strange */
2183 for (i = 4; i < items; ++i) {
2185 if (sv_derived_from(sv1, "Imager::Color")) {
2186 IV tmp = SvIV((SV*)SvRV(sv1));
2187 backp = INT2PTR(i_color *, tmp);
2189 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
2190 IV tmp = SvIV((SV*)SvRV(sv1));
2191 fbackp = INT2PTR(i_fcolor *, tmp);
2194 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
2199 i_gaussian(im,stdev)
2204 i_unsharp_mask(im,stdev,scale)
2219 len = av_len(coef) + 1;
2220 c_coef=mymalloc( len * sizeof(double) );
2221 for(i = 0; i < len; i++) {
2222 sv1 = (*(av_fetch(coef, i, 0)));
2223 c_coef[i] = (double)SvNV(sv1);
2225 RETVAL = i_conv(im, c_coef, len);
2231 i_convert(src, avmain)
2243 outchan = av_len(avmain)+1;
2244 /* find the biggest */
2246 for (j=0; j < outchan; ++j) {
2247 temp = av_fetch(avmain, j, 0);
2248 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
2249 avsub = (AV*)SvRV(*temp);
2250 len = av_len(avsub)+1;
2255 i_push_errorf(0, "invalid matrix: element %d is not an array ref", j);
2259 coeff = mymalloc(sizeof(double) * outchan * inchan);
2260 for (j = 0; j < outchan; ++j) {
2261 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
2262 len = av_len(avsub)+1;
2263 for (i = 0; i < len; ++i) {
2264 temp = av_fetch(avsub, i, 0);
2266 coeff[i+j*inchan] = SvNV(*temp);
2268 coeff[i+j*inchan] = 0;
2271 coeff[i++ + j*inchan] = 0;
2273 RETVAL = i_convert(src, coeff, outchan, inchan);
2284 unsigned int mask = 0;
2289 unsigned char (*maps)[256];
2291 len = av_len(pmaps_av)+1;
2292 if (im->channels < len)
2294 maps = mymalloc( len * sizeof(unsigned char [256]) );
2295 for (j=0; j<len ; j++) {
2296 temp = av_fetch(pmaps_av, j, 0);
2297 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
2298 avsub = (AV*)SvRV(*temp);
2299 if(av_len(avsub) != 255)
2302 for (i=0; i<256 ; i++) {
2304 temp = av_fetch(avsub, i, 0);
2305 val = temp ? SvIV(*temp) : 0;
2307 if (val>255) val = 255;
2312 i_map(im, maps, mask);
2324 i_img_diffd(im1,im2)
2329 i_img_samef(im1, im2, epsilon = i_img_epsilonf(), what=NULL)
2339 _is_color_object(sv)
2343 RETVAL = SvOK(sv) && SvROK(sv) &&
2344 (sv_derived_from(sv, "Imager::Color")
2345 || sv_derived_from(sv, "Imager::Color::Float"));
2357 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
2359 #define TT_DESTROY(handle) i_tt_destroy(handle)
2363 Imager::Font::TT handle
2368 (void)items; /* avoid unused warning */
2374 MODULE = Imager PACKAGE = Imager
2378 i_tt_text(handle,im,xb,yb,cl,points,str_sv,smooth,utf8,align=1)
2379 Imager::Font::TT handle
2393 str = SvPV(str_sv, len);
2398 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
2399 len, smooth, utf8, align);
2405 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,smooth,utf8,align=1)
2406 Imager::Font::TT handle
2420 str = SvPV(str_sv, len);
2425 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
2426 smooth, utf8, align);
2432 i_tt_bbox(handle,point,str_sv,utf8)
2433 Imager::Font::TT handle
2438 i_img_dim cords[BOUNDING_BOX_COUNT];
2444 str = SvPV(str_sv, len);
2449 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
2451 for (i = 0; i < rc; ++i) {
2452 PUSHs(sv_2mortal(newSViv(cords[i])));
2457 i_tt_has_chars(handle, text_sv, utf8)
2458 Imager::Font::TT handle
2469 text = SvPV(text_sv, len);
2471 if (SvUTF8(text_sv))
2474 work = mymalloc(len);
2475 count = i_tt_has_chars(handle, text, len, utf8, work);
2476 if (GIMME_V == G_ARRAY) {
2478 for (i = 0; i < count; ++i) {
2479 PUSHs(boolSV(work[i]));
2484 PUSHs(sv_2mortal(newSVpv(work, count)));
2489 i_tt_dump_names(handle)
2490 Imager::Font::TT handle
2493 i_tt_face_name(handle)
2494 Imager::Font::TT handle
2499 len = i_tt_face_name(handle, name, sizeof(name));
2502 PUSHs(sv_2mortal(newSVpv(name, len-1)));
2506 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2507 Imager::Font::TT handle
2519 text = SvPV(text_sv, work_len);
2521 if (SvUTF8(text_sv))
2528 ch = i_utf8_advance(&text, &len);
2530 i_push_error(0, "invalid UTF8 character");
2538 EXTEND(SP, count+1);
2539 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2540 ST(count) = sv_2mortal(newSVpv(name, 0));
2543 ST(count) = &PL_sv_undef;
2552 i_test_format_probe(ig, length)
2557 i_readpnm_wiol(ig, allow_incomplete)
2559 int allow_incomplete
2563 i_readpnm_multi_wiol(ig, allow_incomplete)
2565 int allow_incomplete
2571 imgs = i_readpnm_multi_wiol(ig, &count, allow_incomplete);
2574 for (i = 0; i < count; ++i) {
2575 SV *sv = sv_newmortal();
2576 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2583 i_writeppm_wiol(im, ig)
2592 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2601 i_writeraw_wiol(im,ig)
2606 i_writebmp_wiol(im,ig)
2611 i_readbmp_wiol(ig, allow_incomplete=0)
2613 int allow_incomplete
2617 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2626 idlen = SvCUR(ST(4));
2627 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2633 i_readtga_wiol(ig, length)
2641 i_scaleaxis(im,Value,Axis)
2647 i_scale_nn(im,scx,scy)
2653 i_scale_mixing(im, width, height)
2663 i_count_colors(im,maxc)
2668 i_get_anonymous_color_histo(im, maxc = 0x40000000)
2673 unsigned int * col_usage = NULL;
2676 col_cnt = i_get_anonymous_color_histo(im, &col_usage, maxc);
2677 EXTEND(SP, col_cnt);
2678 for (i = 0; i < col_cnt; i++) {
2679 PUSHs(sv_2mortal(newSViv( col_usage[i])));
2686 i_transform(im, opx, opy, parm)
2692 STRLEN size_opx, size_opy, size_parm;
2695 result=i_transform(im,opx,size_opx,opy,size_opy,parm,size_parm);
2697 SV *result_sv = sv_newmortal();
2699 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2704 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2730 in_imgs_count = av_len(av_in_imgs)+1;
2731 for (i = 0; i < in_imgs_count; ++i) {
2732 sv1 = *av_fetch(av_in_imgs, i, 0);
2733 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2734 croak("sv_in_img must contain only images");
2737 if (in_imgs_count > 0) {
2738 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
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("Parameter 5 must contain only images");
2744 tmp = SvIV((SV*)SvRV(sv1));
2745 in_imgs[i] = INT2PTR(i_img*, tmp);
2749 /* no input images */
2752 /* default the output size from the first input if possible */
2754 width = SvIV(sv_width);
2755 else if (in_imgs_count)
2756 width = in_imgs[0]->xsize;
2758 croak("No output image width supplied");
2760 if (SvOK(sv_height))
2761 height = SvIV(sv_height);
2762 else if (in_imgs_count)
2763 height = in_imgs[0]->ysize;
2765 croak("No output image height supplied");
2767 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2768 if (ops_len % sizeof(struct rm_op))
2769 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2770 ops_count = ops_len / sizeof(struct rm_op);
2772 n_regs_count = av_len(av_n_regs)+1;
2773 n_regs = mymalloc(n_regs_count * sizeof(double));
2774 for (i = 0; i < n_regs_count; ++i) {
2775 sv1 = *av_fetch(av_n_regs,i,0);
2777 n_regs[i] = SvNV(sv1);
2779 c_regs_count = av_len(av_c_regs)+1;
2780 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2781 /* I don't bother initializing the colou?r registers */
2783 result=i_transform2(width, height, channels, ops, ops_count,
2784 n_regs, n_regs_count,
2785 c_regs, c_regs_count, in_imgs, in_imgs_count);
2791 SV *result_sv = sv_newmortal();
2793 sv_setref_pv(result_sv, "Imager::ImgRaw", (void*)result);
2799 i_contrast(im,intensity)
2812 i_noise(im,amount,type)
2818 i_bumpmap(im,bump,channel,light_x,light_y,strength)
2828 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2847 i_postlevels(im,levels)
2857 i_watermark(im,wmark,tx,ty,pixdiff)
2859 Imager::ImgRaw wmark
2866 i_autolevels(im,lsat,usat,skew)
2873 i_autolevels_mono(im,lsat,usat)
2879 i_radnoise(im,xo,yo,rscale,ascale)
2887 i_turbnoise(im, xo, yo, scale)
2895 i_gradgen(im, xo, yo, ac, dmeasure)
2906 if (size_xo != size_yo || size_xo != size_ac)
2907 croak("i_gradgen: x, y and color arrays must be the same size");
2909 croak("Usage: i_gradgen array refs must have more than 1 entry each");
2910 i_gradgen(im, size_xo, xo, yo, ac, dmeasure);
2913 i_diff_image(im, im2, mindist=0)
2919 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2929 double ssample_param
2933 i_fountain_seg *segs;
2935 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2936 croak("i_fountain: argument 11 must be an array ref");
2938 asegs = (AV *)SvRV(ST(10));
2939 segs = load_fount_segs(aTHX_ asegs, &count);
2940 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
2941 super_sample, ssample_param, count, segs);
2947 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2956 double ssample_param
2960 i_fountain_seg *segs;
2962 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2963 croak("i_fountain: argument 11 must be an array ref");
2965 asegs = (AV *)SvRV(ST(9));
2966 segs = load_fount_segs(aTHX_ asegs, &count);
2967 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2968 super_sample, ssample_param, count, segs);
2974 i_new_fill_opacity(other_fill, alpha_mult)
2975 Imager::FillHandle other_fill
2986 errors = i_errors();
2988 while (errors[i].msg) {
2990 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2991 if (!av_store(av, 0, sv)) {
2994 sv = newSViv(errors[i].code);
2995 if (!av_store(av, 1, sv)) {
2998 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3006 i_push_error(code, msg)
3011 i_nearest_color(im, ...)
3026 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3027 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3028 croak("i_nearest_color: Second argument must be an array ref");
3029 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3030 croak("i_nearest_color: Third argument must be an array ref");
3031 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3032 croak("i_nearest_color: Fourth argument must be an array ref");
3033 axx = (AV *)SvRV(ST(1));
3034 ayy = (AV *)SvRV(ST(2));
3035 ac = (AV *)SvRV(ST(3));
3036 dmeasure = (int)SvIV(ST(4));
3038 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3039 num = num <= av_len(ac) ? num : av_len(ac);
3041 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3042 xo = mymalloc( sizeof(i_img_dim) * num );
3043 yo = mymalloc( sizeof(i_img_dim) * num );
3044 ival = mymalloc( sizeof(i_color) * num );
3045 for(i = 0; i<num; i++) {
3046 xo[i] = (i_img_dim)SvIV(* av_fetch(axx, i, 0));
3047 yo[i] = (i_img_dim)SvIV(* av_fetch(ayy, i, 0));
3048 sv = *av_fetch(ac, i, 0);
3049 if ( !sv_derived_from(sv, "Imager::Color") ) {
3050 free(axx); free(ayy); free(ac);
3051 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3053 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3055 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3069 rc=DSO_open(filename,&evstr);
3073 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3074 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3077 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3083 DSO_close(dso_handle)
3087 DSO_funclist(dso_handle_v)
3091 DSO_handle *dso_handle;
3092 func_ptr *functions;
3094 dso_handle=(DSO_handle*)dso_handle_v;
3095 functions = DSO_funclist(dso_handle);
3097 while( functions[i].name != NULL) {
3099 PUSHs(sv_2mortal(newSVpv(functions[i].name,0)));
3101 PUSHs(sv_2mortal(newSVpv(functions[i++].pcode,0)));
3105 DSO_call(handle,func_index,hv)
3110 DSO_call( (DSO_handle *)handle,func_index,hv);
3113 i_get_pixel(im, x, y)
3118 RETVAL = (i_color *)mymalloc(sizeof(i_color));
3119 memset(RETVAL, 0, sizeof(*RETVAL));
3120 if (i_gpix(im, x, y, RETVAL) != 0) {
3129 i_ppix(im, x, y, cl)
3136 i_img_pal_new(x, y, channels, maxpal)
3143 i_img_to_pal(src, quant)
3149 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3150 croak("i_img_to_pal: second argument must be a hash ref");
3151 hv = (HV *)SvRV(ST(1));
3152 memset(&quant, 0, sizeof(quant));
3154 quant.mc_size = 256;
3155 ip_handle_quant_opts(aTHX_ &quant, hv);
3156 RETVAL = i_img_to_pal(src, &quant);
3158 ip_copy_colors_back(aTHX_ hv, &quant);
3160 ip_cleanup_quant_opts(aTHX_ &quant);
3169 i_img_make_palette(HV *quant_hv, ...)
3171 size_t count = items - 1;
3173 i_img **imgs = NULL;
3177 croak("Please supply at least one image (%d)", (int)count);
3178 imgs = mymalloc(sizeof(i_img *) * count);
3179 for (i = 0; i < count; ++i) {
3180 SV *img_sv = ST(i + 1);
3181 if (SvROK(img_sv) && sv_derived_from(img_sv, "Imager::ImgRaw")) {
3182 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(img_sv)));
3186 croak("Image %d is not an image object", (int)i+1);
3189 memset(&quant, 0, sizeof(quant));
3191 quant.mc_size = 256;
3192 ip_handle_quant_opts(aTHX_ &quant, quant_hv);
3193 i_quant_makemap(&quant, imgs, count);
3194 EXTEND(SP, quant.mc_count);
3195 for (i = 0; i < quant.mc_count; ++i) {
3196 SV *sv_c = make_i_color_sv(aTHX_ quant.mc_colors + i);
3199 ip_cleanup_quant_opts(aTHX_ &quant);
3213 work = mymalloc((r-l) * sizeof(i_palidx));
3214 count = i_gpal(im, l, r, y, work);
3215 if (GIMME_V == G_ARRAY) {
3217 for (i = 0; i < count; ++i) {
3218 PUSHs(sv_2mortal(newSViv(work[i])));
3223 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3228 if (GIMME_V != G_ARRAY) {
3230 PUSHs(&PL_sv_undef);
3235 i_ppal(im, l, y, ...)
3244 work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
3245 for (i=0; i < items-3; ++i) {
3246 work[i] = SvIV(ST(i+3));
3248 validate_i_ppal(im, work, items - 3);
3249 RETVAL = i_ppal(im, l, l+items-3, y, work);
3258 i_ppal_p(im, l, y, data)
3264 i_palidx const *work;
3267 work = (i_palidx const *)SvPV(data, len);
3268 len /= sizeof(i_palidx);
3270 validate_i_ppal(im, work, len);
3271 RETVAL = i_ppal(im, l, l+len, y, work);
3280 i_addcolors(im, ...)
3287 croak("i_addcolors: no colors to add");
3288 colors = mymalloc((items-1) * sizeof(i_color));
3289 for (i=0; i < items-1; ++i) {
3290 if (sv_isobject(ST(i+1))
3291 && sv_derived_from(ST(i+1), "Imager::Color")) {
3292 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3293 colors[i] = *INT2PTR(i_color *, tmp);
3297 croak("i_addcolor: pixels must be Imager::Color objects");
3300 RETVAL = i_addcolors(im, colors, items-1);
3305 i_setcolors(im, index, ...)
3313 croak("i_setcolors: no colors to add");
3314 colors = mymalloc((items-2) * sizeof(i_color));
3315 for (i=0; i < items-2; ++i) {
3316 if (sv_isobject(ST(i+2))
3317 && sv_derived_from(ST(i+2), "Imager::Color")) {
3318 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3319 colors[i] = *INT2PTR(i_color *, tmp);
3323 croak("i_setcolors: pixels must be Imager::Color objects");
3326 RETVAL = i_setcolors(im, index, colors, items-2);
3332 i_getcolors(im, index, count=1)
3341 croak("i_getcolors: count must be positive");
3342 colors = malloc_temp(aTHX_ sizeof(i_color) * count);
3343 if (i_getcolors(im, index, colors, count)) {
3345 for (i = 0; i < count; ++i) {
3346 SV *sv = make_i_color_sv(aTHX_ colors+i);
3360 i_findcolor(im, color)
3364 if (!i_findcolor(im, color, &RETVAL)) {
3383 i_gsamp(im, l, r, y, channels)
3388 i_channel_list channels
3394 data = mymalloc(sizeof(i_sample_t) * (r-l) * channels.count);
3395 count = i_gsamp(im, l, r, y, data, channels.channels, channels.count);
3396 if (GIMME_V == G_ARRAY) {
3398 for (i = 0; i < count; ++i)
3399 PUSHs(sv_2mortal(newSViv(data[i])));
3403 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3408 if (GIMME_V != G_ARRAY) {
3414 i_gsamp_bits(im, l, r, y, bits, target, offset, channels)
3422 i_channel_list channels
3429 croak("No channel numbers supplied to g_samp()");
3431 data = mymalloc(sizeof(unsigned) * (r-l) * channels.count);
3432 count = i_gsamp_bits(im, l, r, y, data, channels.channels, channels.count, bits);
3433 for (i = 0; i < count; ++i) {
3434 av_store(target, i+offset, newSVuv(data[i]));
3446 i_psamp_bits(im, l, y, bits, channels, data_av, data_offset = 0, pixel_count = -1)
3451 i_channel_list channels
3453 i_img_dim data_offset
3454 i_img_dim pixel_count
3463 data_count = av_len(data_av) + 1;
3464 if (data_offset < 0) {
3465 croak("data_offset must be non-negative");
3467 if (data_offset > data_count) {
3468 croak("data_offset greater than number of samples supplied");
3470 if (pixel_count == -1 ||
3471 data_offset + pixel_count * channels.count > data_count) {
3472 pixel_count = (data_count - data_offset) / channels.count;
3475 data_used = pixel_count * channels.count;
3476 data = mymalloc(sizeof(unsigned) * data_count);
3477 for (i = 0; i < data_used; ++i)
3478 data[i] = SvUV(*av_fetch(data_av, data_offset + i, 0));
3480 RETVAL = i_psamp_bits(im, l, l + pixel_count, y, data, channels.channels,
3481 channels.count, bits);
3489 i_psamp(im, x, y, channels, data, offset = 0, width = -1)
3493 i_channel_list channels
3502 i_push_error(0, "offset must be non-negative");
3506 if (offset > data.count) {
3507 i_push_error(0, "offset greater than number of samples supplied");
3510 data.samples += offset;
3511 data.count -= offset;
3514 width * channels.count > data.count) {
3515 width = data.count / channels.count;
3518 RETVAL = i_psamp(im, x, r, y, data.samples, channels.channels, channels.count);
3523 i_psampf(im, x, y, channels, data, offset = 0, width = -1)
3527 i_channel_list channels
3536 i_push_error(0, "offset must be non-negative");
3540 if (offset > data.count) {
3541 i_push_error(0, "offset greater than number of samples supplied");
3544 data.samples += offset;
3545 data.count -= offset;
3548 width * channels.count > data.count) {
3549 width = data.count / channels.count;
3552 RETVAL = i_psampf(im, x, r, y, data.samples, channels.channels, channels.count);
3557 i_img_masked_new(targ, mask, x, y, w, h)
3567 if (!sv_isobject(ST(1))
3568 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3569 croak("i_img_masked_new: parameter 2 must undef or an image");
3571 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3575 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3580 i_plin(im, l, y, ...)
3591 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3592 /* supplied as a byte string */
3593 work = (i_color *)SvPV(ST(3), len);
3594 count = len / sizeof(i_color);
3595 if (count * sizeof(i_color) != len) {
3596 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3598 RETVAL = i_plin(im, l, l+count, y, work);
3601 work = mymalloc(sizeof(i_color) * (items-3));
3602 for (i=0; i < items-3; ++i) {
3603 if (sv_isobject(ST(i+3))
3604 && sv_derived_from(ST(i+3), "Imager::Color")) {
3605 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3606 work[i] = *INT2PTR(i_color *, tmp);
3610 croak("i_plin: pixels must be Imager::Color objects");
3613 RETVAL = i_plin(im, l, l+items-3, y, work);
3624 i_ppixf(im, x, y, cl)
3628 Imager::Color::Float cl
3631 i_gsampf(im, l, r, y, channels)
3636 i_channel_list channels
3642 data = mymalloc(sizeof(i_fsample_t) * (r-l) * channels.count);
3643 count = i_gsampf(im, l, r, y, data, channels.channels, channels.count);
3644 if (GIMME_V == G_ARRAY) {
3646 for (i = 0; i < count; ++i)
3647 PUSHs(sv_2mortal(newSVnv(data[i])));
3651 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3656 if (GIMME_V != G_ARRAY) {
3662 i_plinf(im, l, y, ...)
3673 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3674 /* supplied as a byte string */
3675 work = (i_fcolor *)SvPV(ST(3), len);
3676 count = len / sizeof(i_fcolor);
3677 if (count * sizeof(i_fcolor) != len) {
3678 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3680 RETVAL = i_plinf(im, l, l+count, y, work);
3683 work = mymalloc(sizeof(i_fcolor) * (items-3));
3684 for (i=0; i < items-3; ++i) {
3685 if (sv_isobject(ST(i+3))
3686 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3687 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3688 work[i] = *INT2PTR(i_fcolor *, tmp);
3692 croak("i_plinf: pixels must be Imager::Color::Float objects");
3696 RETVAL = i_plinf(im, l, l+items-3, y, work);
3706 Imager::Color::Float
3712 RETVAL = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3713 memset(RETVAL, 0, sizeof(*RETVAL));
3714 if (i_gpixf(im, x, y, RETVAL) != 0) {
3732 vals = mymalloc((r-l) * sizeof(i_color));
3733 memset(vals, 0, (r-l) * sizeof(i_color));
3734 count = i_glin(im, l, r, y, vals);
3735 if (GIMME_V == G_ARRAY) {
3737 for (i = 0; i < count; ++i) {
3738 SV *sv = make_i_color_sv(aTHX_ vals+i);
3744 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3750 i_glinf(im, l, r, y)
3760 for (i = 0; i < MAXCHANNELS; ++i)
3761 zero.channel[i] = 0;
3763 vals = mymalloc((r-l) * sizeof(i_fcolor));
3764 for (i = 0; i < r-l; ++i)
3766 count = i_glinf(im, l, r, y, vals);
3767 if (GIMME_V == G_ARRAY) {
3769 for (i = 0; i < count; ++i) {
3771 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3773 sv = sv_newmortal();
3774 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3780 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3786 i_img_8_new(x, y, ch)
3792 i_img_16_new(x, y, ch)
3802 i_img_double_new(x, y, ch)
3812 i_tags_addn(im, name_sv, code, idata)
3821 SvGETMAGIC(name_sv);
3823 name = SvPV_nomg(name_sv, len);
3826 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3831 i_tags_add(im, name_sv, code, data_sv, idata)
3842 SvGETMAGIC(name_sv);
3844 name = SvPV_nomg(name_sv, len);
3847 SvGETMAGIC(data_sv);
3849 data = SvPV(data_sv, len);
3854 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3859 i_tags_find(im, name, start)
3866 if (i_tags_find(&im->tags, name, start, &entry)) {
3875 i_tags_findn(im, code, start)
3882 if (i_tags_findn(&im->tags, code, start, &entry)) {
3892 i_tags_delete(im, entry)
3896 RETVAL = i_tags_delete(&im->tags, entry);
3901 i_tags_delbyname(im, name)
3905 RETVAL = i_tags_delbyname(&im->tags, name);
3910 i_tags_delbycode(im, code)
3914 RETVAL = i_tags_delbycode(&im->tags, code);
3919 i_tags_get(im, index)
3923 if (index >= 0 && index < im->tags.count) {
3924 i_img_tag *entry = im->tags.tags + index;
3928 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3931 PUSHs(sv_2mortal(newSViv(entry->code)));
3934 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3937 PUSHs(sv_2mortal(newSViv(entry->idata)));
3942 i_tags_get_string(im, what_sv)
3946 char const *name = NULL;
3950 if (SvIOK(what_sv)) {
3951 code = SvIV(what_sv);
3955 name = SvPV_nolen(what_sv);
3958 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
3960 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
3967 RETVAL = im->tags.count;
3973 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3977 Imager::FillHandle fill
3980 IFILL_CLONE_SKIP(...)
3982 (void)items; /* avoid unused warning for XS variable */
3987 MODULE = Imager PACKAGE = Imager
3990 i_new_fill_solid(cl, combine)
3995 i_new_fill_solidf(cl, combine)
3996 Imager::Color::Float cl
4000 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
4009 unsigned char *cust_hatch;
4012 SvGETMAGIC(cust_hatch_sv);
4013 if (SvOK(cust_hatch_sv)) {
4014 cust_hatch = (unsigned char *)SvPV_nomg(cust_hatch_sv, len);
4018 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4023 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch_sv, dx, dy)
4024 Imager::Color::Float fg
4025 Imager::Color::Float bg
4032 unsigned char *cust_hatch;
4035 SvGETMAGIC(cust_hatch_sv);
4036 if (SvOK(cust_hatch_sv)) {
4037 cust_hatch = (unsigned char *)SvPV(cust_hatch_sv, len);
4041 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4046 i_new_fill_image(src, matrix_sv, xoff, yoff, combine)
4060 SvGETMAGIC(matrix_sv);
4061 if (!SvOK(matrix_sv)) {
4065 if (!SvROK(matrix_sv) || SvTYPE(SvRV(matrix_sv)) != SVt_PVAV)
4066 croak("i_new_fill_image: matrix parameter must be an arrayref or undef");
4067 av=(AV*)SvRV(matrix_sv);
4071 for (i = 0; i < len; ++i) {
4072 sv1=(*(av_fetch(av,i,0)));
4073 matrix[i] = SvNV(sv1);
4079 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4083 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4085 # this class is only exposed for testing
4088 i_int_hlines_testing()
4090 #if i_int_hlines_testing()
4092 Imager::Internal::Hlines
4093 i_int_hlines_new(start_y, count_y, start_x, count_x)
4099 Imager::Internal::Hlines
4100 i_int_hlines_new_img(im)
4104 i_int_hlines_add(hlines, y, minx, width)
4105 Imager::Internal::Hlines hlines
4111 i_int_hlines_DESTROY(hlines)
4112 Imager::Internal::Hlines hlines
4115 i_int_hlines_dump(hlines)
4116 Imager::Internal::Hlines hlines
4119 i_int_hlines_CLONE_SKIP(cls)
4123 MODULE = Imager PACKAGE = Imager::Context PREFIX=im_context_
4126 im_context_DESTROY(ctx)
4129 #ifdef PERL_IMPLICIT_CONTEXT
4132 im_context_CLONE(...)
4136 /* the following sv_setref_pv() will free this inc */
4137 im_context_refinc(MY_CXT.ctx, "CLONE");
4138 MY_CXT.ctx = im_context_clone(MY_CXT.ctx, "CLONE");
4139 sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
4144 PERL_SET_GLOBAL_CALLBACKS;
4145 PERL_PL_SET_GLOBAL_CALLBACKS;
4146 #ifdef PERL_IMPLICIT_CONTEXT
4152 start_context(aTHX);
4153 im_get_context = perl_get_context;