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