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