12 #define i_int_hlines_testing() 1
20 typedef io_glue* Imager__IO;
22 #if i_int_hlines_testing()
28 /* These functions are all shared - then comes platform dependant code */
29 static int getstr(void *hv_t,char *key,char **store) {
33 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
35 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
37 svpp=hv_fetch(hv, key, strlen(key), 0);
38 *store=SvPV(*svpp, PL_na );
43 static int getint(void *hv_t,char *key,int *store) {
47 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
49 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
51 svpp=hv_fetch(hv, key, strlen(key), 0);
52 *store=(int)SvIV(*svpp);
56 static int getdouble(void *hv_t,char* key,double *store) {
60 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
62 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
63 svpp=hv_fetch(hv, key, strlen(key), 0);
64 *store=(float)SvNV(*svpp);
68 static int getvoid(void *hv_t,char* key,void **store) {
72 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
74 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
76 svpp=hv_fetch(hv, key, strlen(key), 0);
77 *store = INT2PTR(void*, SvIV(*svpp));
82 static int getobj(void *hv_t,char *key,char *type,void **store) {
86 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
88 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
90 svpp=hv_fetch(hv, key, strlen(key), 0);
92 if (sv_derived_from(*svpp,type)) {
93 IV tmp = SvIV((SV*)SvRV(*svpp));
94 *store = INT2PTR(void*, tmp);
96 mm_log((1,"getobj: key exists in hash but is not of correct type"));
103 UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
105 void my_SvREFCNT_dec(void *p) {
106 SvREFCNT_dec((SV*)p);
111 log_entry(char *string, int level) {
112 mm_log((level, string));
116 typedef struct i_reader_data_tag
118 /* presumably a CODE ref or name of a sub */
122 /* used by functions that want callbacks */
123 static int read_callback(char *userdata, char *buffer, int need, int want) {
124 i_reader_data *rd = (i_reader_data *)userdata;
128 dSP; dTARG = sv_newmortal();
129 /* thanks to Simon Cozens for help with the dTARG above */
139 count = perl_call_sv(rd->sv, G_SCALAR);
144 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
150 char *ptr = SvPV(data, len);
152 croak("Too much data returned in reader callback");
154 memcpy(buffer, ptr, len);
170 SV *sv; /* a coderef or sub name */
173 /* used by functions that want callbacks */
174 static int write_callback(char *userdata, char const *data, int size) {
175 i_writer_data *wd = (i_writer_data *)userdata;
185 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
188 count = perl_call_sv(wd->sv, G_SCALAR);
193 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
196 success = SvTRUE(sv);
206 #define CBDATA_BUFSIZE 8192
209 /* the SVs we use to call back to Perl */
215 /* we need to remember whether the buffer contains write data or
221 /* how far we've read into the buffer (not used for writing) */
224 /* the amount of space used/data available in the buffer */
227 /* the maximum amount to fill the buffer before flushing
228 If any write is larger than this then the buffer is flushed and
229 the full write is performed. The write is _not_ split into
234 char buffer[CBDATA_BUFSIZE];
239 call_writer(cbd, buf, size)
241 Low-level function to call the perl writer callback.
245 static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
251 if (!SvOK(cbd->writecb))
258 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
261 count = perl_call_sv(cbd->writecb, G_SCALAR);
265 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
268 success = SvTRUE(sv);
275 return success ? size : 0;
278 static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
285 if (!SvOK(cbd->readcb))
292 PUSHs(sv_2mortal(newSViv(size)));
293 PUSHs(sv_2mortal(newSViv(maxread)));
296 count = perl_call_sv(cbd->readcb, G_SCALAR);
301 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
307 char *ptr = SvPV(data, len);
309 croak("Too much data returned in reader callback");
311 memcpy(buf, ptr, len);
325 static ssize_t write_flush(struct cbdata *cbd) {
328 result = call_writer(cbd, cbd->buffer, cbd->used);
333 static off_t io_seeker(void *p, off_t offset, int whence) {
334 struct cbdata *cbd = p;
339 if (!SvOK(cbd->seekcb))
343 if (cbd->used && write_flush(cbd) <= 0)
347 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
348 offset -= cbd->where - cbd->used;
351 cbd->where = cbd->used = 0;
357 PUSHs(sv_2mortal(newSViv(offset)));
358 PUSHs(sv_2mortal(newSViv(whence)));
361 count = perl_call_sv(cbd->seekcb, G_SCALAR);
366 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
377 static ssize_t io_writer(void *p, void const *data, size_t size) {
378 struct cbdata *cbd = p;
380 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
382 if (cbd->reading && cbd->where < cbd->used) {
383 /* we read past the place where the caller expected us to be
384 so adjust our position a bit */
386 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
391 cbd->where = cbd->used = 0;
394 if (cbd->used && cbd->used + size > cbd->maxlength) {
395 if (write_flush(cbd) <= 0) {
400 if (cbd->used+size <= cbd->maxlength) {
401 memcpy(cbd->buffer + cbd->used, data, size);
405 /* it doesn't fit - just pass it up */
406 return call_writer(cbd, data, size);
409 static ssize_t io_reader(void *p, void *data, size_t size) {
410 struct cbdata *cbd = p;
412 char *out = data; /* so we can do pointer arithmetic */
415 if (write_flush(cbd) <= 0)
421 if (size <= cbd->used - cbd->where) {
423 memcpy(data, cbd->buffer+cbd->where, size);
428 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
429 total += cbd->used - cbd->where;
430 size -= cbd->used - cbd->where;
431 out += cbd->used - cbd->where;
432 if (size < sizeof(cbd->buffer)) {
436 && (did_read = call_reader(cbd, cbd->buffer, size,
437 sizeof(cbd->buffer))) > 0) {
439 cbd->used = did_read;
441 copy_size = i_min(size, cbd->used);
442 memcpy(out, cbd->buffer, copy_size);
443 cbd->where += copy_size;
450 /* just read the rest - too big for our buffer*/
452 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
462 static void io_closer(void *p) {
463 struct cbdata *cbd = p;
465 if (cbd->writing && cbd->used > 0) {
470 if (SvOK(cbd->closecb)) {
478 perl_call_sv(cbd->closecb, G_VOID);
487 static void io_destroyer(void *p) {
488 struct cbdata *cbd = p;
490 SvREFCNT_dec(cbd->writecb);
491 SvREFCNT_dec(cbd->readcb);
492 SvREFCNT_dec(cbd->seekcb);
493 SvREFCNT_dec(cbd->closecb);
501 static int lookup_name(struct value_name *names, int count, char *name, int def_value)
504 for (i = 0; i < count; ++i)
505 if (strEQ(names[i].name, name))
506 return names[i].value;
510 static struct value_name transp_names[] =
513 { "threshold", tr_threshold },
514 { "errdiff", tr_errdiff },
515 { "ordered", tr_ordered, },
518 static struct value_name make_color_names[] =
520 { "none", mc_none, },
521 { "webmap", mc_web_map, },
522 { "addi", mc_addi, },
523 { "mediancut", mc_median_cut, },
526 static struct value_name translate_names[] =
529 { "giflib", pt_giflib, },
531 { "closest", pt_closest, },
532 { "perturb", pt_perturb, },
533 { "errdiff", pt_errdiff, },
536 static struct value_name errdiff_names[] =
538 { "floyd", ed_floyd, },
539 { "jarvis", ed_jarvis, },
540 { "stucki", ed_stucki, },
541 { "custom", ed_custom, },
544 static struct value_name orddith_names[] =
546 { "random", od_random, },
547 { "dot8", od_dot8, },
548 { "dot4", od_dot4, },
549 { "hline", od_hline, },
550 { "vline", od_vline, },
551 { "/line", od_slashline, },
552 { "slashline", od_slashline, },
553 { "\\line", od_backline, },
554 { "backline", od_backline, },
555 { "tiny", od_tiny, },
556 { "custom", od_custom, },
559 /* look through the hash for quantization options */
560 static void handle_quant_opts(i_quantize *quant, HV *hv)
562 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
568 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
570 sv = hv_fetch(hv, "transp", 6, 0);
571 if (sv && *sv && (str = SvPV(*sv, len))) {
573 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
575 if (quant->transp != tr_none) {
576 quant->tr_threshold = 127;
577 sv = hv_fetch(hv, "tr_threshold", 12, 0);
579 quant->tr_threshold = SvIV(*sv);
581 if (quant->transp == tr_errdiff) {
582 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
583 if (sv && *sv && (str = SvPV(*sv, len)))
584 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
586 if (quant->transp == tr_ordered) {
587 quant->tr_orddith = od_tiny;
588 sv = hv_fetch(hv, "tr_orddith", 10, 0);
589 if (sv && *sv && (str = SvPV(*sv, len)))
590 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
592 if (quant->tr_orddith == od_custom) {
593 sv = hv_fetch(hv, "tr_map", 6, 0);
594 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
595 AV *av = (AV*)SvRV(*sv);
596 len = av_len(av) + 1;
597 if (len > sizeof(quant->tr_custom))
598 len = sizeof(quant->tr_custom);
599 for (i = 0; i < len; ++i) {
600 SV **sv2 = av_fetch(av, i, 0);
602 quant->tr_custom[i] = SvIV(*sv2);
605 while (i < sizeof(quant->tr_custom))
606 quant->tr_custom[i++] = 0;
611 quant->make_colors = mc_addi;
612 sv = hv_fetch(hv, "make_colors", 11, 0);
613 if (sv && *sv && (str = SvPV(*sv, len))) {
615 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
617 sv = hv_fetch(hv, "colors", 6, 0);
618 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
619 /* needs to be an array of Imager::Color
620 note that the caller allocates the mc_color array and sets mc_size
622 AV *av = (AV *)SvRV(*sv);
623 quant->mc_count = av_len(av)+1;
624 if (quant->mc_count > quant->mc_size)
625 quant->mc_count = quant->mc_size;
626 for (i = 0; i < quant->mc_count; ++i) {
627 SV **sv1 = av_fetch(av, i, 0);
628 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
629 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
630 quant->mc_colors[i] = *col;
634 sv = hv_fetch(hv, "max_colors", 10, 0);
637 if (i <= quant->mc_size && i >= quant->mc_count)
641 quant->translate = pt_closest;
642 sv = hv_fetch(hv, "translate", 9, 0);
643 if (sv && *sv && (str = SvPV(*sv, len))) {
644 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
646 sv = hv_fetch(hv, "errdiff", 7, 0);
647 if (sv && *sv && (str = SvPV(*sv, len))) {
648 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
650 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
651 /* get the error diffusion map */
652 sv = hv_fetch(hv, "errdiff_width", 13, 0);
654 quant->ed_width = SvIV(*sv);
655 sv = hv_fetch(hv, "errdiff_height", 14, 0);
657 quant->ed_height = SvIV(*sv);
658 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
660 quant->ed_orig = SvIV(*sv);
661 if (quant->ed_width > 0 && quant->ed_height > 0) {
663 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
664 sv = hv_fetch(hv, "errdiff_map", 11, 0);
665 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
666 AV *av = (AV*)SvRV(*sv);
667 len = av_len(av) + 1;
668 if (len > quant->ed_width * quant->ed_height)
669 len = quant->ed_width * quant->ed_height;
670 for (i = 0; i < len; ++i) {
671 SV **sv2 = av_fetch(av, i, 0);
673 quant->ed_map[i] = SvIV(*sv2);
674 sum += quant->ed_map[i];
680 myfree(quant->ed_map);
682 quant->errdiff = ed_floyd;
686 sv = hv_fetch(hv, "perturb", 7, 0);
688 quant->perturb = SvIV(*sv);
691 static void cleanup_quant_opts(i_quantize *quant) {
692 myfree(quant->mc_colors);
694 myfree(quant->ed_map);
697 /* copies the color map from the hv into the colors member of the HV */
698 static void copy_colors_back(HV *hv, i_quantize *quant) {
704 sv = hv_fetch(hv, "colors", 6, 0);
705 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
708 ref = newRV_inc((SV*) av);
709 sv = hv_store(hv, "colors", 6, ref, 0);
712 av = (AV *)SvRV(*sv);
714 av_extend(av, quant->mc_count+1);
715 for (i = 0; i < quant->mc_count; ++i) {
716 i_color *in = quant->mc_colors+i;
717 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
718 work = sv_newmortal();
719 sv_setref_pv(work, "Imager::Color", (void *)c);
721 if (!av_store(av, i, work)) {
727 /* loads the segments of a fountain fill into an array */
728 static i_fountain_seg *
729 load_fount_segs(AV *asegs, int *count) {
730 /* Each element of segs must contain:
731 [ start, middle, end, c0, c1, segtype, colortrans ]
732 start, middle, end are doubles from 0 to 1
733 c0, c1 are Imager::Color::Float or Imager::Color objects
734 segtype, colortrans are ints
738 i_fountain_seg *segs;
742 *count = av_len(asegs)+1;
744 croak("i_fountain must have at least one segment");
745 segs = mymalloc(sizeof(i_fountain_seg) * *count);
746 for(i = 0; i < *count; i++) {
747 SV **sv1 = av_fetch(asegs, i, 0);
748 if (!sv1 || !*sv1 || !SvROK(*sv1)
749 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
751 croak("i_fountain: segs must be an arrayref of arrayrefs");
753 aseg = (AV *)SvRV(*sv1);
754 if (av_len(aseg) != 7-1) {
756 croak("i_fountain: a segment must have 7 members");
758 for (j = 0; j < 3; ++j) {
759 SV **sv2 = av_fetch(aseg, j, 0);
762 croak("i_fountain: XS error");
764 work[j] = SvNV(*sv2);
766 segs[i].start = work[0];
767 segs[i].middle = work[1];
768 segs[i].end = work[2];
769 for (j = 0; j < 2; ++j) {
770 SV **sv3 = av_fetch(aseg, 3+j, 0);
771 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
772 (!sv_derived_from(*sv3, "Imager::Color")
773 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
775 croak("i_fountain: segs must contain colors in elements 3 and 4");
777 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
778 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
781 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
783 for (ch = 0; ch < MAXCHANNELS; ++ch) {
784 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
788 for (j = 0; j < 2; ++j) {
789 SV **sv2 = av_fetch(aseg, j+5, 0);
792 croak("i_fountain: XS error");
794 worki[j] = SvIV(*sv2);
796 segs[i].type = worki[0];
797 segs[i].color = worki[1];
803 /* I don't think ICLF_* names belong at the C interface
804 this makes the XS code think we have them, to let us avoid
805 putting function bodies in the XS code
807 #define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
808 #define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
811 /* the m_init_log() function was called init_log(), renamed to reduce
812 potential naming conflicts */
813 #define init_log m_init_log
815 #if i_int_hlines_testing()
817 typedef i_int_hlines *Imager__Internal__Hlines;
819 static i_int_hlines *
820 i_int_hlines_new(int start_y, int count_y, int start_x, int count_x) {
821 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
822 i_int_init_hlines(result, start_y, count_y, start_x, count_x);
827 static i_int_hlines *
828 i_int_hlines_new_img(i_img *im) {
829 i_int_hlines *result = mymalloc(sizeof(i_int_hlines));
830 i_int_init_hlines_img(result, im);
836 i_int_hlines_DESTROY(i_int_hlines *hlines) {
837 i_int_hlines_destroy(hlines);
841 static int seg_compare(const void *vleft, const void *vright) {
842 const i_int_hline_seg *left = vleft;
843 const i_int_hline_seg *right = vright;
845 return left->minx - right->minx;
849 i_int_hlines_dump(i_int_hlines *hlines) {
850 SV *dump = newSVpvf("start_y: %d limit_y: %d start_x: %d limit_x: %d\n",
851 hlines->start_y, hlines->limit_y, hlines->start_x, hlines->limit_x);
854 for (y = hlines->start_y; y < hlines->limit_y; ++y) {
855 i_int_hline_entry *entry = hlines->entries[y-hlines->start_y];
858 /* sort the segments, if any */
860 qsort(entry->segs, entry->count, sizeof(i_int_hline_seg), seg_compare);
862 sv_catpvf(dump, " %d (%d):", y, entry->count);
863 for (i = 0; i < entry->count; ++i) {
864 sv_catpvf(dump, " [%d, %d)", entry->segs[i].minx,
865 entry->segs[i].x_limit);
867 sv_catpv(dump, "\n");
877 #define i_exif_enabled() 1
879 #define i_exif_enabled() 0
882 MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
885 ICL_new_internal(r,g,b,a)
897 ICL_set_internal(cl,r,g,b,a)
904 ICL_set_internal(cl, r, g, b, a);
918 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
919 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
920 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
921 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
927 RETVAL = mymalloc(sizeof(i_color));
929 i_hsv_to_rgb(RETVAL);
937 RETVAL = mymalloc(sizeof(i_color));
939 i_rgb_to_hsv(RETVAL);
945 MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
948 ICLF_new_internal(r, g, b, a)
956 Imager::Color::Float cl
960 Imager::Color::Float cl
964 EXTEND(SP, MAXCHANNELS);
965 for (ch = 0; ch < MAXCHANNELS; ++ch) {
966 /* printf("%d: %g\n", ch, cl->channel[ch]); */
967 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
971 ICLF_set_internal(cl,r,g,b,a)
972 Imager::Color::Float cl
987 Imager::Color::Float c
989 RETVAL = mymalloc(sizeof(i_fcolor));
991 i_hsv_to_rgbf(RETVAL);
997 Imager::Color::Float c
999 RETVAL = mymalloc(sizeof(i_fcolor));
1001 i_rgb_to_hsvf(RETVAL);
1005 MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1019 MODULE = Imager PACKAGE = Imager
1038 SvPV(ST(0), length);
1039 SvREFCNT_inc(ST(0));
1040 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1045 io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1054 cbd = mymalloc(sizeof(struct cbdata));
1055 SvREFCNT_inc(writecb);
1056 cbd->writecb = writecb;
1057 SvREFCNT_inc(readcb);
1058 cbd->readcb = readcb;
1059 SvREFCNT_inc(seekcb);
1060 cbd->seekcb = seekcb;
1061 SvREFCNT_inc(closecb);
1062 cbd->closecb = closecb;
1063 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1064 if (maxwrite > CBDATA_BUFSIZE)
1065 maxwrite = CBDATA_BUFSIZE;
1066 cbd->maxlength = maxwrite;
1067 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1076 unsigned char* data;
1080 tlength = io_slurp(ig, &data);
1082 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
1087 i_set_image_file_limits(width, height, bytes)
1093 i_get_image_file_limits()
1095 int width, height, bytes;
1097 if (i_get_image_file_limits(&width, &height, &bytes)) {
1099 PUSHs(sv_2mortal(newSViv(width)));
1100 PUSHs(sv_2mortal(newSViv(height)));
1101 PUSHs(sv_2mortal(newSViv(bytes)));
1104 MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1111 MODULE = Imager PACKAGE = Imager
1124 while( (item=i_format_list[i++]) != NULL ) {
1126 PUSHs(sv_2mortal(newSVpv(item,0)));
1143 i_img_empty_ch(im,x,y,ch)
1150 i_sametype(im, x, y)
1156 i_sametype_chans(im, x, y, channels)
1163 m_init_log(name,level)
1168 log_entry(string,level)
1187 i_img_info(im,info);
1189 PUSHs(sv_2mortal(newSViv(info[0])));
1190 PUSHs(sv_2mortal(newSViv(info[1])));
1191 PUSHs(sv_2mortal(newSViv(info[2])));
1192 PUSHs(sv_2mortal(newSViv(info[3])));
1198 i_img_setmask(im,ch_mask)
1207 i_img_getchannels(im)
1216 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
1221 i_line(im,x1,y1,x2,y2,val,endp)
1231 i_line_aa(im,x1,y1,x2,y2,val,endp)
1241 i_box(im,x1,y1,x2,y2,val)
1250 i_box_filled(im,x1,y1,x2,y2,val)
1259 i_box_cfill(im,x1,y1,x2,y2,fill)
1265 Imager::FillHandle fill
1268 i_arc(im,x,y,rad,d1,d2,val)
1278 i_arc_aa(im,x,y,rad,d1,d2,val)
1288 i_arc_cfill(im,x,y,rad,d1,d2,fill)
1295 Imager::FillHandle fill
1298 i_arc_aa_cfill(im,x,y,rad,d1,d2,fill)
1305 Imager::FillHandle fill
1309 i_circle_aa(im,x,y,rad,val)
1319 i_bezier_multi(im,xc,yc,val)
1332 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1333 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
1334 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1335 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
1336 av1=(AV*)SvRV(ST(1));
1337 av2=(AV*)SvRV(ST(2));
1338 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
1340 x=mymalloc( len*sizeof(double) );
1341 y=mymalloc( len*sizeof(double) );
1342 for(i=0;i<len;i++) {
1343 sv1=(*(av_fetch(av1,i,0)));
1344 sv2=(*(av_fetch(av2,i,0)));
1345 x[i]=(double)SvNV(sv1);
1346 y[i]=(double)SvNV(sv2);
1348 i_bezier_multi(im,len,x,y,val);
1354 i_poly_aa(im,xc,yc,val)
1367 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1368 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1369 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1370 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
1371 av1=(AV*)SvRV(ST(1));
1372 av2=(AV*)SvRV(ST(2));
1373 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
1375 x=mymalloc( len*sizeof(double) );
1376 y=mymalloc( len*sizeof(double) );
1377 for(i=0;i<len;i++) {
1378 sv1=(*(av_fetch(av1,i,0)));
1379 sv2=(*(av_fetch(av2,i,0)));
1380 x[i]=(double)SvNV(sv1);
1381 y[i]=(double)SvNV(sv2);
1383 i_poly_aa(im,len,x,y,val);
1388 i_poly_aa_cfill(im,xc,yc,fill)
1390 Imager::FillHandle fill
1400 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1401 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1402 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1403 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1404 av1=(AV*)SvRV(ST(1));
1405 av2=(AV*)SvRV(ST(2));
1406 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1408 x=mymalloc( len*sizeof(double) );
1409 y=mymalloc( len*sizeof(double) );
1410 for(i=0;i<len;i++) {
1411 sv1=(*(av_fetch(av1,i,0)));
1412 sv2=(*(av_fetch(av2,i,0)));
1413 x[i]=(double)SvNV(sv1);
1414 y[i]=(double)SvNV(sv2);
1416 i_poly_aa_cfill(im,len,x,y,fill);
1423 i_flood_fill(im,seedx,seedy,dcol)
1430 i_flood_cfill(im,seedx,seedy,fill)
1434 Imager::FillHandle fill
1438 i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1450 i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1467 i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
1479 i_flipxy(im, direction)
1484 i_rotate90(im, degrees)
1489 i_rotate_exact(im, amount, ...)
1493 i_color *backp = NULL;
1494 i_fcolor *fbackp = NULL;
1498 /* extract the bg colors if any */
1499 /* yes, this is kind of strange */
1500 for (i = 2; i < items; ++i) {
1502 if (sv_derived_from(sv1, "Imager::Color")) {
1503 IV tmp = SvIV((SV*)SvRV(sv1));
1504 backp = INT2PTR(i_color *, tmp);
1506 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1507 IV tmp = SvIV((SV*)SvRV(sv1));
1508 fbackp = INT2PTR(i_fcolor *, tmp);
1511 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1516 i_matrix_transform(im, xsize, ysize, matrix, ...)
1526 i_color *backp = NULL;
1527 i_fcolor *fbackp = NULL;
1529 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1530 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1531 av=(AV*)SvRV(ST(3));
1535 for (i = 0; i < len; ++i) {
1536 sv1=(*(av_fetch(av,i,0)));
1537 matrix[i] = SvNV(sv1);
1541 /* extract the bg colors if any */
1542 /* yes, this is kind of strange */
1543 for (i = 4; i < items; ++i) {
1545 if (sv_derived_from(sv1, "Imager::Color")) {
1546 IV tmp = SvIV((SV*)SvRV(sv1));
1547 backp = INT2PTR(i_color *, tmp);
1549 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1550 IV tmp = SvIV((SV*)SvRV(sv1));
1551 fbackp = INT2PTR(i_fcolor *, tmp);
1554 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
1559 i_gaussian(im,stdev)
1564 i_unsharp_mask(im,stdev,scale)
1579 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1580 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1581 av=(AV*)SvRV(ST(1));
1583 coeff=mymalloc( len*sizeof(float) );
1584 for(i=0;i<len;i++) {
1585 sv1=(*(av_fetch(av,i,0)));
1586 coeff[i]=(float)SvNV(sv1);
1588 i_conv(im,coeff,len);
1592 i_convert(im, src, coeff)
1605 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1606 croak("i_convert: parameter 3 must be an arrayref\n");
1607 avmain = (AV*)SvRV(ST(2));
1608 outchan = av_len(avmain)+1;
1609 /* find the biggest */
1611 for (j=0; j < outchan; ++j) {
1612 temp = av_fetch(avmain, j, 0);
1613 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1614 avsub = (AV*)SvRV(*temp);
1615 len = av_len(avsub)+1;
1620 coeff = mymalloc(sizeof(float) * outchan * inchan);
1621 for (j = 0; j < outchan; ++j) {
1622 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1623 len = av_len(avsub)+1;
1624 for (i = 0; i < len; ++i) {
1625 temp = av_fetch(avsub, i, 0);
1627 coeff[i+j*inchan] = SvNV(*temp);
1629 coeff[i+j*inchan] = 0;
1632 coeff[i++ + j*inchan] = 0;
1634 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1644 unsigned int mask = 0;
1650 unsigned char (*maps)[256];
1652 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1653 croak("i_map: parameter 2 must be an arrayref\n");
1654 avmain = (AV*)SvRV(ST(1));
1655 len = av_len(avmain)+1;
1656 if (im->channels < len) len = im->channels;
1658 maps = mymalloc( len * sizeof(unsigned char [256]) );
1660 for (j=0; j<len ; j++) {
1661 temp = av_fetch(avmain, j, 0);
1662 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1663 avsub = (AV*)SvRV(*temp);
1664 if(av_len(avsub) != 255) continue;
1666 for (i=0; i<256 ; i++) {
1668 temp = av_fetch(avsub, i, 0);
1669 val = temp ? SvIV(*temp) : 0;
1671 if (val>255) val = 255;
1676 i_map(im, maps, mask);
1689 i_init_fonts(t1log=0)
1704 i_t1_destroy(font_id)
1709 i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1728 str = SvPV(str_sv, len);
1729 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1736 i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
1745 int cords[BOUNDING_BOX_COUNT];
1753 str = SvPV(str_sv, len);
1754 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1757 for (i = 0; i < rc; ++i)
1758 PUSHs(sv_2mortal(newSViv(cords[i])));
1764 i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
1783 str = SvPV(str_sv, len);
1784 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1790 i_t1_has_chars(handle, text_sv, utf8 = 0)
1802 if (SvUTF8(text_sv))
1805 text = SvPV(text_sv, len);
1806 work = mymalloc(len);
1807 count = i_t1_has_chars(handle, text, len, utf8, work);
1808 if (GIMME_V == G_ARRAY) {
1810 for (i = 0; i < count; ++i) {
1811 PUSHs(sv_2mortal(newSViv(work[i])));
1816 PUSHs(sv_2mortal(newSVpv(work, count)));
1821 i_t1_face_name(handle)
1827 len = i_t1_face_name(handle, name, sizeof(name));
1830 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1834 i_t1_glyph_name(handle, text_sv, utf8 = 0)
1845 if (SvUTF8(text_sv))
1848 text = SvPV(text_sv, work_len);
1853 ch = i_utf8_advance(&text, &len);
1855 i_push_error(0, "invalid UTF8 character");
1864 if (i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1865 PUSHs(sv_2mortal(newSVpv(name, 0)));
1868 PUSHs(&PL_sv_undef);
1882 MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1884 #define TT_DESTROY(handle) i_tt_destroy(handle)
1888 Imager::Font::TT handle
1891 MODULE = Imager PACKAGE = Imager
1895 i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8,align=1)
1896 Imager::Font::TT handle
1914 str = SvPV(str_sv, len);
1915 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1916 len, smooth, utf8, align);
1922 i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8,align=1)
1923 Imager::Font::TT handle
1941 str = SvPV(str_sv, len);
1942 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1943 smooth, utf8, align);
1949 i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
1950 Imager::Font::TT handle
1955 int cords[BOUNDING_BOX_COUNT],rc;
1964 str = SvPV(str_sv, len);
1965 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
1967 for (i = 0; i < rc; ++i) {
1968 PUSHs(sv_2mortal(newSViv(cords[i])));
1973 i_tt_has_chars(handle, text_sv, utf8)
1974 Imager::Font::TT handle
1985 if (SvUTF8(text_sv))
1988 text = SvPV(text_sv, len);
1989 work = mymalloc(len);
1990 count = i_tt_has_chars(handle, text, len, utf8, work);
1991 if (GIMME_V == G_ARRAY) {
1993 for (i = 0; i < count; ++i) {
1994 PUSHs(sv_2mortal(newSViv(work[i])));
1999 PUSHs(sv_2mortal(newSVpv(work, count)));
2004 i_tt_dump_names(handle)
2005 Imager::Font::TT handle
2008 i_tt_face_name(handle)
2009 Imager::Font::TT handle
2014 len = i_tt_face_name(handle, name, sizeof(name));
2017 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2021 i_tt_glyph_name(handle, text_sv, utf8 = 0)
2022 Imager::Font::TT handle
2033 if (SvUTF8(text_sv))
2036 text = SvPV(text_sv, work_len);
2041 ch = i_utf8_advance(&text, &len);
2043 i_push_error(0, "invalid UTF8 character");
2052 if ((outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) != 0) {
2053 PUSHs(sv_2mortal(newSVpv(name, 0)));
2056 PUSHs(&PL_sv_undef);
2065 i_writejpeg_wiol(im, ig, qfactor)
2081 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2082 if (iptc_itext == NULL) {
2085 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2090 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2092 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2103 i_test_format_probe(ig, length)
2112 i_readtiff_wiol(ig, length, page=0)
2118 i_readtiff_multi_wiol(ig, length)
2126 imgs = i_readtiff_multi_wiol(ig, length, &count);
2129 for (i = 0; i < count; ++i) {
2130 SV *sv = sv_newmortal();
2131 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2139 i_writetiff_wiol(im, ig)
2144 i_writetiff_multi_wiol(ig, ...)
2152 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2153 img_count = items - 1;
2155 if (img_count < 1) {
2158 i_push_error(0, "You need to specify images to save");
2161 imgs = mymalloc(sizeof(i_img *) * img_count);
2162 for (i = 0; i < img_count; ++i) {
2165 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2166 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2170 i_push_error(0, "Only images can be saved");
2177 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2185 i_writetiff_wiol_faxable(im, ig, fine)
2191 i_writetiff_multi_wiol_faxable(ig, fine, ...)
2200 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2201 img_count = items - 2;
2203 if (img_count < 1) {
2206 i_push_error(0, "You need to specify images to save");
2209 imgs = mymalloc(sizeof(i_img *) * img_count);
2210 for (i = 0; i < img_count; ++i) {
2213 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2214 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2218 i_push_error(0, "Only images can be saved");
2225 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2233 #endif /* HAVE_LIBTIFF */
2239 i_readpng_wiol(ig, length)
2245 i_writepng_wiol(im, ig)
2258 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2261 i_writegif(im,fd,colors,pixdev,fixed)
2268 Imager__Color fixed;
2275 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2276 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2277 av=(AV*)SvRV(ST(4));
2278 fixedlen=av_len(av)+1;
2279 fixed=mymalloc( fixedlen*sizeof(i_color) );
2280 for(i=0;i<fixedlen;i++) {
2281 sv1=(*(av_fetch(av,i,0)));
2282 if (sv_derived_from(sv1, "Imager::Color")) {
2283 Itmp = SvIV((SV*)SvRV(sv1));
2284 tmp = INT2PTR(i_color*, Itmp);
2285 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2288 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2290 ST(0) = sv_newmortal();
2291 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2292 else sv_setiv(ST(0), (IV)RETVAL);
2298 i_writegifmc(im,fd,colors)
2305 i_writegif_gen(fd, ...)
2310 i_img **imgs = NULL;
2316 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2317 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2318 croak("i_writegif_gen: Second argument must be a hash ref");
2319 hv = (HV *)SvRV(ST(1));
2320 memset(&quant, 0, sizeof(quant));
2321 quant.mc_size = 256;
2322 handle_quant_opts(&quant, hv);
2323 img_count = items - 2;
2325 if (img_count < 1) {
2328 i_push_error(0, "You need to specify images to save");
2331 imgs = mymalloc(sizeof(i_img *) * img_count);
2332 for (i = 0; i < img_count; ++i) {
2335 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2336 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2340 i_push_error(0, "Only images can be saved");
2346 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
2350 copy_colors_back(hv, &quant);
2353 ST(0) = sv_newmortal();
2354 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2355 else sv_setiv(ST(0), (IV)RETVAL);
2356 cleanup_quant_opts(&quant);
2360 i_writegif_callback(cb, maxbuffer,...)
2364 i_img **imgs = NULL;
2371 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2372 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2373 croak("i_writegif_callback: Second argument must be a hash ref");
2374 hv = (HV *)SvRV(ST(2));
2375 memset(&quant, 0, sizeof(quant));
2376 quant.mc_size = 256;
2377 handle_quant_opts(&quant, hv);
2378 img_count = items - 3;
2380 if (img_count < 1) {
2384 imgs = mymalloc(sizeof(i_img *) * img_count);
2385 for (i = 0; i < img_count; ++i) {
2388 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2389 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2398 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
2402 copy_colors_back(hv, &quant);
2405 ST(0) = sv_newmortal();
2406 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2407 else sv_setiv(ST(0), (IV)RETVAL);
2408 cleanup_quant_opts(&quant);
2411 i_writegif_wiol(ig, opts,...)
2415 i_img **imgs = NULL;
2421 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2422 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2423 croak("i_writegif_callback: Second argument must be a hash ref");
2424 hv = (HV *)SvRV(ST(1));
2425 memset(&quant, 0, sizeof(quant));
2426 quant.mc_size = 256;
2427 handle_quant_opts(&quant, hv);
2428 img_count = items - 2;
2430 if (img_count < 1) {
2434 imgs = mymalloc(sizeof(i_img *) * img_count);
2435 for (i = 0; i < img_count; ++i) {
2438 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
2439 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
2447 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
2451 copy_colors_back(hv, &quant);
2454 ST(0) = sv_newmortal();
2455 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2456 else sv_setiv(ST(0), (IV)RETVAL);
2457 cleanup_quant_opts(&quant);
2470 colour_table = NULL;
2473 if(GIMME_V == G_ARRAY) {
2474 rimg = i_readgif(fd,&colour_table,&colours);
2476 /* don't waste time with colours if they aren't wanted */
2477 rimg = i_readgif(fd,NULL,NULL);
2480 if (colour_table == NULL) {
2483 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2486 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2487 /* I don't know if I have the reference counts right or not :( */
2488 /* Neither do I :-) */
2489 /* No Idea here either */
2492 av_extend(ct, colours);
2493 for(q=0; q<colours; q++) {
2495 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2496 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2498 myfree(colour_table);
2502 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2504 PUSHs(newRV_noinc((SV*)ct));
2518 colour_table = NULL;
2521 if(GIMME_V == G_ARRAY) {
2522 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2524 /* don't waste time with colours if they aren't wanted */
2525 rimg = i_readgif_wiol(ig,NULL,NULL);
2528 if (colour_table == NULL) {
2531 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2534 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2535 /* I don't know if I have the reference counts right or not :( */
2536 /* Neither do I :-) */
2537 /* No Idea here either */
2540 av_extend(ct, colours);
2541 for(q=0; q<colours; q++) {
2543 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2544 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2546 myfree(colour_table);
2550 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2552 PUSHs(newRV_noinc((SV*)ct));
2556 i_readgif_single_wiol(ig, page=0)
2561 i_readgif_scalar(...)
2573 data = (char *)SvPV(ST(0), length);
2577 if(GIMME_V == G_ARRAY) {
2578 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2580 /* don't waste time with colours if they aren't wanted */
2581 rimg=i_readgif_scalar(data,length,NULL,NULL);
2584 if (colour_table == NULL) {
2587 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2590 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2591 /* I don't know if I have the reference counts right or not :( */
2592 /* Neither do I :-) */
2594 av_extend(ct, colours);
2595 for(q=0; q<colours; q++) {
2597 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2598 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2600 myfree(colour_table);
2604 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2606 PUSHs(newRV_noinc((SV*)ct));
2610 i_readgif_callback(...)
2625 if(GIMME_V == G_ARRAY) {
2626 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2628 /* don't waste time with colours if they aren't wanted */
2629 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2632 if (colour_table == NULL) {
2635 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2638 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2639 /* I don't know if I have the reference counts right or not :( */
2640 /* Neither do I :-) */
2641 /* Neither do I - maybe I'll move this somewhere */
2643 av_extend(ct, colours);
2644 for(q=0; q<colours; q++) {
2646 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2647 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2649 myfree(colour_table);
2653 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2655 PUSHs(newRV_noinc((SV*)ct));
2666 imgs = i_readgif_multi(fd, &count);
2669 for (i = 0; i < count; ++i) {
2670 SV *sv = sv_newmortal();
2671 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2678 i_readgif_multi_scalar(data)
2686 data = (char *)SvPV(ST(0), length);
2687 imgs = i_readgif_multi_scalar(data, length, &count);
2690 for (i = 0; i < count; ++i) {
2691 SV *sv = sv_newmortal();
2692 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2699 i_readgif_multi_callback(cb)
2707 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2710 for (i = 0; i < count; ++i) {
2711 SV *sv = sv_newmortal();
2712 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2719 i_readgif_multi_wiol(ig)
2726 imgs = i_readgif_multi_wiol(ig, &count);
2729 for (i = 0; i < count; ++i) {
2730 SV *sv = sv_newmortal();
2731 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2743 i_readpnm_wiol(ig, length)
2749 i_writeppm_wiol(im, ig)
2755 i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2764 i_writeraw_wiol(im,ig)
2769 i_writebmp_wiol(im,ig)
2779 i_writetga_wiol(im,ig, wierdpack, compress, idstring)
2788 idlen = SvCUR(ST(4));
2789 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2795 i_readtga_wiol(ig, length)
2801 i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2810 idlen = SvCUR(ST(4));
2811 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2817 i_readrgb_wiol(ig, length)
2824 i_scaleaxis(im,Value,Axis)
2830 i_scale_nn(im,scx,scy)
2840 i_count_colors(im,maxc)
2846 i_transform(im,opx,opy,parm)
2859 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2860 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2861 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2862 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2863 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2864 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2865 av=(AV*)SvRV(ST(1));
2867 opx=mymalloc( opxl*sizeof(int) );
2868 for(i=0;i<opxl;i++) {
2869 sv1=(*(av_fetch(av,i,0)));
2870 opx[i]=(int)SvIV(sv1);
2872 av=(AV*)SvRV(ST(2));
2874 opy=mymalloc( opyl*sizeof(int) );
2875 for(i=0;i<opyl;i++) {
2876 sv1=(*(av_fetch(av,i,0)));
2877 opy[i]=(int)SvIV(sv1);
2879 av=(AV*)SvRV(ST(3));
2880 parmlen=av_len(av)+1;
2881 parm=mymalloc( parmlen*sizeof(double) );
2882 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2883 sv1=(*(av_fetch(av,i,0)));
2884 parm[i]=(double)SvNV(sv1);
2886 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2890 ST(0) = sv_newmortal();
2891 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2892 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2895 i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2920 in_imgs_count = av_len(av_in_imgs)+1;
2921 for (i = 0; i < in_imgs_count; ++i) {
2922 sv1 = *av_fetch(av_in_imgs, i, 0);
2923 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2924 croak("sv_in_img must contain only images");
2927 if (in_imgs_count > 0) {
2928 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2929 for (i = 0; i < in_imgs_count; ++i) {
2930 sv1 = *av_fetch(av_in_imgs,i,0);
2931 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2932 croak("Parameter 5 must contain only images");
2934 tmp = SvIV((SV*)SvRV(sv1));
2935 in_imgs[i] = INT2PTR(i_img*, tmp);
2939 /* no input images */
2942 /* default the output size from the first input if possible */
2944 width = SvIV(sv_width);
2945 else if (in_imgs_count)
2946 width = in_imgs[0]->xsize;
2948 croak("No output image width supplied");
2950 if (SvOK(sv_height))
2951 height = SvIV(sv_height);
2952 else if (in_imgs_count)
2953 height = in_imgs[0]->ysize;
2955 croak("No output image height supplied");
2957 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
2958 if (ops_len % sizeof(struct rm_op))
2959 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2960 ops_count = ops_len / sizeof(struct rm_op);
2962 n_regs_count = av_len(av_n_regs)+1;
2963 n_regs = mymalloc(n_regs_count * sizeof(double));
2964 for (i = 0; i < n_regs_count; ++i) {
2965 sv1 = *av_fetch(av_n_regs,i,0);
2967 n_regs[i] = SvNV(sv1);
2969 c_regs_count = av_len(av_c_regs)+1;
2970 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2971 /* I don't bother initializing the colou?r registers */
2973 RETVAL=i_transform2(width, height, channels, ops, ops_count,
2974 n_regs, n_regs_count,
2975 c_regs, c_regs_count, in_imgs, in_imgs_count);
2980 ST(0) = sv_newmortal();
2981 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2982 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2986 i_contrast(im,intensity)
2995 i_noise(im,amount,type)
3001 i_bumpmap(im,bump,channel,light_x,light_y,strength)
3011 i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3030 i_postlevels(im,levels)
3040 i_watermark(im,wmark,tx,ty,pixdiff)
3042 Imager::ImgRaw wmark
3049 i_autolevels(im,lsat,usat,skew)
3056 i_radnoise(im,xo,yo,rscale,ascale)
3064 i_turbnoise(im, xo, yo, scale)
3087 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3088 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3089 croak("i_gradgen: Second argument must be an array ref");
3090 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3091 croak("i_gradgen: Third argument must be an array ref");
3092 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3093 croak("i_gradgen: Fourth argument must be an array ref");
3094 axx = (AV *)SvRV(ST(1));
3095 ayy = (AV *)SvRV(ST(2));
3096 ac = (AV *)SvRV(ST(3));
3097 dmeasure = (int)SvIV(ST(4));
3099 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3100 num = num <= av_len(ac) ? num : av_len(ac);
3102 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3103 xo = mymalloc( sizeof(int) * num );
3104 yo = mymalloc( sizeof(int) * num );
3105 ival = mymalloc( sizeof(i_color) * num );
3106 for(i = 0; i<num; i++) {
3107 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3108 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3109 sv = *av_fetch(ac, i, 0);
3110 if ( !sv_derived_from(sv, "Imager::Color") ) {
3111 free(axx); free(ayy); free(ac);
3112 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3114 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3116 i_gradgen(im, num, xo, yo, ival, dmeasure);
3122 i_diff_image(im, im2, mindist=0)
3128 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3138 double ssample_param
3142 i_fountain_seg *segs;
3144 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3145 croak("i_fountain: argument 11 must be an array ref");
3147 asegs = (AV *)SvRV(ST(10));
3148 segs = load_fount_segs(asegs, &count);
3149 RETVAL = i_fountain(im, xa, ya, xb, yb, type, repeat, combine,
3150 super_sample, ssample_param, count, segs);
3156 i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3165 double ssample_param
3169 i_fountain_seg *segs;
3171 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3172 croak("i_fountain: argument 11 must be an array ref");
3174 asegs = (AV *)SvRV(ST(9));
3175 segs = load_fount_segs(asegs, &count);
3176 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3177 super_sample, ssample_param, count, segs);
3190 errors = i_errors();
3192 while (errors[i].msg) {
3194 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3195 if (!av_store(av, 0, sv)) {
3198 sv = newSViv(errors[i].code);
3199 if (!av_store(av, 1, sv)) {
3202 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3207 i_nearest_color(im, ...)
3222 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3223 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3224 croak("i_nearest_color: Second argument must be an array ref");
3225 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3226 croak("i_nearest_color: Third argument must be an array ref");
3227 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3228 croak("i_nearest_color: Fourth argument must be an array ref");
3229 axx = (AV *)SvRV(ST(1));
3230 ayy = (AV *)SvRV(ST(2));
3231 ac = (AV *)SvRV(ST(3));
3232 dmeasure = (int)SvIV(ST(4));
3234 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3235 num = num <= av_len(ac) ? num : av_len(ac);
3237 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3238 xo = mymalloc( sizeof(int) * num );
3239 yo = mymalloc( sizeof(int) * num );
3240 ival = mymalloc( sizeof(i_color) * num );
3241 for(i = 0; i<num; i++) {
3242 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3243 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3244 sv = *av_fetch(ac, i, 0);
3245 if ( !sv_derived_from(sv, "Imager::Color") ) {
3246 free(axx); free(ayy); free(ac);
3247 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3249 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
3251 RETVAL = i_nearest_color(im, num, xo, yo, ival, dmeasure);
3264 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3265 hv=(HV*)SvRV(ST(0));
3266 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3267 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3268 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3277 rc=DSO_open(filename,&evstr);
3281 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3282 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3285 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
3291 DSO_close(dso_handle)
3295 DSO_funclist(dso_handle_v)
3299 DSO_handle *dso_handle;
3301 dso_handle=(DSO_handle*)dso_handle_v;
3303 while( dso_handle->function_list[i].name != NULL) {
3305 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3307 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3312 DSO_call(handle,func_index,hv)
3318 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3319 hv=(HV*)SvRV(ST(2));
3320 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3321 DSO_call( (DSO_handle *)handle,func_index,hv);
3326 i_get_pixel(im, x, y)
3333 color = (i_color *)mymalloc(sizeof(i_color));
3334 if (i_gpix(im, x, y, color) == 0) {
3335 RETVAL = NEWSV(0, 0);
3336 sv_setref_pv(RETVAL, "Imager::Color", (void *)color);
3340 RETVAL = &PL_sv_undef;
3347 i_ppix(im, x, y, cl)
3354 i_img_pal_new(x, y, channels, maxpal)
3361 i_img_to_pal(src, quant)
3367 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3368 croak("i_img_to_pal: second argument must be a hash ref");
3369 hv = (HV *)SvRV(ST(1));
3370 memset(&quant, 0, sizeof(quant));
3371 quant.mc_size = 256;
3372 handle_quant_opts(&quant, hv);
3373 RETVAL = i_img_to_pal(src, &quant);
3375 copy_colors_back(hv, &quant);
3377 cleanup_quant_opts(&quant);
3396 work = mymalloc((r-l) * sizeof(i_palidx));
3397 count = i_gpal(im, l, r, y, work);
3398 if (GIMME_V == G_ARRAY) {
3400 for (i = 0; i < count; ++i) {
3401 PUSHs(sv_2mortal(newSViv(work[i])));
3406 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
3411 if (GIMME_V != G_ARRAY) {
3413 PUSHs(&PL_sv_undef);
3418 i_ppal(im, l, y, ...)
3427 work = mymalloc(sizeof(i_palidx) * (items-3));
3428 for (i=0; i < items-3; ++i) {
3429 work[i] = SvIV(ST(i+3));
3431 RETVAL = i_ppal(im, l, l+items-3, y, work);
3441 i_addcolors(im, ...)
3449 croak("i_addcolors: no colors to add");
3450 colors = mymalloc((items-1) * sizeof(i_color));
3451 for (i=0; i < items-1; ++i) {
3452 if (sv_isobject(ST(i+1))
3453 && sv_derived_from(ST(i+1), "Imager::Color")) {
3454 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
3455 colors[i] = *INT2PTR(i_color *, tmp);
3459 croak("i_addcolor: pixels must be Imager::Color objects");
3462 index = i_addcolors(im, colors, items-1);
3465 RETVAL = newSVpv("0 but true", 0);
3467 else if (index == -1) {
3468 RETVAL = &PL_sv_undef;
3471 RETVAL = newSViv(index);
3477 i_setcolors(im, index, ...)
3485 croak("i_setcolors: no colors to add");
3486 colors = mymalloc((items-2) * sizeof(i_color));
3487 for (i=0; i < items-2; ++i) {
3488 if (sv_isobject(ST(i+2))
3489 && sv_derived_from(ST(i+2), "Imager::Color")) {
3490 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
3491 colors[i] = *INT2PTR(i_color *, tmp);
3495 croak("i_setcolors: pixels must be Imager::Color objects");
3498 RETVAL = i_setcolors(im, index, colors, items-2);
3504 i_getcolors(im, index, ...)
3513 croak("i_getcolors: too many arguments");
3515 count = SvIV(ST(2));
3517 croak("i_getcolors: count must be positive");
3518 colors = mymalloc(sizeof(i_color) * count);
3519 if (i_getcolors(im, index, colors, count)) {
3520 for (i = 0; i < count; ++i) {
3522 SV *sv = sv_newmortal();
3523 pv = mymalloc(sizeof(i_color));
3525 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3541 i_findcolor(im, color)
3547 if (i_findcolor(im, color, &index)) {
3548 RETVAL = newSViv(index);
3551 RETVAL = &PL_sv_undef;
3569 i_gsamp(im, l, r, y, ...)
3581 croak("No channel numbers supplied to g_samp()");
3583 chan_count = items - 4;
3584 chans = mymalloc(sizeof(int) * chan_count);
3585 for (i = 0; i < chan_count; ++i)
3586 chans[i] = SvIV(ST(i+4));
3587 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
3588 count = i_gsamp(im, l, r, y, data, chans, chan_count);
3590 if (GIMME_V == G_ARRAY) {
3592 for (i = 0; i < count; ++i)
3593 PUSHs(sv_2mortal(newSViv(data[i])));
3597 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
3602 if (GIMME_V != G_ARRAY) {
3604 PUSHs(&PL_sv_undef);
3610 i_img_masked_new(targ, mask, x, y, w, h)
3620 if (!sv_isobject(ST(1))
3621 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3622 croak("i_img_masked_new: parameter 2 must undef or an image");
3624 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
3628 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3633 i_plin(im, l, y, ...)
3644 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3645 /* supplied as a byte string */
3646 work = (i_color *)SvPV(ST(3), len);
3647 count = len / sizeof(i_color);
3648 if (count * sizeof(i_color) != len) {
3649 croak("i_plin: length of scalar argument must be multiple of sizeof i_color");
3651 RETVAL = i_plin(im, l, l+count, y, work);
3654 work = mymalloc(sizeof(i_color) * (items-3));
3655 for (i=0; i < items-3; ++i) {
3656 if (sv_isobject(ST(i+3))
3657 && sv_derived_from(ST(i+3), "Imager::Color")) {
3658 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3659 work[i] = *INT2PTR(i_color *, tmp);
3663 croak("i_plin: pixels must be Imager::Color objects");
3666 RETVAL = i_plin(im, l, l+items-3, y, work);
3677 i_ppixf(im, x, y, cl)
3681 Imager::Color::Float cl
3684 i_gsampf(im, l, r, y, ...)
3696 croak("No channel numbers supplied to g_sampf()");
3698 chan_count = items - 4;
3699 chans = mymalloc(sizeof(int) * chan_count);
3700 for (i = 0; i < chan_count; ++i)
3701 chans[i] = SvIV(ST(i+4));
3702 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3703 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3704 if (GIMME_V == G_ARRAY) {
3706 for (i = 0; i < count; ++i)
3707 PUSHs(sv_2mortal(newSVnv(data[i])));
3711 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3715 if (GIMME_V != G_ARRAY) {
3717 PUSHs(&PL_sv_undef);
3722 i_plinf(im, l, y, ...)
3733 if (items == 4 && SvOK(ST(3)) && !SvROK(ST(3))) {
3734 /* supplied as a byte string */
3735 work = (i_fcolor *)SvPV(ST(3), len);
3736 count = len / sizeof(i_fcolor);
3737 if (count * sizeof(i_fcolor) != len) {
3738 croak("i_plin: length of scalar argument must be multiple of sizeof i_fcolor");
3740 RETVAL = i_plinf(im, l, l+count, y, work);
3743 work = mymalloc(sizeof(i_fcolor) * (items-3));
3744 for (i=0; i < items-3; ++i) {
3745 if (sv_isobject(ST(i+3))
3746 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3747 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
3748 work[i] = *INT2PTR(i_fcolor *, tmp);
3752 croak("i_plinf: pixels must be Imager::Color::Float objects");
3756 RETVAL = i_plinf(im, l, l+items-3, y, work);
3774 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3775 if (i_gpixf(im, x, y, color) == 0) {
3776 RETVAL = NEWSV(0,0);
3777 sv_setref_pv(RETVAL, "Imager::Color::Float", (void *)color);
3781 RETVAL = &PL_sv_undef;
3797 vals = mymalloc((r-l) * sizeof(i_color));
3798 count = i_glin(im, l, r, y, vals);
3799 if (GIMME_V == G_ARRAY) {
3801 for (i = 0; i < count; ++i) {
3803 i_color *col = mymalloc(sizeof(i_color));
3805 sv = sv_newmortal();
3806 sv_setref_pv(sv, "Imager::Color", (void *)col);
3812 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_color))));
3818 i_glinf(im, l, r, y)
3828 vals = mymalloc((r-l) * sizeof(i_fcolor));
3829 count = i_glinf(im, l, r, y, vals);
3830 if (GIMME_V == G_ARRAY) {
3832 for (i = 0; i < count; ++i) {
3834 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3836 sv = sv_newmortal();
3837 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3843 PUSHs(sv_2mortal(newSVpv((void *)vals, count * sizeof(i_fcolor))));
3849 i_img_16_new(x, y, ch)
3855 i_img_double_new(x, y, ch)
3861 i_tags_addn(im, name, code, idata)
3870 name = SvPV(ST(1), len);
3873 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3878 i_tags_add(im, name, code, data, idata)
3888 name = SvPV(ST(1), len);
3892 data = SvPV(ST(3), len);
3897 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3902 i_tags_find(im, name, start)
3909 if (i_tags_find(&im->tags, name, start, &entry)) {
3911 RETVAL = newSVpv("0 but true", 0);
3913 RETVAL = newSViv(entry);
3915 RETVAL = &PL_sv_undef;
3921 i_tags_findn(im, code, start)
3928 if (i_tags_findn(&im->tags, code, start, &entry)) {
3930 RETVAL = newSVpv("0 but true", 0);
3932 RETVAL = newSViv(entry);
3935 RETVAL = &PL_sv_undef;
3941 i_tags_delete(im, entry)
3945 RETVAL = i_tags_delete(&im->tags, entry);
3950 i_tags_delbyname(im, name)
3954 RETVAL = i_tags_delbyname(&im->tags, name);
3959 i_tags_delbycode(im, code)
3963 RETVAL = i_tags_delbycode(&im->tags, code);
3968 i_tags_get(im, index)
3972 if (index >= 0 && index < im->tags.count) {
3973 i_img_tag *entry = im->tags.tags + index;
3977 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3980 PUSHs(sv_2mortal(newSViv(entry->code)));
3983 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3986 PUSHs(sv_2mortal(newSViv(entry->idata)));
3991 i_tags_get_string(im, what_sv)
3995 char const *name = NULL;
3999 if (SvIOK(what_sv)) {
4000 code = SvIV(what_sv);
4004 name = SvPV_nolen(what_sv);
4007 if (i_tags_get_string(&im->tags, name, code, buffer, sizeof(buffer))) {
4009 PUSHs(sv_2mortal(newSVpv(buffer, 0)));
4016 RETVAL = im->tags.count;
4023 i_wf_bbox(face, size, text)
4028 int cords[BOUNDING_BOX_COUNT];
4031 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
4033 for (i = 0; i < rc; ++i)
4034 PUSHs(sv_2mortal(newSViv(cords[i])));
4038 i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
4049 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
4055 i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4066 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4079 MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4081 #define FT2_DESTROY(font) i_ft2_destroy(font)
4085 Imager::Font::FT2 font
4087 MODULE = Imager PACKAGE = Imager::Font::FreeType2
4090 i_ft2_new(name, index)
4095 i_ft2_setdpi(font, xdpi, ydpi)
4096 Imager::Font::FT2 font
4102 Imager::Font::FT2 font
4106 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4108 PUSHs(sv_2mortal(newSViv(xdpi)));
4109 PUSHs(sv_2mortal(newSViv(ydpi)));
4113 i_ft2_sethinting(font, hinting)
4114 Imager::Font::FT2 font
4118 i_ft2_settransform(font, matrix)
4119 Imager::Font::FT2 font
4127 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4128 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4129 av=(AV*)SvRV(ST(1));
4133 for (i = 0; i < len; ++i) {
4134 sv1=(*(av_fetch(av,i,0)));
4135 matrix[i] = SvNV(sv1);
4139 RETVAL = i_ft2_settransform(font, matrix);
4144 i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
4145 Imager::Font::FT2 font
4151 int bbox[BOUNDING_BOX_COUNT];
4157 text = SvPV(text_sv, text_len);
4159 if (SvUTF8(text_sv))
4162 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4165 for (i = 0; i < rc; ++i)
4166 PUSHs(sv_2mortal(newSViv(bbox[i])));
4170 i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4171 Imager::Font::FT2 font
4185 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4188 for (i = 0; i < 8; ++i)
4189 PUSHs(sv_2mortal(newSViv(bbox[i])));
4193 i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4194 Imager::Font::FT2 font
4210 if (SvUTF8(ST(7))) {
4214 text = SvPV(ST(7), len);
4215 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4216 len, align, aa, vlayout, utf8);
4221 i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4222 Imager::Font::FT2 font
4239 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4240 strlen(text), align, aa, vlayout, 1);
4245 ft2_transform_box(font, x0, x1, x2, x3)
4246 Imager::Font::FT2 font
4254 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4255 ft2_transform_box(font, box);
4257 PUSHs(sv_2mortal(newSViv(box[0])));
4258 PUSHs(sv_2mortal(newSViv(box[1])));
4259 PUSHs(sv_2mortal(newSViv(box[2])));
4260 PUSHs(sv_2mortal(newSViv(box[3])));
4263 i_ft2_has_chars(handle, text_sv, utf8)
4264 Imager::Font::FT2 handle
4275 if (SvUTF8(text_sv))
4278 text = SvPV(text_sv, len);
4279 work = mymalloc(len);
4280 count = i_ft2_has_chars(handle, text, len, utf8, work);
4281 if (GIMME_V == G_ARRAY) {
4283 for (i = 0; i < count; ++i) {
4284 PUSHs(sv_2mortal(newSViv(work[i])));
4289 PUSHs(sv_2mortal(newSVpv(work, count)));
4294 i_ft2_face_name(handle)
4295 Imager::Font::FT2 handle
4300 len = i_ft2_face_name(handle, name, sizeof(name));
4303 PUSHs(sv_2mortal(newSVpv(name, 0)));
4307 i_ft2_can_face_name()
4310 i_ft2_glyph_name(handle, text_sv, utf8 = 0, reliable_only = 1)
4311 Imager::Font::FT2 handle
4322 if (SvUTF8(text_sv))
4325 text = SvPV(text_sv, work_len);
4330 ch = i_utf8_advance(&text, &len);
4332 i_push_error(0, "invalid UTF8 character");
4341 if (i_ft2_glyph_name(handle, ch, name, sizeof(name),
4343 PUSHs(sv_2mortal(newSVpv(name, 0)));
4346 PUSHs(&PL_sv_undef);
4351 i_ft2_can_do_glyph_names()
4354 i_ft2_face_has_glyph_names(handle)
4355 Imager::Font::FT2 handle
4358 i_ft2_is_multiple_master(handle)
4359 Imager::Font::FT2 handle
4362 i_ft2_get_multiple_masters(handle)
4363 Imager::Font::FT2 handle
4368 if (i_ft2_get_multiple_masters(handle, &mm)) {
4369 EXTEND(SP, 2+mm.num_axis);
4370 PUSHs(sv_2mortal(newSViv(mm.num_axis)));
4371 PUSHs(sv_2mortal(newSViv(mm.num_designs)));
4372 for (i = 0; i < mm.num_axis; ++i) {
4376 sv = newSVpv(mm.axis[i].name, strlen(mm.axis[i].name));
4378 av_store(av, 0, sv);
4379 sv = newSViv(mm.axis[i].minimum);
4381 av_store(av, 1, sv);
4382 sv = newSViv(mm.axis[i].maximum);
4384 av_store(av, 2, sv);
4385 PUSHs(newRV_noinc((SV *)av));
4390 i_ft2_set_mm_coords(handle, ...)
4391 Imager::Font::FT2 handle
4397 /* T_ARRAY handling by xsubpp seems to be busted in 5.6.1, so
4398 transfer the array manually */
4399 ix_coords = items-1;
4400 coords = mymalloc(sizeof(long) * ix_coords);
4401 for (i = 0; i < ix_coords; ++i) {
4402 coords[i] = (long)SvIV(ST(1+i));
4404 RETVAL = i_ft2_set_mm_coords(handle, ix_coords, coords);
4411 MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4415 Imager::FillHandle fill
4417 MODULE = Imager PACKAGE = Imager
4420 i_new_fill_solid(cl, combine)
4425 i_new_fill_solidf(cl, combine)
4426 Imager::Color::Float cl
4430 i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4438 unsigned char *cust_hatch;
4442 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4446 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4451 i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4452 Imager::Color::Float fg
4453 Imager::Color::Float bg
4459 unsigned char *cust_hatch;
4463 cust_hatch = (unsigned char *)SvPV(ST(4), len);
4467 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4472 i_new_fill_image(src, matrix, xoff, yoff, combine)
4489 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4490 croak("i_new_fill_image: parameter must be an arrayref");
4491 av=(AV*)SvRV(ST(1));
4495 for (i = 0; i < len; ++i) {
4496 sv1=(*(av_fetch(av,i,0)));
4497 matrix[i] = SvNV(sv1);
4503 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
4507 MODULE = Imager PACKAGE = Imager::Internal::Hlines PREFIX=i_int_hlines_
4509 # this class is only exposed for testing
4512 i_int_hlines_testing()
4514 #if i_int_hlines_testing()
4516 Imager::Internal::Hlines
4517 i_int_hlines_new(start_y, count_y, start_x, count_x)
4523 Imager::Internal::Hlines
4524 i_int_hlines_new_img(im)
4528 i_int_hlines_add(hlines, y, minx, width)
4529 Imager::Internal::Hlines hlines
4535 i_int_hlines_DESTROY(hlines)
4536 Imager::Internal::Hlines hlines
4539 i_int_hlines_dump(hlines)
4540 Imager::Internal::Hlines hlines
4545 PERL_SET_GLOBAL_CALLBACKS;