Rev 33 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 33 | Rev 108 | ||
|---|---|---|---|
| Line 7... | Line 7... | ||
| 7 | # include <time.h> |
7 | # include <time.h> |
| 8 | # ifndef CLOCKS_PER_SEC |
8 | # ifndef CLOCKS_PER_SEC |
| 9 | # define CLOCKS_PER_SEC CLK_TCK |
9 | # define CLOCKS_PER_SEC CLK_TCK |
| 10 | # endif |
10 | # endif |
| 11 | /* ---------------------------- Error codes --------------------------- */ |
11 | /* ---------------------------- Error codes --------------------------- */ |
| 12 | /* |
12 | /* ----------- */ |
| 13 | # define COMP_ERR_NONE 0 /* everything is OK */ |
13 | # define COMP_ERR_NONE 0 /* everything is OK */ |
| 14 | # define COMP_ERR_READ 2 /* input file read error |
14 | # define COMP_ERR_READ 2 /* input file read error */ |
| 15 | # define COMP_ERR_NOMEM 5 /* no enough memory */ |
15 | # define COMP_ERR_NOMEM 5 /* no enough memory */ |
| 16 | # define COMP_ERR_BROKEN 6 /* damaged compressed data |
16 | # define COMP_ERR_BROKEN 6 /* damaged compressed data */ |
| 17 | # define COMP_ERR_PARAM 7 /* incorrect function parameter */ |
17 | # define COMP_ERR_PARAM 7 /* incorrect function parameter */ |
| 18 | # define COMP_ERR_INTERNAL 9 /* everything else is internal error |
18 | # define COMP_ERR_INTERNAL 9 /* everything else is internal error */ |
| 19 | /* hopefully it should never happen */ |
19 | /* hopefully it should never happen */ |
| 20 | /* Almost all functions listed further return one as its result on of */ |
20 | /* Almost all functions listed further return one as its result on of */ |
| 21 | /* codes given |
21 | /* codes given above: if no error occured then COMP_ERR_NONE (i.e. 0) */ |
| 22 | /* is returned, otherwise functions return error code plus number of */ |
22 | /* is returned, otherwise functions return error code plus number of */ |
| 23 | /* line in "comp.c" where the error was detected multiplied by 256; */ |
23 | /* line in "comp.c" where the error was detected multiplied by 256; */ |
| 24 | /* line number may be |
24 | /* line number may be used for exact specification of a place where */ |
| 25 | /* error was detected thus making debugging slightly simpler. */ |
25 | /* error was detected thus making debugging slightly simpler. */ |
| 26 | /* |
26 | /* */ |
| 27 | /* Thus, "(code & 0xff)" gives proper error code, and "(code >> 8)" */ |
27 | /* Thus, "(code & 0xff)" gives proper error code, and "(code >> 8)" */ |
| 28 | /* gives number of line where the error was raised. */ |
28 | /* gives number of line where the error was raised. */ |
| 29 | /* -------------------------------------------------------------------- */ |
29 | /* -------------------------------------------------------------------- */ |
| 30 | /* |
30 | /* */ |
| 31 | /* |
31 | /* Compress/decompress some chess tables */ |
| 32 | /* |
32 | /* */ |
| 33 | /* |
33 | /* Copyright (c) 1991--1998 Andrew Kadatch */ |
| 34 | /* |
34 | /* */ |
| 35 | /* The Limited-Reference variant of Lempel-Ziv algorithm implemented */ |
35 | /* The Limited-Reference variant of Lempel-Ziv algorithm implemented */ |
| 36 | /* here was first described in |
36 | /* here was first described in my B.Sc. thesis "Efficient algorithms */ |
| 37 | /* for image compression", Novosibirsk State University, 1992, and */ |
37 | /* for image compression", Novosibirsk State University, 1992, and */ |
| 38 | /* cannot be used in any product distributed in Russia or CIS without */ |
38 | /* cannot be used in any product distributed in Russia or CIS without */ |
| 39 | /* written permission from the author. |
39 | /* written permission from the author. */ |
| 40 | /* |
40 | /* */ |
| 41 | /* Most of the code listed below is significantly simplified code from */ |
41 | /* Most of the code listed below is significantly simplified code from */ |
| 42 | /* the PRS data compression library and therefore it should not be used */ |
42 | /* the PRS data compression library and therefore it should not be used */ |
| 43 | /* in any product (software or hardware, commercial or not, and so on) */ |
43 | /* in any product (software or hardware, commercial or not, and so on) */ |
| 44 | /* without written permission from the author. |
44 | /* without written permission from the author. */ |
| 45 | /* |
45 | /* */ |
| 46 | /* -------------------------------------------------------------------- */ |
46 | /* -------------------------------------------------------------------- */ |
| 47 | /* ---------------------------- Debugging ----------------------------- */ |
47 | /* ---------------------------- Debugging ----------------------------- */ |
| 48 | /* |
48 | /* --------- */ |
| 49 | # ifndef DEBUG |
49 | # ifndef DEBUG |
| 50 | # define DEBUG 0 |
50 | # define DEBUG 0 |
| 51 | # endif |
51 | # endif |
| 52 | # if DEBUG |
52 | # if DEBUG |
| - | 53 | # undef assert |
|
| 53 | # define assert(cond) ((cond) ? (void) 0 : _local_assert (__LINE__)) |
54 | # define assert(cond) ((cond) ? (void) 0 : _local_assert (__LINE__)) |
| 54 | static void _local_assert(int lineno) |
55 | static void _local_assert(int lineno) |
| 55 | { |
56 | { |
| 56 | fprintf(stderr, "assertion at line %u failed\n", lineno); |
57 | fprintf(stderr, "assertion at line %u failed\n", lineno); |
| 57 | exit(33); |
58 | exit(33); |
| Line 61... | Line 62... | ||
| 61 | # define dprintf(x) printf x |
62 | # define dprintf(x) printf x |
| 62 | # else |
63 | # else |
| 63 | # if !defined (assert) |
64 | # if !defined (assert) |
| 64 | # define assert(cond) ((void) 0) |
65 | # define assert(cond) ((void) 0) |
| 65 | # endif |
66 | # endif |
| 66 | # define debug(x) |
67 | # define debug(x) ((void) 0) |
| 67 | # define dprintf(x) |
68 | # define dprintf(x) ((void) 0) |
| 68 | # endif |
69 | # endif |
| 69 | /* mob_pach */ |
70 | /* mob_pach */ |
| 70 | # ifndef __cplusplus |
71 | # ifndef __cplusplus |
| 71 | int cbEGTBCompBytes = 0; |
72 | int cbEGTBCompBytes = 0; |
| 72 | # else |
73 | # else |
| 73 | extern "C" { |
74 | extern "C" { |
| 74 | int cbEGTBCompBytes = 0; |
75 | int cbEGTBCompBytes = 0; |
| 75 | } |
76 | } |
| 76 | # endif |
77 | # endif |
| 77 | /* --------------------- Constants, types, etc. ----------------------- */ |
78 | /* --------------------- Constants, types, etc. ----------------------- */ |
| 78 | /* |
79 | /* ---------------------- */ |
| 79 | # define MIN_BLOCK_BITS 8 |
80 | # define MIN_BLOCK_BITS 8 |
| 80 | /* LOG2 (min size of block to compress) */ |
81 | /* LOG2 (min size of block to compress) */ |
| 81 | # define MAX_BLOCK_BITS 16 |
82 | # define MAX_BLOCK_BITS 16 |
| 82 | /* LOG2 (max size of block to compress) */ |
83 | /* LOG2 (max size of block to compress) */ |
| 83 | /* max. integer we can take LOG2 by table */ |
84 | /* max. integer we can take LOG2 by table */ |
| 84 | # define MAX_BITS_HALF ((MAX_BLOCK_BITS + 1) >> 1) |
85 | # define MAX_BITS_HALF ((MAX_BLOCK_BITS + 1) >> 1) |
| 85 | # define MAX_BITS (MAX_BITS_HALF * 2) |
86 | # define MAX_BITS (MAX_BITS_HALF * 2) |
| 86 | /* assume that integer is at least 32 bits wide */ |
87 | /* assume that integer is at least 32 bits wide */ |
| 87 | # ifndef uchar |
88 | # ifndef uchar |
| 88 | # define uchar unsigned char |
89 | # define uchar unsigned char |
| 89 | # endif |
90 | # endif |
| 90 | # define HEADER_SIZE 80 |
91 | # define HEADER_SIZE 80 /* number of reserved bytes */ |
| 91 | # define STOP_SEARCH_LENGTH 256 /* terminate search if match |
92 | # define STOP_SEARCH_LENGTH 256 /* terminate search if match */ |
| 92 | /* length exceeds that value |
93 | /* length exceeds that value */ |
| 93 | # define MAX_LENGTH_BITS 5 |
94 | # define MAX_LENGTH_BITS 5 |
| 94 | # define MAX_LENGTH |
95 | # define MAX_LENGTH (1 << MAX_LENGTH_BITS) |
| 95 | # define LONG_BITS 1 |
96 | # define LONG_BITS 1 |
| 96 | # define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) |
97 | # define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) |
| 97 | # define LONG_QUICK (MAX_LENGTH - LONG_LENGTH) |
98 | # define LONG_QUICK (MAX_LENGTH - LONG_LENGTH) |
| 98 | # if LONG_LENGTH > (MAX_BLOCK_BITS - LONG_BITS) |
99 | # if LONG_LENGTH > (MAX_BLOCK_BITS - LONG_BITS) |
| 99 | # undef LONG_LENGTH |
100 | # undef LONG_LENGTH |
| 100 | # define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) |
101 | # define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) |
| 101 | # endif |
102 | # endif |
| 102 | # if LONG_LENGTH >= MAX_LENGTH || LONG_LENGTH <= 0 |
103 | # if LONG_LENGTH >= MAX_LENGTH || LONG_LENGTH <= 0 |
| 103 | # error LONG_LENGTH is out of range |
104 | # error LONG_LENGTH is out of range |
| 104 | # endif |
105 | # endif |
| 105 | # if LONG_BITS <= 0 |
106 | # if LONG_BITS <= 0 |
| 106 | # error LONG_BITS must be positive |
107 | # error LONG_BITS must be positive |
| 107 | # endif |
108 | # endif |
| 108 | # define DELTA (LONG_BITS + LONG_QUICK - 1) |
109 | # define DELTA (LONG_BITS + LONG_QUICK - 1) |
| 109 | # if (MAX_LENGTH - 1) - (LONG_LENGTH - LONG_BITS) != DELTA |
110 | # if (MAX_LENGTH - 1) - (LONG_LENGTH - LONG_BITS) != DELTA |
| 110 | # error Hmmm |
111 | # error Hmmm |
| 111 | # endif |
112 | # endif |
| 112 | # define MAX_DISTANCES 24 |
113 | # define MAX_DISTANCES 24 |
| 113 | # define LOG_MAX_DISTANCES 6 /* see check below |
114 | # define LOG_MAX_DISTANCES 6 /* see check below */ |
| 114 | # if MAX_DISTANCES > (1 << LOG_MAX_DISTANCES) |
115 | # if MAX_DISTANCES > (1 << LOG_MAX_DISTANCES) |
| 115 | # error MAX_DISTANCES should not exceed (1 << LOG_MAX_DISTANCES) |
116 | # error MAX_DISTANCES should not exceed (1 << LOG_MAX_DISTANCES) |
| 116 | # endif |
117 | # endif |
| 117 | # define ALPHABET_SIZE (256 + (MAX_DISTANCES << MAX_LENGTH_BITS)) |
118 | # define ALPHABET_SIZE (256 + (MAX_DISTANCES << MAX_LENGTH_BITS)) |
| 118 | # define MAX_ALPHABET ALPHABET_SIZE /* max. alphabet handled by */ |
119 | # define MAX_ALPHABET ALPHABET_SIZE /* max. alphabet handled by */ |
| 119 | /* Huffman coding routines |
120 | /* Huffman coding routines */ |
| 120 | # define USE_CRC32 1 |
121 | # define USE_CRC32 1 |
| 121 | /* 0 - use Fletcher's checksum, != 0 - use proper CRC32 */ |
122 | /* 0 - use Fletcher's checksum, != 0 - use proper CRC32 */ |
| 122 | static uchar header_title[64] = |
123 | static uchar header_title[64] = |
| 123 | "Compressed by DATACOMP v 1.0 (c) 1991--1998 Andrew Kadatch\r\n\0"; |
124 | "Compressed by DATACOMP v 1.0 (c) 1991--1998 Andrew Kadatch\r\n\0"; |
| 124 | 125 | ||
| 125 | # define RET(n) ((n) + __LINE__ * 256) |
126 | # define RET(n) ((n) + __LINE__ * 256) |
| 126 | /* ------------------------- CRC32 routines --------------------------- */ |
127 | /* ------------------------- CRC32 routines --------------------------- */ |
| 127 | /* |
128 | /* -------------- */ |
| 128 | # if USE_CRC32 |
129 | # if USE_CRC32 |
| 129 | static unsigned CRC32_table[256]; |
130 | static unsigned CRC32_table[256]; |
| 130 | static int CRC32_initialized = 0; |
131 | static int CRC32_initialized = 0; |
| 131 | static void CRC32_init(void) |
132 | static void CRC32_init(void) |
| 132 | { |
133 | { |
| Line 138... | Line 139... | ||
| 138 | for (i = 0; i < 256; ++i) { |
139 | for (i = 0; i < 256; ++i) { |
| 139 | k = i; |
140 | k = i; |
| 140 | j = 8; |
141 | j = 8; |
| 141 | do { |
142 | do { |
| 142 | if ((k & 1) != 0) |
143 | if ((k & 1) != 0) |
| 143 | k >>= 1; |
144 | k >>= 1; |
| 144 | else { |
145 | else { |
| 145 | k >>= 1; |
146 | k >>= 1; |
| 146 | k ^= m; |
147 | k ^= m; |
| 147 | }; |
148 | }; |
| 148 | } while (--j); |
149 | } while (--j); |
| 149 | CRC32_table[i] = k; |
150 | CRC32_table[i] = k; |
| 150 | } |
151 | } |
| 151 | CRC32_initialized = 1; |
152 | CRC32_initialized = 1; |
| Line 220... | Line 221... | ||
| 220 | k0 = (k0 & 0xffff) + (k0 >> 16); |
221 | k0 = (k0 & 0xffff) + (k0 >> 16); |
| 221 | k1 = (k1 & 0xffff) + (k1 >> 16); |
222 | k1 = (k1 & 0xffff) + (k1 >> 16); |
| 222 | assert(((k0 | k1) >> 16) == 0); |
223 | assert(((k0 | k1) >> 16) == 0); |
| 223 | return (k0 + (k1 << 16)); |
224 | return (k0 + (k1 << 16)); |
| 224 | } |
225 | } |
| 225 | # endif |
226 | # endif /* USE_CRC32 */ |
| 226 | /* ------------------------ Bit IO interface -------------------------- */ |
227 | /* ------------------------ Bit IO interface -------------------------- */ |
| 227 | /* |
228 | /* ---------------- */ |
| 228 | # define BITIO_LOCALS \ |
229 | # define BITIO_LOCALS \ |
| 229 | unsigned int _mask; \ |
230 | unsigned int _mask; \ |
| 230 | int _bits; \ |
231 | int _bits; \ |
| 231 | uchar *_ptr |
232 | uchar *_ptr |
| 232 | typedef struct { |
233 | typedef struct { |
| 233 | BITIO_LOCALS; |
234 | BITIO_LOCALS; |
| 234 | } bitio_t; |
235 | } bitio_t; |
| 235 | 236 | ||
| 236 | # define BITIO_ENTER(p) do { \ |
237 | # define BITIO_ENTER(p) do { \ |
| 237 | _mask = (p)._mask; |
238 | _mask = (p)._mask; \ |
| 238 | _bits = (p)._bits; |
239 | _bits = (p)._bits; \ |
| 239 | _ptr |
240 | _ptr = (p)._ptr; \ |
| 240 | } while (0) |
241 | } while (0) |
| 241 | # define BITIO_LEAVE(p) do { \ |
242 | # define BITIO_LEAVE(p) do { \ |
| 242 | (p)._mask = _mask; |
243 | (p)._mask = _mask; \ |
| 243 | (p)._bits = _bits; |
244 | (p)._bits = _bits; \ |
| 244 | (p)._ptr = _ptr; \ |
245 | (p)._ptr = _ptr; \ |
| 245 | } while (0) |
246 | } while (0) |
| 246 | # define BIORD_START(from) do { \ |
247 | # define BIORD_START(from) do { \ |
| 247 | _ptr = (uchar *) (from); |
248 | _ptr = (uchar *) (from); \ |
| 248 | _bits = sizeof (_mask); \ |
249 | _bits = sizeof (_mask); \ |
| 249 | _mask = 0; |
250 | _mask = 0; \ |
| 250 | do |
251 | do \ |
| 251 | _mask = (_mask << 8) | *_ptr++; \ |
252 | _mask = (_mask << 8) | *_ptr++; \ |
| 252 | while (--_bits != 0); \ |
253 | while (--_bits != 0); \ |
| 253 | _bits = 16; \ |
254 | _bits = 16; \ |
| 254 | } while (0) |
255 | } while (0) |
| 255 | /* read [1, 17] bits at once */ |
256 | /* read [1, 17] bits at once */ |
| 256 | # define BIORD(bits) \ |
257 | # define BIORD(bits) \ |
| 257 | (_mask >> (8 * sizeof (_mask) - (bits))) |
258 | (_mask >> (8 * sizeof (_mask) - (bits))) |
| 258 | # define BIORD_MORE(bits) do { \ |
259 | # define BIORD_MORE(bits) do { \ |
| 259 | _mask <<= (bits); \ |
260 | _mask <<= (bits); \ |
| 260 | if ((_bits -= (bits)) <= 0) \ |
261 | if ((_bits -= (bits)) <= 0) \ |
| 261 | { \ |
262 | { \ |
| 262 | _mask |= ((_ptr[0] << 8) + _ptr[1]) << (-_bits); \ |
263 | _mask |= ((_ptr[0] << 8) + _ptr[1]) << (-_bits); \ |
| 263 | _ptr += 2; _bits += 16; \ |
264 | _ptr += 2; _bits += 16; \ |
| 264 | } \ |
265 | } \ |
| 265 | } while (0) |
266 | } while (0) |
| 266 | /* ------------------------ Huffman coding ---------------------------- */ |
267 | /* ------------------------ Huffman coding ---------------------------- */ |
| 267 | /* |
268 | /* -------------- */ |
| 268 | # if MAX_ALPHABET <= 0xffff |
269 | # if MAX_ALPHABET <= 0xffff |
| 269 | # if MAX_ALPHABET <= 1024 |
270 | # if MAX_ALPHABET <= 1024 |
| 270 | /* positive value takes 15 bits => symbol number occupies <= 10 bits |
271 | /* positive value takes 15 bits => symbol number occupies <= 10 bits */ |
| 271 | # define huffman_decode_t short |
272 | # define huffman_decode_t short |
| 272 | # else |
273 | # else |
| 273 | # define huffman_decode_t int |
274 | # define huffman_decode_t int |
| 274 | # endif |
275 | # endif |
| 275 | # else |
276 | # else |
| 276 | # define huffman_decode_t int |
277 | # define huffman_decode_t int |
| 277 | # endif |
278 | # endif |
| 278 | # define HUFFMAN_DECODE(ch,table,start_bits) do { \ |
279 | # define HUFFMAN_DECODE(ch,table,start_bits) do { \ |
| 279 | (ch) = table[BIORD (start_bits)]; \ |
280 | (ch) = table[BIORD (start_bits)]; \ |
| 280 | if (((int) (ch)) >= 0) |
281 | if (((int) (ch)) >= 0) \ |
| 281 | { \ |
282 | { \ |
| 282 | BIORD_MORE ((ch) & 31); \ |
283 | BIORD_MORE ((ch) & 31); \ |
| 283 | (ch) >>= 5; \ |
284 | (ch) >>= 5; \ |
| 284 | break; |
285 | break; \ |
| 285 | } \ |
286 | } \ |
| 286 | BIORD_MORE (start_bits); |
287 | BIORD_MORE (start_bits); \ |
| 287 | do |
288 | do \ |
| 288 | { \ |
289 | { \ |
| 289 | (ch) = table[BIORD (1) - (ch)]; \ |
290 | (ch) = table[BIORD (1) - (ch)]; \ |
| 290 | BIORD_MORE (1); \ |
291 | BIORD_MORE (1); \ |
| 291 | } \ |
292 | } \ |
| 292 | while (((int) (ch)) < 0); \ |
293 | while (((int) (ch)) < 0); \ |
| 293 | } while (0) |
294 | } while (0) |
| 294 | # define HUFFMAN_TABLE_SIZE(n,start_bits) \ |
295 | # define HUFFMAN_TABLE_SIZE(n,start_bits) \ |
| 295 | ((1 << (start_bits)) + ((n) << 1)) |
296 | ((1 << (start_bits)) + ((n) << 1)) |
| 296 | static int huffman_decode_create(huffman_decode_t * table, uchar * length, |
297 | static int huffman_decode_create(huffman_decode_t * table, uchar * length, |
| 297 | int n, int start_bits) |
298 | int n, int start_bits) |
| 298 | { |
299 | { |
| 299 | int i, j, k, last, freq[32], sum[32]; |
300 | int i, j, k, last, freq[32], sum[32]; |
| 300 | 301 | ||
| 301 | /* calculate number of codewords |
302 | /* calculate number of codewords */ |
| 302 | memset(freq, 0, sizeof(freq)); |
303 | memset(freq, 0, sizeof(freq)); |
| 303 | for (i = 0; i < n; ++i) { |
304 | for (i = 0; i < n; ++i) { |
| 304 | if ((k = length[i]) > 31) |
305 | if ((k = length[i]) > 31) |
| 305 | return RET(COMP_ERR_BROKEN); |
306 | return RET(COMP_ERR_BROKEN); |
| 306 | ++freq[k]; |
307 | ++freq[k]; |
| 307 | } |
308 | } |
| 308 | /* handle special case(s) -- 0 and 1 symbols in alphabet |
309 | /* handle special case(s) -- 0 and 1 symbols in alphabet */ |
| 309 | if (freq[0] == n) { |
310 | if (freq[0] == n) { |
| 310 | memset(table, 0, sizeof(table[0]) << start_bits); |
311 | memset(table, 0, sizeof(table[0]) << start_bits); |
| 311 | return (0); |
312 | return (0); |
| 312 | } |
313 | } |
| 313 | if (freq[0] == n - 1) { |
314 | if (freq[0] == n - 1) { |
| Line 318... | Line 319... | ||
| 318 | i <<= 5; |
319 | i <<= 5; |
| 319 | for (k = 1 << start_bits; --k >= 0;) |
320 | for (k = 1 << start_bits; --k >= 0;) |
| 320 | *table++ = (huffman_decode_t) i; |
321 | *table++ = (huffman_decode_t) i; |
| 321 | return (0); |
322 | return (0); |
| 322 | } |
323 | } |
| 323 | /* save frequences |
324 | /* save frequences */ |
| 324 | memcpy(sum, freq, sizeof(sum)); |
325 | memcpy(sum, freq, sizeof(sum)); |
| 325 | /* check code correctness */ |
326 | /* check code correctness */ |
| 326 | k = 0; |
327 | k = 0; |
| 327 | for (i = 32; --i != 0;) { |
328 | for (i = 32; --i != 0;) { |
| 328 | if ((k += freq[i]) & 1) |
329 | if ((k += freq[i]) & 1) |
| 329 | return RET(COMP_ERR_BROKEN); |
330 | return RET(COMP_ERR_BROKEN); |
| 330 | k >>= 1; |
331 | k >>= 1; |
| 331 | } |
332 | } |
| 332 | if (k != 1) |
333 | if (k != 1) |
| 333 | return RET(COMP_ERR_BROKEN); |
334 | return RET(COMP_ERR_BROKEN); |
| 334 | /* sort symbols */ |
335 | /* sort symbols */ |
| 335 | k = 0; |
336 | k = 0; |
| 336 | for (i = 1; i < 32; ++i) |
337 | for (i = 1; i < 32; ++i) |
| 337 | freq[i] = (k += freq[i]); |
338 | freq[i] = (k += freq[i]); |
| 338 | last = freq[31]; |
339 | last = freq[31]; /* preserve number of symbols in alphabet */ |
| 339 | for (i = n; --i >= 0;) { |
340 | for (i = n; --i >= 0;) { |
| 340 | if ((k = length[i]) != 0) |
341 | if ((k = length[i]) != 0) |
| 341 | table[--freq[k]] = (huffman_decode_t) i; |
342 | table[--freq[k]] = (huffman_decode_t) i; |
| 342 | } |
343 | } |
| 343 | /* now create decoding table */ |
344 | /* now create decoding table */ |
| Line 358... | Line 359... | ||
| 358 | for (k = sum[n]; --k >= 0;) { |
359 | for (k = sum[n]; --k >= 0;) { |
| 359 | assert(last <= i && last > 0); |
360 | assert(last <= i && last > 0); |
| 360 | j = i - (1 << (start_bits - n)); |
361 | j = i - (1 << (start_bits - n)); |
| 361 | n |= table[--last] << 5; |
362 | n |= table[--last] << 5; |
| 362 | do |
363 | do |
| 363 | table[--i] = (huffman_decode_t) n; |
364 | table[--i] = (huffman_decode_t) n; |
| 364 | while (i != j); |
365 | while (i != j); |
| 365 | n &= 31; |
366 | n &= 31; |
| 366 | } |
367 | } |
| 367 | } |
368 | } |
| 368 | assert((i | last) == 0); |
369 | assert((i | last) == 0); |
| 369 | return (0); |
370 | return (0); |
| 370 | } |
371 | } |
| 371 | 372 | ||
| 372 | /* -------------------- Read/write Huffman code ----------------------- */ |
373 | /* -------------------- Read/write Huffman code ----------------------- */ |
| 373 | /* |
374 | /* ----------------------- */ |
| 374 | # define MIN_REPT 2 |
375 | # define MIN_REPT 2 |
| 375 | # if MIN_REPT <= 1 |
376 | # if MIN_REPT <= 1 |
| 376 | # error MIN_REPT must exceed 1 |
377 | # error MIN_REPT must exceed 1 |
| 377 | # endif |
378 | # endif |
| 378 | # define TEMP_TABLE_BITS 8 |
379 | # define TEMP_TABLE_BITS 8 |
| Line 395... | Line 396... | ||
| 395 | BIORD_MORE(5); |
396 | BIORD_MORE(5); |
| 396 | for (i = 0; i < n;) { |
397 | for (i = 0; i < n;) { |
| 397 | length[i] = (uchar) BIORD(k); |
398 | length[i] = (uchar) BIORD(k); |
| 398 | BIORD_MORE(k); |
399 | BIORD_MORE(k); |
| 399 | if (length[i++] == 0) { |
400 | if (length[i++] == 0) { |
| 400 | j = i + BIORD(4); |
401 | j = i + BIORD(4); |
| 401 | BIORD_MORE(4); |
402 | BIORD_MORE(4); |
| 402 | if (j > n) |
403 | if (j > n) |
| 403 | return RET(COMP_ERR_BROKEN); |
404 | return RET(COMP_ERR_BROKEN); |
| 404 | while (i != j) |
405 | while (i != j) |
| 405 | length[i++] = 0; |
406 | length[i++] = 0; |
| 406 | } |
407 | } |
| 407 | } |
408 | } |
| 408 | goto ret; |
409 | goto ret; |
| 409 | } |
410 | } |
| 410 | BITIO_LEAVE(*bitio); |
411 | BITIO_LEAVE(*bitio); |
| Line 429... | Line 430... | ||
| 429 | if (j > 31) { |
430 | if (j > 31) { |
| 430 | int jj = j - 32; |
431 | int jj = j - 32; |
| 431 | 432 | ||
| 432 | j = 1 << jj; |
433 | j = 1 << jj; |
| 433 | if (jj != 0) { |
434 | if (jj != 0) { |
| 434 | if (jj > 16) { |
435 | if (jj > 16) { |
| 435 | j += BIORD(16) << (jj - 16); |
436 | j += BIORD(16) << (jj - 16); |
| 436 | BIORD_MORE(16); |
437 | BIORD_MORE(16); |
| 437 | } |
438 | } |
| 438 | j += BIORD(jj); |
439 | j += BIORD(jj); |
| 439 | BIORD_MORE(jj); |
440 | BIORD_MORE(jj); |
| 440 | } |
441 | } |
| 441 | j += 31; |
442 | j += 31; |
| 442 | } |
443 | } |
| 443 | j += MIN_REPT + i; |
444 | j += MIN_REPT + i; |
| 444 | if (j > n) |
445 | if (j > n) |
| Line 451... | Line 452... | ||
| 451 | BITIO_LEAVE(*bitio); |
452 | BITIO_LEAVE(*bitio); |
| 452 | return (0); |
453 | return (0); |
| 453 | } |
454 | } |
| 454 | 455 | ||
| 455 | /* ----------------------- Proper compression ------------------------- */ |
456 | /* ----------------------- Proper compression ------------------------- */ |
| 456 | /* |
457 | /* ------------------ */ |
| 457 | # if MIN_BLOCK_BITS > MAX_BLOCK_BITS || MAX_BLOCK_BITS > MAX_BITS_HALF*2 |
458 | # if MIN_BLOCK_BITS > MAX_BLOCK_BITS || MAX_BLOCK_BITS > MAX_BITS_HALF*2 |
| 458 | # error condition MIN_BLOCK_BITS <= MAX_BLOCK_BITS <= MAX_BITS_HALF*2 failed |
459 | # error condition MIN_BLOCK_BITS <= MAX_BLOCK_BITS <= MAX_BITS_HALF*2 failed |
| 459 | # endif |
460 | # endif |
| 460 | # define DECODE_MAGIC |
461 | # define DECODE_MAGIC ((int) 0x5abc947fL) |
| 461 | # define BLOCK_MAGIC ((int) 0x79a3f29dL) |
462 | # define BLOCK_MAGIC ((int) 0x79a3f29dL) |
| 462 | # define START_BITS |
463 | # define START_BITS 13 |
| 463 | # define SHORT_INDEX 8u |
464 | # define SHORT_INDEX 8u |
| 464 | typedef struct { |
465 | typedef struct { |
| 465 | huffman_decode_t table[HUFFMAN_TABLE_SIZE(ALPHABET_SIZE, START_BITS)]; |
466 | huffman_decode_t table[HUFFMAN_TABLE_SIZE(ALPHABET_SIZE, START_BITS)]; |
| 466 | int distance[MAX_DISTANCES]; |
467 | int distance[MAX_DISTANCES]; |
| 467 | unsigned *crc, *blk_u; |
468 | unsigned *crc, *blk_u; |
| 468 | unsigned short *blk_s; |
469 | unsigned short *blk_s; |
| 469 | int block_size_log, /* block_size is integral power of 2 |
470 | int block_size_log, /* block_size is integral power of 2 */ |
| 470 | block_size, |
471 | block_size, /* 1 << block_size_log */ |
| 471 | last_block_size, /* [original] size of last block |
472 | last_block_size, /* [original] size of last block */ |
| 472 | n_blk, /* total number of blocks */ |
473 | n_blk, /* total number of blocks */ |
| 473 | comp_block_size, /* size of largest compressed block+32 |
474 | comp_block_size, /* size of largest compressed block+32 */ |
| 474 | check_crc; /* check CRC32? */ |
475 | check_crc; /* check CRC32? */ |
| 475 | uchar *comp; |
476 | uchar *comp; |
| 476 | int magic; |
477 | int magic; |
| 477 | } decode_info; |
478 | } decode_info; |
| 478 | typedef struct { |
479 | typedef struct { |
| 479 | unsigned char *ptr; /* pointer to the first decoded byte */ |
480 | unsigned char *ptr; /* pointer to the first decoded byte */ |
| 480 | int decoded; |
481 | int decoded; /* number of bytes decoded so far */ |
| 481 | int total; |
482 | int total; /* total number of bytes in block */ |
| 482 | int number; /* number of this block */ |
483 | int number; /* number of this block */ |
| 483 | } COMP_BLOCK_T; |
484 | } COMP_BLOCK_T; |
| 484 | 485 | ||
| 485 | /* Pointer to compressed data block */ |
486 | /* Pointer to compressed data block */ |
| 486 | typedef struct { |
487 | typedef struct { |
| 487 | COMP_BLOCK_T b; |
488 | COMP_BLOCK_T b; |
| 488 | struct { |
489 | struct { |
| 489 | uchar *first; |
490 | uchar *first; |
| 490 | int size; |
491 | int size; |
| Line 545... | Line 546... | ||
| 545 | OVER; |
546 | OVER; |
| 546 | } else if (ch >= LONG_LENGTH) { |
547 | } else if (ch >= LONG_LENGTH) { |
| 547 | ch -= LONG_LENGTH - LONG_BITS; |
548 | ch -= LONG_LENGTH - LONG_BITS; |
| 548 | # if (MAX_BLOCK_BITS - 1) + (LONG_LENGTH - LONG_BITS) >= MAX_LENGTH |
549 | # if (MAX_BLOCK_BITS - 1) + (LONG_LENGTH - LONG_BITS) >= MAX_LENGTH |
| 549 | if (ch == DELTA) { |
550 | if (ch == DELTA) { |
| 550 | ch = BIORD(5); |
551 | ch = BIORD(5); |
| 551 | BIORD_MORE(5); |
552 | BIORD_MORE(5); |
| 552 | ch += DELTA; |
553 | ch += DELTA; |
| 553 | } |
554 | } |
| 554 | # endif |
555 | # endif |
| 555 | { |
556 | { |
| 556 | int n = 1 << ch; |
557 | int n = 1 << ch; |
| 557 | 558 | ||
| 558 | if (ch > 16) { |
559 | if (ch > 16) { |
| 559 | n += BIORD(16) << (ch -= 16); |
560 | n += BIORD(16) << (ch -= 16); |
| 560 | BIORD_MORE(16); |
561 | BIORD_MORE(16); |
| 561 | } |
562 | } |
| 562 | n += BIORD(ch); |
563 | n += BIORD(ch); |
| 563 | BIORD_MORE(ch); |
564 | BIORD_MORE(ch); |
| 564 | ch = n; |
565 | ch = n; |
| 565 | } |
566 | } |
| 566 | ch += LONG_LENGTH - (1 << LONG_BITS); |
567 | ch += LONG_LENGTH - (1 << LONG_BITS); |
| 567 | } |
568 | } |
| 568 | ++ch; |
569 | ++ch; |
| 569 | copy: |
570 | copy: |
| 570 | if (ch > 16) { |
571 | if (ch > 16) { |
| 571 | if (p + ch > e) { |
572 | if (p + ch > e) { |
| 572 | block->emit.rept = ch - (int) (e - p); |
573 | block->emit.rept = ch - (int) (e - p); |
| 573 | ch = (int) (e - p); |
574 | ch = (int) (e - p); |
| 574 | goto copy; |
575 | goto copy; |
| 575 | } |
576 | } |
| 576 | do { |
577 | do { |
| 577 | # define X(i) p[i] = s[i] |
578 | # define X(i) p[i] = s[i] |
| 578 | X(0); |
579 | X(0); |
| 579 | X(1); |
580 | X(1); |
| 580 | X(2); |
581 | X(2); |
| 581 | X(3); |
582 | X(3); |
| 582 | X(4); |
583 | X(4); |
| 583 | X(5); |
584 | X(5); |
| 584 | X(6); |
585 | X(6); |
| 585 | X(7); |
586 | X(7); |
| 586 | X(8); |
587 | X(8); |
| 587 | X(9); |
588 | X(9); |
| 588 | X(10); |
589 | X(10); |
| 589 | X(11); |
590 | X(11); |
| 590 | X(12); |
591 | X(12); |
| 591 | X(13); |
592 | X(13); |
| 592 | X(14); |
593 | X(14); |
| 593 | X(15); |
594 | X(15); |
| 594 | # undef X |
595 | # undef X |
| 595 | p += 16; |
596 | p += 16; |
| 596 | s += 16; |
597 | s += 16; |
| 597 | } while ((ch -= 16) > 16); |
598 | } while ((ch -= 16) > 16); |
| 598 | } |
599 | } |
| 599 | p += ch; |
600 | p += ch; |
| 600 | s += ch; |
601 | s += ch; |
| 601 | switch (ch) { |
602 | switch (ch) { |
| Line 661... | Line 662... | ||
| 661 | MAX_LENGTH_BITS) |
662 | MAX_LENGTH_BITS) |
| 662 | return RET(COMP_ERR_BROKEN); |
663 | return RET(COMP_ERR_BROKEN); |
| 663 | if ((ptr = (uchar *) malloc(header_size)) == 0) |
664 | if ((ptr = (uchar *) malloc(header_size)) == 0) |
| 664 | return RET(COMP_ERR_NOMEM); |
665 | return RET(COMP_ERR_NOMEM); |
| 665 | if (fread(ptr + HEADER_SIZE, 1, header_size - HEADER_SIZE, |
666 | if (fread(ptr + HEADER_SIZE, 1, header_size - HEADER_SIZE, |
| 666 | fd) != (size_t) (header_size - HEADER_SIZE)) { |
667 | fd) != (size_t) (header_size - HEADER_SIZE)) { |
| 667 | free(ptr); |
668 | free(ptr); |
| 668 | return RET(COMP_ERR_NOMEM); |
669 | return RET(COMP_ERR_NOMEM); |
| 669 | } |
670 | } |
| 670 | memcpy(ptr, temp, HEADER_SIZE); |
671 | memcpy(ptr, temp, HEADER_SIZE); |
| 671 | header_size -= 4; |
672 | header_size -= 4; |
| Line 908... | Line 909... | ||
| 908 | } |
909 | } |
| 909 | size = 0; |
910 | size = 0; |
| 910 | tStart = clock(); |
911 | tStart = clock(); |
| 911 | for (i = 0; i < comp_info->n_blk; i++) { |
912 | for (i = 0; i < comp_info->n_blk; i++) { |
| 912 | if (0 != (result = |
913 | if (0 != (result = |
| 913 | comp_init_block(comp_block, comp_info->block_size, rgbBuf))) { |
914 | comp_init_block(comp_block, comp_info->block_size, rgbBuf))) { |
| 914 | printf("Unable to init block: %d\n", result); |
915 | printf("Unable to init block: %d\n", result); |
| 915 | exit(1); |
916 | exit(1); |
| 916 | } |
917 | } |
| 917 | if (0 != (result = comp_read_block(comp_block, comp_info, fp, i))) { |
918 | if (0 != (result = comp_read_block(comp_block, comp_info, fp, i))) { |
| 918 | printf("Unable to read block: %d\n", result); |
919 | printf("Unable to read block: %d\n", result); |
| 919 | exit(1); |
920 | exit(1); |
| 920 | } |
921 | } |
| 921 | size += comp_block->orig.size; |
922 | size += comp_block->orig.size; |
| 922 | if (0 != (result = |
923 | if (0 != (result = |
| 923 | comp_decode_and_check_crc(comp_block, comp_info, |
924 | comp_decode_and_check_crc(comp_block, comp_info, |
| 924 | comp_block->orig.size, CRC_CHECK))) { |
925 | comp_block->orig.size, CRC_CHECK))) { |
| 925 | printf("Unable to decode block: %d\n", result); |
926 | printf("Unable to decode block: %d\n", result); |
| 926 | exit(1); |
927 | exit(1); |
| 927 | } |
928 | } |
| 928 | } |
929 | } |
| 929 | tEnd = clock(); |
930 | tEnd = clock(); |