Clarified what version of libtiff is required.
[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
1255i_t1_new(pfb,afm=NULL)
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
02d1d628
AMH
1905Imager::ImgRaw
1906i_scaleaxis(im,Value,Axis)
1907 Imager::ImgRaw im
1908 float Value
1909 int Axis
1910
1911Imager::ImgRaw
1912i_scale_nn(im,scx,scy)
1913 Imager::ImgRaw im
1914 float scx
1915 float scy
1916
1917Imager::ImgRaw
1918i_haar(im)
1919 Imager::ImgRaw im
1920
1921int
1922i_count_colors(im,maxc)
1923 Imager::ImgRaw im
1924 int maxc
1925
1926
1927Imager::ImgRaw
1928i_transform(im,opx,opy,parm)
1929 Imager::ImgRaw im
1930 PREINIT:
1931 double* parm;
1932 int* opx;
1933 int* opy;
1934 int opxl;
1935 int opyl;
1936 int parmlen;
1937 AV* av;
1938 SV* sv1;
1939 int i;
1940 CODE:
1941 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1942 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1943 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1944 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1945 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1946 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1947 av=(AV*)SvRV(ST(1));
1948 opxl=av_len(av)+1;
1949 opx=mymalloc( opxl*sizeof(int) );
1950 for(i=0;i<opxl;i++) {
1951 sv1=(*(av_fetch(av,i,0)));
1952 opx[i]=(int)SvIV(sv1);
1953 }
1954 av=(AV*)SvRV(ST(2));
1955 opyl=av_len(av)+1;
1956 opy=mymalloc( opyl*sizeof(int) );
1957 for(i=0;i<opyl;i++) {
1958 sv1=(*(av_fetch(av,i,0)));
1959 opy[i]=(int)SvIV(sv1);
1960 }
1961 av=(AV*)SvRV(ST(3));
1962 parmlen=av_len(av)+1;
1963 parm=mymalloc( parmlen*sizeof(double) );
1964 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1965 sv1=(*(av_fetch(av,i,0)));
1966 parm[i]=(double)SvNV(sv1);
1967 }
1968 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1969 myfree(parm);
1970 myfree(opy);
1971 myfree(opx);
1972 ST(0) = sv_newmortal();
1973 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1974 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1975
1976Imager::ImgRaw
1977i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
1978 PREINIT:
1979 int width;
1980 int height;
1981 double* parm;
1982 struct rm_op *ops;
953209f8 1983 STRLEN ops_len;
02d1d628
AMH
1984 int ops_count;
1985 double *n_regs;
1986 int n_regs_count;
1987 i_color *c_regs;
1988 int c_regs_count;
1989 int in_imgs_count;
1990 i_img **in_imgs;
1991 AV* av;
1992 SV* sv1;
1993 IV tmp;
1994 int i;
1995 CODE:
1996 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
1997 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
1998 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
1999 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
2000 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
2001
2002 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
2003
2004 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
2005 av = (AV*)SvRV(ST(5));
2006 in_imgs_count = av_len(av)+1;
2007 for (i = 0; i < in_imgs_count; ++i) {
2008 sv1 = *av_fetch(av, i, 0);
2009 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2010 croak("Parameter 5 must contain only images");
2011 }
2012 }
2013 }
2014 else {
2015 in_imgs_count = 0;
2016 }
b8c2033e 2017 if (in_imgs_count > 0) {
02d1d628
AMH
2018 av = (AV*)SvRV(ST(5));
2019 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
2020 for (i = 0; i < in_imgs_count; ++i) {
2021 sv1 = *av_fetch(av,i,0);
2022 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
2023 croak("Parameter 5 must contain only images");
2024 }
2025 tmp = SvIV((SV*)SvRV(sv1));
2026 in_imgs[i] = (i_img*)tmp;
2027 }
2028 }
2029 else {
2030 /* no input images */
2031 in_imgs = NULL;
2032 }
2033 /* default the output size from the first input if possible */
2034 if (SvOK(ST(0)))
2035 width = SvIV(ST(0));
2036 else if (in_imgs_count)
2037 width = in_imgs[0]->xsize;
2038 else
2039 croak("No output image width supplied");
2040
2041 if (SvOK(ST(1)))
2042 height = SvIV(ST(1));
2043 else if (in_imgs_count)
2044 height = in_imgs[0]->ysize;
2045 else
2046 croak("No output image height supplied");
2047
2048 ops = (struct rm_op *)SvPV(ST(2), ops_len);
2049 if (ops_len % sizeof(struct rm_op))
2050 croak("Imager: Parameter 3 must be a bitmap of regops\n");
2051 ops_count = ops_len / sizeof(struct rm_op);
2052 av = (AV*)SvRV(ST(3));
2053 n_regs_count = av_len(av)+1;
2054 n_regs = mymalloc(n_regs_count * sizeof(double));
2055 for (i = 0; i < n_regs_count; ++i) {
2056 sv1 = *av_fetch(av,i,0);
2057 if (SvOK(sv1))
2058 n_regs[i] = SvNV(sv1);
2059 }
2060 av = (AV*)SvRV(ST(4));
2061 c_regs_count = av_len(av)+1;
2062 c_regs = mymalloc(c_regs_count * sizeof(i_color));
2063 /* I don't bother initializing the colou?r registers */
2064
2065 RETVAL=i_transform2(width, height, 3, ops, ops_count,
2066 n_regs, n_regs_count,
2067 c_regs, c_regs_count, in_imgs, in_imgs_count);
2068 if (in_imgs)
2069 myfree(in_imgs);
2070 myfree(n_regs);
2071 myfree(c_regs);
2072 ST(0) = sv_newmortal();
2073 if (RETVAL == 0) ST(0)=&PL_sv_undef;
2074 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
2075
2076
2077void
2078i_contrast(im,intensity)
2079 Imager::ImgRaw im
2080 float intensity
2081
2082void
2083i_hardinvert(im)
2084 Imager::ImgRaw im
2085
2086void
2087i_noise(im,amount,type)
2088 Imager::ImgRaw im
2089 float amount
2090 unsigned char type
2091
2092void
2093i_bumpmap(im,bump,channel,light_x,light_y,strength)
2094 Imager::ImgRaw im
2095 Imager::ImgRaw bump
2096 int channel
2097 int light_x
2098 int light_y
2099 int strength
2100
b2778574
AMH
2101
2102void
2103i_bumpmap_complex(im,bump,channel,tx,ty,Lx,Ly,Lz,cd,cs,n,Ia,Il,Is)
2104 Imager::ImgRaw im
2105 Imager::ImgRaw bump
2106 int channel
2107 int tx
2108 int ty
2109 float Lx
2110 float Ly
2111 float Lz
2112 float cd
2113 float cs
2114 float n
2115 Imager::Color Ia
2116 Imager::Color Il
2117 Imager::Color Is
2118
2119
2120
02d1d628
AMH
2121void
2122i_postlevels(im,levels)
2123 Imager::ImgRaw im
2124 int levels
2125
2126void
2127i_mosaic(im,size)
2128 Imager::ImgRaw im
2129 int size
2130
2131void
2132i_watermark(im,wmark,tx,ty,pixdiff)
2133 Imager::ImgRaw im
2134 Imager::ImgRaw wmark
2135 int tx
2136 int ty
2137 int pixdiff
2138
2139
2140void
2141i_autolevels(im,lsat,usat,skew)
2142 Imager::ImgRaw im
2143 float lsat
2144 float usat
2145 float skew
2146
2147void
2148i_radnoise(im,xo,yo,rscale,ascale)
2149 Imager::ImgRaw im
2150 float xo
2151 float yo
2152 float rscale
2153 float ascale
2154
2155void
2156i_turbnoise(im, xo, yo, scale)
2157 Imager::ImgRaw im
2158 float xo
2159 float yo
2160 float scale
2161
2162
2163void
2164i_gradgen(im, ...)
2165 Imager::ImgRaw im
2166 PREINIT:
2167 int num;
2168 int *xo;
2169 int *yo;
2170 i_color *ival;
2171 int dmeasure;
2172 int i;
2173 SV *sv;
2174 AV *axx;
2175 AV *ayy;
2176 AV *ac;
2177 CODE:
2178 if (items != 5)
2179 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
2180 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2181 croak("i_gradgen: Second argument must be an array ref");
2182 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2183 croak("i_gradgen: Third argument must be an array ref");
2184 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2185 croak("i_gradgen: Fourth argument must be an array ref");
2186 axx = (AV *)SvRV(ST(1));
2187 ayy = (AV *)SvRV(ST(2));
2188 ac = (AV *)SvRV(ST(3));
2189 dmeasure = (int)SvIV(ST(4));
2190
2191 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2192 num = num <= av_len(ac) ? num : av_len(ac);
2193 num++;
2194 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
2195 xo = mymalloc( sizeof(int) * num );
2196 yo = mymalloc( sizeof(int) * num );
2197 ival = mymalloc( sizeof(i_color) * num );
2198 for(i = 0; i<num; i++) {
2199 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2200 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2201 sv = *av_fetch(ac, i, 0);
2202 if ( !sv_derived_from(sv, "Imager::Color") ) {
2203 free(axx); free(ayy); free(ac);
2204 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
2205 }
2206 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2207 }
2208 i_gradgen(im, num, xo, yo, ival, dmeasure);
a73aeb5f
AMH
2209 myfree(xo);
2210 myfree(yo);
2211 myfree(ival);
2212
02d1d628 2213
6607600c
TC
2214void
2215i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
2216 Imager::ImgRaw im
2217 double xa
2218 double ya
2219 double xb
2220 double yb
2221 int type
2222 int repeat
2223 int combine
2224 int super_sample
2225 double ssample_param
2226 PREINIT:
6607600c 2227 AV *asegs;
6607600c
TC
2228 int count;
2229 i_fountain_seg *segs;
6607600c 2230 CODE:
6607600c
TC
2231 if (!SvROK(ST(10)) || ! SvTYPE(SvRV(ST(10))))
2232 croak("i_fountain: argument 11 must be an array ref");
2233
2234 asegs = (AV *)SvRV(ST(10));
f1ac5027 2235 segs = load_fount_segs(asegs, &count);
6607600c
TC
2236 i_fountain(im, xa, ya, xb, yb, type, repeat, combine, super_sample,
2237 ssample_param, count, segs);
2238 myfree(segs);
02d1d628 2239
f1ac5027
TC
2240Imager::FillHandle
2241i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, segs)
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:
2252 AV *asegs;
2253 int count;
2254 i_fountain_seg *segs;
2255 CODE:
2256 if (!SvROK(ST(9)) || ! SvTYPE(SvRV(ST(9))))
2257 croak("i_fountain: argument 11 must be an array ref");
2258
2259 asegs = (AV *)SvRV(ST(9));
2260 segs = load_fount_segs(asegs, &count);
2261 RETVAL = i_new_fill_fount(xa, ya, xb, yb, type, repeat, combine,
2262 super_sample, ssample_param, count, segs);
2263 myfree(segs);
2264 OUTPUT:
2265 RETVAL
2266
4f4f776a
TC
2267void
2268i_errors()
2269 PREINIT:
2270 i_errmsg *errors;
2271 int i;
4f4f776a
TC
2272 AV *av;
2273 SV *ref;
2274 SV *sv;
2275 PPCODE:
2276 errors = i_errors();
2277 i = 0;
2278 while (errors[i].msg) {
2279 av = newAV();
2280 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
2281 if (!av_store(av, 0, sv)) {
2282 SvREFCNT_dec(sv);
2283 }
2284 sv = newSViv(errors[i].code);
2285 if (!av_store(av, 1, sv)) {
2286 SvREFCNT_dec(sv);
2287 }
2288 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
2289 ++i;
2290 }
02d1d628
AMH
2291
2292void
2293i_nearest_color(im, ...)
2294 Imager::ImgRaw im
2295 PREINIT:
2296 int num;
2297 int *xo;
2298 int *yo;
2299 i_color *ival;
2300 int dmeasure;
2301 int i;
2302 SV *sv;
2303 AV *axx;
2304 AV *ayy;
2305 AV *ac;
2306 CODE:
2307 if (items != 5)
2308 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
2309 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2310 croak("i_nearest_color: Second argument must be an array ref");
2311 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
2312 croak("i_nearest_color: Third argument must be an array ref");
2313 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
2314 croak("i_nearest_color: Fourth argument must be an array ref");
2315 axx = (AV *)SvRV(ST(1));
2316 ayy = (AV *)SvRV(ST(2));
2317 ac = (AV *)SvRV(ST(3));
2318 dmeasure = (int)SvIV(ST(4));
2319
2320 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
2321 num = num <= av_len(ac) ? num : av_len(ac);
2322 num++;
2323 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
2324 xo = mymalloc( sizeof(int) * num );
2325 yo = mymalloc( sizeof(int) * num );
2326 ival = mymalloc( sizeof(i_color) * num );
2327 for(i = 0; i<num; i++) {
2328 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
2329 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
2330 sv = *av_fetch(ac, i, 0);
2331 if ( !sv_derived_from(sv, "Imager::Color") ) {
2332 free(axx); free(ayy); free(ac);
2333 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
2334 }
2335 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
2336 }
2337 i_nearest_color(im, num, xo, yo, ival, dmeasure);
2338
2339
2340
2341
2342void
2343malloc_state()
2344
2345void
2346hashinfo(hv)
2347 PREINIT:
2348 HV* hv;
2349 int stuff;
2350 PPCODE:
2351 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
2352 hv=(HV*)SvRV(ST(0));
2353 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
2354 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2355 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
2356
2357void
2358DSO_open(filename)
2359 char* filename
2360 PREINIT:
2361 void *rc;
2362 char *evstr;
2363 PPCODE:
2364 rc=DSO_open(filename,&evstr);
2365 if (rc!=NULL) {
2366 if (evstr!=NULL) {
2367 EXTEND(SP,2);
2368 PUSHs(sv_2mortal(newSViv((IV)rc)));
2369 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
2370 } else {
2371 EXTEND(SP,1);
2372 PUSHs(sv_2mortal(newSViv((IV)rc)));
2373 }
2374 }
2375
2376
2377undef_int
2378DSO_close(dso_handle)
2379 void* dso_handle
2380
2381void
2382DSO_funclist(dso_handle_v)
2383 void* dso_handle_v
2384 PREINIT:
2385 int i;
2386 DSO_handle *dso_handle;
2387 PPCODE:
2388 dso_handle=(DSO_handle*)dso_handle_v;
2389 i=0;
2390 while( dso_handle->function_list[i].name != NULL) {
2391 EXTEND(SP,1);
2392 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
2393 EXTEND(SP,1);
2394 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
2395 }
2396
2397
2398void
2399DSO_call(handle,func_index,hv)
2400 void* handle
2401 int func_index
2402 PREINIT:
2403 HV* hv;
2404 PPCODE:
2405 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
2406 hv=(HV*)SvRV(ST(2));
2407 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
2408 DSO_call( (DSO_handle *)handle,func_index,hv);
2409
2410
2411
f5991c03 2412# this is mostly for testing...
faa9b3e7 2413SV *
f5991c03
TC
2414i_get_pixel(im, x, y)
2415 Imager::ImgRaw im
2416 int x
2417 int y;
faa9b3e7
TC
2418 PREINIT:
2419 i_color *color;
2420 CODE:
2421 color = (i_color *)mymalloc(sizeof(i_color));
2422 if (i_gpix(im, x, y, color) == 0) {
2423 ST(0) = sv_newmortal();
2424 sv_setref_pv(ST(0), "Imager::Color", (void *)color);
2425 }
2426 else {
2427 myfree(color);
2428 ST(0) = &PL_sv_undef;
2429 }
2430
2431
2432int
2433i_ppix(im, x, y, cl)
2434 Imager::ImgRaw im
2435 int x
2436 int y
2437 Imager::Color cl
2438
2439Imager::ImgRaw
2440i_img_pal_new(x, y, channels, maxpal)
2441 int x
2442 int y
2443 int channels
2444 int maxpal
2445
2446Imager::ImgRaw
2447i_img_to_pal(src, quant)
2448 Imager::ImgRaw src
2449 PREINIT:
2450 HV *hv;
2451 i_quantize quant;
2452 CODE:
2453 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
2454 croak("i_img_to_pal: second argument must be a hash ref");
2455 hv = (HV *)SvRV(ST(1));
2456 memset(&quant, 0, sizeof(quant));
2457 quant.mc_size = 256;
faa9b3e7
TC
2458 handle_quant_opts(&quant, hv);
2459 RETVAL = i_img_to_pal(src, &quant);
2460 if (RETVAL) {
2461 copy_colors_back(hv, &quant);
2462 }
46a04ceb 2463 cleanup_quant_opts(&quant);
faa9b3e7
TC
2464 OUTPUT:
2465 RETVAL
2466
2467Imager::ImgRaw
2468i_img_to_rgb(src)
2469 Imager::ImgRaw src
2470
2471void
2472i_gpal(im, l, r, y)
2473 Imager::ImgRaw im
2474 int l
2475 int r
2476 int y
2477 PREINIT:
2478 i_palidx *work;
2479 int count, i;
2480 PPCODE:
2481 if (l < r) {
2482 work = mymalloc((r-l) * sizeof(i_palidx));
2483 count = i_gpal(im, l, r, y, work);
2484 if (GIMME_V == G_ARRAY) {
2485 EXTEND(SP, count);
2486 for (i = 0; i < count; ++i) {
2487 PUSHs(sv_2mortal(newSViv(work[i])));
2488 }
2489 }
2490 else {
2491 EXTEND(SP, 1);
2492 PUSHs(sv_2mortal(newSVpv(work, count * sizeof(i_palidx))));
2493 }
2494 myfree(work);
2495 }
2496 else {
2497 if (GIMME_V != G_ARRAY) {
2498 EXTEND(SP, 1);
2499 PUSHs(&PL_sv_undef);
2500 }
2501 }
2502
2503int
2504i_ppal(im, l, y, ...)
2505 Imager::ImgRaw im
2506 int l
2507 int y
2508 PREINIT:
2509 i_palidx *work;
2510 int count, i;
2511 CODE:
2512 if (items > 3) {
2513 work = mymalloc(sizeof(i_palidx) * (items-3));
2514 for (i=0; i < items-3; ++i) {
2515 work[i] = SvIV(ST(i+3));
2516 }
2517 RETVAL = i_ppal(im, l, l+items-3, y, work);
2518 myfree(work);
2519 }
2520 else {
2521 RETVAL = 0;
2522 }
2523 OUTPUT:
2524 RETVAL
2525
2526SV *
2527i_addcolors(im, ...)
2528 Imager::ImgRaw im
2529 PREINIT:
2530 int index;
2531 i_color *colors;
2532 int i;
2533 CODE:
2534 if (items < 2)
2535 croak("i_addcolors: no colors to add");
2536 colors = mymalloc((items-1) * sizeof(i_color));
2537 for (i=0; i < items-1; ++i) {
2538 if (sv_isobject(ST(i+1))
2539 && sv_derived_from(ST(i+1), "Imager::Color")) {
2540 IV tmp = SvIV((SV *)SvRV(ST(i+1)));
2541 colors[i] = *(i_color *)tmp;
2542 }
2543 else {
2544 myfree(colors);
2545 croak("i_plin: pixels must be Imager::Color objects");
2546 }
2547 }
2548 index = i_addcolors(im, colors, items-1);
2549 myfree(colors);
2550 if (index == 0) {
2551 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2552 }
2553 else if (index == -1) {
2554 ST(0) = &PL_sv_undef;
2555 }
2556 else {
2557 ST(0) = sv_2mortal(newSViv(index));
2558 }
2559
2560int
2561i_setcolors(im, index, ...)
2562 Imager::ImgRaw im
2563 int index
2564 PREINIT:
2565 i_color *colors;
2566 int i;
2567 CODE:
2568 if (items < 3)
2569 croak("i_setcolors: no colors to add");
2570 colors = mymalloc((items-2) * sizeof(i_color));
2571 for (i=0; i < items-2; ++i) {
2572 if (sv_isobject(ST(i+2))
2573 && sv_derived_from(ST(i+2), "Imager::Color")) {
2574 IV tmp = SvIV((SV *)SvRV(ST(i+2)));
2575 colors[i] = *(i_color *)tmp;
2576 }
2577 else {
2578 myfree(colors);
2579 croak("i_setcolors: pixels must be Imager::Color objects");
2580 }
2581 }
2582 RETVAL = i_setcolors(im, index, colors, items-2);
2583 myfree(colors);
2584
2585void
2586i_getcolors(im, index, ...)
2587 Imager::ImgRaw im
2588 int index
2589 PREINIT:
2590 i_color *colors;
2591 int count = 1;
2592 int i;
2593 PPCODE:
2594 if (items > 3)
2595 croak("i_getcolors: too many arguments");
2596 if (items == 3)
2597 count = SvIV(ST(2));
2598 if (count < 1)
2599 croak("i_getcolors: count must be positive");
2600 colors = mymalloc(sizeof(i_color) * count);
2601 if (i_getcolors(im, index, colors, count)) {
2602 for (i = 0; i < count; ++i) {
2603 i_color *pv;
2604 SV *sv = sv_newmortal();
2605 pv = mymalloc(sizeof(i_color));
2606 *pv = colors[i];
2607 sv_setref_pv(sv, "Imager::Color", (void *)pv);
2608 PUSHs(sv);
2609 }
2610 }
2611 myfree(colors);
2612
2613
2614SV *
2615i_colorcount(im)
2616 Imager::ImgRaw im
2617 PREINIT:
2618 int count;
2619 CODE:
2620 count = i_colorcount(im);
2621 if (count >= 0) {
2622 ST(0) = sv_2mortal(newSViv(count));
2623 }
2624 else {
2625 ST(0) = &PL_sv_undef;
2626 }
2627
2628SV *
2629i_maxcolors(im)
2630 Imager::ImgRaw im
2631 PREINIT:
2632 int count;
2633 CODE:
2634 count = i_maxcolors(im);
2635 if (count >= 0) {
2636 ST(0) = sv_2mortal(newSViv(count));
2637 }
2638 else {
2639 ST(0) = &PL_sv_undef;
2640 }
2641
2642SV *
2643i_findcolor(im, color)
2644 Imager::ImgRaw im
2645 Imager::Color color
2646 PREINIT:
2647 i_palidx index;
2648 CODE:
2649 if (i_findcolor(im, color, &index)) {
2650 ST(0) = sv_2mortal(newSViv(index));
2651 }
2652 else {
2653 ST(0) = &PL_sv_undef;
2654 }
2655
2656int
2657i_img_bits(im)
2658 Imager::ImgRaw im
2659
2660int
2661i_img_type(im)
2662 Imager::ImgRaw im
2663
2664int
2665i_img_virtual(im)
2666 Imager::ImgRaw im
2667
2668void
2669i_gsamp(im, l, r, y, ...)
2670 Imager::ImgRaw im
2671 int l
2672 int r
2673 int y
2674 PREINIT:
2675 int *chans;
2676 int chan_count;
2677 i_sample_t *data;
2678 int count, i;
2679 PPCODE:
2680 if (items < 5)
2681 croak("No channel numbers supplied to g_samp()");
2682 if (l < r) {
2683 chan_count = items - 4;
2684 chans = mymalloc(sizeof(int) * chan_count);
2685 for (i = 0; i < chan_count; ++i)
2686 chans[i] = SvIV(ST(i+4));
4dfa5522 2687 data = mymalloc(sizeof(i_sample_t) * (r-l) * chan_count); /* XXX: memleak? */
faa9b3e7 2688 count = i_gsamp(im, l, r, y, data, chans, chan_count);
4dfa5522 2689 myfree(chans);
faa9b3e7
TC
2690 if (GIMME_V == G_ARRAY) {
2691 EXTEND(SP, count);
2692 for (i = 0; i < count; ++i)
2693 PUSHs(sv_2mortal(newSViv(data[i])));
2694 }
2695 else {
2696 EXTEND(SP, 1);
2697 PUSHs(sv_2mortal(newSVpv(data, count * sizeof(i_sample_t))));
2698 }
a73aeb5f 2699 myfree(data);
faa9b3e7
TC
2700 }
2701 else {
2702 if (GIMME_V != G_ARRAY) {
2703 EXTEND(SP, 1);
2704 PUSHs(&PL_sv_undef);
2705 }
2706 }
2707
a73aeb5f 2708
faa9b3e7
TC
2709Imager::ImgRaw
2710i_img_masked_new(targ, mask, x, y, w, h)
2711 Imager::ImgRaw targ
2712 int x
2713 int y
2714 int w
2715 int h
2716 PREINIT:
2717 i_img *mask;
2718 CODE:
2719 if (SvOK(ST(1))) {
2720 if (!sv_isobject(ST(1))
2721 || !sv_derived_from(ST(1), "Imager::ImgRaw")) {
2722 croak("i_img_masked_new: parameter 2 must undef or an image");
2723 }
2724 mask = (i_img *)SvIV((SV *)SvRV(ST(1)));
2725 }
2726 else
2727 mask = NULL;
2728 RETVAL = i_img_masked_new(targ, mask, x, y, w, h);
2729 OUTPUT:
2730 RETVAL
2731
2732int
2733i_plin(im, l, y, ...)
2734 Imager::ImgRaw im
2735 int l
2736 int y
2737 PREINIT:
2738 i_color *work;
2739 int count, i;
2740 CODE:
2741 if (items > 3) {
2742 work = mymalloc(sizeof(i_color) * (items-3));
2743 for (i=0; i < items-3; ++i) {
2744 if (sv_isobject(ST(i+3))
2745 && sv_derived_from(ST(i+3), "Imager::Color")) {
2746 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2747 work[i] = *(i_color *)tmp;
2748 }
2749 else {
2750 myfree(work);
2751 croak("i_plin: pixels must be Imager::Color objects");
2752 }
2753 }
2754 /**(char *)0 = 1;*/
2755 RETVAL = i_plin(im, l, l+items-3, y, work);
2756 myfree(work);
2757 }
2758 else {
2759 RETVAL = 0;
2760 }
2761 OUTPUT:
2762 RETVAL
2763
2764int
2765i_ppixf(im, x, y, cl)
2766 Imager::ImgRaw im
2767 int x
2768 int y
2769 Imager::Color::Float cl
2770
2771void
2772i_gsampf(im, l, r, y, ...)
2773 Imager::ImgRaw im
2774 int l
2775 int r
2776 int y
2777 PREINIT:
2778 int *chans;
2779 int chan_count;
2780 i_fsample_t *data;
2781 int count, i;
2782 PPCODE:
2783 if (items < 5)
2784 croak("No channel numbers supplied to g_sampf()");
2785 if (l < r) {
2786 chan_count = items - 4;
2787 chans = mymalloc(sizeof(int) * chan_count);
2788 for (i = 0; i < chan_count; ++i)
2789 chans[i] = SvIV(ST(i+4));
2790 data = mymalloc(sizeof(i_fsample_t) * (r-l) * chan_count);
2791 count = i_gsampf(im, l, r, y, data, chans, chan_count);
2792 if (GIMME_V == G_ARRAY) {
2793 EXTEND(SP, count);
2794 for (i = 0; i < count; ++i)
2795 PUSHs(sv_2mortal(newSVnv(data[i])));
2796 }
2797 else {
2798 EXTEND(SP, 1);
2799 PUSHs(sv_2mortal(newSVpv((void *)data, count * sizeof(i_fsample_t))));
2800 }
2801 }
2802 else {
2803 if (GIMME_V != G_ARRAY) {
2804 EXTEND(SP, 1);
2805 PUSHs(&PL_sv_undef);
2806 }
2807 }
2808
2809int
2810i_plinf(im, l, y, ...)
2811 Imager::ImgRaw im
2812 int l
2813 int y
2814 PREINIT:
2815 i_fcolor *work;
2816 int count, i;
2817 CODE:
2818 if (items > 3) {
2819 work = mymalloc(sizeof(i_fcolor) * (items-3));
2820 for (i=0; i < items-3; ++i) {
2821 if (sv_isobject(ST(i+3))
2822 && sv_derived_from(ST(i+3), "Imager::Color::Float")) {
2823 IV tmp = SvIV((SV *)SvRV(ST(i+3)));
2824 work[i] = *(i_fcolor *)tmp;
2825 }
2826 else {
2827 myfree(work);
2828 croak("i_plin: pixels must be Imager::Color::Float objects");
2829 }
2830 }
2831 /**(char *)0 = 1;*/
2832 RETVAL = i_plinf(im, l, l+items-3, y, work);
2833 myfree(work);
2834 }
2835 else {
2836 RETVAL = 0;
2837 }
2838 OUTPUT:
2839 RETVAL
2840
2841SV *
2842i_gpixf(im, x, y)
2843 Imager::ImgRaw im
2844 int x
2845 int y;
2846 PREINIT:
2847 i_fcolor *color;
2848 CODE:
2849 color = (i_fcolor *)mymalloc(sizeof(i_fcolor));
2850 if (i_gpixf(im, x, y, color) == 0) {
2851 ST(0) = sv_newmortal();
2852 sv_setref_pv(ST(0), "Imager::Color::Float", (void *)color);
2853 }
2854 else {
2855 myfree(color);
2856 ST(0) = &PL_sv_undef;
2857 }
2858
2859void
2860i_glin(im, l, r, y)
2861 Imager::ImgRaw im
2862 int l
2863 int r
2864 int y
2865 PREINIT:
2866 i_color *vals;
2867 int count, i;
2868 PPCODE:
2869 if (l < r) {
2870 vals = mymalloc((r-l) * sizeof(i_color));
2871 count = i_glin(im, l, r, y, vals);
2872 EXTEND(SP, count);
2873 for (i = 0; i < count; ++i) {
2874 SV *sv;
2875 i_color *col = mymalloc(sizeof(i_color));
2876 sv = sv_newmortal();
2877 sv_setref_pv(sv, "Imager::Color", (void *)col);
2878 PUSHs(sv);
2879 }
2880 myfree(vals);
2881 }
2882
2883void
2884i_glinf(im, l, r, y)
2885 Imager::ImgRaw im
2886 int l
2887 int r
2888 int y
2889 PREINIT:
2890 i_fcolor *vals;
2891 int count, i;
2892 PPCODE:
2893 if (l < r) {
2894 vals = mymalloc((r-l) * sizeof(i_fcolor));
2895 count = i_glinf(im, l, r, y, vals);
2896 EXTEND(SP, count);
2897 for (i = 0; i < count; ++i) {
2898 SV *sv;
2899 i_fcolor *col = mymalloc(sizeof(i_fcolor));
2900 *col = vals[i];
2901 sv = sv_newmortal();
2902 sv_setref_pv(sv, "Imager::Color::Float", (void *)col);
2903 PUSHs(sv);
2904 }
2905 myfree(vals);
2906 }
2907
2908Imager::ImgRaw
2909i_img_16_new(x, y, ch)
2910 int x
2911 int y
2912 int ch
2913
365ea842
TC
2914Imager::ImgRaw
2915i_img_double_new(x, y, ch)
2916 int x
2917 int y
2918 int ch
2919
faa9b3e7
TC
2920undef_int
2921i_tags_addn(im, name, code, idata)
2922 Imager::ImgRaw im
2923 int code
2924 int idata
2925 PREINIT:
2926 char *name;
2927 STRLEN len;
2928 CODE:
2929 if (SvOK(ST(1)))
2930 name = SvPV(ST(1), len);
2931 else
2932 name = NULL;
2933 RETVAL = i_tags_addn(&im->tags, name, code, idata);
2934 OUTPUT:
2935 RETVAL
2936
2937undef_int
2938i_tags_add(im, name, code, data, idata)
2939 Imager::ImgRaw im
2940 int code
2941 int idata
2942 PREINIT:
2943 char *name;
2944 char *data;
2945 STRLEN len;
2946 CODE:
2947 if (SvOK(ST(1)))
2948 name = SvPV(ST(1), len);
2949 else
2950 name = NULL;
2951 if (SvOK(ST(3)))
2952 data = SvPV(ST(3), len);
2953 else {
2954 data = NULL;
2955 len = 0;
2956 }
2957 RETVAL = i_tags_add(&im->tags, name, code, data, len, idata);
2958 OUTPUT:
2959 RETVAL
2960
2961SV *
2962i_tags_find(im, name, start)
2963 Imager::ImgRaw im
2964 char *name
2965 int start
2966 PREINIT:
2967 int entry;
2968 CODE:
2969 if (i_tags_find(&im->tags, name, start, &entry)) {
2970 if (entry == 0)
2971 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2972 else
2973 ST(0) = sv_2mortal(newSViv(entry));
2974 } else {
2975 ST(0) = &PL_sv_undef;
2976 }
2977
2978SV *
2979i_tags_findn(im, code, start)
2980 Imager::ImgRaw im
2981 int code
2982 int start
2983 PREINIT:
2984 int entry;
2985 CODE:
2986 if (i_tags_findn(&im->tags, code, start, &entry)) {
2987 if (entry == 0)
2988 ST(0) = sv_2mortal(newSVpv("0 but true", 0));
2989 else
2990 ST(0) = sv_2mortal(newSViv(entry));
2991 }
2992 else
2993 ST(0) = &PL_sv_undef;
2994
2995int
2996i_tags_delete(im, entry)
2997 Imager::ImgRaw im
2998 int entry
2999 CODE:
3000 RETVAL = i_tags_delete(&im->tags, entry);
3001 OUTPUT:
3002 RETVAL
3003
3004int
3005i_tags_delbyname(im, name)
3006 Imager::ImgRaw im
3007 char * name
3008 CODE:
3009 RETVAL = i_tags_delbyname(&im->tags, name);
3010 OUTPUT:
3011 RETVAL
3012
3013int
3014i_tags_delbycode(im, code)
3015 Imager::ImgRaw im
3016 int code
3017 CODE:
3018 RETVAL = i_tags_delbycode(&im->tags, code);
3019 OUTPUT:
3020 RETVAL
3021
3022void
3023i_tags_get(im, index)
3024 Imager::ImgRaw im
3025 int index
3026 PPCODE:
3027 if (index >= 0 && index < im->tags.count) {
3028 i_img_tag *entry = im->tags.tags + index;
3029 EXTEND(SP, 5);
3030
3031 if (entry->name) {
3032 PUSHs(sv_2mortal(newSVpv(entry->name, 0)));
3033 }
3034 else {
3035 PUSHs(sv_2mortal(newSViv(entry->code)));
3036 }
3037 if (entry->data) {
3038 PUSHs(sv_2mortal(newSVpvn(entry->data, entry->size)));
3039 }
3040 else {
3041 PUSHs(sv_2mortal(newSViv(entry->idata)));
3042 }
3043 }
3044
3045int
3046i_tags_count(im)
3047 Imager::ImgRaw im
3048 CODE:
3049 RETVAL = im->tags.count;
3050 OUTPUT:
3051 RETVAL
3052
3053#ifdef HAVE_WIN32
3054
3055void
3056i_wf_bbox(face, size, text)
3057 char *face
3058 int size
3059 char *text
3060 PREINIT:
3061 int cords[6];
3062 PPCODE:
3063 if (i_wf_bbox(face, size, text, strlen(text), cords)) {
3064 EXTEND(SP, 6);
3065 PUSHs(sv_2mortal(newSViv(cords[0])));
3066 PUSHs(sv_2mortal(newSViv(cords[1])));
3067 PUSHs(sv_2mortal(newSViv(cords[2])));
3068 PUSHs(sv_2mortal(newSViv(cords[3])));
3069 PUSHs(sv_2mortal(newSViv(cords[4])));
3070 PUSHs(sv_2mortal(newSViv(cords[5])));
3071 }
3072
3073undef_int
3074i_wf_text(face, im, tx, ty, cl, size, text, align, aa)
3075 char *face
3076 Imager::ImgRaw im
3077 int tx
3078 int ty
3079 Imager::Color cl
3080 int size
3081 char *text
3082 int align
3083 int aa
3084 CODE:
3085 RETVAL = i_wf_text(face, im, tx, ty, cl, size, text, strlen(text),
3086 align, aa);
3087 OUTPUT:
3088 RETVAL
3089
3090undef_int
3091i_wf_cp(face, im, tx, ty, channel, size, text, align, aa)
3092 char *face
3093 Imager::ImgRaw im
3094 int tx
3095 int ty
3096 int channel
3097 int size
3098 char *text
3099 int align
3100 int aa
f5991c03 3101 CODE:
faa9b3e7
TC
3102 RETVAL = i_wf_cp(face, im, tx, ty, channel, size, text, strlen(text),
3103 align, aa);
f5991c03
TC
3104 OUTPUT:
3105 RETVAL
02d1d628 3106
faa9b3e7
TC
3107
3108#endif
3109
3110#ifdef HAVE_FT2
3111
3112MODULE = Imager PACKAGE = Imager::Font::FT2 PREFIX=FT2_
3113
3114#define FT2_DESTROY(font) i_ft2_destroy(font)
3115
3116void
3117FT2_DESTROY(font)
3118 Imager::Font::FT2 font
3119
3120MODULE = Imager PACKAGE = Imager::Font::FreeType2
3121
3122Imager::Font::FT2
3123i_ft2_new(name, index)
3124 char *name
3125 int index
3126
3127undef_int
3128i_ft2_setdpi(font, xdpi, ydpi)
3129 Imager::Font::FT2 font
3130 int xdpi
3131 int ydpi
3132
3133void
3134i_ft2_getdpi(font)
3135 Imager::Font::FT2 font
3136 PREINIT:
3137 int xdpi, ydpi;
3138 CODE:
3139 if (i_ft2_getdpi(font, &xdpi, &ydpi)) {
3140 EXTEND(SP, 2);
3141 PUSHs(sv_2mortal(newSViv(xdpi)));
3142 PUSHs(sv_2mortal(newSViv(ydpi)));
3143 }
3144
3145undef_int
3146i_ft2_sethinting(font, hinting)
3147 Imager::Font::FT2 font
3148 int hinting
3149
3150undef_int
3151i_ft2_settransform(font, matrix)
3152 Imager::Font::FT2 font
3153 PREINIT:
3154 double matrix[6];
3155 int len;
3156 AV *av;
3157 SV *sv1;
3158 int i;
3159 CODE:
3160 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3161 croak("i_ft2_settransform: parameter 2 must be an array ref\n");
3162 av=(AV*)SvRV(ST(1));
3163 len=av_len(av)+1;
3164 if (len > 6)
3165 len = 6;
3166 for (i = 0; i < len; ++i) {
3167 sv1=(*(av_fetch(av,i,0)));
3168 matrix[i] = SvNV(sv1);
3169 }
3170 for (; i < 6; ++i)
3171 matrix[i] = 0;
3172 RETVAL = i_ft2_settransform(font, matrix);
3173 OUTPUT:
3174 RETVAL
3175
3176void
3177i_ft2_bbox(font, cheight, cwidth, text)
3178 Imager::Font::FT2 font
3179 double cheight
3180 double cwidth
3181 char *text
3182 PREINIT:
3183 int bbox[6];
3184 int i;
3185 PPCODE:
3186 if (i_ft2_bbox(font, cheight, cwidth, text, strlen(text), bbox)) {
3187 EXTEND(SP, 6);
3188 for (i = 0; i < 6; ++i)
3189 PUSHs(sv_2mortal(newSViv(bbox[i])));
3190 }
3191
3192void
3193i_ft2_bbox_r(font, cheight, cwidth, text, vlayout, utf8)
3194 Imager::Font::FT2 font
3195 double cheight
3196 double cwidth
3197 char *text
3198 int vlayout
3199 int utf8
3200 PREINIT:
3201 int bbox[8];
3202 int i;
3203 PPCODE:
3204#ifdef SvUTF8
3205 if (SvUTF8(ST(3)))
3206 utf8 = 1;
3207#endif
3208 if (i_ft2_bbox_r(font, cheight, cwidth, text, strlen(text), vlayout,
3209 utf8, bbox)) {
3210 EXTEND(SP, 8);
3211 for (i = 0; i < 8; ++i)
3212 PUSHs(sv_2mortal(newSViv(bbox[i])));
3213 }
3214
3215undef_int
3216i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text, align, aa, vlayout, utf8)
3217 Imager::Font::FT2 font
3218 Imager::ImgRaw im
3219 int tx
3220 int ty
3221 Imager::Color cl
3222 double cheight
3223 double cwidth
3224 int align
3225 int aa
3226 int vlayout
3227 int utf8
3228 PREINIT:
3229 char *text;
3230 STRLEN len;
3231 CODE:
3232#ifdef SvUTF8
3233 if (SvUTF8(ST(7))) {
3234 utf8 = 1;
3235 }
3236#endif
3237 text = SvPV(ST(7), len);
3238 RETVAL = i_ft2_text(font, im, tx, ty, cl, cheight, cwidth, text,
3239 len, align, aa, vlayout, utf8);
3240 OUTPUT:
3241 RETVAL
3242
3243undef_int
3244i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text, align, aa, vlayout, utf8)
3245 Imager::Font::FT2 font
3246 Imager::ImgRaw im
3247 int tx
3248 int ty
3249 int channel
3250 double cheight
3251 double cwidth
3252 char *text
3253 int align
3254 int aa
3255 int vlayout
3256 int utf8
3257 CODE:
3258#ifdef SvUTF8
3259 if (SvUTF8(ST(7)))
3260 utf8 = 1;
3261#endif
3262 RETVAL = i_ft2_cp(font, im, tx, ty, channel, cheight, cwidth, text,
3263 strlen(text), align, aa, vlayout, 1);
3264 OUTPUT:
3265 RETVAL
3266
3267void
3268ft2_transform_box(font, x0, x1, x2, x3)
3269 Imager::Font::FT2 font
3270 int x0
3271 int x1
3272 int x2
3273 int x3
3274 PREINIT:
3275 int box[4];
3276 PPCODE:
3277 box[0] = x0; box[1] = x1; box[2] = x2; box[3] = x3;
3278 ft2_transform_box(font, box);
3279 EXTEND(SP, 4);
3280 PUSHs(sv_2mortal(newSViv(box[0])));
3281 PUSHs(sv_2mortal(newSViv(box[1])));
3282 PUSHs(sv_2mortal(newSViv(box[2])));
3283 PUSHs(sv_2mortal(newSViv(box[3])));
3284
3285#endif
3286
f1ac5027
TC
3287MODULE = Imager PACKAGE = Imager::FillHandle PREFIX=IFILL_
3288
3289void
3290IFILL_DESTROY(fill)
3291 Imager::FillHandle fill
3292
3293MODULE = Imager PACKAGE = Imager
3294
3295Imager::FillHandle
3296i_new_fill_solid(cl, combine)
3297 Imager::Color cl
3298 int combine
3299
3300Imager::FillHandle
3301i_new_fill_solidf(cl, combine)
3302 Imager::Color::Float cl
3303 int combine
3304
3305Imager::FillHandle
3306i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
3307 Imager::Color fg
3308 Imager::Color bg
3309 int combine
3310 int hatch
3311 int dx
3312 int dy
3313 PREINIT:
3314 unsigned char *cust_hatch;
3315 STRLEN len;
3316 CODE:
3317 if (SvOK(ST(4))) {
3318 cust_hatch = SvPV(ST(4), len);
3319 }
3320 else
3321 cust_hatch = NULL;
3322 RETVAL = i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy);
3323 OUTPUT:
3324 RETVAL
3325
efdc2568
TC
3326Imager::FillHandle
3327i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
3328 Imager::Color::Float fg
3329 Imager::Color::Float bg
3330 int combine
3331 int hatch
3332 int dx
3333 int dy
3334 PREINIT:
3335 unsigned char *cust_hatch;
3336 STRLEN len;
3337 CODE:
3338 if (SvOK(ST(4))) {
3339 cust_hatch = SvPV(ST(4), len);
3340 }
3341 else
3342 cust_hatch = NULL;
3343 RETVAL = i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy);
3344 OUTPUT:
3345 RETVAL
3346
f576ce7e
TC
3347Imager::FillHandle
3348i_new_fill_image(src, matrix, xoff, yoff, combine)
3349 Imager::ImgRaw src
3350 int xoff
3351 int yoff
3352 int combine
3353 PREINIT:
3354 double matrix[9];
3355 double *matrixp;
3356 AV *av;
3357 IV len;
3358 SV *sv1;
3359 int i;
3360 CODE:
3361 if (!SvOK(ST(1))) {
3362 matrixp = NULL;
3363 }
3364 else {
3365 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
3366 croak("i_new_fill_image: parameter must be an arrayref");
3367 av=(AV*)SvRV(ST(1));
3368 len=av_len(av)+1;
3369 if (len > 9)
3370 len = 9;
3371 for (i = 0; i < len; ++i) {
3372 sv1=(*(av_fetch(av,i,0)));
3373 matrix[i] = SvNV(sv1);
3374 }
3375 for (; i < 9; ++i)
3376 matrix[i] = 0;
3377 matrixp = matrix;
3378 }
3379 RETVAL = i_new_fill_image(src, matrixp, xoff, yoff, combine);
3380 OUTPUT:
3381 RETVAL