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(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;
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
173PROBE:
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
185NOMATCH:
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
195 }
196 }
197 /* O U T P U T T H E R E S T */
198
199 output(Code);
201 put_byte(0); /* zero-length packet (EOF) */
202 put_byte(';'); /* GIF file terminator */
203
204 return (Nbyte);
205}
206
207static unsigned long cur_accum;
208static int cur_bits;
209static int a_count;
210static char accum[256];
211static 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 ***************************************************************/
226static void output(code)
227 int code;
228{
229 /* O U T P U T C O D E */
230
232 if (cur_bits > 0)
233 cur_accum |= ((long)code << cur_bits);
234 else
235 cur_accum = code;
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
274static void char_init()
275{
276 a_count = 0;
277 cur_accum = 0;
278 cur_bits = 0;
279}
280
281static void char_out(c)
282 int c;
283{
284 accum[a_count++] = c;
285 if (a_count >= 254)
286 char_flush();
287}
288
289static void char_flush()
290{
291 int i;
292
293 if (a_count == 0) return;
295 for (i=0; i<a_count; i++) {
296 put_byte(accum[i]);
297 }
298 a_count = 0;
299}
300
301static void put_short(word)
302 int word;
303{
304 put_byte(word & 0xFF);
305 put_byte((word>>8) & 0xFF);
306}
#define c(i)
Definition: RSha256.hxx:101
#define R(a, b, c, d, e, f, g, h, i)
Definition: RSha256.hxx:110
typedef void((*Func_t)())
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
static double B[]
unsigned char byte
Definition: gifencode.c:20
long GIFencode(void *int, void *int, void *int, R, G, B, ScLine, void *get_scline, pb)
Definition: gifencode.c:63
static unsigned long masks[]
Definition: gifencode.c:211
static void put_short(int word)
Definition: gifencode.c:301
static int ClearCode
Definition: gifencode.c:29
static int cur_bits
Definition: gifencode.c:208
static char accum[256]
Definition: gifencode.c:210
static void char_init()
Definition: gifencode.c:274
#define put_byte(A)
Definition: gifencode.c:18
static long HashTab[HSIZE]
Definition: gifencode.c:22
static unsigned long cur_accum
Definition: gifencode.c:207
static void char_flush()
Definition: gifencode.c:289
static void output(int code)
Definition: gifencode.c:226
static int BitsPixel
Definition: gifencode.c:25
#define THELIMIT
Definition: gifencode.c:14
#define ARGS(alist)
Definition: gifencode.c:10
static int FreeCode
Definition: gifencode.c:31
#define BITS
Definition: gifencode.c:13
static int IniCodeSize
Definition: gifencode.c:26
static void char_out(int c)
Definition: gifencode.c:281
#define SHIFT
Definition: gifencode.c:16
static int a_count
Definition: gifencode.c:209
#define HSIZE
Definition: gifencode.c:15
static int CurCodeSize
Definition: gifencode.c:27
static int CodeTab[HSIZE]
Definition: gifencode.c:23
static int CurMaxCode
Definition: gifencode.c:28
static int EOFCode
Definition: gifencode.c:30
static long Nbyte
Definition: gifencode.c:33