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