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