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