"Fossies" - the Fresh Open Source Software Archive 
Member "libgd-2.3.3/src/gd_gd.c" (11 Sep 2021, 9950 Bytes) of package /linux/www/libgd-2.3.3.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "gd_gd.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.3.2_vs_2.3.3.
1 /**
2 * File: GD IO
3 *
4 * Read and write GD images.
5 *
6 * The GD image format is a proprietary image format of libgd. *It has to be*
7 * *regarded as being obsolete, and should only be used for development and*
8 * *testing purposes.*
9 *
10 * Structure of a GD image file:
11 * - file header
12 * - color header (either truecolor or palette)
13 * - image data
14 *
15 * All numbers are stored in big-endian format. Note that all GD output is done
16 * in the GD 2.x format (not to be confused with the GD2 format), but input may
17 * also be in the GD 1.x format.
18 *
19 * GD 1.x file header structure:
20 * width - 1 word
21 * height - 1 word
22 *
23 * GD 1.x color header (palette only):
24 * count - 1 byte (the number of used palette colors)
25 * transparent - 1 word (257 signals no transparency)
26 * palette - 256×3 bytes (RGB triplets)
27 *
28 * GD 2.x file header structure:
29 * signature - 1 word ("\xFF\xFE" for truecolor, "\xFF\xFF" for palette)
30 * width - 1 word
31 * height - 1 word
32 *
33 * GD 2.x truecolor image color header:
34 * truecolor - 1 byte (always "\001")
35 * transparent - 1 dword (ARGB color); "\377\377\377\377" means that no
36 * transparent color is set
37 *
38 * GD 2.x palette image color header:
39 * truecolor - 1 byte (always "\0")
40 * count - 1 word (the number of used palette colors)
41 * transparent - 1 dword (palette index); "\377\377\377\377" means that no
42 * transparent color is set
43 * palette - 256 dwords (RGBA colors)
44 *
45 * Image data:
46 * Sequential pixel data; row-major from top to bottom, left to right:
47 * - 1 byte per pixel for palette images
48 * - 1 dword (ARGB) per pixel for truecolor images
49 */
50
51 #ifdef HAVE_CONFIG_H
52 #include "config.h"
53 #endif
54
55 #include <stdio.h>
56 #include <math.h>
57 #include <string.h>
58 #include <stdlib.h>
59 #include "gd.h"
60 #include "gd_errors.h"
61
62 /* 2.3: gd is no longer mandatory */
63 #if ENABLE_GD_FORMATS
64
65 #define TRUE 1
66 #define FALSE 0
67
68 /* Use this for commenting out debug-print statements. */
69 /* Just use the first '#define' to allow all the prints... */
70 /*#define GD2_DBG(s) (s) */
71 #define GD2_DBG(s)
72
73 /* */
74 /* Shared code to read color tables from gd file. */
75 /* */
76 int
77 _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
78 {
79 int i;
80 if (gd2xFlag) {
81 int trueColorFlag;
82 if (!gdGetByte (&trueColorFlag, in)) {
83 goto fail1;
84 }
85 /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12.
86 Beginning in 2.0.12 truecolor is indicated by the initial 2-byte
87 signature. */
88 if (trueColorFlag != im->trueColor) {
89 goto fail1;
90 }
91 /* This should have been a word all along */
92 if (!im->trueColor) {
93 if (!gdGetWord (&im->colorsTotal, in)) {
94 goto fail1;
95 }
96 if (im->colorsTotal > gdMaxColors) {
97 goto fail1;
98 }
99 }
100 /* Int to accommodate truecolor single-color transparency */
101 if (!gdGetInt (&im->transparent, in)) {
102 goto fail1;
103 }
104 } else {
105 if (!gdGetByte (&im->colorsTotal, in)) {
106 goto fail1;
107 }
108 if (!gdGetWord (&im->transparent, in)) {
109 goto fail1;
110 }
111 }
112 /* Make sure transparent index is within bounds of the palette. */
113 if (!(im->trueColor) && (im->transparent >= im->colorsTotal || im->transparent < 0)) {
114 im->transparent = (-1);
115 }
116 GD2_DBG (printf
117 ("Palette had %d colours (T=%d)\n", im->colorsTotal,
118 im->transparent));
119 if (im->trueColor) {
120 return TRUE;
121 }
122 for (i = 0; (i < gdMaxColors); i++) {
123 if (!gdGetByte (&im->red[i], in)) {
124 goto fail1;
125 }
126 if (!gdGetByte (&im->green[i], in)) {
127 goto fail1;
128 }
129 if (!gdGetByte (&im->blue[i], in)) {
130 goto fail1;
131 }
132 if (gd2xFlag) {
133 if (!gdGetByte (&im->alpha[i], in)) {
134 goto fail1;
135 }
136 }
137 }
138
139 for (i = 0; (i < im->colorsTotal); i++) {
140 im->open[i] = 0;
141 };
142
143 return TRUE;
144 fail1:
145 return FALSE;
146 }
147
148 /* */
149 /* Use the common basic header info to make the image object. */
150 /* */
151 static gdImagePtr
152 _gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
153 {
154 gdImagePtr im;
155 int gd2xFlag = 0;
156 int trueColorFlag = 0;
157 if (!gdGetWord (sx, in)) {
158 goto fail1;
159 }
160 if ((*sx == 65535) || (*sx == 65534)) {
161 /* This is a gd 2.0 .gd file */
162 gd2xFlag = 1;
163 /* 2.0.12: 65534 signals a truecolor .gd file.
164 There is a slight redundancy here but we can
165 live with it. */
166 if (*sx == 65534) {
167 trueColorFlag = 1;
168 }
169 if (!gdGetWord (sx, in)) {
170 goto fail1;
171 }
172 }
173 if (!gdGetWord (sy, in)) {
174 goto fail1;
175 }
176
177 GD2_DBG (printf ("Image is %dx%d\n", *sx, *sy));
178 if (trueColorFlag) {
179 im = gdImageCreateTrueColor (*sx, *sy);
180 } else {
181 im = gdImageCreate (*sx, *sy);
182 }
183 if (!im) {
184 goto fail1;
185 }
186 if (!_gdGetColors (in, im, gd2xFlag)) {
187 goto fail2;
188 }
189
190 return im;
191 fail2:
192 gdImageDestroy (im);
193 fail1:
194 return 0;
195 }
196
197 /*
198 Function: gdImageCreateFromGd
199
200 <gdImageCreateFromGd> is called to load images from gd format
201 files. Invoke <gdImageCreateFromGd> with an already opened pointer
202 to a file containing the desired image in the gd file format,
203 which is specific to gd and intended for very fast loading. (It is
204 not intended for compression; for compression, use PNG or JPEG.)
205
206 <gdImageCreateFromGd> returns a <gdImagePtr> to the new image, or
207 NULL if unable to load the image (most often because the file is
208 corrupt or does not contain a gd format
209 image). <gdImageCreateFromGd> does not close the file. You can
210 inspect the sx and sy members of the image to determine its
211 size. The image must eventually be destroyed using
212 <gdImageDestroy>.
213
214 Variants:
215
216 <gdImageCreateFromGdPtr> creates an image from GD data (i.e. the
217 contents of a GD file) already in memory.
218
219 <gdImageCreateFromGdCtx> reads in an image using the functions in
220 a <gdIOCtx> struct.
221
222 Parameters:
223
224 infile - The input FILE pointer
225
226 Returns:
227
228 A pointer to the new image or NULL if an error occurred.
229
230 Example:
231
232 > gdImagePtr im;
233 > FILE *in;
234 > in = fopen("mygd.gd", "rb");
235 > im = gdImageCreateFromGd(in);
236 > fclose(in);
237 > // ... Use the image ...
238 > gdImageDestroy(im);
239 */
240 BGD_DECLARE(gdImagePtr) gdImageCreateFromGd (FILE * inFile)
241 {
242 gdImagePtr im;
243 gdIOCtx *in;
244
245 in = gdNewFileCtx (inFile);
246 if (in == NULL) return NULL;
247 im = gdImageCreateFromGdCtx (in);
248
249 in->gd_free (in);
250
251 return im;
252 }
253
254 /*
255 Function: gdImageCreateFromGdPtr
256
257 Parameters:
258
259 size - size of GD data in bytes.
260 data - GD data (i.e. contents of a GIF file).
261
262 Reads in GD data from memory. See <gdImageCreateFromGd>.
263 */
264 BGD_DECLARE(gdImagePtr) gdImageCreateFromGdPtr (int size, void *data)
265 {
266 gdImagePtr im;
267 gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
268 if(!in)
269 return 0;
270 im = gdImageCreateFromGdCtx (in);
271 in->gd_free (in);
272 return im;
273 }
274
275 /*
276 Function: gdImageCreateFromGdCtx
277
278 Reads in a GD image via a <gdIOCtx> struct. See
279 <gdImageCreateFromGd>.
280 */
281 BGD_DECLARE(gdImagePtr) gdImageCreateFromGdCtx (gdIOCtxPtr in)
282 {
283 int sx, sy;
284 int x, y;
285 gdImagePtr im;
286
287 /* Read the header */
288 im = _gdCreateFromFile (in, &sx, &sy);
289
290 if (im == NULL) {
291 goto fail1;
292 };
293
294 /* Then the data... */
295 /* 2.0.12: support truecolor properly in .gd as well as in .gd2.
296 Problem reported by Andreas Pfaller. */
297 if (im->trueColor) {
298 for (y = 0; (y < sy); y++) {
299 for (x = 0; (x < sx); x++) {
300 int pix;
301 if (!gdGetInt (&pix, in)) {
302 goto fail2;
303 }
304 im->tpixels[y][x] = pix;
305 }
306 }
307 } else {
308 for (y = 0; (y < sy); y++) {
309 for (x = 0; (x < sx); x++) {
310 int ch;
311 ch = gdGetC (in);
312 if (ch == EOF) {
313 goto fail2;
314 }
315 /* ROW-MAJOR IN GD 1.3 */
316 im->pixels[y][x] = ch;
317 }
318 }
319 }
320 return im;
321
322 fail2:
323 gdImageDestroy (im);
324 fail1:
325 return 0;
326 }
327
328 void
329 _gdPutColors (gdImagePtr im, gdIOCtx * out)
330 {
331 int i;
332
333 gdPutC (im->trueColor, out);
334 if (!im->trueColor) {
335 gdPutWord (im->colorsTotal, out);
336 }
337 gdPutInt (im->transparent, out);
338 if (!im->trueColor) {
339 for (i = 0; (i < gdMaxColors); i++) {
340 gdPutC ((unsigned char) im->red[i], out);
341 gdPutC ((unsigned char) im->green[i], out);
342 gdPutC ((unsigned char) im->blue[i], out);
343 gdPutC ((unsigned char) im->alpha[i], out);
344 }
345 }
346 }
347
348 static void
349 _gdPutHeader (gdImagePtr im, gdIOCtx * out)
350 {
351 /* 65535 indicates this is a gd 2.x .gd file.
352 2.0.12: 65534 indicates truecolor. */
353 if (im->trueColor) {
354 gdPutWord (65534, out);
355 } else {
356 gdPutWord (65535, out);
357 }
358 gdPutWord (im->sx, out);
359 gdPutWord (im->sy, out);
360
361 _gdPutColors (im, out);
362
363 }
364
365 static void
366 _gdImageGd (gdImagePtr im, gdIOCtx * out)
367 {
368 int x, y;
369
370 _gdPutHeader (im, out);
371
372 for (y = 0; (y < im->sy); y++) {
373 for (x = 0; (x < im->sx); x++) {
374 /* ROW-MAJOR IN GD 1.3 */
375 if (im->trueColor) {
376 gdPutInt (im->tpixels[y][x], out);
377 } else {
378 gdPutC ((unsigned char) im->pixels[y][x], out);
379 }
380 }
381 }
382 }
383
384 /*
385 Function: gdImageGd
386 */
387 BGD_DECLARE(void) gdImageGd (gdImagePtr im, FILE * outFile)
388 {
389 gdIOCtx *out = gdNewFileCtx (outFile);
390 if (out == NULL) return;
391 _gdImageGd (im, out);
392 out->gd_free (out);
393 }
394
395 /*
396 Function: gdImageGdPtr
397 */
398 BGD_DECLARE(void *) gdImageGdPtr (gdImagePtr im, int *size)
399 {
400 void *rv;
401 gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
402 if (out == NULL) return NULL;
403 _gdImageGd (im, out);
404 rv = gdDPExtractData (out, size);
405 out->gd_free (out);
406 return rv;
407 }
408
409 #else /* no HAVE_LIBZ or !ENABLE_GD_FORMATS */
410
411 static void _noGdError (void)
412 {
413 gd_error("GD image support has been disabled\n");
414 }
415
416 BGD_DECLARE(gdImagePtr) gdImageCreateFromGd (FILE * inFile)
417 {
418 ARG_NOT_USED(inFile);
419 _noGdError();
420 return NULL;
421 }
422
423 BGD_DECLARE(gdImagePtr) gdImageCreateFromGdPtr (int size, void *data)
424 {
425 ARG_NOT_USED(size);
426 ARG_NOT_USED(data);
427 _noGdError();
428 return NULL;
429 }
430
431 BGD_DECLARE(gdImagePtr) gdImageCreateFromGdCtx (gdIOCtxPtr in)
432 {
433 ARG_NOT_USED(in);
434 _noGdError();
435 return NULL;
436 }
437
438 BGD_DECLARE(void) gdImageGd (gdImagePtr im, FILE * outFile)
439 {
440 ARG_NOT_USED(im);
441 ARG_NOT_USED(outFile);
442 _noGdError();
443 }
444
445 BGD_DECLARE(void *) gdImageGdPtr (gdImagePtr im, int *size)
446 {
447 ARG_NOT_USED(im);
448 ARG_NOT_USED(size);
449 _noGdError();
450 return NULL;
451 }
452
453 #endif /* ENABLE_GD_FORMATS */