Annotation of embedaddon/php/ext/gd/libgd/gd_gd.c, revision 1.1.1.1
1.1 misho 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: {
24: int i;
25: if (gd2xFlag) {
26: int trueColorFlag;
27: if (!gdGetByte(&trueColorFlag, in)) {
28: 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: if (trueColorFlag != im->trueColor) {
35: goto fail1;
36: }
37: /* This should have been a word all along */
38: if (!im->trueColor) {
39: if (!gdGetWord(&im->colorsTotal, in)) {
40: goto fail1;
41: }
42: if (im->colorsTotal > gdMaxColors) {
43: goto fail1;
44: }
45: }
46: /* Int to accommodate truecolor single-color transparency */
47: if (!gdGetInt(&im->transparent, in)) {
48: goto fail1;
49: }
50: } else {
51: if (!gdGetByte(&im->colorsTotal, in)) {
52: goto fail1;
53: }
54: if (!gdGetWord(&im->transparent, in)) {
55: goto fail1;
56: }
57: if (im->transparent == 257) {
58: im->transparent = (-1);
59: }
60: }
61:
62: GD2_DBG(printf("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
63:
64: if (im->trueColor) {
65: return TRUE;
66: }
67:
68: for (i = 0; i < gdMaxColors; i++) {
69: if (!gdGetByte(&im->red[i], in)) {
70: goto fail1;
71: }
72: if (!gdGetByte(&im->green[i], in)) {
73: goto fail1;
74: }
75: if (!gdGetByte(&im->blue[i], in)) {
76: goto fail1;
77: }
78: if (gd2xFlag) {
79: if (!gdGetByte(&im->alpha[i], in)) {
80: goto fail1;
81: }
82: }
83: }
84:
85: for (i = 0; i < im->colorsTotal; i++) {
86: im->open[i] = 0;
87: }
88:
89: return TRUE;
90: fail1:
91: 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: {
99: gdImagePtr im;
100: int gd2xFlag = 0;
101: int trueColorFlag = 0;
102:
103: if (!gdGetWord(sx, in)) {
104: goto fail1;
105: }
106: if (*sx == 65535 || *sx == 65534) {
107: /* This is a gd 2.0 .gd file */
108: 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: if (*sx == 65534) {
111: trueColorFlag = 1;
112: }
113: if (!gdGetWord(sx, in)) {
114: goto fail1;
115: }
116: }
117: if (!gdGetWord(sy, in)) {
118: goto fail1;
119: }
120:
121: GD2_DBG(printf("Image is %dx%d\n", *sx, *sy));
122:
123: if (trueColorFlag) {
124: im = gdImageCreateTrueColor(*sx, *sy);
125: } else {
126: im = gdImageCreate(*sx, *sy);
127: }
128: if(!im) {
129: goto fail1;
130: }
131: if (!_gdGetColors(in, im, gd2xFlag)) {
132: goto fail2;
133: }
134:
135: return im;
136: fail2:
137: gdImageDestroy(im);
138: fail1:
139: return 0;
140: }
141:
142: gdImagePtr gdImageCreateFromGd (FILE * inFile)
143: {
144: gdImagePtr im;
145: gdIOCtx *in;
146:
147: in = gdNewFileCtx(inFile);
148: im = gdImageCreateFromGdCtx(in);
149:
150: in->gd_free(in);
151:
152: return im;
153: }
154:
155: gdImagePtr gdImageCreateFromGdPtr (int size, void *data)
156: {
157: gdImagePtr im;
158: gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
159: im = gdImageCreateFromGdCtx(in);
160: in->gd_free(in);
161:
162: return im;
163: }
164:
165: gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in)
166: {
167: int sx, sy;
168: int x, y;
169: gdImagePtr im;
170:
171: /* Read the header */
172: im = _gdCreateFromFile(in, &sx, &sy);
173:
174: if (im == NULL) {
175: 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: if (im->trueColor) {
181: for (y = 0; y < sy; y++) {
182: for (x = 0; x < sx; x++) {
183: int pix;
184: if (!gdGetInt(&pix, in)) {
185: goto fail2;
186: }
187: im->tpixels[y][x] = pix;
188: }
189: }
190: } else {
191: for (y = 0; y < sy; y++) {
192: for (x = 0; x < sx; x++) {
193: int ch;
194: ch = gdGetC(in);
195: if (ch == EOF) {
196: goto fail2;
197: }
198: /* ROW-MAJOR IN GD 1.3 */
199: im->pixels[y][x] = ch;
200: }
201: }
202: }
203:
204: return im;
205:
206: fail2:
207: gdImageDestroy (im);
208: fail1:
209: return 0;
210: }
211:
212: void _gdPutColors (gdImagePtr im, gdIOCtx * out)
213: {
214: int i;
215:
216: gdPutC(im->trueColor, out);
217: if (!im->trueColor) {
218: gdPutWord(im->colorsTotal, out);
219: }
220: gdPutInt(im->transparent, out);
221: if (!im->trueColor) {
222: for (i = 0; i < gdMaxColors; i++) {
223: gdPutC((unsigned char) im->red[i], out);
224: gdPutC((unsigned char) im->green[i], out);
225: gdPutC((unsigned char) im->blue[i], out);
226: gdPutC((unsigned char) im->alpha[i], out);
227: }
228: }
229: }
230:
231: static void _gdPutHeader (gdImagePtr im, gdIOCtx * out)
232: {
233: /* 65535 indicates this is a gd 2.x .gd file.
234: * 2.0.12: 65534 indicates truecolor.
235: */
236: if (im->trueColor) {
237: gdPutWord(65534, out);
238: } else {
239: gdPutWord(65535, out);
240: }
241: gdPutWord(im->sx, out);
242: gdPutWord(im->sy, out);
243:
244: _gdPutColors(im, out);
245: }
246:
247: static void _gdImageGd (gdImagePtr im, gdIOCtx * out)
248: {
249: int x, y;
250:
251: _gdPutHeader(im, out);
252:
253: for (y = 0; y < im->sy; y++) {
254: for (x = 0; x < im->sx; x++) {
255: /* ROW-MAJOR IN GD 1.3 */
256: if (im->trueColor) {
257: gdPutInt(im->tpixels[y][x], out);
258: } else {
259: gdPutC((unsigned char) im->pixels[y][x], out);
260: }
261: }
262: }
263: }
264:
265: void gdImageGd (gdImagePtr im, FILE * outFile)
266: {
267: gdIOCtx *out = gdNewFileCtx(outFile);
268: _gdImageGd(im, out);
269: out->gd_free(out);
270: }
271:
272: void *gdImageGdPtr (gdImagePtr im, int *size)
273: {
274: void *rv;
275: gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
276: _gdImageGd(im, out);
277: rv = gdDPExtractData(out, size);
278: out->gd_free(out);
279: return rv;
280: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>