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