Added extra parameters to rubthrough so only a subimage of
[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
71dc4a83 1481i_rubthru(im,src,tx,ty,src_minx,src_miny,src_maxx,src_maxy)
02d1d628
AMH
1482 Imager::ImgRaw im
1483 Imager::ImgRaw src
1484 int tx
1485 int ty
71dc4a83
AMH
1486 int src_minx
1487 int src_miny
1488 int src_maxx
1489 int src_maxy
1490
02d1d628 1491
142c26ff
AMH
1492undef_int
1493i_flipxy(im, direction)
1494 Imager::ImgRaw im
1495 int direction
1496
faa9b3e7
TC
1497Imager::ImgRaw
1498i_rotate90(im, degrees)
1499 Imager::ImgRaw im
1500 int degrees
1501
1502Imager::ImgRaw
1503i_rotate_exact(im, amount)
1504 Imager::ImgRaw im
1505 double amount
1506
1507Imager::ImgRaw
1508i_matrix_transform(im, xsize, ysize, matrix)
1509 Imager::ImgRaw im
1510 int xsize
1511 int ysize
1512 PREINIT:
1513 double matrix[9];
1514 AV *av;
1515 IV len;
1516 SV *sv1;
1517 int i;
1518 CODE:
1519 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1520 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1521 av=(AV*)SvRV(ST(3));
1522 len=av_len(av)+1;
1523 if (len > 9)
1524 len = 9;
1525 for (i = 0; i < len; ++i) {
1526 sv1=(*(av_fetch(av,i,0)));
1527 matrix[i] = SvNV(sv1);
1528 }
1529 for (; i < 9; ++i)
1530 matrix[i] = 0;
1531 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1532 OUTPUT:
1533 RETVAL
02d1d628
AMH
1534
1535void
1536i_gaussian(im,stdev)
1537 Imager::ImgRaw im
1538 float stdev
1539
b6381851
TC
1540void
1541i_unsharp_mask(im,stdev,scale)
1542 Imager::ImgRaw im
1543 float stdev
1544 double scale
1545
02d1d628
AMH
1546void
1547i_conv(im,pcoef)
1548 Imager::ImgRaw im
1549 PREINIT:
1550 float* coeff;
1551 int len;
1552 AV* av;
1553 SV* sv1;
1554 int i;
1555 PPCODE:
1556 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1557 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1558 av=(AV*)SvRV(ST(1));
1559 len=av_len(av)+1;
1560 coeff=mymalloc( len*sizeof(float) );
1561 for(i=0;i<len;i++) {
1562 sv1=(*(av_fetch(av,i,0)));
1563 coeff[i]=(float)SvNV(sv1);
1564 }
1565 i_conv(im,coeff,len);
1566 myfree(coeff);
1567
f5991c03
TC
1568undef_int
1569i_convert(im, src, coeff)
1570 Imager::ImgRaw im
1571 Imager::ImgRaw src
1572 PREINIT:
1573 float *coeff;
1574 int outchan;
1575 int inchan;
1576 AV *avmain;
1577 SV **temp;
1578 SV *svsub;
1579 AV *avsub;
1580 int len;
1581 int i, j;
1582 CODE:
f5991c03
TC
1583 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1584 croak("i_convert: parameter 3 must be an arrayref\n");
1585 avmain = (AV*)SvRV(ST(2));
1586 outchan = av_len(avmain)+1;
1587 /* find the biggest */
1588 inchan = 0;
1589 for (j=0; j < outchan; ++j) {
1590 temp = av_fetch(avmain, j, 0);
1591 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1592 avsub = (AV*)SvRV(*temp);
1593 len = av_len(avsub)+1;
1594 if (len > inchan)
1595 inchan = len;
1596 }
1597 }
1598 coeff = mymalloc(sizeof(float) * outchan * inchan);
1599 for (j = 0; j < outchan; ++j) {
1600 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1601 len = av_len(avsub)+1;
1602 for (i = 0; i < len; ++i) {
1603 temp = av_fetch(avsub, i, 0);
1604 if (temp)
1605 coeff[i+j*inchan] = SvNV(*temp);
1606 else
1607 coeff[i+j*inchan] = 0;
1608 }
1609 while (i < inchan)
1610 coeff[i++ + j*inchan] = 0;
1611 }
1612 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1613 myfree(coeff);
f5991c03
TC
1614 OUTPUT:
1615 RETVAL
40eba1ea
AMH
1616
1617
1618void
1619i_map(im, pmaps)
1620 Imager::ImgRaw im
1621 PREINIT:
1622 unsigned int mask = 0;
1623 AV *avmain;
1624 AV *avsub;
1625 SV **temp;
1626 int len;
1627 int i, j;
1628 unsigned char (*maps)[256];
1629 CODE:
1630 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1631 croak("i_map: parameter 2 must be an arrayref\n");
1632 avmain = (AV*)SvRV(ST(1));
1633 len = av_len(avmain)+1;
1634 if (im->channels < len) len = im->channels;
1635
1636 maps = mymalloc( len * sizeof(unsigned char [256]) );
1637
1638 for (j=0; j<len ; j++) {
1639 temp = av_fetch(avmain, j, 0);
1640 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1641 avsub = (AV*)SvRV(*temp);
1642 if(av_len(avsub) != 255) continue;
1643 mask |= 1<<j;
1644 for (i=0; i<256 ; i++) {
9495ee93 1645 int val;
40eba1ea 1646 temp = av_fetch(avsub, i, 0);
9495ee93
AMH
1647 val = temp ? SvIV(*temp) : 0;
1648 if (val<0) val = 0;
1649 if (val>255) val = 255;
1650 maps[j][i] = val;
40eba1ea
AMH
1651 }
1652 }
1653 }
1654 i_map(im, maps, mask);
1655 myfree(maps);
1656
1657
1658
02d1d628
AMH
1659float
1660i_img_diff(im1,im2)
1661 Imager::ImgRaw im1
1662 Imager::ImgRaw im2
1663
1664
1665
1666undef_int
4cb58f1b
TC
1667i_init_fonts(t1log=0)
1668 int t1log
02d1d628
AMH
1669
1670#ifdef HAVE_LIBT1
1671
1672void
1673i_t1_set_aa(st)
1674 int st
1675
1676int
6b012d62 1677i_t1_new(pfb,afm)
02d1d628
AMH
1678 char* pfb
1679 char* afm
1680
1681int
1682i_t1_destroy(font_id)
1683 int font_id
1684
1685
1686undef_int
1bd75e4c 1687i_t1_cp(im,xb,yb,channel,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
02d1d628
AMH
1688 Imager::ImgRaw im
1689 int xb
1690 int yb
1691 int channel
1692 int fontnum
1693 float points
1bd75e4c 1694 SV* str_sv
02d1d628 1695 int align
1bd75e4c
TC
1696 int utf8
1697 char* flags
1698 PREINIT:
1699 char *str;
1700 STRLEN len;
1701 CODE:
1702#ifdef SvUTF8
1703 if (SvUTF8(str_sv))
1704 utf8 = 1;
1705#endif
1706 str = SvPV(str_sv, len);
1707 RETVAL = i_t1_cp(im, xb,yb,channel,fontnum,points,str,len,align,
1708 utf8,flags);
1709 OUTPUT:
1710 RETVAL
1711
02d1d628
AMH
1712
1713void
1bd75e4c 1714i_t1_bbox(fontnum,point,str_sv,len_ignored,utf8=0,flags="")
02d1d628
AMH
1715 int fontnum
1716 float point
1bd75e4c
TC
1717 SV* str_sv
1718 int utf8
1719 char* flags
02d1d628 1720 PREINIT:
1bd75e4c
TC
1721 char *str;
1722 STRLEN len;
3799c4d1 1723 int cords[BOUNDING_BOX_COUNT];
1bd75e4c 1724 int i;
3799c4d1 1725 int rc;
02d1d628 1726 PPCODE:
1bd75e4c
TC
1727#ifdef SvUTF8
1728 if (SvUTF8(str_sv))
1729 utf8 = 1;
1730#endif
1731 str = SvPV(str_sv, len);
3799c4d1
TC
1732 rc = i_t1_bbox(fontnum,point,str,len,cords,utf8,flags);
1733 if (rc > 0) {
1734 EXTEND(SP, rc);
1735 for (i = 0; i < rc; ++i)
1736 PUSHs(sv_2mortal(newSViv(cords[i])));
1737 }
02d1d628
AMH
1738
1739
1740
1741undef_int
1bd75e4c 1742i_t1_text(im,xb,yb,cl,fontnum,points,str_sv,len_ignored,align,utf8=0,flags="")
02d1d628
AMH
1743 Imager::ImgRaw im
1744 int xb
1745 int yb
1746 Imager::Color cl
1747 int fontnum
1748 float points
1bd75e4c 1749 SV* str_sv
02d1d628 1750 int align
1bd75e4c
TC
1751 int utf8
1752 char* flags
1753 PREINIT:
1754 char *str;
1755 STRLEN len;
1756 CODE:
1757#ifdef SvUTF8
1758 if (SvUTF8(str_sv))
1759 utf8 = 1;
1760#endif
1761 str = SvPV(str_sv, len);
1762 RETVAL = i_t1_text(im, xb,yb,cl,fontnum,points,str,len,align,
1763 utf8,flags);
1764 OUTPUT:
1765 RETVAL
02d1d628 1766
3799c4d1
TC
1767void
1768i_t1_has_chars(handle, text_sv, utf8 = 0)
1769 int handle
1770 SV *text_sv
1771 int utf8
1772 PREINIT:
1773 char const *text;
1774 STRLEN len;
1775 char *work;
1776 int count;
1777 int i;
1778 PPCODE:
1779#ifdef SvUTF8
1780 if (SvUTF8(text_sv))
1781 utf8 = 1;
1782#endif
1783 text = SvPV(text_sv, len);
1784 work = mymalloc(len);
1785 count = i_t1_has_chars(handle, text, len, utf8, work);
1786 if (GIMME_V == G_ARRAY) {
1787 EXTEND(SP, count);
1788 for (i = 0; i < count; ++i) {
1789 PUSHs(sv_2mortal(newSViv(work[i])));
1790 }
1791 }
1792 else {
1793 EXTEND(SP, 1);
1794 PUSHs(sv_2mortal(newSVpv(work, count)));
1795 }
1796 myfree(work);
1797
1798void
1799i_t1_face_name(handle)
1800 int handle
1801 PREINIT:
1802 char name[255];
1803 int len;
1804 PPCODE:
1805 len = i_t1_face_name(handle, name, sizeof(name));
1806 if (len) {
1807 EXTEND(SP, 1);
1808 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1809 }
1810
19fa4baf
AMH
1811void
1812i_t1_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
1813 int handle
1814 SV *text_sv
1815 int utf8
1816 PREINIT:
1817 char const *text;
1818 STRLEN work_len;
1819 int len;
1820 int outsize;
1821 char name[255];
1822 PPCODE:
1823#ifdef SvUTF8
1824 if (SvUTF8(text_sv))
1825 utf8 = 1;
1826#endif
1827 text = SvPV(text_sv, work_len);
1828 len = work_len;
1829 while (len) {
1830 unsigned char ch;
1831 if (utf8) {
1832 ch = i_utf8_advance(&text, &len);
1833 if (ch == ~0UL) {
1834 i_push_error(0, "invalid UTF8 character");
1835 break;
1836 }
1837 }
1838 else {
1839 ch = *text++;
1840 --len;
1841 }
1842 EXTEND(SP, 1);
1843 if (outsize = i_t1_glyph_name(handle, ch, name, sizeof(name))) {
1844 PUSHs(sv_2mortal(newSVpv(name, 0)));
1845 }
1846 else {
1847 PUSHs(&PL_sv_undef);
1848 }
1849 }
1850
02d1d628
AMH
1851#endif
1852
1853#ifdef HAVE_LIBTT
1854
1855
4b19f77a 1856Imager::Font::TT
02d1d628
AMH
1857i_tt_new(fontname)
1858 char* fontname
1859
4b19f77a
AMH
1860
1861MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1862
1863#define TT_DESTROY(handle) i_tt_destroy(handle)
1864
02d1d628 1865void
4b19f77a
AMH
1866TT_DESTROY(handle)
1867 Imager::Font::TT handle
1868
02d1d628 1869
4b19f77a 1870MODULE = Imager PACKAGE = Imager
02d1d628
AMH
1871
1872
1873undef_int
4f68b48f 1874i_tt_text(handle,im,xb,yb,cl,points,str_sv,len_ignored,smooth,utf8)
4b19f77a 1875 Imager::Font::TT handle
02d1d628
AMH
1876 Imager::ImgRaw im
1877 int xb
1878 int yb
1879 Imager::Color cl
1880 float points
4f68b48f
TC
1881 SV * str_sv
1882 int len_ignored
02d1d628 1883 int smooth
4f68b48f
TC
1884 int utf8
1885 PREINIT:
1886 char *str;
1887 STRLEN len;
1888 CODE:
1889#ifdef SvUTF8
1890 if (SvUTF8(str_sv))
1891 utf8 = 1;
1892#endif
1893 str = SvPV(str_sv, len);
1894 RETVAL = i_tt_text(handle, im, xb, yb, cl, points, str,
1895 len, smooth, utf8);
1896 OUTPUT:
1897 RETVAL
02d1d628
AMH
1898
1899
1900undef_int
4f68b48f 1901i_tt_cp(handle,im,xb,yb,channel,points,str_sv,len_ignored,smooth,utf8)
4b19f77a 1902 Imager::Font::TT handle
02d1d628
AMH
1903 Imager::ImgRaw im
1904 int xb
1905 int yb
1906 int channel
1907 float points
4f68b48f
TC
1908 SV * str_sv
1909 int len_ignored
02d1d628 1910 int smooth
4f68b48f
TC
1911 int utf8
1912 PREINIT:
1913 char *str;
1914 STRLEN len;
1915 CODE:
1916#ifdef SvUTF8
1917 if (SvUTF8(str_sv))
1918 utf8 = 1;
1919#endif
1920 str = SvPV(str_sv, len);
1921 RETVAL = i_tt_cp(handle, im, xb, yb, channel, points, str, len,
1922 smooth, utf8);
1923 OUTPUT:
1924 RETVAL
02d1d628
AMH
1925
1926
1927undef_int
4f68b48f 1928i_tt_bbox(handle,point,str_sv,len_ignored, utf8)
4b19f77a 1929 Imager::Font::TT handle
02d1d628 1930 float point
4f68b48f
TC
1931 SV* str_sv
1932 int len_ignored
1933 int utf8
02d1d628 1934 PREINIT:
3799c4d1 1935 int cords[BOUNDING_BOX_COUNT],rc;
4f68b48f
TC
1936 char * str;
1937 STRLEN len;
3799c4d1 1938 int i;
02d1d628 1939 PPCODE:
4f68b48f
TC
1940#ifdef SvUTF8
1941 if (SvUTF8(ST(2)))
1942 utf8 = 1;
1943#endif
1944 str = SvPV(str_sv, len);
1945 if ((rc=i_tt_bbox(handle,point,str,len,cords, utf8))) {
3799c4d1
TC
1946 EXTEND(SP, rc);
1947 for (i = 0; i < rc; ++i) {
1948 PUSHs(sv_2mortal(newSViv(cords[i])));
1949 }
02d1d628
AMH
1950 }
1951
eeaa33fd
TC
1952void
1953i_tt_has_chars(handle, text_sv, utf8)
1954 Imager::Font::TT handle
1955 SV *text_sv
1956 int utf8
1957 PREINIT:
1958 char const *text;
1959 STRLEN len;
1960 char *work;
1961 int count;
1962 int i;
1963 PPCODE:
1964#ifdef SvUTF8
1965 if (SvUTF8(text_sv))
1966 utf8 = 1;
1967#endif
1968 text = SvPV(text_sv, len);
1969 work = mymalloc(len);
1970 count = i_tt_has_chars(handle, text, len, utf8, work);
1971 if (GIMME_V == G_ARRAY) {
1972 EXTEND(SP, count);
1973 for (i = 0; i < count; ++i) {
1974 PUSHs(sv_2mortal(newSViv(work[i])));
1975 }
1976 }
1977 else {
1978 EXTEND(SP, 1);
1979 PUSHs(sv_2mortal(newSVpv(work, count)));
1980 }
1981 myfree(work);
02d1d628 1982
3799c4d1
TC
1983void
1984i_tt_dump_names(handle)
1985 Imager::Font::TT handle
02d1d628 1986
3799c4d1
TC
1987void
1988i_tt_face_name(handle)
1989 Imager::Font::TT handle
1990 PREINIT:
1991 char name[255];
1992 int len;
1993 PPCODE:
1994 len = i_tt_face_name(handle, name, sizeof(name));
1995 if (len) {
1996 EXTEND(SP, 1);
1997 PUSHs(sv_2mortal(newSVpv(name, strlen(name))));
1998 }
02d1d628 1999
19fa4baf
AMH
2000void
2001i_tt_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
2002 Imager::Font::TT handle
2003 SV *text_sv
2004 int utf8
2005 PREINIT:
2006 char const *text;
2007 STRLEN work_len;
2008 int len;
2009 int outsize;
2010 char name[255];
2011 PPCODE:
2012#ifdef SvUTF8
2013 if (SvUTF8(text_sv))
2014 utf8 = 1;
2015#endif
2016 text = SvPV(text_sv, work_len);
2017 len = work_len;
2018 while (len) {
2019 unsigned char ch;
2020 if (utf8) {
2021 ch = i_utf8_advance(&text, &len);
2022 if (ch == ~0UL) {
2023 i_push_error(0, "invalid UTF8 character");
2024 break;
2025 }
2026 }
2027 else {
2028 ch = *text++;
2029 --len;
2030 }
2031 EXTEND(SP, 1);
2032 if (outsize = i_tt_glyph_name(handle, ch, name, sizeof(name))) {
2033 PUSHs(sv_2mortal(newSVpv(name, 0)));
2034 }
2035 else {
2036 PUSHs(&PL_sv_undef);
2037 }
2038 }
2039
2040#endif
02d1d628
AMH
2041
2042
2043#ifdef HAVE_LIBJPEG
2044undef_int
dd55acc8 2045i_writejpeg_wiol(im, ig, qfactor)
02d1d628 2046 Imager::ImgRaw im
dd55acc8 2047 Imager::IO ig
02d1d628
AMH
2048 int qfactor
2049
02d1d628
AMH
2050
2051void
2052i_readjpeg_wiol(ig)
2053 Imager::IO ig
2054 PREINIT:
2055 char* iptc_itext;
2056 int tlength;
2057 i_img* rimg;
2058 SV* r;
2059 PPCODE:
2060 iptc_itext = NULL;
2061 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
2062 if (iptc_itext == NULL) {
2063 r = sv_newmortal();
2064 EXTEND(SP,1);
2065 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2066 PUSHs(r);
2067 } else {
2068 r = sv_newmortal();
2069 EXTEND(SP,2);
2070 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2071 PUSHs(r);
2072 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
2073 myfree(iptc_itext);
2074 }
2075
2076
2077#endif
2078
2079
e10bf46e
AMH
2080char *
2081i_test_format_probe(ig, length)
2082 Imager::IO ig
2083 int length
2084
02d1d628
AMH
2085
2086
2087#ifdef HAVE_LIBTIFF
2088
2089Imager::ImgRaw
2090i_readtiff_wiol(ig, length)
2091 Imager::IO ig
2092 int length
2093
10461f9a
TC
2094void
2095i_readtiff_multi_wiol(ig, length)
2096 Imager::IO ig
2097 int length
2098 PREINIT:
2099 i_img **imgs;
2100 int count;
2101 int i;
2102 PPCODE:
2103 imgs = i_readtiff_multi_wiol(ig, length, &count);
2104 if (imgs) {
2105 EXTEND(SP, count);
2106 for (i = 0; i < count; ++i) {
2107 SV *sv = sv_newmortal();
2108 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2109 PUSHs(sv);
2110 }
2111 myfree(imgs);
2112 }
2113
02d1d628
AMH
2114
2115undef_int
2116i_writetiff_wiol(im, ig)
2117 Imager::ImgRaw im
2118 Imager::IO ig
2119
10461f9a
TC
2120undef_int
2121i_writetiff_multi_wiol(ig, ...)
2122 Imager::IO ig
2123 PREINIT:
2124 int i;
2125 int img_count;
2126 i_img **imgs;
2127 CODE:
2128 if (items < 2)
2129 croak("Usage: i_writetiff_multi_wiol(ig, images...)");
2130 img_count = items - 1;
2131 RETVAL = 1;
2132 if (img_count < 1) {
2133 RETVAL = 0;
2134 i_clear_error();
2135 i_push_error(0, "You need to specify images to save");
2136 }
2137 else {
2138 imgs = mymalloc(sizeof(i_img *) * img_count);
2139 for (i = 0; i < img_count; ++i) {
2140 SV *sv = ST(1+i);
2141 imgs[i] = NULL;
2142 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2143 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2144 }
2145 else {
2146 i_clear_error();
2147 i_push_error(0, "Only images can be saved");
2148 myfree(imgs);
2149 RETVAL = 0;
2150 break;
2151 }
2152 }
2153 if (RETVAL) {
2154 RETVAL = i_writetiff_multi_wiol(ig, imgs, img_count);
2155 }
2156 myfree(imgs);
2157 }
2158 OUTPUT:
2159 RETVAL
2160
d2dfdcc9 2161undef_int
4c2d6970 2162i_writetiff_wiol_faxable(im, ig, fine)
d2dfdcc9
TC
2163 Imager::ImgRaw im
2164 Imager::IO ig
4c2d6970 2165 int fine
d2dfdcc9 2166
10461f9a
TC
2167undef_int
2168i_writetiff_multi_wiol_faxable(ig, fine, ...)
2169 Imager::IO ig
2170 int fine
2171 PREINIT:
2172 int i;
2173 int img_count;
2174 i_img **imgs;
2175 CODE:
2176 if (items < 3)
2177 croak("Usage: i_writetiff_multi_wiol_faxable(ig, fine, images...)");
2178 img_count = items - 2;
2179 RETVAL = 1;
2180 if (img_count < 1) {
2181 RETVAL = 0;
2182 i_clear_error();
2183 i_push_error(0, "You need to specify images to save");
2184 }
2185 else {
2186 imgs = mymalloc(sizeof(i_img *) * img_count);
2187 for (i = 0; i < img_count; ++i) {
2188 SV *sv = ST(2+i);
2189 imgs[i] = NULL;
2190 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2191 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2192 }
2193 else {
2194 i_clear_error();
2195 i_push_error(0, "Only images can be saved");
2196 myfree(imgs);
2197 RETVAL = 0;
2198 break;
2199 }
2200 }
2201 if (RETVAL) {
2202 RETVAL = i_writetiff_multi_wiol_faxable(ig, imgs, img_count, fine);
2203 }
2204 myfree(imgs);
2205 }
2206 OUTPUT:
2207 RETVAL
02d1d628
AMH
2208
2209
10461f9a 2210#endif /* HAVE_LIBTIFF */
02d1d628
AMH
2211
2212
2213#ifdef HAVE_LIBPNG
2214
2215Imager::ImgRaw
790923a4
AMH
2216i_readpng_wiol(ig, length)
2217 Imager::IO ig
2218 int length
02d1d628
AMH
2219
2220
2221undef_int
790923a4 2222i_writepng_wiol(im, ig)
02d1d628 2223 Imager::ImgRaw im
790923a4 2224 Imager::IO ig
02d1d628
AMH
2225
2226
2227#endif
2228
2229
2230#ifdef HAVE_LIBGIF
2231
03bd24d4
TC
2232void
2233i_giflib_version()
2234 PPCODE:
2235 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
2236
02d1d628
AMH
2237undef_int
2238i_writegif(im,fd,colors,pixdev,fixed)
2239 Imager::ImgRaw im
2240 int fd
2241 int colors
2242 int pixdev
2243 PREINIT:
2244 int fixedlen;
2245 Imager__Color fixed;
2246 Imager__Color tmp;
2247 AV* av;
2248 SV* sv1;
2249 IV Itmp;
2250 int i;
2251 CODE:
2252 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
2253 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2254 av=(AV*)SvRV(ST(4));
2255 fixedlen=av_len(av)+1;
2256 fixed=mymalloc( fixedlen*sizeof(i_color) );
2257 for(i=0;i<fixedlen;i++) {
2258 sv1=(*(av_fetch(av,i,0)));
2259 if (sv_derived_from(sv1, "Imager::Color")) {
2260 Itmp = SvIV((SV*)SvRV(sv1));
2261 tmp = (i_color*) Itmp;
2262 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
2263 fixed[i]=*tmp;
2264 }
2265 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
2266 myfree(fixed);
2267 ST(0) = sv_newmortal();
2268 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2269 else sv_setiv(ST(0), (IV)RETVAL);
2270
2271
2272
2273
2274undef_int
2275i_writegifmc(im,fd,colors)
067d6bdc 2276 Imager::ImgRaw im
02d1d628
AMH
2277 int fd
2278 int colors
2279
02d1d628
AMH
2280
2281undef_int
2282i_writegif_gen(fd, ...)
2283 int fd
2284 PROTOTYPE: $$@
2285 PREINIT:
2286 i_quantize quant;
02d1d628
AMH
2287 i_img **imgs = NULL;
2288 int img_count;
2289 int i;
2290 HV *hv;
2291 CODE:
2292 if (items < 3)
2293 croak("Usage: i_writegif_gen(fd,hashref, images...)");
2294 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2295 croak("i_writegif_gen: Second argument must be a hash ref");
2296 hv = (HV *)SvRV(ST(1));
2297 memset(&quant, 0, sizeof(quant));
2298 quant.mc_size = 256;
02d1d628 2299 handle_quant_opts(&quant, hv);
02d1d628
AMH
2300 img_count = items - 2;
2301 RETVAL = 1;
2302 if (img_count < 1) {
2303 RETVAL = 0;
95b44a76
TC
2304 i_clear_error();
2305 i_push_error(0, "You need to specify images to save");
02d1d628
AMH
2306 }
2307 else {
2308 imgs = mymalloc(sizeof(i_img *) * img_count);
2309 for (i = 0; i < img_count; ++i) {
2310 SV *sv = ST(2+i);
2311 imgs[i] = NULL;
2312 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2313 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
02d1d628
AMH
2314 }
2315 else {
95b44a76
TC
2316 i_clear_error();
2317 i_push_error(0, "Only images can be saved");
02d1d628
AMH
2318 RETVAL = 0;
2319 break;
2320 }
2321 }
2322 if (RETVAL) {
97c4effc 2323 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count);
02d1d628
AMH
2324 }
2325 myfree(imgs);
2326 if (RETVAL) {
2327 copy_colors_back(hv, &quant);
2328 }
2329 }
a73aeb5f
AMH
2330 ST(0) = sv_newmortal();
2331 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2332 else sv_setiv(ST(0), (IV)RETVAL);
46a04ceb 2333 cleanup_quant_opts(&quant);
a73aeb5f 2334
02d1d628
AMH
2335
2336undef_int
2337i_writegif_callback(cb, maxbuffer,...)
2338 int maxbuffer;
2339 PREINIT:
2340 i_quantize quant;
02d1d628
AMH
2341 i_img **imgs = NULL;
2342 int img_count;
2343 int i;
2344 HV *hv;
2345 i_writer_data wd;
2346 CODE:
2347 if (items < 4)
2348 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
2349 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2350 croak("i_writegif_callback: Second argument must be a hash ref");
2351 hv = (HV *)SvRV(ST(2));
2352 memset(&quant, 0, sizeof(quant));
2353 quant.mc_size = 256;
02d1d628 2354 handle_quant_opts(&quant, hv);
02d1d628
AMH
2355 img_count = items - 3;
2356 RETVAL = 1;
2357 if (img_count < 1) {
2358 RETVAL = 0;
2359 }
2360 else {
2361 imgs = mymalloc(sizeof(i_img *) * img_count);
2362 for (i = 0; i < img_count; ++i) {
2363 SV *sv = ST(3+i);
2364 imgs[i] = NULL;
2365 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2366 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
02d1d628
AMH
2367 }
2368 else {
2369 RETVAL = 0;
2370 break;
2371 }
2372 }
2373 if (RETVAL) {
2374 wd.sv = ST(0);
97c4effc 2375 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count);
02d1d628
AMH
2376 }
2377 myfree(imgs);
2378 if (RETVAL) {
2379 copy_colors_back(hv, &quant);
2380 }
2381 }
46a04ceb
TC
2382 ST(0) = sv_newmortal();
2383 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2384 else sv_setiv(ST(0), (IV)RETVAL);
46a04ceb 2385 cleanup_quant_opts(&quant);
02d1d628 2386
10461f9a
TC
2387undef_int
2388i_writegif_wiol(ig, opts,...)
2389 Imager::IO ig
2390 PREINIT:
2391 i_quantize quant;
10461f9a
TC
2392 i_img **imgs = NULL;
2393 int img_count;
2394 int i;
2395 HV *hv;
2396 CODE:
2397 if (items < 3)
2398 croak("Usage: i_writegif_wiol(IO,hashref, images...)");
2399 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2400 croak("i_writegif_callback: Second argument must be a hash ref");
2401 hv = (HV *)SvRV(ST(1));
2402 memset(&quant, 0, sizeof(quant));
2403 quant.mc_size = 256;
10461f9a 2404 handle_quant_opts(&quant, hv);
10461f9a
TC
2405 img_count = items - 2;
2406 RETVAL = 1;
2407 if (img_count < 1) {
2408 RETVAL = 0;
2409 }
2410 else {
2411 imgs = mymalloc(sizeof(i_img *) * img_count);
2412 for (i = 0; i < img_count; ++i) {
2413 SV *sv = ST(2+i);
2414 imgs[i] = NULL;
2415 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
4c4c2ffd 2416 imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
10461f9a
TC
2417 }
2418 else {
2419 RETVAL = 0;
2420 break;
2421 }
2422 }
2423 if (RETVAL) {
97c4effc 2424 RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
10461f9a
TC
2425 }
2426 myfree(imgs);
2427 if (RETVAL) {
2428 copy_colors_back(hv, &quant);
2429 }
2430 }
2431 ST(0) = sv_newmortal();
2432 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2433 else sv_setiv(ST(0), (IV)RETVAL);
10461f9a
TC
2434 cleanup_quant_opts(&quant);
2435
02d1d628
AMH
2436void
2437i_readgif(fd)
2438 int fd
2439 PREINIT:
2440 int* colour_table;
2441 int colours, q, w;
2442 i_img* rimg;
2443 SV* temp[3];
2444 AV* ct;
2445 SV* r;
2446 PPCODE:
2447 colour_table = NULL;
2448 colours = 0;
2449
895dbd34 2450 if(GIMME_V == G_ARRAY) {
02d1d628
AMH
2451 rimg = i_readgif(fd,&colour_table,&colours);
2452 } else {
2453 /* don't waste time with colours if they aren't wanted */
2454 rimg = i_readgif(fd,NULL,NULL);
2455 }
895dbd34 2456
02d1d628
AMH
2457 if (colour_table == NULL) {
2458 EXTEND(SP,1);
2459 r=sv_newmortal();
2460 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2461 PUSHs(r);
2462 } else {
2463 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2464 /* I don't know if I have the reference counts right or not :( */
2465 /* Neither do I :-) */
2466 /* No Idea here either */
2467
2468 ct=newAV();
2469 av_extend(ct, colours);
2470 for(q=0; q<colours; q++) {
2471 for(w=0; w<3; w++)
2472 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2473 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2474 }
2475 myfree(colour_table);
895dbd34 2476
02d1d628 2477 EXTEND(SP,2);
895dbd34 2478 r = sv_newmortal();
02d1d628
AMH
2479 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2480 PUSHs(r);
2481 PUSHs(newRV_noinc((SV*)ct));
2482 }
2483
10461f9a
TC
2484void
2485i_readgif_wiol(ig)
2486 Imager::IO ig
2487 PREINIT:
2488 int* colour_table;
2489 int colours, q, w;
2490 i_img* rimg;
2491 SV* temp[3];
2492 AV* ct;
2493 SV* r;
2494 PPCODE:
2495 colour_table = NULL;
2496 colours = 0;
02d1d628 2497
10461f9a
TC
2498 if(GIMME_V == G_ARRAY) {
2499 rimg = i_readgif_wiol(ig,&colour_table,&colours);
2500 } else {
2501 /* don't waste time with colours if they aren't wanted */
2502 rimg = i_readgif_wiol(ig,NULL,NULL);
2503 }
2504
2505 if (colour_table == NULL) {
2506 EXTEND(SP,1);
2507 r=sv_newmortal();
2508 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2509 PUSHs(r);
2510 } else {
2511 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2512 /* I don't know if I have the reference counts right or not :( */
2513 /* Neither do I :-) */
2514 /* No Idea here either */
02d1d628 2515
10461f9a
TC
2516 ct=newAV();
2517 av_extend(ct, colours);
2518 for(q=0; q<colours; q++) {
2519 for(w=0; w<3; w++)
2520 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2521 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2522 }
2523 myfree(colour_table);
02d1d628 2524
10461f9a
TC
2525 EXTEND(SP,2);
2526 r = sv_newmortal();
2527 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2528 PUSHs(r);
2529 PUSHs(newRV_noinc((SV*)ct));
2530 }
02d1d628
AMH
2531
2532void
2533i_readgif_scalar(...)
2534 PROTOTYPE: $
2535 PREINIT:
2536 char* data;
21e952df 2537 STRLEN length;
02d1d628
AMH
2538 int* colour_table;
2539 int colours, q, w;
2540 i_img* rimg;
2541 SV* temp[3];
2542 AV* ct;
2543 SV* r;
2544 PPCODE:
2545 data = (char *)SvPV(ST(0), length);
2546 colour_table=NULL;
2547 colours=0;
2548
2549 if(GIMME_V == G_ARRAY) {
2550 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
2551 } else {
2552 /* don't waste time with colours if they aren't wanted */
2553 rimg=i_readgif_scalar(data,length,NULL,NULL);
2554 }
2555
2556 if (colour_table == NULL) {
2557 EXTEND(SP,1);
2558 r=sv_newmortal();
2559 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2560 PUSHs(r);
2561 } else {
2562 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2563 /* I don't know if I have the reference counts right or not :( */
2564 /* Neither do I :-) */
2565 ct=newAV();
2566 av_extend(ct, colours);
2567 for(q=0; q<colours; q++) {
2568 for(w=0; w<3; w++)
2569 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2570 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2571 }
2572 myfree(colour_table);
2573
2574 EXTEND(SP,2);
2575 r=sv_newmortal();
2576 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2577 PUSHs(r);
2578 PUSHs(newRV_noinc((SV*)ct));
2579 }
2580
2581void
2582i_readgif_callback(...)
2583 PROTOTYPE: &
2584 PREINIT:
2585 char* data;
2586 int length;
2587 int* colour_table;
2588 int colours, q, w;
2589 i_img* rimg;
2590 SV* temp[3];
2591 AV* ct;
2592 SV* r;
2593 i_reader_data rd;
2594 PPCODE:
2595 rd.sv = ST(0);
2596 colour_table=NULL;
2597 colours=0;
2598
2599 if(GIMME_V == G_ARRAY) {
2600 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
2601 } else {
2602 /* don't waste time with colours if they aren't wanted */
2603 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
2604 }
2605
2606 if (colour_table == NULL) {
2607 EXTEND(SP,1);
2608 r=sv_newmortal();
2609 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2610 PUSHs(r);
2611 } else {
2612 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
2613 /* I don't know if I have the reference counts right or not :( */
2614 /* Neither do I :-) */
2615 /* Neither do I - maybe I'll move this somewhere */
2616 ct=newAV();
2617 av_extend(ct, colours);
2618 for(q=0; q<colours; q++) {
2619 for(w=0; w<3; w++)
2620 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
2621 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
2622 }
2623 myfree(colour_table);
2624
2625 EXTEND(SP,2);
2626 r=sv_newmortal();
2627 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
2628 PUSHs(r);
2629 PUSHs(newRV_noinc((SV*)ct));
2630 }
2631
faa9b3e7
TC
2632void
2633i_readgif_multi(fd)
2634 int fd
2635 PREINIT:
2636 i_img **imgs;
2637 int count;
2638 int i;
2639 PPCODE:
2640 imgs = i_readgif_multi(fd, &count);
2641 if (imgs) {
2642 EXTEND(SP, count);
2643 for (i = 0; i < count; ++i) {
2644 SV *sv = sv_newmortal();
2645 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2646 PUSHs(sv);
2647 }
2648 myfree(imgs);
2649 }
02d1d628 2650
faa9b3e7
TC
2651void
2652i_readgif_multi_scalar(data)
2653 PREINIT:
2654 i_img **imgs;
2655 int count;
2656 char *data;
21e952df 2657 STRLEN length;
faa9b3e7
TC
2658 int i;
2659 PPCODE:
2660 data = (char *)SvPV(ST(0), length);
2661 imgs = i_readgif_multi_scalar(data, length, &count);
2662 if (imgs) {
2663 EXTEND(SP, count);
2664 for (i = 0; i < count; ++i) {
2665 SV *sv = sv_newmortal();
2666 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2667 PUSHs(sv);
2668 }
2669 myfree(imgs);
2670 }
02d1d628 2671
faa9b3e7
TC
2672void
2673i_readgif_multi_callback(cb)
2674 PREINIT:
2675 i_reader_data rd;
2676 i_img **imgs;
2677 int count;
2678 int i;
2679 PPCODE:
2680 rd.sv = ST(0);
2681 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
2682 if (imgs) {
2683 EXTEND(SP, count);
2684 for (i = 0; i < count; ++i) {
2685 SV *sv = sv_newmortal();
2686 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2687 PUSHs(sv);
2688 }
2689 myfree(imgs);
2690 }
02d1d628 2691
10461f9a
TC
2692void
2693i_readgif_multi_wiol(ig)
2694 Imager::IO ig
2695 PREINIT:
2696 i_img **imgs;
2697 int count;
2698 int i;
2699 PPCODE:
2700 imgs = i_readgif_multi_wiol(ig, &count);
2701 if (imgs) {
2702 EXTEND(SP, count);
2703 for (i = 0; i < count; ++i) {
2704 SV *sv = sv_newmortal();
2705 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
2706 PUSHs(sv);
2707 }
2708 myfree(imgs);
2709 }
2710
2711
02d1d628
AMH
2712#endif
2713
2714
2715
2716Imager::ImgRaw
2717i_readpnm_wiol(ig, length)
2718 Imager::IO ig
2719 int length
2720
2721
067d6bdc
AMH
2722undef_int
2723i_writeppm_wiol(im, ig)
2724 Imager::ImgRaw im
2725 Imager::IO ig
2726
2727
02d1d628 2728Imager::ImgRaw
895dbd34
AMH
2729i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
2730 Imager::IO ig
02d1d628
AMH
2731 int x
2732 int y
2733 int datachannels
2734 int storechannels
2735 int intrl
2736
2737undef_int
895dbd34 2738i_writeraw_wiol(im,ig)
02d1d628 2739 Imager::ImgRaw im
895dbd34
AMH
2740 Imager::IO ig
2741
261f91c5
TC
2742undef_int
2743i_writebmp_wiol(im,ig)
2744 Imager::ImgRaw im
2745 Imager::IO ig
02d1d628 2746
705fd961
TC
2747Imager::ImgRaw
2748i_readbmp_wiol(ig)
2749 Imager::IO ig
2750
1ec86afa
AMH
2751
2752undef_int
febba01f 2753i_writetga_wiol(im,ig, wierdpack, compress, idstring)
1ec86afa
AMH
2754 Imager::ImgRaw im
2755 Imager::IO ig
febba01f
AMH
2756 int wierdpack
2757 int compress
2758 char* idstring
2759 PREINIT:
2760 SV* sv1;
2761 int rc;
2762 int idlen;
2763 CODE:
2764 idlen = SvCUR(ST(4));
2765 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
2766 OUTPUT:
2767 RETVAL
2768
1ec86afa
AMH
2769
2770Imager::ImgRaw
2771i_readtga_wiol(ig, length)
2772 Imager::IO ig
2773 int length
2774
2775
737a830c
AMH
2776undef_int
2777i_writergb_wiol(im,ig, wierdpack, compress, idstring)
2778 Imager::ImgRaw im
2779 Imager::IO ig
2780 int wierdpack
2781 int compress
2782 char* idstring
2783 PREINIT:
2784 SV* sv1;
2785 int rc;
2786 int idlen;
2787 CODE:
2788 idlen = SvCUR(ST(4));
2789 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
2790 OUTPUT:
2791 RETVAL
2792
2793
2794Imager::ImgRaw
2795i_readrgb_wiol(ig, length)
2796 Imager::IO ig
2797 int length
2798
2799
2800
02d1d628
AMH
2801Imager::ImgRaw
2802i_scaleaxis(im,Value,Axis)
2803 Imager::ImgRaw im
2804 float Value
2805 int Axis
2806
2807Imager::ImgRaw
2808i_scale_nn(im,scx,scy)
2809 Imager::ImgRaw im
2810 float scx
2811 float scy
2812
2813Imager::ImgRaw
2814i_haar(im)
2815 Imager::ImgRaw im
2816
2817int
2818i_count_colors(im,maxc)
2819 Imager::ImgRaw im
2820 int maxc
2821
2822
2823Imager::ImgRaw
2824i_transform(im,opx,opy,parm)
2825 Imager::ImgRaw im
2826 PREINIT:
2827 double* parm;
2828 int* opx;
2829 int* opy;
2830 int opxl;
2831 int opyl;
2832 int parmlen;
2833 AV* av;
2834 SV* sv1;
2835 int i;
2836 CODE:
2837 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
2838 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
2839 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
2840 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
2841 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
2842 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
2843 av=(AV*)SvRV(ST(1));
2844 opxl=av_len(av)+1;
2845 opx=mymalloc( opxl*sizeof(int) );
2846 for(i=0;i<opxl;i++) {
2847 sv1=(*(av_fetch(av,i,0)));
2848 opx[i]=(int)SvIV(sv1);
2849 }
2850 av=(AV*)SvRV(ST(2));
2851 opyl=av_len(av)+1;
2852 opy=mymalloc( opyl*sizeof(int) );
2853 for(i=0;i<opyl;i++) {
2854 sv1=(*(av_fetch(av,i,0)));
2855 opy[i]=(int)SvIV(sv1);
2856 }
2857 av=(AV*)SvRV(ST(3));
2858 parmlen=av_len(av)+1;
2859 parm=mymalloc( parmlen*sizeof(double) );
2860 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
2861 sv1=(*(av_fetch(av,i,0)));
2862 parm[i]=(double)SvNV(sv1);
2863 }
2864 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
2865 myfree(parm);
2866 myfree(opy);
2867 myfree(opx);
2868 ST(0) = sv_newmortal();
2869 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2870 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2871
2872Imager::ImgRaw
2873i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
2874 PREINIT:
2875 int width;
2876 int height;
2877 double* parm;
2878 struct rm_op *ops;
953209f8 2879 STRLEN ops_len;
02d1d628
AMH
2880 int ops_count;
2881 double *n_regs;
2882 int n_regs_count;
2883 i_color *c_regs;
2884 int c_regs_count;
2885 int in_imgs_count;
2886 i_img **in_imgs;
2887 AV* av;
2888 SV* sv1;
2889 IV tmp;
2890 int i;
2891 CODE:
2892 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
2893 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
2894 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
2895 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2896 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2897
2898 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2899
2900 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2901 av = (AV*)SvRV(ST(5));
2902 in_imgs_count = av_len(av)+1;
2903 for (i = 0; i < in_imgs_count; ++i) {
2904 sv1 = *av_fetch(av, i, 0);
2905 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2906 croak("Parameter 5 must contain only images");
2907 }
2908 }
2909 }
2910 else {
2911 in_imgs_count = 0;
2912 }
b8c2033e 2913 if (in_imgs_count > 0) {
02d1d628
AMH
2914 av = (AV*)SvRV(ST(5));
2915 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2916 for (i = 0; i < in_imgs_count; ++i) {
2917 sv1 = *av_fetch(av,i,0);
2918 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2919 croak("Parameter 5 must contain only images");
2920 }
2921 tmp = SvIV((SV*)SvRV(sv1));
e375fbd8 2922 in_imgs[i] = INT2PTR(i_img*, tmp);
02d1d628
AMH
2923 }
2924 }
2925 else {
2926 /* no input images */
2927 in_imgs = NULL;
2928 }
2929 /* default the output size from the first input if possible */
2930 if (SvOK(ST(0)))
2931 width = SvIV(ST(0));
2932 else if (in_imgs_count)
2933 width = in_imgs[0]->xsize;
2934 else
2935 croak("No output image width supplied");
2936
2937 if (SvOK(ST(1)))
2938 height = SvIV(ST(1));
2939 else if (in_imgs_count)
2940 height = in_imgs[0]->ysize;
2941 else
2942 croak("No output image height supplied");
2943
2944 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2945 if (ops_len % sizeof(struct rm_op))
2946 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2947 ops_count = ops_len / sizeof(struct rm_op);
2948 av = (AV*)SvRV(ST(3));
2949 n_regs_count = av_len(av)+1;
2950 n_regs = mymalloc(n_regs_count * sizeof(double));
2951 for (i = 0; i < n_regs_count; ++i) {
2952 sv1 = *av_fetch(av,i,0);
2953 if (SvOK(sv1))
2954 n_regs[i] = SvNV(sv1);
2955 }
2956 av = (AV*)SvRV(ST(4));
2957 c_regs_count = av_len(av)+1;
2958 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2959 /* I don't bother initializing the colou?r registers */
2960
2961 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2962 n_regs, n_regs_count,
2963 c_regs, c_regs_count, in_imgs, in_imgs_count);
2964 if (in_imgs)
2965 myfree(in_imgs);
2966 myfree(n_regs);
2967 myfree(c_regs);
2968 ST(0) = sv_newmortal();
2969 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2970 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2971
2972
2973void
2974i_contrast(im,intensity)
2975 Imager::ImgRaw im
2976 float intensity
2977
2978void
2979i_hardinvert(im)
2980 Imager::ImgRaw im
2981
2982void
2983i_noise(im,amount,type)
2984 Imager::ImgRaw im
2985 float amount
2986 unsigned char type
2987
2988void
2989i_bumpmap(im,bump,channel,light_x,light_y,strength)
2990 Imager::ImgRaw im
2991 Imager::ImgRaw bump
2992 int channel
2993 int light_x
2994 int light_y
2995 int strength
2996
b2778574
AMH
2997
2998void
2999i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
3000 Imager::ImgRaw im
3001 Imager::ImgRaw bump
3002 int channel
3003 int tx
3004 int ty
3005 float Lx
3006 float Ly
3007 float Lz
3008 float cd
3009 float cs
3010 float n
3011 Imager::Color Ia
3012 Imager::Color Il
3013 Imager::Color Is
3014
3015
3016
02d1d628
AMH
3017void
3018i_postlevels(im,levels)
3019 Imager::ImgRaw im
3020 int levels
3021
3022void
3023i_mosaic(im,size)
3024 Imager::ImgRaw im
3025 int size
3026
3027void
3028i_watermark(im,wmark,tx,ty,pixdiff)
3029 Imager::ImgRaw im
3030 Imager::ImgRaw wmark
3031 int tx
3032 int ty
3033 int pixdiff
3034
3035
3036void
3037i_autolevels(im,lsat,usat,skew)
3038 Imager::ImgRaw im
3039 float lsat
3040 float usat
3041 float skew
3042
3043void
3044i_radnoise(im,xo,yo,rscale,ascale)
3045 Imager::ImgRaw im
3046 float xo
3047 float yo
3048 float rscale
3049 float ascale
3050
3051void
3052i_turbnoise(im, xo, yo, scale)
3053 Imager::ImgRaw im
3054 float xo
3055 float yo
3056 float scale
3057
3058
3059void
3060i_gradgen(im, ...)
3061 Imager::ImgRaw im
3062 PREINIT:
3063 int num;
3064 int *xo;
3065 int *yo;
3066 i_color *ival;
3067 int dmeasure;
3068 int i;
3069 SV *sv;
3070 AV *axx;
3071 AV *ayy;
3072 AV *ac;
3073 CODE:
3074 if (items != 5)
3075 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
3076 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3077 croak("i_gradgen: Second argument must be an array ref");
3078 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3079 croak("i_gradgen: Third argument must be an array ref");
3080 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3081 croak("i_gradgen: Fourth argument must be an array ref");
3082 axx = (AV *)SvRV(ST(1));
3083 ayy = (AV *)SvRV(ST(2));
3084 ac = (AV *)SvRV(ST(3));
3085 dmeasure = (int)SvIV(ST(4));
3086
3087 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3088 num = num <= av_len(ac) ? num : av_len(ac);
3089 num++;
3090 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
3091 xo = mymalloc( sizeof(int) * num );
3092 yo = mymalloc( sizeof(int) * num );
3093 ival = mymalloc( sizeof(i_color) * num );
3094 for(i = 0; i<num; i++) {
3095 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3096 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3097 sv = *av_fetch(ac, i, 0);
3098 if ( !sv_derived_from(sv, "Imager::Color") ) {
3099 free(axx); free(ayy); free(ac);
3100 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
3101 }
4c4c2ffd 3102 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
02d1d628
AMH
3103 }
3104 i_gradgen(im, num, xo, yo, ival, dmeasure);
a73aeb5f
AMH
3105 myfree(xo);
3106 myfree(yo);
3107 myfree(ival);
3108
dff75dee
TC
3109Imager::ImgRaw
3110i_diff_image(im, im2, mindist=0)
3111 Imager::ImgRaw im
3112 Imager::ImgRaw im2
3113 int mindist
02d1d628 3114
6607600c
TC
3115void
3116i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3117 Imager::ImgRaw im
3118 double xa
3119 double ya
3120 double xb
3121 double yb
3122 int type
3123 int repeat
3124 int combine
3125 int super_sample
3126 double ssample_param
3127 PREINIT:
6607600c 3128 AV *asegs;
6607600c
TC
3129 int count;
3130 i_fountain_seg *segs;
6607600c 3131 CODE:
6607600c
TC
3132 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
3133 croak("i_fountain: argument 11 must be an array ref");
3134
3135 asegs = (AV *)SvRV(ST(10));
f1ac5027 3136 segs = load_fount_segs(asegs, &count);
6607600c
TC
3137 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
3138 ssample_param, count, segs);
3139 myfree(segs);
02d1d628 3140
f1ac5027
TC
3141Imager::FillHandle
3142i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
3143 double xa
3144 double ya
3145 double xb
3146 double yb
3147 int type
3148 int repeat
3149 int combine
3150 int super_sample
3151 double ssample_param
3152 PREINIT:
3153 AV *asegs;
3154 int count;
3155 i_fountain_seg *segs;
3156 CODE:
3157 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
3158 croak("i_fountain: argument 11 must be an array ref");
3159
3160 asegs = (AV *)SvRV(ST(9));
3161 segs = load_fount_segs(asegs, &count);
3162 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
3163 super_sample, ssample_param, count, segs);
3164 myfree(segs);
3165 OUTPUT:
3166 RETVAL
3167
4f4f776a
TC
3168void
3169i_errors()
3170 PREINIT:
3171 i_errmsg *errors;
3172 int i;
4f4f776a
TC
3173 AV *av;
3174 SV *ref;
3175 SV *sv;
3176 PPCODE:
3177 errors = i_errors();
3178 i = 0;
3179 while (errors[i].msg) {
3180 av = newAV();
3181 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
3182 if (!av_store(av, 0, sv)) {
3183 SvREFCNT_dec(sv);
3184 }
3185 sv = newSViv(errors[i].code);
3186 if (!av_store(av, 1, sv)) {
3187 SvREFCNT_dec(sv);
3188 }
3189 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
3190 ++i;
3191 }
02d1d628
AMH
3192
3193void
3194i_nearest_color(im, ...)
3195 Imager::ImgRaw im
3196 PREINIT:
3197 int num;
3198 int *xo;
3199 int *yo;
3200 i_color *ival;
3201 int dmeasure;
3202 int i;
3203 SV *sv;
3204 AV *axx;
3205 AV *ayy;
3206 AV *ac;
3207 CODE:
3208 if (items != 5)
3209 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
3210 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3211 croak("i_nearest_color: Second argument must be an array ref");
3212 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
3213 croak("i_nearest_color: Third argument must be an array ref");
3214 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
3215 croak("i_nearest_color: Fourth argument must be an array ref");
3216 axx = (AV *)SvRV(ST(1));
3217 ayy = (AV *)SvRV(ST(2));
3218 ac = (AV *)SvRV(ST(3));
3219 dmeasure = (int)SvIV(ST(4));
3220
3221 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
3222 num = num <= av_len(ac) ? num : av_len(ac);
3223 num++;
3224 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
3225 xo = mymalloc( sizeof(int) * num );
3226 yo = mymalloc( sizeof(int) * num );
3227 ival = mymalloc( sizeof(i_color) * num );
3228 for(i = 0; i<num; i++) {
3229 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
3230 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
3231 sv = *av_fetch(ac, i, 0);
3232 if ( !sv_derived_from(sv, "Imager::Color") ) {
3233 free(axx); free(ayy); free(ac);
3234 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
3235 }
4c4c2ffd 3236 ival[i] = *INT2PTR(i_color *, SvIV((SV *)SvRV(sv)));
02d1d628
AMH
3237 }
3238 i_nearest_color(im, num, xo, yo, ival, dmeasure);
3239
3240
3241
3242
3243void
3244malloc_state()
3245
3246void
3247hashinfo(hv)
3248 PREINIT:
3249 HV* hv;
3250 int stuff;
3251 PPCODE:
3252 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
3253 hv=(HV*)SvRV(ST(0));
3254 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
3255 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3256 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
3257
3258void
3259DSO_open(filename)
3260 char* filename
3261 PREINIT:
3262 void *rc;
3263 char *evstr;
3264 PPCODE:
3265 rc=DSO_open(filename,&evstr);
3266 if (rc!=NULL) {
3267 if (evstr!=NULL) {
3268 EXTEND(SP,2);
e375fbd8 3269 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
02d1d628
AMH
3270 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
3271 } else {
3272 EXTEND(SP,1);
e375fbd8 3273 PUSHs(sv_2mortal(newSViv(PTR2IV(rc))));
02d1d628
AMH
3274 }
3275 }
3276
3277
3278undef_int
3279DSO_close(dso_handle)
3280 void* dso_handle
3281
3282void
3283DSO_funclist(dso_handle_v)
3284 void* dso_handle_v
3285 PREINIT:
3286 int i;
3287 DSO_handle *dso_handle;
3288 PPCODE:
3289 dso_handle=(DSO_handle*)dso_handle_v;
3290 i=0;
3291 while( dso_handle->function_list[i].name != NULL) {
3292 EXTEND(SP,1);
3293 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
3294 EXTEND(SP,1);
3295 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
3296 }
3297
3298
3299void
3300DSO_call(handle,func_index,hv)
3301 void* handle
3302 int func_index
3303 PREINIT:
3304 HV* hv;
3305 PPCODE:
3306 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
3307 hv=(HV*)SvRV(ST(2));
3308 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
3309 DSO_call( (DSO_handle *)handle,func_index,hv);
3310
3311
3312
f5991c03 3313# this is mostly for testing...
faa9b3e7 3314SV *
f5991c03
TC
3315i_get_pixel(im, x, y)
3316 Imager::ImgRaw im
3317 int x
3318 int y;
faa9b3e7
TC
3319 PREINIT:
3320 i_color *color;
3321 CODE:
3322 color = (i_color *)mymalloc(sizeof(i_color));
3323 if (i_gpix(im, x, y, color) == 0) {
3324 ST(0) = sv_newmortal();
3325 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
3326 }
3327 else {
3328 myfree(color);
3329 ST(0) = &PL_sv_undef;
3330 }
3331
3332
3333int
3334i_ppix(im, x, y, cl)
3335 Imager::ImgRaw im
3336 int x
3337 int y
3338 Imager::Color cl
3339
3340Imager::ImgRaw
3341i_img_pal_new(x, y, channels, maxpal)
3342 int x
3343 int y
3344 int channels
3345 int maxpal
3346
3347Imager::ImgRaw
3348i_img_to_pal(src, quant)
3349 Imager::ImgRaw src
3350 PREINIT:
3351 HV *hv;
3352 i_quantize quant;
3353 CODE:
3354 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
3355 croak("i_img_to_pal: second argument must be a hash ref");
3356 hv = (HV *)SvRV(ST(1));
3357 memset(&quant, 0, sizeof(quant));
3358 quant.mc_size = 256;
faa9b3e7
TC
3359 handle_quant_opts(&quant, hv);
3360 RETVAL = i_img_to_pal(src, &quant);
3361 if (RETVAL) {
3362 copy_colors_back(hv, &quant);
3363 }
46a04ceb 3364 cleanup_quant_opts(&quant);
faa9b3e7
TC
3365 OUTPUT:
3366 RETVAL
3367
3368Imager::ImgRaw
3369i_img_to_rgb(src)
3370 Imager::ImgRaw src
3371
3372void
3373i_gpal(im, l, r, y)
3374 Imager::ImgRaw im
3375 int l
3376 int r
3377 int y
3378 PREINIT:
3379 i_palidx *work;
3380 int count, i;
3381 PPCODE:
3382 if (l < r) {
3383 work = mymalloc((r-l) * sizeof(i_palidx));
3384 count = i_gpal(im, l, r, y, work);
3385 if (GIMME_V == G_ARRAY) {
3386 EXTEND(SP, count);
3387 for (i = 0; i < count; ++i) {
3388 PUSHs(sv_2mortal(newSViv(work[i])));
3389 }
3390 }
3391 else {
3392 EXTEND(SP, 1);
26fd367b 3393 PUSHs(sv_2mortal(newSVpv((char *)work, count * sizeof(i_palidx))));
faa9b3e7
TC
3394 }
3395 myfree(work);
3396 }
3397 else {
3398 if (GIMME_V != G_ARRAY) {
3399 EXTEND(SP, 1);
3400 PUSHs(&PL_sv_undef);
3401 }
3402 }
3403
3404int
3405i_ppal(im, l, y, ...)
3406 Imager::ImgRaw im
3407 int l
3408 int y
3409 PREINIT:
3410 i_palidx *work;
3411 int count, i;
3412 CODE:
3413 if (items > 3) {
3414 work = mymalloc(sizeof(i_palidx) * (items-3));
3415 for (i=0; i < items-3; ++i) {
3416 work[i] = SvIV(ST(i+3));
3417 }
3418 RETVAL = i_ppal(im, l, l+items-3, y, work);
3419 myfree(work);
3420 }
3421 else {
3422 RETVAL = 0;
3423 }
3424 OUTPUT:
3425 RETVAL
3426
3427SV *
3428i_addcolors(im, ...)
3429 Imager::ImgRaw im
3430 PREINIT:
3431 int index;
3432 i_color *colors;
3433 int i;
3434 CODE:
3435 if (items < 2)
3436 croak("i_addcolors: no colors to add");
3437 colors = mymalloc((items-1) * sizeof(i_color));
3438 for (i=0; i < items-1; ++i) {
3439 if (sv_isobject(ST(i+1))
3440 && sv_derived_from(ST(i+1), "Imager::Color")) {
3441 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
4c4c2ffd 3442 colors[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3443 }
3444 else {
3445 myfree(colors);
3446 croak("i_plin: pixels must be Imager::Color objects");
3447 }
3448 }
3449 index = i_addcolors(im, colors, items-1);
3450 myfree(colors);
3451 if (index == 0) {
3452 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3453 }
3454 else if (index == -1) {
3455 ST(0) = &PL_sv_undef;
3456 }
3457 else {
3458 ST(0) = sv_2mortal(newSViv(index));
3459 }
3460
3461int
3462i_setcolors(im, index, ...)
3463 Imager::ImgRaw im
3464 int index
3465 PREINIT:
3466 i_color *colors;
3467 int i;
3468 CODE:
3469 if (items < 3)
3470 croak("i_setcolors: no colors to add");
3471 colors = mymalloc((items-2) * sizeof(i_color));
3472 for (i=0; i < items-2; ++i) {
3473 if (sv_isobject(ST(i+2))
3474 && sv_derived_from(ST(i+2), "Imager::Color")) {
3475 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
4c4c2ffd 3476 colors[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3477 }
3478 else {
3479 myfree(colors);
3480 croak("i_setcolors: pixels must be Imager::Color objects");
3481 }
3482 }
3483 RETVAL = i_setcolors(im, index, colors, items-2);
3484 myfree(colors);
3485
3486void
3487i_getcolors(im, index, ...)
3488 Imager::ImgRaw im
3489 int index
3490 PREINIT:
3491 i_color *colors;
3492 int count = 1;
3493 int i;
3494 PPCODE:
3495 if (items > 3)
3496 croak("i_getcolors: too many arguments");
3497 if (items == 3)
3498 count = SvIV(ST(2));
3499 if (count < 1)
3500 croak("i_getcolors: count must be positive");
3501 colors = mymalloc(sizeof(i_color) * count);
3502 if (i_getcolors(im, index, colors, count)) {
3503 for (i = 0; i < count; ++i) {
3504 i_color *pv;
3505 SV *sv = sv_newmortal();
3506 pv = mymalloc(sizeof(i_color));
3507 *pv = colors[i];
3508 sv_setref_pv(sv, "Imager::Color", (void *)pv);
3509 PUSHs(sv);
3510 }
3511 }
3512 myfree(colors);
3513
3514
3515SV *
3516i_colorcount(im)
3517 Imager::ImgRaw im
3518 PREINIT:
3519 int count;
3520 CODE:
3521 count = i_colorcount(im);
3522 if (count >= 0) {
3523 ST(0) = sv_2mortal(newSViv(count));
3524 }
3525 else {
3526 ST(0) = &PL_sv_undef;
3527 }
3528
3529SV *
3530i_maxcolors(im)
3531 Imager::ImgRaw im
3532 PREINIT:
3533 int count;
3534 CODE:
3535 count = i_maxcolors(im);
3536 if (count >= 0) {
3537 ST(0) = sv_2mortal(newSViv(count));
3538 }
3539 else {
3540 ST(0) = &PL_sv_undef;
3541 }
3542
3543SV *
3544i_findcolor(im, color)
3545 Imager::ImgRaw im
3546 Imager::Color color
3547 PREINIT:
3548 i_palidx index;
3549 CODE:
3550 if (i_findcolor(im, color, &index)) {
3551 ST(0) = sv_2mortal(newSViv(index));
3552 }
3553 else {
3554 ST(0) = &PL_sv_undef;
3555 }
3556
3557int
3558i_img_bits(im)
3559 Imager::ImgRaw im
3560
3561int
3562i_img_type(im)
3563 Imager::ImgRaw im
3564
3565int
3566i_img_virtual(im)
3567 Imager::ImgRaw im
3568
3569void
3570i_gsamp(im, l, r, y, ...)
3571 Imager::ImgRaw im
3572 int l
3573 int r
3574 int y
3575 PREINIT:
3576 int *chans;
3577 int chan_count;
3578 i_sample_t *data;
3579 int count, i;
3580 PPCODE:
3581 if (items < 5)
3582 croak("No channel numbers supplied to g_samp()");
3583 if (l < r) {
3584 chan_count = items - 4;
3585 chans = mymalloc(sizeof(int) * chan_count);
3586 for (i = 0; i < chan_count; ++i)
3587 chans[i] = SvIV(ST(i+4));
4dfa5522 3588 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
faa9b3e7 3589 count = i_gsamp(im, l, r, y, data, chans, chan_count);
4dfa5522 3590 myfree(chans);
faa9b3e7
TC
3591 if (GIMME_V == G_ARRAY) {
3592 EXTEND(SP, count);
3593 for (i = 0; i < count; ++i)
3594 PUSHs(sv_2mortal(newSViv(data[i])));
3595 }
3596 else {
3597 EXTEND(SP, 1);
26fd367b 3598 PUSHs(sv_2mortal(newSVpv((char *)data, count * sizeof(i_sample_t))));
faa9b3e7 3599 }
a73aeb5f 3600 myfree(data);
faa9b3e7
TC
3601 }
3602 else {
3603 if (GIMME_V != G_ARRAY) {
3604 EXTEND(SP, 1);
3605 PUSHs(&PL_sv_undef);
3606 }
3607 }
3608
a73aeb5f 3609
faa9b3e7
TC
3610Imager::ImgRaw
3611i_img_masked_new(targ, mask, x, y, w, h)
3612 Imager::ImgRaw targ
3613 int x
3614 int y
3615 int w
3616 int h
3617 PREINIT:
3618 i_img *mask;
3619 CODE:
3620 if (SvOK(ST(1))) {
3621 if (!sv_isobject(ST(1))
3622 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
3623 croak("i_img_masked_new: parameter 2 must undef or an image");
3624 }
4c4c2ffd 3625 mask = INT2PTR(i_img *, SvIV((SV *)SvRV(ST(1))));
faa9b3e7
TC
3626 }
3627 else
3628 mask = NULL;
3629 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
3630 OUTPUT:
3631 RETVAL
3632
3633int
3634i_plin(im, l, y, ...)
3635 Imager::ImgRaw im
3636 int l
3637 int y
3638 PREINIT:
3639 i_color *work;
3640 int count, i;
3641 CODE:
3642 if (items > 3) {
3643 work = mymalloc(sizeof(i_color) * (items-3));
3644 for (i=0; i < items-3; ++i) {
3645 if (sv_isobject(ST(i+3))
3646 && sv_derived_from(ST(i+3), "Imager::Color")) {
3647 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
4c4c2ffd 3648 work[i] = *INT2PTR(i_color *, tmp);
faa9b3e7
TC
3649 }
3650 else {
3651 myfree(work);
3652 croak("i_plin: pixels must be Imager::Color objects");
3653 }
3654 }
3655 /**(char *)0 = 1;*/
3656 RETVAL = i_plin(im, l, l+items-3, y, work);
3657 myfree(work);
3658 }
3659 else {
3660 RETVAL = 0;
3661 }
3662 OUTPUT:
3663 RETVAL
3664
3665int
3666i_ppixf(im, x, y, cl)
3667 Imager::ImgRaw im
3668 int x
3669 int y
3670 Imager::Color::Float cl
3671
3672void
3673i_gsampf(im, l, r, y, ...)
3674 Imager::ImgRaw im
3675 int l
3676 int r
3677 int y
3678 PREINIT:
3679 int *chans;
3680 int chan_count;
3681 i_fsample_t *data;
3682 int count, i;
3683 PPCODE:
3684 if (items < 5)
3685 croak("No channel numbers supplied to g_sampf()");
3686 if (l < r) {
3687 chan_count = items - 4;
3688 chans = mymalloc(sizeof(int) * chan_count);
3689 for (i = 0; i < chan_count; ++i)
3690 chans[i] = SvIV(ST(i+4));
3691 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
3692 count = i_gsampf(im, l, r, y, data, chans, chan_count);
3693 if (GIMME_V == G_ARRAY) {
3694 EXTEND(SP, count);
3695 for (i = 0; i < count; ++i)
3696 PUSHs(sv_2mortal(newSVnv(data[i])));
3697 }
3698 else {
3699 EXTEND(SP, 1);
3700 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
3701 }
3702 }
3703 else {
3704 if (GIMME_V != G_ARRAY) {
3705 EXTEND(SP, 1);
3706 PUSHs(&PL_sv_undef);
3707 }
3708 }
3709
3710int
3711i_plinf(im, l, y, ...)
3712 Imager::ImgRaw im
3713 int l
3714 int y
3715 PREINIT:
3716 i_fcolor *work;
3717 int count, i;
3718 CODE:
3719 if (items > 3) {
3720 work = mymalloc(sizeof(i_fcolor) * (items-3));
3721 for (i=0; i < items-3; ++i) {
3722 if (sv_isobject(ST(i+3))
3723 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
3724 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
4c4c2ffd 3725 work[i] = *INT2PTR(i_fcolor *, tmp);
faa9b3e7
TC
3726 }
3727 else {
3728 myfree(work);
3729 croak("i_plin: pixels must be Imager::Color::Float objects");
3730 }
3731 }
3732 /**(char *)0 = 1;*/
3733 RETVAL = i_plinf(im, l, l+items-3, y, work);
3734 myfree(work);
3735 }
3736 else {
3737 RETVAL = 0;
3738 }
3739 OUTPUT:
3740 RETVAL
3741
3742SV *
3743i_gpixf(im, x, y)
3744 Imager::ImgRaw im
3745 int x
3746 int y;
3747 PREINIT:
3748 i_fcolor *color;
3749 CODE:
3750 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
3751 if (i_gpixf(im, x, y, color) == 0) {
3752 ST(0) = sv_newmortal();
3753 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
3754 }
3755 else {
3756 myfree(color);
3757 ST(0) = &PL_sv_undef;
3758 }
3759
3760void
3761i_glin(im, l, r, y)
3762 Imager::ImgRaw im
3763 int l
3764 int r
3765 int y
3766 PREINIT:
3767 i_color *vals;
3768 int count, i;
3769 PPCODE:
3770 if (l < r) {
3771 vals = mymalloc((r-l) * sizeof(i_color));
3772 count = i_glin(im, l, r, y, vals);
3773 EXTEND(SP, count);
3774 for (i = 0; i < count; ++i) {
3775 SV *sv;
3776 i_color *col = mymalloc(sizeof(i_color));
3777 sv = sv_newmortal();
3778 sv_setref_pv(sv, "Imager::Color", (void *)col);
3779 PUSHs(sv);
3780 }
3781 myfree(vals);
3782 }
3783
3784void
3785i_glinf(im, l, r, y)
3786 Imager::ImgRaw im
3787 int l
3788 int r
3789 int y
3790 PREINIT:
3791 i_fcolor *vals;
3792 int count, i;
3793 PPCODE:
3794 if (l < r) {
3795 vals = mymalloc((r-l) * sizeof(i_fcolor));
3796 count = i_glinf(im, l, r, y, vals);
3797 EXTEND(SP, count);
3798 for (i = 0; i < count; ++i) {
3799 SV *sv;
3800 i_fcolor *col = mymalloc(sizeof(i_fcolor));
3801 *col = vals[i];
3802 sv = sv_newmortal();
3803 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
3804 PUSHs(sv);
3805 }
3806 myfree(vals);
3807 }
3808
3809Imager::ImgRaw
3810i_img_16_new(x, y, ch)
3811 int x
3812 int y
3813 int ch
3814
365ea842
TC
3815Imager::ImgRaw
3816i_img_double_new(x, y, ch)
3817 int x
3818 int y
3819 int ch
3820
faa9b3e7
TC
3821undef_int
3822i_tags_addn(im, name, code, idata)
3823 Imager::ImgRaw im
3824 int code
3825 int idata
3826 PREINIT:
3827 char *name;
3828 STRLEN len;
3829 CODE:
3830 if (SvOK(ST(1)))
3831 name = SvPV(ST(1), len);
3832 else
3833 name = NULL;
3834 RETVAL = i_tags_addn(&im->tags, name, code, idata);
3835 OUTPUT:
3836 RETVAL
3837
3838undef_int
3839i_tags_add(im, name, code, data, idata)
3840 Imager::ImgRaw im
3841 int code
3842 int idata
3843 PREINIT:
3844 char *name;
3845 char *data;
3846 STRLEN len;
3847 CODE:
3848 if (SvOK(ST(1)))
3849 name = SvPV(ST(1), len);
3850 else
3851 name = NULL;
3852 if (SvOK(ST(3)))
3853 data = SvPV(ST(3), len);
3854 else {
3855 data = NULL;
3856 len = 0;
3857 }
3858 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
3859 OUTPUT:
3860 RETVAL
3861
3862SV *
3863i_tags_find(im, name, start)
3864 Imager::ImgRaw im
3865 char *name
3866 int start
3867 PREINIT:
3868 int entry;
3869 CODE:
3870 if (i_tags_find(&im->tags, name, start, &entry)) {
3871 if (entry == 0)
3872 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3873 else
3874 ST(0) = sv_2mortal(newSViv(entry));
3875 } else {
3876 ST(0) = &PL_sv_undef;
3877 }
3878
3879SV *
3880i_tags_findn(im, code, start)
3881 Imager::ImgRaw im
3882 int code
3883 int start
3884 PREINIT:
3885 int entry;
3886 CODE:
3887 if (i_tags_findn(&im->tags, code, start, &entry)) {
3888 if (entry == 0)
3889 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3890 else
3891 ST(0) = sv_2mortal(newSViv(entry));
3892 }
3893 else
3894 ST(0) = &PL_sv_undef;
3895
3896int
3897i_tags_delete(im, entry)
3898 Imager::ImgRaw im
3899 int entry
3900 CODE:
3901 RETVAL = i_tags_delete(&im->tags, entry);
3902 OUTPUT:
3903 RETVAL
3904
3905int
3906i_tags_delbyname(im, name)
3907 Imager::ImgRaw im
3908 char * name
3909 CODE:
3910 RETVAL = i_tags_delbyname(&im->tags, name);
3911 OUTPUT:
3912 RETVAL
3913
3914int
3915i_tags_delbycode(im, code)
3916 Imager::ImgRaw im
3917 int code
3918 CODE:
3919 RETVAL = i_tags_delbycode(&im->tags, code);
3920 OUTPUT:
3921 RETVAL
3922
3923void
3924i_tags_get(im, index)
3925 Imager::ImgRaw im
3926 int index
3927 PPCODE:
3928 if (index >= 0 && index < im->tags.count) {
3929 i_img_tag *entry = im->tags.tags + index;
3930 EXTEND(SP, 5);
3931
3932 if (entry->name) {
3933 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3934 }
3935 else {
3936 PUSHs(sv_2mortal(newSViv(entry->code)));
3937 }
3938 if (entry->data) {
3939 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3940 }
3941 else {
3942 PUSHs(sv_2mortal(newSViv(entry->idata)));
3943 }
3944 }
3945
3946int
3947i_tags_count(im)
3948 Imager::ImgRaw im
3949 CODE:
3950 RETVAL = im->tags.count;
3951 OUTPUT:
3952 RETVAL
3953
3954#ifdef HAVE_WIN32
3955
3956void
3957i_wf_bbox(face, size, text)
3958 char *face
3959 int size
3960 char *text
3799c4d1 3961 int rc, i;
faa9b3e7 3962 PREINIT:
3799c4d1 3963 int cords[BOUNDING_BOX_COUNT];
faa9b3e7 3964 PPCODE:
3799c4d1
TC
3965 if (rc = i_wf_bbox(face, size, text, strlen(text), cords)) {
3966 EXTEND(SP, rc);
3967 for (i = 0; i < rc; ++i)
3968 PUSHs(sv_2mortal(newSViv(cords[i])));
faa9b3e7
TC
3969 }
3970
3971undef_int
3972i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3973 char *face
3974 Imager::ImgRaw im
3975 int tx
3976 int ty
3977 Imager::Color cl
3978 int size
3979 char *text
3980 int align
3981 int aa
3982 CODE:
3983 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3984 align, aa);
3985 OUTPUT:
3986 RETVAL
3987
3988undef_int
3989i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3990 char *face
3991 Imager::ImgRaw im
3992 int tx
3993 int ty
3994 int channel
3995 int size
3996 char *text
3997 int align
3998 int aa
f5991c03 3999 CODE:
faa9b3e7
TC
4000 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
4001 align, aa);
f5991c03
TC
4002 OUTPUT:
4003 RETVAL
02d1d628 4004
faa9b3e7
TC
4005
4006#endif
4007
4008#ifdef HAVE_FT2
4009
4010MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
4011
4012#define FT2_DESTROY(font) i_ft2_destroy(font)
4013
4014void
4015FT2_DESTROY(font)
4016 Imager::Font::FT2 font
4017
4018MODULE = Imager PACKAGE = Imager::Font::FreeType2
4019
4020Imager::Font::FT2
4021i_ft2_new(name, index)
4022 char *name
4023 int index
4024
4025undef_int
4026i_ft2_setdpi(font, xdpi, ydpi)
4027 Imager::Font::FT2 font
4028 int xdpi
4029 int ydpi
4030
4031void
4032i_ft2_getdpi(font)
4033 Imager::Font::FT2 font
4034 PREINIT:
4035 int xdpi, ydpi;
4036 CODE:
4037 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
4038 EXTEND(SP, 2);
4039 PUSHs(sv_2mortal(newSViv(xdpi)));
4040 PUSHs(sv_2mortal(newSViv(ydpi)));
4041 }
4042
4043undef_int
4044i_ft2_sethinting(font, hinting)
4045 Imager::Font::FT2 font
4046 int hinting
4047
4048undef_int
4049i_ft2_settransform(font, matrix)
4050 Imager::Font::FT2 font
4051 PREINIT:
4052 double matrix[6];
4053 int len;
4054 AV *av;
4055 SV *sv1;
4056 int i;
4057 CODE:
4058 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
4059 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
4060 av=(AV*)SvRV(ST(1));
4061 len=av_len(av)+1;
4062 if (len > 6)
4063 len = 6;
4064 for (i = 0; i < len; ++i) {
4065 sv1=(*(av_fetch(av,i,0)));
4066 matrix[i] = SvNV(sv1);
4067 }
4068 for (; i < 6; ++i)
4069 matrix[i] = 0;
4070 RETVAL = i_ft2_settransform(font, matrix);
4071 OUTPUT:
4072 RETVAL
4073
4074void
3799c4d1 4075i_ft2_bbox(font, cheight, cwidth, text_sv, utf8)
faa9b3e7
TC
4076 Imager::Font::FT2 font
4077 double cheight
4078 double cwidth
3799c4d1 4079 SV *text_sv
5cb9270b 4080 int utf8
faa9b3e7 4081 PREINIT:
3799c4d1 4082 int bbox[BOUNDING_BOX_COUNT];
faa9b3e7 4083 int i;
3799c4d1
TC
4084 char *text;
4085 STRLEN text_len;
4086 int rc;
faa9b3e7 4087 PPCODE:
3799c4d1 4088 text = SvPV(text_sv, text_len);
5cb9270b 4089#ifdef SvUTF8
3799c4d1 4090 if (SvUTF8(text_sv))
5cb9270b
TC
4091 utf8 = 1;
4092#endif
3799c4d1
TC
4093 rc = i_ft2_bbox(font, cheight, cwidth, text, text_len, bbox, utf8);
4094 if (rc) {
4095 EXTEND(SP, rc);
4096 for (i = 0; i < rc; ++i)
faa9b3e7
TC
4097 PUSHs(sv_2mortal(newSViv(bbox[i])));
4098 }
4099
4100void
4101i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
4102 Imager::Font::FT2 font
4103 double cheight
4104 double cwidth
4105 char *text
4106 int vlayout
4107 int utf8
4108 PREINIT:
4109 int bbox[8];
4110 int i;
4111 PPCODE:
4112#ifdef SvUTF8
4113 if (SvUTF8(ST(3)))
4114 utf8 = 1;
4115#endif
4116 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
4117 utf8, bbox)) {
4118 EXTEND(SP, 8);
4119 for (i = 0; i < 8; ++i)
4120 PUSHs(sv_2mortal(newSViv(bbox[i])));
4121 }
4122
4123undef_int
4124i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
4125 Imager::Font::FT2 font
4126 Imager::ImgRaw im
4127 int tx
4128 int ty
4129 Imager::Color cl
4130 double cheight
4131 double cwidth
4132 int align
4133 int aa
4134 int vlayout
4135 int utf8
4136 PREINIT:
4137 char *text;
4138 STRLEN len;
4139 CODE:
4140#ifdef SvUTF8
4141 if (SvUTF8(ST(7))) {
4142 utf8 = 1;
4143 }
4144#endif
4145 text = SvPV(ST(7), len);
4146 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
4147 len, align, aa, vlayout, utf8);
4148 OUTPUT:
4149 RETVAL
4150
4151undef_int
4152i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
4153 Imager::Font::FT2 font
4154 Imager::ImgRaw im
4155 int tx
4156 int ty
4157 int channel
4158 double cheight
4159 double cwidth
4160 char *text
4161 int align
4162 int aa
4163 int vlayout
4164 int utf8
4165 CODE:
4166#ifdef SvUTF8
4167 if (SvUTF8(ST(7)))
4168 utf8 = 1;
4169#endif
4170 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
4171 strlen(text), align, aa, vlayout, 1);
4172 OUTPUT:
4173 RETVAL
4174
4175void
4176ft2_transform_box(font, x0, x1, x2, x3)
4177 Imager::Font::FT2 font
4178 int x0
4179 int x1
4180 int x2
4181 int x3
4182 PREINIT:
4183 int box[4];
4184 PPCODE:
4185 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
4186 ft2_transform_box(font, box);
4187 EXTEND(SP, 4);
4188 PUSHs(sv_2mortal(newSViv(box[0])));
4189 PUSHs(sv_2mortal(newSViv(box[1])));
4190 PUSHs(sv_2mortal(newSViv(box[2])));
4191 PUSHs(sv_2mortal(newSViv(box[3])));
3dec2c92
TC
4192
4193void
eeaa33fd 4194i_ft2_has_chars(handle, text_sv, utf8)
3dec2c92 4195 Imager::Font::FT2 handle
eeaa33fd 4196 SV *text_sv
3dec2c92
TC
4197 int utf8
4198 PREINIT:
4199 char *text;
4200 STRLEN len;
4201 char *work;
4202 int count;
4203 int i;
4204 PPCODE:
4205#ifdef SvUTF8
eeaa33fd 4206 if (SvUTF8(text_sv))
3dec2c92
TC
4207 utf8 = 1;
4208#endif
eeaa33fd 4209 text = SvPV(text_sv, len);
3dec2c92
TC
4210 work = mymalloc(len);
4211 count = i_ft2_has_chars(handle, text, len, utf8, work);
4212 if (GIMME_V == G_ARRAY) {
4213 EXTEND(SP, count);
4214 for (i = 0; i < count; ++i) {
4215 PUSHs(sv_2mortal(newSViv(work[i])));
4216 }
4217 }
4218 else {
4219 EXTEND(SP, 1);
4220 PUSHs(sv_2mortal(newSVpv(work, count)));
4221 }
4222 myfree(work);
4223
3799c4d1
TC
4224void
4225i_ft2_face_name(handle)
4226 Imager::Font::FT2 handle
4227 PREINIT:
4228 char name[255];
4229 int len;
4230 PPCODE:
4231 len = i_ft2_face_name(handle, name, sizeof(name));
4232 if (len) {
4233 EXTEND(SP, 1);
4234 PUSHs(sv_2mortal(newSVpv(name, 0)));
4235 }
4236
19fa4baf
AMH
4237void
4238i_ft2_glyph_name(handle, text_sv, utf8 = 0)
3799c4d1
TC
4239 Imager::Font::FT2 handle
4240 SV *text_sv
4241 int utf8
4242 PREINIT:
4243 char const *text;
4244 STRLEN work_len;
4245 int len;
4246 int outsize;
4247 char name[255];
4248 PPCODE:
4249#ifdef SvUTF8
4250 if (SvUTF8(text_sv))
4251 utf8 = 1;
4252#endif
4253 text = SvPV(text_sv, work_len);
4254 len = work_len;
4255 while (len) {
4256 unsigned char ch;
4257 if (utf8) {
4258 ch = i_utf8_advance(&text, &len);
4259 if (ch == ~0UL) {
4260 i_push_error(0, "invalid UTF8 character");
4261 break;
4262 }
4263 }
4264 else {
4265 ch = *text++;
4266 --len;
4267 }
4268 EXTEND(SP, 1);
4269 if (outsize = i_ft2_glyph_name(handle, ch, name, sizeof(name))) {
4270 PUSHs(sv_2mortal(newSVpv(name, 0)));
4271 }
4272 else {
4273 PUSHs(&PL_sv_undef);
4274 }
4275 }
4276
4277int
4278i_ft2_can_do_glyph_names()
4279
4280int
4281i_ft2_face_has_glyph_names(handle)
4282 Imager::Font::FT2 handle
4283
faa9b3e7
TC
4284#endif
4285
f1ac5027
TC
4286MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
4287
4288void
4289IFILL_DESTROY(fill)
4290 Imager::FillHandle fill
4291
4292MODULE = Imager PACKAGE = Imager
4293
4294Imager::FillHandle
4295i_new_fill_solid(cl, combine)
4296 Imager::Color cl
4297 int combine
4298
4299Imager::FillHandle
4300i_new_fill_solidf(cl, combine)
4301 Imager::Color::Float cl
4302 int combine
4303
4304Imager::FillHandle
4305i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
4306 Imager::Color fg
4307 Imager::Color bg
4308 int combine
4309 int hatch
4310 int dx
4311 int dy
4312 PREINIT:
4313 unsigned char *cust_hatch;
4314 STRLEN len;
4315 CODE:
4316 if (SvOK(ST(4))) {
26fd367b 4317 cust_hatch = (unsigned char *)SvPV(ST(4), len);
f1ac5027
TC
4318 }
4319 else
4320 cust_hatch = NULL;
4321 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
4322 OUTPUT:
4323 RETVAL
4324
efdc2568
TC
4325Imager::FillHandle
4326i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
4327 Imager::Color::Float fg
4328 Imager::Color::Float bg
4329 int combine
4330 int hatch
4331 int dx
4332 int dy
4333 PREINIT:
4334 unsigned char *cust_hatch;
4335 STRLEN len;
4336 CODE:
4337 if (SvOK(ST(4))) {
26fd367b 4338 cust_hatch = (unsigned char *)SvPV(ST(4), len);
efdc2568
TC
4339 }
4340 else
4341 cust_hatch = NULL;
4342 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
4343 OUTPUT:
4344 RETVAL
4345
f576ce7e
TC
4346Imager::FillHandle
4347i_new_fill_image(src, matrix, xoff, yoff, combine)
4348 Imager::ImgRaw src
4349 int xoff
4350 int yoff
4351 int combine
4352 PREINIT:
4353 double matrix[9];
4354 double *matrixp;
4355 AV *av;
4356 IV len;
4357 SV *sv1;
4358 int i;
4359