Logo ROOT   6.16/01
Reference Guide
gifdecode.c
Go to the documentation of this file.
1/* @(#)root/x11:$Id$ */
2/* Author: Rene Brun 11/06/97*/
3#include <stdio.h>
4#include <string.h>
5
6
7#define BITS 12 /* largest code size */
8#define TSIZE 4096 /* tables size */
9
10typedef unsigned char byte;
11
12static int Prefix[TSIZE]; /* prefix table */
13static byte Suffix[TSIZE]; /* suffix table */
14static byte OutCode[TSIZE]; /* output stack */
15
16static byte *ptr1, /* pointer to GIF array */
17 *ptr2; /* pointer to PIX array */
18
19static int CurCodeSize, /* current number of bits per code */
20 CurMaxCode; /* maximum code, given CurCodeSize */
21
22static long CurBit; /* current bit in GIF image data */
23
24/***************************************************************
25 * *
26 ***************************************************************/
27static int ReadCode()
28{
29 static long b3[3], CurByte;
30 static byte lblk;
31 int shift, nbyte;
32 long OldByte;
33
34 if (CurBit == -1) {
35 lblk = 0;
36 CurByte = -1;
37 }
38
40 OldByte = CurByte;
41 CurByte = CurBit/8;
42 nbyte = CurByte - OldByte;
43 shift = 17 + (CurBit%8) - CurCodeSize;
44 while (nbyte-- > 0) {
45 if (lblk == 0) {
46 lblk = *ptr1++;
47 if (lblk == 0) return -1;
48 }
49 b3[0] = b3[1];
50 b3[1] = b3[2];
51 b3[2] = *ptr1++;
52 lblk--;
53 }
54 return (((b3[0]+0x100*b3[1]+0x10000*b3[2])>>shift) & (CurMaxCode-1));
55}
56
57/***************************************************************
58 * *
59 ***************************************************************/
60static void OutPixel(byte pix)
61{
62 *ptr2++ = pix;
63}
64
65/***************************************************************
66 * *
67 * Name: GIFinfo Date: 03.10.94 *
68 * *
69 * Function: Get information on GIF image *
70 * *
71 * Input: GIFarr[] - compressed image in GIF format *
72 * *
73 * Output: Width - image width *
74 * Height - image height *
75 * Ncols - number of colors *
76 * return - 0 - if O.K. *
77 * 1 - if error *
78 * *
79 ***************************************************************/
80int GIFinfo(byte *GIFarr, int *Width, int *Height, int *Ncols)
81{
82 byte b;
83
84 ptr1 = GIFarr;
85
86 /* R E A D H E A D E R */
87
88 if (strncmp((char *)GIFarr,"GIF87a",6) && strncmp((char *)GIFarr,"GIF89a",6))
89 {
90 fprintf(stderr,"\nGIFinfo: not a GIF\n");
91 return 1;
92 }
93
94 ptr1 += 6;
95
96 ptr1 += 2; /* screen width ... ignore */
97 ptr1 += 2; /* screen height ... ignore */
98
99 b = *ptr1++;
100 *Ncols = 1 << ((b & 7) + 1);
101 if ((b & 0x80) == 0) { /* is there color map? */
102 fprintf(stderr,"\nGIFinfo: warning! no color map\n");
103 *Ncols = 0;
104 }
105
106 ++ptr1; /* background color ... ignore */
107 b = *ptr1++; /* supposed to be NULL */
108 if (b) {
109 fprintf(stderr,"\nGIFdecode: bad screen descriptor\n");
110 return 1;
111 }
112
113 ptr1 += (*Ncols) * 3; /* skip color map */
114
115 b = *ptr1++; /* image separator */
116 if (b != ',') {
117 fprintf(stderr,"\nGIFinfo: no image separator\n");
118 return 1;
119 }
120
121 ptr1 += 2; /* left offset ... ignore */
122 ptr1 += 2; /* top offset ... ignore */
123 b = *ptr1++; /* image width */
124 *Width = b + 0x100*(*ptr1++);
125 b = *ptr1++; /* image height */
126 *Height = b + 0x100*(*ptr1++);
127 return 0;
128}
129
130/***************************************************************
131 * *
132 * Name: GIFdecode Date: 06.10.92 *
133 * *
134 * Function: Decode image from GIF array *
135 * *
136 * Input: GIFarr[] - compressed image in GIF format *
137 * *
138 * Output: PIXarr[] - image (byte per pixel) *
139 * Width - image width *
140 * Height - image height *
141 * Ncols - number of colors *
142 * R[] - red components *
143 * G[] - green components *
144 * B[] - blue components *
145 * return - 0 - if O.K. *
146 * 1 - if error *
147 * *
148 ***************************************************************/
149int GIFdecode(byte *GIFarr, byte *PIXarr, int *Width, int *Height, int *Ncols, byte *R, byte *G, byte *B)
150{
151 byte b, /* working variable */
152 FinChar; /* final character */
153
154 int i, /* working variable for loops */
155 BitsPixel, /* number of bits per pixel */
156 IniCodeSize, /* initial number of bits per code */
157 ClearCode, /* reset code */
158 EOFCode, /* end of file code */
159 FreeCode, /* first unused entry */
160 CurCode, /* current code */
161 InCode, /* input code */
162 OldCode, /* previous code */
163 PixMask, /* mask for pixel */
164 OutCount; /* output stack counter */
165
166 long Npix; /* number of pixels */
167
168 ptr1 = GIFarr;
169 ptr2 = PIXarr;
170 OldCode = 0;
171 FinChar = 0;
172
173 /* R E A D H E A D E R */
174 if (strncmp((char *)GIFarr,"GIF87a",6) && strncmp((char *)GIFarr,"GIF89a",6))
175 {
176 fprintf(stderr,"\nGIFinfo: not a GIF\n");
177 return 1;
178 }
179
180 ptr1 += 6;
181
182 ptr1 += 2; /* screen width ... ignore */
183 ptr1 += 2; /* screen height ... ignore */
184
185 b = *ptr1++;
186 BitsPixel = (b & 7) + 1; /* # of bits per pixel */
187 *Ncols = 1 << BitsPixel;
188 PixMask = (*Ncols) - 1; /* mask for pixel code */
189 if ((b & 0x80) == 0) { /* is there color map? */
190 fprintf(stderr,"\nGIFdecode: warning! no color map\n");
191 *Ncols = 0;
192 }
193
194 ++ptr1; /* background color ... ignore */
195 b = *ptr1++; /* supposed to be NULL */
196 if (b) {
197 fprintf(stderr,"\nGIFdecode: bad screen descriptor\n");
198 return 1;
199 }
200
201 for (i=0; i<(*Ncols); i++) { /* global color map */
202 R[i] = *ptr1++;
203 G[i] = *ptr1++;
204 B[i] = *ptr1++;
205 }
206
207 b = *ptr1++; /* image separator */
208 if (b != ',') {
209 fprintf(stderr,"\nGIFdecode: no image separator\n");
210 return 1;
211 }
212
213 ptr1 += 2; /* left offset ... ignore */
214 ptr1 += 2; /* top offset ... ignore */
215 b = *ptr1++; /* image width */
216 *Width = b + 0x100*(*ptr1++);
217 b = *ptr1++; /* image height */
218 *Height = b + 0x100*(*ptr1++);
219
220 b = *ptr1++; /* local colors, interlace */
221 if ((b & 0xc0) != 0) {
222 fprintf(stderr,
223 "\nGIFdecode: unexpected item (local colors or interlace)\n");
224 return 1;
225 }
226
227 IniCodeSize = *ptr1++;
229 CurMaxCode = (1 << IniCodeSize);
230 ClearCode = (1 << (IniCodeSize - 1));
231 EOFCode = ClearCode + 1;
232 FreeCode = ClearCode + 2;
233
234 /* D E C O D E I M A G E */
235
236 Npix =(long) (*Width) * (*Height);
237 OutCount = 0;
238 CurBit = -1;
239 CurCode = ReadCode();
240 while (Npix > 0) {
241
242 if (CurCode < 0) {
243 fprintf(stderr,"\nGIFdecode: corrupted GIF (zero block length)\n");
244 return 1;
245 }
246
247 if (CurCode == EOFCode) {
248 fprintf(stderr,"\nGIFdecode: corrupted GIF (unexpected EOF)\n");
249 return 1;
250 }
251
252 if (CurCode == ClearCode) { /* clear code ... reset */
253
255 CurMaxCode = (1 << IniCodeSize);
256 FreeCode = ClearCode + 2;
257 OldCode = CurCode = ReadCode();
258 FinChar = CurCode;
259 OutPixel(FinChar);
260 Npix--;
261
262 } else { /* image code */
263
264 InCode = CurCode;
265 if (CurCode >= FreeCode) {
266 CurCode = OldCode;
267 OutCode[OutCount++] = FinChar;
268 }
269 while (CurCode > PixMask) { /* build output pixel chain */
270 if (OutCount >= TSIZE) {
271 fprintf(stderr,"\nGIFdecode: corrupted GIF (big output count)\n");
272 return 1;
273 }
274 OutCode[OutCount++] = Suffix[CurCode];
275 CurCode = Prefix[CurCode];
276 }
277 FinChar = CurCode;
278 OutCode[OutCount++] = FinChar;
279
280 for (i=OutCount-1; i>=0; i--) { /* put out pixel chain */
281 OutPixel(OutCode[i]);
282 Npix--;
283 }
284 OutCount = 0;
285
286 Prefix[FreeCode] = OldCode; /* build the tables */
287 Suffix[FreeCode] = FinChar;
288 OldCode = InCode;
289
290 FreeCode++; /* move pointer */
291 if (FreeCode >= CurMaxCode) {
292 if (CurCodeSize < BITS) {
293 CurCodeSize++;
294 CurMaxCode *= 2;
295 }
296 }
297 }
298 CurCode = ReadCode();
299 }
300 return 0;
301}
#define b(i)
Definition: RSha256.hxx:100
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
#define G(x, y, z)
static double B[]
unsigned char byte
Definition: gifdecode.c:10
int GIFdecode(byte *GIFarr, byte *PIXarr, int *Width, int *Height, int *Ncols, byte *R, byte *G, byte *B)
Definition: gifdecode.c:149
int GIFinfo(byte *GIFarr, int *Width, int *Height, int *Ncols)
Definition: gifdecode.c:80
static int ClearCode
Definition: gifencode.c:29
static int BitsPixel
Definition: gifencode.c:25
static int FreeCode
Definition: gifencode.c:31
static int IniCodeSize
Definition: gifencode.c:26
static int EOFCode
Definition: gifencode.c:30
#define TSIZE
Definition: gifdecode.c:8
static byte Suffix[TSIZE]
Definition: gifdecode.c:13
static byte OutCode[TSIZE]
Definition: gifdecode.c:14
static void OutPixel(byte pix)
Definition: gifdecode.c:60
static int ReadCode()
Definition: gifdecode.c:27
#define BITS
Definition: gifdecode.c:7
static long CurBit
Definition: gifdecode.c:22
static byte * ptr1
Definition: gifdecode.c:16
static int CurCodeSize
Definition: gifdecode.c:19
static int CurMaxCode
Definition: gifdecode.c:20
static int Prefix[TSIZE]
Definition: gifdecode.c:12
static byte * ptr2
Definition: gifdecode.c:17