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