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