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