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