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