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