12 #define i_int_hlines_testing() 1
19 #if i_int_hlines_testing()
23 typedef io_glue* Imager__IO;
24 typedef i_color* Imager__Color;
25 typedef i_fcolor* Imager__Color__Float;
26 typedef i_img* Imager__ImgRaw;
27 typedef int undef_neg_int;
30 typedef TT_Fonthandle* Imager__Font__TT;
34 typedef FT2_Fonthandle* Imager__Font__FT2;
37 /* These functions are all shared - then comes platform dependant code */
38 static int getstr(void *hv_t,char *key,char **store) {
42 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
44 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
46 svpp=hv_fetch(hv, key, strlen(key), 0);
47 *store=SvPV(*svpp, PL_na );
52 static int getint(void *hv_t,char *key,int *store) {
56 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
58 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
60 svpp=hv_fetch(hv, key, strlen(key), 0);
61 *store=(int)SvIV(*svpp);
65 static int getdouble(void *hv_t,char* key,double *store) {
69 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
71 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
72 svpp=hv_fetch(hv, key, strlen(key), 0);
73 *store=(float)SvNV(*svpp);
77 static int getvoid(void *hv_t,char* key,void **store) {
81 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
83 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
85 svpp=hv_fetch(hv, key, strlen(key), 0);
86 *store = INT2PTR(void*, SvIV(*svpp));
91 static int getobj(void *hv_t,char *key,char *type,void **store) {
95 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
97 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
99 svpp=hv_fetch(hv, key, strlen(key), 0);
101 if (sv_derived_from(*svpp,type)) {
102 IV tmp = SvIV((SV*)SvRV(*svpp));
103 *store = INT2PTR(void*, tmp);
105 mm_log((1,"getobj: key exists in hash but is not of correct type"));
112 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
114 void my_SvREFCNT_dec(void *p) {
115 SvREFCNT_dec((SV*)p);
120 log_entry(char *string, int level) {
121 mm_log((level, string));
125 typedef struct i_reader_data_tag
127 /* presumably a CODE ref or name of a sub */
131 /* used by functions that want callbacks */
132 static int read_callback(char *userdata, char *buffer, int need, int want) {
133 i_reader_data *rd = (i_reader_data *)userdata;
137 dSP; dTARG = sv_newmortal();
138 /* thanks to Simon Cozens for help with the dTARG above */
148 count = perl_call_sv(rd->sv, G_SCALAR);
153 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
159 char *ptr = SvPV(data, len);
161 croak("Too much data returned in reader callback");
163 memcpy(buffer, ptr, len);
179 SV *sv; /* a coderef or sub name */
182 /* used by functions that want callbacks */
183 static int write_callback(char *userdata, char const *data, int size) {
184 i_writer_data *wd = (i_writer_data *)userdata;
194 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
197 count = perl_call_sv(wd->sv, G_SCALAR);
202 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
205 success = SvTRUE(sv);
215 #define CBDATA_BUFSIZE 8192
218 /* the SVs we use to call back to Perl */
224 /* we need to remember whether the buffer contains write data or
230 /* how far we've read into the buffer (not used for writing) */
233 /* the amount of space used/data available in the buffer */
236 /* the maximum amount to fill the buffer before flushing
237 If any write is larger than this then the buffer is flushed and
238 the full write is performed. The write is _not_ split into
243 char buffer[CBDATA_BUFSIZE];
248 call_writer(cbd, buf, size)
250 Low-level function to call the perl writer callback.
254 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
260 if (!SvOK(cbd->writecb))
267 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
270 count = perl_call_sv(cbd->writecb, G_SCALAR);
274 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
277 success = SvTRUE(sv);
284 return success ? size : 0;
287 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
294 if (!SvOK(cbd->readcb))
301 PUSHs(sv_2mortal(newSViv(size)));
302 PUSHs(sv_2mortal(newSViv(maxread)));
305 count = perl_call_sv(cbd->readcb, G_SCALAR);
310 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
316 char *ptr = SvPV(data, len);
318 croak("Too much data returned in reader callback");
320 memcpy(buf, ptr, len);
334 static ssize_t write_flush(struct cbdata *cbd) {
337 result = call_writer(cbd, cbd->buffer, cbd->used);
342 static off_t io_seeker(void *p, off_t offset, int whence) {
343 struct cbdata *cbd = p;
348 if (!SvOK(cbd->seekcb))
352 if (cbd->used && write_flush(cbd) <= 0)
356 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
357 offset -= cbd->where - cbd->used;
360 cbd->where = cbd->used = 0;
366 PUSHs(sv_2mortal(newSViv(offset)));
367 PUSHs(sv_2mortal(newSViv(whence)));
370 count = perl_call_sv(cbd->seekcb, G_SCALAR);
375 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
386 static ssize_t io_writer(void *p, void const *data, size_t size) {
387 struct cbdata *cbd = p;
389 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
391 if (cbd->reading && cbd->where < cbd->used) {
392 /* we read past the place where the caller expected us to be
393 so adjust our position a bit */
395 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
400 cbd->where = cbd->used = 0;
403 if (cbd->used && cbd->used + size > cbd->maxlength) {
404 if (write_flush(cbd) <= 0) {
409 if (cbd->used+size <= cbd->maxlength) {
410 memcpy(cbd->buffer + cbd->used, data, size);
414 /* it doesn't fit - just pass it up */
415 return call_writer(cbd, data, size);
418 static ssize_t io_reader(void *p, void *data, size_t size) {
419 struct cbdata *cbd = p;
421 char *out = data; /* so we can do pointer arithmetic */
424 if (write_flush(cbd) <= 0)
430 if (size <= cbd->used - cbd->where) {
432 memcpy(data, cbd->buffer+cbd->where, size);
437 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
438 total += cbd->used - cbd->where;
439 size -= cbd->used - cbd->where;
440 out += cbd->used - cbd->where;
441 if (size < sizeof(cbd->buffer)) {
445 && (did_read = call_reader(cbd, cbd->buffer, size,
446 sizeof(cbd->buffer))) > 0) {
448 cbd->used = did_read;
450 copy_size = i_min(size, cbd->used);
451 memcpy(out, cbd->buffer, copy_size);
452 cbd->where += copy_size;
459 /* just read the rest - too big for our buffer*/
461 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
471 static void io_closer(void *p) {
472 struct cbdata *cbd = p;
474 if (cbd->writing && cbd->used > 0) {
479 if (SvOK(cbd->closecb)) {
487 perl_call_sv(cbd->closecb, G_VOID);
496 static void io_destroyer(void *p) {
497 struct cbdata *cbd = p;
499 SvREFCNT_dec(cbd->writecb);
500 SvREFCNT_dec(cbd->readcb);
501 SvREFCNT_dec(cbd->seekcb);
502 SvREFCNT_dec(cbd->closecb);
510 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
513 for (i = 0; i < count; ++i)
514 if (strEQ(names[i].name, name))
515 return names[i].value;
519 static struct value_name transp_names[] =
522 { "threshold", tr_threshold },
523 { "errdiff", tr_errdiff },
524 { "ordered", tr_ordered, },
527 static struct value_name make_color_names[] =
529 { "none", mc_none, },
530 { "webmap", mc_web_map, },
531 { "addi", mc_addi, },
532 { "mediancut", mc_median_cut, },
535 static struct value_name translate_names[] =
538 { "giflib", pt_giflib, },
540 { "closest", pt_closest, },
541 { "perturb", pt_perturb, },
542 { "errdiff", pt_errdiff, },
545 static struct value_name errdiff_names[] =
547 { "floyd", ed_floyd, },
548 { "jarvis", ed_jarvis, },
549 { "stucki", ed_stucki, },
550 { "custom", ed_custom, },
553 static struct value_name orddith_names[] =
555 { "random", od_random, },
556 { "dot8", od_dot8, },
557 { "dot4", od_dot4, },
558 { "hline", od_hline, },
559 { "vline", od_vline, },
560 { "/line", od_slashline, },
561 { "slashline", od_slashline, },
562 { "\\line", od_backline, },
563 { "backline", od_backline, },
564 { "tiny", od_tiny, },
565 { "custom", od_custom, },
568 /* look through the hash for quantization options */
569 static void handle_quant_opts(i_quantize *quant, HV *hv)
571 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
577 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
579 sv = hv_fetch(hv, "transp", 6, 0);
580 if (sv && *sv && (str = SvPV(*sv, len))) {
582 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
584 if (quant->transp != tr_none) {
585 quant->tr_threshold = 127;
586 sv = hv_fetch(hv, "tr_threshold", 12, 0);
588 quant->tr_threshold = SvIV(*sv);
590 if (quant->transp == tr_errdiff) {
591 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
592 if (sv && *sv && (str = SvPV(*sv, len)))
593 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
595 if (quant->transp == tr_ordered) {
596 quant->tr_orddith = od_tiny;
597 sv = hv_fetch(hv, "tr_orddith", 10, 0);
598 if (sv && *sv && (str = SvPV(*sv, len)))
599 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
601 if (quant->tr_orddith == od_custom) {
602 sv = hv_fetch(hv, "tr_map", 6, 0);
603 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
604 AV *av = (AV*)SvRV(*sv);
605 len = av_len(av) + 1;
606 if (len > sizeof(quant->tr_custom))
607 len = sizeof(quant->tr_custom);
608 for (i = 0; i < len; ++i) {
609 SV **sv2 = av_fetch(av, i, 0);
611 quant->tr_custom[i] = SvIV(*sv2);
614 while (i < sizeof(quant->tr_custom))
615 quant->tr_custom[i++] = 0;
620 quant->make_colors = mc_addi;
621 sv = hv_fetch(hv, "make_colors", 11, 0);
622 if (sv && *sv && (str = SvPV(*sv, len))) {
624 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
626 sv = hv_fetch(hv, "colors", 6, 0);
627 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
628 /* needs to be an array of Imager::Color
629 note that the caller allocates the mc_color array and sets mc_size
631 AV *av = (AV *)SvRV(*sv);
632 quant->mc_count = av_len(av)+1;
633 if (quant->mc_count > quant->mc_size)
634 quant->mc_count = quant->mc_size;
635 for (i = 0; i < quant->mc_count; ++i) {
636 SV **sv1 = av_fetch(av, i, 0);
637 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
638 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
639 quant->mc_colors[i] = *col;
643 sv = hv_fetch(hv, "max_colors", 10, 0);
646 if (i <= quant->mc_size && i >= quant->mc_count)
650 quant->translate = pt_closest;
651 sv = hv_fetch(hv, "translate", 9, 0);
652 if (sv && *sv && (str = SvPV(*sv, len))) {
653 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
655 sv = hv_fetch(hv, "errdiff", 7, 0);
656 if (sv && *sv && (str = SvPV(*sv, len))) {
657 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
659 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
660 /* get the error diffusion map */
661 sv = hv_fetch(hv, "errdiff_width", 13, 0);
663 quant->ed_width = SvIV(*sv);
664 sv = hv_fetch(hv, "errdiff_height", 14, 0);
666 quant->ed_height = SvIV(*sv);
667 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
669 quant->ed_orig = SvIV(*sv);
670 if (quant->ed_width > 0 && quant->ed_height > 0) {
672 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
673 sv = hv_fetch(hv, "errdiff_map", 11, 0);
674 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
675 AV *av = (AV*)SvRV(*sv);
676 len = av_len(av) + 1;
677 if (len > quant->ed_width * quant->ed_height)
678 len = quant->ed_width * quant->ed_height;
679 for (i = 0; i < len; ++i) {
680 SV **sv2 = av_fetch(av, i, 0);
682 quant->ed_map[i] = SvIV(*sv2);
683 sum += quant->ed_map[i];
689 myfree(quant->ed_map);
691 quant->errdiff = ed_floyd;
695 sv = hv_fetch(hv, "perturb", 7, 0);
697 quant->perturb = SvIV(*sv);
700 static void cleanup_quant_opts(i_quantize *quant) {
701 myfree(quant->mc_colors);
703 myfree(quant->ed_map);
706 /* copies the color map from the hv into the colors member of the HV */
707 static void copy_colors_back(HV *hv, i_quantize *quant) {
713 sv = hv_fetch(hv, "colors", 6, 0);
714 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
717 ref = newRV_inc((SV*) av);
718 sv = hv_store(hv, "colors", 6, ref, 0);
721 av = (AV *)SvRV(*sv);
723 av_extend(av, quant->mc_count+1);
724 for (i = 0; i < quant->mc_count; ++i) {
725 i_color *in = quant->mc_colors+i;
726 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
727 work = sv_newmortal();
728 sv_setref_pv(work, "Imager::Color", (void *)c);
730 if (!av_store(av, i, work)) {
736 /* loads the segments of a fountain fill into an array */
737 static i_fountain_seg *
738 load_fount_segs(AV *asegs, int *count) {
739 /* Each element of segs must contain:
740 [ start, middle, end, c0, c1, segtype, colortrans ]
741 start, middle, end are doubles from 0 to 1
742 c0, c1 are Imager::Color::Float or Imager::Color objects
743 segtype, colortrans are ints
747 i_fountain_seg *segs;
751 *count = av_len(asegs)+1;
753 croak("i_fountain must have at least one segment");
754 segs = mymalloc(sizeof(i_fountain_seg) * *count);
755 for(i = 0; i < *count; i++) {
756 SV **sv1 = av_fetch(asegs, i, 0);
757 if (!sv1 || !*sv1 || !SvROK(*sv1)
758 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
760 croak("i_fountain: segs must be an arrayref of arrayrefs");
762 aseg = (AV *)SvRV(*sv1);
763 if (av_len(aseg) != 7-1) {
765 croak("i_fountain: a segment must have 7 members");
767 for (j = 0; j < 3; ++j) {
768 SV **sv2 = av_fetch(aseg, j, 0);
771 croak("i_fountain: XS error");
773 work[j] = SvNV(*sv2);
775 segs[i].start = work[0];
776 segs[i].middle = work[1];
777 segs[i].end = work[2];
778 for (j = 0; j < 2; ++j) {
779 SV **sv3 = av_fetch(aseg, 3+j, 0);
780 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
781 (!sv_derived_from(*sv3, "Imager::Color")
782 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
784 croak("i_fountain: segs must contain colors in elements 3 and 4");
786 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
787 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
790 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
792 for (ch = 0; ch < MAXCHANNELS; ++ch) {
793 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
797 for (j = 0; j < 2; ++j) {
798 SV **sv2 = av_fetch(aseg, j+5, 0);
801 croak("i_fountain: XS error");
803 worki[j] = SvIV(*sv2);
805 segs[i].type = worki[0];
806 segs[i].color = worki[1];
812 /* I don't think ICLF_* names belong at the C interface
813 this makes the XS code think we have them, to let us avoid
814 putting function bodies in the XS code
816 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
817 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
819 /* for the fill objects
820 Since a fill object may later have dependent images, (or fills!)
821 we need perl wrappers - oh well
823 #define IFILL_DESTROY(fill) i_fill_destroy(fill);
824 typedef i_fill_t* Imager__FillHandle;
826 /* the m_init_log() function was called init_log(), renamed to reduce
827 potential naming conflicts */
828 #define init_log m_init_log
830 #if i_int_hlines_testing()
832 typedef i_int_hlines *Imager__Internal__Hlines;
834 static i_int_hlines *
835 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
836 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
837 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
842 static i_int_hlines *
843 i_int_hlines_new_img(i_img *im) {
844 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
845 i_int_init_hlines_img(result, im);
851 i_int_hlines_DESTROY(i_int_hlines *hlines) {
852 i_int_hlines_destroy(hlines);
856 static int seg_compare(const void *vleft, const void *vright) {
857 const i_int_hline_seg *left = vleft;
858 const i_int_hline_seg *right = vright;
860 return left->minx - right->minx;
864 i_int_hlines_dump(i_int_hlines *hlines) {
865 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
866 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
869 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
870 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
873 /* sort the segments, if any */
875 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
877 sv_catpvf(dump, " %d (%d):", y, entry->count);
878 for (i = 0; i < entry->count; ++i) {
879 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
880 entry->segs[i].x_limit);
882 sv_catpv(dump, "\n");
891 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
894 ICL_new_internal(r,g,b,a)
906 ICL_set_internal(cl,r,g,b,a)
913 ICL_set_internal(cl, r, g, b, a);
927 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
928 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
929 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
930 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
936 RETVAL = mymalloc(sizeof(i_color));
938 i_hsv_to_rgb(RETVAL);
946 RETVAL = mymalloc(sizeof(i_color));
948 i_rgb_to_hsv(RETVAL);
954 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
957 ICLF_new_internal(r, g, b, a)
965 Imager::Color::Float cl
969 Imager::Color::Float cl
973 EXTEND(SP, MAXCHANNELS);
974 for (ch = 0; ch < MAXCHANNELS; ++ch) {
975 /* printf("%d: %g\n", ch, cl->channel[ch]); */
976 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
980 ICLF_set_internal(cl,r,g,b,a)
981 Imager::Color::Float cl
996 Imager::Color::Float c
998 RETVAL = mymalloc(sizeof(i_fcolor));
1000 i_hsv_to_rgbf(RETVAL);
1004 Imager::Color::Float
1006 Imager::Color::Float c
1008 RETVAL = mymalloc(sizeof(i_fcolor));
1010 i_rgb_to_hsvf(RETVAL);
1014 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1028 MODULE = Imager PACKAGE = Imager
1047 SvPV(ST(0), length);
1048 SvREFCNT_inc(ST(0));
1049 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1054 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1063 cbd = mymalloc(sizeof(struct cbdata));
1064 SvREFCNT_inc(writecb);
1065 cbd->writecb = writecb;
1066 SvREFCNT_inc(readcb);
1067 cbd->readcb = readcb;
1068 SvREFCNT_inc(seekcb);
1069 cbd->seekcb = seekcb;
1070 SvREFCNT_inc(closecb);
1071 cbd->closecb = closecb;
1072 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1073 if (maxwrite > CBDATA_BUFSIZE)
1074 maxwrite = CBDATA_BUFSIZE;
1075 cbd->maxlength = maxwrite;
1076 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1085 unsigned char* data;
1089 tlength = io_slurp(ig, &data);
1091 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1096 i_set_image_file_limits(width, height, bytes)
1102 i_get_image_file_limits()
1104 int width, height, bytes;
1106 if (i_get_image_file_limits(&width, &height, &bytes)) {
1108 PUSHs(sv_2mortal(newSViv(width)));
1109 PUSHs(sv_2mortal(newSViv(height)));
1110 PUSHs(sv_2mortal(newSViv(bytes)));
1113 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1120 MODULE = Imager PACKAGE = Imager
1133 while( (item=i_format_list[i++]) != NULL ) {
1135 PUSHs(sv_2mortal(newSVpv(item,0)));
1152 i_img_empty_ch(im,x,y,ch)
1159 i_sametype(im, x, y)
1165 i_sametype_chans(im, x, y, channels)
1172 m_init_log(name,level)
1177 log_entry(string,level)
1196 i_img_info(im,info);
1198 PUSHs(sv_2mortal(newSViv(info[0])));
1199 PUSHs(sv_2mortal(newSViv(info[1])));
1200 PUSHs(sv_2mortal(newSViv(info[2])));
1201 PUSHs(sv_2mortal(newSViv(info[3])));
1207 i_img_setmask(im,ch_mask)
1216 i_img_getchannels(im)
1225 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1230 i_line(im,x1,y1,x2,y2,val,endp)
1240 i_line_aa(im,x1,y1,x2,y2,val,endp)
1250 i_box(im,x1,y1,x2,y2,val)
1259 i_box_filled(im,x1,y1,x2,y2,val)
1268 i_box_cfill(im,x1,y1,x2,y2,fill)
1274 Imager::FillHandle fill
1277 i_arc(im,x,y,rad,d1,d2,val)
1287 i_arc_aa(im,x,y,rad,d1,d2,val)
1297 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1304 Imager::FillHandle fill
1307 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1314 Imager::FillHandle fill
1318 i_circle_aa(im,x,y,rad,val)
1328 i_bezier_multi(im,xc,yc,val)
1341 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1342 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1343 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1344 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1345 av1=(AV*)SvRV(ST(1));
1346 av2=(AV*)SvRV(ST(2));
1347 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1349 x=mymalloc( len*sizeof(double) );
1350 y=mymalloc( len*sizeof(double) );
1351 for(i=0;i<len;i++) {
1352 sv1=(*(av_fetch(av1,i,0)));
1353 sv2=(*(av_fetch(av2,i,0)));
1354 x[i]=(double)SvNV(sv1);
1355 y[i]=(double)SvNV(sv2);
1357 i_bezier_multi(im,len,x,y,val);
1363 i_poly_aa(im,xc,yc,val)
1376 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1377 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1378 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1379 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1380 av1=(AV*)SvRV(ST(1));
1381 av2=(AV*)SvRV(ST(2));
1382 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1384 x=mymalloc( len*sizeof(double) );
1385 y=mymalloc( len*sizeof(double) );
1386 for(i=0;i<len;i++) {
1387 sv1=(*(av_fetch(av1,i,0)));
1388 sv2=(*(av_fetch(av2,i,0)));
1389 x[i]=(double)SvNV(sv1);
1390 y[i]=(double)SvNV(sv2);
1392 i_poly_aa(im,len,x,y,val);
1397 i_poly_aa_cfill(im,xc,yc,fill)
1399 Imager::FillHandle fill
1409 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1410 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1411 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1412 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1413 av1=(AV*)SvRV(ST(1));
1414 av2=(AV*)SvRV(ST(2));
1415 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1417 x=mymalloc( len*sizeof(double) );
1418 y=mymalloc( len*sizeof(double) );
1419 for(i=0;i<len;i++) {
1420 sv1=(*(av_fetch(av1,i,0)));
1421 sv2=(*(av_fetch(av2,i,0)));
1422 x[i]=(double)SvNV(sv1);
1423 y[i]=(double)SvNV(sv2);
1425 i_poly_aa_cfill(im,len,x,y,fill);
1432 i_flood_fill(im,seedx,seedy,dcol)
1439 i_flood_cfill(im,seedx,seedy,fill)
1443 Imager::FillHandle fill
1447 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1459 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1477 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1489 i_flipxy(im, direction)
1494 i_rotate90(im, degrees)
1499 i_rotate_exact(im, amount, ...)
1503 i_color *backp = NULL;
1504 i_fcolor *fbackp = NULL;
1508 /* extract the bg colors if any */
1509 /* yes, this is kind of strange */
1510 for (i = 2; i < items; ++i) {
1512 if (sv_derived_from(sv1, "Imager::Color")) {
1513 IV tmp = SvIV((SV*)SvRV(sv1));
1514 backp = INT2PTR(i_color *, tmp);
1516 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1517 IV tmp = SvIV((SV*)SvRV(sv1));
1518 fbackp = INT2PTR(i_fcolor *, tmp);
1521 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1526 i_matrix_transform(im, xsize, ysize, matrix, ...)
1536 i_color *backp = NULL;
1537 i_fcolor *fbackp = NULL;
1539 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1540 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1541 av=(AV*)SvRV(ST(3));
1545 for (i = 0; i < len; ++i) {
1546 sv1=(*(av_fetch(av,i,0)));
1547 matrix[i] = SvNV(sv1);
1551 /* extract the bg colors if any */
1552 /* yes, this is kind of strange */
1553 for (i = 4; i < items; ++i) {
1555 if (sv_derived_from(sv1, "Imager::Color")) {
1556 IV tmp = SvIV((SV*)SvRV(sv1));
1557 backp = INT2PTR(i_color *, tmp);
1559 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1560 IV tmp = SvIV((SV*)SvRV(sv1));
1561 fbackp = INT2PTR(i_fcolor *, tmp);
1564 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1569 i_gaussian(im,stdev)
1574 i_unsharp_mask(im,stdev,scale)
1589 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1590 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1591 av=(AV*)SvRV(ST(1));
1593 coeff=mymalloc( len*sizeof(float) );
1594 for(i=0;i<len;i++) {
1595 sv1=(*(av_fetch(av,i,0)));
1596 coeff[i]=(float)SvNV(sv1);
1598 i_conv(im,coeff,len);
1602 i_convert(im, src, coeff)
1615 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1616 croak("i_convert: parameter 3 must be an arrayref\n");
1617 avmain = (AV*)SvRV(ST(2));
1618 outchan = av_len(avmain)+1;
1619 /* find the biggest */
1621 for (j=0; j < outchan; ++j) {
1622 temp = av_fetch(avmain, j, 0);
1623 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1624 avsub = (AV*)SvRV(*temp);
1625 len = av_len(avsub)+1;
1630 coeff = mymalloc(sizeof(float) * outchan * inchan);
1631 for (j = 0; j < outchan; ++j) {
1632 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1633 len = av_len(avsub)+1;
1634 for (i = 0; i < len; ++i) {
1635 temp = av_fetch(avsub, i, 0);
1637 coeff[i+j*inchan] = SvNV(*temp);
1639 coeff[i+j*inchan] = 0;
1642 coeff[i++ + j*inchan] = 0;
1644 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1654 unsigned int mask = 0;
1660 unsigned char (*maps)[256];
1662 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1663 croak("i_map: parameter 2 must be an arrayref\n");
1664 avmain = (AV*)SvRV(ST(1));
1665 len = av_len(avmain)+1;
1666 if (im->channels < len) len = im->channels;
1668 maps = mymalloc( len * sizeof(unsigned char [256]) );
1670 for (j=0; j<len ; j++) {
1671 temp = av_fetch(avmain, j, 0);
1672 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1673 avsub = (AV*)SvRV(*temp);
1674 if(av_len(avsub) != 255) continue;
1676 for (i=0; i<256 ; i++) {
1678 temp = av_fetch(avsub, i, 0);
1679 val = temp ? SvIV(*temp) : 0;
1681 if (val>255) val = 255;
1686 i_map(im, maps, mask);
1699 i_init_fonts(t1log=0)
1714 i_t1_destroy(font_id)
1719 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1738 str = SvPV(str_sv, len);
1739 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1746 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1755 int cords[BOUNDING_BOX_COUNT];
1763 str = SvPV(str_sv, len);
1764 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1767 for (i = 0; i < rc; ++i)
1768 PUSHs(sv_2mortal(newSViv(cords[i])));
1774 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1793 str = SvPV(str_sv, len);
1794 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1800 i_t1_has_chars(handle, text_sv, utf8 = 0)
1812 if (SvUTF8(text_sv))
1815 text = SvPV(text_sv, len);
1816 work = mymalloc(len);
1817 count = i_t1_has_chars(handle, text, len, utf8, work);
1818 if (GIMME_V == G_ARRAY) {
1820 for (i = 0; i < count; ++i) {
1821 PUSHs(sv_2mortal(newSViv(work[i])));
1826 PUSHs(sv_2mortal(newSVpv(work, count)));
1831 i_t1_face_name(handle)
1837 len = i_t1_face_name(handle, name, sizeof(name));
1840 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1844 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1856 if (SvUTF8(text_sv))
1859 text = SvPV(text_sv, work_len);
1864 ch = i_utf8_advance(&text, &len);
1866 i_push_error(0, "invalid UTF8 character");
1875 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1876 PUSHs(sv_2mortal(newSVpv(name, 0)));
1879 PUSHs(&PL_sv_undef);
1893 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1895 #define TT_DESTROY(handle) i_tt_destroy(handle)
1899 Imager::Font::TT handle
1902 MODULE = Imager PACKAGE = Imager
1906 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1907 Imager::Font::TT handle
1926 str = SvPV(str_sv, len);
1927 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1928 len, smooth, utf8, align);
1934 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1935 Imager::Font::TT handle
1954 str = SvPV(str_sv, len);
1955 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1956 smooth, utf8, align);
1962 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1963 Imager::Font::TT handle
1969 int cords[BOUNDING_BOX_COUNT],rc;
1978 str = SvPV(str_sv, len);
1979 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1981 for (i = 0; i < rc; ++i) {
1982 PUSHs(sv_2mortal(newSViv(cords[i])));
1987 i_tt_has_chars(handle, text_sv, utf8)
1988 Imager::Font::TT handle
1999 if (SvUTF8(text_sv))
2002 text = SvPV(text_sv, len);
2003 work = mymalloc(len);
2004 count = i_tt_has_chars(handle, text, len, utf8, work);
2005 if (GIMME_V == G_ARRAY) {
2007 for (i = 0; i < count; ++i) {
2008 PUSHs(sv_2mortal(newSViv(work[i])));
2013 PUSHs(sv_2mortal(newSVpv(work, count)));
2018 i_tt_dump_names(handle)
2019 Imager::Font::TT handle
2022 i_tt_face_name(handle)
2023 Imager::Font::TT handle
2028 len = i_tt_face_name(handle, name, sizeof(name));
2031 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2035 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2036 Imager::Font::TT handle
2047 if (SvUTF8(text_sv))
2050 text = SvPV(text_sv, work_len);
2055 ch = i_utf8_advance(&text, &len);
2057 i_push_error(0, "invalid UTF8 character");
2066 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2067 PUSHs(sv_2mortal(newSVpv(name, 0)));
2070 PUSHs(&PL_sv_undef);
2079 i_writejpeg_wiol(im, ig, qfactor)
2095 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2096 if (iptc_itext == NULL) {
2099 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2104 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2106 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2115 i_test_format_probe(ig, length)
2124 i_readtiff_wiol(ig, length, page=0)
2130 i_readtiff_multi_wiol(ig, length)
2138 imgs = i_readtiff_multi_wiol(ig, length, &count);
2141 for (i = 0; i < count; ++i) {
2142 SV *sv = sv_newmortal();
2143 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2151 i_writetiff_wiol(im, ig)
2156 i_writetiff_multi_wiol(ig, ...)
2164 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2165 img_count = items - 1;
2167 if (img_count < 1) {
2170 i_push_error(0, "You need to specify images to save");
2173 imgs = mymalloc(sizeof(i_img *) * img_count);
2174 for (i = 0; i < img_count; ++i) {
2177 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2178 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2182 i_push_error(0, "Only images can be saved");
2189 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2197 i_writetiff_wiol_faxable(im, ig, fine)
2203 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2212 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2213 img_count = items - 2;
2215 if (img_count < 1) {
2218 i_push_error(0, "You need to specify images to save");
2221 imgs = mymalloc(sizeof(i_img *) * img_count);
2222 for (i = 0; i < img_count; ++i) {
2225 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2226 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2230 i_push_error(0, "Only images can be saved");
2237 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2245 #endif /* HAVE_LIBTIFF */
2251 i_readpng_wiol(ig, length)
2257 i_writepng_wiol(im, ig)
2270 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2273 i_writegif(im,fd,colors,pixdev,fixed)
2280 Imager__Color fixed;
2287 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2288 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2289 av=(AV*)SvRV(ST(4));
2290 fixedlen=av_len(av)+1;
2291 fixed=mymalloc( fixedlen*sizeof(i_color) );
2292 for(i=0;i<fixedlen;i++) {
2293 sv1=(*(av_fetch(av,i,0)));
2294 if (sv_derived_from(sv1, "Imager::Color")) {
2295 Itmp = SvIV((SV*)SvRV(sv1));
2296 tmp = INT2PTR(i_color*, Itmp);
2297 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2300 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2302 ST(0) = sv_newmortal();
2303 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2304 else sv_setiv(ST(0), (IV)RETVAL);
2310 i_writegifmc(im,fd,colors)
2317 i_writegif_gen(fd, ...)
2322 i_img **imgs = NULL;
2328 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2329 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2330 croak("i_writegif_gen: Second argument must be a hash ref");
2331 hv = (HV *)SvRV(ST(1));
2332 memset(&quant, 0, sizeof(quant));
2333 quant.mc_size = 256;
2334 handle_quant_opts(&quant, hv);
2335 img_count = items - 2;
2337 if (img_count < 1) {
2340 i_push_error(0, "You need to specify images to save");
2343 imgs = mymalloc(sizeof(i_img *) * img_count);
2344 for (i = 0; i < img_count; ++i) {
2347 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2348 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2352 i_push_error(0, "Only images can be saved");
2358 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2362 copy_colors_back(hv, &quant);
2365 ST(0) = sv_newmortal();
2366 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2367 else sv_setiv(ST(0), (IV)RETVAL);
2368 cleanup_quant_opts(&quant);
2372 i_writegif_callback(cb, maxbuffer,...)
2376 i_img **imgs = NULL;
2383 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2384 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2385 croak("i_writegif_callback: Second argument must be a hash ref");
2386 hv = (HV *)SvRV(ST(2));
2387 memset(&quant, 0, sizeof(quant));
2388 quant.mc_size = 256;
2389 handle_quant_opts(&quant, hv);
2390 img_count = items - 3;
2392 if (img_count < 1) {
2396 imgs = mymalloc(sizeof(i_img *) * img_count);
2397 for (i = 0; i < img_count; ++i) {
2400 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2401 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2410 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2414 copy_colors_back(hv, &quant);
2417 ST(0) = sv_newmortal();
2418 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2419 else sv_setiv(ST(0), (IV)RETVAL);
2420 cleanup_quant_opts(&quant);
2423 i_writegif_wiol(ig, opts,...)
2427 i_img **imgs = NULL;
2433 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2434 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2435 croak("i_writegif_callback: Second argument must be a hash ref");
2436 hv = (HV *)SvRV(ST(1));
2437 memset(&quant, 0, sizeof(quant));
2438 quant.mc_size = 256;
2439 handle_quant_opts(&quant, hv);
2440 img_count = items - 2;
2442 if (img_count < 1) {
2446 imgs = mymalloc(sizeof(i_img *) * img_count);
2447 for (i = 0; i < img_count; ++i) {
2450 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2451 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2459 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2463 copy_colors_back(hv, &quant);
2466 ST(0) = sv_newmortal();
2467 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2468 else sv_setiv(ST(0), (IV)RETVAL);
2469 cleanup_quant_opts(&quant);
2482 colour_table = NULL;
2485 if(GIMME_V == G_ARRAY) {
2486 rimg = i_readgif(fd,&colour_table,&colours);
2488 /* don't waste time with colours if they aren't wanted */
2489 rimg = i_readgif(fd,NULL,NULL);
2492 if (colour_table == NULL) {
2495 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2498 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2499 /* I don't know if I have the reference counts right or not :( */
2500 /* Neither do I :-) */
2501 /* No Idea here either */
2504 av_extend(ct, colours);
2505 for(q=0; q<colours; q++) {
2507 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2508 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2510 myfree(colour_table);
2514 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2516 PUSHs(newRV_noinc((SV*)ct));
2530 colour_table = NULL;
2533 if(GIMME_V == G_ARRAY) {
2534 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2536 /* don't waste time with colours if they aren't wanted */
2537 rimg = i_readgif_wiol(ig,NULL,NULL);
2540 if (colour_table == NULL) {
2543 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2546 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2547 /* I don't know if I have the reference counts right or not :( */
2548 /* Neither do I :-) */
2549 /* No Idea here either */
2552 av_extend(ct, colours);
2553 for(q=0; q<colours; q++) {
2555 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2556 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2558 myfree(colour_table);
2562 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2564 PUSHs(newRV_noinc((SV*)ct));
2568 i_readgif_single_wiol(ig, page=0)
2573 i_readgif_scalar(...)
2585 data = (char *)SvPV(ST(0), length);
2589 if(GIMME_V == G_ARRAY) {
2590 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2592 /* don't waste time with colours if they aren't wanted */
2593 rimg=i_readgif_scalar(data,length,NULL,NULL);
2596 if (colour_table == NULL) {
2599 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2602 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2603 /* I don't know if I have the reference counts right or not :( */
2604 /* Neither do I :-) */
2606 av_extend(ct, colours);
2607 for(q=0; q<colours; q++) {
2609 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2610 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2612 myfree(colour_table);
2616 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2618 PUSHs(newRV_noinc((SV*)ct));
2622 i_readgif_callback(...)
2637 if(GIMME_V == G_ARRAY) {
2638 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2640 /* don't waste time with colours if they aren't wanted */
2641 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2644 if (colour_table == NULL) {
2647 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2650 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2651 /* I don't know if I have the reference counts right or not :( */
2652 /* Neither do I :-) */
2653 /* Neither do I - maybe I'll move this somewhere */
2655 av_extend(ct, colours);
2656 for(q=0; q<colours; q++) {
2658 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2659 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2661 myfree(colour_table);
2665 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2667 PUSHs(newRV_noinc((SV*)ct));
2678 imgs = i_readgif_multi(fd, &count);
2681 for (i = 0; i < count; ++i) {
2682 SV *sv = sv_newmortal();
2683 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2690 i_readgif_multi_scalar(data)
2698 data = (char *)SvPV(ST(0), length);
2699 imgs = i_readgif_multi_scalar(data, length, &count);
2702 for (i = 0; i < count; ++i) {
2703 SV *sv = sv_newmortal();
2704 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2711 i_readgif_multi_callback(cb)
2719 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2722 for (i = 0; i < count; ++i) {
2723 SV *sv = sv_newmortal();
2724 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2731 i_readgif_multi_wiol(ig)
2738 imgs = i_readgif_multi_wiol(ig, &count);
2741 for (i = 0; i < count; ++i) {
2742 SV *sv = sv_newmortal();
2743 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2755 i_readpnm_wiol(ig, length)
2761 i_writeppm_wiol(im, ig)
2767 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2776 i_writeraw_wiol(im,ig)
2781 i_writebmp_wiol(im,ig)
2791 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2800 idlen = SvCUR(ST(4));
2801 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2807 i_readtga_wiol(ig, length)
2813 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2822 idlen = SvCUR(ST(4));
2823 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2829 i_readrgb_wiol(ig, length)
2836 i_scaleaxis(im,Value,Axis)
2842 i_scale_nn(im,scx,scy)
2852 i_count_colors(im,maxc)
2858 i_transform(im,opx,opy,parm)
2871 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2872 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2873 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2874 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2875 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2876 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2877 av=(AV*)SvRV(ST(1));
2879 opx=mymalloc( opxl*sizeof(int) );
2880 for(i=0;i<opxl;i++) {
2881 sv1=(*(av_fetch(av,i,0)));
2882 opx[i]=(int)SvIV(sv1);
2884 av=(AV*)SvRV(ST(2));
2886 opy=mymalloc( opyl*sizeof(int) );
2887 for(i=0;i<opyl;i++) {
2888 sv1=(*(av_fetch(av,i,0)));
2889 opy[i]=(int)SvIV(sv1);
2891 av=(AV*)SvRV(ST(3));
2892 parmlen=av_len(av)+1;
2893 parm=mymalloc( parmlen*sizeof(double) );
2894 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2895 sv1=(*(av_fetch(av,i,0)));
2896 parm[i]=(double)SvNV(sv1);
2898 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2902 ST(0) = sv_newmortal();
2903 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2904 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2907 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2932 in_imgs_count = av_len(av_in_imgs)+1;
2933 for (i = 0; i < in_imgs_count; ++i) {
2934 sv1 = *av_fetch(av_in_imgs, i, 0);
2935 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2936 croak("sv_in_img must contain only images");
2939 if (in_imgs_count > 0) {
2940 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2941 for (i = 0; i < in_imgs_count; ++i) {
2942 sv1 = *av_fetch(av_in_imgs,i,0);
2943 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2944 croak("Parameter 5 must contain only images");
2946 tmp = SvIV((SV*)SvRV(sv1));
2947 in_imgs[i] = INT2PTR(i_img*, tmp);
2951 /* no input images */
2954 /* default the output size from the first input if possible */
2956 width = SvIV(sv_width);
2957 else if (in_imgs_count)
2958 width = in_imgs[0]->xsize;
2960 croak("No output image width supplied");
2962 if (SvOK(sv_height))
2963 height = SvIV(sv_height);
2964 else if (in_imgs_count)
2965 height = in_imgs[0]->ysize;
2967 croak("No output image height supplied");
2969 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2970 if (ops_len % sizeof(struct rm_op))
2971 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2972 ops_count = ops_len / sizeof(struct rm_op);
2974 n_regs_count = av_len(av_n_regs)+1;
2975 n_regs = mymalloc(n_regs_count * sizeof(double));
2976 for (i = 0; i < n_regs_count; ++i) {
2977 sv1 = *av_fetch(av_n_regs,i,0);
2979 n_regs[i] = SvNV(sv1);
2981 c_regs_count = av_len(av_c_regs)+1;
2982 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2983 /* I don't bother initializing the colou?r registers */
2985 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2986 n_regs, n_regs_count,
2987 c_regs, c_regs_count, in_imgs, in_imgs_count);
2992 ST(0) = sv_newmortal();
2993 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2994 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2998 i_contrast(im,intensity)
3007 i_noise(im,amount,type)
3013 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3023 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3042 i_postlevels(im,levels)
3052 i_watermark(im,wmark,tx,ty,pixdiff)
3054 Imager::ImgRaw wmark
3061 i_autolevels(im,lsat,usat,skew)
3068 i_radnoise(im,xo,yo,rscale,ascale)
3076 i_turbnoise(im, xo, yo, scale)
3099 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3100 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3101 croak("i_gradgen: Second argument must be an array ref");
3102 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3103 croak("i_gradgen: Third argument must be an array ref");
3104 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3105 croak("i_gradgen: Fourth argument must be an array ref");
3106 axx = (AV *)SvRV(ST(1));
3107 ayy = (AV *)SvRV(ST(2));
3108 ac = (AV *)SvRV(ST(3));
3109 dmeasure = (int)SvIV(ST(4));
3111 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3112 num = num <= av_len(ac) ? num : av_len(ac);
3114 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3115 xo = mymalloc( sizeof(int) * num );
3116 yo = mymalloc( sizeof(int) * num );
3117 ival = mymalloc( sizeof(i_color) * num );
3118 for(i = 0; i<num; i++) {
3119 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3120 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3121 sv = *av_fetch(ac, i, 0);
3122 if ( !sv_derived_from(sv, "Imager::Color") ) {
3123 free(axx); free(ayy); free(ac);
3124 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3126 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3128 i_gradgen(im, num, xo, yo, ival, dmeasure);
3134 i_diff_image(im, im2, mindist=0)
3140 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3150 double ssample_param
3154 i_fountain_seg *segs;
3156 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3157 croak("i_fountain: argument 11 must be an array ref");
3159 asegs = (AV *)SvRV(ST(10));
3160 segs = load_fount_segs(asegs, &count);
3161 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3162 ssample_param, count, segs);
3166 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3175 double ssample_param
3179 i_fountain_seg *segs;
3181 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3182 croak("i_fountain: argument 11 must be an array ref");
3184 asegs = (AV *)SvRV(ST(9));
3185 segs = load_fount_segs(asegs, &count);
3186 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3187 super_sample, ssample_param, count, segs);
3200 errors = i_errors();
3202 while (errors[i].msg) {
3204 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3205 if (!av_store(av, 0, sv)) {
3208 sv = newSViv(errors[i].code);
3209 if (!av_store(av, 1, sv)) {
3212 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3217 i_nearest_color(im, ...)
3232 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3233 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3234 croak("i_nearest_color: Second argument must be an array ref");
3235 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3236 croak("i_nearest_color: Third argument must be an array ref");
3237 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3238 croak("i_nearest_color: Fourth argument must be an array ref");
3239 axx = (AV *)SvRV(ST(1));
3240 ayy = (AV *)SvRV(ST(2));
3241 ac = (AV *)SvRV(ST(3));
3242 dmeasure = (int)SvIV(ST(4));
3244 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3245 num = num <= av_len(ac) ? num : av_len(ac);
3247 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3248 xo = mymalloc( sizeof(int) * num );
3249 yo = mymalloc( sizeof(int) * num );
3250 ival = mymalloc( sizeof(i_color) * num );
3251 for(i = 0; i<num; i++) {
3252 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3253 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3254 sv = *av_fetch(ac, i, 0);
3255 if ( !sv_derived_from(sv, "Imager::Color") ) {
3256 free(axx); free(ayy); free(ac);
3257 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3259 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3261 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3275 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3276 hv=(HV*)SvRV(ST(0));
3277 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3278 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3279 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3288 rc=DSO_open(filename,&evstr);
3292 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3293 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3296 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3302 DSO_close(dso_handle)
3306 DSO_funclist(dso_handle_v)
3310 DSO_handle *dso_handle;
3312 dso_handle=(DSO_handle*)dso_handle_v;
3314 while( dso_handle->function_list[i].name != NULL) {
3316 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3318 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3323 DSO_call(handle,func_index,hv)
3329 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3330 hv=(HV*)SvRV(ST(2));
3331 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3332 DSO_call( (DSO_handle *)handle,func_index,hv);
3337 i_get_pixel(im, x, y)
3344 color = (i_color *)mymalloc(sizeof(i_color));
3345 if (i_gpix(im, x, y, color) == 0) {
3346 RETVAL = NEWSV(0, 0);
3347 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3351 RETVAL = &PL_sv_undef;
3358 i_ppix(im, x, y, cl)
3365 i_img_pal_new(x, y, channels, maxpal)
3372 i_img_to_pal(src, quant)
3378 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3379 croak("i_img_to_pal: second argument must be a hash ref");
3380 hv = (HV *)SvRV(ST(1));
3381 memset(&quant, 0, sizeof(quant));
3382 quant.mc_size = 256;
3383 handle_quant_opts(&quant, hv);
3384 RETVAL = i_img_to_pal(src, &quant);
3386 copy_colors_back(hv, &quant);
3388 cleanup_quant_opts(&quant);
3407 work = mymalloc((r-l) * sizeof(i_palidx));
3408 count = i_gpal(im, l, r, y, work);
3409 if (GIMME_V == G_ARRAY) {
3411 for (i = 0; i < count; ++i) {
3412 PUSHs(sv_2mortal(newSViv(work[i])));
3417 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3422 if (GIMME_V != G_ARRAY) {
3424 PUSHs(&PL_sv_undef);
3429 i_ppal(im, l, y, ...)
3438 work = mymalloc(sizeof(i_palidx) * (items-3));
3439 for (i=0; i < items-3; ++i) {
3440 work[i] = SvIV(ST(i+3));
3442 RETVAL = i_ppal(im, l, l+items-3, y, work);
3452 i_addcolors(im, ...)
3460 croak("i_addcolors: no colors to add");
3461 colors = mymalloc((items-1) * sizeof(i_color));
3462 for (i=0; i < items-1; ++i) {
3463 if (sv_isobject(ST(i+1))
3464 && sv_derived_from(ST(i+1), "Imager::Color")) {
3465 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3466 colors[i] = *INT2PTR(i_color *, tmp);
3470 croak("i_addcolor: pixels must be Imager::Color objects");
3473 index = i_addcolors(im, colors, items-1);
3476 RETVAL = newSVpv("0 but true", 0);
3478 else if (index == -1) {
3479 RETVAL = &PL_sv_undef;
3482 RETVAL = newSViv(index);
3488 i_setcolors(im, index, ...)
3496 croak("i_setcolors: no colors to add");
3497 colors = mymalloc((items-2) * sizeof(i_color));
3498 for (i=0; i < items-2; ++i) {
3499 if (sv_isobject(ST(i+2))
3500 && sv_derived_from(ST(i+2), "Imager::Color")) {
3501 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3502 colors[i] = *INT2PTR(i_color *, tmp);
3506 croak("i_setcolors: pixels must be Imager::Color objects");
3509 RETVAL = i_setcolors(im, index, colors, items-2);
3515 i_getcolors(im, index, ...)
3524 croak("i_getcolors: too many arguments");
3526 count = SvIV(ST(2));
3528 croak("i_getcolors: count must be positive");
3529 colors = mymalloc(sizeof(i_color) * count);
3530 if (i_getcolors(im, index, colors, count)) {
3531 for (i = 0; i < count; ++i) {
3533 SV *sv = sv_newmortal();
3534 pv = mymalloc(sizeof(i_color));
3536 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3552 i_findcolor(im, color)
3558 if (i_findcolor(im, color, &index)) {
3559 RETVAL = newSViv(index);
3562 RETVAL = &PL_sv_undef;
3580 i_gsamp(im, l, r, y, ...)
3592 croak("No channel numbers supplied to g_samp()");
3594 chan_count = items - 4;
3595 chans = mymalloc(sizeof(int) * chan_count);
3596 for (i = 0; i < chan_count; ++i)
3597 chans[i] = SvIV(ST(i+4));
3598 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3599 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3601 if (GIMME_V == G_ARRAY) {
3603 for (i = 0; i < count; ++i)
3604 PUSHs(sv_2mortal(newSViv(data[i])));
3608 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3613 if (GIMME_V != G_ARRAY) {
3615 PUSHs(&PL_sv_undef);
3621 i_img_masked_new(targ, mask, x, y, w, h)
3631 if (!sv_isobject(ST(1))
3632 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3633 croak("i_img_masked_new: parameter 2 must undef or an image");
3635 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3639 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3644 i_plin(im, l, y, ...)
3655 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3656 /* supplied as a byte string */
3657 work = (i_color *)SvPV(ST(3), len);
3658 count = len / sizeof(i_color);
3659 if (count * sizeof(i_color) != len) {
3660 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3662 RETVAL = i_plin(im, l, l+count, y, work);
3665 work = mymalloc(sizeof(i_color) * (items-3));
3666 for (i=0; i < items-3; ++i) {
3667 if (sv_isobject(ST(i+3))
3668 && sv_derived_from(ST(i+3), "Imager::Color")) {
3669 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3670 work[i] = *INT2PTR(i_color *, tmp);
3674 croak("i_plin: pixels must be Imager::Color objects");
3677 RETVAL = i_plin(im, l, l+items-3, y, work);
3688 i_ppixf(im, x, y, cl)
3692 Imager::Color::Float cl
3695 i_gsampf(im, l, r, y, ...)
3707 croak("No channel numbers supplied to g_sampf()");
3709 chan_count = items - 4;
3710 chans = mymalloc(sizeof(int) * chan_count);
3711 for (i = 0; i < chan_count; ++i)
3712 chans[i] = SvIV(ST(i+4));
3713 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3714 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3715 if (GIMME_V == G_ARRAY) {
3717 for (i = 0; i < count; ++i)
3718 PUSHs(sv_2mortal(newSVnv(data[i])));
3722 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3726 if (GIMME_V != G_ARRAY) {
3728 PUSHs(&PL_sv_undef);
3733 i_plinf(im, l, y, ...)
3744 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3745 /* supplied as a byte string */
3746 work = (i_fcolor *)SvPV(ST(3), len);
3747 count = len / sizeof(i_fcolor);
3748 if (count * sizeof(i_fcolor) != len) {
3749 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3751 RETVAL = i_plinf(im, l, l+count, y, work);
3754 work = mymalloc(sizeof(i_fcolor) * (items-3));
3755 for (i=0; i < items-3; ++i) {
3756 if (sv_isobject(ST(i+3))
3757 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3758 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3759 work[i] = *INT2PTR(i_fcolor *, tmp);
3763 croak("i_plinf: pixels must be Imager::Color::Float objects");
3767 RETVAL = i_plinf(im, l, l+items-3, y, work);
3785 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3786 if (i_gpixf(im, x, y, color) == 0) {
3787 RETVAL = NEWSV(0,0);
3788 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3792 RETVAL = &PL_sv_undef;
3808 vals = mymalloc((r-l) * sizeof(i_color));
3809 count = i_glin(im, l, r, y, vals);
3810 if (GIMME_V == G_ARRAY) {
3812 for (i = 0; i < count; ++i) {
3814 i_color *col = mymalloc(sizeof(i_color));
3816 sv = sv_newmortal();
3817 sv_setref_pv(sv, "Imager::Color", (void *)col);
3823 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3829 i_glinf(im, l, r, y)
3839 vals = mymalloc((r-l) * sizeof(i_fcolor));
3840 count = i_glinf(im, l, r, y, vals);
3841 if (GIMME_V == G_ARRAY) {
3843 for (i = 0; i < count; ++i) {
3845 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3847 sv = sv_newmortal();
3848 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3854 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3860 i_img_16_new(x, y, ch)
3866 i_img_double_new(x, y, ch)
3872 i_tags_addn(im, name, code, idata)
3881 name = SvPV(ST(1), len);
3884 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3889 i_tags_add(im, name, code, data, idata)
3899 name = SvPV(ST(1), len);
3903 data = SvPV(ST(3), len);
3908 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3913 i_tags_find(im, name, start)
3920 if (i_tags_find(&im->tags, name, start, &entry)) {
3922 RETVAL = newSVpv("0 but true", 0);
3924 RETVAL = newSViv(entry);
3926 RETVAL = &PL_sv_undef;
3932 i_tags_findn(im, code, start)
3939 if (i_tags_findn(&im->tags, code, start, &entry)) {
3941 RETVAL = newSVpv("0 but true", 0);
3943 RETVAL = newSViv(entry);
3946 RETVAL = &PL_sv_undef;
3952 i_tags_delete(im, entry)
3956 RETVAL = i_tags_delete(&im->tags, entry);
3961 i_tags_delbyname(im, name)
3965 RETVAL = i_tags_delbyname(&im->tags, name);
3970 i_tags_delbycode(im, code)
3974 RETVAL = i_tags_delbycode(&im->tags, code);
3979 i_tags_get(im, index)
3983 if (index >= 0 && index < im->tags.count) {
3984 i_img_tag *entry = im->tags.tags + index;
3988 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3991 PUSHs(sv_2mortal(newSViv(entry->code)));
3994 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3997 PUSHs(sv_2mortal(newSViv(entry->idata)));
4002 i_tags_get_string(im, what_sv)
4006 char const *name = NULL;
4010 if (SvIOK(what_sv)) {
4011 code = SvIV(what_sv);
4015 name = SvPV_nolen(what_sv);
4018 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4020 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4027 RETVAL = im->tags.count;
4034 i_wf_bbox(face, size, text)
4039 int cords[BOUNDING_BOX_COUNT];
4042 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4044 for (i = 0; i < rc; ++i)
4045 PUSHs(sv_2mortal(newSViv(cords[i])));
4049 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4060 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4066 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4077 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4090 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4092 #define FT2_DESTROY(font) i_ft2_destroy(font)
4096 Imager::Font::FT2 font
4098 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4101 i_ft2_new(name, index)
4106 i_ft2_setdpi(font, xdpi, ydpi)
4107 Imager::Font::FT2 font
4113 Imager::Font::FT2 font
4117 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4119 PUSHs(sv_2mortal(newSViv(xdpi)));
4120 PUSHs(sv_2mortal(newSViv(ydpi)));
4124 i_ft2_sethinting(font, hinting)
4125 Imager::Font::FT2 font
4129 i_ft2_settransform(font, matrix)
4130 Imager::Font::FT2 font
4138 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4139 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4140 av=(AV*)SvRV(ST(1));
4144 for (i = 0; i < len; ++i) {
4145 sv1=(*(av_fetch(av,i,0)));
4146 matrix[i] = SvNV(sv1);
4150 RETVAL = i_ft2_settransform(font, matrix);
4155 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4156 Imager::Font::FT2 font
4162 int bbox[BOUNDING_BOX_COUNT];
4168 text = SvPV(text_sv, text_len);
4170 if (SvUTF8(text_sv))
4173 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4176 for (i = 0; i < rc; ++i)
4177 PUSHs(sv_2mortal(newSViv(bbox[i])));
4181 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4182 Imager::Font::FT2 font
4196 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4199 for (i = 0; i < 8; ++i)
4200 PUSHs(sv_2mortal(newSViv(bbox[i])));
4204 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4205 Imager::Font::FT2 font
4221 if (SvUTF8(ST(7))) {
4225 text = SvPV(ST(7), len);
4226 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4227 len, align, aa, vlayout, utf8);
4232 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4233 Imager::Font::FT2 font
4250 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4251 strlen(text), align, aa, vlayout, 1);
4256 ft2_transform_box(font, x0, x1, x2, x3)
4257 Imager::Font::FT2 font
4265 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4266 ft2_transform_box(font, box);
4268 PUSHs(sv_2mortal(newSViv(box[0])));
4269 PUSHs(sv_2mortal(newSViv(box[1])));
4270 PUSHs(sv_2mortal(newSViv(box[2])));
4271 PUSHs(sv_2mortal(newSViv(box[3])));
4274 i_ft2_has_chars(handle, text_sv, utf8)
4275 Imager::Font::FT2 handle
4286 if (SvUTF8(text_sv))
4289 text = SvPV(text_sv, len);
4290 work = mymalloc(len);
4291 count = i_ft2_has_chars(handle, text, len, utf8, work);
4292 if (GIMME_V == G_ARRAY) {
4294 for (i = 0; i < count; ++i) {
4295 PUSHs(sv_2mortal(newSViv(work[i])));
4300 PUSHs(sv_2mortal(newSVpv(work, count)));
4305 i_ft2_face_name(handle)
4306 Imager::Font::FT2 handle
4311 len = i_ft2_face_name(handle, name, sizeof(name));
4314 PUSHs(sv_2mortal(newSVpv(name, 0)));
4318 i_ft2_can_face_name()
4321 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4322 Imager::Font::FT2 handle
4334 if (SvUTF8(text_sv))
4337 text = SvPV(text_sv, work_len);
4342 ch = i_utf8_advance(&text, &len);
4344 i_push_error(0, "invalid UTF8 character");
4353 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name),
4355 PUSHs(sv_2mortal(newSVpv(name, 0)));
4358 PUSHs(&PL_sv_undef);
4363 i_ft2_can_do_glyph_names()
4366 i_ft2_face_has_glyph_names(handle)
4367 Imager::Font::FT2 handle
4370 i_ft2_is_multiple_master(handle)
4371 Imager::Font::FT2 handle
4374 i_ft2_get_multiple_masters(handle)
4375 Imager::Font::FT2 handle
4380 if (i_ft2_get_multiple_masters(handle, &mm)) {
4381 EXTEND(SP, 2+mm.num_axis);
4382 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4383 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4384 for (i = 0; i < mm.num_axis; ++i) {
4388 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4390 av_store(av, 0, sv);
4391 sv = newSViv(mm.axis[i].minimum);
4393 av_store(av, 1, sv);
4394 sv = newSViv(mm.axis[i].maximum);
4396 av_store(av, 2, sv);
4397 PUSHs(newRV_noinc((SV *)av));
4402 i_ft2_set_mm_coords(handle, ...)
4403 Imager::Font::FT2 handle
4409 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4410 transfer the array manually */
4411 ix_coords = items-1;
4412 coords = mymalloc(sizeof(long) * ix_coords);
4413 for (i = 0; i < ix_coords; ++i) {
4414 coords[i] = (long)SvIV(ST(1+i));
4416 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4423 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4427 Imager::FillHandle fill
4429 MODULE = Imager PACKAGE = Imager
4432 i_new_fill_solid(cl, combine)
4437 i_new_fill_solidf(cl, combine)
4438 Imager::Color::Float cl
4442 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4450 unsigned char *cust_hatch;
4454 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4458 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4463 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4464 Imager::Color::Float fg
4465 Imager::Color::Float bg
4471 unsigned char *cust_hatch;
4475 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4479 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4484 i_new_fill_image(src, matrix, xoff, yoff, combine)
4501 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4502 croak("i_new_fill_image: parameter must be an arrayref");
4503 av=(AV*)SvRV(ST(1));
4507 for (i = 0; i < len; ++i) {
4508 sv1=(*(av_fetch(av,i,0)));
4509 matrix[i] = SvNV(sv1);
4515 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4519 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4521 # this class is only exposed for testing
4524 i_int_hlines_testing()
4526 #if i_int_hlines_testing()
4528 Imager::Internal::Hlines
4529 i_int_hlines_new(start_y, count_y, start_x, count_x)
4535 Imager::Internal::Hlines
4536 i_int_hlines_new_img(im)
4540 i_int_hlines_add(hlines, y, minx, width)
4541 Imager::Internal::Hlines hlines
4547 i_int_hlines_DESTROY(hlines)
4548 Imager::Internal::Hlines hlines
4551 i_int_hlines_dump(hlines)
4552 Imager::Internal::Hlines hlines