compressed BMP files for testing
[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
261f91c5
TC
1592undef_int
1593i_writebmp_wiol(im,ig)
1594 Imager::ImgRaw im
1595 Imager::IO ig
02d1d628
AMH
1596
1597Imager::ImgRaw
1598i_scaleaxis(im,Value,Axis)
1599 Imager::ImgRaw im
1600 float Value
1601 int Axis
1602
1603Imager::ImgRaw
1604i_scale_nn(im,scx,scy)
1605 Imager::ImgRaw im
1606 float scx
1607 float scy
1608
1609Imager::ImgRaw
1610i_haar(im)
1611 Imager::ImgRaw im
1612
1613int
1614i_count_colors(im,maxc)
1615 Imager::ImgRaw im
1616 int maxc
1617
1618
1619Imager::ImgRaw
1620i_transform(im,opx,opy,parm)
1621 Imager::ImgRaw im
1622 PREINIT:
1623 double* parm;
1624 int* opx;
1625 int* opy;
1626 int opxl;
1627 int opyl;
1628 int parmlen;
1629 AV* av;
1630 SV* sv1;
1631 int i;
1632 CODE:
1633 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1634 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1635 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1636 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1637 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1638 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1639 av=(AV*)SvRV(ST(1));
1640 opxl=av_len(av)+1;
1641 opx=mymalloc( opxl*sizeof(int) );
1642 for(i=0;i<opxl;i++) {
1643 sv1=(*(av_fetch(av,i,0)));
1644 opx[i]=(int)SvIV(sv1);
1645 }
1646 av=(AV*)SvRV(ST(2));
1647 opyl=av_len(av)+1;
1648 opy=mymalloc( opyl*sizeof(int) );
1649 for(i=0;i<opyl;i++) {
1650 sv1=(*(av_fetch(av,i,0)));
1651 opy[i]=(int)SvIV(sv1);
1652 }
1653 av=(AV*)SvRV(ST(3));
1654 parmlen=av_len(av)+1;
1655 parm=mymalloc( parmlen*sizeof(double) );
1656 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1657 sv1=(*(av_fetch(av,i,0)));
1658 parm[i]=(double)SvNV(sv1);
1659 }
1660 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1661 myfree(parm);
1662 myfree(opy);
1663 myfree(opx);
1664 ST(0) = sv_newmortal();
1665 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1666 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1667
1668Imager::ImgRaw
1669i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
1670 PREINIT:
1671 int width;
1672 int height;
1673 double* parm;
1674 struct rm_op *ops;
1675 unsigned int ops_len;
1676 int ops_count;
1677 double *n_regs;
1678 int n_regs_count;
1679 i_color *c_regs;
1680 int c_regs_count;
1681 int in_imgs_count;
1682 i_img **in_imgs;
1683 AV* av;
1684 SV* sv1;
1685 IV tmp;
1686 int i;
1687 CODE:
1688 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
1689 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
1690 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
1691 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1692 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
1693
1694 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
1695
1696 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1697 av = (AV*)SvRV(ST(5));
1698 in_imgs_count = av_len(av)+1;
1699 for (i = 0; i < in_imgs_count; ++i) {
1700 sv1 = *av_fetch(av, i, 0);
1701 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1702 croak("Parameter 5 must contain only images");
1703 }
1704 }
1705 }
1706 else {
1707 in_imgs_count = 0;
1708 }
1709 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1710 av = (AV*)SvRV(ST(5));
1711 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
1712 for (i = 0; i < in_imgs_count; ++i) {
1713 sv1 = *av_fetch(av,i,0);
1714 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1715 croak("Parameter 5 must contain only images");
1716 }
1717 tmp = SvIV((SV*)SvRV(sv1));
1718 in_imgs[i] = (i_img*)tmp;
1719 }
1720 }
1721 else {
1722 /* no input images */
1723 in_imgs = NULL;
1724 }
1725 /* default the output size from the first input if possible */
1726 if (SvOK(ST(0)))
1727 width = SvIV(ST(0));
1728 else if (in_imgs_count)
1729 width = in_imgs[0]->xsize;
1730 else
1731 croak("No output image width supplied");
1732
1733 if (SvOK(ST(1)))
1734 height = SvIV(ST(1));
1735 else if (in_imgs_count)
1736 height = in_imgs[0]->ysize;
1737 else
1738 croak("No output image height supplied");
1739
1740 ops = (struct rm_op *)SvPV(ST(2), ops_len);
1741 if (ops_len % sizeof(struct rm_op))
1742 croak("Imager: Parameter 3 must be a bitmap of regops\n");
1743 ops_count = ops_len / sizeof(struct rm_op);
1744 av = (AV*)SvRV(ST(3));
1745 n_regs_count = av_len(av)+1;
1746 n_regs = mymalloc(n_regs_count * sizeof(double));
1747 for (i = 0; i < n_regs_count; ++i) {
1748 sv1 = *av_fetch(av,i,0);
1749 if (SvOK(sv1))
1750 n_regs[i] = SvNV(sv1);
1751 }
1752 av = (AV*)SvRV(ST(4));
1753 c_regs_count = av_len(av)+1;
1754 c_regs = mymalloc(c_regs_count * sizeof(i_color));
1755 /* I don't bother initializing the colou?r registers */
1756
1757 RETVAL=i_transform2(width, height, 3, ops, ops_count,
1758 n_regs, n_regs_count,
1759 c_regs, c_regs_count, in_imgs, in_imgs_count);
1760 if (in_imgs)
1761 myfree(in_imgs);
1762 myfree(n_regs);
1763 myfree(c_regs);
1764 ST(0) = sv_newmortal();
1765 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1766 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1767
1768
1769void
1770i_contrast(im,intensity)
1771 Imager::ImgRaw im
1772 float intensity
1773
1774void
1775i_hardinvert(im)
1776 Imager::ImgRaw im
1777
1778void
1779i_noise(im,amount,type)
1780 Imager::ImgRaw im
1781 float amount
1782 unsigned char type
1783
1784void
1785i_bumpmap(im,bump,channel,light_x,light_y,strength)
1786 Imager::ImgRaw im
1787 Imager::ImgRaw bump
1788 int channel
1789 int light_x
1790 int light_y
1791 int strength
1792
1793void
1794i_postlevels(im,levels)
1795 Imager::ImgRaw im
1796 int levels
1797
1798void
1799i_mosaic(im,size)
1800 Imager::ImgRaw im
1801 int size
1802
1803void
1804i_watermark(im,wmark,tx,ty,pixdiff)
1805 Imager::ImgRaw im
1806 Imager::ImgRaw wmark
1807 int tx
1808 int ty
1809 int pixdiff
1810
1811
1812void
1813i_autolevels(im,lsat,usat,skew)
1814 Imager::ImgRaw im
1815 float lsat
1816 float usat
1817 float skew
1818
1819void
1820i_radnoise(im,xo,yo,rscale,ascale)
1821 Imager::ImgRaw im
1822 float xo
1823 float yo
1824 float rscale
1825 float ascale
1826
1827void
1828i_turbnoise(im, xo, yo, scale)
1829 Imager::ImgRaw im
1830 float xo
1831 float yo
1832 float scale
1833
1834
1835void
1836i_gradgen(im, ...)
1837 Imager::ImgRaw im
1838 PREINIT:
1839 int num;
1840 int *xo;
1841 int *yo;
1842 i_color *ival;
1843 int dmeasure;
1844 int i;
1845 SV *sv;
1846 AV *axx;
1847 AV *ayy;
1848 AV *ac;
1849 CODE:
1850 if (items != 5)
1851 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
1852 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1853 croak("i_gradgen: Second argument must be an array ref");
1854 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1855 croak("i_gradgen: Third argument must be an array ref");
1856 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1857 croak("i_gradgen: Fourth argument must be an array ref");
1858 axx = (AV *)SvRV(ST(1));
1859 ayy = (AV *)SvRV(ST(2));
1860 ac = (AV *)SvRV(ST(3));
1861 dmeasure = (int)SvIV(ST(4));
1862
1863 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1864 num = num <= av_len(ac) ? num : av_len(ac);
1865 num++;
1866 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
1867 xo = mymalloc( sizeof(int) * num );
1868 yo = mymalloc( sizeof(int) * num );
1869 ival = mymalloc( sizeof(i_color) * num );
1870 for(i = 0; i<num; i++) {
1871 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1872 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1873 sv = *av_fetch(ac, i, 0);
1874 if ( !sv_derived_from(sv, "Imager::Color") ) {
1875 free(axx); free(ayy); free(ac);
1876 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
1877 }
1878 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1879 }
1880 i_gradgen(im, num, xo, yo, ival, dmeasure);
1881
1882
1883
1884
1885
4f4f776a
TC
1886void
1887i_errors()
1888 PREINIT:
1889 i_errmsg *errors;
1890 int i;
4f4f776a
TC
1891 AV *av;
1892 SV *ref;
1893 SV *sv;
1894 PPCODE:
1895 errors = i_errors();
1896 i = 0;
1897 while (errors[i].msg) {
1898 av = newAV();
1899 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
1900 if (!av_store(av, 0, sv)) {
1901 SvREFCNT_dec(sv);
1902 }
1903 sv = newSViv(errors[i].code);
1904 if (!av_store(av, 1, sv)) {
1905 SvREFCNT_dec(sv);
1906 }
1907 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
1908 ++i;
1909 }
02d1d628
AMH
1910
1911void
1912i_nearest_color(im, ...)
1913 Imager::ImgRaw im
1914 PREINIT:
1915 int num;
1916 int *xo;
1917 int *yo;
1918 i_color *ival;
1919 int dmeasure;
1920 int i;
1921 SV *sv;
1922 AV *axx;
1923 AV *ayy;
1924 AV *ac;
1925 CODE:
1926 if (items != 5)
1927 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
1928 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1929 croak("i_nearest_color: Second argument must be an array ref");
1930 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1931 croak("i_nearest_color: Third argument must be an array ref");
1932 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1933 croak("i_nearest_color: Fourth argument must be an array ref");
1934 axx = (AV *)SvRV(ST(1));
1935 ayy = (AV *)SvRV(ST(2));
1936 ac = (AV *)SvRV(ST(3));
1937 dmeasure = (int)SvIV(ST(4));
1938
1939 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1940 num = num <= av_len(ac) ? num : av_len(ac);
1941 num++;
1942 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
1943 xo = mymalloc( sizeof(int) * num );
1944 yo = mymalloc( sizeof(int) * num );
1945 ival = mymalloc( sizeof(i_color) * num );
1946 for(i = 0; i<num; i++) {
1947 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1948 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1949 sv = *av_fetch(ac, i, 0);
1950 if ( !sv_derived_from(sv, "Imager::Color") ) {
1951 free(axx); free(ayy); free(ac);
1952 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
1953 }
1954 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1955 }
1956 i_nearest_color(im, num, xo, yo, ival, dmeasure);
1957
1958
1959
1960
1961void
1962malloc_state()
1963
1964void
1965hashinfo(hv)
1966 PREINIT:
1967 HV* hv;
1968 int stuff;
1969 PPCODE:
1970 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
1971 hv=(HV*)SvRV(ST(0));
1972 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
1973 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1974 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1975
1976void
1977DSO_open(filename)
1978 char* filename
1979 PREINIT:
1980 void *rc;
1981 char *evstr;
1982 PPCODE:
1983 rc=DSO_open(filename,&evstr);
1984 if (rc!=NULL) {
1985 if (evstr!=NULL) {
1986 EXTEND(SP,2);
1987 PUSHs(sv_2mortal(newSViv((IV)rc)));
1988 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
1989 } else {
1990 EXTEND(SP,1);
1991 PUSHs(sv_2mortal(newSViv((IV)rc)));
1992 }
1993 }
1994
1995
1996undef_int
1997DSO_close(dso_handle)
1998 void* dso_handle
1999
2000void
2001DSO_funclist(dso_handle_v)
2002 void* dso_handle_v
2003 PREINIT:
2004 int i;
2005 DSO_handle *dso_handle;
2006 PPCODE:
2007 dso_handle=(DSO_handle*)dso_handle_v;
2008 i=0;
2009 while( dso_handle->function_list[i].name != NULL) {
2010 EXTEND(SP,1);
2011 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
2012 EXTEND(SP,1);
2013 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
2014 }
2015
2016
2017void
2018DSO_call(handle,func_index,hv)
2019 void* handle
2020 int func_index
2021 PREINIT:
2022 HV* hv;
2023 PPCODE:
2024 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2025 hv=(HV*)SvRV(ST(2));
2026 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2027 DSO_call( (DSO_handle *)handle,func_index,hv);
2028
2029
2030
f5991c03 2031# this is mostly for testing...
faa9b3e7 2032SV *
f5991c03
TC
2033i_get_pixel(im, x, y)
2034 Imager::ImgRaw im
2035 int x
2036 int y;
faa9b3e7
TC
2037 PREINIT:
2038 i_color *color;
2039 CODE:
2040 color = (i_color *)mymalloc(sizeof(i_color));
2041 if (i_gpix(im, x, y, color) == 0) {
2042 ST(0) = sv_newmortal();
2043 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
2044 }
2045 else {
2046 myfree(color);
2047 ST(0) = &PL_sv_undef;
2048 }
2049
2050
2051int
2052i_ppix(im, x, y, cl)
2053 Imager::ImgRaw im
2054 int x
2055 int y
2056 Imager::Color cl
2057
2058Imager::ImgRaw
2059i_img_pal_new(x, y, channels, maxpal)
2060 int x
2061 int y
2062 int channels
2063 int maxpal
2064
2065Imager::ImgRaw
2066i_img_to_pal(src, quant)
2067 Imager::ImgRaw src
2068 PREINIT:
2069 HV *hv;
2070 i_quantize quant;
2071 CODE:
2072 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2073 croak("i_img_to_pal: second argument must be a hash ref");
2074 hv = (HV *)SvRV(ST(1));
2075 memset(&quant, 0, sizeof(quant));
2076 quant.mc_size = 256;
2077 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
2078 handle_quant_opts(&quant, hv);
2079 RETVAL = i_img_to_pal(src, &quant);
2080 if (RETVAL) {
2081 copy_colors_back(hv, &quant);
2082 }
2083 myfree(quant.mc_colors);
2084 OUTPUT:
2085 RETVAL
2086
2087Imager::ImgRaw
2088i_img_to_rgb(src)
2089 Imager::ImgRaw src
2090
2091void
2092i_gpal(im, l, r, y)
2093 Imager::ImgRaw im
2094 int l
2095 int r
2096 int y
2097 PREINIT:
2098 i_palidx *work;
2099 int count, i;
2100 PPCODE:
2101 if (l < r) {
2102 work = mymalloc((r-l) * sizeof(i_palidx));
2103 count = i_gpal(im, l, r, y, work);
2104 if (GIMME_V == G_ARRAY) {
2105 EXTEND(SP, count);
2106 for (i = 0; i < count; ++i) {
2107 PUSHs(sv_2mortal(newSViv(work[i])));
2108 }
2109 }
2110 else {
2111 EXTEND(SP, 1);
2112 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
2113 }
2114 myfree(work);
2115 }
2116 else {
2117 if (GIMME_V != G_ARRAY) {
2118 EXTEND(SP, 1);
2119 PUSHs(&PL_sv_undef);
2120 }
2121 }
2122
2123int
2124i_ppal(im, l, y, ...)
2125 Imager::ImgRaw im
2126 int l
2127 int y
2128 PREINIT:
2129 i_palidx *work;
2130 int count, i;
2131 CODE:
2132 if (items > 3) {
2133 work = mymalloc(sizeof(i_palidx) * (items-3));
2134 for (i=0; i < items-3; ++i) {
2135 work[i] = SvIV(ST(i+3));
2136 }
2137 RETVAL = i_ppal(im, l, l+items-3, y, work);
2138 myfree(work);
2139 }
2140 else {
2141 RETVAL = 0;
2142 }
2143 OUTPUT:
2144 RETVAL
2145
2146SV *
2147i_addcolors(im, ...)
2148 Imager::ImgRaw im
2149 PREINIT:
2150 int index;
2151 i_color *colors;
2152 int i;
2153 CODE:
2154 if (items < 2)
2155 croak("i_addcolors: no colors to add");
2156 colors = mymalloc((items-1) * sizeof(i_color));
2157 for (i=0; i < items-1; ++i) {
2158 if (sv_isobject(ST(i+1))
2159 && sv_derived_from(ST(i+1), "Imager::Color")) {
2160 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2161 colors[i] = *(i_color *)tmp;
2162 }
2163 else {
2164 myfree(colors);
2165 croak("i_plin: pixels must be Imager::Color objects");
2166 }
2167 }
2168 index = i_addcolors(im, colors, items-1);
2169 myfree(colors);
2170 if (index == 0) {
2171 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2172 }
2173 else if (index == -1) {
2174 ST(0) = &PL_sv_undef;
2175 }
2176 else {
2177 ST(0) = sv_2mortal(newSViv(index));
2178 }
2179
2180int
2181i_setcolors(im, index, ...)
2182 Imager::ImgRaw im
2183 int index
2184 PREINIT:
2185 i_color *colors;
2186 int i;
2187 CODE:
2188 if (items < 3)
2189 croak("i_setcolors: no colors to add");
2190 colors = mymalloc((items-2) * sizeof(i_color));
2191 for (i=0; i < items-2; ++i) {
2192 if (sv_isobject(ST(i+2))
2193 && sv_derived_from(ST(i+2), "Imager::Color")) {
2194 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
2195 colors[i] = *(i_color *)tmp;
2196 }
2197 else {
2198 myfree(colors);
2199 croak("i_setcolors: pixels must be Imager::Color objects");
2200 }
2201 }
2202 RETVAL = i_setcolors(im, index, colors, items-2);
2203 myfree(colors);
2204
2205void
2206i_getcolors(im, index, ...)
2207 Imager::ImgRaw im
2208 int index
2209 PREINIT:
2210 i_color *colors;
2211 int count = 1;
2212 int i;
2213 PPCODE:
2214 if (items > 3)
2215 croak("i_getcolors: too many arguments");
2216 if (items == 3)
2217 count = SvIV(ST(2));
2218 if (count < 1)
2219 croak("i_getcolors: count must be positive");
2220 colors = mymalloc(sizeof(i_color) * count);
2221 if (i_getcolors(im, index, colors, count)) {
2222 for (i = 0; i < count; ++i) {
2223 i_color *pv;
2224 SV *sv = sv_newmortal();
2225 pv = mymalloc(sizeof(i_color));
2226 *pv = colors[i];
2227 sv_setref_pv(sv, "Imager::Color", (void *)pv);
2228 PUSHs(sv);
2229 }
2230 }
2231 myfree(colors);
2232
2233
2234SV *
2235i_colorcount(im)
2236 Imager::ImgRaw im
2237 PREINIT:
2238 int count;
2239 CODE:
2240 count = i_colorcount(im);
2241 if (count >= 0) {
2242 ST(0) = sv_2mortal(newSViv(count));
2243 }
2244 else {
2245 ST(0) = &PL_sv_undef;
2246 }
2247
2248SV *
2249i_maxcolors(im)
2250 Imager::ImgRaw im
2251 PREINIT:
2252 int count;
2253 CODE:
2254 count = i_maxcolors(im);
2255 if (count >= 0) {
2256 ST(0) = sv_2mortal(newSViv(count));
2257 }
2258 else {
2259 ST(0) = &PL_sv_undef;
2260 }
2261
2262SV *
2263i_findcolor(im, color)
2264 Imager::ImgRaw im
2265 Imager::Color color
2266 PREINIT:
2267 i_palidx index;
2268 CODE:
2269 if (i_findcolor(im, color, &index)) {
2270 ST(0) = sv_2mortal(newSViv(index));
2271 }
2272 else {
2273 ST(0) = &PL_sv_undef;
2274 }
2275
2276int
2277i_img_bits(im)
2278 Imager::ImgRaw im
2279
2280int
2281i_img_type(im)
2282 Imager::ImgRaw im
2283
2284int
2285i_img_virtual(im)
2286 Imager::ImgRaw im
2287
2288void
2289i_gsamp(im, l, r, y, ...)
2290 Imager::ImgRaw im
2291 int l
2292 int r
2293 int y
2294 PREINIT:
2295 int *chans;
2296 int chan_count;
2297 i_sample_t *data;
2298 int count, i;
2299 PPCODE:
2300 if (items < 5)
2301 croak("No channel numbers supplied to g_samp()");
2302 if (l < r) {
2303 chan_count = items - 4;
2304 chans = mymalloc(sizeof(int) * chan_count);
2305 for (i = 0; i < chan_count; ++i)
2306 chans[i] = SvIV(ST(i+4));
2307 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count);
2308 count = i_gsamp(im, l, r, y, data, chans, chan_count);
2309 if (GIMME_V == G_ARRAY) {
2310 EXTEND(SP, count);
2311 for (i = 0; i < count; ++i)
2312 PUSHs(sv_2mortal(newSViv(data[i])));
2313 }
2314 else {
2315 EXTEND(SP, 1);
2316 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
2317 }
2318 }
2319 else {
2320 if (GIMME_V != G_ARRAY) {
2321 EXTEND(SP, 1);
2322 PUSHs(&PL_sv_undef);
2323 }
2324 }
2325
2326Imager::ImgRaw
2327i_img_masked_new(targ, mask, x, y, w, h)
2328 Imager::ImgRaw targ
2329 int x
2330 int y
2331 int w
2332 int h
2333 PREINIT:
2334 i_img *mask;
2335 CODE:
2336 if (SvOK(ST(1))) {
2337 if (!sv_isobject(ST(1))
2338 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
2339 croak("i_img_masked_new: parameter 2 must undef or an image");
2340 }
2341 mask = (i_img *)SvIV((SV *)SvRV(ST(1)));
2342 }
2343 else
2344 mask = NULL;
2345 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
2346 OUTPUT:
2347 RETVAL
2348
2349int
2350i_plin(im, l, y, ...)
2351 Imager::ImgRaw im
2352 int l
2353 int y
2354 PREINIT:
2355 i_color *work;
2356 int count, i;
2357 CODE:
2358 if (items > 3) {
2359 work = mymalloc(sizeof(i_color) * (items-3));
2360 for (i=0; i < items-3; ++i) {
2361 if (sv_isobject(ST(i+3))
2362 && sv_derived_from(ST(i+3), "Imager::Color")) {
2363 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2364 work[i] = *(i_color *)tmp;
2365 }
2366 else {
2367 myfree(work);
2368 croak("i_plin: pixels must be Imager::Color objects");
2369 }
2370 }
2371 /**(char *)0 = 1;*/
2372 RETVAL = i_plin(im, l, l+items-3, y, work);
2373 myfree(work);
2374 }
2375 else {
2376 RETVAL = 0;
2377 }
2378 OUTPUT:
2379 RETVAL
2380
2381int
2382i_ppixf(im, x, y, cl)
2383 Imager::ImgRaw im
2384 int x
2385 int y
2386 Imager::Color::Float cl
2387
2388void
2389i_gsampf(im, l, r, y, ...)
2390 Imager::ImgRaw im
2391 int l
2392 int r
2393 int y
2394 PREINIT:
2395 int *chans;
2396 int chan_count;
2397 i_fsample_t *data;
2398 int count, i;
2399 PPCODE:
2400 if (items < 5)
2401 croak("No channel numbers supplied to g_sampf()");
2402 if (l < r) {
2403 chan_count = items - 4;
2404 chans = mymalloc(sizeof(int) * chan_count);
2405 for (i = 0; i < chan_count; ++i)
2406 chans[i] = SvIV(ST(i+4));
2407 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
2408 count = i_gsampf(im, l, r, y, data, chans, chan_count);
2409 if (GIMME_V == G_ARRAY) {
2410 EXTEND(SP, count);
2411 for (i = 0; i < count; ++i)
2412 PUSHs(sv_2mortal(newSVnv(data[i])));
2413 }
2414 else {
2415 EXTEND(SP, 1);
2416 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
2417 }
2418 }
2419 else {
2420 if (GIMME_V != G_ARRAY) {
2421 EXTEND(SP, 1);
2422 PUSHs(&PL_sv_undef);
2423 }
2424 }
2425
2426int
2427i_plinf(im, l, y, ...)
2428 Imager::ImgRaw im
2429 int l
2430 int y
2431 PREINIT:
2432 i_fcolor *work;
2433 int count, i;
2434 CODE:
2435 if (items > 3) {
2436 work = mymalloc(sizeof(i_fcolor) * (items-3));
2437 for (i=0; i < items-3; ++i) {
2438 if (sv_isobject(ST(i+3))
2439 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
2440 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2441 work[i] = *(i_fcolor *)tmp;
2442 }
2443 else {
2444 myfree(work);
2445 croak("i_plin: pixels must be Imager::Color::Float objects");
2446 }
2447 }
2448 /**(char *)0 = 1;*/
2449 RETVAL = i_plinf(im, l, l+items-3, y, work);
2450 myfree(work);
2451 }
2452 else {
2453 RETVAL = 0;
2454 }
2455 OUTPUT:
2456 RETVAL
2457
2458SV *
2459i_gpixf(im, x, y)
2460 Imager::ImgRaw im
2461 int x
2462 int y;
2463 PREINIT:
2464 i_fcolor *color;
2465 CODE:
2466 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
2467 if (i_gpixf(im, x, y, color) == 0) {
2468 ST(0) = sv_newmortal();
2469 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
2470 }
2471 else {
2472 myfree(color);
2473 ST(0) = &PL_sv_undef;
2474 }
2475
2476void
2477i_glin(im, l, r, y)
2478 Imager::ImgRaw im
2479 int l
2480 int r
2481 int y
2482 PREINIT:
2483 i_color *vals;
2484 int count, i;
2485 PPCODE:
2486 if (l < r) {
2487 vals = mymalloc((r-l) * sizeof(i_color));
2488 count = i_glin(im, l, r, y, vals);
2489 EXTEND(SP, count);
2490 for (i = 0; i < count; ++i) {
2491 SV *sv;
2492 i_color *col = mymalloc(sizeof(i_color));
2493 sv = sv_newmortal();
2494 sv_setref_pv(sv, "Imager::Color", (void *)col);
2495 PUSHs(sv);
2496 }
2497 myfree(vals);
2498 }
2499
2500void
2501i_glinf(im, l, r, y)
2502 Imager::ImgRaw im
2503 int l
2504 int r
2505 int y
2506 PREINIT:
2507 i_fcolor *vals;
2508 int count, i;
2509 PPCODE:
2510 if (l < r) {
2511 vals = mymalloc((r-l) * sizeof(i_fcolor));
2512 count = i_glinf(im, l, r, y, vals);
2513 EXTEND(SP, count);
2514 for (i = 0; i < count; ++i) {
2515 SV *sv;
2516 i_fcolor *col = mymalloc(sizeof(i_fcolor));
2517 *col = vals[i];
2518 sv = sv_newmortal();
2519 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
2520 PUSHs(sv);
2521 }
2522 myfree(vals);
2523 }
2524
2525Imager::ImgRaw
2526i_img_16_new(x, y, ch)
2527 int x
2528 int y
2529 int ch
2530
2531undef_int
2532i_tags_addn(im, name, code, idata)
2533 Imager::ImgRaw im
2534 int code
2535 int idata
2536 PREINIT:
2537 char *name;
2538 STRLEN len;
2539 CODE:
2540 if (SvOK(ST(1)))
2541 name = SvPV(ST(1), len);
2542 else
2543 name = NULL;
2544 RETVAL = i_tags_addn(&im->tags, name, code, idata);
2545 OUTPUT:
2546 RETVAL
2547
2548undef_int
2549i_tags_add(im, name, code, data, idata)
2550 Imager::ImgRaw im
2551 int code
2552 int idata
2553 PREINIT:
2554 char *name;
2555 char *data;
2556 STRLEN len;
2557 CODE:
2558 if (SvOK(ST(1)))
2559 name = SvPV(ST(1), len);
2560 else
2561 name = NULL;
2562 if (SvOK(ST(3)))
2563 data = SvPV(ST(3), len);
2564 else {
2565 data = NULL;
2566 len = 0;
2567 }
2568 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
2569 OUTPUT:
2570 RETVAL
2571
2572SV *
2573i_tags_find(im, name, start)
2574 Imager::ImgRaw im
2575 char *name
2576 int start
2577 PREINIT:
2578 int entry;
2579 CODE:
2580 if (i_tags_find(&im->tags, name, start, &entry)) {
2581 if (entry == 0)
2582 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2583 else
2584 ST(0) = sv_2mortal(newSViv(entry));
2585 } else {
2586 ST(0) = &PL_sv_undef;
2587 }
2588
2589SV *
2590i_tags_findn(im, code, start)
2591 Imager::ImgRaw im
2592 int code
2593 int start
2594 PREINIT:
2595 int entry;
2596 CODE:
2597 if (i_tags_findn(&im->tags, code, start, &entry)) {
2598 if (entry == 0)
2599 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2600 else
2601 ST(0) = sv_2mortal(newSViv(entry));
2602 }
2603 else
2604 ST(0) = &PL_sv_undef;
2605
2606int
2607i_tags_delete(im, entry)
2608 Imager::ImgRaw im
2609 int entry
2610 CODE:
2611 RETVAL = i_tags_delete(&im->tags, entry);
2612 OUTPUT:
2613 RETVAL
2614
2615int
2616i_tags_delbyname(im, name)
2617 Imager::ImgRaw im
2618 char * name
2619 CODE:
2620 RETVAL = i_tags_delbyname(&im->tags, name);
2621 OUTPUT:
2622 RETVAL
2623
2624int
2625i_tags_delbycode(im, code)
2626 Imager::ImgRaw im
2627 int code
2628 CODE:
2629 RETVAL = i_tags_delbycode(&im->tags, code);
2630 OUTPUT:
2631 RETVAL
2632
2633void
2634i_tags_get(im, index)
2635 Imager::ImgRaw im
2636 int index
2637 PPCODE:
2638 if (index >= 0 && index < im->tags.count) {
2639 i_img_tag *entry = im->tags.tags + index;
2640 EXTEND(SP, 5);
2641
2642 if (entry->name) {
2643 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
2644 }
2645 else {
2646 PUSHs(sv_2mortal(newSViv(entry->code)));
2647 }
2648 if (entry->data) {
2649 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
2650 }
2651 else {
2652 PUSHs(sv_2mortal(newSViv(entry->idata)));
2653 }
2654 }
2655
2656int
2657i_tags_count(im)
2658 Imager::ImgRaw im
2659 CODE:
2660 RETVAL = im->tags.count;
2661 OUTPUT:
2662 RETVAL
2663
2664#ifdef HAVE_WIN32
2665
2666void
2667i_wf_bbox(face, size, text)
2668 char *face
2669 int size
2670 char *text
2671 PREINIT:
2672 int cords[6];
2673 PPCODE:
2674 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
2675 EXTEND(SP, 6);
2676 PUSHs(sv_2mortal(newSViv(cords[0])));
2677 PUSHs(sv_2mortal(newSViv(cords[1])));
2678 PUSHs(sv_2mortal(newSViv(cords[2])));
2679 PUSHs(sv_2mortal(newSViv(cords[3])));
2680 PUSHs(sv_2mortal(newSViv(cords[4])));
2681 PUSHs(sv_2mortal(newSViv(cords[5])));
2682 }
2683
2684undef_int
2685i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
2686 char *face
2687 Imager::ImgRaw im
2688 int tx
2689 int ty
2690 Imager::Color cl
2691 int size
2692 char *text
2693 int align
2694 int aa
2695 CODE:
2696 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
2697 align, aa);
2698 OUTPUT:
2699 RETVAL
2700
2701undef_int
2702i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
2703 char *face
2704 Imager::ImgRaw im
2705 int tx
2706 int ty
2707 int channel
2708 int size
2709 char *text
2710 int align
2711 int aa
f5991c03 2712 CODE:
faa9b3e7
TC
2713 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
2714 align, aa);
f5991c03
TC
2715 OUTPUT:
2716 RETVAL
02d1d628 2717
faa9b3e7
TC
2718
2719#endif
2720
2721#ifdef HAVE_FT2
2722
2723MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
2724
2725#define FT2_DESTROY(font) i_ft2_destroy(font)
2726
2727void
2728FT2_DESTROY(font)
2729 Imager::Font::FT2 font
2730
2731MODULE = Imager PACKAGE = Imager::Font::FreeType2
2732
2733Imager::Font::FT2
2734i_ft2_new(name, index)
2735 char *name
2736 int index
2737
2738undef_int
2739i_ft2_setdpi(font, xdpi, ydpi)
2740 Imager::Font::FT2 font
2741 int xdpi
2742 int ydpi
2743
2744void
2745i_ft2_getdpi(font)
2746 Imager::Font::FT2 font
2747 PREINIT:
2748 int xdpi, ydpi;
2749 CODE:
2750 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
2751 EXTEND(SP, 2);
2752 PUSHs(sv_2mortal(newSViv(xdpi)));
2753 PUSHs(sv_2mortal(newSViv(ydpi)));
2754 }
2755
2756undef_int
2757i_ft2_sethinting(font, hinting)
2758 Imager::Font::FT2 font
2759 int hinting
2760
2761undef_int
2762i_ft2_settransform(font, matrix)
2763 Imager::Font::FT2 font
2764 PREINIT:
2765 double matrix[6];
2766 int len;
2767 AV *av;
2768 SV *sv1;
2769 int i;
2770 CODE:
2771 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
2772 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
2773 av=(AV*)SvRV(ST(1));
2774 len=av_len(av)+1;
2775 if (len > 6)
2776 len = 6;
2777 for (i = 0; i < len; ++i) {
2778 sv1=(*(av_fetch(av,i,0)));
2779 matrix[i] = SvNV(sv1);
2780 }
2781 for (; i < 6; ++i)
2782 matrix[i] = 0;
2783 RETVAL = i_ft2_settransform(font, matrix);
2784 OUTPUT:
2785 RETVAL
2786
2787void
2788i_ft2_bbox(font, cheight, cwidth, text)
2789 Imager::Font::FT2 font
2790 double cheight
2791 double cwidth
2792 char *text
2793 PREINIT:
2794 int bbox[6];
2795 int i;
2796 PPCODE:
2797 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox)) {
2798 EXTEND(SP, 6);
2799 for (i = 0; i < 6; ++i)
2800 PUSHs(sv_2mortal(newSViv(bbox[i])));
2801 }
2802
2803void
2804i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
2805 Imager::Font::FT2 font
2806 double cheight
2807 double cwidth
2808 char *text
2809 int vlayout
2810 int utf8
2811 PREINIT:
2812 int bbox[8];
2813 int i;
2814 PPCODE:
2815#ifdef SvUTF8
2816 if (SvUTF8(ST(3)))
2817 utf8 = 1;
2818#endif
2819 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
2820 utf8, bbox)) {
2821 EXTEND(SP, 8);
2822 for (i = 0; i < 8; ++i)
2823 PUSHs(sv_2mortal(newSViv(bbox[i])));
2824 }
2825
2826undef_int
2827i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
2828 Imager::Font::FT2 font
2829 Imager::ImgRaw im
2830 int tx
2831 int ty
2832 Imager::Color cl
2833 double cheight
2834 double cwidth
2835 int align
2836 int aa
2837 int vlayout
2838 int utf8
2839 PREINIT:
2840 char *text;
2841 STRLEN len;
2842 CODE:
2843#ifdef SvUTF8
2844 if (SvUTF8(ST(7))) {
2845 utf8 = 1;
2846 }
2847#endif
2848 text = SvPV(ST(7), len);
2849 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
2850 len, align, aa, vlayout, utf8);
2851 OUTPUT:
2852 RETVAL
2853
2854undef_int
2855i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
2856 Imager::Font::FT2 font
2857 Imager::ImgRaw im
2858 int tx
2859 int ty
2860 int channel
2861 double cheight
2862 double cwidth
2863 char *text
2864 int align
2865 int aa
2866 int vlayout
2867 int utf8
2868 CODE:
2869#ifdef SvUTF8
2870 if (SvUTF8(ST(7)))
2871 utf8 = 1;
2872#endif
2873 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
2874 strlen(text), align, aa, vlayout, 1);
2875 OUTPUT:
2876 RETVAL
2877
2878void
2879ft2_transform_box(font, x0, x1, x2, x3)
2880 Imager::Font::FT2 font
2881 int x0
2882 int x1
2883 int x2
2884 int x3
2885 PREINIT:
2886 int box[4];
2887 PPCODE:
2888 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
2889 ft2_transform_box(font, box);
2890 EXTEND(SP, 4);
2891 PUSHs(sv_2mortal(newSViv(box[0])));
2892 PUSHs(sv_2mortal(newSViv(box[1])));
2893 PUSHs(sv_2mortal(newSViv(box[2])));
2894 PUSHs(sv_2mortal(newSViv(box[3])));
2895
2896#endif
2897