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