(changes)
[imager.git] / Imager.xs
CommitLineData
02d1d628
AMH
1#ifdef __cplusplus
2extern "C" {
3#endif
4#include "EXTERN.h"
5#include "perl.h"
6#include "XSUB.h"
7#include "ppport.h"
8#ifdef __cplusplus
9
10#endif
11
12#include "image.h"
13#include "feat.h"
14#include "dynaload.h"
15#include "regmach.h"
16
17typedef io_glue* Imager__IO;
18typedef i_color* Imager__Color;
faa9b3e7 19typedef i_fcolor* Imager__Color__Float;
02d1d628
AMH
20typedef i_img* Imager__ImgRaw;
21
22
23#ifdef HAVE_LIBTT
24typedef TT_Fonthandle* Imager__TTHandle;
25#endif
26
faa9b3e7
TC
27#ifdef HAVE_FT2
28typedef FT2_Fonthandle* Imager__Font__FT2;
29#endif
30
02d1d628
AMH
31typedef struct i_reader_data_tag
32{
33 /* presumably a CODE ref or name of a sub */
34 SV *sv;
35} i_reader_data;
36
37/* used by functions that want callbacks */
38static int read_callback(char *userdata, char *buffer, int need, int want) {
39 i_reader_data *rd = (i_reader_data *)userdata;
40 int count;
41 int result;
42 SV *data;
43 dSP; dTARG = sv_newmortal();
44 /* thanks to Simon Cozens for help with the dTARG above */
45
46 ENTER;
47 SAVETMPS;
48 EXTEND(SP, 2);
49 PUSHMARK(SP);
50 PUSHi(want);
51 PUSHi(need);
52 PUTBACK;
53
54 count = perl_call_sv(rd->sv, G_SCALAR);
55
56 SPAGAIN;
57
58 if (count != 1)
59 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
60
61 data = POPs;
62
63 if (SvOK(data)) {
64 STRLEN len;
65 char *ptr = SvPV(data, len);
66 if (len > want)
67 croak("Too much data returned in reader callback");
68
69 memcpy(buffer, ptr, len);
70 result = len;
71 }
72 else {
73 result = -1;
74 }
75
76 PUTBACK;
77 FREETMPS;
78 LEAVE;
79
80 return result;
81}
82
83typedef struct
84{
85 SV *sv; /* a coderef or sub name */
86} i_writer_data;
87
88/* used by functions that want callbacks */
89static int write_callback(char *userdata, char const *data, int size) {
90 i_writer_data *wd = (i_writer_data *)userdata;
91 int count;
92 int success;
93 SV *sv;
94 dSP;
95
96 ENTER;
97 SAVETMPS;
98 EXTEND(SP, 1);
99 PUSHMARK(SP);
100 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
101 PUTBACK;
102
103 count = perl_call_sv(wd->sv, G_SCALAR);
104
105 SPAGAIN;
106
107 if (count != 1)
108 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
109
110 sv = POPs;
111 success = SvTRUE(sv);
112
113
114 PUTBACK;
115 FREETMPS;
116 LEAVE;
117
118 return success;
119}
120
121struct value_name {
122 char *name;
123 int value;
124};
125static int lookup_name(struct value_name *names, int count, char *name, int def_value)
126{
127 int i;
128 for (i = 0; i < count; ++i)
129 if (strEQ(names[i].name, name))
130 return names[i].value;
131
132 return def_value;
133}
134static struct value_name transp_names[] =
135{
136 { "none", tr_none },
137 { "threshold", tr_threshold },
138 { "errdiff", tr_errdiff },
139 { "ordered", tr_ordered, },
140};
141
142static struct value_name make_color_names[] =
143{
144 { "none", mc_none, },
145 { "webmap", mc_web_map, },
146 { "addi", mc_addi, },
147};
148
149static struct value_name translate_names[] =
150{
151#ifdef HAVE_LIBGIF
152 { "giflib", pt_giflib, },
153#endif
154 { "closest", pt_closest, },
155 { "perturb", pt_perturb, },
156 { "errdiff", pt_errdiff, },
157};
158
159static struct value_name errdiff_names[] =
160{
161 { "floyd", ed_floyd, },
162 { "jarvis", ed_jarvis, },
163 { "stucki", ed_stucki, },
164 { "custom", ed_custom, },
165};
166
167static struct value_name orddith_names[] =
168{
169 { "random", od_random, },
170 { "dot8", od_dot8, },
171 { "dot4", od_dot4, },
172 { "hline", od_hline, },
173 { "vline", od_vline, },
174 { "/line", od_slashline, },
175 { "slashline", od_slashline, },
176 { "\\line", od_backline, },
177 { "backline", od_backline, },
e7d4ea82 178 { "tiny", od_tiny, },
02d1d628
AMH
179 { "custom", od_custom, },
180};
181
182/* look through the hash for quantization options */
183static void handle_quant_opts(i_quantize *quant, HV *hv)
184{
185 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
186 SV **sv;
187 int i;
188 STRLEN len;
189 char *str;
190
191 sv = hv_fetch(hv, "transp", 6, 0);
192 if (sv && *sv && (str = SvPV(*sv, len))) {
193 quant->transp =
194 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
195 str, tr_none);
196 if (quant->transp != tr_none) {
197 quant->tr_threshold = 127;
198 sv = hv_fetch(hv, "tr_threshold", 12, 0);
199 if (sv && *sv)
200 quant->tr_threshold = SvIV(*sv);
201 }
202 if (quant->transp == tr_errdiff) {
203 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
204 if (sv && *sv && (str = SvPV(*sv, len)))
205 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
206 }
207 if (quant->transp == tr_ordered) {
e7d4ea82 208 quant->tr_orddith = od_tiny;
02d1d628
AMH
209 sv = hv_fetch(hv, "tr_orddith", 10, 0);
210 if (sv && *sv && (str = SvPV(*sv, len)))
211 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
212
213 if (quant->tr_orddith == od_custom) {
214 sv = hv_fetch(hv, "tr_map", 6, 0);
215 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
216 AV *av = (AV*)SvRV(*sv);
217 len = av_len(av) + 1;
218 if (len > sizeof(quant->tr_custom))
219 len = sizeof(quant->tr_custom);
220 for (i = 0; i < len; ++i) {
221 SV **sv2 = av_fetch(av, i, 0);
222 if (sv2 && *sv2) {
223 quant->tr_custom[i] = SvIV(*sv2);
224 }
225 }
226 while (i < sizeof(quant->tr_custom))
227 quant->tr_custom[i++] = 0;
228 }
229 }
230 }
231 }
232 quant->make_colors = mc_addi;
233 sv = hv_fetch(hv, "make_colors", 11, 0);
234 if (sv && *sv && (str = SvPV(*sv, len))) {
235 quant->make_colors =
236 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
237 }
238 sv = hv_fetch(hv, "colors", 6, 0);
239 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
240 /* needs to be an array of Imager::Color
241 note that the caller allocates the mc_color array and sets mc_size
242 to it's size */
243 AV *av = (AV *)SvRV(*sv);
244 quant->mc_count = av_len(av)+1;
245 if (quant->mc_count > quant->mc_size)
246 quant->mc_count = quant->mc_size;
247 for (i = 0; i < quant->mc_count; ++i) {
248 SV **sv1 = av_fetch(av, i, 0);
249 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
250 i_color *col = (i_color *)SvIV((SV*)SvRV(*sv1));
251 quant->mc_colors[i] = *col;
252 }
253 }
254 }
255 sv = hv_fetch(hv, "max_colors", 10, 0);
256 if (sv && *sv) {
257 i = SvIV(*sv);
258 if (i <= quant->mc_size && i >= quant->mc_count)
259 quant->mc_size = i;
260 }
261
262 quant->translate = pt_closest;
263 sv = hv_fetch(hv, "translate", 9, 0);
264 if (sv && *sv && (str = SvPV(*sv, len))) {
265 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
266 }
267 sv = hv_fetch(hv, "errdiff", 7, 0);
268 if (sv && *sv && (str = SvPV(*sv, len))) {
269 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
270 }
271 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
272 /* get the error diffusion map */
273 sv = hv_fetch(hv, "errdiff_width", 13, 0);
274 if (sv && *sv)
275 quant->ed_width = SvIV(*sv);
276 sv = hv_fetch(hv, "errdiff_height", 14, 0);
277 if (sv && *sv)
278 quant->ed_height = SvIV(*sv);
279 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
280 if (sv && *sv)
281 quant->ed_orig = SvIV(*sv);
282 if (quant->ed_width > 0 && quant->ed_height > 0) {
283 int sum = 0;
284 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
285 sv = hv_fetch(hv, "errdiff_map", 11, 0);
286 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
287 AV *av = (AV*)SvRV(*sv);
288 len = av_len(av) + 1;
289 if (len > quant->ed_width * quant->ed_height)
290 len = quant->ed_width * quant->ed_height;
291 for (i = 0; i < len; ++i) {
292 SV **sv2 = av_fetch(av, i, 0);
293 if (sv2 && *sv2) {
294 quant->ed_map[i] = SvIV(*sv2);
295 sum += quant->ed_map[i];
296 }
297 }
298 }
299 if (!sum) {
300 /* broken map */
301 myfree(quant->ed_map);
302 quant->ed_map = 0;
303 quant->errdiff = ed_floyd;
304 }
305 }
306 }
307 sv = hv_fetch(hv, "perturb", 7, 0);
308 if (sv && *sv)
309 quant->perturb = SvIV(*sv);
310}
311
312/* look through the hash for options to add to opts */
313static void handle_gif_opts(i_gif_opts *opts, HV *hv)
314{
315 /*** FIXME: POSSIBLY BROKEN: do I need to unref the SV from hv_fetch? ***/
316 SV **sv;
317 int i;
318 /**((char *)0) = '\0';*/
319 sv = hv_fetch(hv, "gif_each_palette", 16, 0);
320 if (sv && *sv)
321 opts->each_palette = SvIV(*sv);
322 sv = hv_fetch(hv, "interlace", 9, 0);
323 if (sv && *sv)
324 opts->interlace = SvIV(*sv);
325 sv = hv_fetch(hv, "gif_delays", 10, 0);
326 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
327 AV *av = (AV*)SvRV(*sv);
328 opts->delay_count = av_len(av)+1;
329 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
330 for (i = 0; i < opts->delay_count; ++i) {
331 SV *sv1 = *av_fetch(av, i, 0);
332 opts->delays[i] = SvIV(sv1);
333 }
334 }
335 sv = hv_fetch(hv, "gif_user_input", 14, 0);
336 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
337 AV *av = (AV*)SvRV(*sv);
338 opts->user_input_count = av_len(av)+1;
339 opts->user_input_flags = mymalloc(opts->user_input_count);
340 for (i = 0; i < opts->user_input_count; ++i) {
341 SV *sv1 = *av_fetch(av, i, 0);
342 opts->user_input_flags[i] = SvIV(sv1) != 0;
343 }
344 }
345 sv = hv_fetch(hv, "gif_disposal", 12, 0);
346 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
347 AV *av = (AV*)SvRV(*sv);
348 opts->disposal_count = av_len(av)+1;
349 opts->disposal = mymalloc(opts->disposal_count);
350 for (i = 0; i < opts->disposal_count; ++i) {
351 SV *sv1 = *av_fetch(av, i, 0);
352 opts->disposal[i] = SvIV(sv1);
353 }
354 }
355 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
356 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
357 i_color *col = (i_color *)SvIV((SV *)SvRV(*sv));
358 opts->tran_color = *col;
359 }
360 sv = hv_fetch(hv, "gif_positions", 13, 0);
361 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
362 AV *av = (AV *)SvRV(*sv);
363 opts->position_count = av_len(av) + 1;
364 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
365 for (i = 0; i < opts->position_count; ++i) {
366 SV **sv2 = av_fetch(av, i, 0);
367 opts->positions[i].x = opts->positions[i].y = 0;
368 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
369 AV *av2 = (AV*)SvRV(*sv2);
370 SV **sv3;
371 sv3 = av_fetch(av2, 0, 0);
372 if (sv3 && *sv3)
373 opts->positions[i].x = SvIV(*sv3);
374 sv3 = av_fetch(av2, 1, 0);
375 if (sv3 && *sv3)
376 opts->positions[i].y = SvIV(*sv3);
377 }
378 }
379 }
380 /* Netscape2.0 loop count extension */
381 sv = hv_fetch(hv, "gif_loop_count", 14, 0);
382 if (sv && *sv)
383 opts->loop_count = SvIV(*sv);
384}
385
386/* copies the color map from the hv into the colors member of the HV */
387static void copy_colors_back(HV *hv, i_quantize *quant) {
388 SV **sv;
389 AV *av;
390 int i;
391 SV *work;
392
393 sv = hv_fetch(hv, "colors", 6, 0);
394 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
395 SV *ref;
396 av = newAV();
397 ref = newRV_inc((SV*) av);
398 sv = hv_store(hv, "colors", 6, ref, 0);
399 }
400 else {
401 av = (AV *)SvRV(*sv);
402 }
403 av_extend(av, quant->mc_count+1);
404 for (i = 0; i < quant->mc_count; ++i) {
405 i_color *in = quant->mc_colors+i;
406 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
407 work = sv_newmortal();
408 sv_setref_pv(work, "Imager::Color", (void *)c);
409 SvREFCNT_inc(work);
410 if (!av_store(av, i, work)) {
411 SvREFCNT_dec(work);
412 }
413 }
414}
415
faa9b3e7
TC
416/* I don't think ICLF_* names belong at the C interface
417 this makes the XS code think we have them, to let us avoid
418 putting function bodies in the XS code
419*/
420#define ICLF_new_internal(r, g, b, a) i_fcolor_new((r), (g), (b), (a))
421#define ICLF_DESTROY(cl) i_fcolor_destroy(cl)
422
02d1d628
AMH
423MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
424
425Imager::Color
426ICL_new_internal(r,g,b,a)
427 unsigned char r
428 unsigned char g
429 unsigned char b
430 unsigned char a
431
432void
433ICL_DESTROY(cl)
434 Imager::Color cl
435
436
29106a11 437void
02d1d628
AMH
438ICL_set_internal(cl,r,g,b,a)
439 Imager::Color cl
440 unsigned char r
441 unsigned char g
442 unsigned char b
443 unsigned char a
29106a11 444 PPCODE:
46062ab6 445 ICL_set_internal(cl, r, g, b, a);
29106a11
TC
446 EXTEND(SP, 1);
447 PUSHs(ST(0));
02d1d628
AMH
448
449void
450ICL_info(cl)
451 Imager::Color cl
452
453
454void
455ICL_rgba(cl)
456 Imager::Color cl
457 PPCODE:
458 EXTEND(SP, 4);
459 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
460 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
461 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
462 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
463
464
465
466
faa9b3e7 467MODULE = Imager PACKAGE = Imager::Color::Float PREFIX=ICLF_
02d1d628 468
faa9b3e7
TC
469Imager::Color::Float
470ICLF_new_internal(r, g, b, a)
471 double r
472 double g
473 double b
474 double a
475
476void
477ICLF_DESTROY(cl)
478 Imager::Color::Float cl
02d1d628 479
faa9b3e7
TC
480void
481ICLF_rgba(cl)
482 Imager::Color::Float cl
483 PREINIT:
484 int ch;
485 PPCODE:
486 EXTEND(SP, MAXCHANNELS);
487 for (ch = 0; ch < MAXCHANNELS; ++ch) {
488 /* printf("%d: %g\n", ch, cl->channel[ch]); */
489 PUSHs(sv_2mortal(newSVnv(cl->channel[ch])));
490 }
491
492void
493ICLF_set_internal(cl,r,g,b,a)
494 Imager::Color::Float cl
495 double r
496 double g
497 double b
498 double a
499 PPCODE:
500 cl->rgba.r = r;
501 cl->rgba.g = g;
502 cl->rgba.b = b;
503 cl->rgba.a = a;
504 EXTEND(SP, 1);
505 PUSHs(ST(0));
02d1d628
AMH
506
507MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
508
509Imager::ImgRaw
510IIM_new(x,y,ch)
511 int x
512 int y
513 int ch
514
515void
516IIM_DESTROY(im)
517 Imager::ImgRaw im
518
519
520
521MODULE = Imager PACKAGE = Imager
522
523PROTOTYPES: ENABLE
524
525
526Imager::IO
527io_new_fd(fd)
528 int fd
529
530Imager::IO
531io_new_bufchain()
532
533
534void
535io_slurp(ig)
536 Imager::IO ig
537 PREINIT:
538 unsigned char* data;
539 size_t tlength;
540 SV* r;
541 PPCODE:
542 data = NULL;
543 tlength = io_slurp(ig, &data);
544 r = sv_newmortal();
545 EXTEND(SP,1);
546 PUSHs(sv_2mortal(newSVpv(data,tlength)));
547 myfree(data);
548
549
550
551void
552i_list_formats()
553 PREINIT:
554 char* item;
555 int i;
556 PPCODE:
557 i=0;
558 while( (item=i_format_list[i++]) != NULL ) {
559 EXTEND(SP, 1);
560 PUSHs(sv_2mortal(newSVpv(item,0)));
561 }
562
563undef_int
564i_has_format(frmt)
565 char* frmt
566
567Imager::ImgRaw
568i_img_new()
569
570Imager::ImgRaw
571i_img_empty(im,x,y)
572 Imager::ImgRaw im
573 int x
574 int y
575
576Imager::ImgRaw
577i_img_empty_ch(im,x,y,ch)
578 Imager::ImgRaw im
579 int x
580 int y
581 int ch
582
583void
584init_log(name,level)
585 char* name
586 int level
587
588void
589i_img_exorcise(im)
590 Imager::ImgRaw im
591
592void
593i_img_destroy(im)
594 Imager::ImgRaw im
595
596void
597i_img_info(im)
598 Imager::ImgRaw im
599 PREINIT:
600 int info[4];
601 PPCODE:
602 i_img_info(im,info);
603 EXTEND(SP, 4);
604 PUSHs(sv_2mortal(newSViv(info[0])));
605 PUSHs(sv_2mortal(newSViv(info[1])));
606 PUSHs(sv_2mortal(newSViv(info[2])));
607 PUSHs(sv_2mortal(newSViv(info[3])));
608
609
610
611
612void
613i_img_setmask(im,ch_mask)
614 Imager::ImgRaw im
615 int ch_mask
616
617int
618i_img_getmask(im)
619 Imager::ImgRaw im
620
621int
622i_img_getchannels(im)
623 Imager::ImgRaw im
624
625void
626i_img_getdata(im)
627 Imager::ImgRaw im
628 PPCODE:
629 EXTEND(SP, 1);
faa9b3e7
TC
630 PUSHs(im->idata ? sv_2mortal(newSVpv(im->idata, im->bytes))
631 : &PL_sv_undef);
02d1d628
AMH
632
633
634void
635i_draw(im,x1,y1,x2,y2,val)
636 Imager::ImgRaw im
637 int x1
638 int y1
639 int x2
640 int y2
641 Imager::Color val
642
643void
644i_line_aa(im,x1,y1,x2,y2,val)
645 Imager::ImgRaw im
646 int x1
647 int y1
648 int x2
649 int y2
650 Imager::Color val
651
652void
653i_box(im,x1,y1,x2,y2,val)
654 Imager::ImgRaw im
655 int x1
656 int y1
657 int x2
658 int y2
659 Imager::Color val
660
661void
662i_box_filled(im,x1,y1,x2,y2,val)
663 Imager::ImgRaw im
664 int x1
665 int y1
666 int x2
667 int y2
668 Imager::Color val
669
670void
671i_arc(im,x,y,rad,d1,d2,val)
672 Imager::ImgRaw im
673 int x
674 int y
675 float rad
676 float d1
677 float d2
678 Imager::Color val
679
680
681
6af18d2b
AMH
682void
683i_circle_aa(im,x,y,rad,val)
684 Imager::ImgRaw im
685 float x
686 float y
687 float rad
688 Imager::Color val
689
690
691
02d1d628
AMH
692void
693i_bezier_multi(im,xc,yc,val)
694 Imager::ImgRaw im
695 Imager::Color val
696 PREINIT:
697 double *x,*y;
698 int len;
699 AV *av1;
700 AV *av2;
701 SV *sv1;
702 SV *sv2;
703 int i;
704 PPCODE:
705 ICL_info(val);
706 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
707 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
708 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
709 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
710 av1=(AV*)SvRV(ST(1));
711 av2=(AV*)SvRV(ST(2));
712 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
713 len=av_len(av1)+1;
714 x=mymalloc( len*sizeof(double) );
715 y=mymalloc( len*sizeof(double) );
716 for(i=0;i<len;i++) {
717 sv1=(*(av_fetch(av1,i,0)));
718 sv2=(*(av_fetch(av2,i,0)));
719 x[i]=(double)SvNV(sv1);
720 y[i]=(double)SvNV(sv2);
721 }
722 i_bezier_multi(im,len,x,y,val);
723 myfree(x);
724 myfree(y);
725
726
727void
728i_poly_aa(im,xc,yc,val)
729 Imager::ImgRaw im
730 Imager::Color val
731 PREINIT:
732 double *x,*y;
733 int len;
734 AV *av1;
735 AV *av2;
736 SV *sv1;
737 SV *sv2;
738 int i;
739 PPCODE:
740 ICL_info(val);
741 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
742 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
743 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
744 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
745 av1=(AV*)SvRV(ST(1));
746 av2=(AV*)SvRV(ST(2));
747 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
748 len=av_len(av1)+1;
749 x=mymalloc( len*sizeof(double) );
750 y=mymalloc( len*sizeof(double) );
751 for(i=0;i<len;i++) {
752 sv1=(*(av_fetch(av1,i,0)));
753 sv2=(*(av_fetch(av2,i,0)));
754 x[i]=(double)SvNV(sv1);
755 y[i]=(double)SvNV(sv2);
756 }
757 i_poly_aa(im,len,x,y,val);
758 myfree(x);
759 myfree(y);
760
761
762
763void
764i_flood_fill(im,seedx,seedy,dcol)
765 Imager::ImgRaw im
766 int seedx
767 int seedy
768 Imager::Color dcol
769
770
771void
772i_copyto(im,src,x1,y1,x2,y2,tx,ty)
773 Imager::ImgRaw im
774 Imager::ImgRaw src
775 int x1
776 int y1
777 int x2
778 int y2
779 int tx
780 int ty
781
782
783void
784i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
785 Imager::ImgRaw im
786 Imager::ImgRaw src
787 int x1
788 int y1
789 int x2
790 int y2
791 int tx
792 int ty
793 Imager::Color trans
794
795void
796i_copy(im,src)
797 Imager::ImgRaw im
798 Imager::ImgRaw src
799
800
faa9b3e7 801undef_int
02d1d628
AMH
802i_rubthru(im,src,tx,ty)
803 Imager::ImgRaw im
804 Imager::ImgRaw src
805 int tx
806 int ty
807
142c26ff
AMH
808undef_int
809i_flipxy(im, direction)
810 Imager::ImgRaw im
811 int direction
812
faa9b3e7
TC
813Imager::ImgRaw
814i_rotate90(im, degrees)
815 Imager::ImgRaw im
816 int degrees
817
818Imager::ImgRaw
819i_rotate_exact(im, amount)
820 Imager::ImgRaw im
821 double amount
822
823Imager::ImgRaw
824i_matrix_transform(im, xsize, ysize, matrix)
825 Imager::ImgRaw im
826 int xsize
827 int ysize
828 PREINIT:
829 double matrix[9];
830 AV *av;
831 IV len;
832 SV *sv1;
833 int i;
834 CODE:
835 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
836 croak("i_matrix_transform: parameter 4 must be an array ref\n");
837 av=(AV*)SvRV(ST(3));
838 len=av_len(av)+1;
839 if (len > 9)
840 len = 9;
841 for (i = 0; i < len; ++i) {
842 sv1=(*(av_fetch(av,i,0)));
843 matrix[i] = SvNV(sv1);
844 }
845 for (; i < 9; ++i)
846 matrix[i] = 0;
847 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
848 OUTPUT:
849 RETVAL
02d1d628
AMH
850
851void
852i_gaussian(im,stdev)
853 Imager::ImgRaw im
854 float stdev
855
856void
857i_conv(im,pcoef)
858 Imager::ImgRaw im
859 PREINIT:
860 float* coeff;
861 int len;
862 AV* av;
863 SV* sv1;
864 int i;
865 PPCODE:
866 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
867 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
868 av=(AV*)SvRV(ST(1));
869 len=av_len(av)+1;
870 coeff=mymalloc( len*sizeof(float) );
871 for(i=0;i<len;i++) {
872 sv1=(*(av_fetch(av,i,0)));
873 coeff[i]=(float)SvNV(sv1);
874 }
875 i_conv(im,coeff,len);
876 myfree(coeff);
877
f5991c03
TC
878undef_int
879i_convert(im, src, coeff)
880 Imager::ImgRaw im
881 Imager::ImgRaw src
882 PREINIT:
883 float *coeff;
884 int outchan;
885 int inchan;
886 AV *avmain;
887 SV **temp;
888 SV *svsub;
889 AV *avsub;
890 int len;
891 int i, j;
892 CODE:
f5991c03
TC
893 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
894 croak("i_convert: parameter 3 must be an arrayref\n");
895 avmain = (AV*)SvRV(ST(2));
896 outchan = av_len(avmain)+1;
897 /* find the biggest */
898 inchan = 0;
899 for (j=0; j < outchan; ++j) {
900 temp = av_fetch(avmain, j, 0);
901 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
902 avsub = (AV*)SvRV(*temp);
903 len = av_len(avsub)+1;
904 if (len > inchan)
905 inchan = len;
906 }
907 }
908 coeff = mymalloc(sizeof(float) * outchan * inchan);
909 for (j = 0; j < outchan; ++j) {
910 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
911 len = av_len(avsub)+1;
912 for (i = 0; i < len; ++i) {
913 temp = av_fetch(avsub, i, 0);
914 if (temp)
915 coeff[i+j*inchan] = SvNV(*temp);
916 else
917 coeff[i+j*inchan] = 0;
918 }
919 while (i < inchan)
920 coeff[i++ + j*inchan] = 0;
921 }
922 RETVAL = i_convert(im, src, coeff, outchan, inchan);
923 myfree(coeff);
f5991c03
TC
924 OUTPUT:
925 RETVAL
40eba1ea
AMH
926
927
928void
929i_map(im, pmaps)
930 Imager::ImgRaw im
931 PREINIT:
932 unsigned int mask = 0;
933 AV *avmain;
934 AV *avsub;
935 SV **temp;
936 int len;
937 int i, j;
938 unsigned char (*maps)[256];
939 CODE:
940 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
941 croak("i_map: parameter 2 must be an arrayref\n");
942 avmain = (AV*)SvRV(ST(1));
943 len = av_len(avmain)+1;
944 if (im->channels < len) len = im->channels;
945
946 maps = mymalloc( len * sizeof(unsigned char [256]) );
947
948 for (j=0; j<len ; j++) {
949 temp = av_fetch(avmain, j, 0);
950 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
951 avsub = (AV*)SvRV(*temp);
952 if(av_len(avsub) != 255) continue;
953 mask |= 1<<j;
954 for (i=0; i<256 ; i++) {
9495ee93 955 int val;
40eba1ea 956 temp = av_fetch(avsub, i, 0);
9495ee93
AMH
957 val = temp ? SvIV(*temp) : 0;
958 if (val<0) val = 0;
959 if (val>255) val = 255;
960 maps[j][i] = val;
40eba1ea
AMH
961 }
962 }
963 }
964 i_map(im, maps, mask);
965 myfree(maps);
966
967
968
02d1d628
AMH
969float
970i_img_diff(im1,im2)
971 Imager::ImgRaw im1
972 Imager::ImgRaw im2
973
974
975
976undef_int
977i_init_fonts()
978
979#ifdef HAVE_LIBT1
980
981void
982i_t1_set_aa(st)
983 int st
984
985int
986i_t1_new(pfb,afm=NULL)
987 char* pfb
988 char* afm
989
990int
991i_t1_destroy(font_id)
992 int font_id
993
994
995undef_int
996i_t1_cp(im,xb,yb,channel,fontnum,points,str,len,align)
997 Imager::ImgRaw im
998 int xb
999 int yb
1000 int channel
1001 int fontnum
1002 float points
1003 char* str
1004 int len
1005 int align
1006
1007void
1008i_t1_bbox(fontnum,point,str,len)
1009 int fontnum
1010 float point
1011 char* str
1012 int len
1013 PREINIT:
1014 int cords[6];
1015 PPCODE:
1016 i_t1_bbox(fontnum,point,str,len,cords);
1017 EXTEND(SP, 4);
1018 PUSHs(sv_2mortal(newSViv(cords[0])));
1019 PUSHs(sv_2mortal(newSViv(cords[1])));
1020 PUSHs(sv_2mortal(newSViv(cords[2])));
1021 PUSHs(sv_2mortal(newSViv(cords[3])));
1022 PUSHs(sv_2mortal(newSViv(cords[4])));
1023 PUSHs(sv_2mortal(newSViv(cords[5])));
1024
1025
1026
1027undef_int
1028i_t1_text(im,xb,yb,cl,fontnum,points,str,len,align)
1029 Imager::ImgRaw im
1030 int xb
1031 int yb
1032 Imager::Color cl
1033 int fontnum
1034 float points
1035 char* str
1036 int len
1037 int align
1038
1039#endif
1040
1041#ifdef HAVE_LIBTT
1042
1043
1044Imager::TTHandle
1045i_tt_new(fontname)
1046 char* fontname
1047
1048void
1049i_tt_destroy(handle)
1050 Imager::TTHandle handle
1051
1052
1053
1054undef_int
1055i_tt_text(handle,im,xb,yb,cl,points,str,len,smooth)
1056 Imager::TTHandle handle
1057 Imager::ImgRaw im
1058 int xb
1059 int yb
1060 Imager::Color cl
1061 float points
1062 char* str
1063 int len
1064 int smooth
1065
1066
1067undef_int
1068i_tt_cp(handle,im,xb,yb,channel,points,str,len,smooth)
1069 Imager::TTHandle handle
1070 Imager::ImgRaw im
1071 int xb
1072 int yb
1073 int channel
1074 float points
1075 char* str
1076 int len
1077 int smooth
1078
1079
1080
1081undef_int
1082i_tt_bbox(handle,point,str,len)
1083 Imager::TTHandle handle
1084 float point
1085 char* str
1086 int len
1087 PREINIT:
1088 int cords[6],rc;
1089 PPCODE:
1090 if ((rc=i_tt_bbox(handle,point,str,len,cords))) {
1091 EXTEND(SP, 4);
1092 PUSHs(sv_2mortal(newSViv(cords[0])));
1093 PUSHs(sv_2mortal(newSViv(cords[1])));
1094 PUSHs(sv_2mortal(newSViv(cords[2])));
1095 PUSHs(sv_2mortal(newSViv(cords[3])));
1096 PUSHs(sv_2mortal(newSViv(cords[4])));
1097 PUSHs(sv_2mortal(newSViv(cords[5])));
1098 }
1099
1100
1101#endif
1102
1103
1104
1105
1106#ifdef HAVE_LIBJPEG
1107undef_int
dd55acc8 1108i_writejpeg_wiol(im, ig, qfactor)
02d1d628 1109 Imager::ImgRaw im
dd55acc8 1110 Imager::IO ig
02d1d628
AMH
1111 int qfactor
1112
02d1d628
AMH
1113
1114void
1115i_readjpeg_wiol(ig)
1116 Imager::IO ig
1117 PREINIT:
1118 char* iptc_itext;
1119 int tlength;
1120 i_img* rimg;
1121 SV* r;
1122 PPCODE:
1123 iptc_itext = NULL;
1124 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1125 if (iptc_itext == NULL) {
1126 r = sv_newmortal();
1127 EXTEND(SP,1);
1128 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1129 PUSHs(r);
1130 } else {
1131 r = sv_newmortal();
1132 EXTEND(SP,2);
1133 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1134 PUSHs(r);
1135 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1136 myfree(iptc_itext);
1137 }
1138
1139
1140#endif
1141
1142
1143
1144
1145#ifdef HAVE_LIBTIFF
1146
1147Imager::ImgRaw
1148i_readtiff_wiol(ig, length)
1149 Imager::IO ig
1150 int length
1151
1152
1153undef_int
1154i_writetiff_wiol(im, ig)
1155 Imager::ImgRaw im
1156 Imager::IO ig
1157
d2dfdcc9 1158undef_int
4c2d6970 1159i_writetiff_wiol_faxable(im, ig, fine)
d2dfdcc9
TC
1160 Imager::ImgRaw im
1161 Imager::IO ig
4c2d6970 1162 int fine
d2dfdcc9 1163
02d1d628
AMH
1164
1165#endif /* HAVE_LIBTIFF */
1166
1167
1168
1169
1170
1171#ifdef HAVE_LIBPNG
1172
1173Imager::ImgRaw
790923a4
AMH
1174i_readpng_wiol(ig, length)
1175 Imager::IO ig
1176 int length
02d1d628
AMH
1177
1178
1179undef_int
790923a4 1180i_writepng_wiol(im, ig)
02d1d628 1181 Imager::ImgRaw im
790923a4 1182 Imager::IO ig
02d1d628
AMH
1183
1184
1185#endif
1186
1187
1188#ifdef HAVE_LIBGIF
1189
03bd24d4
TC
1190void
1191i_giflib_version()
1192 PPCODE:
1193 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
1194
02d1d628
AMH
1195undef_int
1196i_writegif(im,fd,colors,pixdev,fixed)
1197 Imager::ImgRaw im
1198 int fd
1199 int colors
1200 int pixdev
1201 PREINIT:
1202 int fixedlen;
1203 Imager__Color fixed;
1204 Imager__Color tmp;
1205 AV* av;
1206 SV* sv1;
1207 IV Itmp;
1208 int i;
1209 CODE:
1210 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
1211 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1212 av=(AV*)SvRV(ST(4));
1213 fixedlen=av_len(av)+1;
1214 fixed=mymalloc( fixedlen*sizeof(i_color) );
1215 for(i=0;i<fixedlen;i++) {
1216 sv1=(*(av_fetch(av,i,0)));
1217 if (sv_derived_from(sv1, "Imager::Color")) {
1218 Itmp = SvIV((SV*)SvRV(sv1));
1219 tmp = (i_color*) Itmp;
1220 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
1221 fixed[i]=*tmp;
1222 }
1223 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
1224 myfree(fixed);
1225 ST(0) = sv_newmortal();
1226 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1227 else sv_setiv(ST(0), (IV)RETVAL);
1228
1229
1230
1231
1232undef_int
1233i_writegifmc(im,fd,colors)
067d6bdc 1234 Imager::ImgRaw im
02d1d628
AMH
1235 int fd
1236 int colors
1237
02d1d628
AMH
1238
1239undef_int
1240i_writegif_gen(fd, ...)
1241 int fd
1242 PROTOTYPE: $$@
1243 PREINIT:
1244 i_quantize quant;
1245 i_gif_opts opts;
1246 i_img **imgs = NULL;
1247 int img_count;
1248 int i;
1249 HV *hv;
1250 CODE:
1251 if (items < 3)
1252 croak("Usage: i_writegif_gen(fd,hashref, images...)");
1253 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1254 croak("i_writegif_gen: Second argument must be a hash ref");
1255 hv = (HV *)SvRV(ST(1));
1256 memset(&quant, 0, sizeof(quant));
1257 quant.mc_size = 256;
1258 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1259 memset(&opts, 0, sizeof(opts));
1260 handle_quant_opts(&quant, hv);
1261 handle_gif_opts(&opts, hv);
1262 img_count = items - 2;
1263 RETVAL = 1;
1264 if (img_count < 1) {
1265 RETVAL = 0;
95b44a76
TC
1266 i_clear_error();
1267 i_push_error(0, "You need to specify images to save");
02d1d628
AMH
1268 }
1269 else {
1270 imgs = mymalloc(sizeof(i_img *) * img_count);
1271 for (i = 0; i < img_count; ++i) {
1272 SV *sv = ST(2+i);
1273 imgs[i] = NULL;
1274 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1275 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1276 }
1277 else {
95b44a76
TC
1278 i_clear_error();
1279 i_push_error(0, "Only images can be saved");
02d1d628
AMH
1280 RETVAL = 0;
1281 break;
1282 }
1283 }
1284 if (RETVAL) {
1285 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count, &opts);
1286 }
1287 myfree(imgs);
1288 if (RETVAL) {
1289 copy_colors_back(hv, &quant);
1290 }
1291 }
1292 ST(0) = sv_newmortal();
1293 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1294 else sv_setiv(ST(0), (IV)RETVAL);
1295
1296undef_int
1297i_writegif_callback(cb, maxbuffer,...)
1298 int maxbuffer;
1299 PREINIT:
1300 i_quantize quant;
1301 i_gif_opts opts;
1302 i_img **imgs = NULL;
1303 int img_count;
1304 int i;
1305 HV *hv;
1306 i_writer_data wd;
1307 CODE:
1308 if (items < 4)
1309 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
1310 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1311 croak("i_writegif_callback: Second argument must be a hash ref");
1312 hv = (HV *)SvRV(ST(2));
1313 memset(&quant, 0, sizeof(quant));
1314 quant.mc_size = 256;
1315 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1316 memset(&opts, 0, sizeof(opts));
1317 handle_quant_opts(&quant, hv);
1318 handle_gif_opts(&opts, hv);
1319 img_count = items - 3;
1320 RETVAL = 1;
1321 if (img_count < 1) {
1322 RETVAL = 0;
1323 }
1324 else {
1325 imgs = mymalloc(sizeof(i_img *) * img_count);
1326 for (i = 0; i < img_count; ++i) {
1327 SV *sv = ST(3+i);
1328 imgs[i] = NULL;
1329 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1330 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1331 }
1332 else {
1333 RETVAL = 0;
1334 break;
1335 }
1336 }
1337 if (RETVAL) {
1338 wd.sv = ST(0);
1339 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count, &opts);
1340 }
1341 myfree(imgs);
1342 if (RETVAL) {
1343 copy_colors_back(hv, &quant);
1344 }
1345 }
1346 ST(0) = sv_newmortal();
1347 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1348 else sv_setiv(ST(0), (IV)RETVAL);
1349
1350void
1351i_readgif(fd)
1352 int fd
1353 PREINIT:
1354 int* colour_table;
1355 int colours, q, w;
1356 i_img* rimg;
1357 SV* temp[3];
1358 AV* ct;
1359 SV* r;
1360 PPCODE:
1361 colour_table = NULL;
1362 colours = 0;
1363
895dbd34 1364 if(GIMME_V == G_ARRAY) {
02d1d628
AMH
1365 rimg = i_readgif(fd,&colour_table,&colours);
1366 } else {
1367 /* don't waste time with colours if they aren't wanted */
1368 rimg = i_readgif(fd,NULL,NULL);
1369 }
895dbd34 1370
02d1d628
AMH
1371 if (colour_table == NULL) {
1372 EXTEND(SP,1);
1373 r=sv_newmortal();
1374 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1375 PUSHs(r);
1376 } else {
1377 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1378 /* I don't know if I have the reference counts right or not :( */
1379 /* Neither do I :-) */
1380 /* No Idea here either */
1381
1382 ct=newAV();
1383 av_extend(ct, colours);
1384 for(q=0; q<colours; q++) {
1385 for(w=0; w<3; w++)
1386 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1387 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1388 }
1389 myfree(colour_table);
895dbd34 1390
02d1d628 1391 EXTEND(SP,2);
895dbd34 1392 r = sv_newmortal();
02d1d628
AMH
1393 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1394 PUSHs(r);
1395 PUSHs(newRV_noinc((SV*)ct));
1396 }
1397
1398
1399
1400
1401
1402void
1403i_readgif_scalar(...)
1404 PROTOTYPE: $
1405 PREINIT:
1406 char* data;
1407 unsigned int length;
1408 int* colour_table;
1409 int colours, q, w;
1410 i_img* rimg;
1411 SV* temp[3];
1412 AV* ct;
1413 SV* r;
1414 PPCODE:
1415 data = (char *)SvPV(ST(0), length);
1416 colour_table=NULL;
1417 colours=0;
1418
1419 if(GIMME_V == G_ARRAY) {
1420 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
1421 } else {
1422 /* don't waste time with colours if they aren't wanted */
1423 rimg=i_readgif_scalar(data,length,NULL,NULL);
1424 }
1425
1426 if (colour_table == NULL) {
1427 EXTEND(SP,1);
1428 r=sv_newmortal();
1429 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1430 PUSHs(r);
1431 } else {
1432 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1433 /* I don't know if I have the reference counts right or not :( */
1434 /* Neither do I :-) */
1435 ct=newAV();
1436 av_extend(ct, colours);
1437 for(q=0; q<colours; q++) {
1438 for(w=0; w<3; w++)
1439 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1440 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1441 }
1442 myfree(colour_table);
1443
1444 EXTEND(SP,2);
1445 r=sv_newmortal();
1446 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1447 PUSHs(r);
1448 PUSHs(newRV_noinc((SV*)ct));
1449 }
1450
1451void
1452i_readgif_callback(...)
1453 PROTOTYPE: &
1454 PREINIT:
1455 char* data;
1456 int length;
1457 int* colour_table;
1458 int colours, q, w;
1459 i_img* rimg;
1460 SV* temp[3];
1461 AV* ct;
1462 SV* r;
1463 i_reader_data rd;
1464 PPCODE:
1465 rd.sv = ST(0);
1466 colour_table=NULL;
1467 colours=0;
1468
1469 if(GIMME_V == G_ARRAY) {
1470 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
1471 } else {
1472 /* don't waste time with colours if they aren't wanted */
1473 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
1474 }
1475
1476 if (colour_table == NULL) {
1477 EXTEND(SP,1);
1478 r=sv_newmortal();
1479 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1480 PUSHs(r);
1481 } else {
1482 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1483 /* I don't know if I have the reference counts right or not :( */
1484 /* Neither do I :-) */
1485 /* Neither do I - maybe I'll move this somewhere */
1486 ct=newAV();
1487 av_extend(ct, colours);
1488 for(q=0; q<colours; q++) {
1489 for(w=0; w<3; w++)
1490 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1491 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1492 }
1493 myfree(colour_table);
1494
1495 EXTEND(SP,2);
1496 r=sv_newmortal();
1497 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1498 PUSHs(r);
1499 PUSHs(newRV_noinc((SV*)ct));
1500 }
1501
faa9b3e7
TC
1502void
1503i_readgif_multi(fd)
1504 int fd
1505 PREINIT:
1506 i_img **imgs;
1507 int count;
1508 int i;
1509 PPCODE:
1510 imgs = i_readgif_multi(fd, &count);
1511 if (imgs) {
1512 EXTEND(SP, count);
1513 for (i = 0; i < count; ++i) {
1514 SV *sv = sv_newmortal();
1515 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1516 PUSHs(sv);
1517 }
1518 myfree(imgs);
1519 }
02d1d628 1520
faa9b3e7
TC
1521void
1522i_readgif_multi_scalar(data)
1523 PREINIT:
1524 i_img **imgs;
1525 int count;
1526 char *data;
1527 unsigned int length;
1528 int i;
1529 PPCODE:
1530 data = (char *)SvPV(ST(0), length);
1531 imgs = i_readgif_multi_scalar(data, length, &count);
1532 if (imgs) {
1533 EXTEND(SP, count);
1534 for (i = 0; i < count; ++i) {
1535 SV *sv = sv_newmortal();
1536 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1537 PUSHs(sv);
1538 }
1539 myfree(imgs);
1540 }
02d1d628 1541
faa9b3e7
TC
1542void
1543i_readgif_multi_callback(cb)
1544 PREINIT:
1545 i_reader_data rd;
1546 i_img **imgs;
1547 int count;
1548 int i;
1549 PPCODE:
1550 rd.sv = ST(0);
1551 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
1552 if (imgs) {
1553 EXTEND(SP, count);
1554 for (i = 0; i < count; ++i) {
1555 SV *sv = sv_newmortal();
1556 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1557 PUSHs(sv);
1558 }
1559 myfree(imgs);
1560 }
02d1d628
AMH
1561
1562#endif
1563
1564
1565
1566Imager::ImgRaw
1567i_readpnm_wiol(ig, length)
1568 Imager::IO ig
1569 int length
1570
1571
067d6bdc
AMH
1572undef_int
1573i_writeppm_wiol(im, ig)
1574 Imager::ImgRaw im
1575 Imager::IO ig
1576
1577
02d1d628 1578Imager::ImgRaw
895dbd34
AMH
1579i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
1580 Imager::IO ig
02d1d628
AMH
1581 int x
1582 int y
1583 int datachannels
1584 int storechannels
1585 int intrl
1586
1587undef_int
895dbd34 1588i_writeraw_wiol(im,ig)
02d1d628 1589 Imager::ImgRaw im
895dbd34
AMH
1590 Imager::IO ig
1591
02d1d628
AMH
1592
1593
1594Imager::ImgRaw
1595i_scaleaxis(im,Value,Axis)
1596 Imager::ImgRaw im
1597 float Value
1598 int Axis
1599
1600Imager::ImgRaw
1601i_scale_nn(im,scx,scy)
1602 Imager::ImgRaw im
1603 float scx
1604 float scy
1605
1606Imager::ImgRaw
1607i_haar(im)
1608 Imager::ImgRaw im
1609
1610int
1611i_count_colors(im,maxc)
1612 Imager::ImgRaw im
1613 int maxc
1614
1615
1616Imager::ImgRaw
1617i_transform(im,opx,opy,parm)
1618 Imager::ImgRaw im
1619 PREINIT:
1620 double* parm;
1621 int* opx;
1622 int* opy;
1623 int opxl;
1624 int opyl;
1625 int parmlen;
1626 AV* av;
1627 SV* sv1;
1628 int i;
1629 CODE:
1630 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1631 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1632 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1633 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1634 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1635 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1636 av=(AV*)SvRV(ST(1));
1637 opxl=av_len(av)+1;
1638 opx=mymalloc( opxl*sizeof(int) );
1639 for(i=0;i<opxl;i++) {
1640 sv1=(*(av_fetch(av,i,0)));
1641 opx[i]=(int)SvIV(sv1);
1642 }
1643 av=(AV*)SvRV(ST(2));
1644 opyl=av_len(av)+1;
1645 opy=mymalloc( opyl*sizeof(int) );
1646 for(i=0;i<opyl;i++) {
1647 sv1=(*(av_fetch(av,i,0)));
1648 opy[i]=(int)SvIV(sv1);
1649 }
1650 av=(AV*)SvRV(ST(3));
1651 parmlen=av_len(av)+1;
1652 parm=mymalloc( parmlen*sizeof(double) );
1653 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1654 sv1=(*(av_fetch(av,i,0)));
1655 parm[i]=(double)SvNV(sv1);
1656 }
1657 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1658 myfree(parm);
1659 myfree(opy);
1660 myfree(opx);
1661 ST(0) = sv_newmortal();
1662 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1663 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1664
1665Imager::ImgRaw
1666i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
1667 PREINIT:
1668 int width;
1669 int height;
1670 double* parm;
1671 struct rm_op *ops;
1672 unsigned int ops_len;
1673 int ops_count;
1674 double *n_regs;
1675 int n_regs_count;
1676 i_color *c_regs;
1677 int c_regs_count;
1678 int in_imgs_count;
1679 i_img **in_imgs;
1680 AV* av;
1681 SV* sv1;
1682 IV tmp;
1683 int i;
1684 CODE:
1685 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
1686 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
1687 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
1688 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1689 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
1690
1691 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
1692
1693 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1694 av = (AV*)SvRV(ST(5));
1695 in_imgs_count = av_len(av)+1;
1696 for (i = 0; i < in_imgs_count; ++i) {
1697 sv1 = *av_fetch(av, i, 0);
1698 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1699 croak("Parameter 5 must contain only images");
1700 }
1701 }
1702 }
1703 else {
1704 in_imgs_count = 0;
1705 }
1706 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1707 av = (AV*)SvRV(ST(5));
1708 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
1709 for (i = 0; i < in_imgs_count; ++i) {
1710 sv1 = *av_fetch(av,i,0);
1711 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1712 croak("Parameter 5 must contain only images");
1713 }
1714 tmp = SvIV((SV*)SvRV(sv1));
1715 in_imgs[i] = (i_img*)tmp;
1716 }
1717 }
1718 else {
1719 /* no input images */
1720 in_imgs = NULL;
1721 }
1722 /* default the output size from the first input if possible */
1723 if (SvOK(ST(0)))
1724 width = SvIV(ST(0));
1725 else if (in_imgs_count)
1726 width = in_imgs[0]->xsize;
1727 else
1728 croak("No output image width supplied");
1729
1730 if (SvOK(ST(1)))
1731 height = SvIV(ST(1));
1732 else if (in_imgs_count)
1733 height = in_imgs[0]->ysize;
1734 else
1735 croak("No output image height supplied");
1736
1737 ops = (struct rm_op *)SvPV(ST(2), ops_len);
1738 if (ops_len % sizeof(struct rm_op))
1739 croak("Imager: Parameter 3 must be a bitmap of regops\n");
1740 ops_count = ops_len / sizeof(struct rm_op);
1741 av = (AV*)SvRV(ST(3));
1742 n_regs_count = av_len(av)+1;
1743 n_regs = mymalloc(n_regs_count * sizeof(double));
1744 for (i = 0; i < n_regs_count; ++i) {
1745 sv1 = *av_fetch(av,i,0);
1746 if (SvOK(sv1))
1747 n_regs[i] = SvNV(sv1);
1748 }
1749 av = (AV*)SvRV(ST(4));
1750 c_regs_count = av_len(av)+1;
1751 c_regs = mymalloc(c_regs_count * sizeof(i_color));
1752 /* I don't bother initializing the colou?r registers */
1753
1754 RETVAL=i_transform2(width, height, 3, ops, ops_count,
1755 n_regs, n_regs_count,
1756 c_regs, c_regs_count, in_imgs, in_imgs_count);
1757 if (in_imgs)
1758 myfree(in_imgs);
1759 myfree(n_regs);
1760 myfree(c_regs);
1761 ST(0) = sv_newmortal();
1762 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1763 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1764
1765
1766void
1767i_contrast(im,intensity)
1768 Imager::ImgRaw im
1769 float intensity
1770
1771void
1772i_hardinvert(im)
1773 Imager::ImgRaw im
1774
1775void
1776i_noise(im,amount,type)
1777 Imager::ImgRaw im
1778 float amount
1779 unsigned char type
1780
1781void
1782i_bumpmap(im,bump,channel,light_x,light_y,strength)
1783 Imager::ImgRaw im
1784 Imager::ImgRaw bump
1785 int channel
1786 int light_x
1787 int light_y
1788 int strength
1789
1790void
1791i_postlevels(im,levels)
1792 Imager::ImgRaw im
1793 int levels
1794
1795void
1796i_mosaic(im,size)
1797 Imager::ImgRaw im
1798 int size
1799
1800void
1801i_watermark(im,wmark,tx,ty,pixdiff)
1802 Imager::ImgRaw im
1803 Imager::ImgRaw wmark
1804 int tx
1805 int ty
1806 int pixdiff
1807
1808
1809void
1810i_autolevels(im,lsat,usat,skew)
1811 Imager::ImgRaw im
1812 float lsat
1813 float usat
1814 float skew
1815
1816void
1817i_radnoise(im,xo,yo,rscale,ascale)
1818 Imager::ImgRaw im
1819 float xo
1820 float yo
1821 float rscale
1822 float ascale
1823
1824void
1825i_turbnoise(im, xo, yo, scale)
1826 Imager::ImgRaw im
1827 float xo
1828 float yo
1829 float scale
1830
1831
1832void
1833i_gradgen(im, ...)
1834 Imager::ImgRaw im
1835 PREINIT:
1836 int num;
1837 int *xo;
1838 int *yo;
1839 i_color *ival;
1840 int dmeasure;
1841 int i;
1842 SV *sv;
1843 AV *axx;
1844 AV *ayy;
1845 AV *ac;
1846 CODE:
1847 if (items != 5)
1848 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
1849 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1850 croak("i_gradgen: Second argument must be an array ref");
1851 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1852 croak("i_gradgen: Third argument must be an array ref");
1853 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1854 croak("i_gradgen: Fourth argument must be an array ref");
1855 axx = (AV *)SvRV(ST(1));
1856 ayy = (AV *)SvRV(ST(2));
1857 ac = (AV *)SvRV(ST(3));
1858 dmeasure = (int)SvIV(ST(4));
1859
1860 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1861 num = num <= av_len(ac) ? num : av_len(ac);
1862 num++;
1863 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
1864 xo = mymalloc( sizeof(int) * num );
1865 yo = mymalloc( sizeof(int) * num );
1866 ival = mymalloc( sizeof(i_color) * num );
1867 for(i = 0; i<num; i++) {
1868 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1869 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1870 sv = *av_fetch(ac, i, 0);
1871 if ( !sv_derived_from(sv, "Imager::Color") ) {
1872 free(axx); free(ayy); free(ac);
1873 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
1874 }
1875 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1876 }
1877 i_gradgen(im, num, xo, yo, ival, dmeasure);
1878
1879
1880
1881
1882
4f4f776a
TC
1883void
1884i_errors()
1885 PREINIT:
1886 i_errmsg *errors;
1887 int i;
4f4f776a
TC
1888 AV *av;
1889 SV *ref;
1890 SV *sv;
1891 PPCODE:
1892 errors = i_errors();
1893 i = 0;
1894 while (errors[i].msg) {
1895 av = newAV();
1896 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
1897 if (!av_store(av, 0, sv)) {
1898 SvREFCNT_dec(sv);
1899 }
1900 sv = newSViv(errors[i].code);
1901 if (!av_store(av, 1, sv)) {
1902 SvREFCNT_dec(sv);
1903 }
1904 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
1905 ++i;
1906 }
02d1d628
AMH
1907
1908void
1909i_nearest_color(im, ...)
1910 Imager::ImgRaw im
1911 PREINIT:
1912 int num;
1913 int *xo;
1914 int *yo;
1915 i_color *ival;
1916 int dmeasure;
1917 int i;
1918 SV *sv;
1919 AV *axx;
1920 AV *ayy;
1921 AV *ac;
1922 CODE:
1923 if (items != 5)
1924 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
1925 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1926 croak("i_nearest_color: Second argument must be an array ref");
1927 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1928 croak("i_nearest_color: Third argument must be an array ref");
1929 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1930 croak("i_nearest_color: Fourth argument must be an array ref");
1931 axx = (AV *)SvRV(ST(1));
1932 ayy = (AV *)SvRV(ST(2));
1933 ac = (AV *)SvRV(ST(3));
1934 dmeasure = (int)SvIV(ST(4));
1935
1936 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1937 num = num <= av_len(ac) ? num : av_len(ac);
1938 num++;
1939 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
1940 xo = mymalloc( sizeof(int) * num );
1941 yo = mymalloc( sizeof(int) * num );
1942 ival = mymalloc( sizeof(i_color) * num );
1943 for(i = 0; i<num; i++) {
1944 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1945 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1946 sv = *av_fetch(ac, i, 0);
1947 if ( !sv_derived_from(sv, "Imager::Color") ) {
1948 free(axx); free(ayy); free(ac);
1949 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
1950 }
1951 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1952 }
1953 i_nearest_color(im, num, xo, yo, ival, dmeasure);
1954
1955
1956
1957
1958void
1959malloc_state()
1960
1961void
1962hashinfo(hv)
1963 PREINIT:
1964 HV* hv;
1965 int stuff;
1966 PPCODE:
1967 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
1968 hv=(HV*)SvRV(ST(0));
1969 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
1970 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1971 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1972
1973void
1974DSO_open(filename)
1975 char* filename
1976 PREINIT:
1977 void *rc;
1978 char *evstr;
1979 PPCODE:
1980 rc=DSO_open(filename,&evstr);
1981 if (rc!=NULL) {
1982 if (evstr!=NULL) {
1983 EXTEND(SP,2);
1984 PUSHs(sv_2mortal(newSViv((IV)rc)));
1985 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
1986 } else {
1987 EXTEND(SP,1);
1988 PUSHs(sv_2mortal(newSViv((IV)rc)));
1989 }
1990 }
1991
1992
1993undef_int
1994DSO_close(dso_handle)
1995 void* dso_handle
1996
1997void
1998DSO_funclist(dso_handle_v)
1999 void* dso_handle_v
2000 PREINIT:
2001 int i;
2002 DSO_handle *dso_handle;
2003 PPCODE:
2004 dso_handle=(DSO_handle*)dso_handle_v;
2005 i=0;
2006 while( dso_handle->function_list[i].name != NULL) {
2007 EXTEND(SP,1);
2008 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
2009 EXTEND(SP,1);
2010 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
2011 }
2012
2013
2014void
2015DSO_call(handle,func_index,hv)
2016 void* handle
2017 int func_index
2018 PREINIT:
2019 HV* hv;
2020 PPCODE:
2021 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2022 hv=(HV*)SvRV(ST(2));
2023 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2024 DSO_call( (DSO_handle *)handle,func_index,hv);
2025
2026
2027
f5991c03 2028# this is mostly for testing...
faa9b3e7 2029SV *
f5991c03
TC
2030i_get_pixel(im, x, y)
2031 Imager::ImgRaw im
2032 int x
2033 int y;
faa9b3e7
TC
2034 PREINIT:
2035 i_color *color;
2036 CODE:
2037 color = (i_color *)mymalloc(sizeof(i_color));
2038 if (i_gpix(im, x, y, color) == 0) {
2039 ST(0) = sv_newmortal();
2040 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
2041 }
2042 else {
2043 myfree(color);
2044 ST(0) = &PL_sv_undef;
2045 }
2046
2047
2048int
2049i_ppix(im, x, y, cl)
2050 Imager::ImgRaw im
2051 int x
2052 int y
2053 Imager::Color cl
2054
2055Imager::ImgRaw
2056i_img_pal_new(x, y, channels, maxpal)
2057 int x
2058 int y
2059 int channels
2060 int maxpal
2061
2062Imager::ImgRaw
2063i_img_to_pal(src, quant)
2064 Imager::ImgRaw src
2065 PREINIT:
2066 HV *hv;
2067 i_quantize quant;
2068 CODE:
2069 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2070 croak("i_img_to_pal: second argument must be a hash ref");
2071 hv = (HV *)SvRV(ST(1));
2072 memset(&quant, 0, sizeof(quant));
2073 quant.mc_size = 256;
2074 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
2075 handle_quant_opts(&quant, hv);
2076 RETVAL = i_img_to_pal(src, &quant);
2077 if (RETVAL) {
2078 copy_colors_back(hv, &quant);
2079 }
2080 myfree(quant.mc_colors);
2081 OUTPUT:
2082 RETVAL
2083
2084Imager::ImgRaw
2085i_img_to_rgb(src)
2086 Imager::ImgRaw src
2087
2088void
2089i_gpal(im, l, r, y)
2090 Imager::ImgRaw im
2091 int l
2092 int r
2093 int y
2094 PREINIT:
2095 i_palidx *work;
2096 int count, i;
2097 PPCODE:
2098 if (l < r) {
2099 work = mymalloc((r-l) * sizeof(i_palidx));
2100 count = i_gpal(im, l, r, y, work);
2101 if (GIMME_V == G_ARRAY) {
2102 EXTEND(SP, count);
2103 for (i = 0; i < count; ++i) {
2104 PUSHs(sv_2mortal(newSViv(work[i])));
2105 }
2106 }
2107 else {
2108 EXTEND(SP, 1);
2109 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
2110 }
2111 myfree(work);
2112 }
2113 else {
2114 if (GIMME_V != G_ARRAY) {
2115 EXTEND(SP, 1);
2116 PUSHs(&PL_sv_undef);
2117 }
2118 }
2119
2120int
2121i_ppal(im, l, y, ...)
2122 Imager::ImgRaw im
2123 int l
2124 int y
2125 PREINIT:
2126 i_palidx *work;
2127 int count, i;
2128 CODE:
2129 if (items > 3) {
2130 work = mymalloc(sizeof(i_palidx) * (items-3));
2131 for (i=0; i < items-3; ++i) {
2132 work[i] = SvIV(ST(i+3));
2133 }
2134 RETVAL = i_ppal(im, l, l+items-3, y, work);
2135 myfree(work);
2136 }
2137 else {
2138 RETVAL = 0;
2139 }
2140 OUTPUT:
2141 RETVAL
2142
2143SV *
2144i_addcolors(im, ...)
2145 Imager::ImgRaw im
2146 PREINIT:
2147 int index;
2148 i_color *colors;
2149 int i;
2150 CODE:
2151 if (items < 2)
2152 croak("i_addcolors: no colors to add");
2153 colors = mymalloc((items-1) * sizeof(i_color));
2154 for (i=0; i < items-1; ++i) {
2155 if (sv_isobject(ST(i+1))
2156 && sv_derived_from(ST(i+1), "Imager::Color")) {
2157 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2158 colors[i] = *(i_color *)tmp;
2159 }
2160 else {
2161 myfree(colors);
2162 croak("i_plin: pixels must be Imager::Color objects");
2163 }
2164 }
2165 index = i_addcolors(im, colors, items-1);
2166 myfree(colors);
2167 if (index == 0) {
2168 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2169 }
2170 else if (index == -1) {
2171 ST(0) = &PL_sv_undef;
2172 }
2173 else {
2174 ST(0) = sv_2mortal(newSViv(index));
2175 }
2176
2177int
2178i_setcolors(im, index, ...)
2179 Imager::ImgRaw im
2180 int index
2181 PREINIT:
2182 i_color *colors;
2183 int i;
2184 CODE:
2185 if (items < 3)
2186 croak("i_setcolors: no colors to add");
2187 colors = mymalloc((items-2) * sizeof(i_color));
2188 for (i=0; i < items-2; ++i) {
2189 if (sv_isobject(ST(i+2))
2190 && sv_derived_from(ST(i+2), "Imager::Color")) {
2191 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
2192 colors[i] = *(i_color *)tmp;
2193 }
2194 else {
2195 myfree(colors);
2196 croak("i_setcolors: pixels must be Imager::Color objects");
2197 }
2198 }
2199 RETVAL = i_setcolors(im, index, colors, items-2);
2200 myfree(colors);
2201
2202void
2203i_getcolors(im, index, ...)
2204 Imager::ImgRaw im
2205 int index
2206 PREINIT:
2207 i_color *colors;
2208 int count = 1;
2209 int i;
2210 PPCODE:
2211 if (items > 3)
2212 croak("i_getcolors: too many arguments");
2213 if (items == 3)
2214 count = SvIV(ST(2));
2215 if (count < 1)
2216 croak("i_getcolors: count must be positive");
2217 colors = mymalloc(sizeof(i_color) * count);
2218 if (i_getcolors(im, index, colors, count)) {
2219 for (i = 0; i < count; ++i) {
2220 i_color *pv;
2221 SV *sv = sv_newmortal();
2222 pv = mymalloc(sizeof(i_color));
2223 *pv = colors[i];
2224 sv_setref_pv(sv, "Imager::Color", (void *)pv);
2225 PUSHs(sv);
2226 }
2227 }
2228 myfree(colors);
2229
2230
2231SV *
2232i_colorcount(im)
2233 Imager::ImgRaw im
2234 PREINIT:
2235 int count;
2236 CODE:
2237 count = i_colorcount(im);
2238 if (count >= 0) {
2239 ST(0) = sv_2mortal(newSViv(count));
2240 }
2241 else {
2242 ST(0) = &PL_sv_undef;
2243 }
2244
2245SV *
2246i_maxcolors(im)
2247 Imager::ImgRaw im
2248 PREINIT:
2249 int count;
2250 CODE:
2251 count = i_maxcolors(im);
2252 if (count >= 0) {
2253 ST(0) = sv_2mortal(newSViv(count));
2254 }
2255 else {
2256 ST(0) = &PL_sv_undef;
2257 }
2258
2259SV *
2260i_findcolor(im, color)
2261 Imager::ImgRaw im
2262 Imager::Color color
2263 PREINIT:
2264 i_palidx index;
2265 CODE:
2266 if (i_findcolor(im, color, &index)) {
2267 ST(0) = sv_2mortal(newSViv(index));
2268 }
2269 else {
2270 ST(0) = &PL_sv_undef;
2271 }
2272
2273int
2274i_img_bits(im)
2275 Imager::ImgRaw im
2276
2277int
2278i_img_type(im)
2279 Imager::ImgRaw im
2280
2281int
2282i_img_virtual(im)
2283 Imager::ImgRaw im
2284
2285void
2286i_gsamp(im, l, r, y, ...)
2287 Imager::ImgRaw im
2288 int l
2289 int r
2290 int y
2291 PREINIT:
2292 int *chans;
2293 int chan_count;
2294 i_sample_t *data;
2295 int count, i;
2296 PPCODE:
2297 if (items < 5)
2298 croak("No channel numbers supplied to g_samp()");
2299 if (l < r) {
2300 chan_count = items - 4;
2301 chans = mymalloc(sizeof(int) * chan_count);
2302 for (i = 0; i < chan_count; ++i)
2303 chans[i] = SvIV(ST(i+4));
2304 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count);
2305 count = i_gsamp(im, l, r, y, data, chans, chan_count);
2306 if (GIMME_V == G_ARRAY) {
2307 EXTEND(SP, count);
2308 for (i = 0; i < count; ++i)
2309 PUSHs(sv_2mortal(newSViv(data[i])));
2310 }
2311 else {
2312 EXTEND(SP, 1);
2313 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
2314 }
2315 }
2316 else {
2317 if (GIMME_V != G_ARRAY) {
2318 EXTEND(SP, 1);
2319 PUSHs(&PL_sv_undef);
2320 }
2321 }
2322
2323Imager::ImgRaw
2324i_img_masked_new(targ, mask, x, y, w, h)
2325 Imager::ImgRaw targ
2326 int x
2327 int y
2328 int w
2329 int h
2330 PREINIT:
2331 i_img *mask;
2332 CODE:
2333 if (SvOK(ST(1))) {
2334 if (!sv_isobject(ST(1))
2335 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
2336 croak("i_img_masked_new: parameter 2 must undef or an image");
2337 }
2338 mask = (i_img *)SvIV((SV *)SvRV(ST(1)));
2339 }
2340 else
2341 mask = NULL;
2342 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
2343 OUTPUT:
2344 RETVAL
2345
2346int
2347i_plin(im, l, y, ...)
2348 Imager::ImgRaw im
2349 int l
2350 int y
2351 PREINIT:
2352 i_color *work;
2353 int count, i;
2354 CODE:
2355 if (items > 3) {
2356 work = mymalloc(sizeof(i_color) * (items-3));
2357 for (i=0; i < items-3; ++i) {
2358 if (sv_isobject(ST(i+3))
2359 && sv_derived_from(ST(i+3), "Imager::Color")) {
2360 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2361 work[i] = *(i_color *)tmp;
2362 }
2363 else {
2364 myfree(work);
2365 croak("i_plin: pixels must be Imager::Color objects");
2366 }
2367 }
2368 /**(char *)0 = 1;*/
2369 RETVAL = i_plin(im, l, l+items-3, y, work);
2370 myfree(work);
2371 }
2372 else {
2373 RETVAL = 0;
2374 }
2375 OUTPUT:
2376 RETVAL
2377
2378int
2379i_ppixf(im, x, y, cl)
2380 Imager::ImgRaw im
2381 int x
2382 int y
2383 Imager::Color::Float cl
2384
2385void
2386i_gsampf(im, l, r, y, ...)
2387 Imager::ImgRaw im
2388 int l
2389 int r
2390 int y
2391 PREINIT:
2392 int *chans;
2393 int chan_count;
2394 i_fsample_t *data;
2395 int count, i;
2396 PPCODE:
2397 if (items < 5)
2398 croak("No channel numbers supplied to g_sampf()");
2399 if (l < r) {
2400 chan_count = items - 4;
2401 chans = mymalloc(sizeof(int) * chan_count);
2402 for (i = 0; i < chan_count; ++i)
2403 chans[i] = SvIV(ST(i+4));
2404 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
2405 count = i_gsampf(im, l, r, y, data, chans, chan_count);
2406 if (GIMME_V == G_ARRAY) {
2407 EXTEND(SP, count);
2408 for (i = 0; i < count; ++i)
2409 PUSHs(sv_2mortal(newSVnv(data[i])));
2410 }
2411 else {
2412 EXTEND(SP, 1);
2413 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
2414 }
2415 }
2416 else {
2417 if (GIMME_V != G_ARRAY) {
2418 EXTEND(SP, 1);
2419 PUSHs(&PL_sv_undef);
2420 }
2421 }
2422
2423int
2424i_plinf(im, l, y, ...)
2425 Imager::ImgRaw im
2426 int l
2427 int y
2428 PREINIT:
2429 i_fcolor *work;
2430 int count, i;
2431 CODE:
2432 if (items > 3) {
2433 work = mymalloc(sizeof(i_fcolor) * (items-3));
2434 for (i=0; i < items-3; ++i) {
2435 if (sv_isobject(ST(i+3))
2436 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
2437 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2438 work[i] = *(i_fcolor *)tmp;
2439 }
2440 else {
2441 myfree(work);
2442 croak("i_plin: pixels must be Imager::Color::Float objects");
2443 }
2444 }
2445 /**(char *)0 = 1;*/
2446 RETVAL = i_plinf(im, l, l+items-3, y, work);
2447 myfree(work);
2448 }
2449 else {
2450 RETVAL = 0;
2451 }
2452 OUTPUT:
2453 RETVAL
2454
2455SV *
2456i_gpixf(im, x, y)
2457 Imager::ImgRaw im
2458 int x
2459 int y;
2460 PREINIT:
2461 i_fcolor *color;
2462 CODE:
2463 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
2464 if (i_gpixf(im, x, y, color) == 0) {
2465 ST(0) = sv_newmortal();
2466 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
2467 }
2468 else {
2469 myfree(color);
2470 ST(0) = &PL_sv_undef;
2471 }
2472
2473void
2474i_glin(im, l, r, y)
2475 Imager::ImgRaw im
2476 int l
2477 int r
2478 int y
2479 PREINIT:
2480 i_color *vals;
2481 int count, i;
2482 PPCODE:
2483 if (l < r) {
2484 vals = mymalloc((r-l) * sizeof(i_color));
2485 count = i_glin(im, l, r, y, vals);
2486 EXTEND(SP, count);
2487 for (i = 0; i < count; ++i) {
2488 SV *sv;
2489 i_color *col = mymalloc(sizeof(i_color));
2490 sv = sv_newmortal();
2491 sv_setref_pv(sv, "Imager::Color", (void *)col);
2492 PUSHs(sv);
2493 }
2494 myfree(vals);
2495 }
2496
2497void
2498i_glinf(im, l, r, y)
2499 Imager::ImgRaw im
2500 int l
2501 int r
2502 int y
2503 PREINIT:
2504 i_fcolor *vals;
2505 int count, i;
2506 PPCODE:
2507 if (l < r) {
2508 vals = mymalloc((r-l) * sizeof(i_fcolor));
2509 count = i_glinf(im, l, r, y, vals);
2510 EXTEND(SP, count);
2511 for (i = 0; i < count; ++i) {
2512 SV *sv;
2513 i_fcolor *col = mymalloc(sizeof(i_fcolor));
2514 *col = vals[i];
2515 sv = sv_newmortal();
2516 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
2517 PUSHs(sv);
2518 }
2519 myfree(vals);
2520 }
2521
2522Imager::ImgRaw
2523i_img_16_new(x, y, ch)
2524 int x
2525 int y
2526 int ch
2527
2528undef_int
2529i_tags_addn(im, name, code, idata)
2530 Imager::ImgRaw im
2531 int code
2532 int idata
2533 PREINIT:
2534 char *name;
2535 STRLEN len;
2536 CODE:
2537 if (SvOK(ST(1)))
2538 name = SvPV(ST(1), len);
2539 else
2540 name = NULL;
2541 RETVAL = i_tags_addn(&im->tags, name, code, idata);
2542 OUTPUT:
2543 RETVAL
2544
2545undef_int
2546i_tags_add(im, name, code, data, idata)
2547 Imager::ImgRaw im
2548 int code
2549 int idata
2550 PREINIT:
2551 char *name;
2552 char *data;
2553 STRLEN len;
2554 CODE:
2555 if (SvOK(ST(1)))
2556 name = SvPV(ST(1), len);
2557 else
2558 name = NULL;
2559 if (SvOK(ST(3)))
2560 data = SvPV(ST(3), len);
2561 else {
2562 data = NULL;
2563 len = 0;
2564 }
2565 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
2566 OUTPUT:
2567 RETVAL
2568
2569SV *
2570i_tags_find(im, name, start)
2571 Imager::ImgRaw im
2572 char *name
2573 int start
2574 PREINIT:
2575 int entry;
2576 CODE:
2577 if (i_tags_find(&im->tags, name, start, &entry)) {
2578 if (entry == 0)
2579 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2580 else
2581 ST(0) = sv_2mortal(newSViv(entry));
2582 } else {
2583 ST(0) = &PL_sv_undef;
2584 }
2585
2586SV *
2587i_tags_findn(im, code, start)
2588 Imager::ImgRaw im
2589 int code
2590 int start
2591 PREINIT:
2592 int entry;
2593 CODE:
2594 if (i_tags_findn(&im->tags, code, start, &entry)) {
2595 if (entry == 0)
2596 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2597 else
2598 ST(0) = sv_2mortal(newSViv(entry));
2599 }
2600 else
2601 ST(0) = &PL_sv_undef;
2602
2603int
2604i_tags_delete(im, entry)
2605 Imager::ImgRaw im
2606 int entry
2607 CODE:
2608 RETVAL = i_tags_delete(&im->tags, entry);
2609 OUTPUT:
2610 RETVAL
2611
2612int
2613i_tags_delbyname(im, name)
2614 Imager::ImgRaw im
2615 char * name
2616 CODE:
2617 RETVAL = i_tags_delbyname(&im->tags, name);
2618 OUTPUT:
2619 RETVAL
2620
2621int
2622i_tags_delbycode(im, code)
2623 Imager::ImgRaw im
2624 int code
2625 CODE:
2626 RETVAL = i_tags_delbycode(&im->tags, code);
2627 OUTPUT:
2628 RETVAL
2629
2630void
2631i_tags_get(im, index)
2632 Imager::ImgRaw im
2633 int index
2634 PPCODE:
2635 if (index >= 0 && index < im->tags.count) {
2636 i_img_tag *entry = im->tags.tags + index;
2637 EXTEND(SP, 5);
2638
2639 if (entry->name) {
2640 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
2641 }
2642 else {
2643 PUSHs(sv_2mortal(newSViv(entry->code)));
2644 }
2645 if (entry->data) {
2646 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
2647 }
2648 else {
2649 PUSHs(sv_2mortal(newSViv(entry->idata)));
2650 }
2651 }
2652
2653int
2654i_tags_count(im)
2655 Imager::ImgRaw im
2656 CODE:
2657 RETVAL = im->tags.count;
2658 OUTPUT:
2659 RETVAL
2660
2661#ifdef HAVE_WIN32
2662
2663void
2664i_wf_bbox(face, size, text)
2665 char *face
2666 int size
2667 char *text
2668 PREINIT:
2669 int cords[6];
2670 PPCODE:
2671 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
2672 EXTEND(SP, 6);
2673 PUSHs(sv_2mortal(newSViv(cords[0])));
2674 PUSHs(sv_2mortal(newSViv(cords[1])));
2675 PUSHs(sv_2mortal(newSViv(cords[2])));
2676 PUSHs(sv_2mortal(newSViv(cords[3])));
2677 PUSHs(sv_2mortal(newSViv(cords[4])));
2678 PUSHs(sv_2mortal(newSViv(cords[5])));
2679 }
2680
2681undef_int
2682i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
2683 char *face
2684 Imager::ImgRaw im
2685 int tx
2686 int ty
2687 Imager::Color cl
2688 int size
2689 char *text
2690 int align
2691 int aa
2692 CODE:
2693 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
2694 align, aa);
2695 OUTPUT:
2696 RETVAL
2697
2698undef_int
2699i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
2700 char *face
2701 Imager::ImgRaw im
2702 int tx
2703 int ty
2704 int channel
2705 int size
2706 char *text
2707 int align
2708 int aa
f5991c03 2709 CODE:
faa9b3e7
TC
2710 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
2711 align, aa);
f5991c03
TC
2712 OUTPUT:
2713 RETVAL
02d1d628 2714
faa9b3e7
TC
2715
2716#endif
2717
2718#ifdef HAVE_FT2
2719
2720MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
2721
2722#define FT2_DESTROY(font) i_ft2_destroy(font)
2723
2724void
2725FT2_DESTROY(font)
2726 Imager::Font::FT2 font
2727
2728MODULE = Imager PACKAGE = Imager::Font::FreeType2
2729
2730Imager::Font::FT2
2731i_ft2_new(name, index)
2732 char *name
2733 int index
2734
2735undef_int
2736i_ft2_setdpi(font, xdpi, ydpi)
2737 Imager::Font::FT2 font
2738 int xdpi
2739 int ydpi
2740
2741void
2742i_ft2_getdpi(font)
2743 Imager::Font::FT2 font
2744 PREINIT:
2745 int xdpi, ydpi;
2746 CODE:
2747 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
2748 EXTEND(SP, 2);
2749 PUSHs(sv_2mortal(newSViv(xdpi)));
2750 PUSHs(sv_2mortal(newSViv(ydpi)));
2751 }
2752
2753undef_int
2754i_ft2_sethinting(font, hinting)
2755 Imager::Font::FT2 font
2756 int hinting
2757
2758undef_int
2759i_ft2_settransform(font, matrix)
2760 Imager::Font::FT2 font
2761 PREINIT:
2762 double matrix[6];
2763 int len;
2764 AV *av;
2765 SV *sv1;
2766 int i;
2767 CODE:
2768 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2769 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
2770 av=(AV*)SvRV(ST(1));
2771 len=av_len(av)+1;
2772 if (len > 6)
2773 len = 6;
2774 for (i = 0; i < len; ++i) {
2775 sv1=(*(av_fetch(av,i,0)));
2776 matrix[i] = SvNV(sv1);
2777 }
2778 for (; i < 6; ++i)
2779 matrix[i] = 0;
2780 RETVAL = i_ft2_settransform(font, matrix);
2781 OUTPUT:
2782 RETVAL
2783
2784void
2785i_ft2_bbox(font, cheight, cwidth, text)
2786 Imager::Font::FT2 font
2787 double cheight
2788 double cwidth
2789 char *text
2790 PREINIT:
2791 int bbox[6];
2792 int i;
2793 PPCODE:
2794 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox)) {
2795 EXTEND(SP, 6);
2796 for (i = 0; i < 6; ++i)
2797 PUSHs(sv_2mortal(newSViv(bbox[i])));
2798 }
2799
2800void
2801i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
2802 Imager::Font::FT2 font
2803 double cheight
2804 double cwidth
2805 char *text
2806 int vlayout
2807 int utf8
2808 PREINIT:
2809 int bbox[8];
2810 int i;
2811 PPCODE:
2812#ifdef SvUTF8
2813 if (SvUTF8(ST(3)))
2814 utf8 = 1;
2815#endif
2816 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
2817 utf8, bbox)) {
2818 EXTEND(SP, 8);
2819 for (i = 0; i < 8; ++i)
2820 PUSHs(sv_2mortal(newSViv(bbox[i])));
2821 }
2822
2823undef_int
2824i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
2825 Imager::Font::FT2 font
2826 Imager::ImgRaw im
2827 int tx
2828 int ty
2829 Imager::Color cl
2830 double cheight
2831 double cwidth
2832 int align
2833 int aa
2834 int vlayout
2835 int utf8
2836 PREINIT:
2837 char *text;
2838 STRLEN len;
2839 CODE:
2840#ifdef SvUTF8
2841 if (SvUTF8(ST(7))) {
2842 utf8 = 1;
2843 }
2844#endif
2845 text = SvPV(ST(7), len);
2846 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
2847 len, align, aa, vlayout, utf8);
2848 OUTPUT:
2849 RETVAL
2850
2851undef_int
2852i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
2853 Imager::Font::FT2 font
2854 Imager::ImgRaw im
2855 int tx
2856 int ty
2857 int channel
2858 double cheight
2859 double cwidth
2860 char *text
2861 int align
2862 int aa
2863 int vlayout
2864 int utf8
2865 CODE:
2866#ifdef SvUTF8
2867 if (SvUTF8(ST(7)))
2868 utf8 = 1;
2869#endif
2870 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
2871 strlen(text), align, aa, vlayout, 1);
2872 OUTPUT:
2873 RETVAL
2874
2875void
2876ft2_transform_box(font, x0, x1, x2, x3)
2877 Imager::Font::FT2 font
2878 int x0
2879 int x1
2880 int x2
2881 int x3
2882 PREINIT:
2883 int box[4];
2884 PPCODE:
2885 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
2886 ft2_transform_box(font, box);
2887 EXTEND(SP, 4);
2888 PUSHs(sv_2mortal(newSViv(box[0])));
2889 PUSHs(sv_2mortal(newSViv(box[1])));
2890 PUSHs(sv_2mortal(newSViv(box[2])));
2891 PUSHs(sv_2mortal(newSViv(box[3])));
2892
2893#endif
2894