Logo ROOT   6.12/07
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 
10 typedef unsigned char byte;
11 
12 static int Prefix[TSIZE]; /* prefix table */
13 static byte Suffix[TSIZE]; /* suffix table */
14 static byte OutCode[TSIZE]; /* output stack */
15 
16 static byte *ptr1, /* pointer to GIF array */
17  *ptr2; /* pointer to PIX array */
18 
19 static int CurCodeSize, /* current number of bits per code */
20  CurMaxCode; /* maximum code, given CurCodeSize */
21 
22 static long CurBit; /* current bit in GIF image data */
23 
24 /***************************************************************
25  * *
26  ***************************************************************/
27 static 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  ***************************************************************/
60 static 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  ***************************************************************/
80 int 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  ***************************************************************/
149 int 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 }
static double B[]
static int ReadCode()
Definition: gifdecode.c:27
static int IniCodeSize
Definition: gifencode.c:25
static int EOFCode
Definition: gifencode.c:25
static byte * ptr1
Definition: gifdecode.c:16
#define G(x, y, z)
static byte Suffix[TSIZE]
Definition: gifdecode.c:13
static byte * ptr2
Definition: gifdecode.c:16
#define BITS
Definition: gifdecode.c:7
#define TSIZE
Definition: gifdecode.c:8
unsigned char byte
Definition: gifdecode.c:10
static int ClearCode
Definition: gifencode.c:25
static int FreeCode
Definition: gifencode.c:25
static void OutPixel(byte pix)
Definition: gifdecode.c:60
static byte OutCode[TSIZE]
Definition: gifdecode.c:14
int GIFdecode(byte *GIFarr, byte *PIXarr, int *Width, int *Height, int *Ncols, byte *R, byte *G, byte *B)
Definition: gifdecode.c:149
static int CurMaxCode
Definition: gifdecode.c:19
static int Prefix[TSIZE]
Definition: gifdecode.c:12
static int CurCodeSize
Definition: gifdecode.c:19
int GIFinfo(byte *GIFarr, int *Width, int *Height, int *Ncols)
Definition: gifdecode.c:80
static long CurBit
Definition: gifdecode.c:22
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
static int BitsPixel
Definition: gifencode.c:25
constexpr Double_t R()
Definition: TMath.h:213