Added rgb.c to MANIFEST
[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
43c5dacb
TC
984void
985i_poly_aa_cfill(im,xc,yc,fill)
986 Imager::ImgRaw im
987 Imager::FillHandle fill
988 PREINIT:
989 double *x,*y;
990 int len;
991 AV *av1;
992 AV *av2;
993 SV *sv1;
994 SV *sv2;
995 int i;
996 PPCODE:
997 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
998 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
999 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1000 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa_cfill must be a reference to an array\n");
1001 av1=(AV*)SvRV(ST(1));
1002 av2=(AV*)SvRV(ST(2));
1003 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa_cfill must be equal length\n");
1004 len=av_len(av1)+1;
1005 x=mymalloc( len*sizeof(double) );
1006 y=mymalloc( len*sizeof(double) );
1007 for(i=0;i<len;i++) {
1008 sv1=(*(av_fetch(av1,i,0)));
1009 sv2=(*(av_fetch(av2,i,0)));
1010 x[i]=(double)SvNV(sv1);
1011 y[i]=(double)SvNV(sv2);
1012 }
1013 i_poly_aa_cfill(im,len,x,y,fill);
1014 myfree(x);
1015 myfree(y);
1016
02d1d628
AMH
1017
1018
1019void
1020i_flood_fill(im,seedx,seedy,dcol)
1021 Imager::ImgRaw im
1022 int seedx
1023 int seedy
1024 Imager::Color dcol
1025
cc6483e0
TC
1026void
1027i_flood_cfill(im,seedx,seedy,fill)
1028 Imager::ImgRaw im
1029 int seedx
1030 int seedy
1031 Imager::FillHandle fill
1032
02d1d628
AMH
1033
1034void
1035i_copyto(im,src,x1,y1,x2,y2,tx,ty)
1036 Imager::ImgRaw im
1037 Imager::ImgRaw src
1038 int x1
1039 int y1
1040 int x2
1041 int y2
1042 int tx
1043 int ty
1044
1045
1046void
1047i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
1048 Imager::ImgRaw im
1049 Imager::ImgRaw src
1050 int x1
1051 int y1
1052 int x2
1053 int y2
1054 int tx
1055 int ty
1056 Imager::Color trans
1057
1058void
1059i_copy(im,src)
1060 Imager::ImgRaw im
1061 Imager::ImgRaw src
1062
1063
faa9b3e7 1064undef_int
02d1d628
AMH
1065i_rubthru(im,src,tx,ty)
1066 Imager::ImgRaw im
1067 Imager::ImgRaw src
1068 int tx
1069 int ty
1070
142c26ff
AMH
1071undef_int
1072i_flipxy(im, direction)
1073 Imager::ImgRaw im
1074 int direction
1075
faa9b3e7
TC
1076Imager::ImgRaw
1077i_rotate90(im, degrees)
1078 Imager::ImgRaw im
1079 int degrees
1080
1081Imager::ImgRaw
1082i_rotate_exact(im, amount)
1083 Imager::ImgRaw im
1084 double amount
1085
1086Imager::ImgRaw
1087i_matrix_transform(im, xsize, ysize, matrix)
1088 Imager::ImgRaw im
1089 int xsize
1090 int ysize
1091 PREINIT:
1092 double matrix[9];
1093 AV *av;
1094 IV len;
1095 SV *sv1;
1096 int i;
1097 CODE:
1098 if (!SvROK(ST(3)) || SvTYPE(SvRV(ST(3))) != SVt_PVAV)
1099 croak("i_matrix_transform: parameter 4 must be an array ref\n");
1100 av=(AV*)SvRV(ST(3));
1101 len=av_len(av)+1;
1102 if (len > 9)
1103 len = 9;
1104 for (i = 0; i < len; ++i) {
1105 sv1=(*(av_fetch(av,i,0)));
1106 matrix[i] = SvNV(sv1);
1107 }
1108 for (; i < 9; ++i)
1109 matrix[i] = 0;
1110 RETVAL = i_matrix_transform(im, xsize, ysize, matrix);
1111 OUTPUT:
1112 RETVAL
02d1d628
AMH
1113
1114void
1115i_gaussian(im,stdev)
1116 Imager::ImgRaw im
1117 float stdev
1118
b6381851
TC
1119void
1120i_unsharp_mask(im,stdev,scale)
1121 Imager::ImgRaw im
1122 float stdev
1123 double scale
1124
02d1d628
AMH
1125void
1126i_conv(im,pcoef)
1127 Imager::ImgRaw im
1128 PREINIT:
1129 float* coeff;
1130 int len;
1131 AV* av;
1132 SV* sv1;
1133 int i;
1134 PPCODE:
1135 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1136 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1137 av=(AV*)SvRV(ST(1));
1138 len=av_len(av)+1;
1139 coeff=mymalloc( len*sizeof(float) );
1140 for(i=0;i<len;i++) {
1141 sv1=(*(av_fetch(av,i,0)));
1142 coeff[i]=(float)SvNV(sv1);
1143 }
1144 i_conv(im,coeff,len);
1145 myfree(coeff);
1146
f5991c03
TC
1147undef_int
1148i_convert(im, src, coeff)
1149 Imager::ImgRaw im
1150 Imager::ImgRaw src
1151 PREINIT:
1152 float *coeff;
1153 int outchan;
1154 int inchan;
1155 AV *avmain;
1156 SV **temp;
1157 SV *svsub;
1158 AV *avsub;
1159 int len;
1160 int i, j;
1161 CODE:
f5991c03
TC
1162 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
1163 croak("i_convert: parameter 3 must be an arrayref\n");
1164 avmain = (AV*)SvRV(ST(2));
1165 outchan = av_len(avmain)+1;
1166 /* find the biggest */
1167 inchan = 0;
1168 for (j=0; j < outchan; ++j) {
1169 temp = av_fetch(avmain, j, 0);
1170 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
1171 avsub = (AV*)SvRV(*temp);
1172 len = av_len(avsub)+1;
1173 if (len > inchan)
1174 inchan = len;
1175 }
1176 }
1177 coeff = mymalloc(sizeof(float) * outchan * inchan);
1178 for (j = 0; j < outchan; ++j) {
1179 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
1180 len = av_len(avsub)+1;
1181 for (i = 0; i < len; ++i) {
1182 temp = av_fetch(avsub, i, 0);
1183 if (temp)
1184 coeff[i+j*inchan] = SvNV(*temp);
1185 else
1186 coeff[i+j*inchan] = 0;
1187 }
1188 while (i < inchan)
1189 coeff[i++ + j*inchan] = 0;
1190 }
1191 RETVAL = i_convert(im, src, coeff, outchan, inchan);
1192 myfree(coeff);
f5991c03
TC
1193 OUTPUT:
1194 RETVAL
40eba1ea
AMH
1195
1196
1197void
1198i_map(im, pmaps)
1199 Imager::ImgRaw im
1200 PREINIT:
1201 unsigned int mask = 0;
1202 AV *avmain;
1203 AV *avsub;
1204 SV **temp;
1205 int len;
1206 int i, j;
1207 unsigned char (*maps)[256];
1208 CODE:
1209 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
1210 croak("i_map: parameter 2 must be an arrayref\n");
1211 avmain = (AV*)SvRV(ST(1));
1212 len = av_len(avmain)+1;
1213 if (im->channels < len) len = im->channels;
1214
1215 maps = mymalloc( len * sizeof(unsigned char [256]) );
1216
1217 for (j=0; j<len ; j++) {
1218 temp = av_fetch(avmain, j, 0);
1219 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
1220 avsub = (AV*)SvRV(*temp);
1221 if(av_len(avsub) != 255) continue;
1222 mask |= 1<<j;
1223 for (i=0; i<256 ; i++) {
9495ee93 1224 int val;
40eba1ea 1225 temp = av_fetch(avsub, i, 0);
9495ee93
AMH
1226 val = temp ? SvIV(*temp) : 0;
1227 if (val<0) val = 0;
1228 if (val>255) val = 255;
1229 maps[j][i] = val;
40eba1ea
AMH
1230 }
1231 }
1232 }
1233 i_map(im, maps, mask);
1234 myfree(maps);
1235
1236
1237
02d1d628
AMH
1238float
1239i_img_diff(im1,im2)
1240 Imager::ImgRaw im1
1241 Imager::ImgRaw im2
1242
1243
1244
1245undef_int
1246i_init_fonts()
1247
1248#ifdef HAVE_LIBT1
1249
1250void
1251i_t1_set_aa(st)
1252 int st
1253
1254int
6b012d62 1255i_t1_new(pfb,afm)
02d1d628
AMH
1256 char* pfb
1257 char* afm
1258
1259int
1260i_t1_destroy(font_id)
1261 int font_id
1262
1263
1264undef_int
1265i_t1_cp(im,xb,yb,channel,fontnum,points,str,len,align)
1266 Imager::ImgRaw im
1267 int xb
1268 int yb
1269 int channel
1270 int fontnum
1271 float points
1272 char* str
1273 int len
1274 int align
1275
1276void
1277i_t1_bbox(fontnum,point,str,len)
1278 int fontnum
1279 float point
1280 char* str
1281 int len
1282 PREINIT:
1283 int cords[6];
1284 PPCODE:
1285 i_t1_bbox(fontnum,point,str,len,cords);
1286 EXTEND(SP, 4);
1287 PUSHs(sv_2mortal(newSViv(cords[0])));
1288 PUSHs(sv_2mortal(newSViv(cords[1])));
1289 PUSHs(sv_2mortal(newSViv(cords[2])));
1290 PUSHs(sv_2mortal(newSViv(cords[3])));
1291 PUSHs(sv_2mortal(newSViv(cords[4])));
1292 PUSHs(sv_2mortal(newSViv(cords[5])));
1293
1294
1295
1296undef_int
1297i_t1_text(im,xb,yb,cl,fontnum,points,str,len,align)
1298 Imager::ImgRaw im
1299 int xb
1300 int yb
1301 Imager::Color cl
1302 int fontnum
1303 float points
1304 char* str
1305 int len
1306 int align
1307
1308#endif
1309
1310#ifdef HAVE_LIBTT
1311
1312
4b19f77a 1313Imager::Font::TT
02d1d628
AMH
1314i_tt_new(fontname)
1315 char* fontname
1316
4b19f77a
AMH
1317
1318MODULE = Imager PACKAGE = Imager::Font::TT PREFIX=TT_
1319
1320#define TT_DESTROY(handle) i_tt_destroy(handle)
1321
02d1d628 1322void
4b19f77a
AMH
1323TT_DESTROY(handle)
1324 Imager::Font::TT handle
1325
02d1d628 1326
4b19f77a 1327MODULE = Imager PACKAGE = Imager
02d1d628
AMH
1328
1329
1330undef_int
1331i_tt_text(handle,im,xb,yb,cl,points,str,len,smooth)
4b19f77a 1332 Imager::Font::TT handle
02d1d628
AMH
1333 Imager::ImgRaw im
1334 int xb
1335 int yb
1336 Imager::Color cl
1337 float points
1338 char* str
1339 int len
1340 int smooth
1341
1342
1343undef_int
1344i_tt_cp(handle,im,xb,yb,channel,points,str,len,smooth)
4b19f77a 1345 Imager::Font::TT handle
02d1d628
AMH
1346 Imager::ImgRaw im
1347 int xb
1348 int yb
1349 int channel
1350 float points
1351 char* str
1352 int len
1353 int smooth
1354
1355
1356
1357undef_int
1358i_tt_bbox(handle,point,str,len)
4b19f77a 1359 Imager::Font::TT handle
02d1d628
AMH
1360 float point
1361 char* str
1362 int len
1363 PREINIT:
1364 int cords[6],rc;
1365 PPCODE:
1366 if ((rc=i_tt_bbox(handle,point,str,len,cords))) {
1367 EXTEND(SP, 4);
1368 PUSHs(sv_2mortal(newSViv(cords[0])));
1369 PUSHs(sv_2mortal(newSViv(cords[1])));
1370 PUSHs(sv_2mortal(newSViv(cords[2])));
1371 PUSHs(sv_2mortal(newSViv(cords[3])));
1372 PUSHs(sv_2mortal(newSViv(cords[4])));
1373 PUSHs(sv_2mortal(newSViv(cords[5])));
1374 }
1375
1376
1377#endif
1378
1379
1380
1381
1382#ifdef HAVE_LIBJPEG
1383undef_int
dd55acc8 1384i_writejpeg_wiol(im, ig, qfactor)
02d1d628 1385 Imager::ImgRaw im
dd55acc8 1386 Imager::IO ig
02d1d628
AMH
1387 int qfactor
1388
02d1d628
AMH
1389
1390void
1391i_readjpeg_wiol(ig)
1392 Imager::IO ig
1393 PREINIT:
1394 char* iptc_itext;
1395 int tlength;
1396 i_img* rimg;
1397 SV* r;
1398 PPCODE:
1399 iptc_itext = NULL;
1400 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1401 if (iptc_itext == NULL) {
1402 r = sv_newmortal();
1403 EXTEND(SP,1);
1404 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1405 PUSHs(r);
1406 } else {
1407 r = sv_newmortal();
1408 EXTEND(SP,2);
1409 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1410 PUSHs(r);
1411 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1412 myfree(iptc_itext);
1413 }
1414
1415
1416#endif
1417
1418
1419
1420
1421#ifdef HAVE_LIBTIFF
1422
1423Imager::ImgRaw
1424i_readtiff_wiol(ig, length)
1425 Imager::IO ig
1426 int length
1427
1428
1429undef_int
1430i_writetiff_wiol(im, ig)
1431 Imager::ImgRaw im
1432 Imager::IO ig
1433
d2dfdcc9 1434undef_int
4c2d6970 1435i_writetiff_wiol_faxable(im, ig, fine)
d2dfdcc9
TC
1436 Imager::ImgRaw im
1437 Imager::IO ig
4c2d6970 1438 int fine
d2dfdcc9 1439
02d1d628
AMH
1440
1441#endif /* HAVE_LIBTIFF */
1442
1443
1444
1445
1446
1447#ifdef HAVE_LIBPNG
1448
1449Imager::ImgRaw
790923a4
AMH
1450i_readpng_wiol(ig, length)
1451 Imager::IO ig
1452 int length
02d1d628
AMH
1453
1454
1455undef_int
790923a4 1456i_writepng_wiol(im, ig)
02d1d628 1457 Imager::ImgRaw im
790923a4 1458 Imager::IO ig
02d1d628
AMH
1459
1460
1461#endif
1462
1463
1464#ifdef HAVE_LIBGIF
1465
03bd24d4
TC
1466void
1467i_giflib_version()
1468 PPCODE:
1469 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
1470
02d1d628
AMH
1471undef_int
1472i_writegif(im,fd,colors,pixdev,fixed)
1473 Imager::ImgRaw im
1474 int fd
1475 int colors
1476 int pixdev
1477 PREINIT:
1478 int fixedlen;
1479 Imager__Color fixed;
1480 Imager__Color tmp;
1481 AV* av;
1482 SV* sv1;
1483 IV Itmp;
1484 int i;
1485 CODE:
1486 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
1487 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1488 av=(AV*)SvRV(ST(4));
1489 fixedlen=av_len(av)+1;
1490 fixed=mymalloc( fixedlen*sizeof(i_color) );
1491 for(i=0;i<fixedlen;i++) {
1492 sv1=(*(av_fetch(av,i,0)));
1493 if (sv_derived_from(sv1, "Imager::Color")) {
1494 Itmp = SvIV((SV*)SvRV(sv1));
1495 tmp = (i_color*) Itmp;
1496 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
1497 fixed[i]=*tmp;
1498 }
1499 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
1500 myfree(fixed);
1501 ST(0) = sv_newmortal();
1502 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1503 else sv_setiv(ST(0), (IV)RETVAL);
1504
1505
1506
1507
1508undef_int
1509i_writegifmc(im,fd,colors)
067d6bdc 1510 Imager::ImgRaw im
02d1d628
AMH
1511 int fd
1512 int colors
1513
02d1d628
AMH
1514
1515undef_int
1516i_writegif_gen(fd, ...)
1517 int fd
1518 PROTOTYPE: $$@
1519 PREINIT:
1520 i_quantize quant;
1521 i_gif_opts opts;
1522 i_img **imgs = NULL;
1523 int img_count;
1524 int i;
1525 HV *hv;
1526 CODE:
1527 if (items < 3)
1528 croak("Usage: i_writegif_gen(fd,hashref, images...)");
1529 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1530 croak("i_writegif_gen: Second argument must be a hash ref");
1531 hv = (HV *)SvRV(ST(1));
1532 memset(&quant, 0, sizeof(quant));
1533 quant.mc_size = 256;
02d1d628
AMH
1534 memset(&opts, 0, sizeof(opts));
1535 handle_quant_opts(&quant, hv);
1536 handle_gif_opts(&opts, hv);
1537 img_count = items - 2;
1538 RETVAL = 1;
1539 if (img_count < 1) {
1540 RETVAL = 0;
95b44a76
TC
1541 i_clear_error();
1542 i_push_error(0, "You need to specify images to save");
02d1d628
AMH
1543 }
1544 else {
1545 imgs = mymalloc(sizeof(i_img *) * img_count);
1546 for (i = 0; i < img_count; ++i) {
1547 SV *sv = ST(2+i);
1548 imgs[i] = NULL;
1549 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1550 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1551 }
1552 else {
95b44a76
TC
1553 i_clear_error();
1554 i_push_error(0, "Only images can be saved");
02d1d628
AMH
1555 RETVAL = 0;
1556 break;
1557 }
1558 }
1559 if (RETVAL) {
1560 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count, &opts);
1561 }
1562 myfree(imgs);
1563 if (RETVAL) {
1564 copy_colors_back(hv, &quant);
1565 }
1566 }
a73aeb5f
AMH
1567 ST(0) = sv_newmortal();
1568 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1569 else sv_setiv(ST(0), (IV)RETVAL);
46a04ceb
TC
1570 cleanup_gif_opts(&opts);
1571 cleanup_quant_opts(&quant);
a73aeb5f 1572
02d1d628
AMH
1573
1574undef_int
1575i_writegif_callback(cb, maxbuffer,...)
1576 int maxbuffer;
1577 PREINIT:
1578 i_quantize quant;
1579 i_gif_opts opts;
1580 i_img **imgs = NULL;
1581 int img_count;
1582 int i;
1583 HV *hv;
1584 i_writer_data wd;
1585 CODE:
1586 if (items < 4)
1587 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
1588 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1589 croak("i_writegif_callback: Second argument must be a hash ref");
1590 hv = (HV *)SvRV(ST(2));
1591 memset(&quant, 0, sizeof(quant));
1592 quant.mc_size = 256;
02d1d628
AMH
1593 memset(&opts, 0, sizeof(opts));
1594 handle_quant_opts(&quant, hv);
1595 handle_gif_opts(&opts, hv);
1596 img_count = items - 3;
1597 RETVAL = 1;
1598 if (img_count < 1) {
1599 RETVAL = 0;
1600 }
1601 else {
1602 imgs = mymalloc(sizeof(i_img *) * img_count);
1603 for (i = 0; i < img_count; ++i) {
1604 SV *sv = ST(3+i);
1605 imgs[i] = NULL;
1606 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1607 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1608 }
1609 else {
1610 RETVAL = 0;
1611 break;
1612 }
1613 }
1614 if (RETVAL) {
1615 wd.sv = ST(0);
1616 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count, &opts);
1617 }
1618 myfree(imgs);
1619 if (RETVAL) {
1620 copy_colors_back(hv, &quant);
1621 }
1622 }
46a04ceb
TC
1623 ST(0) = sv_newmortal();
1624 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1625 else sv_setiv(ST(0), (IV)RETVAL);
1626 cleanup_gif_opts(&opts);
1627 cleanup_quant_opts(&quant);
02d1d628
AMH
1628
1629void
1630i_readgif(fd)
1631 int fd
1632 PREINIT:
1633 int* colour_table;
1634 int colours, q, w;
1635 i_img* rimg;
1636 SV* temp[3];
1637 AV* ct;
1638 SV* r;
1639 PPCODE:
1640 colour_table = NULL;
1641 colours = 0;
1642
895dbd34 1643 if(GIMME_V == G_ARRAY) {
02d1d628
AMH
1644 rimg = i_readgif(fd,&colour_table,&colours);
1645 } else {
1646 /* don't waste time with colours if they aren't wanted */
1647 rimg = i_readgif(fd,NULL,NULL);
1648 }
895dbd34 1649
02d1d628
AMH
1650 if (colour_table == NULL) {
1651 EXTEND(SP,1);
1652 r=sv_newmortal();
1653 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1654 PUSHs(r);
1655 } else {
1656 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1657 /* I don't know if I have the reference counts right or not :( */
1658 /* Neither do I :-) */
1659 /* No Idea here either */
1660
1661 ct=newAV();
1662 av_extend(ct, colours);
1663 for(q=0; q<colours; q++) {
1664 for(w=0; w<3; w++)
1665 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1666 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1667 }
1668 myfree(colour_table);
895dbd34 1669
02d1d628 1670 EXTEND(SP,2);
895dbd34 1671 r = sv_newmortal();
02d1d628
AMH
1672 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1673 PUSHs(r);
1674 PUSHs(newRV_noinc((SV*)ct));
1675 }
1676
1677
1678
1679
1680
1681void
1682i_readgif_scalar(...)
1683 PROTOTYPE: $
1684 PREINIT:
1685 char* data;
1686 unsigned int length;
1687 int* colour_table;
1688 int colours, q, w;
1689 i_img* rimg;
1690 SV* temp[3];
1691 AV* ct;
1692 SV* r;
1693 PPCODE:
1694 data = (char *)SvPV(ST(0), length);
1695 colour_table=NULL;
1696 colours=0;
1697
1698 if(GIMME_V == G_ARRAY) {
1699 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
1700 } else {
1701 /* don't waste time with colours if they aren't wanted */
1702 rimg=i_readgif_scalar(data,length,NULL,NULL);
1703 }
1704
1705 if (colour_table == NULL) {
1706 EXTEND(SP,1);
1707 r=sv_newmortal();
1708 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1709 PUSHs(r);
1710 } else {
1711 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1712 /* I don't know if I have the reference counts right or not :( */
1713 /* Neither do I :-) */
1714 ct=newAV();
1715 av_extend(ct, colours);
1716 for(q=0; q<colours; q++) {
1717 for(w=0; w<3; w++)
1718 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1719 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1720 }
1721 myfree(colour_table);
1722
1723 EXTEND(SP,2);
1724 r=sv_newmortal();
1725 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1726 PUSHs(r);
1727 PUSHs(newRV_noinc((SV*)ct));
1728 }
1729
1730void
1731i_readgif_callback(...)
1732 PROTOTYPE: &
1733 PREINIT:
1734 char* data;
1735 int length;
1736 int* colour_table;
1737 int colours, q, w;
1738 i_img* rimg;
1739 SV* temp[3];
1740 AV* ct;
1741 SV* r;
1742 i_reader_data rd;
1743 PPCODE:
1744 rd.sv = ST(0);
1745 colour_table=NULL;
1746 colours=0;
1747
1748 if(GIMME_V == G_ARRAY) {
1749 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
1750 } else {
1751 /* don't waste time with colours if they aren't wanted */
1752 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
1753 }
1754
1755 if (colour_table == NULL) {
1756 EXTEND(SP,1);
1757 r=sv_newmortal();
1758 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1759 PUSHs(r);
1760 } else {
1761 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1762 /* I don't know if I have the reference counts right or not :( */
1763 /* Neither do I :-) */
1764 /* Neither do I - maybe I'll move this somewhere */
1765 ct=newAV();
1766 av_extend(ct, colours);
1767 for(q=0; q<colours; q++) {
1768 for(w=0; w<3; w++)
1769 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1770 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1771 }
1772 myfree(colour_table);
1773
1774 EXTEND(SP,2);
1775 r=sv_newmortal();
1776 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1777 PUSHs(r);
1778 PUSHs(newRV_noinc((SV*)ct));
1779 }
1780
faa9b3e7
TC
1781void
1782i_readgif_multi(fd)
1783 int fd
1784 PREINIT:
1785 i_img **imgs;
1786 int count;
1787 int i;
1788 PPCODE:
1789 imgs = i_readgif_multi(fd, &count);
1790 if (imgs) {
1791 EXTEND(SP, count);
1792 for (i = 0; i < count; ++i) {
1793 SV *sv = sv_newmortal();
1794 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1795 PUSHs(sv);
1796 }
1797 myfree(imgs);
1798 }
02d1d628 1799
faa9b3e7
TC
1800void
1801i_readgif_multi_scalar(data)
1802 PREINIT:
1803 i_img **imgs;
1804 int count;
1805 char *data;
1806 unsigned int length;
1807 int i;
1808 PPCODE:
1809 data = (char *)SvPV(ST(0), length);
1810 imgs = i_readgif_multi_scalar(data, length, &count);
1811 if (imgs) {
1812 EXTEND(SP, count);
1813 for (i = 0; i < count; ++i) {
1814 SV *sv = sv_newmortal();
1815 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1816 PUSHs(sv);
1817 }
1818 myfree(imgs);
1819 }
02d1d628 1820
faa9b3e7
TC
1821void
1822i_readgif_multi_callback(cb)
1823 PREINIT:
1824 i_reader_data rd;
1825 i_img **imgs;
1826 int count;
1827 int i;
1828 PPCODE:
1829 rd.sv = ST(0);
1830 imgs = i_readgif_multi_callback(read_callback, (char *)&rd, &count);
1831 if (imgs) {
1832 EXTEND(SP, count);
1833 for (i = 0; i < count; ++i) {
1834 SV *sv = sv_newmortal();
1835 sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
1836 PUSHs(sv);
1837 }
1838 myfree(imgs);
1839 }
02d1d628
AMH
1840
1841#endif
1842
1843
1844
1845Imager::ImgRaw
1846i_readpnm_wiol(ig, length)
1847 Imager::IO ig
1848 int length
1849
1850
067d6bdc
AMH
1851undef_int
1852i_writeppm_wiol(im, ig)
1853 Imager::ImgRaw im
1854 Imager::IO ig
1855
1856
02d1d628 1857Imager::ImgRaw
895dbd34
AMH
1858i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
1859 Imager::IO ig
02d1d628
AMH
1860 int x
1861 int y
1862 int datachannels
1863 int storechannels
1864 int intrl
1865
1866undef_int
895dbd34 1867i_writeraw_wiol(im,ig)
02d1d628 1868 Imager::ImgRaw im
895dbd34
AMH
1869 Imager::IO ig
1870
261f91c5
TC
1871undef_int
1872i_writebmp_wiol(im,ig)
1873 Imager::ImgRaw im
1874 Imager::IO ig
02d1d628 1875
705fd961
TC
1876Imager::ImgRaw
1877i_readbmp_wiol(ig)
1878 Imager::IO ig
1879
1ec86afa
AMH
1880
1881undef_int
febba01f 1882i_writetga_wiol(im,ig, wierdpack, compress, idstring)
1ec86afa
AMH
1883 Imager::ImgRaw im
1884 Imager::IO ig
febba01f
AMH
1885 int wierdpack
1886 int compress
1887 char* idstring
1888 PREINIT:
1889 SV* sv1;
1890 int rc;
1891 int idlen;
1892 CODE:
1893 idlen = SvCUR(ST(4));
1894 RETVAL = i_writetga_wiol(im, ig, wierdpack, compress, idstring, idlen);
1895 OUTPUT:
1896 RETVAL
1897
1ec86afa
AMH
1898
1899Imager::ImgRaw
1900i_readtga_wiol(ig, length)
1901 Imager::IO ig
1902 int length
1903
1904
737a830c
AMH
1905undef_int
1906i_writergb_wiol(im,ig, wierdpack, compress, idstring)
1907 Imager::ImgRaw im
1908 Imager::IO ig
1909 int wierdpack
1910 int compress
1911 char* idstring
1912 PREINIT:
1913 SV* sv1;
1914 int rc;
1915 int idlen;
1916 CODE:
1917 idlen = SvCUR(ST(4));
1918 RETVAL = i_writergb_wiol(im, ig, wierdpack, compress, idstring, idlen);
1919 OUTPUT:
1920 RETVAL
1921
1922
1923Imager::ImgRaw
1924i_readrgb_wiol(ig, length)
1925 Imager::IO ig
1926 int length
1927
1928
1929
02d1d628
AMH
1930Imager::ImgRaw
1931i_scaleaxis(im,Value,Axis)
1932 Imager::ImgRaw im
1933 float Value
1934 int Axis
1935
1936Imager::ImgRaw
1937i_scale_nn(im,scx,scy)
1938 Imager::ImgRaw im
1939 float scx
1940 float scy
1941
1942Imager::ImgRaw
1943i_haar(im)
1944 Imager::ImgRaw im
1945
1946int
1947i_count_colors(im,maxc)
1948 Imager::ImgRaw im
1949 int maxc
1950
1951
1952Imager::ImgRaw
1953i_transform(im,opx,opy,parm)
1954 Imager::ImgRaw im
1955 PREINIT:
1956 double* parm;
1957 int* opx;
1958 int* opy;
1959 int opxl;
1960 int opyl;
1961 int parmlen;
1962 AV* av;
1963 SV* sv1;
1964 int i;
1965 CODE:
1966 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1967 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1968 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1969 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1970 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1971 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1972 av=(AV*)SvRV(ST(1));
1973 opxl=av_len(av)+1;
1974 opx=mymalloc( opxl*sizeof(int) );
1975 for(i=0;i<opxl;i++) {
1976 sv1=(*(av_fetch(av,i,0)));
1977 opx[i]=(int)SvIV(sv1);
1978 }
1979 av=(AV*)SvRV(ST(2));
1980 opyl=av_len(av)+1;
1981 opy=mymalloc( opyl*sizeof(int) );
1982 for(i=0;i<opyl;i++) {
1983 sv1=(*(av_fetch(av,i,0)));
1984 opy[i]=(int)SvIV(sv1);
1985 }
1986 av=(AV*)SvRV(ST(3));
1987 parmlen=av_len(av)+1;
1988 parm=mymalloc( parmlen*sizeof(double) );
1989 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1990 sv1=(*(av_fetch(av,i,0)));
1991 parm[i]=(double)SvNV(sv1);
1992 }
1993 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1994 myfree(parm);
1995 myfree(opy);
1996 myfree(opx);
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
2001Imager::ImgRaw
2002i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
2003 PREINIT:
2004 int width;
2005 int height;
2006 double* parm;
2007 struct rm_op *ops;
953209f8 2008 STRLEN ops_len;
02d1d628
AMH
2009 int ops_count;
2010 double *n_regs;
2011 int n_regs_count;
2012 i_color *c_regs;
2013 int c_regs_count;
2014 int in_imgs_count;
2015 i_img **in_imgs;
2016 AV* av;
2017 SV* sv1;
2018 IV tmp;
2019 int i;
2020 CODE:
2021 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
2022 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
2023 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
2024 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2025 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2026
2027 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2028
2029 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2030 av = (AV*)SvRV(ST(5));
2031 in_imgs_count = av_len(av)+1;
2032 for (i = 0; i < in_imgs_count; ++i) {
2033 sv1 = *av_fetch(av, i, 0);
2034 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2035 croak("Parameter 5 must contain only images");
2036 }
2037 }
2038 }
2039 else {
2040 in_imgs_count = 0;
2041 }
b8c2033e 2042 if (in_imgs_count > 0) {
02d1d628
AMH
2043 av = (AV*)SvRV(ST(5));
2044 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2045 for (i = 0; i < in_imgs_count; ++i) {
2046 sv1 = *av_fetch(av,i,0);
2047 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2048 croak("Parameter 5 must contain only images");
2049 }
2050 tmp = SvIV((SV*)SvRV(sv1));
2051 in_imgs[i] = (i_img*)tmp;
2052 }
2053 }
2054 else {
2055 /* no input images */
2056 in_imgs = NULL;
2057 }
2058 /* default the output size from the first input if possible */
2059 if (SvOK(ST(0)))
2060 width = SvIV(ST(0));
2061 else if (in_imgs_count)
2062 width = in_imgs[0]->xsize;
2063 else
2064 croak("No output image width supplied");
2065
2066 if (SvOK(ST(1)))
2067 height = SvIV(ST(1));
2068 else if (in_imgs_count)
2069 height = in_imgs[0]->ysize;
2070 else
2071 croak("No output image height supplied");
2072
2073 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2074 if (ops_len % sizeof(struct rm_op))
2075 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2076 ops_count = ops_len / sizeof(struct rm_op);
2077 av = (AV*)SvRV(ST(3));
2078 n_regs_count = av_len(av)+1;
2079 n_regs = mymalloc(n_regs_count * sizeof(double));
2080 for (i = 0; i < n_regs_count; ++i) {
2081 sv1 = *av_fetch(av,i,0);
2082 if (SvOK(sv1))
2083 n_regs[i] = SvNV(sv1);
2084 }
2085 av = (AV*)SvRV(ST(4));
2086 c_regs_count = av_len(av)+1;
2087 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2088 /* I don't bother initializing the colou?r registers */
2089
2090 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2091 n_regs, n_regs_count,
2092 c_regs, c_regs_count, in_imgs, in_imgs_count);
2093 if (in_imgs)
2094 myfree(in_imgs);
2095 myfree(n_regs);
2096 myfree(c_regs);
2097 ST(0) = sv_newmortal();
2098 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2099 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2100
2101
2102void
2103i_contrast(im,intensity)
2104 Imager::ImgRaw im
2105 float intensity
2106
2107void
2108i_hardinvert(im)
2109 Imager::ImgRaw im
2110
2111void
2112i_noise(im,amount,type)
2113 Imager::ImgRaw im
2114 float amount
2115 unsigned char type
2116
2117void
2118i_bumpmap(im,bump,channel,light_x,light_y,strength)
2119 Imager::ImgRaw im
2120 Imager::ImgRaw bump
2121 int channel
2122 int light_x
2123 int light_y
2124 int strength
2125
b2778574
AMH
2126
2127void
2128i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2129 Imager::ImgRaw im
2130 Imager::ImgRaw bump
2131 int channel
2132 int tx
2133 int ty
2134 float Lx
2135 float Ly
2136 float Lz
2137 float cd
2138 float cs
2139 float n
2140 Imager::Color Ia
2141 Imager::Color Il
2142 Imager::Color Is
2143
2144
2145
02d1d628
AMH
2146void
2147i_postlevels(im,levels)
2148 Imager::ImgRaw im
2149 int levels
2150
2151void
2152i_mosaic(im,size)
2153 Imager::ImgRaw im
2154 int size
2155
2156void
2157i_watermark(im,wmark,tx,ty,pixdiff)
2158 Imager::ImgRaw im
2159 Imager::ImgRaw wmark
2160 int tx
2161 int ty
2162 int pixdiff
2163
2164
2165void
2166i_autolevels(im,lsat,usat,skew)
2167 Imager::ImgRaw im
2168 float lsat
2169 float usat
2170 float skew
2171
2172void
2173i_radnoise(im,xo,yo,rscale,ascale)
2174 Imager::ImgRaw im
2175 float xo
2176 float yo
2177 float rscale
2178 float ascale
2179
2180void
2181i_turbnoise(im, xo, yo, scale)
2182 Imager::ImgRaw im
2183 float xo
2184 float yo
2185 float scale
2186
2187
2188void
2189i_gradgen(im, ...)
2190 Imager::ImgRaw im
2191 PREINIT:
2192 int num;
2193 int *xo;
2194 int *yo;
2195 i_color *ival;
2196 int dmeasure;
2197 int i;
2198 SV *sv;
2199 AV *axx;
2200 AV *ayy;
2201 AV *ac;
2202 CODE:
2203 if (items != 5)
2204 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2205 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2206 croak("i_gradgen: Second argument must be an array ref");
2207 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2208 croak("i_gradgen: Third argument must be an array ref");
2209 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2210 croak("i_gradgen: Fourth argument must be an array ref");
2211 axx = (AV *)SvRV(ST(1));
2212 ayy = (AV *)SvRV(ST(2));
2213 ac = (AV *)SvRV(ST(3));
2214 dmeasure = (int)SvIV(ST(4));
2215
2216 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2217 num = num <= av_len(ac) ? num : av_len(ac);
2218 num++;
2219 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2220 xo = mymalloc( sizeof(int) * num );
2221 yo = mymalloc( sizeof(int) * num );
2222 ival = mymalloc( sizeof(i_color) * num );
2223 for(i = 0; i<num; i++) {
2224 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2225 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2226 sv = *av_fetch(ac, i, 0);
2227 if ( !sv_derived_from(sv, "Imager::Color") ) {
2228 free(axx); free(ayy); free(ac);
2229 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2230 }
2231 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2232 }
2233 i_gradgen(im, num, xo, yo, ival, dmeasure);
a73aeb5f
AMH
2234 myfree(xo);
2235 myfree(yo);
2236 myfree(ival);
2237
02d1d628 2238
6607600c
TC
2239void
2240i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2241 Imager::ImgRaw im
2242 double xa
2243 double ya
2244 double xb
2245 double yb
2246 int type
2247 int repeat
2248 int combine
2249 int super_sample
2250 double ssample_param
2251 PREINIT:
6607600c 2252 AV *asegs;
6607600c
TC
2253 int count;
2254 i_fountain_seg *segs;
6607600c 2255 CODE:
6607600c
TC
2256 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2257 croak("i_fountain: argument 11 must be an array ref");
2258
2259 asegs = (AV *)SvRV(ST(10));
f1ac5027 2260 segs = load_fount_segs(asegs, &count);
6607600c
TC
2261 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
2262 ssample_param, count, segs);
2263 myfree(segs);
02d1d628 2264
f1ac5027
TC
2265Imager::FillHandle
2266i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2267 double xa
2268 double ya
2269 double xb
2270 double yb
2271 int type
2272 int repeat
2273 int combine
2274 int super_sample
2275 double ssample_param
2276 PREINIT:
2277 AV *asegs;
2278 int count;
2279 i_fountain_seg *segs;
2280 CODE:
2281 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2282 croak("i_fountain: argument 11 must be an array ref");
2283
2284 asegs = (AV *)SvRV(ST(9));
2285 segs = load_fount_segs(asegs, &count);
2286 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2287 super_sample, ssample_param, count, segs);
2288 myfree(segs);
2289 OUTPUT:
2290 RETVAL
2291
4f4f776a
TC
2292void
2293i_errors()
2294 PREINIT:
2295 i_errmsg *errors;
2296 int i;
4f4f776a
TC
2297 AV *av;
2298 SV *ref;
2299 SV *sv;
2300 PPCODE:
2301 errors = i_errors();
2302 i = 0;
2303 while (errors[i].msg) {
2304 av = newAV();
2305 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2306 if (!av_store(av, 0, sv)) {
2307 SvREFCNT_dec(sv);
2308 }
2309 sv = newSViv(errors[i].code);
2310 if (!av_store(av, 1, sv)) {
2311 SvREFCNT_dec(sv);
2312 }
2313 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2314 ++i;
2315 }
02d1d628
AMH
2316
2317void
2318i_nearest_color(im, ...)
2319 Imager::ImgRaw im
2320 PREINIT:
2321 int num;
2322 int *xo;
2323 int *yo;
2324 i_color *ival;
2325 int dmeasure;
2326 int i;
2327 SV *sv;
2328 AV *axx;
2329 AV *ayy;
2330 AV *ac;
2331 CODE:
2332 if (items != 5)
2333 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2334 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2335 croak("i_nearest_color: Second argument must be an array ref");
2336 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2337 croak("i_nearest_color: Third argument must be an array ref");
2338 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2339 croak("i_nearest_color: Fourth argument must be an array ref");
2340 axx = (AV *)SvRV(ST(1));
2341 ayy = (AV *)SvRV(ST(2));
2342 ac = (AV *)SvRV(ST(3));
2343 dmeasure = (int)SvIV(ST(4));
2344
2345 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2346 num = num <= av_len(ac) ? num : av_len(ac);
2347 num++;
2348 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2349 xo = mymalloc( sizeof(int) * num );
2350 yo = mymalloc( sizeof(int) * num );
2351 ival = mymalloc( sizeof(i_color) * num );
2352 for(i = 0; i<num; i++) {
2353 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2354 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2355 sv = *av_fetch(ac, i, 0);
2356 if ( !sv_derived_from(sv, "Imager::Color") ) {
2357 free(axx); free(ayy); free(ac);
2358 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2359 }
2360 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2361 }
2362 i_nearest_color(im, num, xo, yo, ival, dmeasure);
2363
2364
2365
2366
2367void
2368malloc_state()
2369
2370void
2371hashinfo(hv)
2372 PREINIT:
2373 HV* hv;
2374 int stuff;
2375 PPCODE:
2376 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
2377 hv=(HV*)SvRV(ST(0));
2378 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
2379 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2380 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2381
2382void
2383DSO_open(filename)
2384 char* filename
2385 PREINIT:
2386 void *rc;
2387 char *evstr;
2388 PPCODE:
2389 rc=DSO_open(filename,&evstr);
2390 if (rc!=NULL) {
2391 if (evstr!=NULL) {
2392 EXTEND(SP,2);
2393 PUSHs(sv_2mortal(newSViv((IV)rc)));
2394 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2395 } else {
2396 EXTEND(SP,1);
2397 PUSHs(sv_2mortal(newSViv((IV)rc)));
2398 }
2399 }
2400
2401
2402undef_int
2403DSO_close(dso_handle)
2404 void* dso_handle
2405
2406void
2407DSO_funclist(dso_handle_v)
2408 void* dso_handle_v
2409 PREINIT:
2410 int i;
2411 DSO_handle *dso_handle;
2412 PPCODE:
2413 dso_handle=(DSO_handle*)dso_handle_v;
2414 i=0;
2415 while( dso_handle->function_list[i].name != NULL) {
2416 EXTEND(SP,1);
2417 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
2418 EXTEND(SP,1);
2419 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
2420 }
2421
2422
2423void
2424DSO_call(handle,func_index,hv)
2425 void* handle
2426 int func_index
2427 PREINIT:
2428 HV* hv;
2429 PPCODE:
2430 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2431 hv=(HV*)SvRV(ST(2));
2432 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2433 DSO_call( (DSO_handle *)handle,func_index,hv);
2434
2435
2436
f5991c03 2437# this is mostly for testing...
faa9b3e7 2438SV *
f5991c03
TC
2439i_get_pixel(im, x, y)
2440 Imager::ImgRaw im
2441 int x
2442 int y;
faa9b3e7
TC
2443 PREINIT:
2444 i_color *color;
2445 CODE:
2446 color = (i_color *)mymalloc(sizeof(i_color));
2447 if (i_gpix(im, x, y, color) == 0) {
2448 ST(0) = sv_newmortal();
2449 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
2450 }
2451 else {
2452 myfree(color);
2453 ST(0) = &PL_sv_undef;
2454 }
2455
2456
2457int
2458i_ppix(im, x, y, cl)
2459 Imager::ImgRaw im
2460 int x
2461 int y
2462 Imager::Color cl
2463
2464Imager::ImgRaw
2465i_img_pal_new(x, y, channels, maxpal)
2466 int x
2467 int y
2468 int channels
2469 int maxpal
2470
2471Imager::ImgRaw
2472i_img_to_pal(src, quant)
2473 Imager::ImgRaw src
2474 PREINIT:
2475 HV *hv;
2476 i_quantize quant;
2477 CODE:
2478 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2479 croak("i_img_to_pal: second argument must be a hash ref");
2480 hv = (HV *)SvRV(ST(1));
2481 memset(&quant, 0, sizeof(quant));
2482 quant.mc_size = 256;
faa9b3e7
TC
2483 handle_quant_opts(&quant, hv);
2484 RETVAL = i_img_to_pal(src, &quant);
2485 if (RETVAL) {
2486 copy_colors_back(hv, &quant);
2487 }
46a04ceb 2488 cleanup_quant_opts(&quant);
faa9b3e7
TC
2489 OUTPUT:
2490 RETVAL
2491
2492Imager::ImgRaw
2493i_img_to_rgb(src)
2494 Imager::ImgRaw src
2495
2496void
2497i_gpal(im, l, r, y)
2498 Imager::ImgRaw im
2499 int l
2500 int r
2501 int y
2502 PREINIT:
2503 i_palidx *work;
2504 int count, i;
2505 PPCODE:
2506 if (l < r) {
2507 work = mymalloc((r-l) * sizeof(i_palidx));
2508 count = i_gpal(im, l, r, y, work);
2509 if (GIMME_V == G_ARRAY) {
2510 EXTEND(SP, count);
2511 for (i = 0; i < count; ++i) {
2512 PUSHs(sv_2mortal(newSViv(work[i])));
2513 }
2514 }
2515 else {
2516 EXTEND(SP, 1);
2517 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
2518 }
2519 myfree(work);
2520 }
2521 else {
2522 if (GIMME_V != G_ARRAY) {
2523 EXTEND(SP, 1);
2524 PUSHs(&PL_sv_undef);
2525 }
2526 }
2527
2528int
2529i_ppal(im, l, y, ...)
2530 Imager::ImgRaw im
2531 int l
2532 int y
2533 PREINIT:
2534 i_palidx *work;
2535 int count, i;
2536 CODE:
2537 if (items > 3) {
2538 work = mymalloc(sizeof(i_palidx) * (items-3));
2539 for (i=0; i < items-3; ++i) {
2540 work[i] = SvIV(ST(i+3));
2541 }
2542 RETVAL = i_ppal(im, l, l+items-3, y, work);
2543 myfree(work);
2544 }
2545 else {
2546 RETVAL = 0;
2547 }
2548 OUTPUT:
2549 RETVAL
2550
2551SV *
2552i_addcolors(im, ...)
2553 Imager::ImgRaw im
2554 PREINIT:
2555 int index;
2556 i_color *colors;
2557 int i;
2558 CODE:
2559 if (items < 2)
2560 croak("i_addcolors: no colors to add");
2561 colors = mymalloc((items-1) * sizeof(i_color));
2562 for (i=0; i < items-1; ++i) {
2563 if (sv_isobject(ST(i+1))
2564 && sv_derived_from(ST(i+1), "Imager::Color")) {
2565 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2566 colors[i] = *(i_color *)tmp;
2567 }
2568 else {
2569 myfree(colors);
2570 croak("i_plin: pixels must be Imager::Color objects");
2571 }
2572 }
2573 index = i_addcolors(im, colors, items-1);
2574 myfree(colors);
2575 if (index == 0) {
2576 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2577 }
2578 else if (index == -1) {
2579 ST(0) = &PL_sv_undef;
2580 }
2581 else {
2582 ST(0) = sv_2mortal(newSViv(index));
2583 }
2584
2585int
2586i_setcolors(im, index, ...)
2587 Imager::ImgRaw im
2588 int index
2589 PREINIT:
2590 i_color *colors;
2591 int i;
2592 CODE:
2593 if (items < 3)
2594 croak("i_setcolors: no colors to add");
2595 colors = mymalloc((items-2) * sizeof(i_color));
2596 for (i=0; i < items-2; ++i) {
2597 if (sv_isobject(ST(i+2))
2598 && sv_derived_from(ST(i+2), "Imager::Color")) {
2599 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
2600 colors[i] = *(i_color *)tmp;
2601 }
2602 else {
2603 myfree(colors);
2604 croak("i_setcolors: pixels must be Imager::Color objects");
2605 }
2606 }
2607 RETVAL = i_setcolors(im, index, colors, items-2);
2608 myfree(colors);
2609
2610void
2611i_getcolors(im, index, ...)
2612 Imager::ImgRaw im
2613 int index
2614 PREINIT:
2615 i_color *colors;
2616 int count = 1;
2617 int i;
2618 PPCODE:
2619 if (items > 3)
2620 croak("i_getcolors: too many arguments");
2621 if (items == 3)
2622 count = SvIV(ST(2));
2623 if (count < 1)
2624 croak("i_getcolors: count must be positive");
2625 colors = mymalloc(sizeof(i_color) * count);
2626 if (i_getcolors(im, index, colors, count)) {
2627 for (i = 0; i < count; ++i) {
2628 i_color *pv;
2629 SV *sv = sv_newmortal();
2630 pv = mymalloc(sizeof(i_color));
2631 *pv = colors[i];
2632 sv_setref_pv(sv, "Imager::Color", (void *)pv);
2633 PUSHs(sv);
2634 }
2635 }
2636 myfree(colors);
2637
2638
2639SV *
2640i_colorcount(im)
2641 Imager::ImgRaw im
2642 PREINIT:
2643 int count;
2644 CODE:
2645 count = i_colorcount(im);
2646 if (count >= 0) {
2647 ST(0) = sv_2mortal(newSViv(count));
2648 }
2649 else {
2650 ST(0) = &PL_sv_undef;
2651 }
2652
2653SV *
2654i_maxcolors(im)
2655 Imager::ImgRaw im
2656 PREINIT:
2657 int count;
2658 CODE:
2659 count = i_maxcolors(im);
2660 if (count >= 0) {
2661 ST(0) = sv_2mortal(newSViv(count));
2662 }
2663 else {
2664 ST(0) = &PL_sv_undef;
2665 }
2666
2667SV *
2668i_findcolor(im, color)
2669 Imager::ImgRaw im
2670 Imager::Color color
2671 PREINIT:
2672 i_palidx index;
2673 CODE:
2674 if (i_findcolor(im, color, &index)) {
2675 ST(0) = sv_2mortal(newSViv(index));
2676 }
2677 else {
2678 ST(0) = &PL_sv_undef;
2679 }
2680
2681int
2682i_img_bits(im)
2683 Imager::ImgRaw im
2684
2685int
2686i_img_type(im)
2687 Imager::ImgRaw im
2688
2689int
2690i_img_virtual(im)
2691 Imager::ImgRaw im
2692
2693void
2694i_gsamp(im, l, r, y, ...)
2695 Imager::ImgRaw im
2696 int l
2697 int r
2698 int y
2699 PREINIT:
2700 int *chans;
2701 int chan_count;
2702 i_sample_t *data;
2703 int count, i;
2704 PPCODE:
2705 if (items < 5)
2706 croak("No channel numbers supplied to g_samp()");
2707 if (l < r) {
2708 chan_count = items - 4;
2709 chans = mymalloc(sizeof(int) * chan_count);
2710 for (i = 0; i < chan_count; ++i)
2711 chans[i] = SvIV(ST(i+4));
4dfa5522 2712 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
faa9b3e7 2713 count = i_gsamp(im, l, r, y, data, chans, chan_count);
4dfa5522 2714 myfree(chans);
faa9b3e7
TC
2715 if (GIMME_V == G_ARRAY) {
2716 EXTEND(SP, count);
2717 for (i = 0; i < count; ++i)
2718 PUSHs(sv_2mortal(newSViv(data[i])));
2719 }
2720 else {
2721 EXTEND(SP, 1);
2722 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
2723 }
a73aeb5f 2724 myfree(data);
faa9b3e7
TC
2725 }
2726 else {
2727 if (GIMME_V != G_ARRAY) {
2728 EXTEND(SP, 1);
2729 PUSHs(&PL_sv_undef);
2730 }
2731 }
2732
a73aeb5f 2733
faa9b3e7
TC
2734Imager::ImgRaw
2735i_img_masked_new(targ, mask, x, y, w, h)
2736 Imager::ImgRaw targ
2737 int x
2738 int y
2739 int w
2740 int h
2741 PREINIT:
2742 i_img *mask;
2743 CODE:
2744 if (SvOK(ST(1))) {
2745 if (!sv_isobject(ST(1))
2746 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
2747 croak("i_img_masked_new: parameter 2 must undef or an image");
2748 }
2749 mask = (i_img *)SvIV((SV *)SvRV(ST(1)));
2750 }
2751 else
2752 mask = NULL;
2753 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
2754 OUTPUT:
2755 RETVAL
2756
2757int
2758i_plin(im, l, y, ...)
2759 Imager::ImgRaw im
2760 int l
2761 int y
2762 PREINIT:
2763 i_color *work;
2764 int count, i;
2765 CODE:
2766 if (items > 3) {
2767 work = mymalloc(sizeof(i_color) * (items-3));
2768 for (i=0; i < items-3; ++i) {
2769 if (sv_isobject(ST(i+3))
2770 && sv_derived_from(ST(i+3), "Imager::Color")) {
2771 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2772 work[i] = *(i_color *)tmp;
2773 }
2774 else {
2775 myfree(work);
2776 croak("i_plin: pixels must be Imager::Color objects");
2777 }
2778 }
2779 /**(char *)0 = 1;*/
2780 RETVAL = i_plin(im, l, l+items-3, y, work);
2781 myfree(work);
2782 }
2783 else {
2784 RETVAL = 0;
2785 }
2786 OUTPUT:
2787 RETVAL
2788
2789int
2790i_ppixf(im, x, y, cl)
2791 Imager::ImgRaw im
2792 int x
2793 int y
2794 Imager::Color::Float cl
2795
2796void
2797i_gsampf(im, l, r, y, ...)
2798 Imager::ImgRaw im
2799 int l
2800 int r
2801 int y
2802 PREINIT:
2803 int *chans;
2804 int chan_count;
2805 i_fsample_t *data;
2806 int count, i;
2807 PPCODE:
2808 if (items < 5)
2809 croak("No channel numbers supplied to g_sampf()");
2810 if (l < r) {
2811 chan_count = items - 4;
2812 chans = mymalloc(sizeof(int) * chan_count);
2813 for (i = 0; i < chan_count; ++i)
2814 chans[i] = SvIV(ST(i+4));
2815 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
2816 count = i_gsampf(im, l, r, y, data, chans, chan_count);
2817 if (GIMME_V == G_ARRAY) {
2818 EXTEND(SP, count);
2819 for (i = 0; i < count; ++i)
2820 PUSHs(sv_2mortal(newSVnv(data[i])));
2821 }
2822 else {
2823 EXTEND(SP, 1);
2824 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
2825 }
2826 }
2827 else {
2828 if (GIMME_V != G_ARRAY) {
2829 EXTEND(SP, 1);
2830 PUSHs(&PL_sv_undef);
2831 }
2832 }
2833
2834int
2835i_plinf(im, l, y, ...)
2836 Imager::ImgRaw im
2837 int l
2838 int y
2839 PREINIT:
2840 i_fcolor *work;
2841 int count, i;
2842 CODE:
2843 if (items > 3) {
2844 work = mymalloc(sizeof(i_fcolor) * (items-3));
2845 for (i=0; i < items-3; ++i) {
2846 if (sv_isobject(ST(i+3))
2847 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
2848 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2849 work[i] = *(i_fcolor *)tmp;
2850 }
2851 else {
2852 myfree(work);
2853 croak("i_plin: pixels must be Imager::Color::Float objects");
2854 }
2855 }
2856 /**(char *)0 = 1;*/
2857 RETVAL = i_plinf(im, l, l+items-3, y, work);
2858 myfree(work);
2859 }
2860 else {
2861 RETVAL = 0;
2862 }
2863 OUTPUT:
2864 RETVAL
2865
2866SV *
2867i_gpixf(im, x, y)
2868 Imager::ImgRaw im
2869 int x
2870 int y;
2871 PREINIT:
2872 i_fcolor *color;
2873 CODE:
2874 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
2875 if (i_gpixf(im, x, y, color) == 0) {
2876 ST(0) = sv_newmortal();
2877 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
2878 }
2879 else {
2880 myfree(color);
2881 ST(0) = &PL_sv_undef;
2882 }
2883
2884void
2885i_glin(im, l, r, y)
2886 Imager::ImgRaw im
2887 int l
2888 int r
2889 int y
2890 PREINIT:
2891 i_color *vals;
2892 int count, i;
2893 PPCODE:
2894 if (l < r) {
2895 vals = mymalloc((r-l) * sizeof(i_color));
2896 count = i_glin(im, l, r, y, vals);
2897 EXTEND(SP, count);
2898 for (i = 0; i < count; ++i) {
2899 SV *sv;
2900 i_color *col = mymalloc(sizeof(i_color));
2901 sv = sv_newmortal();
2902 sv_setref_pv(sv, "Imager::Color", (void *)col);
2903 PUSHs(sv);
2904 }
2905 myfree(vals);
2906 }
2907
2908void
2909i_glinf(im, l, r, y)
2910 Imager::ImgRaw im
2911 int l
2912 int r
2913 int y
2914 PREINIT:
2915 i_fcolor *vals;
2916 int count, i;
2917 PPCODE:
2918 if (l < r) {
2919 vals = mymalloc((r-l) * sizeof(i_fcolor));
2920 count = i_glinf(im, l, r, y, vals);
2921 EXTEND(SP, count);
2922 for (i = 0; i < count; ++i) {
2923 SV *sv;
2924 i_fcolor *col = mymalloc(sizeof(i_fcolor));
2925 *col = vals[i];
2926 sv = sv_newmortal();
2927 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
2928 PUSHs(sv);
2929 }
2930 myfree(vals);
2931 }
2932
2933Imager::ImgRaw
2934i_img_16_new(x, y, ch)
2935 int x
2936 int y
2937 int ch
2938
365ea842
TC
2939Imager::ImgRaw
2940i_img_double_new(x, y, ch)
2941 int x
2942 int y
2943 int ch
2944
faa9b3e7
TC
2945undef_int
2946i_tags_addn(im, name, code, idata)
2947 Imager::ImgRaw im
2948 int code
2949 int idata
2950 PREINIT:
2951 char *name;
2952 STRLEN len;
2953 CODE:
2954 if (SvOK(ST(1)))
2955 name = SvPV(ST(1), len);
2956 else
2957 name = NULL;
2958 RETVAL = i_tags_addn(&im->tags, name, code, idata);
2959 OUTPUT:
2960 RETVAL
2961
2962undef_int
2963i_tags_add(im, name, code, data, idata)
2964 Imager::ImgRaw im
2965 int code
2966 int idata
2967 PREINIT:
2968 char *name;
2969 char *data;
2970 STRLEN len;
2971 CODE:
2972 if (SvOK(ST(1)))
2973 name = SvPV(ST(1), len);
2974 else
2975 name = NULL;
2976 if (SvOK(ST(3)))
2977 data = SvPV(ST(3), len);
2978 else {
2979 data = NULL;
2980 len = 0;
2981 }
2982 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
2983 OUTPUT:
2984 RETVAL
2985
2986SV *
2987i_tags_find(im, name, start)
2988 Imager::ImgRaw im
2989 char *name
2990 int start
2991 PREINIT:
2992 int entry;
2993 CODE:
2994 if (i_tags_find(&im->tags, name, start, &entry)) {
2995 if (entry == 0)
2996 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2997 else
2998 ST(0) = sv_2mortal(newSViv(entry));
2999 } else {
3000 ST(0) = &PL_sv_undef;
3001 }
3002
3003SV *
3004i_tags_findn(im, code, start)
3005 Imager::ImgRaw im
3006 int code
3007 int start
3008 PREINIT:
3009 int entry;
3010 CODE:
3011 if (i_tags_findn(&im->tags, code, start, &entry)) {
3012 if (entry == 0)
3013 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
3014 else
3015 ST(0) = sv_2mortal(newSViv(entry));
3016 }
3017 else
3018 ST(0) = &PL_sv_undef;
3019
3020int
3021i_tags_delete(im, entry)
3022 Imager::ImgRaw im
3023 int entry
3024 CODE:
3025 RETVAL = i_tags_delete(&im->tags, entry);
3026 OUTPUT:
3027 RETVAL
3028
3029int
3030i_tags_delbyname(im, name)
3031 Imager::ImgRaw im
3032 char * name
3033 CODE:
3034 RETVAL = i_tags_delbyname(&im->tags, name);
3035 OUTPUT:
3036 RETVAL
3037
3038int
3039i_tags_delbycode(im, code)
3040 Imager::ImgRaw im
3041 int code
3042 CODE:
3043 RETVAL = i_tags_delbycode(&im->tags, code);
3044 OUTPUT:
3045 RETVAL
3046
3047void
3048i_tags_get(im, index)
3049 Imager::ImgRaw im
3050 int index
3051 PPCODE:
3052 if (index >= 0 && index < im->tags.count) {
3053 i_img_tag *entry = im->tags.tags + index;
3054 EXTEND(SP, 5);
3055
3056 if (entry->name) {
3057 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3058 }
3059 else {
3060 PUSHs(sv_2mortal(newSViv(entry->code)));
3061 }
3062 if (entry->data) {
3063 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3064 }
3065 else {
3066 PUSHs(sv_2mortal(newSViv(entry->idata)));
3067 }
3068 }
3069
3070int
3071i_tags_count(im)
3072 Imager::ImgRaw im
3073 CODE:
3074 RETVAL = im->tags.count;
3075 OUTPUT:
3076 RETVAL
3077
3078#ifdef HAVE_WIN32
3079
3080void
3081i_wf_bbox(face, size, text)
3082 char *face
3083 int size
3084 char *text
3085 PREINIT:
3086 int cords[6];
3087 PPCODE:
3088 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
3089 EXTEND(SP, 6);
3090 PUSHs(sv_2mortal(newSViv(cords[0])));
3091 PUSHs(sv_2mortal(newSViv(cords[1])));
3092 PUSHs(sv_2mortal(newSViv(cords[2])));
3093 PUSHs(sv_2mortal(newSViv(cords[3])));
3094 PUSHs(sv_2mortal(newSViv(cords[4])));
3095 PUSHs(sv_2mortal(newSViv(cords[5])));
3096 }
3097
3098undef_int
3099i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3100 char *face
3101 Imager::ImgRaw im
3102 int tx
3103 int ty
3104 Imager::Color cl
3105 int size
3106 char *text
3107 int align
3108 int aa
3109 CODE:
3110 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3111 align, aa);
3112 OUTPUT:
3113 RETVAL
3114
3115undef_int
3116i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3117 char *face
3118 Imager::ImgRaw im
3119 int tx
3120 int ty
3121 int channel
3122 int size
3123 char *text
3124 int align
3125 int aa
f5991c03 3126 CODE:
faa9b3e7
TC
3127 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3128 align, aa);
f5991c03
TC
3129 OUTPUT:
3130 RETVAL
02d1d628 3131
faa9b3e7
TC
3132
3133#endif
3134
3135#ifdef HAVE_FT2
3136
3137MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3138
3139#define FT2_DESTROY(font) i_ft2_destroy(font)
3140
3141void
3142FT2_DESTROY(font)
3143 Imager::Font::FT2 font
3144
3145MODULE = Imager PACKAGE = Imager::Font::FreeType2
3146
3147Imager::Font::FT2
3148i_ft2_new(name, index)
3149 char *name
3150 int index
3151
3152undef_int
3153i_ft2_setdpi(font, xdpi, ydpi)
3154 Imager::Font::FT2 font
3155 int xdpi
3156 int ydpi
3157
3158void
3159i_ft2_getdpi(font)
3160 Imager::Font::FT2 font
3161 PREINIT:
3162 int xdpi, ydpi;
3163 CODE:
3164 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3165 EXTEND(SP, 2);
3166 PUSHs(sv_2mortal(newSViv(xdpi)));
3167 PUSHs(sv_2mortal(newSViv(ydpi)));
3168 }
3169
3170undef_int
3171i_ft2_sethinting(font, hinting)
3172 Imager::Font::FT2 font
3173 int hinting
3174
3175undef_int
3176i_ft2_settransform(font, matrix)
3177 Imager::Font::FT2 font
3178 PREINIT:
3179 double matrix[6];
3180 int len;
3181 AV *av;
3182 SV *sv1;
3183 int i;
3184 CODE:
3185 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3186 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3187 av=(AV*)SvRV(ST(1));
3188 len=av_len(av)+1;
3189 if (len > 6)
3190 len = 6;
3191 for (i = 0; i < len; ++i) {
3192 sv1=(*(av_fetch(av,i,0)));
3193 matrix[i] = SvNV(sv1);
3194 }
3195 for (; i < 6; ++i)
3196 matrix[i] = 0;
3197 RETVAL = i_ft2_settransform(font, matrix);
3198 OUTPUT:
3199 RETVAL
3200
3201void
5cb9270b 3202i_ft2_bbox(font, cheight, cwidth, text, utf8)
faa9b3e7
TC
3203 Imager::Font::FT2 font
3204 double cheight
3205 double cwidth
3206 char *text
5cb9270b 3207 int utf8
faa9b3e7
TC
3208 PREINIT:
3209 int bbox[6];
3210 int i;
3211 PPCODE:
5cb9270b
TC
3212#ifdef SvUTF8
3213 if (SvUTF8(ST(3)))
3214 utf8 = 1;
3215#endif
3216 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox, utf8)) {
faa9b3e7
TC
3217 EXTEND(SP, 6);
3218 for (i = 0; i < 6; ++i)
3219 PUSHs(sv_2mortal(newSViv(bbox[i])));
3220 }
3221
3222void
3223i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
3224 Imager::Font::FT2 font
3225 double cheight
3226 double cwidth
3227 char *text
3228 int vlayout
3229 int utf8
3230 PREINIT:
3231 int bbox[8];
3232 int i;
3233 PPCODE:
3234#ifdef SvUTF8
3235 if (SvUTF8(ST(3)))
3236 utf8 = 1;
3237#endif
3238 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
3239 utf8, bbox)) {
3240 EXTEND(SP, 8);
3241 for (i = 0; i < 8; ++i)
3242 PUSHs(sv_2mortal(newSViv(bbox[i])));
3243 }
3244
3245undef_int
3246i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
3247 Imager::Font::FT2 font
3248 Imager::ImgRaw im
3249 int tx
3250 int ty
3251 Imager::Color cl
3252 double cheight
3253 double cwidth
3254 int align
3255 int aa
3256 int vlayout
3257 int utf8
3258 PREINIT:
3259 char *text;
3260 STRLEN len;
3261 CODE:
3262#ifdef SvUTF8
3263 if (SvUTF8(ST(7))) {
3264 utf8 = 1;
3265 }
3266#endif
3267 text = SvPV(ST(7), len);
3268 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
3269 len, align, aa, vlayout, utf8);
3270 OUTPUT:
3271 RETVAL
3272
3273undef_int
3274i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
3275 Imager::Font::FT2 font
3276 Imager::ImgRaw im
3277 int tx
3278 int ty
3279 int channel
3280 double cheight
3281 double cwidth
3282 char *text
3283 int align
3284 int aa
3285 int vlayout
3286 int utf8
3287 CODE:
3288#ifdef SvUTF8
3289 if (SvUTF8(ST(7)))
3290 utf8 = 1;
3291#endif
3292 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
3293 strlen(text), align, aa, vlayout, 1);
3294 OUTPUT:
3295 RETVAL
3296
3297void
3298ft2_transform_box(font, x0, x1, x2, x3)
3299 Imager::Font::FT2 font
3300 int x0
3301 int x1
3302 int x2
3303 int x3
3304 PREINIT:
3305 int box[4];
3306 PPCODE:
3307 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
3308 ft2_transform_box(font, box);
3309 EXTEND(SP, 4);
3310 PUSHs(sv_2mortal(newSViv(box[0])));
3311 PUSHs(sv_2mortal(newSViv(box[1])));
3312 PUSHs(sv_2mortal(newSViv(box[2])));
3313 PUSHs(sv_2mortal(newSViv(box[3])));
3dec2c92
TC
3314
3315void
3316i_ft2_has_chars(handle, text, utf8)
3317 Imager::Font::FT2 handle
3318 int utf8
3319 PREINIT:
3320 char *text;
3321 STRLEN len;
3322 char *work;
3323 int count;
3324 int i;
3325 PPCODE:
3326#ifdef SvUTF8
3327 if (SvUTF8(ST(7)))
3328 utf8 = 1;
3329#endif
3330 text = SvPV(ST(1), len);
3331 work = mymalloc(len);
3332 count = i_ft2_has_chars(handle, text, len, utf8, work);
3333 if (GIMME_V == G_ARRAY) {
3334 EXTEND(SP, count);
3335 for (i = 0; i < count; ++i) {
3336 PUSHs(sv_2mortal(newSViv(work[i])));
3337 }
3338 }
3339 else {
3340 EXTEND(SP, 1);
3341 PUSHs(sv_2mortal(newSVpv(work, count)));
3342 }
3343 myfree(work);
3344
faa9b3e7
TC
3345#endif
3346
f1ac5027
TC
3347MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3348
3349void
3350IFILL_DESTROY(fill)
3351 Imager::FillHandle fill
3352
3353MODULE = Imager PACKAGE = Imager
3354
3355Imager::FillHandle
3356i_new_fill_solid(cl, combine)
3357 Imager::Color cl
3358 int combine
3359
3360Imager::FillHandle
3361i_new_fill_solidf(cl, combine)
3362 Imager::Color::Float cl
3363 int combine
3364
3365Imager::FillHandle
3366i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3367 Imager::Color fg
3368 Imager::Color bg
3369 int combine
3370 int hatch
3371 int dx
3372 int dy
3373 PREINIT:
3374 unsigned char *cust_hatch;
3375 STRLEN len;
3376 CODE:
3377 if (SvOK(ST(4))) {
3378 cust_hatch = SvPV(ST(4), len);
3379 }
3380 else
3381 cust_hatch = NULL;
3382 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3383 OUTPUT:
3384 RETVAL
3385
efdc2568
TC
3386Imager::FillHandle
3387i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3388 Imager::Color::Float fg
3389 Imager::Color::Float bg
3390 int combine
3391 int hatch
3392 int dx
3393 int dy
3394 PREINIT:
3395 unsigned char *cust_hatch;
3396 STRLEN len;
3397 CODE:
3398 if (SvOK(ST(4))) {
3399 cust_hatch = SvPV(ST(4), len);
3400 }
3401 else
3402 cust_hatch = NULL;
3403 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3404 OUTPUT:
3405 RETVAL
3406
f576ce7e
TC
3407Imager::FillHandle
3408i_new_fill_image(src, matrix, xoff, yoff, combine)
3409 Imager::ImgRaw src
3410 int xoff
3411 int yoff
3412 int combine
3413 PREINIT:
3414 double matrix[9];
3415 double *matrixp;
3416 AV *av;
3417 IV len;
3418 SV *sv1;
3419 int i;
3420 CODE:
3421 if (!SvOK(ST(1))) {
3422 matrixp = NULL;
3423 }
3424 else {
3425 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3426 croak("i_new_fill_image: parameter must be an arrayref");
3427 av=(AV*)SvRV(ST(1));
3428 len=av_len(av)+1;
3429 if (len > 9)
3430 len = 9;
3431 for (i = 0; i < len; ++i) {
3432 sv1=(*(av_fetch(av,i,0)));
3433 matrix[i] = SvNV(sv1);
3434 }
3435 for (; i < 9; ++i)
3436 matrix[i] = 0;
3437 matrixp = matrix;
3438 }
3439 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3440 OUTPUT:
3441 RETVAL