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