]> git.imager.perl.org - imager.git/blob - GIF/GIF.xs
convert t/t55trans.t to Test::More
[imager.git] / GIF / GIF.xs
1 #define PERL_NO_GET_CONTEXT
2 #ifdef __cplusplus
3 extern "C" {
4 #endif
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8 #include "imext.h"
9 #include "imperl.h"
10 #include "imgif.h"
11 #include "imextpl.h"
12
13 DEFINE_IMAGER_CALLBACKS;
14 DEFINE_IMAGER_PERL_CALLBACKS;
15
16 MODULE = Imager::File::GIF  PACKAGE = Imager::File::GIF
17
18 double
19 i_giflib_version()
20
21 undef_int
22 i_writegif_wiol(ig, opts,...)
23         Imager::IO ig
24       PREINIT:
25         i_quantize quant;
26         i_img **imgs = NULL;
27         int img_count;
28         int i;
29         HV *hv;
30       CODE:
31         if (items < 3)
32             croak("Usage: i_writegif_wiol(IO,hashref, images...)");
33         if (!SvROK(ST(1)) || ! SvTYPE(SvRV(ST(1))))
34             croak("i_writegif_callback: Second argument must be a hash ref");
35         hv = (HV *)SvRV(ST(1));
36         memset(&quant, 0, sizeof(quant));
37         quant.version = 1;
38         quant.mc_size = 256;
39         quant.transp = tr_threshold;
40         quant.tr_threshold = 127;
41         ip_handle_quant_opts(aTHX_ &quant, hv);
42         img_count = items - 2;
43         RETVAL = 1;
44         if (img_count < 1) {
45           RETVAL = 0;
46         }
47         else {
48           imgs = mymalloc(sizeof(i_img *) * img_count);
49           for (i = 0; i < img_count; ++i) {
50             SV *sv = ST(2+i);
51             imgs[i] = NULL;
52             if (SvROK(sv) && sv_derived_from(sv, "Imager::ImgRaw")) {
53               imgs[i] = INT2PTR(i_img *, SvIV((SV*)SvRV(sv)));
54             }
55             else {
56               RETVAL = 0;
57               break;
58             }
59           }
60           if (RETVAL) {
61             RETVAL = i_writegif_wiol(ig, &quant, imgs, img_count);
62           }
63           myfree(imgs);
64           if (RETVAL) {
65             ip_copy_colors_back(aTHX_ hv, &quant);
66           }
67         }
68         ST(0) = sv_newmortal();
69         if (RETVAL == 0) ST(0)=&PL_sv_undef;
70         else sv_setiv(ST(0), (IV)RETVAL);
71         ip_cleanup_quant_opts(aTHX_ &quant);
72
73
74 void
75 i_readgif_wiol(ig)
76      Imager::IO         ig
77               PREINIT:
78                 int*    colour_table;
79                 int     colours, q, w;
80               i_img*    rimg;
81                  SV*    temp[3];
82                  AV*    ct; 
83                  SV*    r;
84                PPCODE:
85                colour_table = NULL;
86                colours = 0;
87
88         if(GIMME_V == G_ARRAY) {
89             rimg = i_readgif_wiol(ig,&colour_table,&colours);
90         } else {
91             /* don't waste time with colours if they aren't wanted */
92             rimg = i_readgif_wiol(ig,NULL,NULL);
93         }
94         
95         if (colour_table == NULL) {
96             EXTEND(SP,1);
97             r=sv_newmortal();
98             sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
99             PUSHs(r);
100         } else {
101             /* the following creates an [[r,g,b], [r, g, b], [r, g, b]...] */
102             /* I don't know if I have the reference counts right or not :( */
103             /* Neither do I :-) */
104             /* No Idea here either */
105
106             ct=newAV();
107             av_extend(ct, colours);
108             for(q=0; q<colours; q++) {
109                 for(w=0; w<3; w++)
110                     temp[w]=sv_2mortal(newSViv(colour_table[q*3 + w]));
111                 av_store(ct, q, (SV*)newRV_noinc((SV*)av_make(3, temp)));
112             }
113             myfree(colour_table);
114
115             EXTEND(SP,2);
116             r = sv_newmortal();
117             sv_setref_pv(r, "Imager::ImgRaw", (void*)rimg);
118             PUSHs(r);
119             PUSHs(newRV_noinc((SV*)ct));
120         }
121
122 Imager::ImgRaw
123 i_readgif_single_wiol(ig, page=0)
124         Imager::IO      ig
125         int             page
126
127 void
128 i_readgif_multi_wiol(ig)
129         Imager::IO ig
130       PREINIT:
131         i_img **imgs;
132         int count;
133         int i;
134       PPCODE:
135         imgs = i_readgif_multi_wiol(ig, &count);
136         if (imgs) {
137           EXTEND(SP, count);
138           for (i = 0; i < count; ++i) {
139             SV *sv = sv_newmortal();
140             sv_setref_pv(sv, "Imager::ImgRaw", (void *)imgs[i]);
141             PUSHs(sv);
142           }
143           myfree(imgs);
144         }
145
146
147 BOOT:
148         PERL_INITIALIZE_IMAGER_CALLBACKS;
149         PERL_INITIALIZE_IMAGER_PERL_CALLBACKS;