1 : #include <stdio.h>
2 : #include <math.h>
3 : #include <string.h>
4 : #include <stdlib.h>
5 : #include "gd.h"
6 :
7 : #define TRUE 1
8 : #define FALSE 0
9 :
10 : /* Exported functions: */
11 : extern void gdImageGd (gdImagePtr im, FILE * out);
12 :
13 :
14 : /* Use this for commenting out debug-print statements. */
15 : /* Just use the first '#define' to allow all the prints... */
16 : /*#define GD2_DBG(s) (s) */
17 : #define GD2_DBG(s)
18 :
19 : /* */
20 : /* Shared code to read color tables from gd file. */
21 : /* */
22 : int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
23 10 : {
24 : int i;
25 10 : if (gd2xFlag) {
26 : int trueColorFlag;
27 10 : if (!gdGetByte(&trueColorFlag, in)) {
28 0 : goto fail1;
29 : }
30 : /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12.
31 : * Beginning in 2.0.12 truecolor is indicated by the initial 2-byte
32 : * signature.
33 : */
34 10 : if (trueColorFlag != im->trueColor) {
35 0 : goto fail1;
36 : }
37 : /* This should have been a word all along */
38 10 : if (!im->trueColor) {
39 3 : if (!gdGetWord(&im->colorsTotal, in)) {
40 0 : goto fail1;
41 : }
42 3 : if (im->colorsTotal > gdMaxColors) {
43 1 : goto fail1;
44 : }
45 : }
46 : /* Int to accommodate truecolor single-color transparency */
47 9 : if (!gdGetInt(&im->transparent, in)) {
48 0 : goto fail1;
49 : }
50 : } else {
51 0 : if (!gdGetByte(&im->colorsTotal, in)) {
52 0 : goto fail1;
53 : }
54 0 : if (!gdGetWord(&im->transparent, in)) {
55 0 : goto fail1;
56 : }
57 0 : if (im->transparent == 257) {
58 0 : im->transparent = (-1);
59 : }
60 : }
61 :
62 : GD2_DBG(printf("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
63 :
64 9 : if (im->trueColor) {
65 7 : return TRUE;
66 : }
67 :
68 514 : for (i = 0; i < gdMaxColors; i++) {
69 512 : if (!gdGetByte(&im->red[i], in)) {
70 0 : goto fail1;
71 : }
72 512 : if (!gdGetByte(&im->green[i], in)) {
73 0 : goto fail1;
74 : }
75 512 : if (!gdGetByte(&im->blue[i], in)) {
76 0 : goto fail1;
77 : }
78 512 : if (gd2xFlag) {
79 512 : if (!gdGetByte(&im->alpha[i], in)) {
80 0 : goto fail1;
81 : }
82 : }
83 : }
84 :
85 514 : for (i = 0; i < im->colorsTotal; i++) {
86 512 : im->open[i] = 0;
87 : }
88 :
89 2 : return TRUE;
90 1 : fail1:
91 1 : return FALSE;
92 : }
93 :
94 : /* */
95 : /* Use the common basic header info to make the image object. */
96 : /* */
97 : static gdImagePtr _gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
98 4 : {
99 : gdImagePtr im;
100 4 : int gd2xFlag = 0;
101 4 : int trueColorFlag = 0;
102 :
103 4 : if (!gdGetWord(sx, in)) {
104 0 : goto fail1;
105 : }
106 4 : if (*sx == 65535 || *sx == 65534) {
107 : /* This is a gd 2.0 .gd file */
108 3 : gd2xFlag = 1;
109 : /* 2.0.12: 65534 signals a truecolor .gd file. There is a slight redundancy here but we can live with it. */
110 3 : if (*sx == 65534) {
111 0 : trueColorFlag = 1;
112 : }
113 3 : if (!gdGetWord(sx, in)) {
114 0 : goto fail1;
115 : }
116 : }
117 4 : if (!gdGetWord(sy, in)) {
118 0 : goto fail1;
119 : }
120 :
121 : GD2_DBG(printf("Image is %dx%d\n", *sx, *sy));
122 :
123 4 : if (trueColorFlag) {
124 0 : im = gdImageCreateTrueColor(*sx, *sy);
125 : } else {
126 4 : im = gdImageCreate(*sx, *sy);
127 : }
128 4 : if(!im) {
129 1 : goto fail1;
130 : }
131 3 : if (!_gdGetColors(in, im, gd2xFlag)) {
132 1 : goto fail2;
133 : }
134 :
135 2 : return im;
136 1 : fail2:
137 1 : gdImageDestroy(im);
138 2 : fail1:
139 2 : return 0;
140 : }
141 :
142 : gdImagePtr gdImageCreateFromGd (FILE * inFile)
143 4 : {
144 : gdImagePtr im;
145 : gdIOCtx *in;
146 :
147 4 : in = gdNewFileCtx(inFile);
148 4 : im = gdImageCreateFromGdCtx(in);
149 :
150 4 : in->gd_free(in);
151 :
152 4 : return im;
153 : }
154 :
155 : gdImagePtr gdImageCreateFromGdPtr (int size, void *data)
156 0 : {
157 : gdImagePtr im;
158 0 : gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
159 0 : im = gdImageCreateFromGdCtx(in);
160 0 : in->gd_free(in);
161 :
162 0 : return im;
163 : }
164 :
165 : gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in)
166 4 : {
167 : int sx, sy;
168 : int x, y;
169 : gdImagePtr im;
170 :
171 : /* Read the header */
172 4 : im = _gdCreateFromFile(in, &sx, &sy);
173 :
174 4 : if (im == NULL) {
175 2 : goto fail1;
176 : }
177 :
178 : /* Then the data... */
179 : /* 2.0.12: support truecolor properly in .gd as well as in .gd2. Problem reported by Andreas Pfaller. */
180 2 : if (im->trueColor) {
181 0 : for (y = 0; y < sy; y++) {
182 0 : for (x = 0; x < sx; x++) {
183 : int pix;
184 0 : if (!gdGetInt(&pix, in)) {
185 0 : goto fail2;
186 : }
187 0 : im->tpixels[y][x] = pix;
188 : }
189 : }
190 : } else {
191 333 : for (y = 0; y < sy; y++) {
192 71492 : for (x = 0; x < sx; x++) {
193 : int ch;
194 71161 : ch = gdGetC(in);
195 71161 : if (ch == EOF) {
196 0 : goto fail2;
197 : }
198 : /* ROW-MAJOR IN GD 1.3 */
199 71161 : im->pixels[y][x] = ch;
200 : }
201 : }
202 : }
203 :
204 2 : return im;
205 :
206 0 : fail2:
207 0 : gdImageDestroy (im);
208 2 : fail1:
209 2 : return 0;
210 : }
211 :
212 : void _gdPutColors (gdImagePtr im, gdIOCtx * out)
213 11 : {
214 : int i;
215 :
216 11 : gdPutC(im->trueColor, out);
217 11 : if (!im->trueColor) {
218 6 : gdPutWord(im->colorsTotal, out);
219 : }
220 11 : gdPutInt(im->transparent, out);
221 11 : if (!im->trueColor) {
222 1542 : for (i = 0; i < gdMaxColors; i++) {
223 1536 : gdPutC((unsigned char) im->red[i], out);
224 1536 : gdPutC((unsigned char) im->green[i], out);
225 1536 : gdPutC((unsigned char) im->blue[i], out);
226 1536 : gdPutC((unsigned char) im->alpha[i], out);
227 : }
228 : }
229 11 : }
230 :
231 : static void _gdPutHeader (gdImagePtr im, gdIOCtx * out)
232 4 : {
233 : /* 65535 indicates this is a gd 2.x .gd file.
234 : * 2.0.12: 65534 indicates truecolor.
235 : */
236 4 : if (im->trueColor) {
237 0 : gdPutWord(65534, out);
238 : } else {
239 4 : gdPutWord(65535, out);
240 : }
241 4 : gdPutWord(im->sx, out);
242 4 : gdPutWord(im->sy, out);
243 :
244 4 : _gdPutColors(im, out);
245 4 : }
246 :
247 : static void _gdImageGd (gdImagePtr im, gdIOCtx * out)
248 4 : {
249 : int x, y;
250 :
251 4 : _gdPutHeader(im, out);
252 :
253 460 : for (y = 0; y < im->sy; y++) {
254 79742 : for (x = 0; x < im->sx; x++) {
255 : /* ROW-MAJOR IN GD 1.3 */
256 79286 : if (im->trueColor) {
257 0 : gdPutInt(im->tpixels[y][x], out);
258 : } else {
259 79286 : gdPutC((unsigned char) im->pixels[y][x], out);
260 : }
261 : }
262 : }
263 4 : }
264 :
265 : void gdImageGd (gdImagePtr im, FILE * outFile)
266 4 : {
267 4 : gdIOCtx *out = gdNewFileCtx(outFile);
268 4 : _gdImageGd(im, out);
269 4 : out->gd_free(out);
270 4 : }
271 :
272 : void *gdImageGdPtr (gdImagePtr im, int *size)
273 0 : {
274 : void *rv;
275 0 : gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
276 0 : _gdImageGd(im, out);
277 0 : rv = gdDPExtractData(out, size);
278 0 : out->gd_free(out);
279 0 : return rv;
280 : }
|