Logo ROOT   6.12/07
Reference Guide
gifencode.c
Go to the documentation of this file.
1 /* @(#)root/win32gdk:$Id$ */
2 /* Author: E.Chernyaev 19/01/94*/
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #ifdef __STDC__
8 #define ARGS(alist) alist
9 #else
10 #define ARGS(alist) ()
11 #endif
12 
13 #define BITS 12 /* largest code size */
14 #define THELIMIT 4096 /* NEVER generate this */
15 #define HSIZE 5003 /* hash table size */
16 #define SHIFT 4 /* shift for hashing */
17 
18 #define put_byte(A) (*put_b)((byte)(A)); Nbyte++
19 
20 typedef unsigned char byte;
21 
22 static long HashTab [HSIZE]; /* hash table */
23 static int CodeTab [HSIZE]; /* code table */
24 
25 static int BitsPixel, /* number of bits per pixel */
26  IniCodeSize, /* initial number of bits per code */
27  CurCodeSize, /* current number of bits per code */
28  CurMaxCode, /* maximum code, given CurCodeSize */
29  ClearCode, /* reset code */
30  EOFCode, /* end of file code */
31  FreeCode; /* first unused entry */
32 
33 static long Nbyte;
34 static void (*put_b) ARGS((byte));
35 
36 static void output ARGS((int));
37 static void char_init();
38 static void char_out ARGS((int));
39 static void char_flush();
40 static void put_short ARGS((int));
41 
42 /***********************************************************************
43  * *
44  * Name: GIFencode Date: 02.10.92 *
45  * Author: E.Chernyaev (IHEP/Protvino) Revised: *
46  * *
47  * Function: GIF compression of the image *
48  * *
49  * Input: Width - image width (must be >= 8) *
50  * Height - image height (must be >= 8) *
51  * Ncol - number of colors *
52  * R[] - red components *
53  * G[] - green components *
54  * B[] - blue components *
55  * ScLine[] - array for scan line (byte per pixel) *
56  * get_scline - user routine to read scan line: *
57  * get_scline(y, Width, ScLine) *
58  * pb - user routine for "put_byte": pb(b) *
59  * *
60  * Return: size of GIF *
61  * *
62  ***********************************************************************/
63 long GIFencode(Width, Height, Ncol, R, G, B, ScLine, get_scline, pb)
64  int Width, Height, Ncol;
65  byte R[], G[], B[], ScLine[];
66  void (*get_scline) ARGS((int, int, byte *)), (*pb) ARGS((byte));
67 {
68  long CodeK;
69  int ncol, i, x, y, disp, Code, K;
70 
71  /* C H E C K P A R A M E T E R S */
72 
73  Code = 0;
74  if (Width <= 0 || Width > 4096 || Height <= 0 || Height > 4096) {
75  fprintf(stderr,
76  "\nGIFencode: incorrect image size: %d x %d\n", Width, Height);
77  return 0;
78  }
79 
80  if (Ncol <= 0 || Ncol > 256) {
81  fprintf(stderr,"\nGIFencode: wrong number of colors: %d\n", Ncol);
82  return 0;
83  }
84 
85  /* I N I T I A L I S A T I O N */
86 
87  put_b = pb;
88  Nbyte = 0;
89  char_init(); /* initialise "char_..." routines */
90 
91  /* F I N D # O F B I T S P E R P I X E L */
92 
93  BitsPixel = 1;
94  if (Ncol > 2) BitsPixel = 2;
95  if (Ncol > 4) BitsPixel = 3;
96  if (Ncol > 8) BitsPixel = 4;
97  if (Ncol > 16) BitsPixel = 5;
98  if (Ncol > 32) BitsPixel = 6;
99  if (Ncol > 64) BitsPixel = 7;
100  if (Ncol > 128) BitsPixel = 8;
101 
102  ncol = 1 << BitsPixel;
104  if (BitsPixel <= 1) IniCodeSize = 2;
105 
106  /* W R I T E H E A D E R */
107 
108  put_byte('G'); /* magic number: GIF87a */
109  put_byte('I');
110  put_byte('F');
111  put_byte('8');
112  put_byte('7');
113  put_byte('a');
114 
115  put_short(Width); /* screen size */
116  put_short(Height);
117 
118  K = 0x80; /* yes, there is a color map */
119  K |= (8-1)<<4; /* OR in the color resolution */
120  K |= (BitsPixel - 1); /* OR in the # of bits per pixel */
121  put_byte(K);
122 
123  put_byte(0); /* background color */
124  put_byte(0); /* future expansion byte */
125 
126  for (i=0; i<Ncol; i++) { /* global colormap */
127  put_byte(R[i]);
128  put_byte(G[i]);
129  put_byte(B[i]);
130  }
131  for (; i<ncol; i++) {
132  put_byte(0);
133  put_byte(0);
134  put_byte(0);
135  }
136 
137  put_byte(','); /* image separator */
138  put_short(0); /* left offset of image */
139  put_short(0); /* top offset of image */
140  put_short(Width); /* image size */
141  put_short(Height);
142  put_byte(0); /* no local colors, no interlace */
143  put_byte(IniCodeSize); /* initial code size */
144 
145  /* L W Z C O M P R E S S I O N */
146 
148  CurMaxCode = (1 << (IniCodeSize)) - 1;
149  ClearCode = (1 << (IniCodeSize - 1));
150  EOFCode = ClearCode + 1;
151  FreeCode = ClearCode + 2;
152  output(ClearCode);
153  for (y=0; y<Height; y++) {
154  (*get_scline)(y, Width, ScLine);
155  x = 0;
156  if (y == 0)
157  Code = ScLine[x++];
158  while(x < Width) {
159  K = ScLine[x++]; /* next symbol */
160  CodeK = ((long) K << BITS) + Code; /* set full code */
161  i = (K << SHIFT) ^ Code; /* xor hashing */
162 
163  if (HashTab[i] == CodeK) { /* full code found */
164  Code = CodeTab[i];
165  continue;
166  }
167  else if (HashTab[i] < 0 ) /* empty slot */
168  goto NOMATCH;
169 
170  disp = HSIZE - i; /* secondary hash */
171  if (i == 0) disp = 1;
172 
173 PROBE:
174  if ((i -= disp) < 0)
175  i += HSIZE;
176 
177  if (HashTab[i] == CodeK) { /* full code found */
178  Code = CodeTab[i];
179  continue;
180  }
181 
182  if (HashTab[i] > 0) /* try again */
183  goto PROBE;
184 
185 NOMATCH:
186  output(Code); /* full code not found */
187  Code = K;
188 
189  if (FreeCode < THELIMIT) {
190  CodeTab[i] = FreeCode++; /* code -> hashtable */
191  HashTab[i] = CodeK;
192  }
193  else
194  output(ClearCode);
195  }
196  }
197  /* O U T P U T T H E R E S T */
198 
199  output(Code);
200  output(EOFCode);
201  put_byte(0); /* zero-length packet (EOF) */
202  put_byte(';'); /* GIF file terminator */
203 
204  return (Nbyte);
205 }
206 
207 static unsigned long cur_accum;
208 static int cur_bits;
209 static int a_count;
210 static char accum[256];
211 static unsigned long masks[] = { 0x0000,
212  0x0001, 0x0003, 0x0007, 0x000F,
213  0x001F, 0x003F, 0x007F, 0x00FF,
214  0x01FF, 0x03FF, 0x07FF, 0x0FFF,
215  0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
216 
217 /***************************************************************
218  * *
219  * Name: output Date: 02.10.92 *
220  * *
221  * Function: output GIF code *
222  * *
223  * Input: code - GIF code *
224  * *
225  ***************************************************************/
226 static void output(code)
227  int code;
228 {
229  /* O U T P U T C O D E */
230 
231  cur_accum &= masks[cur_bits];
232  if (cur_bits > 0)
233  cur_accum |= ((long)code << cur_bits);
234  else
235  cur_accum = code;
236  cur_bits += CurCodeSize;
237  while( cur_bits >= 8 ) {
238  char_out( (unsigned int) (cur_accum & 0xFF) );
239  cur_accum >>= 8;
240  cur_bits -= 8;
241  }
242 
243  /* R E S E T */
244 
245  if (code == ClearCode ) {
246  memset((char *) HashTab, -1, sizeof(HashTab));
247  FreeCode = ClearCode + 2;
249  CurMaxCode = (1 << (IniCodeSize)) - 1;
250  }
251 
252  /* I N C R E A S E C O D E S I Z E */
253 
254  if (FreeCode > CurMaxCode ) {
255  CurCodeSize++;
256  if ( CurCodeSize == BITS )
258  else
259  CurMaxCode = (1 << (CurCodeSize)) - 1;
260  }
261 
262  /* E N D O F F I L E : write the rest of the buffer */
263 
264  if( code == EOFCode ) {
265  while( cur_bits > 0 ) {
266  char_out( (unsigned int)(cur_accum & 0xff) );
267  cur_accum >>= 8;
268  cur_bits -= 8;
269  }
270  char_flush();
271  }
272 }
273 
274 static void char_init()
275 {
276  a_count = 0;
277  cur_accum = 0;
278  cur_bits = 0;
279 }
280 
281 static void char_out(c)
282  int c;
283 {
284  accum[a_count++] = c;
285  if (a_count >= 254)
286  char_flush();
287 }
288 
289 static void char_flush()
290 {
291  int i;
292 
293  if (a_count == 0) return;
294  put_byte(a_count);
295  for (i=0; i<a_count; i++) {
296  put_byte(accum[i]);
297  }
298  a_count = 0;
299 }
300 
301 static void put_short(word)
302  int word;
303 {
304  put_byte(word & 0xFF);
305  put_byte((word>>8) & 0xFF);
306 }
static int CurMaxCode
Definition: gifencode.c:25
static double B[]
#define HSIZE
Definition: gifencode.c:15
#define ARGS(alist)
Definition: gifencode.c:10
constexpr Double_t K()
Definition: TMath.h:178
static int IniCodeSize
Definition: gifencode.c:25
static int EOFCode
Definition: gifencode.c:25
#define BITS
Definition: gifencode.c:13
long GIFencode(void *int, void *int, void *int, R, G, B, ScLine, void *get_scline, pb)
Definition: gifencode.c:63
static int cur_bits
Definition: gifencode.c:208
#define G(x, y, z)
#define THELIMIT
Definition: gifencode.c:14
Double_t x[n]
Definition: legend1.C:17
unsigned char byte
Definition: gifdecode.c:10
static long Nbyte
Definition: gifencode.c:33
static int ClearCode
Definition: gifencode.c:25
static int FreeCode
Definition: gifencode.c:25
static unsigned long cur_accum
Definition: gifencode.c:207
static int a_count
Definition: gifencode.c:209
#define put_byte(A)
Definition: gifencode.c:18
unsigned char byte
Definition: gifencode.c:20
#define SHIFT
Definition: gifencode.c:16
static void char_flush()
Definition: gifencode.c:289
static void char_out(int c)
Definition: gifencode.c:281
static long HashTab[HSIZE]
Definition: gifencode.c:22
Double_t y[n]
Definition: legend1.C:17
static char accum[256]
Definition: gifencode.c:210
typedef void((*Func_t)())
static void put_short(int word)
Definition: gifencode.c:301
static unsigned long masks[]
Definition: gifencode.c:211
static void output(int code)
Definition: gifencode.c:226
static int BitsPixel
Definition: gifencode.c:25
static void char_init()
Definition: gifencode.c:274
constexpr Double_t R()
Definition: TMath.h:213
static int CodeTab[HSIZE]
Definition: gifencode.c:23
static int CurCodeSize
Definition: gifencode.c:25