- removed a warning generated by the new matrix_transform() test
[imager.git] / Imager.xs
CommitLineData
02d1d628
AMH
1#ifdef __cplusplus
2extern "C" {
3#endif
4#include "EXTERN.h"
5#include "perl.h"
6#include "XSUB.h"
7#include "ppport.h"
8#ifdef __cplusplus
9
10#endif
11
12#include "image.h"
13#include "feat.h"
14#include "dynaload.h"
15#include "regmach.h"
16
17typedef io_glue* Imager__IO;
18typedef i_color* Imager__Color;
faa9b3e7 19typedef i_fcolor* Imager__Color__Float;
02d1d628
AMH
20typedef i_img* Imager__ImgRaw;
21
02d1d628 22#ifdef HAVE_LIBTT
4b19f77a 23typedef TT_Fonthandle* Imager__Font__TT;
02d1d628
AMH
24#endif
25
faa9b3e7
TC
26#ifdef HAVE_FT2
27typedef FT2_Fonthandle* Imager__Font__FT2;
28#endif
29
b33c08f8
TC
30/* These functions are all shared - then comes platform dependant code */
31static int getstr(void *hv_t,char *key,char **store) {
32 SV** svpp;
33 HV* hv=(HV*)hv_t;
34
35 mm_log((1,"getstr(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
36
37 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
38
39 svpp=hv_fetch(hv, key, strlen(key), 0);
40 *store=SvPV(*svpp, PL_na );
41
42 return 1;
43}
44
45static int getint(void *hv_t,char *key,int *store) {
46 SV** svpp;
47 HV* hv=(HV*)hv_t;
48
49 mm_log((1,"getint(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
50
51 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
52
53 svpp=hv_fetch(hv, key, strlen(key), 0);
54 *store=(int)SvIV(*svpp);
55 return 1;
56}
57
58static int getdouble(void *hv_t,char* key,double *store) {
59 SV** svpp;
60 HV* hv=(HV*)hv_t;
61
62 mm_log((1,"getdouble(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
63
64 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
65 svpp=hv_fetch(hv, key, strlen(key), 0);
66 *store=(float)SvNV(*svpp);
67 return 1;
68}
69
70static int getvoid(void *hv_t,char* key,void **store) {
71 SV** svpp;
72 HV* hv=(HV*)hv_t;
73
74 mm_log((1,"getvoid(hv_t 0x%X, key %s, store 0x%X)\n",hv_t,key,store));
75
76 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
77
78 svpp=hv_fetch(hv, key, strlen(key), 0);
79 *store = INT2PTR(void*, SvIV(*svpp));
80
81 return 1;
82}
83
84static int getobj(void *hv_t,char *key,char *type,void **store) {
85 SV** svpp;
86 HV* hv=(HV*)hv_t;
87
88 mm_log((1,"getobj(hv_t 0x%X, key %s,type %s, store 0x%X)\n",hv_t,key,type,store));
89
90 if ( !hv_exists(hv,key,strlen(key)) ) return 0;
91
92 svpp=hv_fetch(hv, key, strlen(key), 0);
93
94 if (sv_derived_from(*svpp,type)) {
95 IV tmp = SvIV((SV*)SvRV(*svpp));
96 *store = INT2PTR(void*, tmp);
97 } else {
98 mm_log((1,"getobj: key exists in hash but is not of correct type"));
99 return 0;
100 }
101
102 return 1;
103}
104
105UTIL_table_t i_UTIL_table={getstr,getint,getdouble,getvoid,getobj};
4dfa5522
AMH
106
107void my_SvREFCNT_dec(void *p) {
108 SvREFCNT_dec((SV*)p);
109}
110
7f882a01 111
b33c08f8 112static void
7f882a01
AMH
113log_entry(char *string, int level) {
114 mm_log((level, string));
115}
116
117
02d1d628
AMH
118typedef struct i_reader_data_tag
119{
120 /* presumably a CODE ref or name of a sub */
121 SV *sv;
122} i_reader_data;
123
124/* used by functions that want callbacks */
125static int read_callback(char *userdata, char *buffer, int need, int want) {
126 i_reader_data *rd = (i_reader_data *)userdata;
127 int count;
128 int result;
129 SV *data;
130 dSP; dTARG = sv_newmortal();
131 /* thanks to Simon Cozens for help with the dTARG above */
132
133 ENTER;
134 SAVETMPS;
135 EXTEND(SP, 2);
136 PUSHMARK(SP);
137 PUSHi(want);
138 PUSHi(need);
139 PUTBACK;
140
141 count = perl_call_sv(rd->sv, G_SCALAR);
142
143 SPAGAIN;
144
145 if (count != 1)
146 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
147
148 data = POPs;
149
150 if (SvOK(data)) {
151 STRLEN len;
152 char *ptr = SvPV(data, len);
153 if (len > want)
154 croak("Too much data returned in reader callback");
155
156 memcpy(buffer, ptr, len);
157 result = len;
158 }
159 else {
160 result = -1;
161 }
162
163 PUTBACK;
164 FREETMPS;
165 LEAVE;
166
167 return result;
168}
169
170typedef struct
171{
172 SV *sv; /* a coderef or sub name */
173} i_writer_data;
174
175/* used by functions that want callbacks */
176static int write_callback(char *userdata, char const *data, int size) {
177 i_writer_data *wd = (i_writer_data *)userdata;
178 int count;
179 int success;
180 SV *sv;
181 dSP;
182
183 ENTER;
184 SAVETMPS;
185 EXTEND(SP, 1);
186 PUSHMARK(SP);
187 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
188 PUTBACK;
189
190 count = perl_call_sv(wd->sv, G_SCALAR);
191
192 SPAGAIN;
193
194 if (count != 1)
195 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
196
197 sv = POPs;
198 success = SvTRUE(sv);
199
200
201 PUTBACK;
202 FREETMPS;
203 LEAVE;
204
205 return success;
206}
207
10461f9a
TC
208#define CBDATA_BUFSIZE 8192
209
210struct cbdata {
211 /* the SVs we use to call back to Perl */
212 SV *writecb;
213 SV *readcb;
214 SV *seekcb;
215 SV *closecb;
216
217 /* we need to remember whether the buffer contains write data or
218 read data
219 */
220 int reading;
221 int writing;
222
223 /* how far we've read into the buffer (not used for writing) */
224 int where;
225
226 /* the amount of space used/data available in the buffer */
227 int used;
228
229 /* the maximum amount to fill the buffer before flushing
230 If any write is larger than this then the buffer is flushed and
231 the full write is performed. The write is _not_ split into
232 maxwrite sized calls
233 */
234 int maxlength;
235
236 char buffer[CBDATA_BUFSIZE];
237};
238
239/*
240
241call_writer(cbd, buf, size)
242
243Low-level function to call the perl writer callback.
244
245*/
246
247static ssize_t call_writer(struct cbdata *cbd, void const *buf, size_t size) {
248 int count;
249 int success;
250 SV *sv;
251 dSP;
252
253 if (!SvOK(cbd->writecb))
254 return -1;
255
256 ENTER;
257 SAVETMPS;
258 EXTEND(SP, 1);
259 PUSHMARK(SP);
260 PUSHs(sv_2mortal(newSVpv((char *)buf, size)));
261 PUTBACK;
262
263 count = perl_call_sv(cbd->writecb, G_SCALAR);
264
265 SPAGAIN;
266 if (count != 1)
267 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
268
269 sv = POPs;
270 success = SvTRUE(sv);
271
272
273 PUTBACK;
274 FREETMPS;
275 LEAVE;
276
277 return success ? size : 0;
278}
279
280static ssize_t call_reader(struct cbdata *cbd, void *buf, size_t size,
281 size_t maxread) {
282 int count;
283 int result;
284 SV *data;
285 dSP;
286
287 if (!SvOK(cbd->readcb))
288 return -1;
289
290 ENTER;
291 SAVETMPS;
292 EXTEND(SP, 2);
293 PUSHMARK(SP);
294 PUSHs(sv_2mortal(newSViv(size)));
295 PUSHs(sv_2mortal(newSViv(maxread)));
296 PUTBACK;
297
298 count = perl_call_sv(cbd->readcb, G_SCALAR);
299
300 SPAGAIN;
301
302 if (count != 1)
303 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
304
305 data = POPs;
306
307 if (SvOK(data)) {
308 STRLEN len;
309 char *ptr = SvPV(data, len);
310 if (len > maxread)
311 croak("Too much data returned in reader callback");
312
313 memcpy(buf, ptr, len);
314 result = len;
315 }
316 else {
317 result = -1;
318 }
319
320 PUTBACK;
321 FREETMPS;
322 LEAVE;
323
324 return result;
325}
326
327static ssize_t write_flush(struct cbdata *cbd) {
328 ssize_t result;
329
330 result = call_writer(cbd, cbd->buffer, cbd->used);
331 cbd->used = 0;
332 return result;
333}
334
335static off_t io_seeker(void *p, off_t offset, int whence) {
336 struct cbdata *cbd = p;
337 int count;
338 off_t result;
339 dSP;
340
341 if (!SvOK(cbd->seekcb))
342 return -1;
343
344 if (cbd->writing) {
345 if (cbd->used && write_flush(cbd) <= 0)
346 return -1;
347 cbd->writing = 0;
348 }
349 if (whence == SEEK_CUR && cbd->reading && cbd->where != cbd->used) {
350 offset -= cbd->where - cbd->used;
351 }
352 cbd->reading = 0;
353 cbd->where = cbd->used = 0;
354
355 ENTER;
356 SAVETMPS;
357 EXTEND(SP, 2);
358 PUSHMARK(SP);
359 PUSHs(sv_2mortal(newSViv(offset)));
360 PUSHs(sv_2mortal(newSViv(whence)));
361 PUTBACK;
362
363 count = perl_call_sv(cbd->seekcb, G_SCALAR);
364
365 SPAGAIN;
366
367 if (count != 1)
368 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
369
370 result = POPi;
371
372 PUTBACK;
373 FREETMPS;
374 LEAVE;
375
376 return result;
377}
378
379static ssize_t io_writer(void *p, void const *data, size_t size) {
380 struct cbdata *cbd = p;
381
382 /*printf("io_writer(%p, %p, %u)\n", p, data, size);*/
383 if (!cbd->writing) {
384 if (cbd->reading && cbd->where < cbd->used) {
385 /* we read past the place where the caller expected us to be
386 so adjust our position a bit */
387 *(char *)0 = 0;
388 if (io_seeker(p, cbd->where - cbd->used, SEEK_CUR) < 0) {
389 return -1;
390 }
391 cbd->reading = 0;
392 }
393 cbd->where = cbd->used = 0;
394 }
395 cbd->writing = 1;
396 if (cbd->used && cbd->used + size > cbd->maxlength) {
397 if (write_flush(cbd) <= 0) {
398 return 0;
399 }
400 cbd->used = 0;
401 }
402 if (cbd->used+size <= cbd->maxlength) {
403 memcpy(cbd->buffer + cbd->used, data, size);
404 cbd->used += size;
405 return size;
406 }
407 /* it doesn't fit - just pass it up */
408 return call_writer(cbd, data, size);
409}
410
411static ssize_t io_reader(void *p, void *data, size_t size) {
412 struct cbdata *cbd = p;
413 ssize_t total;
414 char *out = data; /* so we can do pointer arithmetic */
10461f9a
TC
415
416 if (cbd->writing) {
417 if (write_flush(cbd) <= 0)
418 return 0;
419 cbd->writing = 0;
420 }
421
422 cbd->reading = 1;
423 if (size <= cbd->used - cbd->where) {
424 /* simplest case */
425 memcpy(data, cbd->buffer+cbd->where, size);
426 cbd->where += size;
427 return size;
428 }
429 total = 0;
430 memcpy(out, cbd->buffer + cbd->where, cbd->used - cbd->where);
431 total += cbd->used - cbd->where;
432 size -= cbd->used - cbd->where;
433 out += cbd->used - cbd->where;
434 if (size < sizeof(cbd->buffer)) {
435 int did_read;
436 int copy_size;
437 while (size
438 && (did_read = call_reader(cbd, cbd->buffer, size,
439 sizeof(cbd->buffer))) > 0) {
440 cbd->where = 0;
441 cbd->used = did_read;
442
b33c08f8 443 copy_size = i_min(size, cbd->used);
10461f9a
TC
444 memcpy(out, cbd->buffer, copy_size);
445 cbd->where += copy_size;
446 out += copy_size;
447 total += copy_size;
448 size -= copy_size;
449 }
450 }
451 else {
452 /* just read the rest - too big for our buffer*/
453 int did_read;
454 while ((did_read = call_reader(cbd, out, size, size)) > 0) {
455 size -= did_read;
456 total += did_read;
457 out += did_read;
458 }
459 }
460
461 return total;
462}
463
464static void io_closer(void *p) {
465 struct cbdata *cbd = p;
466
467 if (cbd->writing && cbd->used > 0) {
468 write_flush(cbd);
469 cbd->writing = 0;
470 }
471
472 if (SvOK(cbd->closecb)) {
473 dSP;
474
475 ENTER;
476 SAVETMPS;
477 PUSHMARK(SP);
478 PUTBACK;
479
480 perl_call_sv(cbd->closecb, G_VOID);
481
482 SPAGAIN;
483 PUTBACK;
484 FREETMPS;
485 LEAVE;
486 }
487}
488
489static void io_destroyer(void *p) {
490 struct cbdata *cbd = p;
491
492 SvREFCNT_dec(cbd->writecb);
493 SvREFCNT_dec(cbd->readcb);
494 SvREFCNT_dec(cbd->seekcb);
495 SvREFCNT_dec(cbd->closecb);
496}
497
02d1d628
AMH
498struct value_name {
499 char *name;
500 int value;
501};
502static int lookup_name(struct value_name *names, int count, char *name, int def_value)
503{
504 int i;
505 for (i = 0; i < count; ++i)
506 if (strEQ(names[i].name, name))
507 return names[i].value;
508
509 return def_value;
510}
511static struct value_name transp_names[] =
512{
513 { "none", tr_none },
514 { "threshold", tr_threshold },
515 { "errdiff", tr_errdiff },
516 { "ordered", tr_ordered, },
517};
518
519static struct value_name make_color_names[] =
520{
521 { "none", mc_none, },
522 { "webmap", mc_web_map, },
523 { "addi", mc_addi, },
97c4effc 524 { "mediancut", mc_median_cut, },
02d1d628
AMH
525};
526
527static struct value_name translate_names[] =
528{
529#ifdef HAVE_LIBGIF
530 { "giflib", pt_giflib, },
531#endif
532 { "closest", pt_closest, },
533 { "perturb", pt_perturb, },
534 { "errdiff", pt_errdiff, },
535};
536
537static struct value_name errdiff_names[] =
538{
539 { "floyd", ed_floyd, },
540 { "jarvis", ed_jarvis, },
541 { "stucki", ed_stucki, },
542 { "custom", ed_custom, },
543};
544
545static struct value_name orddith_names[] =
546{
547 { "random", od_random, },
548 { "dot8", od_dot8, },
549 { "dot4", od_dot4, },
550 { "hline", od_hline, },
551 { "vline", od_vline, },
552 { "/line", od_slashline, },
553 { "slashline", od_slashline, },
554 { "\\line", od_backline, },
555 { "backline", od_backline, },
e7d4ea82 556 { "tiny", od_tiny, },
02d1d628
AMH
557 { "custom", od_custom, },
558};
559
bf9dd17c 560static int
07e3e23d 561hv_fetch_bool(HV *hv, char *name, int def) {
bf9dd17c
TC
562 SV **sv;
563
564 sv = hv_fetch(hv, name, strlen(name), 0);
565 if (sv && *sv) {
566 return SvTRUE(*sv);
567 }
568 else
569 return def;
570}
571
572static int
07e3e23d 573hv_fetch_int(HV *hv, char *name, int def) {
bf9dd17c
TC
574 SV **sv;
575
576 sv = hv_fetch(hv, name, strlen(name), 0);
577 if (sv && *sv) {
578 return SvIV(*sv);
579 }
580 else
581 return def;
582}
583
02d1d628
AMH
584/* look through the hash for quantization options */
585static void handle_quant_opts(i_quantize *quant, HV *hv)
586{
587 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
588 SV **sv;
589 int i;
590 STRLEN len;
591 char *str;
592
46a04ceb
TC
593 quant->mc_colors = mymalloc(quant->mc_size * sizeof(i_color));
594
02d1d628
AMH
595 sv = hv_fetch(hv, "transp", 6, 0);
596 if (sv && *sv && (str = SvPV(*sv, len))) {
597 quant->transp =
598 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
599 str, tr_none);
600 if (quant->transp != tr_none) {
601 quant->tr_threshold = 127;
602 sv = hv_fetch(hv, "tr_threshold", 12, 0);
603 if (sv && *sv)
604 quant->tr_threshold = SvIV(*sv);
605 }
606 if (quant->transp == tr_errdiff) {
607 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
608 if (sv && *sv && (str = SvPV(*sv, len)))
609 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
610 }
611 if (quant->transp == tr_ordered) {
e7d4ea82 612 quant->tr_orddith = od_tiny;
02d1d628
AMH
613 sv = hv_fetch(hv, "tr_orddith", 10, 0);
614 if (sv && *sv && (str = SvPV(*sv, len)))
615 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
616
617 if (quant->tr_orddith == od_custom) {
618 sv = hv_fetch(hv, "tr_map", 6, 0);
619 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
620 AV *av = (AV*)SvRV(*sv);
621 len = av_len(av) + 1;
622 if (len > sizeof(quant->tr_custom))
623 len = sizeof(quant->tr_custom);
624 for (i = 0; i < len; ++i) {
625 SV **sv2 = av_fetch(av, i, 0);
626 if (sv2 && *sv2) {
627 quant->tr_custom[i] = SvIV(*sv2);
628 }
629 }
630 while (i < sizeof(quant->tr_custom))
631 quant->tr_custom[i++] = 0;
632 }
633 }
634 }
635 }
636 quant->make_colors = mc_addi;
637 sv = hv_fetch(hv, "make_colors", 11, 0);
638 if (sv && *sv && (str = SvPV(*sv, len))) {
639 quant->make_colors =
640 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
641 }
642 sv = hv_fetch(hv, "colors", 6, 0);
643 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
644 /* needs to be an array of Imager::Color
645 note that the caller allocates the mc_color array and sets mc_size
646 to it's size */
647 AV *av = (AV *)SvRV(*sv);
648 quant->mc_count = av_len(av)+1;
649 if (quant->mc_count > quant->mc_size)
650 quant->mc_count = quant->mc_size;
651 for (i = 0; i < quant->mc_count; ++i) {
652 SV **sv1 = av_fetch(av, i, 0);
653 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
4c4c2ffd 654 i_color *col = INT2PTR(i_color *, SvIV((SV*)SvRV(*sv1)));
02d1d628
AMH
655 quant->mc_colors[i] = *col;
656 }
657 }
658 }
659 sv = hv_fetch(hv, "max_colors", 10, 0);
660 if (sv && *sv) {
661 i = SvIV(*sv);
662 if (i <= quant->mc_size && i >= quant->mc_count)
663 quant->mc_size = i;
664 }
665
666 quant->translate = pt_closest;
667 sv = hv_fetch(hv, "translate", 9, 0);
668 if (sv && *sv && (str = SvPV(*sv, len))) {
669 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
670 }
671 sv = hv_fetch(hv, "errdiff", 7, 0);
672 if (sv && *sv && (str = SvPV(*sv, len))) {
673 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
674 }
675 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
676 /* get the error diffusion map */
677 sv = hv_fetch(hv, "errdiff_width", 13, 0);
678 if (sv && *sv)
679 quant->ed_width = SvIV(*sv);
680 sv = hv_fetch(hv, "errdiff_height", 14, 0);
681 if (sv && *sv)
682 quant->ed_height = SvIV(*sv);
683 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
684 if (sv && *sv)
685 quant->ed_orig = SvIV(*sv);
686 if (quant->ed_width > 0 && quant->ed_height > 0) {
687 int sum = 0;
688 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
689 sv = hv_fetch(hv, "errdiff_map", 11, 0);
690 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
691 AV *av = (AV*)SvRV(*sv);
692 len = av_len(av) + 1;
693 if (len > quant->ed_width * quant->ed_height)
694 len = quant->ed_width * quant->ed_height;
695 for (i = 0; i < len; ++i) {
696 SV **sv2 = av_fetch(av, i, 0);
697 if (sv2 && *sv2) {
698 quant->ed_map[i] = SvIV(*sv2);
699 sum += quant->ed_map[i];
700 }
701 }
702 }
703 if (!sum) {
704 /* broken map */
705 myfree(quant->ed_map);
706 quant->ed_map = 0;
707 quant->errdiff = ed_floyd;
708 }
709 }
710 }
711 sv = hv_fetch(hv, "perturb", 7, 0);
712 if (sv && *sv)
713 quant->perturb = SvIV(*sv);
714}
715
46a04ceb
TC
716static void cleanup_quant_opts(i_quantize *quant) {
717 myfree(quant->mc_colors);
718 if (quant->ed_map)
719 myfree(quant->ed_map);
720}
721
97c4effc 722#if 0
02d1d628
AMH
723/* look through the hash for options to add to opts */
724static void handle_gif_opts(i_gif_opts *opts, HV *hv)
725{
02d1d628
AMH
726 SV **sv;
727 int i;
728 /**((char *)0) = '\0';*/
bf9dd17c
TC
729 opts->each_palette = hv_fetch_bool(hv, "gif_each_palette", 0);
730 opts->interlace = hv_fetch_bool(hv, "interlace", 0);
731
02d1d628
AMH
732 sv = hv_fetch(hv, "gif_delays", 10, 0);
733 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
734 AV *av = (AV*)SvRV(*sv);
735 opts->delay_count = av_len(av)+1;
736 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
737 for (i = 0; i < opts->delay_count; ++i) {
738 SV *sv1 = *av_fetch(av, i, 0);
739 opts->delays[i] = SvIV(sv1);
740 }
741 }
742 sv = hv_fetch(hv, "gif_user_input", 14, 0);
743 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
744 AV *av = (AV*)SvRV(*sv);
745 opts->user_input_count = av_len(av)+1;
746 opts->user_input_flags = mymalloc(opts->user_input_count);
747 for (i = 0; i < opts->user_input_count; ++i) {
748 SV *sv1 = *av_fetch(av, i, 0);
749 opts->user_input_flags[i] = SvIV(sv1) != 0;
750 }
751 }
752 sv = hv_fetch(hv, "gif_disposal", 12, 0);
753 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
754 AV *av = (AV*)SvRV(*sv);
755 opts->disposal_count = av_len(av)+1;
756 opts->disposal = mymalloc(opts->disposal_count);
757 for (i = 0; i < opts->disposal_count; ++i) {
758 SV *sv1 = *av_fetch(av, i, 0);
759 opts->disposal[i] = SvIV(sv1);
760 }
761 }
762 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
763 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
4c4c2ffd 764 i_color *col = INT2PTR(i_color *, SvIV((SV *)SvRV(*sv)));
02d1d628
AMH
765 opts->tran_color = *col;
766 }
767 sv = hv_fetch(hv, "gif_positions", 13, 0);
768 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
769 AV *av = (AV *)SvRV(*sv);
770 opts->position_count = av_len(av) + 1;
771 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
772 for (i = 0; i < opts->position_count; ++i) {
773 SV **sv2 = av_fetch(av, i, 0);
774 opts->positions[i].x = opts->positions[i].y = 0;
775 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
776 AV *av2 = (AV*)SvRV(*sv2);
777 SV **sv3;
778 sv3 = av_fetch(av2, 0, 0);
779 if (sv3 && *sv3)
780 opts->positions[i].x = SvIV(*sv3);
781 sv3 = av_fetch(av2, 1, 0);
782 if (sv3 && *sv3)
783 opts->positions[i].y = SvIV(*sv3);
784 }
785 }
786 }
787 /* Netscape2.0 loop count extension */
bf9dd17c
TC
788 opts->loop_count = hv_fetch_int(hv, "gif_loop_count", 0);
789
790 opts->eliminate_unused = hv_fetch_bool(hv, "gif_eliminate_unused", 1);
02d1d628
AMH
791}
792
46a04ceb
TC
793static void cleanup_gif_opts(i_gif_opts *opts) {
794 if (opts->delays)
795 myfree(opts->delays);
796 if (opts->user_input_flags)
797 myfree(opts->user_input_flags);
798 if (opts->disposal)
799 myfree(opts->disposal);
800 if (opts->positions)
801 myfree(opts->positions);
802}
803
97c4effc
TC
804#endif
805
02d1d628
AMH
806/* copies the color map from the hv into the colors member of the HV */
807static void copy_colors_back(HV *hv, i_quantize *quant) {
808 SV **sv;
809 AV *av;
810 int i;
811 SV *work;
812
813 sv = hv_fetch(hv, "colors", 6, 0);
814 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
815 SV *ref;
816 av = newAV();
817 ref = newRV_inc((SV*) av);
818 sv = hv_store(hv, "colors", 6, ref, 0);
819 }
820 else {
821 av = (AV *)SvRV(*sv);
822 }
823 av_extend(av, quant->mc_count+1);
824 for (i = 0; i < quant->mc_count; ++i) {
825 i_color *in = quant->mc_colors+i;
826 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
827 work = sv_newmortal();
828 sv_setref_pv(work, "Imager::Color", (void *)c);
829 SvREFCNT_inc(work);
830 if (!av_store(av, i, work)) {
831 SvREFCNT_dec(work);
832 }
833 }
834}
835
f1ac5027 836/* loads the segments of a fountain fill into an array */
b33c08f8
TC
837static i_fountain_seg *
838load_fount_segs(AV *asegs, int *count) {
f1ac5027
TC
839 /* Each element of segs must contain:
840 [ start, middle, end, c0, c1, segtype, colortrans ]
841 start, middle, end are doubles from 0 to 1
842 c0, c1 are Imager::Color::Float or Imager::Color objects
843 segtype, colortrans are ints
844 */
845 int i, j;
846 AV *aseg;
847 SV *sv;
848 i_fountain_seg *segs;
849 double work[3];
850 int worki[2];
851
852 *count = av_len(asegs)+1;
853 if (*count < 1)
854 croak("i_fountain must have at least one segment");
855 segs = mymalloc(sizeof(i_fountain_seg) * *count);
856 for(i = 0; i < *count; i++) {
857 SV **sv1 = av_fetch(asegs, i, 0);
858 if (!sv1 || !*sv1 || !SvROK(*sv1)
859 || SvTYPE(SvRV(*sv1)) != SVt_PVAV) {
860 myfree(segs);
861 croak("i_fountain: segs must be an arrayref of arrayrefs");
862 }
863 aseg = (AV *)SvRV(*sv1);
864 if (av_len(aseg) != 7-1) {
865 myfree(segs);
866 croak("i_fountain: a segment must have 7 members");
867 }
868 for (j = 0; j < 3; ++j) {
869 SV **sv2 = av_fetch(aseg, j, 0);
870 if (!sv2 || !*sv2) {
871 myfree(segs);
872 croak("i_fountain: XS error");
873 }
874 work[j] = SvNV(*sv2);
875 }
876 segs[i].start = work[0];
877 segs[i].middle = work[1];
878 segs[i].end = work[2];
879 for (j = 0; j < 2; ++j) {
880 SV **sv3 = av_fetch(aseg, 3+j, 0);
881 if (!sv3 || !*sv3 || !SvROK(*sv3) ||
882 (!sv_derived_from(*sv3, "Imager::Color")
883 && !sv_derived_from(*sv3, "Imager::Color::Float"))) {
884 myfree(segs);
885 croak("i_fountain: segs must contain colors in elements 3 and 4");
886 }
887 if (sv_derived_from(*sv3, "Imager::Color::Float")) {
4c4c2ffd 888 segs[i].c[j] = *INT2PTR(i_fcolor *, SvIV((SV *)SvRV(*sv3)));
f1ac5027
TC
889 }
890 else {
4c4c2ffd 891 i_color c = *INT2PTR(i_color *, SvIV((SV *)SvRV(*sv3)));
f1ac5027
TC
892 int ch;
893 for (ch = 0; ch < MAXCHANNELS; ++ch) {
894 segs[i].c[j].channel[ch] = c.channel[ch] / 255.0;
895 }
896 }
897 }
898 for (j = 0; j < 2; ++j) {
899 SV **sv2 = av_fetch(aseg, j+5, 0);
900 if (!sv2 || !*sv2) {
901 myfree(segs);
902 croak("i_fountain: XS error");
903 }
904 worki[j] = SvIV(*sv2);
905 }
906 segs[i].type = worki[0];
907 segs[i].color = worki[1];
908 }
909
910 return segs;
911}
912
faa9b3e7
TC
913/* I don't think ICLF_* names belong at the C interface
914 this makes the XS code think we have them, to let us avoid
915 putting function bodies in the XS code
916*/
917#define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
918#define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
919
f1ac5027
TC
920/* for the fill objects
921 Since a fill object may later have dependent images, (or fills!)
922 we need perl wrappers - oh well
923*/
924#define IFILL_DESTROY(fill) i_fill_destroy(fill);
925typedef i_fill_t* Imager__FillHandle;
926
b33c08f8
TC
927/* the m_init_log() function was called init_log(), renamed to reduce
928 potential naming conflicts */
929#define init_log m_init_log
930
02d1d628
AMH
931MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
932
933Imager::Color
934ICL_new_internal(r,g,b,a)
935 unsigned char r
936 unsigned char g
937 unsigned char b
938 unsigned char a
939
940void
941ICL_DESTROY(cl)
942 Imager::Color cl
943
944
29106a11 945void
02d1d628
AMH
946ICL_set_internal(cl,r,g,b,a)
947 Imager::Color cl
948 unsigned char r
949 unsigned char g
950 unsigned char b
951 unsigned char a
29106a11 952 PPCODE:
46062ab6 953 ICL_set_internal(cl, r, g, b, a);
29106a11
TC
954 EXTEND(SP, 1);
955 PUSHs(ST(0));
02d1d628
AMH
956
957void
958ICL_info(cl)
959 Imager::Color cl
960
961
962void
963ICL_rgba(cl)
964 Imager::Color cl
965 PPCODE:
966 EXTEND(SP, 4);
967 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
968 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
969 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
970 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
971
efdc2568
TC
972Imager::Color
973i_hsv_to_rgb(c)
974 Imager::Color c
975 CODE:
976 RETVAL = mymalloc(sizeof(i_color));
977 *RETVAL = *c;
978 i_hsv_to_rgb(RETVAL);
979 OUTPUT:
980 RETVAL
981
982Imager::Color
983i_rgb_to_hsv(c)
984 Imager::Color c
985 CODE:
986 RETVAL = mymalloc(sizeof(i_color));
987 *RETVAL = *c;
988 i_rgb_to_hsv(RETVAL);
989 OUTPUT:
990 RETVAL
991
02d1d628
AMH
992
993
faa9b3e7 994MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
02d1d628 995
faa9b3e7
TC
996Imager::Color::Float
997ICLF_new_internal(r, g, b, a)
998 double r
999 double g
1000 double b
1001 double a
1002
1003void
1004ICLF_DESTROY(cl)
1005 Imager::Color::Float cl
02d1d628 1006
faa9b3e7
TC
1007void
1008ICLF_rgba(cl)
1009 Imager::Color::Float cl
1010 PREINIT:
1011 int ch;
1012 PPCODE:
1013 EXTEND(SP, MAXCHANNELS);
1014 for (ch = 0; ch < MAXCHANNELS; ++ch) {
1015 /* printf("%d: %g\n", ch, cl->channel[ch]); */
1016 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
1017 }
1018
1019void
1020ICLF_set_internal(cl,r,g,b,a)
1021 Imager::Color::Float cl
1022 double r
1023 double g
1024 double b
1025 double a
1026 PPCODE:
1027 cl->rgba.r = r;
1028 cl->rgba.g = g;
1029 cl->rgba.b = b;
1030 cl->rgba.a = a;
1031 EXTEND(SP, 1);
1032 PUSHs(ST(0));
02d1d628 1033
efdc2568
TC
1034Imager::Color::Float
1035i_hsv_to_rgb(c)
1036 Imager::Color::Float c
1037 CODE:
1038 RETVAL = mymalloc(sizeof(i_fcolor));
1039 *RETVAL = *c;
1040 i_hsv_to_rgbf(RETVAL);
1041 OUTPUT:
1042 RETVAL
1043
1044Imager::Color::Float
1045i_rgb_to_hsv(c)
1046 Imager::Color::Float c
1047 CODE:
1048 RETVAL = mymalloc(sizeof(i_fcolor));
1049 *RETVAL = *c;
1050 i_rgb_to_hsvf(RETVAL);
1051 OUTPUT:
1052 RETVAL
1053
1054
02d1d628
AMH
1055MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
1056
1057Imager::ImgRaw
1058IIM_new(x,y,ch)
1059 int x
1060 int y
1061 int ch
1062
1063void
1064IIM_DESTROY(im)
1065 Imager::ImgRaw im
1066
1067
1068
1069MODULE = Imager PACKAGE = Imager
1070
1071PROTOTYPES: ENABLE
1072
1073
1074Imager::IO
1075io_new_fd(fd)
1076 int fd
1077
1078Imager::IO
1079io_new_bufchain()
1080
1081
4dfa5522
AMH
1082Imager::IO
1083io_new_buffer(data)
1084 char *data
1085 PREINIT:
1086 size_t length;
4dfa5522
AMH
1087 CODE:
1088 SvPV(ST(0), length);
1089 SvREFCNT_inc(ST(0));
1090 RETVAL = io_new_buffer(data, length, my_SvREFCNT_dec, ST(0));
1091 OUTPUT:
1092 RETVAL
10461f9a
TC
1093
1094Imager::IO
1095io_new_cb(writecb, readcb, seekcb, closecb, maxwrite = CBDATA_BUFSIZE)
1096 SV *writecb;
1097 SV *readcb;
1098 SV *seekcb;
1099 SV *closecb;
1100 int maxwrite;
1101 PREINIT:
1102 struct cbdata *cbd;
1103 CODE:
1104 cbd = mymalloc(sizeof(struct cbdata));
1105 SvREFCNT_inc(writecb);
1106 cbd->writecb = writecb;
1107 SvREFCNT_inc(readcb);
1108 cbd->readcb = readcb;
1109 SvREFCNT_inc(seekcb);
1110 cbd->seekcb = seekcb;
1111 SvREFCNT_inc(closecb);
1112 cbd->closecb = closecb;
1113 cbd->reading = cbd->writing = cbd->where = cbd->used = 0;
1114 if (maxwrite > CBDATA_BUFSIZE)
1115 maxwrite = CBDATA_BUFSIZE;
1116 cbd->maxlength = maxwrite;
1117 RETVAL = io_new_cb(cbd, io_reader, io_writer, io_seeker, io_closer,
1118 io_destroyer);
1119 OUTPUT:
1120 RETVAL
4dfa5522 1121
02d1d628
AMH
1122void
1123io_slurp(ig)
1124 Imager::IO ig
1125 PREINIT:
1126 unsigned char* data;
4dfa5522 1127 size_t tlength;
02d1d628
AMH
1128 PPCODE:
1129 data = NULL;
1130 tlength = io_slurp(ig, &data);
02d1d628 1131 EXTEND(SP,1);
26fd367b 1132 PUSHs(sv_2mortal(newSVpv((char *)data,tlength)));
02d1d628
AMH
1133 myfree(data);
1134
1135
c3cc977e
AMH
1136MODULE = Imager PACKAGE = Imager::IO PREFIX = io_glue_
1137
1138void
1139io_glue_DESTROY(ig)
1140 Imager::IO ig
1141
1142
1143MODULE = Imager PACKAGE = Imager
1144
1145PROTOTYPES: ENABLE
1146
1147
02d1d628
AMH
1148
1149void
1150i_list_formats()
1151 PREINIT:
1152 char* item;
1153 int i;
1154 PPCODE:
1155 i=0;
1156 while( (item=i_format_list[i++]) != NULL ) {
1157 EXTEND(SP, 1);
1158 PUSHs(sv_2mortal(newSVpv(item,0)));
1159 }
1160
1161undef_int
1162i_has_format(frmt)
1163 char* frmt
1164
1165Imager::ImgRaw
1166i_img_new()
1167
1168Imager::ImgRaw
1169i_img_empty(im,x,y)
1170 Imager::ImgRaw im
1171 int x
1172 int y
1173
1174Imager::ImgRaw
1175i_img_empty_ch(im,x,y,ch)
1176 Imager::ImgRaw im
1177 int x
1178 int y
1179 int ch
1180
1181void
f83bf98a 1182m_init_log(name,level)
02d1d628
AMH
1183 char* name
1184 int level
1185
7f882a01
AMH
1186void
1187log_entry(string,level)
1188 char* string
1189 int level
1190
1191
02d1d628
AMH
1192void
1193i_img_exorcise(im)
1194 Imager::ImgRaw im
1195
1196void
1197i_img_destroy(im)
1198 Imager::ImgRaw im
1199
1200void
1201i_img_info(im)
1202 Imager::ImgRaw im
1203 PREINIT:
1204 int info[4];
1205 PPCODE:
1206 i_img_info(im,info);
1207 EXTEND(SP, 4);
1208 PUSHs(sv_2mortal(newSViv(info[0])));
1209 PUSHs(sv_2mortal(newSViv(info[1])));
1210 PUSHs(sv_2mortal(newSViv(info[2])));
1211 PUSHs(sv_2mortal(newSViv(info[3])));
1212
1213
1214
1215
1216void
1217i_img_setmask(im,ch_mask)
1218 Imager::ImgRaw im
1219 int ch_mask
1220
1221int
1222i_img_getmask(im)
1223 Imager::ImgRaw im
1224
1225int
1226i_img_getchannels(im)
1227 Imager::ImgRaw im
1228
1229void
1230i_img_getdata(im)
1231 Imager::ImgRaw im
1232 PPCODE:
1233 EXTEND(SP, 1);
26fd367b
TC
1234 PUSHs(im->idata ?
1235 sv_2mortal(newSVpv((char *)im->idata, im->bytes))
faa9b3e7 1236 : &PL_sv_undef);
02d1d628
AMH
1237
1238
1239void
aa833c97 1240i_line(im,x1,y1,x2,y2,val,endp)
02d1d628
AMH
1241 Imager::ImgRaw im
1242 int x1
1243 int y1
1244 int x2
1245 int y2
1246 Imager::Color val
aa833c97 1247 int endp
02d1d628
AMH
1248
1249void
b437ce0a 1250i_line_aa(im,x1,y1,x2,y2,val,endp)
02d1d628
AMH
1251 Imager::ImgRaw im
1252 int x1
1253 int y1
1254 int x2
1255 int y2
1256 Imager::Color val
b437ce0a 1257 int endp
02d1d628
AMH
1258
1259void
1260i_box(im,x1,y1,x2,y2,val)
1261 Imager::ImgRaw im
1262 int x1
1263 int y1
1264 int x2
1265 int y2
1266 Imager::Color val
1267
1268void
1269i_box_filled(im,x1,y1,x2,y2,val)
1270 Imager::ImgRaw im
1271 int x1
1272 int y1
1273 int x2
1274 int y2
1275 Imager::Color val
1276
f1ac5027
TC
1277void
1278i_box_cfill(im,x1,y1,x2,y2,fill)
1279 Imager::ImgRaw im
1280 int x1
1281 int y1
1282 int x2
1283 int y2
1284 Imager::FillHandle fill
1285
02d1d628
AMH
1286void
1287i_arc(im,x,y,rad,d1,d2,val)
1288 Imager::ImgRaw im
1289 int x
1290 int y
1291 float rad
1292 float d1
1293 float d2
1294 Imager::Color val
1295
f1ac5027
TC
1296void
1297i_arc_cfill(im,x,y,rad,d1,d2,fill)
1298 Imager::ImgRaw im
1299 int x
1300 int y
1301 float rad
1302 float d1
1303 float d2
1304 Imager::FillHandle fill
1305
02d1d628
AMH
1306
1307
6af18d2b
AMH
1308void
1309i_circle_aa(im,x,y,rad,val)
1310 Imager::ImgRaw im
1311 float x
1312 float y
1313 float rad
1314 Imager::Color val
1315
1316
1317
02d1d628
AMH
1318void
1319i_bezier_multi(im,xc,yc,val)
1320 Imager::ImgRaw im
1321 Imager::Color val
1322 PREINIT:
1323 double *x,*y;
1324 int len;
1325 AV *av1;
1326 AV *av2;
1327 SV *sv1;
1328 SV *sv2;
1329 int i;
1330 PPCODE:
1331 ICL_info(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");
1339 len=av_len(av1)+1;
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);
1347 }
1348 i_bezier_multi(im,len,x,y,val);
1349 myfree(x);
1350 myfree(y);
1351
1352
1353void
1354i_poly_aa(im,xc,yc,val)
1355 Imager::ImgRaw im
1356 Imager::Color val
1357 PREINIT:
1358 double *x,*y;
1359 int len;
1360 AV *av1;
1361 AV *av2;
1362 SV *sv1;
1363 SV *sv2;
1364 int i;
1365 PPCODE:
1366 ICL_info(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");
1374 len=av_len(av1)+1;
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);
1382 }
1383 i_poly_aa(im,len,x,y,val);
1384 myfree(x);
1385 myfree(y);
1386
43c5dacb
TC
1387void
1388i_poly_aa_cfill(im,xc,yc,fill)
1389 Imager::ImgRaw im
1390 Imager::FillHandle fill
1391 PREINIT:
1392 double *x,*y;
1393 int len;
1394 AV *av1;
1395 AV *av2;
1396 SV *sv1;
1397 SV *sv2;
1398 int i;
1399 PPCODE:
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");
1407 len=av_len(av1)+1;
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);
1415 }
1416 i_poly_aa_cfill(im,len,x,y,fill);
1417 myfree(x);
1418 myfree(y);
1419
02d1d628
AMH
1420
1421
a321d497 1422undef_int
02d1d628
AMH
1423i_flood_fill(im,seedx,seedy,dcol)
1424 Imager::ImgRaw im
1425 int seedx
1426 int seedy
1427 Imager::Color dcol
1428
a321d497 1429undef_int
cc6483e0
TC
1430i_flood_cfill(im,seedx,seedy,fill)
1431 Imager::ImgRaw im
1432 int seedx
1433 int seedy
1434 Imager::FillHandle fill
1435
02d1d628
AMH
1436
1437void
1438i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1439 Imager::ImgRaw im
1440 Imager::ImgRaw src
1441 int x1
1442 int y1
1443 int x2
1444 int y2
1445 int tx
1446 int ty
1447
1448
1449void
1450i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1451 Imager::ImgRaw im
1452 Imager::ImgRaw src
1453 int x1
1454 int y1
1455 int x2
1456 int y2
1457 int tx
1458 int ty
1459 Imager::Color trans
1460
1461void
1462i_copy(im,src)
1463 Imager::ImgRaw im
1464 Imager::ImgRaw src
1465
1466
faa9b3e7 1467undef_int
71dc4a83 1468i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
02d1d628
AMH
1469 Imager::ImgRaw im
1470 Imager::ImgRaw src
1471 int tx
1472 int ty
71dc4a83
AMH
1473 int src_minx
1474 int src_miny
1475 int src_maxx
1476 int src_maxy
1477
02d1d628 1478
142c26ff
AMH
1479undef_int
1480i_flipxy(im, direction)
1481 Imager::ImgRaw im
1482 int direction
1483
faa9b3e7
TC
1484Imager::ImgRaw
1485i_rotate90(im, degrees)
1486 Imager::ImgRaw im
1487 int degrees
1488
1489Imager::ImgRaw
0d3b936e 1490i_rotate_exact(im, amount, ...)
faa9b3e7
TC
1491 Imager::ImgRaw im
1492 double amount
0d3b936e
TC
1493 PREINIT:
1494 i_color *backp = NULL;
1495 i_fcolor *fbackp = NULL;
1496 int i;
1497 SV * sv1;
1498 CODE:
1499 /* extract the bg colors if any */
1500 /* yes, this is kind of strange */
1501 for (i = 2; i < items; ++i) {
1502 sv1 = ST(i);
1503 if (sv_derived_from(sv1, "Imager::Color")) {
1504 IV tmp = SvIV((SV*)SvRV(sv1));
1505 backp = INT2PTR(i_color *, tmp);
1506 }
1507 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1508 IV tmp = SvIV((SV*)SvRV(sv1));
1509 fbackp = INT2PTR(i_fcolor *, tmp);
1510 }
1511 }
1512 RETVAL = i_rotate_exact_bg(im, amount, backp, fbackp);
1513 OUTPUT:
1514 RETVAL
faa9b3e7
TC
1515
1516Imager::ImgRaw
0d3b936e 1517i_matrix_transform(im, xsize, ysize, matrix, ...)
faa9b3e7
TC
1518 Imager::ImgRaw im
1519 int xsize
1520 int ysize
1521 PREINIT:
1522 double matrix[9];
1523 AV *av;
1524 IV len;
1525 SV *sv1;
1526 int i;
0d3b936e
TC
1527 i_color *backp = NULL;
1528 i_fcolor *fbackp = NULL;
faa9b3e7
TC
1529 CODE:
1530 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1531 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1532 av=(AV*)SvRV(ST(3));
1533 len=av_len(av)+1;
1534 if (len > 9)
1535 len = 9;
1536 for (i = 0; i < len; ++i) {
1537 sv1=(*(av_fetch(av,i,0)));
1538 matrix[i] = SvNV(sv1);
1539 }
1540 for (; i < 9; ++i)
1541 matrix[i] = 0;
0d3b936e
TC
1542 /* extract the bg colors if any */
1543 /* yes, this is kind of strange */
1544 for (i = 4; i < items; ++i) {
1545 sv1 = ST(i);
1546 if (sv_derived_from(sv1, "Imager::Color")) {
1547 IV tmp = SvIV((SV*)SvRV(sv1));
1548 backp = INT2PTR(i_color *, tmp);
1549 }
1550 else if (sv_derived_from(sv1, "Imager::Color::Float")) {
1551 IV tmp = SvIV((SV*)SvRV(sv1));
1552 fbackp = INT2PTR(i_fcolor *, tmp);
1553 }
1554 }
1555 RETVAL = i_matrix_transform_bg(im, xsize, ysize, matrix, backp, fbackp);
faa9b3e7
TC
1556 OUTPUT:
1557 RETVAL
02d1d628
AMH
1558
1559void
1560i_gaussian(im,stdev)
1561 Imager::ImgRaw im
1562 float stdev
1563
b6381851
TC
1564void
1565i_unsharp_mask(im,stdev,scale)
1566 Imager::ImgRaw im
1567 float stdev
1568 double scale
1569
02d1d628
AMH
1570void
1571i_conv(im,pcoef)
1572 Imager::ImgRaw im
1573 PREINIT:
1574 float* coeff;
1575 int len;
1576 AV* av;
1577 SV* sv1;
1578 int i;
1579 PPCODE:
1580 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1581 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1582 av=(AV*)SvRV(ST(1));
1583 len=av_len(av)+1;
1584 coeff=mymalloc( len*sizeof(float) );
1585 for(i=0;i<len;i++) {
1586 sv1=(*(av_fetch(av,i,0)));
1587 coeff[i]=(float)SvNV(sv1);
1588 }
1589 i_conv(im,coeff,len);
1590 myfree(coeff);
1591
f5991c03
TC
1592undef_int
1593i_convert(im, src, coeff)
1594 Imager::ImgRaw im
1595 Imager::ImgRaw src
1596 PREINIT:
1597 float *coeff;
1598 int outchan;
1599 int inchan;
1600 AV *avmain;
1601 SV **temp;
f5991c03
TC
1602 AV *avsub;
1603 int len;
1604 int i, j;
1605 CODE:
f5991c03
TC
1606 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1607 croak("i_convert: parameter 3 must be an arrayref\n");
1608 avmain = (AV*)SvRV(ST(2));
1609 outchan = av_len(avmain)+1;
1610 /* find the biggest */
1611 inchan = 0;
1612 for (j=0; j < outchan; ++j) {
1613 temp = av_fetch(avmain, j, 0);
1614 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1615 avsub = (AV*)SvRV(*temp);
1616 len = av_len(avsub)+1;
1617 if (len > inchan)
1618 inchan = len;
1619 }
1620 }
1621 coeff = mymalloc(sizeof(float) * outchan * inchan);
1622 for (j = 0; j < outchan; ++j) {
1623 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1624 len = av_len(avsub)+1;
1625 for (i = 0; i < len; ++i) {
1626 temp = av_fetch(avsub, i, 0);
1627 if (temp)
1628 coeff[i+j*inchan] = SvNV(*temp);
1629 else
1630 coeff[i+j*inchan] = 0;
1631 }
1632 while (i < inchan)
1633 coeff[i++ + j*inchan] = 0;
1634 }
1635 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1636 myfree(coeff);
f5991c03
TC
1637 OUTPUT:
1638 RETVAL
40eba1ea
AMH
1639
1640
1641void
1642i_map(im, pmaps)
1643 Imager::ImgRaw im
1644 PREINIT:
1645 unsigned int mask = 0;
1646 AV *avmain;
1647 AV *avsub;
1648 SV **temp;
1649 int len;
1650 int i, j;
1651 unsigned char (*maps)[256];
1652 CODE:
1653 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1654 croak("i_map: parameter 2 must be an arrayref\n");
1655 avmain = (AV*)SvRV(ST(1));
1656 len = av_len(avmain)+1;
1657 if (im->channels < len) len = im->channels;
1658
1659 maps = mymalloc( len * sizeof(unsigned char [256]) );
1660
1661 for (j=0; j<len ; j++) {
1662 temp = av_fetch(avmain, j, 0);
1663 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1664 avsub = (AV*)SvRV(*temp);
1665 if(av_len(avsub) != 255) continue;
1666 mask |= 1<<j;
1667 for (i=0; i<256 ; i++) {
9495ee93 1668 int val;
40eba1ea 1669 temp = av_fetch(avsub, i, 0);
9495ee93
AMH
1670 val = temp ? SvIV(*temp) : 0;
1671 if (val<0) val = 0;
1672 if (val>255) val = 255;
1673 maps[j][i] = val;
40eba1ea
AMH
1674 }
1675 }
1676 }
1677 i_map(im, maps, mask);
1678 myfree(maps);
1679
1680
1681
02d1d628
AMH
1682float
1683i_img_diff(im1,im2)
1684 Imager::ImgRaw im1
1685 Imager::ImgRaw im2
1686
1687
1688
1689undef_int
4cb58f1b
TC
1690i_init_fonts(t1log=0)
1691 int t1log
02d1d628
AMH
1692
1693#ifdef HAVE_LIBT1
1694
1695void
1696i_t1_set_aa(st)
1697 int st
1698
1699int
6b012d62 1700i_t1_new(pfb,afm)
02d1d628
AMH
1701 char* pfb
1702 char* afm
1703
1704int
1705i_t1_destroy(font_id)
1706 int font_id
1707
1708
1709undef_int
1bd75e4c 1710i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
02d1d628
AMH
1711 Imager::ImgRaw im
1712 int xb
1713 int yb
1714 int channel
1715 int fontnum
1716 float points
1bd75e4c 1717 SV* str_sv
02d1d628 1718 int align
1bd75e4c
TC
1719 int utf8
1720 char* flags
1721 PREINIT:
1722 char *str;
1723 STRLEN len;
1724 CODE:
1725#ifdef SvUTF8
1726 if (SvUTF8(str_sv))
1727 utf8 = 1;
1728#endif
1729 str = SvPV(str_sv, len);
1730 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1731 utf8,flags);
1732 OUTPUT:
1733 RETVAL
1734
02d1d628
AMH
1735
1736void
1bd75e4c 1737i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
02d1d628
AMH
1738 int fontnum
1739 float point
1bd75e4c
TC
1740 SV* str_sv
1741 int utf8
1742 char* flags
02d1d628 1743 PREINIT:
1bd75e4c
TC
1744 char *str;
1745 STRLEN len;
3799c4d1 1746 int cords[BOUNDING_BOX_COUNT];
1bd75e4c 1747 int i;
3799c4d1 1748 int rc;
02d1d628 1749 PPCODE:
1bd75e4c
TC
1750#ifdef SvUTF8
1751 if (SvUTF8(str_sv))
1752 utf8 = 1;
1753#endif
1754 str = SvPV(str_sv, len);
3799c4d1
TC
1755 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1756 if (rc > 0) {
1757 EXTEND(SP, rc);
1758 for (i = 0; i < rc; ++i)
1759 PUSHs(sv_2mortal(newSViv(cords[i])));
1760 }
02d1d628
AMH
1761
1762
1763
1764undef_int
1bd75e4c 1765i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
02d1d628
AMH
1766 Imager::ImgRaw im
1767 int xb
1768 int yb
1769 Imager::Color cl
1770 int fontnum
1771 float points
1bd75e4c 1772 SV* str_sv
02d1d628 1773 int align
1bd75e4c
TC
1774 int utf8
1775 char* flags
1776 PREINIT:
1777 char *str;
1778 STRLEN len;
1779 CODE:
1780#ifdef SvUTF8
1781 if (SvUTF8(str_sv))
1782 utf8 = 1;
1783#endif
1784 str = SvPV(str_sv, len);
1785 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1786 utf8,flags);
1787 OUTPUT:
1788 RETVAL
02d1d628 1789
3799c4d1
TC
1790void
1791i_t1_has_chars(handle, text_sv, utf8 = 0)
1792 int handle
1793 SV *text_sv
1794 int utf8
1795 PREINIT:
1796 char const *text;
1797 STRLEN len;
1798 char *work;
1799 int count;
1800 int i;
1801 PPCODE:
1802#ifdef SvUTF8
1803 if (SvUTF8(text_sv))
1804 utf8 = 1;
1805#endif
1806 text = SvPV(text_sv, len);
1807 work = mymalloc(len);
1808 count = i_t1_has_chars(handle, text, len, utf8, work);
1809 if (GIMME_V == G_ARRAY) {
1810 EXTEND(SP, count);
1811 for (i = 0; i < count; ++i) {
1812 PUSHs(sv_2mortal(newSViv(work[i])));
1813 }
1814 }
1815 else {
1816 EXTEND(SP, 1);
1817 PUSHs(sv_2mortal(newSVpv(work, count)));
1818 }
1819 myfree(work);
1820
1821void
1822i_t1_face_name(handle)
1823 int handle
1824 PREINIT:
1825 char name[255];
1826 int len;
1827 PPCODE:
1828 len = i_t1_face_name(handle, name, sizeof(name));
1829 if (len) {
1830 EXTEND(SP, 1);
1831 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1832 }
1833
19fa4baf
AMH
1834void
1835i_t1_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
1836 int handle
1837 SV *text_sv
1838 int utf8
1839 PREINIT:
1840 char const *text;
1841 STRLEN work_len;
1842 int len;
1843 int outsize;
1844 char name[255];
1845 PPCODE:
1846#ifdef SvUTF8
1847 if (SvUTF8(text_sv))
1848 utf8 = 1;
1849#endif
1850 text = SvPV(text_sv, work_len);
1851 len = work_len;
1852 while (len) {
1853 unsigned char ch;
1854 if (utf8) {
1855 ch = i_utf8_advance(&text, &len);
1856 if (ch == ~0UL) {
1857 i_push_error(0, "invalid UTF8 character");
1858 break;
1859 }
1860 }
1861 else {
1862 ch = *text++;
1863 --len;
1864 }
1865 EXTEND(SP, 1);
1866 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1867 PUSHs(sv_2mortal(newSVpv(name, 0)));
1868 }
1869 else {
1870 PUSHs(&PL_sv_undef);
1871 }
1872 }
1873
02d1d628
AMH
1874#endif
1875
1876#ifdef HAVE_LIBTT
1877
1878
4b19f77a 1879Imager::Font::TT
02d1d628
AMH
1880i_tt_new(fontname)
1881 char* fontname
1882
4b19f77a
AMH
1883
1884MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1885
1886#define TT_DESTROY(handle) i_tt_destroy(handle)
1887
02d1d628 1888void
4b19f77a
AMH
1889TT_DESTROY(handle)
1890 Imager::Font::TT handle
1891
02d1d628 1892
4b19f77a 1893MODULE = Imager PACKAGE = Imager
02d1d628
AMH
1894
1895
1896undef_int
4f68b48f 1897i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
4b19f77a 1898 Imager::Font::TT handle
02d1d628
AMH
1899 Imager::ImgRaw im
1900 int xb
1901 int yb
1902 Imager::Color cl
1903 float points
4f68b48f
TC
1904 SV * str_sv
1905 int len_ignored
02d1d628 1906 int smooth
4f68b48f
TC
1907 int utf8
1908 PREINIT:
1909 char *str;
1910 STRLEN len;
1911 CODE:
1912#ifdef SvUTF8
1913 if (SvUTF8(str_sv))
1914 utf8 = 1;
1915#endif
1916 str = SvPV(str_sv, len);
1917 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1918 len, smooth, utf8);
1919 OUTPUT:
1920 RETVAL
02d1d628
AMH
1921
1922
1923undef_int
4f68b48f 1924i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
4b19f77a 1925 Imager::Font::TT handle
02d1d628
AMH
1926 Imager::ImgRaw im
1927 int xb
1928 int yb
1929 int channel
1930 float points
4f68b48f
TC
1931 SV * str_sv
1932 int len_ignored
02d1d628 1933 int smooth
4f68b48f
TC
1934 int utf8
1935 PREINIT:
1936 char *str;
1937 STRLEN len;
1938 CODE:
1939#ifdef SvUTF8
1940 if (SvUTF8(str_sv))
1941 utf8 = 1;
1942#endif
1943 str = SvPV(str_sv, len);
1944 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1945 smooth, utf8);
1946 OUTPUT:
1947 RETVAL
02d1d628
AMH
1948
1949
1950undef_int
4f68b48f 1951i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
4b19f77a 1952 Imager::Font::TT handle
02d1d628 1953 float point
4f68b48f
TC
1954 SV* str_sv
1955 int len_ignored
1956 int utf8
02d1d628 1957 PREINIT:
3799c4d1 1958 int cords[BOUNDING_BOX_COUNT],rc;
4f68b48f
TC
1959 char * str;
1960 STRLEN len;
3799c4d1 1961 int i;
02d1d628 1962 PPCODE:
4f68b48f
TC
1963#ifdef SvUTF8
1964 if (SvUTF8(ST(2)))
1965 utf8 = 1;
1966#endif
1967 str = SvPV(str_sv, len);
1968 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
3799c4d1
TC
1969 EXTEND(SP, rc);
1970 for (i = 0; i < rc; ++i) {
1971 PUSHs(sv_2mortal(newSViv(cords[i])));
1972 }
02d1d628
AMH
1973 }
1974
eeaa33fd
TC
1975void
1976i_tt_has_chars(handle, text_sv, utf8)
1977 Imager::Font::TT handle
1978 SV *text_sv
1979 int utf8
1980 PREINIT:
1981 char const *text;
1982 STRLEN len;
1983 char *work;
1984 int count;
1985 int i;
1986 PPCODE:
1987#ifdef SvUTF8
1988 if (SvUTF8(text_sv))
1989 utf8 = 1;
1990#endif
1991 text = SvPV(text_sv, len);
1992 work = mymalloc(len);
1993 count = i_tt_has_chars(handle, text, len, utf8, work);
1994 if (GIMME_V == G_ARRAY) {
1995 EXTEND(SP, count);
1996 for (i = 0; i < count; ++i) {
1997 PUSHs(sv_2mortal(newSViv(work[i])));
1998 }
1999 }
2000 else {
2001 EXTEND(SP, 1);
2002 PUSHs(sv_2mortal(newSVpv(work, count)));
2003 }
2004 myfree(work);
02d1d628 2005
3799c4d1
TC
2006void
2007i_tt_dump_names(handle)
2008 Imager::Font::TT handle
02d1d628 2009
3799c4d1
TC
2010void
2011i_tt_face_name(handle)
2012 Imager::Font::TT handle
2013 PREINIT:
2014 char name[255];
2015 int len;
2016 PPCODE:
2017 len = i_tt_face_name(handle, name, sizeof(name));
2018 if (len) {
2019 EXTEND(SP, 1);
2020 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
2021 }
02d1d628 2022
19fa4baf
AMH
2023void
2024i_tt_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
2025 Imager::Font::TT handle
2026 SV *text_sv
2027 int utf8
2028 PREINIT:
2029 char const *text;
2030 STRLEN work_len;
2031 int len;
2032 int outsize;
2033 char name[255];
2034 PPCODE:
2035#ifdef SvUTF8
2036 if (SvUTF8(text_sv))
2037 utf8 = 1;
2038#endif
2039 text = SvPV(text_sv, work_len);
2040 len = work_len;
2041 while (len) {
2042 unsigned char ch;
2043 if (utf8) {
2044 ch = i_utf8_advance(&text, &len);
2045 if (ch == ~0UL) {
2046 i_push_error(0, "invalid UTF8 character");
2047 break;
2048 }
2049 }
2050 else {
2051 ch = *text++;
2052 --len;
2053 }
2054 EXTEND(SP, 1);
2055 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2056 PUSHs(sv_2mortal(newSVpv(name, 0)));
2057 }
2058 else {
2059 PUSHs(&PL_sv_undef);
2060 }
2061 }
2062
2063#endif
02d1d628
AMH
2064
2065
2066#ifdef HAVE_LIBJPEG
2067undef_int
dd55acc8 2068i_writejpeg_wiol(im, ig, qfactor)
02d1d628 2069 Imager::ImgRaw im
dd55acc8 2070 Imager::IO ig
02d1d628
AMH
2071 int qfactor
2072
02d1d628
AMH
2073
2074void
2075i_readjpeg_wiol(ig)
2076 Imager::IO ig
2077 PREINIT:
2078 char* iptc_itext;
2079 int tlength;
2080 i_img* rimg;
2081 SV* r;
2082 PPCODE:
2083 iptc_itext = NULL;
2084 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2085 if (iptc_itext == NULL) {
2086 r = sv_newmortal();
2087 EXTEND(SP,1);
2088 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2089 PUSHs(r);
2090 } else {
2091 r = sv_newmortal();
2092 EXTEND(SP,2);
2093 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2094 PUSHs(r);
2095 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2096 myfree(iptc_itext);
2097 }
2098
2099
2100#endif
2101
2102
e10bf46e
AMH
2103char *
2104i_test_format_probe(ig, length)
2105 Imager::IO ig
2106 int length
2107
02d1d628
AMH
2108
2109
2110#ifdef HAVE_LIBTIFF
2111
2112Imager::ImgRaw
2113i_readtiff_wiol(ig, length)
2114 Imager::IO ig
2115 int length
2116
10461f9a
TC
2117void
2118i_readtiff_multi_wiol(ig, length)
2119 Imager::IO ig
2120 int length
2121 PREINIT:
2122 i_img **imgs;
2123 int count;
2124 int i;
2125 PPCODE:
2126 imgs = i_readtiff_multi_wiol(ig, length, &count);
2127 if (imgs) {
2128 EXTEND(SP, count);
2129 for (i = 0; i < count; ++i) {
2130 SV *sv = sv_newmortal();
2131 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2132 PUSHs(sv);
2133 }
2134 myfree(imgs);
2135 }
2136
02d1d628
AMH
2137
2138undef_int
2139i_writetiff_wiol(im, ig)
2140 Imager::ImgRaw im
2141 Imager::IO ig
2142
10461f9a
TC
2143undef_int
2144i_writetiff_multi_wiol(ig, ...)
2145 Imager::IO ig
2146 PREINIT:
2147 int i;
2148 int img_count;
2149 i_img **imgs;
2150 CODE:
2151 if (items < 2)
2152 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2153 img_count = items - 1;
2154 RETVAL = 1;
2155 if (img_count < 1) {
2156 RETVAL = 0;
2157 i_clear_error();
2158 i_push_error(0, "You need to specify images to save");
2159 }
2160 else {
2161 imgs = mymalloc(sizeof(i_img *) * img_count);
2162 for (i = 0; i < img_count; ++i) {
2163 SV *sv = ST(1+i);
2164 imgs[i] = NULL;
2165 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2166 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2167 }
2168 else {
2169 i_clear_error();
2170 i_push_error(0, "Only images can be saved");
2171 myfree(imgs);
2172 RETVAL = 0;
2173 break;
2174 }
2175 }
2176 if (RETVAL) {
2177 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2178 }
2179 myfree(imgs);
2180 }
2181 OUTPUT:
2182 RETVAL
2183
d2dfdcc9 2184undef_int
4c2d6970 2185i_writetiff_wiol_faxable(im, ig, fine)
d2dfdcc9
TC
2186 Imager::ImgRaw im
2187 Imager::IO ig
4c2d6970 2188 int fine
d2dfdcc9 2189
10461f9a
TC
2190undef_int
2191i_writetiff_multi_wiol_faxable(ig, fine, ...)
2192 Imager::IO ig
2193 int fine
2194 PREINIT:
2195 int i;
2196 int img_count;
2197 i_img **imgs;
2198 CODE:
2199 if (items < 3)
2200 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2201 img_count = items - 2;
2202 RETVAL = 1;
2203 if (img_count < 1) {
2204 RETVAL = 0;
2205 i_clear_error();
2206 i_push_error(0, "You need to specify images to save");
2207 }
2208 else {
2209 imgs = mymalloc(sizeof(i_img *) * img_count);
2210 for (i = 0; i < img_count; ++i) {
2211 SV *sv = ST(2+i);
2212 imgs[i] = NULL;
2213 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2214 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2215 }
2216 else {
2217 i_clear_error();
2218 i_push_error(0, "Only images can be saved");
2219 myfree(imgs);
2220 RETVAL = 0;
2221 break;
2222 }
2223 }
2224 if (RETVAL) {
2225 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2226 }
2227 myfree(imgs);
2228 }
2229 OUTPUT:
2230 RETVAL
02d1d628
AMH
2231
2232
10461f9a 2233#endif /* HAVE_LIBTIFF */
02d1d628
AMH
2234
2235
2236#ifdef HAVE_LIBPNG
2237
2238Imager::ImgRaw
790923a4
AMH
2239i_readpng_wiol(ig, length)
2240 Imager::IO ig
2241 int length
02d1d628
AMH
2242
2243
2244undef_int
790923a4 2245i_writepng_wiol(im, ig)
02d1d628 2246 Imager::ImgRaw im
790923a4 2247 Imager::IO ig
02d1d628
AMH
2248
2249
2250#endif
2251
2252
2253#ifdef HAVE_LIBGIF
2254
03bd24d4
TC
2255void
2256i_giflib_version()
2257 PPCODE:
2258 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2259
02d1d628
AMH
2260undef_int
2261i_writegif(im,fd,colors,pixdev,fixed)
2262 Imager::ImgRaw im
2263 int fd
2264 int colors
2265 int pixdev
2266 PREINIT:
2267 int fixedlen;
2268 Imager__Color fixed;
2269 Imager__Color tmp;
2270 AV* av;
2271 SV* sv1;
2272 IV Itmp;
2273 int i;
2274 CODE:
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 = (i_color*) Itmp;
2285 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2286 fixed[i]=*tmp;
2287 }
2288 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2289 myfree(fixed);
2290 ST(0) = sv_newmortal();
2291 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2292 else sv_setiv(ST(0), (IV)RETVAL);
2293
2294
2295
2296
2297undef_int
2298i_writegifmc(im,fd,colors)
067d6bdc 2299 Imager::ImgRaw im
02d1d628
AMH
2300 int fd
2301 int colors
2302
02d1d628
AMH
2303
2304undef_int
2305i_writegif_gen(fd, ...)
2306 int fd
2307 PROTOTYPE: $$@
2308 PREINIT:
2309 i_quantize quant;
02d1d628
AMH
2310 i_img **imgs = NULL;
2311 int img_count;
2312 int i;
2313 HV *hv;
2314 CODE:
2315 if (items < 3)
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;
02d1d628 2322 handle_quant_opts(&quant, hv);
02d1d628
AMH
2323 img_count = items - 2;
2324 RETVAL = 1;
2325 if (img_count < 1) {
2326 RETVAL = 0;
95b44a76
TC
2327 i_clear_error();
2328 i_push_error(0, "You need to specify images to save");
02d1d628
AMH
2329 }
2330 else {
2331 imgs = mymalloc(sizeof(i_img *) * img_count);
2332 for (i = 0; i < img_count; ++i) {
2333 SV *sv = ST(2+i);
2334 imgs[i] = NULL;
2335 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2336 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
02d1d628
AMH
2337 }
2338 else {
95b44a76
TC
2339 i_clear_error();
2340 i_push_error(0, "Only images can be saved");
02d1d628
AMH
2341 RETVAL = 0;
2342 break;
2343 }
2344 }
2345 if (RETVAL) {
97c4effc 2346 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
02d1d628
AMH
2347 }
2348 myfree(imgs);
2349 if (RETVAL) {
2350 copy_colors_back(hv, &quant);
2351 }
2352 }
a73aeb5f
AMH
2353 ST(0) = sv_newmortal();
2354 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2355 else sv_setiv(ST(0), (IV)RETVAL);
46a04ceb 2356 cleanup_quant_opts(&quant);
a73aeb5f 2357
02d1d628
AMH
2358
2359undef_int
2360i_writegif_callback(cb, maxbuffer,...)
2361 int maxbuffer;
2362 PREINIT:
2363 i_quantize quant;
02d1d628
AMH
2364 i_img **imgs = NULL;
2365 int img_count;
2366 int i;
2367 HV *hv;
2368 i_writer_data wd;
2369 CODE:
2370 if (items < 4)
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;
02d1d628 2377 handle_quant_opts(&quant, hv);
02d1d628
AMH
2378 img_count = items - 3;
2379 RETVAL = 1;
2380 if (img_count < 1) {
2381 RETVAL = 0;
2382 }
2383 else {
2384 imgs = mymalloc(sizeof(i_img *) * img_count);
2385 for (i = 0; i < img_count; ++i) {
2386 SV *sv = ST(3+i);
2387 imgs[i] = NULL;
2388 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2389 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
02d1d628
AMH
2390 }
2391 else {
2392 RETVAL = 0;
2393 break;
2394 }
2395 }
2396 if (RETVAL) {
2397 wd.sv = ST(0);
97c4effc 2398 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
02d1d628
AMH
2399 }
2400 myfree(imgs);
2401 if (RETVAL) {
2402 copy_colors_back(hv, &quant);
2403 }
2404 }
46a04ceb
TC
2405 ST(0) = sv_newmortal();
2406 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2407 else sv_setiv(ST(0), (IV)RETVAL);
46a04ceb 2408 cleanup_quant_opts(&quant);
02d1d628 2409
10461f9a
TC
2410undef_int
2411i_writegif_wiol(ig, opts,...)
2412 Imager::IO ig
2413 PREINIT:
2414 i_quantize quant;
10461f9a
TC
2415 i_img **imgs = NULL;
2416 int img_count;
2417 int i;
2418 HV *hv;
2419 CODE:
2420 if (items < 3)
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;
10461f9a 2427 handle_quant_opts(&quant, hv);
10461f9a
TC
2428 img_count = items - 2;
2429 RETVAL = 1;
2430 if (img_count < 1) {
2431 RETVAL = 0;
2432 }
2433 else {
2434 imgs = mymalloc(sizeof(i_img *) * img_count);
2435 for (i = 0; i < img_count; ++i) {
2436 SV *sv = ST(2+i);
2437 imgs[i] = NULL;
2438 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2439 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2440 }
2441 else {
2442 RETVAL = 0;
2443 break;
2444 }
2445 }
2446 if (RETVAL) {
97c4effc 2447 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
10461f9a
TC
2448 }
2449 myfree(imgs);
2450 if (RETVAL) {
2451 copy_colors_back(hv, &quant);
2452 }
2453 }
2454 ST(0) = sv_newmortal();
2455 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2456 else sv_setiv(ST(0), (IV)RETVAL);
10461f9a
TC
2457 cleanup_quant_opts(&quant);
2458
02d1d628
AMH
2459void
2460i_readgif(fd)
2461 int fd
2462 PREINIT:
2463 int* colour_table;
2464 int colours, q, w;
2465 i_img* rimg;
2466 SV* temp[3];
2467 AV* ct;
2468 SV* r;
2469 PPCODE:
2470 colour_table = NULL;
2471 colours = 0;
2472
895dbd34 2473 if(GIMME_V == G_ARRAY) {
02d1d628
AMH
2474 rimg = i_readgif(fd,&colour_table,&colours);
2475 } else {
2476 /* don't waste time with colours if they aren't wanted */
2477 rimg = i_readgif(fd,NULL,NULL);
2478 }
895dbd34 2479
02d1d628
AMH
2480 if (colour_table == NULL) {
2481 EXTEND(SP,1);
2482 r=sv_newmortal();
2483 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2484 PUSHs(r);
2485 } else {
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 */
2490
2491 ct=newAV();
2492 av_extend(ct, colours);
2493 for(q=0; q<colours; q++) {
2494 for(w=0; w<3; w++)
2495 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2496 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2497 }
2498 myfree(colour_table);
895dbd34 2499
02d1d628 2500 EXTEND(SP,2);
895dbd34 2501 r = sv_newmortal();
02d1d628
AMH
2502 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2503 PUSHs(r);
2504 PUSHs(newRV_noinc((SV*)ct));
2505 }
2506
10461f9a
TC
2507void
2508i_readgif_wiol(ig)
2509 Imager::IO ig
2510 PREINIT:
2511 int* colour_table;
2512 int colours, q, w;
2513 i_img* rimg;
2514 SV* temp[3];
2515 AV* ct;
2516 SV* r;
2517 PPCODE:
2518 colour_table = NULL;
2519 colours = 0;
02d1d628 2520
10461f9a
TC
2521 if(GIMME_V == G_ARRAY) {
2522 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2523 } else {
2524 /* don't waste time with colours if they aren't wanted */
2525 rimg = i_readgif_wiol(ig,NULL,NULL);
2526 }
2527
2528 if (colour_table == NULL) {
2529 EXTEND(SP,1);
2530 r=sv_newmortal();
2531 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2532 PUSHs(r);
2533 } else {
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 */
02d1d628 2538
10461f9a
TC
2539 ct=newAV();
2540 av_extend(ct, colours);
2541 for(q=0; q<colours; q++) {
2542 for(w=0; w<3; w++)
2543 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2544 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2545 }
2546 myfree(colour_table);
02d1d628 2547
10461f9a
TC
2548 EXTEND(SP,2);
2549 r = sv_newmortal();
2550 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2551 PUSHs(r);
2552 PUSHs(newRV_noinc((SV*)ct));
2553 }
02d1d628
AMH
2554
2555void
2556i_readgif_scalar(...)
2557 PROTOTYPE: $
2558 PREINIT:
2559 char* data;
21e952df 2560 STRLEN length;
02d1d628
AMH
2561 int* colour_table;
2562 int colours, q, w;
2563 i_img* rimg;
2564 SV* temp[3];
2565 AV* ct;
2566 SV* r;
2567 PPCODE:
2568 data = (char *)SvPV(ST(0), length);
2569 colour_table=NULL;
2570 colours=0;
2571
2572 if(GIMME_V == G_ARRAY) {
2573 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2574 } else {
2575 /* don't waste time with colours if they aren't wanted */
2576 rimg=i_readgif_scalar(data,length,NULL,NULL);
2577 }
2578
2579 if (colour_table == NULL) {
2580 EXTEND(SP,1);
2581 r=sv_newmortal();
2582 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2583 PUSHs(r);
2584 } else {
2585 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2586 /* I don't know if I have the reference counts right or not :( */
2587 /* Neither do I :-) */
2588 ct=newAV();
2589 av_extend(ct, colours);
2590 for(q=0; q<colours; q++) {
2591 for(w=0; w<3; w++)
2592 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2593 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2594 }
2595 myfree(colour_table);
2596
2597 EXTEND(SP,2);
2598 r=sv_newmortal();
2599 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2600 PUSHs(r);
2601 PUSHs(newRV_noinc((SV*)ct));
2602 }
2603
2604void
2605i_readgif_callback(...)
2606 PROTOTYPE: &
2607 PREINIT:
2608 char* data;
2609 int length;
2610 int* colour_table;
2611 int colours, q, w;
2612 i_img* rimg;
2613 SV* temp[3];
2614 AV* ct;
2615 SV* r;
2616 i_reader_data rd;
2617 PPCODE:
2618 rd.sv = ST(0);
2619 colour_table=NULL;
2620 colours=0;
2621
2622 if(GIMME_V == G_ARRAY) {
2623 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2624 } else {
2625 /* don't waste time with colours if they aren't wanted */
2626 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2627 }
2628
2629 if (colour_table == NULL) {
2630 EXTEND(SP,1);
2631 r=sv_newmortal();
2632 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2633 PUSHs(r);
2634 } else {
2635 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2636 /* I don't know if I have the reference counts right or not :( */
2637 /* Neither do I :-) */
2638 /* Neither do I - maybe I'll move this somewhere */
2639 ct=newAV();
2640 av_extend(ct, colours);
2641 for(q=0; q<colours; q++) {
2642 for(w=0; w<3; w++)
2643 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2644 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2645 }
2646 myfree(colour_table);
2647
2648 EXTEND(SP,2);
2649 r=sv_newmortal();
2650 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2651 PUSHs(r);
2652 PUSHs(newRV_noinc((SV*)ct));
2653 }
2654
faa9b3e7
TC
2655void
2656i_readgif_multi(fd)
2657 int fd
2658 PREINIT:
2659 i_img **imgs;
2660 int count;
2661 int i;
2662 PPCODE:
2663 imgs = i_readgif_multi(fd, &count);
2664 if (imgs) {
2665 EXTEND(SP, count);
2666 for (i = 0; i < count; ++i) {
2667 SV *sv = sv_newmortal();
2668 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2669 PUSHs(sv);
2670 }
2671 myfree(imgs);
2672 }
02d1d628 2673
faa9b3e7
TC
2674void
2675i_readgif_multi_scalar(data)
2676 PREINIT:
2677 i_img **imgs;
2678 int count;
2679 char *data;
21e952df 2680 STRLEN length;
faa9b3e7
TC
2681 int i;
2682 PPCODE:
2683 data = (char *)SvPV(ST(0), length);
2684 imgs = i_readgif_multi_scalar(data, length, &count);
2685 if (imgs) {
2686 EXTEND(SP, count);
2687 for (i = 0; i < count; ++i) {
2688 SV *sv = sv_newmortal();
2689 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2690 PUSHs(sv);
2691 }
2692 myfree(imgs);
2693 }
02d1d628 2694
faa9b3e7
TC
2695void
2696i_readgif_multi_callback(cb)
2697 PREINIT:
2698 i_reader_data rd;
2699 i_img **imgs;
2700 int count;
2701 int i;
2702 PPCODE:
2703 rd.sv = ST(0);
2704 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2705 if (imgs) {
2706 EXTEND(SP, count);
2707 for (i = 0; i < count; ++i) {
2708 SV *sv = sv_newmortal();
2709 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2710 PUSHs(sv);
2711 }
2712 myfree(imgs);
2713 }
02d1d628 2714
10461f9a
TC
2715void
2716i_readgif_multi_wiol(ig)
2717 Imager::IO ig
2718 PREINIT:
2719 i_img **imgs;
2720 int count;
2721 int i;
2722 PPCODE:
2723 imgs = i_readgif_multi_wiol(ig, &count);
2724 if (imgs) {
2725 EXTEND(SP, count);
2726 for (i = 0; i < count; ++i) {
2727 SV *sv = sv_newmortal();
2728 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2729 PUSHs(sv);
2730 }
2731 myfree(imgs);
2732 }
2733
2734
02d1d628
AMH
2735#endif
2736
2737
2738
2739Imager::ImgRaw
2740i_readpnm_wiol(ig, length)
2741 Imager::IO ig
2742 int length
2743
2744
067d6bdc
AMH
2745undef_int
2746i_writeppm_wiol(im, ig)
2747 Imager::ImgRaw im
2748 Imager::IO ig
2749
2750
02d1d628 2751Imager::ImgRaw
895dbd34
AMH
2752i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2753 Imager::IO ig
02d1d628
AMH
2754 int x
2755 int y
2756 int datachannels
2757 int storechannels
2758 int intrl
2759
2760undef_int
895dbd34 2761i_writeraw_wiol(im,ig)
02d1d628 2762 Imager::ImgRaw im
895dbd34
AMH
2763 Imager::IO ig
2764
261f91c5
TC
2765undef_int
2766i_writebmp_wiol(im,ig)
2767 Imager::ImgRaw im
2768 Imager::IO ig
02d1d628 2769
705fd961
TC
2770Imager::ImgRaw
2771i_readbmp_wiol(ig)
2772 Imager::IO ig
2773
1ec86afa
AMH
2774
2775undef_int
febba01f 2776i_writetga_wiol(im,ig, wierdpack, compress, idstring)
1ec86afa
AMH
2777 Imager::ImgRaw im
2778 Imager::IO ig
febba01f
AMH
2779 int wierdpack
2780 int compress
2781 char* idstring
2782 PREINIT:
febba01f
AMH
2783 int idlen;
2784 CODE:
2785 idlen = SvCUR(ST(4));
2786 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2787 OUTPUT:
2788 RETVAL
2789
1ec86afa
AMH
2790
2791Imager::ImgRaw
2792i_readtga_wiol(ig, length)
2793 Imager::IO ig
2794 int length
2795
2796
737a830c
AMH
2797undef_int
2798i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2799 Imager::ImgRaw im
2800 Imager::IO ig
2801 int wierdpack
2802 int compress
2803 char* idstring
2804 PREINIT:
737a830c
AMH
2805 int idlen;
2806 CODE:
2807 idlen = SvCUR(ST(4));
2808 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2809 OUTPUT:
2810 RETVAL
2811
2812
2813Imager::ImgRaw
2814i_readrgb_wiol(ig, length)
2815 Imager::IO ig
2816 int length
2817
2818
2819
02d1d628
AMH
2820Imager::ImgRaw
2821i_scaleaxis(im,Value,Axis)
2822 Imager::ImgRaw im
2823 float Value
2824 int Axis
2825
2826Imager::ImgRaw
2827i_scale_nn(im,scx,scy)
2828 Imager::ImgRaw im
2829 float scx
2830 float scy
2831
2832Imager::ImgRaw
2833i_haar(im)
2834 Imager::ImgRaw im
2835
2836int
2837i_count_colors(im,maxc)
2838 Imager::ImgRaw im
2839 int maxc
2840
2841
2842Imager::ImgRaw
2843i_transform(im,opx,opy,parm)
2844 Imager::ImgRaw im
2845 PREINIT:
2846 double* parm;
2847 int* opx;
2848 int* opy;
2849 int opxl;
2850 int opyl;
2851 int parmlen;
2852 AV* av;
2853 SV* sv1;
2854 int i;
2855 CODE:
2856 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2857 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2858 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2859 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2860 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2861 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2862 av=(AV*)SvRV(ST(1));
2863 opxl=av_len(av)+1;
2864 opx=mymalloc( opxl*sizeof(int) );
2865 for(i=0;i<opxl;i++) {
2866 sv1=(*(av_fetch(av,i,0)));
2867 opx[i]=(int)SvIV(sv1);
2868 }
2869 av=(AV*)SvRV(ST(2));
2870 opyl=av_len(av)+1;
2871 opy=mymalloc( opyl*sizeof(int) );
2872 for(i=0;i<opyl;i++) {
2873 sv1=(*(av_fetch(av,i,0)));
2874 opy[i]=(int)SvIV(sv1);
2875 }
2876 av=(AV*)SvRV(ST(3));
2877 parmlen=av_len(av)+1;
2878 parm=mymalloc( parmlen*sizeof(double) );
2879 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2880 sv1=(*(av_fetch(av,i,0)));
2881 parm[i]=(double)SvNV(sv1);
2882 }
2883 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2884 myfree(parm);
2885 myfree(opy);
2886 myfree(opx);
2887 ST(0) = sv_newmortal();
2888 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2889 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2890
2891Imager::ImgRaw
e5744e01
TC
2892i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
2893 SV *sv_width
2894 SV *sv_height
2895 SV *sv_ops
2896 AV *av_n_regs
2897 AV *av_c_regs
2898 AV *av_in_imgs
2899 int channels
02d1d628
AMH
2900 PREINIT:
2901 int width;
2902 int height;
02d1d628 2903 struct rm_op *ops;
953209f8 2904 STRLEN ops_len;
02d1d628
AMH
2905 int ops_count;
2906 double *n_regs;
2907 int n_regs_count;
2908 i_color *c_regs;
2909 int c_regs_count;
2910 int in_imgs_count;
2911 i_img **in_imgs;
ea9e6c3f 2912 SV *sv1;
02d1d628
AMH
2913 IV tmp;
2914 int i;
2915 CODE:
e5744e01
TC
2916
2917 in_imgs_count = av_len(av_in_imgs)+1;
2918 for (i = 0; i < in_imgs_count; ++i) {
2919 sv1 = *av_fetch(av_in_imgs, i, 0);
2920 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2921 croak("sv_in_img must contain only images");
02d1d628
AMH
2922 }
2923 }
b8c2033e 2924 if (in_imgs_count > 0) {
02d1d628
AMH
2925 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2926 for (i = 0; i < in_imgs_count; ++i) {
e5744e01 2927 sv1 = *av_fetch(av_in_imgs,i,0);
02d1d628
AMH
2928 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2929 croak("Parameter 5 must contain only images");
2930 }
2931 tmp = SvIV((SV*)SvRV(sv1));
e375fbd8 2932 in_imgs[i] = INT2PTR(i_img*, tmp);
02d1d628
AMH
2933 }
2934 }
2935 else {
2936 /* no input images */
2937 in_imgs = NULL;
2938 }
2939 /* default the output size from the first input if possible */
e5744e01
TC
2940 if (SvOK(sv_width))
2941 width = SvIV(sv_width);
02d1d628
AMH
2942 else if (in_imgs_count)
2943 width = in_imgs[0]->xsize;
2944 else
2945 croak("No output image width supplied");
2946
e5744e01
TC
2947 if (SvOK(sv_height))
2948 height = SvIV(sv_height);
02d1d628
AMH
2949 else if (in_imgs_count)
2950 height = in_imgs[0]->ysize;
2951 else
2952 croak("No output image height supplied");
2953
e5744e01 2954 ops = (struct rm_op *)SvPV(sv_ops, ops_len);
02d1d628
AMH
2955 if (ops_len % sizeof(struct rm_op))
2956 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2957 ops_count = ops_len / sizeof(struct rm_op);
e5744e01
TC
2958
2959 n_regs_count = av_len(av_n_regs)+1;
02d1d628
AMH
2960 n_regs = mymalloc(n_regs_count * sizeof(double));
2961 for (i = 0; i < n_regs_count; ++i) {
e5744e01 2962 sv1 = *av_fetch(av_n_regs,i,0);
02d1d628
AMH
2963 if (SvOK(sv1))
2964 n_regs[i] = SvNV(sv1);
2965 }
e5744e01 2966 c_regs_count = av_len(av_c_regs)+1;
02d1d628
AMH
2967 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2968 /* I don't bother initializing the colou?r registers */
2969
e5744e01 2970 RETVAL=i_transform2(width, height, channels, ops, ops_count,
02d1d628
AMH
2971 n_regs, n_regs_count,
2972 c_regs, c_regs_count, in_imgs, in_imgs_count);
2973 if (in_imgs)
2974 myfree(in_imgs);
2975 myfree(n_regs);
2976 myfree(c_regs);
2977 ST(0) = sv_newmortal();
2978 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2979 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2980
2981
2982void
2983i_contrast(im,intensity)
2984 Imager::ImgRaw im
2985 float intensity
2986
2987void
2988i_hardinvert(im)
2989 Imager::ImgRaw im
2990
2991void
2992i_noise(im,amount,type)
2993 Imager::ImgRaw im
2994 float amount
2995 unsigned char type
2996
2997void
2998i_bumpmap(im,bump,channel,light_x,light_y,strength)
2999 Imager::ImgRaw im
3000 Imager::ImgRaw bump
3001 int channel
3002 int light_x
3003 int light_y
3004 int strength
3005
b2778574
AMH
3006
3007void
3008i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3009 Imager::ImgRaw im
3010 Imager::ImgRaw bump
3011 int channel
3012 int tx
3013 int ty
3014 float Lx
3015 float Ly
3016 float Lz
3017 float cd
3018 float cs
3019 float n
3020 Imager::Color Ia
3021 Imager::Color Il
3022 Imager::Color Is
3023
3024
3025
02d1d628
AMH
3026void
3027i_postlevels(im,levels)
3028 Imager::ImgRaw im
3029 int levels
3030
3031void
3032i_mosaic(im,size)
3033 Imager::ImgRaw im
3034 int size
3035
3036void
3037i_watermark(im,wmark,tx,ty,pixdiff)
3038 Imager::ImgRaw im
3039 Imager::ImgRaw wmark
3040 int tx
3041 int ty
3042 int pixdiff
3043
3044
3045void
3046i_autolevels(im,lsat,usat,skew)
3047 Imager::ImgRaw im
3048 float lsat
3049 float usat
3050 float skew
3051
3052void
3053i_radnoise(im,xo,yo,rscale,ascale)
3054 Imager::ImgRaw im
3055 float xo
3056 float yo
3057 float rscale
3058 float ascale
3059
3060void
3061i_turbnoise(im, xo, yo, scale)
3062 Imager::ImgRaw im
3063 float xo
3064 float yo
3065 float scale
3066
3067
3068void
3069i_gradgen(im, ...)
3070 Imager::ImgRaw im
3071 PREINIT:
3072 int num;
3073 int *xo;
3074 int *yo;
3075 i_color *ival;
3076 int dmeasure;
3077 int i;
3078 SV *sv;
3079 AV *axx;
3080 AV *ayy;
3081 AV *ac;
3082 CODE:
3083 if (items != 5)
3084 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3085 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3086 croak("i_gradgen: Second argument must be an array ref");
3087 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3088 croak("i_gradgen: Third argument must be an array ref");
3089 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3090 croak("i_gradgen: Fourth argument must be an array ref");
3091 axx = (AV *)SvRV(ST(1));
3092 ayy = (AV *)SvRV(ST(2));
3093 ac = (AV *)SvRV(ST(3));
3094 dmeasure = (int)SvIV(ST(4));
3095
3096 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3097 num = num <= av_len(ac) ? num : av_len(ac);
3098 num++;
3099 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3100 xo = mymalloc( sizeof(int) * num );
3101 yo = mymalloc( sizeof(int) * num );
3102 ival = mymalloc( sizeof(i_color) * num );
3103 for(i = 0; i<num; i++) {
3104 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3105 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3106 sv = *av_fetch(ac, i, 0);
3107 if ( !sv_derived_from(sv, "Imager::Color") ) {
3108 free(axx); free(ayy); free(ac);
3109 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3110 }
4c4c2ffd 3111 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
02d1d628
AMH
3112 }
3113 i_gradgen(im, num, xo, yo, ival, dmeasure);
a73aeb5f
AMH
3114 myfree(xo);
3115 myfree(yo);
3116 myfree(ival);
3117
dff75dee
TC
3118Imager::ImgRaw
3119i_diff_image(im, im2, mindist=0)
3120 Imager::ImgRaw im
3121 Imager::ImgRaw im2
3122 int mindist
02d1d628 3123
6607600c
TC
3124void
3125i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3126 Imager::ImgRaw im
3127 double xa
3128 double ya
3129 double xb
3130 double yb
3131 int type
3132 int repeat
3133 int combine
3134 int super_sample
3135 double ssample_param
3136 PREINIT:
6607600c 3137 AV *asegs;
6607600c
TC
3138 int count;
3139 i_fountain_seg *segs;
6607600c 3140 CODE:
6607600c
TC
3141 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3142 croak("i_fountain: argument 11 must be an array ref");
3143
3144 asegs = (AV *)SvRV(ST(10));
f1ac5027 3145 segs = load_fount_segs(asegs, &count);
6607600c
TC
3146 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3147 ssample_param, count, segs);
3148 myfree(segs);
02d1d628 3149
f1ac5027
TC
3150Imager::FillHandle
3151i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3152 double xa
3153 double ya
3154 double xb
3155 double yb
3156 int type
3157 int repeat
3158 int combine
3159 int super_sample
3160 double ssample_param
3161 PREINIT:
3162 AV *asegs;
3163 int count;
3164 i_fountain_seg *segs;
3165 CODE:
3166 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3167 croak("i_fountain: argument 11 must be an array ref");
3168
3169 asegs = (AV *)SvRV(ST(9));
3170 segs = load_fount_segs(asegs, &count);
3171 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3172 super_sample, ssample_param, count, segs);
3173 myfree(segs);
3174 OUTPUT:
3175 RETVAL
3176
4f4f776a
TC
3177void
3178i_errors()
3179 PREINIT:
3180 i_errmsg *errors;
3181 int i;
4f4f776a 3182 AV *av;
4f4f776a
TC
3183 SV *sv;
3184 PPCODE:
3185 errors = i_errors();
3186 i = 0;
3187 while (errors[i].msg) {
3188 av = newAV();
3189 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3190 if (!av_store(av, 0, sv)) {
3191 SvREFCNT_dec(sv);
3192 }
3193 sv = newSViv(errors[i].code);
3194 if (!av_store(av, 1, sv)) {
3195 SvREFCNT_dec(sv);
3196 }
3197 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3198 ++i;
3199 }
02d1d628
AMH
3200
3201void
3202i_nearest_color(im, ...)
3203 Imager::ImgRaw im
3204 PREINIT:
3205 int num;
3206 int *xo;
3207 int *yo;
3208 i_color *ival;
3209 int dmeasure;
3210 int i;
3211 SV *sv;
3212 AV *axx;
3213 AV *ayy;
3214 AV *ac;
3215 CODE:
3216 if (items != 5)
3217 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3218 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3219 croak("i_nearest_color: Second argument must be an array ref");
3220 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3221 croak("i_nearest_color: Third argument must be an array ref");
3222 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3223 croak("i_nearest_color: Fourth argument must be an array ref");
3224 axx = (AV *)SvRV(ST(1));
3225 ayy = (AV *)SvRV(ST(2));
3226 ac = (AV *)SvRV(ST(3));
3227 dmeasure = (int)SvIV(ST(4));
3228
3229 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3230 num = num <= av_len(ac) ? num : av_len(ac);
3231 num++;
3232 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3233 xo = mymalloc( sizeof(int) * num );
3234 yo = mymalloc( sizeof(int) * num );
3235 ival = mymalloc( sizeof(i_color) * num );
3236 for(i = 0; i<num; i++) {
3237 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3238 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3239 sv = *av_fetch(ac, i, 0);
3240 if ( !sv_derived_from(sv, "Imager::Color") ) {
3241 free(axx); free(ayy); free(ac);
3242 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3243 }
4c4c2ffd 3244 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
02d1d628
AMH
3245 }
3246 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3247
3248
3249
3250
3251void
3252malloc_state()
3253
3254void
3255hashinfo(hv)
3256 PREINIT:
3257 HV* hv;
3258 int stuff;
3259 PPCODE:
3260 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3261 hv=(HV*)SvRV(ST(0));
3262 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3263 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3264 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3265
3266void
3267DSO_open(filename)
3268 char* filename
3269 PREINIT:
3270 void *rc;
3271 char *evstr;
3272 PPCODE:
3273 rc=DSO_open(filename,&evstr);
3274 if (rc!=NULL) {
3275 if (evstr!=NULL) {
3276 EXTEND(SP,2);
e375fbd8 3277 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
02d1d628
AMH
3278 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3279 } else {
3280 EXTEND(SP,1);
e375fbd8 3281 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
02d1d628
AMH
3282 }
3283 }
3284
3285
3286undef_int
3287DSO_close(dso_handle)
3288 void* dso_handle
3289
3290void
3291DSO_funclist(dso_handle_v)
3292 void* dso_handle_v
3293 PREINIT:
3294 int i;
3295 DSO_handle *dso_handle;
3296 PPCODE:
3297 dso_handle=(DSO_handle*)dso_handle_v;
3298 i=0;
3299 while( dso_handle->function_list[i].name != NULL) {
3300 EXTEND(SP,1);
3301 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3302 EXTEND(SP,1);
3303 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3304 }
3305
3306
3307void
3308DSO_call(handle,func_index,hv)
3309 void* handle
3310 int func_index
3311 PREINIT:
3312 HV* hv;
3313 PPCODE:
3314 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3315 hv=(HV*)SvRV(ST(2));
3316 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3317 DSO_call( (DSO_handle *)handle,func_index,hv);
3318
3319
3320
f5991c03 3321# this is mostly for testing...
ea9e6c3f
TC
3322# this function results in 'RETVAL' : unreferenced local variable
3323# in VC++, and might be subtley wrong
3324# the most obvious change may result in a double free so I'm leaving it
3325# for now
faa9b3e7 3326SV *
f5991c03
TC
3327i_get_pixel(im, x, y)
3328 Imager::ImgRaw im
3329 int x
3330 int y;
faa9b3e7
TC
3331 PREINIT:
3332 i_color *color;
3333 CODE:
3334 color = (i_color *)mymalloc(sizeof(i_color));
3335 if (i_gpix(im, x, y, color) == 0) {
3336 ST(0) = sv_newmortal();
3337 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3338 }
3339 else {
3340 myfree(color);
3341 ST(0) = &PL_sv_undef;
3342 }
3343
3344
3345int
3346i_ppix(im, x, y, cl)
3347 Imager::ImgRaw im
3348 int x
3349 int y
3350 Imager::Color cl
3351
3352Imager::ImgRaw
3353i_img_pal_new(x, y, channels, maxpal)
3354 int x
3355 int y
3356 int channels
3357 int maxpal
3358
3359Imager::ImgRaw
3360i_img_to_pal(src, quant)
3361 Imager::ImgRaw src
3362 PREINIT:
3363 HV *hv;
3364 i_quantize quant;
3365 CODE:
3366 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3367 croak("i_img_to_pal: second argument must be a hash ref");
3368 hv = (HV *)SvRV(ST(1));
3369 memset(&quant, 0, sizeof(quant));
3370 quant.mc_size = 256;
faa9b3e7
TC
3371 handle_quant_opts(&quant, hv);
3372 RETVAL = i_img_to_pal(src, &quant);
3373 if (RETVAL) {
3374 copy_colors_back(hv, &quant);
3375 }
46a04ceb 3376 cleanup_quant_opts(&quant);
faa9b3e7
TC
3377 OUTPUT:
3378 RETVAL
3379
3380Imager::ImgRaw
3381i_img_to_rgb(src)
3382 Imager::ImgRaw src
3383
3384void
3385i_gpal(im, l, r, y)
3386 Imager::ImgRaw im
3387 int l
3388 int r
3389 int y
3390 PREINIT:
3391 i_palidx *work;
3392 int count, i;
3393 PPCODE:
3394 if (l < r) {
3395 work = mymalloc((r-l) * sizeof(i_palidx));
3396 count = i_gpal(im, l, r, y, work);
3397 if (GIMME_V == G_ARRAY) {
3398 EXTEND(SP, count);
3399 for (i = 0; i < count; ++i) {
3400 PUSHs(sv_2mortal(newSViv(work[i])));
3401 }
3402 }
3403 else {
3404 EXTEND(SP, 1);
26fd367b 3405 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
faa9b3e7
TC
3406 }
3407 myfree(work);
3408 }
3409 else {
3410 if (GIMME_V != G_ARRAY) {
3411 EXTEND(SP, 1);
3412 PUSHs(&PL_sv_undef);
3413 }
3414 }
3415
3416int
3417i_ppal(im, l, y, ...)
3418 Imager::ImgRaw im
3419 int l
3420 int y
3421 PREINIT:
3422 i_palidx *work;
ea9e6c3f 3423 int i;
faa9b3e7
TC
3424 CODE:
3425 if (items > 3) {
3426 work = mymalloc(sizeof(i_palidx) * (items-3));
3427 for (i=0; i < items-3; ++i) {
3428 work[i] = SvIV(ST(i+3));
3429 }
3430 RETVAL = i_ppal(im, l, l+items-3, y, work);
3431 myfree(work);
3432 }
3433 else {
3434 RETVAL = 0;
3435 }
3436 OUTPUT:
3437 RETVAL
3438
3439SV *
3440i_addcolors(im, ...)
3441 Imager::ImgRaw im
3442 PREINIT:
3443 int index;
3444 i_color *colors;
3445 int i;
3446 CODE:
3447 if (items < 2)
3448 croak("i_addcolors: no colors to add");
3449 colors = mymalloc((items-1) * sizeof(i_color));
3450 for (i=0; i < items-1; ++i) {
3451 if (sv_isobject(ST(i+1))
3452 && sv_derived_from(ST(i+1), "Imager::Color")) {
3453 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
4c4c2ffd 3454 colors[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3455 }
3456 else {
3457 myfree(colors);
3458 croak("i_plin: pixels must be Imager::Color objects");
3459 }
3460 }
3461 index = i_addcolors(im, colors, items-1);
3462 myfree(colors);
3463 if (index == 0) {
3464 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3465 }
3466 else if (index == -1) {
3467 ST(0) = &PL_sv_undef;
3468 }
3469 else {
3470 ST(0) = sv_2mortal(newSViv(index));
3471 }
3472
1501d9b3 3473undef_int
faa9b3e7
TC
3474i_setcolors(im, index, ...)
3475 Imager::ImgRaw im
3476 int index
3477 PREINIT:
3478 i_color *colors;
3479 int i;
3480 CODE:
3481 if (items < 3)
3482 croak("i_setcolors: no colors to add");
3483 colors = mymalloc((items-2) * sizeof(i_color));
3484 for (i=0; i < items-2; ++i) {
3485 if (sv_isobject(ST(i+2))
3486 && sv_derived_from(ST(i+2), "Imager::Color")) {
3487 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
4c4c2ffd 3488 colors[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3489 }
3490 else {
3491 myfree(colors);
3492 croak("i_setcolors: pixels must be Imager::Color objects");
3493 }
3494 }
3495 RETVAL = i_setcolors(im, index, colors, items-2);
3496 myfree(colors);
1501d9b3
TC
3497 OUTPUT:
3498 RETVAL
faa9b3e7
TC
3499
3500void
3501i_getcolors(im, index, ...)
3502 Imager::ImgRaw im
3503 int index
3504 PREINIT:
3505 i_color *colors;
3506 int count = 1;
3507 int i;
3508 PPCODE:
3509 if (items > 3)
3510 croak("i_getcolors: too many arguments");
3511 if (items == 3)
3512 count = SvIV(ST(2));
3513 if (count < 1)
3514 croak("i_getcolors: count must be positive");
3515 colors = mymalloc(sizeof(i_color) * count);
3516 if (i_getcolors(im, index, colors, count)) {
3517 for (i = 0; i < count; ++i) {
3518 i_color *pv;
3519 SV *sv = sv_newmortal();
3520 pv = mymalloc(sizeof(i_color));
3521 *pv = colors[i];
3522 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3523 PUSHs(sv);
3524 }
3525 }
3526 myfree(colors);
3527
3528
3529SV *
3530i_colorcount(im)
3531 Imager::ImgRaw im
3532 PREINIT:
3533 int count;
3534 CODE:
3535 count = i_colorcount(im);
3536 if (count >= 0) {
3537 ST(0) = sv_2mortal(newSViv(count));
3538 }
3539 else {
3540 ST(0) = &PL_sv_undef;
3541 }
3542
3543SV *
3544i_maxcolors(im)
3545 Imager::ImgRaw im
3546 PREINIT:
3547 int count;
3548 CODE:
3549 count = i_maxcolors(im);
3550 if (count >= 0) {
3551 ST(0) = sv_2mortal(newSViv(count));
3552 }
3553 else {
3554 ST(0) = &PL_sv_undef;
3555 }
3556
3557SV *
3558i_findcolor(im, color)
3559 Imager::ImgRaw im
3560 Imager::Color color
3561 PREINIT:
3562 i_palidx index;
3563 CODE:
3564 if (i_findcolor(im, color, &index)) {
3565 ST(0) = sv_2mortal(newSViv(index));
3566 }
3567 else {
3568 ST(0) = &PL_sv_undef;
3569 }
3570
3571int
3572i_img_bits(im)
3573 Imager::ImgRaw im
3574
3575int
3576i_img_type(im)
3577 Imager::ImgRaw im
3578
3579int
3580i_img_virtual(im)
3581 Imager::ImgRaw im
3582
3583void
3584i_gsamp(im, l, r, y, ...)
3585 Imager::ImgRaw im
3586 int l
3587 int r
3588 int y
3589 PREINIT:
3590 int *chans;
3591 int chan_count;
3592 i_sample_t *data;
3593 int count, i;
3594 PPCODE:
3595 if (items < 5)
3596 croak("No channel numbers supplied to g_samp()");
3597 if (l < r) {
3598 chan_count = items - 4;
3599 chans = mymalloc(sizeof(int) * chan_count);
3600 for (i = 0; i < chan_count; ++i)
3601 chans[i] = SvIV(ST(i+4));
4dfa5522 3602 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
faa9b3e7 3603 count = i_gsamp(im, l, r, y, data, chans, chan_count);
4dfa5522 3604 myfree(chans);
faa9b3e7
TC
3605 if (GIMME_V == G_ARRAY) {
3606 EXTEND(SP, count);
3607 for (i = 0; i < count; ++i)
3608 PUSHs(sv_2mortal(newSViv(data[i])));
3609 }
3610 else {
3611 EXTEND(SP, 1);
26fd367b 3612 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
faa9b3e7 3613 }
a73aeb5f 3614 myfree(data);
faa9b3e7
TC
3615 }
3616 else {
3617 if (GIMME_V != G_ARRAY) {
3618 EXTEND(SP, 1);
3619 PUSHs(&PL_sv_undef);
3620 }
3621 }
3622
a73aeb5f 3623
faa9b3e7
TC
3624Imager::ImgRaw
3625i_img_masked_new(targ, mask, x, y, w, h)
3626 Imager::ImgRaw targ
3627 int x
3628 int y
3629 int w
3630 int h
3631 PREINIT:
3632 i_img *mask;
3633 CODE:
3634 if (SvOK(ST(1))) {
3635 if (!sv_isobject(ST(1))
3636 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3637 croak("i_img_masked_new: parameter 2 must undef or an image");
3638 }
4c4c2ffd 3639 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
faa9b3e7
TC
3640 }
3641 else
3642 mask = NULL;
3643 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3644 OUTPUT:
3645 RETVAL
3646
3647int
3648i_plin(im, l, y, ...)
3649 Imager::ImgRaw im
3650 int l
3651 int y
3652 PREINIT:
3653 i_color *work;
ea9e6c3f 3654 int i;
faa9b3e7
TC
3655 CODE:
3656 if (items > 3) {
3657 work = mymalloc(sizeof(i_color) * (items-3));
3658 for (i=0; i < items-3; ++i) {
3659 if (sv_isobject(ST(i+3))
3660 && sv_derived_from(ST(i+3), "Imager::Color")) {
3661 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
4c4c2ffd 3662 work[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3663 }
3664 else {
3665 myfree(work);
3666 croak("i_plin: pixels must be Imager::Color objects");
3667 }
3668 }
3669 /**(char *)0 = 1;*/
3670 RETVAL = i_plin(im, l, l+items-3, y, work);
3671 myfree(work);
3672 }
3673 else {
3674 RETVAL = 0;
3675 }
3676 OUTPUT:
3677 RETVAL
3678
3679int
3680i_ppixf(im, x, y, cl)
3681 Imager::ImgRaw im
3682 int x
3683 int y
3684 Imager::Color::Float cl
3685
3686void
3687i_gsampf(im, l, r, y, ...)
3688 Imager::ImgRaw im
3689 int l
3690 int r
3691 int y
3692 PREINIT:
3693 int *chans;
3694 int chan_count;
3695 i_fsample_t *data;
3696 int count, i;
3697 PPCODE:
3698 if (items < 5)
3699 croak("No channel numbers supplied to g_sampf()");
3700 if (l < r) {
3701 chan_count = items - 4;
3702 chans = mymalloc(sizeof(int) * chan_count);
3703 for (i = 0; i < chan_count; ++i)
3704 chans[i] = SvIV(ST(i+4));
3705 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3706 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3707 if (GIMME_V == G_ARRAY) {
3708 EXTEND(SP, count);
3709 for (i = 0; i < count; ++i)
3710 PUSHs(sv_2mortal(newSVnv(data[i])));
3711 }
3712 else {
3713 EXTEND(SP, 1);
3714 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3715 }
3716 }
3717 else {
3718 if (GIMME_V != G_ARRAY) {
3719 EXTEND(SP, 1);
3720 PUSHs(&PL_sv_undef);
3721 }
3722 }
3723
3724int
3725i_plinf(im, l, y, ...)
3726 Imager::ImgRaw im
3727 int l
3728 int y
3729 PREINIT:
3730 i_fcolor *work;
ea9e6c3f 3731 int i;
faa9b3e7
TC
3732 CODE:
3733 if (items > 3) {
3734 work = mymalloc(sizeof(i_fcolor) * (items-3));
3735 for (i=0; i < items-3; ++i) {
3736 if (sv_isobject(ST(i+3))
3737 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3738 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
4c4c2ffd 3739 work[i] = *INT2PTR(i_fcolor *, tmp);
faa9b3e7
TC
3740 }
3741 else {
3742 myfree(work);
3743 croak("i_plin: pixels must be Imager::Color::Float objects");
3744 }
3745 }
3746 /**(char *)0 = 1;*/
3747 RETVAL = i_plinf(im, l, l+items-3, y, work);
3748 myfree(work);
3749 }
3750 else {
3751 RETVAL = 0;
3752 }
3753 OUTPUT:
3754 RETVAL
3755
3756SV *
3757i_gpixf(im, x, y)
3758 Imager::ImgRaw im
3759 int x
3760 int y;
3761 PREINIT:
3762 i_fcolor *color;
3763 CODE:
3764 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3765 if (i_gpixf(im, x, y, color) == 0) {
3766 ST(0) = sv_newmortal();
3767 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3768 }
3769 else {
3770 myfree(color);
3771 ST(0) = &PL_sv_undef;
3772 }
3773
3774void
3775i_glin(im, l, r, y)
3776 Imager::ImgRaw im
3777 int l
3778 int r
3779 int y
3780 PREINIT:
3781 i_color *vals;
3782 int count, i;
3783 PPCODE:
3784 if (l < r) {
3785 vals = mymalloc((r-l) * sizeof(i_color));
3786 count = i_glin(im, l, r, y, vals);
3787 EXTEND(SP, count);
3788 for (i = 0; i < count; ++i) {
3789 SV *sv;
3790 i_color *col = mymalloc(sizeof(i_color));
3791 sv = sv_newmortal();
3792 sv_setref_pv(sv, "Imager::Color", (void *)col);
3793 PUSHs(sv);
3794 }
3795 myfree(vals);
3796 }
3797
3798void
3799i_glinf(im, l, r, y)
3800 Imager::ImgRaw im
3801 int l
3802 int r
3803 int y
3804 PREINIT:
3805 i_fcolor *vals;
3806 int count, i;
3807 PPCODE:
3808 if (l < r) {
3809 vals = mymalloc((r-l) * sizeof(i_fcolor));
3810 count = i_glinf(im, l, r, y, vals);
3811 EXTEND(SP, count);
3812 for (i = 0; i < count; ++i) {
3813 SV *sv;
3814 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3815 *col = vals[i];
3816 sv = sv_newmortal();
3817 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3818 PUSHs(sv);
3819 }
3820 myfree(vals);
3821 }
3822
3823Imager::ImgRaw
3824i_img_16_new(x, y, ch)
3825 int x
3826 int y
3827 int ch
3828
365ea842
TC
3829Imager::ImgRaw
3830i_img_double_new(x, y, ch)
3831 int x
3832 int y
3833 int ch
3834
faa9b3e7
TC
3835undef_int
3836i_tags_addn(im, name, code, idata)
3837 Imager::ImgRaw im
3838 int code
3839 int idata
3840 PREINIT:
3841 char *name;
3842 STRLEN len;
3843 CODE:
3844 if (SvOK(ST(1)))
3845 name = SvPV(ST(1), len);
3846 else
3847 name = NULL;
3848 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3849 OUTPUT:
3850 RETVAL
3851
3852undef_int
3853i_tags_add(im, name, code, data, idata)
3854 Imager::ImgRaw im
3855 int code
3856 int idata
3857 PREINIT:
3858 char *name;
3859 char *data;
3860 STRLEN len;
3861 CODE:
3862 if (SvOK(ST(1)))
3863 name = SvPV(ST(1), len);
3864 else
3865 name = NULL;
3866 if (SvOK(ST(3)))
3867 data = SvPV(ST(3), len);
3868 else {
3869 data = NULL;
3870 len = 0;
3871 }
3872 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3873 OUTPUT:
3874 RETVAL
3875
3876SV *
3877i_tags_find(im, name, start)
3878 Imager::ImgRaw im
3879 char *name
3880 int start
3881 PREINIT:
3882 int entry;
3883 CODE:
3884 if (i_tags_find(&im->tags, name, start, &entry)) {
3885 if (entry == 0)
3886 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3887 else
3888 ST(0) = sv_2mortal(newSViv(entry));
3889 } else {
3890 ST(0) = &PL_sv_undef;
3891 }
3892
3893SV *
3894i_tags_findn(im, code, start)
3895 Imager::ImgRaw im
3896 int code
3897 int start
3898 PREINIT:
3899 int entry;
3900 CODE:
3901 if (i_tags_findn(&im->tags, code, start, &entry)) {
3902 if (entry == 0)
3903 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3904 else
3905 ST(0) = sv_2mortal(newSViv(entry));
3906 }
3907 else
3908 ST(0) = &PL_sv_undef;
3909
3910int
3911i_tags_delete(im, entry)
3912 Imager::ImgRaw im
3913 int entry
3914 CODE:
3915 RETVAL = i_tags_delete(&im->tags, entry);
3916 OUTPUT:
3917 RETVAL
3918
3919int
3920i_tags_delbyname(im, name)
3921 Imager::ImgRaw im
3922 char * name
3923 CODE:
3924 RETVAL = i_tags_delbyname(&im->tags, name);
3925 OUTPUT:
3926 RETVAL
3927
3928int
3929i_tags_delbycode(im, code)
3930 Imager::ImgRaw im
3931 int code
3932 CODE:
3933 RETVAL = i_tags_delbycode(&im->tags, code);
3934 OUTPUT:
3935 RETVAL
3936
3937void
3938i_tags_get(im, index)
3939 Imager::ImgRaw im
3940 int index
3941 PPCODE:
3942 if (index >= 0 && index < im->tags.count) {
3943 i_img_tag *entry = im->tags.tags + index;
3944 EXTEND(SP, 5);
3945
3946 if (entry->name) {
3947 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3948 }
3949 else {
3950 PUSHs(sv_2mortal(newSViv(entry->code)));
3951 }
3952 if (entry->data) {
3953 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3954 }
3955 else {
3956 PUSHs(sv_2mortal(newSViv(entry->idata)));
3957 }
3958 }
3959
3960int
3961i_tags_count(im)
3962 Imager::ImgRaw im
3963 CODE:
3964 RETVAL = im->tags.count;
3965 OUTPUT:
3966 RETVAL
3967
3968#ifdef HAVE_WIN32
3969
3970void
3971i_wf_bbox(face, size, text)
3972 char *face
3973 int size
3974 char *text
3975 PREINIT:
3799c4d1 3976 int cords[BOUNDING_BOX_COUNT];
0ab90434 3977 int rc, i;
faa9b3e7 3978 PPCODE:
3799c4d1
TC
3979 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3980 EXTEND(SP, rc);
3981 for (i = 0; i < rc; ++i)
3982 PUSHs(sv_2mortal(newSViv(cords[i])));
faa9b3e7
TC
3983 }
3984
3985undef_int
3986i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3987 char *face
3988 Imager::ImgRaw im
3989 int tx
3990 int ty
3991 Imager::Color cl
3992 int size
3993 char *text
3994 int align
3995 int aa
3996 CODE:
3997 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3998 align, aa);
3999 OUTPUT:
4000 RETVAL
4001
4002undef_int
4003i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
4004 char *face
4005 Imager::ImgRaw im
4006 int tx
4007 int ty
4008 int channel
4009 int size
4010 char *text
4011 int align
4012 int aa
f5991c03 4013 CODE:
faa9b3e7
TC
4014 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4015 align, aa);
f5991c03
TC
4016 OUTPUT:
4017 RETVAL
02d1d628 4018
faa9b3e7
TC
4019
4020#endif
4021
4022#ifdef HAVE_FT2
4023
4024MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4025
4026#define FT2_DESTROY(font) i_ft2_destroy(font)
4027
4028void
4029FT2_DESTROY(font)
4030 Imager::Font::FT2 font
4031
4032MODULE = Imager PACKAGE = Imager::Font::FreeType2
4033
4034Imager::Font::FT2
4035i_ft2_new(name, index)
4036 char *name
4037 int index
4038
4039undef_int
4040i_ft2_setdpi(font, xdpi, ydpi)
4041 Imager::Font::FT2 font
4042 int xdpi
4043 int ydpi
4044
4045void
4046i_ft2_getdpi(font)
4047 Imager::Font::FT2 font
4048 PREINIT:
4049 int xdpi, ydpi;
4050 CODE:
4051 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4052 EXTEND(SP, 2);
4053 PUSHs(sv_2mortal(newSViv(xdpi)));
4054 PUSHs(sv_2mortal(newSViv(ydpi)));
4055 }
4056
4057undef_int
4058i_ft2_sethinting(font, hinting)
4059 Imager::Font::FT2 font
4060 int hinting
4061
4062undef_int
4063i_ft2_settransform(font, matrix)
4064 Imager::Font::FT2 font
4065 PREINIT:
4066 double matrix[6];
4067 int len;
4068 AV *av;
4069 SV *sv1;
4070 int i;
4071 CODE:
4072 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4073 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4074 av=(AV*)SvRV(ST(1));
4075 len=av_len(av)+1;
4076 if (len > 6)
4077 len = 6;
4078 for (i = 0; i < len; ++i) {
4079 sv1=(*(av_fetch(av,i,0)));
4080 matrix[i] = SvNV(sv1);
4081 }
4082 for (; i < 6; ++i)
4083 matrix[i] = 0;
4084 RETVAL = i_ft2_settransform(font, matrix);
4085 OUTPUT:
4086 RETVAL
4087
4088void
3799c4d1 4089i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
faa9b3e7
TC
4090 Imager::Font::FT2 font
4091 double cheight
4092 double cwidth
3799c4d1 4093 SV *text_sv
5cb9270b 4094 int utf8
faa9b3e7 4095 PREINIT:
3799c4d1 4096 int bbox[BOUNDING_BOX_COUNT];
faa9b3e7 4097 int i;
3799c4d1
TC
4098 char *text;
4099 STRLEN text_len;
4100 int rc;
faa9b3e7 4101 PPCODE:
3799c4d1 4102 text = SvPV(text_sv, text_len);
5cb9270b 4103#ifdef SvUTF8
3799c4d1 4104 if (SvUTF8(text_sv))
5cb9270b
TC
4105 utf8 = 1;
4106#endif
3799c4d1
TC
4107 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4108 if (rc) {
4109 EXTEND(SP, rc);
4110 for (i = 0; i < rc; ++i)
faa9b3e7
TC
4111 PUSHs(sv_2mortal(newSViv(bbox[i])));
4112 }
4113
4114void
4115i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4116 Imager::Font::FT2 font
4117 double cheight
4118 double cwidth
4119 char *text
4120 int vlayout
4121 int utf8
4122 PREINIT:
4123 int bbox[8];
4124 int i;
4125 PPCODE:
4126#ifdef SvUTF8
4127 if (SvUTF8(ST(3)))
4128 utf8 = 1;
4129#endif
4130 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4131 utf8, bbox)) {
4132 EXTEND(SP, 8);
4133 for (i = 0; i < 8; ++i)
4134 PUSHs(sv_2mortal(newSViv(bbox[i])));
4135 }
4136
4137undef_int
4138i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4139 Imager::Font::FT2 font
4140 Imager::ImgRaw im
4141 int tx
4142 int ty
4143 Imager::Color cl
4144 double cheight
4145 double cwidth
4146 int align
4147 int aa
4148 int vlayout
4149 int utf8
4150 PREINIT:
4151 char *text;
4152 STRLEN len;
4153 CODE:
4154#ifdef SvUTF8
4155 if (SvUTF8(ST(7))) {
4156 utf8 = 1;
4157 }
4158#endif
4159 text = SvPV(ST(7), len);
4160 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4161 len, align, aa, vlayout, utf8);
4162 OUTPUT:
4163 RETVAL
4164
4165undef_int
4166i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4167 Imager::Font::FT2 font
4168 Imager::ImgRaw im
4169 int tx
4170 int ty
4171 int channel
4172 double cheight
4173 double cwidth
4174 char *text
4175 int align
4176 int aa
4177 int vlayout
4178 int utf8
4179 CODE:
4180#ifdef SvUTF8
4181 if (SvUTF8(ST(7)))
4182 utf8 = 1;
4183#endif
4184 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4185 strlen(text), align, aa, vlayout, 1);
4186 OUTPUT:
4187 RETVAL
4188
4189void
4190ft2_transform_box(font, x0, x1, x2, x3)
4191 Imager::Font::FT2 font
4192 int x0
4193 int x1
4194 int x2
4195 int x3
4196 PREINIT:
4197 int box[4];
4198 PPCODE:
4199 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4200 ft2_transform_box(font, box);
4201 EXTEND(SP, 4);
4202 PUSHs(sv_2mortal(newSViv(box[0])));
4203 PUSHs(sv_2mortal(newSViv(box[1])));
4204 PUSHs(sv_2mortal(newSViv(box[2])));
4205 PUSHs(sv_2mortal(newSViv(box[3])));
3dec2c92
TC
4206
4207void
eeaa33fd 4208i_ft2_has_chars(handle, text_sv, utf8)
3dec2c92 4209 Imager::Font::FT2 handle
eeaa33fd 4210 SV *text_sv
3dec2c92
TC
4211 int utf8
4212 PREINIT:
4213 char *text;
4214 STRLEN len;
4215 char *work;
4216 int count;
4217 int i;
4218 PPCODE:
4219#ifdef SvUTF8
eeaa33fd 4220 if (SvUTF8(text_sv))
3dec2c92
TC
4221 utf8 = 1;
4222#endif
eeaa33fd 4223 text = SvPV(text_sv, len);
3dec2c92
TC
4224 work = mymalloc(len);
4225 count = i_ft2_has_chars(handle, text, len, utf8, work);
4226 if (GIMME_V == G_ARRAY) {
4227 EXTEND(SP, count);
4228 for (i = 0; i < count; ++i) {
4229 PUSHs(sv_2mortal(newSViv(work[i])));
4230 }
4231 }
4232 else {
4233 EXTEND(SP, 1);
4234 PUSHs(sv_2mortal(newSVpv(work, count)));
4235 }
4236 myfree(work);
4237
3799c4d1
TC
4238void
4239i_ft2_face_name(handle)
4240 Imager::Font::FT2 handle
4241 PREINIT:
4242 char name[255];
4243 int len;
4244 PPCODE:
4245 len = i_ft2_face_name(handle, name, sizeof(name));
4246 if (len) {
4247 EXTEND(SP, 1);
4248 PUSHs(sv_2mortal(newSVpv(name, 0)));
4249 }
4250
042cdaea
TC
4251undef_int
4252i_ft2_can_face_name()
4253
19fa4baf
AMH
4254void
4255i_ft2_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
4256 Imager::Font::FT2 handle
4257 SV *text_sv
4258 int utf8
4259 PREINIT:
4260 char const *text;
4261 STRLEN work_len;
4262 int len;
4263 int outsize;
4264 char name[255];
4265 PPCODE:
4266#ifdef SvUTF8
4267 if (SvUTF8(text_sv))
4268 utf8 = 1;
4269#endif
4270 text = SvPV(text_sv, work_len);
4271 len = work_len;
4272 while (len) {
4273 unsigned char ch;
4274 if (utf8) {
4275 ch = i_utf8_advance(&text, &len);
4276 if (ch == ~0UL) {
4277 i_push_error(0, "invalid UTF8 character");
4278 break;
4279 }
4280 }
4281 else {
4282 ch = *text++;
4283 --len;
4284 }
4285 EXTEND(SP, 1);
4286 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name))) {
4287 PUSHs(sv_2mortal(newSVpv(name, 0)));
4288 }
4289 else {
4290 PUSHs(&PL_sv_undef);
4291 }
4292 }
4293
4294int
4295i_ft2_can_do_glyph_names()
4296
4297int
4298i_ft2_face_has_glyph_names(handle)
4299 Imager::Font::FT2 handle
4300
faa9b3e7
TC
4301#endif
4302
f1ac5027
TC
4303MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4304
4305void
4306IFILL_DESTROY(fill)
4307 Imager::FillHandle fill
4308
4309MODULE = Imager PACKAGE = Imager
4310
4311Imager::FillHandle
4312i_new_fill_solid(cl, combine)
4313 Imager::Color cl
4314 int combine
4315
4316Imager::FillHandle
4317i_new_fill_solidf(cl, combine)
4318 Imager::Color::Float cl
4319 int combine
4320
4321Imager::FillHandle
4322i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4323 Imager::Color fg