]> git.imager.perl.org - imager.git/blame - Imager.xs
More fixes still for iolayer changes.
[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;
19typedef i_img* Imager__ImgRaw;
20
21
22#ifdef HAVE_LIBTT
23typedef TT_Fonthandle* Imager__TTHandle;
24#endif
25
26typedef struct i_reader_data_tag
27{
28 /* presumably a CODE ref or name of a sub */
29 SV *sv;
30} i_reader_data;
31
32/* used by functions that want callbacks */
33static int read_callback(char *userdata, char *buffer, int need, int want) {
34 i_reader_data *rd = (i_reader_data *)userdata;
35 int count;
36 int result;
37 SV *data;
38 dSP; dTARG = sv_newmortal();
39 /* thanks to Simon Cozens for help with the dTARG above */
40
41 ENTER;
42 SAVETMPS;
43 EXTEND(SP, 2);
44 PUSHMARK(SP);
45 PUSHi(want);
46 PUSHi(need);
47 PUTBACK;
48
49 count = perl_call_sv(rd->sv, G_SCALAR);
50
51 SPAGAIN;
52
53 if (count != 1)
54 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
55
56 data = POPs;
57
58 if (SvOK(data)) {
59 STRLEN len;
60 char *ptr = SvPV(data, len);
61 if (len > want)
62 croak("Too much data returned in reader callback");
63
64 memcpy(buffer, ptr, len);
65 result = len;
66 }
67 else {
68 result = -1;
69 }
70
71 PUTBACK;
72 FREETMPS;
73 LEAVE;
74
75 return result;
76}
77
78typedef struct
79{
80 SV *sv; /* a coderef or sub name */
81} i_writer_data;
82
83/* used by functions that want callbacks */
84static int write_callback(char *userdata, char const *data, int size) {
85 i_writer_data *wd = (i_writer_data *)userdata;
86 int count;
87 int success;
88 SV *sv;
89 dSP;
90
91 ENTER;
92 SAVETMPS;
93 EXTEND(SP, 1);
94 PUSHMARK(SP);
95 XPUSHs(sv_2mortal(newSVpv((char *)data, size)));
96 PUTBACK;
97
98 count = perl_call_sv(wd->sv, G_SCALAR);
99
100 SPAGAIN;
101
102 if (count != 1)
103 croak("Result of perl_call_sv(..., G_SCALAR) != 1");
104
105 sv = POPs;
106 success = SvTRUE(sv);
107
108
109 PUTBACK;
110 FREETMPS;
111 LEAVE;
112
113 return success;
114}
115
116struct value_name {
117 char *name;
118 int value;
119};
120static int lookup_name(struct value_name *names, int count, char *name, int def_value)
121{
122 int i;
123 for (i = 0; i < count; ++i)
124 if (strEQ(names[i].name, name))
125 return names[i].value;
126
127 return def_value;
128}
129static struct value_name transp_names[] =
130{
131 { "none", tr_none },
132 { "threshold", tr_threshold },
133 { "errdiff", tr_errdiff },
134 { "ordered", tr_ordered, },
135};
136
137static struct value_name make_color_names[] =
138{
139 { "none", mc_none, },
140 { "webmap", mc_web_map, },
141 { "addi", mc_addi, },
142};
143
144static struct value_name translate_names[] =
145{
146#ifdef HAVE_LIBGIF
147 { "giflib", pt_giflib, },
148#endif
149 { "closest", pt_closest, },
150 { "perturb", pt_perturb, },
151 { "errdiff", pt_errdiff, },
152};
153
154static struct value_name errdiff_names[] =
155{
156 { "floyd", ed_floyd, },
157 { "jarvis", ed_jarvis, },
158 { "stucki", ed_stucki, },
159 { "custom", ed_custom, },
160};
161
162static struct value_name orddith_names[] =
163{
164 { "random", od_random, },
165 { "dot8", od_dot8, },
166 { "dot4", od_dot4, },
167 { "hline", od_hline, },
168 { "vline", od_vline, },
169 { "/line", od_slashline, },
170 { "slashline", od_slashline, },
171 { "\\line", od_backline, },
172 { "backline", od_backline, },
e7d4ea82 173 { "tiny", od_tiny, },
02d1d628
AMH
174 { "custom", od_custom, },
175};
176
177/* look through the hash for quantization options */
178static void handle_quant_opts(i_quantize *quant, HV *hv)
179{
180 /*** POSSIBLY BROKEN: do I need to unref the SV from hv_fetch ***/
181 SV **sv;
182 int i;
183 STRLEN len;
184 char *str;
185
186 sv = hv_fetch(hv, "transp", 6, 0);
187 if (sv && *sv && (str = SvPV(*sv, len))) {
188 quant->transp =
189 lookup_name(transp_names, sizeof(transp_names)/sizeof(*transp_names),
190 str, tr_none);
191 if (quant->transp != tr_none) {
192 quant->tr_threshold = 127;
193 sv = hv_fetch(hv, "tr_threshold", 12, 0);
194 if (sv && *sv)
195 quant->tr_threshold = SvIV(*sv);
196 }
197 if (quant->transp == tr_errdiff) {
198 sv = hv_fetch(hv, "tr_errdiff", 10, 0);
199 if (sv && *sv && (str = SvPV(*sv, len)))
200 quant->tr_errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
201 }
202 if (quant->transp == tr_ordered) {
e7d4ea82 203 quant->tr_orddith = od_tiny;
02d1d628
AMH
204 sv = hv_fetch(hv, "tr_orddith", 10, 0);
205 if (sv && *sv && (str = SvPV(*sv, len)))
206 quant->tr_orddith = lookup_name(orddith_names, sizeof(orddith_names)/sizeof(*orddith_names), str, od_random);
207
208 if (quant->tr_orddith == od_custom) {
209 sv = hv_fetch(hv, "tr_map", 6, 0);
210 if (sv && *sv && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
211 AV *av = (AV*)SvRV(*sv);
212 len = av_len(av) + 1;
213 if (len > sizeof(quant->tr_custom))
214 len = sizeof(quant->tr_custom);
215 for (i = 0; i < len; ++i) {
216 SV **sv2 = av_fetch(av, i, 0);
217 if (sv2 && *sv2) {
218 quant->tr_custom[i] = SvIV(*sv2);
219 }
220 }
221 while (i < sizeof(quant->tr_custom))
222 quant->tr_custom[i++] = 0;
223 }
224 }
225 }
226 }
227 quant->make_colors = mc_addi;
228 sv = hv_fetch(hv, "make_colors", 11, 0);
229 if (sv && *sv && (str = SvPV(*sv, len))) {
230 quant->make_colors =
231 lookup_name(make_color_names, sizeof(make_color_names)/sizeof(*make_color_names), str, mc_addi);
232 }
233 sv = hv_fetch(hv, "colors", 6, 0);
234 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
235 /* needs to be an array of Imager::Color
236 note that the caller allocates the mc_color array and sets mc_size
237 to it's size */
238 AV *av = (AV *)SvRV(*sv);
239 quant->mc_count = av_len(av)+1;
240 if (quant->mc_count > quant->mc_size)
241 quant->mc_count = quant->mc_size;
242 for (i = 0; i < quant->mc_count; ++i) {
243 SV **sv1 = av_fetch(av, i, 0);
244 if (sv1 && *sv1 && SvROK(*sv1) && sv_derived_from(*sv1, "Imager::Color")) {
245 i_color *col = (i_color *)SvIV((SV*)SvRV(*sv1));
246 quant->mc_colors[i] = *col;
247 }
248 }
249 }
250 sv = hv_fetch(hv, "max_colors", 10, 0);
251 if (sv && *sv) {
252 i = SvIV(*sv);
253 if (i <= quant->mc_size && i >= quant->mc_count)
254 quant->mc_size = i;
255 }
256
257 quant->translate = pt_closest;
258 sv = hv_fetch(hv, "translate", 9, 0);
259 if (sv && *sv && (str = SvPV(*sv, len))) {
260 quant->translate = lookup_name(translate_names, sizeof(translate_names)/sizeof(*translate_names), str, pt_closest);
261 }
262 sv = hv_fetch(hv, "errdiff", 7, 0);
263 if (sv && *sv && (str = SvPV(*sv, len))) {
264 quant->errdiff = lookup_name(errdiff_names, sizeof(errdiff_names)/sizeof(*errdiff_names), str, ed_floyd);
265 }
266 if (quant->translate == pt_errdiff && quant->errdiff == ed_custom) {
267 /* get the error diffusion map */
268 sv = hv_fetch(hv, "errdiff_width", 13, 0);
269 if (sv && *sv)
270 quant->ed_width = SvIV(*sv);
271 sv = hv_fetch(hv, "errdiff_height", 14, 0);
272 if (sv && *sv)
273 quant->ed_height = SvIV(*sv);
274 sv = hv_fetch(hv, "errdiff_orig", 12, 0);
275 if (sv && *sv)
276 quant->ed_orig = SvIV(*sv);
277 if (quant->ed_width > 0 && quant->ed_height > 0) {
278 int sum = 0;
279 quant->ed_map = mymalloc(sizeof(int)*quant->ed_width*quant->ed_height);
280 sv = hv_fetch(hv, "errdiff_map", 11, 0);
281 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
282 AV *av = (AV*)SvRV(*sv);
283 len = av_len(av) + 1;
284 if (len > quant->ed_width * quant->ed_height)
285 len = quant->ed_width * quant->ed_height;
286 for (i = 0; i < len; ++i) {
287 SV **sv2 = av_fetch(av, i, 0);
288 if (sv2 && *sv2) {
289 quant->ed_map[i] = SvIV(*sv2);
290 sum += quant->ed_map[i];
291 }
292 }
293 }
294 if (!sum) {
295 /* broken map */
296 myfree(quant->ed_map);
297 quant->ed_map = 0;
298 quant->errdiff = ed_floyd;
299 }
300 }
301 }
302 sv = hv_fetch(hv, "perturb", 7, 0);
303 if (sv && *sv)
304 quant->perturb = SvIV(*sv);
305}
306
307/* look through the hash for options to add to opts */
308static void handle_gif_opts(i_gif_opts *opts, HV *hv)
309{
310 /*** FIXME: POSSIBLY BROKEN: do I need to unref the SV from hv_fetch? ***/
311 SV **sv;
312 int i;
313 /**((char *)0) = '\0';*/
314 sv = hv_fetch(hv, "gif_each_palette", 16, 0);
315 if (sv && *sv)
316 opts->each_palette = SvIV(*sv);
317 sv = hv_fetch(hv, "interlace", 9, 0);
318 if (sv && *sv)
319 opts->interlace = SvIV(*sv);
320 sv = hv_fetch(hv, "gif_delays", 10, 0);
321 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
322 AV *av = (AV*)SvRV(*sv);
323 opts->delay_count = av_len(av)+1;
324 opts->delays = mymalloc(sizeof(int) * opts->delay_count);
325 for (i = 0; i < opts->delay_count; ++i) {
326 SV *sv1 = *av_fetch(av, i, 0);
327 opts->delays[i] = SvIV(sv1);
328 }
329 }
330 sv = hv_fetch(hv, "gif_user_input", 14, 0);
331 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
332 AV *av = (AV*)SvRV(*sv);
333 opts->user_input_count = av_len(av)+1;
334 opts->user_input_flags = mymalloc(opts->user_input_count);
335 for (i = 0; i < opts->user_input_count; ++i) {
336 SV *sv1 = *av_fetch(av, i, 0);
337 opts->user_input_flags[i] = SvIV(sv1) != 0;
338 }
339 }
340 sv = hv_fetch(hv, "gif_disposal", 12, 0);
341 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
342 AV *av = (AV*)SvRV(*sv);
343 opts->disposal_count = av_len(av)+1;
344 opts->disposal = mymalloc(opts->disposal_count);
345 for (i = 0; i < opts->disposal_count; ++i) {
346 SV *sv1 = *av_fetch(av, i, 0);
347 opts->disposal[i] = SvIV(sv1);
348 }
349 }
350 sv = hv_fetch(hv, "gif_tran_color", 14, 0);
351 if (sv && *sv && SvROK(*sv) && sv_derived_from(*sv, "Imager::Color")) {
352 i_color *col = (i_color *)SvIV((SV *)SvRV(*sv));
353 opts->tran_color = *col;
354 }
355 sv = hv_fetch(hv, "gif_positions", 13, 0);
356 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
357 AV *av = (AV *)SvRV(*sv);
358 opts->position_count = av_len(av) + 1;
359 opts->positions = mymalloc(sizeof(i_gif_pos) * opts->position_count);
360 for (i = 0; i < opts->position_count; ++i) {
361 SV **sv2 = av_fetch(av, i, 0);
362 opts->positions[i].x = opts->positions[i].y = 0;
363 if (sv && *sv && SvROK(*sv) && SvTYPE(SvRV(*sv)) == SVt_PVAV) {
364 AV *av2 = (AV*)SvRV(*sv2);
365 SV **sv3;
366 sv3 = av_fetch(av2, 0, 0);
367 if (sv3 && *sv3)
368 opts->positions[i].x = SvIV(*sv3);
369 sv3 = av_fetch(av2, 1, 0);
370 if (sv3 && *sv3)
371 opts->positions[i].y = SvIV(*sv3);
372 }
373 }
374 }
375 /* Netscape2.0 loop count extension */
376 sv = hv_fetch(hv, "gif_loop_count", 14, 0);
377 if (sv && *sv)
378 opts->loop_count = SvIV(*sv);
379}
380
381/* copies the color map from the hv into the colors member of the HV */
382static void copy_colors_back(HV *hv, i_quantize *quant) {
383 SV **sv;
384 AV *av;
385 int i;
386 SV *work;
387
388 sv = hv_fetch(hv, "colors", 6, 0);
389 if (!sv || !*sv || !SvROK(*sv) || SvTYPE(SvRV(*sv)) != SVt_PVAV) {
390 SV *ref;
391 av = newAV();
392 ref = newRV_inc((SV*) av);
393 sv = hv_store(hv, "colors", 6, ref, 0);
394 }
395 else {
396 av = (AV *)SvRV(*sv);
397 }
398 av_extend(av, quant->mc_count+1);
399 for (i = 0; i < quant->mc_count; ++i) {
400 i_color *in = quant->mc_colors+i;
401 Imager__Color c = ICL_new_internal(in->rgb.r, in->rgb.g, in->rgb.b, 255);
402 work = sv_newmortal();
403 sv_setref_pv(work, "Imager::Color", (void *)c);
404 SvREFCNT_inc(work);
405 if (!av_store(av, i, work)) {
406 SvREFCNT_dec(work);
407 }
408 }
409}
410
02d1d628
AMH
411MODULE = Imager PACKAGE = Imager::Color PREFIX = ICL_
412
413Imager::Color
414ICL_new_internal(r,g,b,a)
415 unsigned char r
416 unsigned char g
417 unsigned char b
418 unsigned char a
419
420void
421ICL_DESTROY(cl)
422 Imager::Color cl
423
424
29106a11 425void
02d1d628
AMH
426ICL_set_internal(cl,r,g,b,a)
427 Imager::Color cl
428 unsigned char r
429 unsigned char g
430 unsigned char b
431 unsigned char a
29106a11 432 PPCODE:
46062ab6 433 ICL_set_internal(cl, r, g, b, a);
29106a11
TC
434 EXTEND(SP, 1);
435 PUSHs(ST(0));
02d1d628
AMH
436
437void
438ICL_info(cl)
439 Imager::Color cl
440
441
442void
443ICL_rgba(cl)
444 Imager::Color cl
445 PPCODE:
446 EXTEND(SP, 4);
447 PUSHs(sv_2mortal(newSVnv(cl->rgba.r)));
448 PUSHs(sv_2mortal(newSVnv(cl->rgba.g)));
449 PUSHs(sv_2mortal(newSVnv(cl->rgba.b)));
450 PUSHs(sv_2mortal(newSVnv(cl->rgba.a)));
451
452
453
454
455
456
457
458MODULE = Imager PACKAGE = Imager::ImgRaw PREFIX = IIM_
459
460Imager::ImgRaw
461IIM_new(x,y,ch)
462 int x
463 int y
464 int ch
465
466void
467IIM_DESTROY(im)
468 Imager::ImgRaw im
469
470
471
472MODULE = Imager PACKAGE = Imager
473
474PROTOTYPES: ENABLE
475
476
477Imager::IO
478io_new_fd(fd)
479 int fd
480
481Imager::IO
482io_new_bufchain()
483
484
485void
486io_slurp(ig)
487 Imager::IO ig
488 PREINIT:
489 unsigned char* data;
490 size_t tlength;
491 SV* r;
492 PPCODE:
493 data = NULL;
494 tlength = io_slurp(ig, &data);
495 r = sv_newmortal();
496 EXTEND(SP,1);
497 PUSHs(sv_2mortal(newSVpv(data,tlength)));
498 myfree(data);
499
500
501
502void
503i_list_formats()
504 PREINIT:
505 char* item;
506 int i;
507 PPCODE:
508 i=0;
509 while( (item=i_format_list[i++]) != NULL ) {
510 EXTEND(SP, 1);
511 PUSHs(sv_2mortal(newSVpv(item,0)));
512 }
513
514undef_int
515i_has_format(frmt)
516 char* frmt
517
518Imager::ImgRaw
519i_img_new()
520
521Imager::ImgRaw
522i_img_empty(im,x,y)
523 Imager::ImgRaw im
524 int x
525 int y
526
527Imager::ImgRaw
528i_img_empty_ch(im,x,y,ch)
529 Imager::ImgRaw im
530 int x
531 int y
532 int ch
533
534void
535init_log(name,level)
536 char* name
537 int level
538
539void
540i_img_exorcise(im)
541 Imager::ImgRaw im
542
543void
544i_img_destroy(im)
545 Imager::ImgRaw im
546
547void
548i_img_info(im)
549 Imager::ImgRaw im
550 PREINIT:
551 int info[4];
552 PPCODE:
553 i_img_info(im,info);
554 EXTEND(SP, 4);
555 PUSHs(sv_2mortal(newSViv(info[0])));
556 PUSHs(sv_2mortal(newSViv(info[1])));
557 PUSHs(sv_2mortal(newSViv(info[2])));
558 PUSHs(sv_2mortal(newSViv(info[3])));
559
560
561
562
563void
564i_img_setmask(im,ch_mask)
565 Imager::ImgRaw im
566 int ch_mask
567
568int
569i_img_getmask(im)
570 Imager::ImgRaw im
571
572int
573i_img_getchannels(im)
574 Imager::ImgRaw im
575
576void
577i_img_getdata(im)
578 Imager::ImgRaw im
579 PPCODE:
580 EXTEND(SP, 1);
581 PUSHs(sv_2mortal(newSVpv(im->data, im->bytes)));
582
583
584void
585i_draw(im,x1,y1,x2,y2,val)
586 Imager::ImgRaw im
587 int x1
588 int y1
589 int x2
590 int y2
591 Imager::Color val
592
593void
594i_line_aa(im,x1,y1,x2,y2,val)
595 Imager::ImgRaw im
596 int x1
597 int y1
598 int x2
599 int y2
600 Imager::Color val
601
602void
603i_box(im,x1,y1,x2,y2,val)
604 Imager::ImgRaw im
605 int x1
606 int y1
607 int x2
608 int y2
609 Imager::Color val
610
611void
612i_box_filled(im,x1,y1,x2,y2,val)
613 Imager::ImgRaw im
614 int x1
615 int y1
616 int x2
617 int y2
618 Imager::Color val
619
620void
621i_arc(im,x,y,rad,d1,d2,val)
622 Imager::ImgRaw im
623 int x
624 int y
625 float rad
626 float d1
627 float d2
628 Imager::Color val
629
630
631
6af18d2b
AMH
632void
633i_circle_aa(im,x,y,rad,val)
634 Imager::ImgRaw im
635 float x
636 float y
637 float rad
638 Imager::Color val
639
640
641
02d1d628
AMH
642void
643i_bezier_multi(im,xc,yc,val)
644 Imager::ImgRaw im
645 Imager::Color val
646 PREINIT:
647 double *x,*y;
648 int len;
649 AV *av1;
650 AV *av2;
651 SV *sv1;
652 SV *sv2;
653 int i;
654 PPCODE:
655 ICL_info(val);
656 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
657 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_bezier_multi must be a reference to an array\n");
658 if (!SvROK(ST(2))) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
659 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 to i_bezier_multi must be a reference to an array\n");
660 av1=(AV*)SvRV(ST(1));
661 av2=(AV*)SvRV(ST(2));
662 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_bezier_multi must be equal length\n");
663 len=av_len(av1)+1;
664 x=mymalloc( len*sizeof(double) );
665 y=mymalloc( len*sizeof(double) );
666 for(i=0;i<len;i++) {
667 sv1=(*(av_fetch(av1,i,0)));
668 sv2=(*(av_fetch(av2,i,0)));
669 x[i]=(double)SvNV(sv1);
670 y[i]=(double)SvNV(sv2);
671 }
672 i_bezier_multi(im,len,x,y,val);
673 myfree(x);
674 myfree(y);
675
676
677void
678i_poly_aa(im,xc,yc,val)
679 Imager::ImgRaw im
680 Imager::Color val
681 PREINIT:
682 double *x,*y;
683 int len;
684 AV *av1;
685 AV *av2;
686 SV *sv1;
687 SV *sv2;
688 int i;
689 PPCODE:
690 ICL_info(val);
691 if (!SvROK(ST(1))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
692 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
693 if (!SvROK(ST(2))) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
694 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 1 to i_poly_aa must be a reference to an array\n");
695 av1=(AV*)SvRV(ST(1));
696 av2=(AV*)SvRV(ST(2));
697 if (av_len(av1) != av_len(av2)) croak("Imager: x and y arrays to i_poly_aa must be equal length\n");
698 len=av_len(av1)+1;
699 x=mymalloc( len*sizeof(double) );
700 y=mymalloc( len*sizeof(double) );
701 for(i=0;i<len;i++) {
702 sv1=(*(av_fetch(av1,i,0)));
703 sv2=(*(av_fetch(av2,i,0)));
704 x[i]=(double)SvNV(sv1);
705 y[i]=(double)SvNV(sv2);
706 }
707 i_poly_aa(im,len,x,y,val);
708 myfree(x);
709 myfree(y);
710
711
712
713void
714i_flood_fill(im,seedx,seedy,dcol)
715 Imager::ImgRaw im
716 int seedx
717 int seedy
718 Imager::Color dcol
719
720
721void
722i_copyto(im,src,x1,y1,x2,y2,tx,ty)
723 Imager::ImgRaw im
724 Imager::ImgRaw src
725 int x1
726 int y1
727 int x2
728 int y2
729 int tx
730 int ty
731
732
733void
734i_copyto_trans(im,src,x1,y1,x2,y2,tx,ty,trans)
735 Imager::ImgRaw im
736 Imager::ImgRaw src
737 int x1
738 int y1
739 int x2
740 int y2
741 int tx
742 int ty
743 Imager::Color trans
744
745void
746i_copy(im,src)
747 Imager::ImgRaw im
748 Imager::ImgRaw src
749
750
751void
752i_rubthru(im,src,tx,ty)
753 Imager::ImgRaw im
754 Imager::ImgRaw src
755 int tx
756 int ty
757
142c26ff
AMH
758undef_int
759i_flipxy(im, direction)
760 Imager::ImgRaw im
761 int direction
762
02d1d628
AMH
763
764void
765i_gaussian(im,stdev)
766 Imager::ImgRaw im
767 float stdev
768
769void
770i_conv(im,pcoef)
771 Imager::ImgRaw im
772 PREINIT:
773 float* coeff;
774 int len;
775 AV* av;
776 SV* sv1;
777 int i;
778 PPCODE:
779 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
780 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
781 av=(AV*)SvRV(ST(1));
782 len=av_len(av)+1;
783 coeff=mymalloc( len*sizeof(float) );
784 for(i=0;i<len;i++) {
785 sv1=(*(av_fetch(av,i,0)));
786 coeff[i]=(float)SvNV(sv1);
787 }
788 i_conv(im,coeff,len);
789 myfree(coeff);
790
f5991c03
TC
791undef_int
792i_convert(im, src, coeff)
793 Imager::ImgRaw im
794 Imager::ImgRaw src
795 PREINIT:
796 float *coeff;
797 int outchan;
798 int inchan;
799 AV *avmain;
800 SV **temp;
801 SV *svsub;
802 AV *avsub;
803 int len;
804 int i, j;
805 CODE:
f5991c03
TC
806 if (!SvROK(ST(2)) || SvTYPE(SvRV(ST(2))) != SVt_PVAV)
807 croak("i_convert: parameter 3 must be an arrayref\n");
808 avmain = (AV*)SvRV(ST(2));
809 outchan = av_len(avmain)+1;
810 /* find the biggest */
811 inchan = 0;
812 for (j=0; j < outchan; ++j) {
813 temp = av_fetch(avmain, j, 0);
814 if (temp && SvROK(*temp) && SvTYPE(SvRV(*temp)) == SVt_PVAV) {
815 avsub = (AV*)SvRV(*temp);
816 len = av_len(avsub)+1;
817 if (len > inchan)
818 inchan = len;
819 }
820 }
821 coeff = mymalloc(sizeof(float) * outchan * inchan);
822 for (j = 0; j < outchan; ++j) {
823 avsub = (AV*)SvRV(*av_fetch(avmain, j, 0));
824 len = av_len(avsub)+1;
825 for (i = 0; i < len; ++i) {
826 temp = av_fetch(avsub, i, 0);
827 if (temp)
828 coeff[i+j*inchan] = SvNV(*temp);
829 else
830 coeff[i+j*inchan] = 0;
831 }
832 while (i < inchan)
833 coeff[i++ + j*inchan] = 0;
834 }
835 RETVAL = i_convert(im, src, coeff, outchan, inchan);
836 myfree(coeff);
f5991c03
TC
837 OUTPUT:
838 RETVAL
40eba1ea
AMH
839
840
841void
842i_map(im, pmaps)
843 Imager::ImgRaw im
844 PREINIT:
845 unsigned int mask = 0;
846 AV *avmain;
847 AV *avsub;
848 SV **temp;
849 int len;
850 int i, j;
851 unsigned char (*maps)[256];
852 CODE:
853 if (!SvROK(ST(1)) || SvTYPE(SvRV(ST(1))) != SVt_PVAV)
854 croak("i_map: parameter 2 must be an arrayref\n");
855 avmain = (AV*)SvRV(ST(1));
856 len = av_len(avmain)+1;
857 if (im->channels < len) len = im->channels;
858
859 maps = mymalloc( len * sizeof(unsigned char [256]) );
860
861 for (j=0; j<len ; j++) {
862 temp = av_fetch(avmain, j, 0);
863 if (temp && SvROK(*temp) && (SvTYPE(SvRV(*temp)) == SVt_PVAV) ) {
864 avsub = (AV*)SvRV(*temp);
865 if(av_len(avsub) != 255) continue;
866 mask |= 1<<j;
867 for (i=0; i<256 ; i++) {
9495ee93 868 int val;
40eba1ea 869 temp = av_fetch(avsub, i, 0);
9495ee93
AMH
870 val = temp ? SvIV(*temp) : 0;
871 if (val<0) val = 0;
872 if (val>255) val = 255;
873 maps[j][i] = val;
40eba1ea
AMH
874 }
875 }
876 }
877 i_map(im, maps, mask);
878 myfree(maps);
879
880
881
02d1d628
AMH
882float
883i_img_diff(im1,im2)
884 Imager::ImgRaw im1
885 Imager::ImgRaw im2
886
887
888
889undef_int
890i_init_fonts()
891
892#ifdef HAVE_LIBT1
893
894void
895i_t1_set_aa(st)
896 int st
897
898int
899i_t1_new(pfb,afm=NULL)
900 char* pfb
901 char* afm
902
903int
904i_t1_destroy(font_id)
905 int font_id
906
907
908undef_int
909i_t1_cp(im,xb,yb,channel,fontnum,points,str,len,align)
910 Imager::ImgRaw im
911 int xb
912 int yb
913 int channel
914 int fontnum
915 float points
916 char* str
917 int len
918 int align
919
920void
921i_t1_bbox(fontnum,point,str,len)
922 int fontnum
923 float point
924 char* str
925 int len
926 PREINIT:
927 int cords[6];
928 PPCODE:
929 i_t1_bbox(fontnum,point,str,len,cords);
930 EXTEND(SP, 4);
931 PUSHs(sv_2mortal(newSViv(cords[0])));
932 PUSHs(sv_2mortal(newSViv(cords[1])));
933 PUSHs(sv_2mortal(newSViv(cords[2])));
934 PUSHs(sv_2mortal(newSViv(cords[3])));
935 PUSHs(sv_2mortal(newSViv(cords[4])));
936 PUSHs(sv_2mortal(newSViv(cords[5])));
937
938
939
940undef_int
941i_t1_text(im,xb,yb,cl,fontnum,points,str,len,align)
942 Imager::ImgRaw im
943 int xb
944 int yb
945 Imager::Color cl
946 int fontnum
947 float points
948 char* str
949 int len
950 int align
951
952#endif
953
954#ifdef HAVE_LIBTT
955
956
957Imager::TTHandle
958i_tt_new(fontname)
959 char* fontname
960
961void
962i_tt_destroy(handle)
963 Imager::TTHandle handle
964
965
966
967undef_int
968i_tt_text(handle,im,xb,yb,cl,points,str,len,smooth)
969 Imager::TTHandle handle
970 Imager::ImgRaw im
971 int xb
972 int yb
973 Imager::Color cl
974 float points
975 char* str
976 int len
977 int smooth
978
979
980undef_int
981i_tt_cp(handle,im,xb,yb,channel,points,str,len,smooth)
982 Imager::TTHandle handle
983 Imager::ImgRaw im
984 int xb
985 int yb
986 int channel
987 float points
988 char* str
989 int len
990 int smooth
991
992
993
994undef_int
995i_tt_bbox(handle,point,str,len)
996 Imager::TTHandle handle
997 float point
998 char* str
999 int len
1000 PREINIT:
1001 int cords[6],rc;
1002 PPCODE:
1003 if ((rc=i_tt_bbox(handle,point,str,len,cords))) {
1004 EXTEND(SP, 4);
1005 PUSHs(sv_2mortal(newSViv(cords[0])));
1006 PUSHs(sv_2mortal(newSViv(cords[1])));
1007 PUSHs(sv_2mortal(newSViv(cords[2])));
1008 PUSHs(sv_2mortal(newSViv(cords[3])));
1009 PUSHs(sv_2mortal(newSViv(cords[4])));
1010 PUSHs(sv_2mortal(newSViv(cords[5])));
1011 }
1012
1013
1014#endif
1015
1016
1017
1018
1019#ifdef HAVE_LIBJPEG
1020undef_int
1021i_writejpeg(im,fd,qfactor)
1022 Imager::ImgRaw im
1023 int fd
1024 int qfactor
1025
1026void
1027i_readjpeg(fd)
1028 int fd
1029 PREINIT:
1030 char* iptc_itext;
1031 int tlength;
1032 i_img* rimg;
1033 SV* r;
1034 PPCODE:
1035 iptc_itext = NULL;
1036 rimg=i_readjpeg(fd,&iptc_itext,&tlength);
1037 if (iptc_itext == NULL) {
1038 r = sv_newmortal();
1039 EXTEND(SP,1);
1040 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1041 PUSHs(r);
1042 } else {
1043 r = sv_newmortal();
1044 EXTEND(SP,2);
1045 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1046 PUSHs(r);
1047 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1048 myfree(iptc_itext);
1049 }
1050
1051
1052void
1053i_readjpeg_scalar(...)
1054 PROTOTYPE: $
1055 PREINIT:
1056 char* data;
1057 unsigned int length;
1058 char* iptc_itext;
1059 int tlength;
1060 i_img* rimg;
1061 SV* r;
1062 PPCODE:
1063 iptc_itext = NULL;
1064 data = (char *)SvPV(ST(0), length);
1065 rimg=i_readjpeg_scalar(data,length,&iptc_itext,&tlength);
1066 mm_log((1,"i_readjpeg_scalar: 0x%08X\n",rimg));
1067 if (iptc_itext == NULL) {
1068 r = sv_newmortal();
1069 EXTEND(SP,1);
1070 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1071 PUSHs(r);
1072 } else {
1073 r = sv_newmortal();
1074 EXTEND(SP,2);
1075 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1076 PUSHs(r);
1077 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1078 myfree(iptc_itext);
1079 }
1080
1081
1082void
1083i_readjpeg_wiol(ig)
1084 Imager::IO ig
1085 PREINIT:
1086 char* iptc_itext;
1087 int tlength;
1088 i_img* rimg;
1089 SV* r;
1090 PPCODE:
1091 iptc_itext = NULL;
1092 rimg = i_readjpeg_wiol(ig,-1,&iptc_itext,&tlength);
1093 if (iptc_itext == NULL) {
1094 r = sv_newmortal();
1095 EXTEND(SP,1);
1096 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1097 PUSHs(r);
1098 } else {
1099 r = sv_newmortal();
1100 EXTEND(SP,2);
1101 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1102 PUSHs(r);
1103 PUSHs(sv_2mortal(newSVpv(iptc_itext,tlength)));
1104 myfree(iptc_itext);
1105 }
1106
1107
1108#endif
1109
1110
1111
1112
1113#ifdef HAVE_LIBTIFF
1114
1115Imager::ImgRaw
1116i_readtiff_wiol(ig, length)
1117 Imager::IO ig
1118 int length
1119
1120
1121undef_int
1122i_writetiff_wiol(im, ig)
1123 Imager::ImgRaw im
1124 Imager::IO ig
1125
d2dfdcc9 1126undef_int
4c2d6970 1127i_writetiff_wiol_faxable(im, ig, fine)
d2dfdcc9
TC
1128 Imager::ImgRaw im
1129 Imager::IO ig
4c2d6970 1130 int fine
d2dfdcc9 1131
02d1d628
AMH
1132
1133#endif /* HAVE_LIBTIFF */
1134
1135
1136
1137
1138
1139#ifdef HAVE_LIBPNG
1140
1141Imager::ImgRaw
790923a4
AMH
1142i_readpng_wiol(ig, length)
1143 Imager::IO ig
1144 int length
02d1d628
AMH
1145
1146
1147undef_int
790923a4 1148i_writepng_wiol(im, ig)
02d1d628 1149 Imager::ImgRaw im
790923a4 1150 Imager::IO ig
02d1d628
AMH
1151
1152
1153#endif
1154
1155
1156#ifdef HAVE_LIBGIF
1157
03bd24d4
TC
1158void
1159i_giflib_version()
1160 PPCODE:
1161 PUSHs(sv_2mortal(newSVnv(IM_GIFMAJOR+IM_GIFMINOR*0.1)));
1162
02d1d628
AMH
1163undef_int
1164i_writegif(im,fd,colors,pixdev,fixed)
1165 Imager::ImgRaw im
1166 int fd
1167 int colors
1168 int pixdev
1169 PREINIT:
1170 int fixedlen;
1171 Imager__Color fixed;
1172 Imager__Color tmp;
1173 AV* av;
1174 SV* sv1;
1175 IV Itmp;
1176 int i;
1177 CODE:
1178 if (!SvROK(ST(4))) croak("Imager: Parameter 4 must be a reference to an array\n");
1179 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1180 av=(AV*)SvRV(ST(4));
1181 fixedlen=av_len(av)+1;
1182 fixed=mymalloc( fixedlen*sizeof(i_color) );
1183 for(i=0;i<fixedlen;i++) {
1184 sv1=(*(av_fetch(av,i,0)));
1185 if (sv_derived_from(sv1, "Imager::Color")) {
1186 Itmp = SvIV((SV*)SvRV(sv1));
1187 tmp = (i_color*) Itmp;
1188 } else croak("Imager: one of the elements of array ref is not of Imager::Color type\n");
1189 fixed[i]=*tmp;
1190 }
1191 RETVAL=i_writegif(im,fd,colors,pixdev,fixedlen,fixed);
1192 myfree(fixed);
1193 ST(0) = sv_newmortal();
1194 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1195 else sv_setiv(ST(0), (IV)RETVAL);
1196
1197
1198
1199
1200undef_int
1201i_writegifmc(im,fd,colors)
067d6bdc 1202 Imager::ImgRaw im
02d1d628
AMH
1203 int fd
1204 int colors
1205
02d1d628
AMH
1206
1207undef_int
1208i_writegif_gen(fd, ...)
1209 int fd
1210 PROTOTYPE: $$@
1211 PREINIT:
1212 i_quantize quant;
1213 i_gif_opts opts;
1214 i_img **imgs = NULL;
1215 int img_count;
1216 int i;
1217 HV *hv;
1218 CODE:
1219 if (items < 3)
1220 croak("Usage: i_writegif_gen(fd,hashref, images...)");
1221 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1222 croak("i_writegif_gen: Second argument must be a hash ref");
1223 hv = (HV *)SvRV(ST(1));
1224 memset(&quant, 0, sizeof(quant));
1225 quant.mc_size = 256;
1226 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1227 memset(&opts, 0, sizeof(opts));
1228 handle_quant_opts(&quant, hv);
1229 handle_gif_opts(&opts, hv);
1230 img_count = items - 2;
1231 RETVAL = 1;
1232 if (img_count < 1) {
1233 RETVAL = 0;
95b44a76
TC
1234 i_clear_error();
1235 i_push_error(0, "You need to specify images to save");
02d1d628
AMH
1236 }
1237 else {
1238 imgs = mymalloc(sizeof(i_img *) * img_count);
1239 for (i = 0; i < img_count; ++i) {
1240 SV *sv = ST(2+i);
1241 imgs[i] = NULL;
1242 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1243 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1244 }
1245 else {
95b44a76
TC
1246 i_clear_error();
1247 i_push_error(0, "Only images can be saved");
02d1d628
AMH
1248 RETVAL = 0;
1249 break;
1250 }
1251 }
1252 if (RETVAL) {
1253 RETVAL = i_writegif_gen(&quant, fd, imgs, img_count, &opts);
1254 }
1255 myfree(imgs);
1256 if (RETVAL) {
1257 copy_colors_back(hv, &quant);
1258 }
1259 }
1260 ST(0) = sv_newmortal();
1261 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1262 else sv_setiv(ST(0), (IV)RETVAL);
1263
1264undef_int
1265i_writegif_callback(cb, maxbuffer,...)
1266 int maxbuffer;
1267 PREINIT:
1268 i_quantize quant;
1269 i_gif_opts opts;
1270 i_img **imgs = NULL;
1271 int img_count;
1272 int i;
1273 HV *hv;
1274 i_writer_data wd;
1275 CODE:
1276 if (items < 4)
1277 croak("Usage: i_writegif_callback(\\&callback,maxbuffer,hashref, images...)");
1278 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1279 croak("i_writegif_callback: Second argument must be a hash ref");
1280 hv = (HV *)SvRV(ST(2));
1281 memset(&quant, 0, sizeof(quant));
1282 quant.mc_size = 256;
1283 quant.mc_colors = mymalloc(quant.mc_size * sizeof(i_color));
1284 memset(&opts, 0, sizeof(opts));
1285 handle_quant_opts(&quant, hv);
1286 handle_gif_opts(&opts, hv);
1287 img_count = items - 3;
1288 RETVAL = 1;
1289 if (img_count < 1) {
1290 RETVAL = 0;
1291 }
1292 else {
1293 imgs = mymalloc(sizeof(i_img *) * img_count);
1294 for (i = 0; i < img_count; ++i) {
1295 SV *sv = ST(3+i);
1296 imgs[i] = NULL;
1297 if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
1298 imgs[i] = (i_img *)SvIV((SV*)SvRV(sv));
1299 }
1300 else {
1301 RETVAL = 0;
1302 break;
1303 }
1304 }
1305 if (RETVAL) {
1306 wd.sv = ST(0);
1307 RETVAL = i_writegif_callback(&quant, write_callback, (char *)&wd, maxbuffer, imgs, img_count, &opts);
1308 }
1309 myfree(imgs);
1310 if (RETVAL) {
1311 copy_colors_back(hv, &quant);
1312 }
1313 }
1314 ST(0) = sv_newmortal();
1315 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1316 else sv_setiv(ST(0), (IV)RETVAL);
1317
1318void
1319i_readgif(fd)
1320 int fd
1321 PREINIT:
1322 int* colour_table;
1323 int colours, q, w;
1324 i_img* rimg;
1325 SV* temp[3];
1326 AV* ct;
1327 SV* r;
1328 PPCODE:
1329 colour_table = NULL;
1330 colours = 0;
1331
895dbd34 1332 if(GIMME_V == G_ARRAY) {
02d1d628
AMH
1333 rimg = i_readgif(fd,&colour_table,&colours);
1334 } else {
1335 /* don't waste time with colours if they aren't wanted */
1336 rimg = i_readgif(fd,NULL,NULL);
1337 }
895dbd34 1338
02d1d628
AMH
1339 if (colour_table == NULL) {
1340 EXTEND(SP,1);
1341 r=sv_newmortal();
1342 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1343 PUSHs(r);
1344 } else {
1345 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1346 /* I don't know if I have the reference counts right or not :( */
1347 /* Neither do I :-) */
1348 /* No Idea here either */
1349
1350 ct=newAV();
1351 av_extend(ct, colours);
1352 for(q=0; q<colours; q++) {
1353 for(w=0; w<3; w++)
1354 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1355 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1356 }
1357 myfree(colour_table);
895dbd34 1358
02d1d628 1359 EXTEND(SP,2);
895dbd34 1360 r = sv_newmortal();
02d1d628
AMH
1361 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1362 PUSHs(r);
1363 PUSHs(newRV_noinc((SV*)ct));
1364 }
1365
1366
1367
1368
1369
1370void
1371i_readgif_scalar(...)
1372 PROTOTYPE: $
1373 PREINIT:
1374 char* data;
1375 unsigned int length;
1376 int* colour_table;
1377 int colours, q, w;
1378 i_img* rimg;
1379 SV* temp[3];
1380 AV* ct;
1381 SV* r;
1382 PPCODE:
1383 data = (char *)SvPV(ST(0), length);
1384 colour_table=NULL;
1385 colours=0;
1386
1387 if(GIMME_V == G_ARRAY) {
1388 rimg=i_readgif_scalar(data,length,&colour_table,&colours);
1389 } else {
1390 /* don't waste time with colours if they aren't wanted */
1391 rimg=i_readgif_scalar(data,length,NULL,NULL);
1392 }
1393
1394 if (colour_table == NULL) {
1395 EXTEND(SP,1);
1396 r=sv_newmortal();
1397 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1398 PUSHs(r);
1399 } else {
1400 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1401 /* I don't know if I have the reference counts right or not :( */
1402 /* Neither do I :-) */
1403 ct=newAV();
1404 av_extend(ct, colours);
1405 for(q=0; q<colours; q++) {
1406 for(w=0; w<3; w++)
1407 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1408 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1409 }
1410 myfree(colour_table);
1411
1412 EXTEND(SP,2);
1413 r=sv_newmortal();
1414 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1415 PUSHs(r);
1416 PUSHs(newRV_noinc((SV*)ct));
1417 }
1418
1419void
1420i_readgif_callback(...)
1421 PROTOTYPE: &
1422 PREINIT:
1423 char* data;
1424 int length;
1425 int* colour_table;
1426 int colours, q, w;
1427 i_img* rimg;
1428 SV* temp[3];
1429 AV* ct;
1430 SV* r;
1431 i_reader_data rd;
1432 PPCODE:
1433 rd.sv = ST(0);
1434 colour_table=NULL;
1435 colours=0;
1436
1437 if(GIMME_V == G_ARRAY) {
1438 rimg=i_readgif_callback(read_callback, (char *)&rd,&colour_table,&colours);
1439 } else {
1440 /* don't waste time with colours if they aren't wanted */
1441 rimg=i_readgif_callback(read_callback, (char *)&rd,NULL,NULL);
1442 }
1443
1444 if (colour_table == NULL) {
1445 EXTEND(SP,1);
1446 r=sv_newmortal();
1447 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1448 PUSHs(r);
1449 } else {
1450 /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
1451 /* I don't know if I have the reference counts right or not :( */
1452 /* Neither do I :-) */
1453 /* Neither do I - maybe I'll move this somewhere */
1454 ct=newAV();
1455 av_extend(ct, colours);
1456 for(q=0; q<colours; q++) {
1457 for(w=0; w<3; w++)
1458 temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
1459 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
1460 }
1461 myfree(colour_table);
1462
1463 EXTEND(SP,2);
1464 r=sv_newmortal();
1465 sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
1466 PUSHs(r);
1467 PUSHs(newRV_noinc((SV*)ct));
1468 }
1469
1470
1471
1472
1473
1474
1475#endif
1476
1477
1478
1479Imager::ImgRaw
1480i_readpnm_wiol(ig, length)
1481 Imager::IO ig
1482 int length
1483
1484
067d6bdc
AMH
1485undef_int
1486i_writeppm_wiol(im, ig)
1487 Imager::ImgRaw im
1488 Imager::IO ig
1489
1490
02d1d628 1491Imager::ImgRaw
895dbd34
AMH
1492i_readraw_wiol(ig,x,y,datachannels,storechannels,intrl)
1493 Imager::IO ig
02d1d628
AMH
1494 int x
1495 int y
1496 int datachannels
1497 int storechannels
1498 int intrl
1499
1500undef_int
895dbd34 1501i_writeraw_wiol(im,ig)
02d1d628 1502 Imager::ImgRaw im
895dbd34
AMH
1503 Imager::IO ig
1504
02d1d628
AMH
1505
1506
1507Imager::ImgRaw
1508i_scaleaxis(im,Value,Axis)
1509 Imager::ImgRaw im
1510 float Value
1511 int Axis
1512
1513Imager::ImgRaw
1514i_scale_nn(im,scx,scy)
1515 Imager::ImgRaw im
1516 float scx
1517 float scy
1518
1519Imager::ImgRaw
1520i_haar(im)
1521 Imager::ImgRaw im
1522
1523int
1524i_count_colors(im,maxc)
1525 Imager::ImgRaw im
1526 int maxc
1527
1528
1529Imager::ImgRaw
1530i_transform(im,opx,opy,parm)
1531 Imager::ImgRaw im
1532 PREINIT:
1533 double* parm;
1534 int* opx;
1535 int* opy;
1536 int opxl;
1537 int opyl;
1538 int parmlen;
1539 AV* av;
1540 SV* sv1;
1541 int i;
1542 CODE:
1543 if (!SvROK(ST(1))) croak("Imager: Parameter 1 must be a reference to an array\n");
1544 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to an array\n");
1545 if (!SvROK(ST(3))) croak("Imager: Parameter 3 must be a reference to an array\n");
1546 if (SvTYPE(SvRV(ST(1))) != SVt_PVAV) croak("Imager: Parameter 1 must be a reference to an array\n");
1547 if (SvTYPE(SvRV(ST(2))) != SVt_PVAV) croak("Imager: Parameter 2 must be a reference to an array\n");
1548 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 3 must be a reference to an array\n");
1549 av=(AV*)SvRV(ST(1));
1550 opxl=av_len(av)+1;
1551 opx=mymalloc( opxl*sizeof(int) );
1552 for(i=0;i<opxl;i++) {
1553 sv1=(*(av_fetch(av,i,0)));
1554 opx[i]=(int)SvIV(sv1);
1555 }
1556 av=(AV*)SvRV(ST(2));
1557 opyl=av_len(av)+1;
1558 opy=mymalloc( opyl*sizeof(int) );
1559 for(i=0;i<opyl;i++) {
1560 sv1=(*(av_fetch(av,i,0)));
1561 opy[i]=(int)SvIV(sv1);
1562 }
1563 av=(AV*)SvRV(ST(3));
1564 parmlen=av_len(av)+1;
1565 parm=mymalloc( parmlen*sizeof(double) );
1566 for(i=0;i<parmlen;i++) { /* FIXME: Bug? */
1567 sv1=(*(av_fetch(av,i,0)));
1568 parm[i]=(double)SvNV(sv1);
1569 }
1570 RETVAL=i_transform(im,opx,opxl,opy,opyl,parm,parmlen);
1571 myfree(parm);
1572 myfree(opy);
1573 myfree(opx);
1574 ST(0) = sv_newmortal();
1575 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1576 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1577
1578Imager::ImgRaw
1579i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
1580 PREINIT:
1581 int width;
1582 int height;
1583 double* parm;
1584 struct rm_op *ops;
1585 unsigned int ops_len;
1586 int ops_count;
1587 double *n_regs;
1588 int n_regs_count;
1589 i_color *c_regs;
1590 int c_regs_count;
1591 int in_imgs_count;
1592 i_img **in_imgs;
1593 AV* av;
1594 SV* sv1;
1595 IV tmp;
1596 int i;
1597 CODE:
1598 if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
1599 if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n");
1600 if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n");
1601 if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n");
1602 if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n");
1603
1604 /*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/
1605
1606 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1607 av = (AV*)SvRV(ST(5));
1608 in_imgs_count = av_len(av)+1;
1609 for (i = 0; i < in_imgs_count; ++i) {
1610 sv1 = *av_fetch(av, i, 0);
1611 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1612 croak("Parameter 5 must contain only images");
1613 }
1614 }
1615 }
1616 else {
1617 in_imgs_count = 0;
1618 }
1619 if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
1620 av = (AV*)SvRV(ST(5));
1621 in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
1622 for (i = 0; i < in_imgs_count; ++i) {
1623 sv1 = *av_fetch(av,i,0);
1624 if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
1625 croak("Parameter 5 must contain only images");
1626 }
1627 tmp = SvIV((SV*)SvRV(sv1));
1628 in_imgs[i] = (i_img*)tmp;
1629 }
1630 }
1631 else {
1632 /* no input images */
1633 in_imgs = NULL;
1634 }
1635 /* default the output size from the first input if possible */
1636 if (SvOK(ST(0)))
1637 width = SvIV(ST(0));
1638 else if (in_imgs_count)
1639 width = in_imgs[0]->xsize;
1640 else
1641 croak("No output image width supplied");
1642
1643 if (SvOK(ST(1)))
1644 height = SvIV(ST(1));
1645 else if (in_imgs_count)
1646 height = in_imgs[0]->ysize;
1647 else
1648 croak("No output image height supplied");
1649
1650 ops = (struct rm_op *)SvPV(ST(2), ops_len);
1651 if (ops_len % sizeof(struct rm_op))
1652 croak("Imager: Parameter 3 must be a bitmap of regops\n");
1653 ops_count = ops_len / sizeof(struct rm_op);
1654 av = (AV*)SvRV(ST(3));
1655 n_regs_count = av_len(av)+1;
1656 n_regs = mymalloc(n_regs_count * sizeof(double));
1657 for (i = 0; i < n_regs_count; ++i) {
1658 sv1 = *av_fetch(av,i,0);
1659 if (SvOK(sv1))
1660 n_regs[i] = SvNV(sv1);
1661 }
1662 av = (AV*)SvRV(ST(4));
1663 c_regs_count = av_len(av)+1;
1664 c_regs = mymalloc(c_regs_count * sizeof(i_color));
1665 /* I don't bother initializing the colou?r registers */
1666
1667 RETVAL=i_transform2(width, height, 3, ops, ops_count,
1668 n_regs, n_regs_count,
1669 c_regs, c_regs_count, in_imgs, in_imgs_count);
1670 if (in_imgs)
1671 myfree(in_imgs);
1672 myfree(n_regs);
1673 myfree(c_regs);
1674 ST(0) = sv_newmortal();
1675 if (RETVAL == 0) ST(0)=&PL_sv_undef;
1676 else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);
1677
1678
1679void
1680i_contrast(im,intensity)
1681 Imager::ImgRaw im
1682 float intensity
1683
1684void
1685i_hardinvert(im)
1686 Imager::ImgRaw im
1687
1688void
1689i_noise(im,amount,type)
1690 Imager::ImgRaw im
1691 float amount
1692 unsigned char type
1693
1694void
1695i_bumpmap(im,bump,channel,light_x,light_y,strength)
1696 Imager::ImgRaw im
1697 Imager::ImgRaw bump
1698 int channel
1699 int light_x
1700 int light_y
1701 int strength
1702
1703void
1704i_postlevels(im,levels)
1705 Imager::ImgRaw im
1706 int levels
1707
1708void
1709i_mosaic(im,size)
1710 Imager::ImgRaw im
1711 int size
1712
1713void
1714i_watermark(im,wmark,tx,ty,pixdiff)
1715 Imager::ImgRaw im
1716 Imager::ImgRaw wmark
1717 int tx
1718 int ty
1719 int pixdiff
1720
1721
1722void
1723i_autolevels(im,lsat,usat,skew)
1724 Imager::ImgRaw im
1725 float lsat
1726 float usat
1727 float skew
1728
1729void
1730i_radnoise(im,xo,yo,rscale,ascale)
1731 Imager::ImgRaw im
1732 float xo
1733 float yo
1734 float rscale
1735 float ascale
1736
1737void
1738i_turbnoise(im, xo, yo, scale)
1739 Imager::ImgRaw im
1740 float xo
1741 float yo
1742 float scale
1743
1744
1745void
1746i_gradgen(im, ...)
1747 Imager::ImgRaw im
1748 PREINIT:
1749 int num;
1750 int *xo;
1751 int *yo;
1752 i_color *ival;
1753 int dmeasure;
1754 int i;
1755 SV *sv;
1756 AV *axx;
1757 AV *ayy;
1758 AV *ac;
1759 CODE:
1760 if (items != 5)
1761 croak("Usage: i_gradgen(im, xo, yo, ival, dmeasure)");
1762 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1763 croak("i_gradgen: Second argument must be an array ref");
1764 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1765 croak("i_gradgen: Third argument must be an array ref");
1766 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1767 croak("i_gradgen: Fourth argument must be an array ref");
1768 axx = (AV *)SvRV(ST(1));
1769 ayy = (AV *)SvRV(ST(2));
1770 ac = (AV *)SvRV(ST(3));
1771 dmeasure = (int)SvIV(ST(4));
1772
1773 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1774 num = num <= av_len(ac) ? num : av_len(ac);
1775 num++;
1776 if (num < 2) croak("Usage: i_gradgen array refs must have more than 1 entry each");
1777 xo = mymalloc( sizeof(int) * num );
1778 yo = mymalloc( sizeof(int) * num );
1779 ival = mymalloc( sizeof(i_color) * num );
1780 for(i = 0; i<num; i++) {
1781 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1782 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1783 sv = *av_fetch(ac, i, 0);
1784 if ( !sv_derived_from(sv, "Imager::Color") ) {
1785 free(axx); free(ayy); free(ac);
1786 croak("i_gradgen: Element of fourth argument is not derived from Imager::Color");
1787 }
1788 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1789 }
1790 i_gradgen(im, num, xo, yo, ival, dmeasure);
1791
1792
1793
1794
1795
4f4f776a
TC
1796void
1797i_errors()
1798 PREINIT:
1799 i_errmsg *errors;
1800 int i;
1801 int count;
1802 AV *av;
1803 SV *ref;
1804 SV *sv;
1805 PPCODE:
1806 errors = i_errors();
1807 i = 0;
1808 while (errors[i].msg) {
1809 av = newAV();
1810 sv = newSVpv(errors[i].msg, strlen(errors[i].msg));
1811 if (!av_store(av, 0, sv)) {
1812 SvREFCNT_dec(sv);
1813 }
1814 sv = newSViv(errors[i].code);
1815 if (!av_store(av, 1, sv)) {
1816 SvREFCNT_dec(sv);
1817 }
1818 PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
1819 ++i;
1820 }
02d1d628
AMH
1821
1822void
1823i_nearest_color(im, ...)
1824 Imager::ImgRaw im
1825 PREINIT:
1826 int num;
1827 int *xo;
1828 int *yo;
1829 i_color *ival;
1830 int dmeasure;
1831 int i;
1832 SV *sv;
1833 AV *axx;
1834 AV *ayy;
1835 AV *ac;
1836 CODE:
1837 if (items != 5)
1838 croak("Usage: i_nearest_color(im, xo, yo, ival, dmeasure)");
1839 if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
1840 croak("i_nearest_color: Second argument must be an array ref");
1841 if (!SvROK(ST(2)) || ! SvTYPE(SvRV(ST(2))))
1842 croak("i_nearest_color: Third argument must be an array ref");
1843 if (!SvROK(ST(3)) || ! SvTYPE(SvRV(ST(3))))
1844 croak("i_nearest_color: Fourth argument must be an array ref");
1845 axx = (AV *)SvRV(ST(1));
1846 ayy = (AV *)SvRV(ST(2));
1847 ac = (AV *)SvRV(ST(3));
1848 dmeasure = (int)SvIV(ST(4));
1849
1850 num = av_len(axx) < av_len(ayy) ? av_len(axx) : av_len(ayy);
1851 num = num <= av_len(ac) ? num : av_len(ac);
1852 num++;
1853 if (num < 2) croak("Usage: i_nearest_color array refs must have more than 1 entry each");
1854 xo = mymalloc( sizeof(int) * num );
1855 yo = mymalloc( sizeof(int) * num );
1856 ival = mymalloc( sizeof(i_color) * num );
1857 for(i = 0; i<num; i++) {
1858 xo[i] = (int)SvIV(* av_fetch(axx, i, 0));
1859 yo[i] = (int)SvIV(* av_fetch(ayy, i, 0));
1860 sv = *av_fetch(ac, i, 0);
1861 if ( !sv_derived_from(sv, "Imager::Color") ) {
1862 free(axx); free(ayy); free(ac);
1863 croak("i_nearest_color: Element of fourth argument is not derived from Imager::Color");
1864 }
1865 ival[i] = *(i_color *)SvIV((SV *)SvRV(sv));
1866 }
1867 i_nearest_color(im, num, xo, yo, ival, dmeasure);
1868
1869
1870
1871
1872void
1873malloc_state()
1874
1875void
1876hashinfo(hv)
1877 PREINIT:
1878 HV* hv;
1879 int stuff;
1880 PPCODE:
1881 if (!SvROK(ST(0))) croak("Imager: Parameter 0 must be a reference to a hash\n");
1882 hv=(HV*)SvRV(ST(0));
1883 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 0 must be a reference to a hash\n");
1884 if (getint(hv,"stuff",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1885 if (getint(hv,"stuff2",&stuff)) printf("ok: %d\n",stuff); else printf("key doesn't exist\n");
1886
1887void
1888DSO_open(filename)
1889 char* filename
1890 PREINIT:
1891 void *rc;
1892 char *evstr;
1893 PPCODE:
1894 rc=DSO_open(filename,&evstr);
1895 if (rc!=NULL) {
1896 if (evstr!=NULL) {
1897 EXTEND(SP,2);
1898 PUSHs(sv_2mortal(newSViv((IV)rc)));
1899 PUSHs(sv_2mortal(newSVpvn(evstr, strlen(evstr))));
1900 } else {
1901 EXTEND(SP,1);
1902 PUSHs(sv_2mortal(newSViv((IV)rc)));
1903 }
1904 }
1905
1906
1907undef_int
1908DSO_close(dso_handle)
1909 void* dso_handle
1910
1911void
1912DSO_funclist(dso_handle_v)
1913 void* dso_handle_v
1914 PREINIT:
1915 int i;
1916 DSO_handle *dso_handle;
1917 PPCODE:
1918 dso_handle=(DSO_handle*)dso_handle_v;
1919 i=0;
1920 while( dso_handle->function_list[i].name != NULL) {
1921 EXTEND(SP,1);
1922 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i].name,0)));
1923 EXTEND(SP,1);
1924 PUSHs(sv_2mortal(newSVpv(dso_handle->function_list[i++].pcode,0)));
1925 }
1926
1927
1928void
1929DSO_call(handle,func_index,hv)
1930 void* handle
1931 int func_index
1932 PREINIT:
1933 HV* hv;
1934 PPCODE:
1935 if (!SvROK(ST(2))) croak("Imager: Parameter 2 must be a reference to a hash\n");
1936 hv=(HV*)SvRV(ST(2));
1937 if (SvTYPE(hv)!=SVt_PVHV) croak("Imager: Parameter 2 must be a reference to a hash\n");
1938 DSO_call( (DSO_handle *)handle,func_index,hv);
1939
1940
1941
f5991c03
TC
1942# this is mostly for testing...
1943Imager::Color
1944i_get_pixel(im, x, y)
1945 Imager::ImgRaw im
1946 int x
1947 int y;
1948 CODE:
1949 RETVAL = (i_color *)mymalloc(sizeof(i_color));
1950 i_gpix(im, x, y, RETVAL);
1951 OUTPUT:
1952 RETVAL
02d1d628 1953