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