1 #ifndef WINCE
2
3 #ifndef TBDECODE
4 #define TBDECODE
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #ifndef CLOCKS_PER_SEC
11 #define CLOCKS_PER_SEC CLK_TCK
12 #endif
13
14 /* ---------------------------- Error codes --------------------------- */
15 /* ----------- */
16
17
18 #define COMP_ERR_NONE 0 /* everything is OK */
19 #define COMP_ERR_READ 2 /* input file read error */
20 #define COMP_ERR_NOMEM 5 /* no enough memory */
21 #define COMP_ERR_BROKEN 6 /* damaged compressed data */
22 #define COMP_ERR_PARAM 7 /* incorrect function parameter */
23 #define COMP_ERR_INTERNAL 9 /* everything else is internal error */
24 /* hopefully it should never happen */
25
26 /* Almost all functions listed further return one as its result on of */
27 /* codes given above: if no error occurred then COMP_ERR_NONE (i.e. 0) */
28 /* is returned, otherwise functions return error code plus number of */
29 /* line in "comp.c" where the error was detected multiplied by 256; */
30 /* line number may be used for exact specification of a place where */
31 /* error was detected thus making debugging slightly simpler. */
32 /* */
33 /* Thus, "(code & 0xff)" gives proper error code, and "(code >> 8)" */
34 /* gives number of line where the error was raised. */
35
36
37 /* -------------------------------------------------------------------- */
38 /* */
39 /* Compress/decompress some chess tables */
40 /* */
41 /* Copyright (c) 1991--1998 Andrew Kadatch */
42 /* */
43 /* The Limited-Reference variant of Lempel-Ziv algorithm implemented */
44 /* here was first described in my B.Sc. thesis "Efficient algorithms */
45 /* for image compression", Novosibirsk State University, 1992, and */
46 /* cannot be used in any product distributed in Russia or CIS without */
47 /* written permission from the author. */
48 /* */
49 /* Most of the code listed below is significantly simplified code from */
50 /* the PRS data compression library and therefore it should not be used */
51 /* in any product (software or hardware, commercial or not, and so on) */
52 /* without written permission from the author. */
53 /* */
54 /* -------------------------------------------------------------------- */
55
56
57 /* ---------------------------- Debugging ----------------------------- */
58 /* --------- */
59
60 #ifndef DEBUG
61 #define DEBUG 0
62 #endif
63
64 #if DEBUG
65 #define assert(cond) ((cond) ? (void) 0 : _local_assert (__LINE__))
_local_assert(int lineno)66 static void _local_assert (int lineno)
67 {
68 fprintf (stderr, "assertion at line %u failed\n", lineno);
69 exit (33);
70 }
71 #define debug(x) x
72 #define dprintf(x) printf x
73 #else
74 #if !defined (assert)
75 #define assert(cond) ((void) 0)
76 #endif
77 #define debug(x) ((void) 0)
78 #define dprintf(x) ((void) 0)
79 #endif
80
81 extern "C" { int cbEGTBCompBytes = 0; }
82
83 /* --------------------- Constants, types, etc. ----------------------- */
84 /* ---------------------- */
85
86 #define MIN_BLOCK_BITS 8 /* LOG2 (min size of block to compress) */
87 #define MAX_BLOCK_BITS 16 /* LOG2 (max size of block to compress) */
88
89 /* max. integer we can take LOG2 by table */
90 #define MAX_BITS_HALF ((MAX_BLOCK_BITS + 1) >> 1)
91 #define MAX_BITS (MAX_BITS_HALF * 2)
92
93 /* assume that integer is at least 32 bits wide */
94 #ifndef uint
95 #define uint unsigned
96 #endif
97
98 #ifndef uchar
99 #define uchar unsigned char
100 #endif
101
102 #define HEADER_SIZE 80 /* number of reserved bytes */
103 #define STOP_SEARCH_LENGTH 256 /* terminate search if match */
104 /* length exceeds that value */
105
106 #define MAX_LENGTH_BITS 5
107 #define MAX_LENGTH (1 << MAX_LENGTH_BITS)
108 #define LONG_BITS 1
109 #define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS)
110 #define LONG_QUICK (MAX_LENGTH - LONG_LENGTH)
111
112 #if LONG_LENGTH > (MAX_BLOCK_BITS - LONG_BITS)
113 # undef LONG_LENGTH
114 # define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS)
115 #endif
116
117 #if LONG_LENGTH >= MAX_LENGTH || LONG_LENGTH <= 0
118 #error LONG_LENGTH is out of range
119 #endif
120
121 #if LONG_BITS <= 0
122 #error LONG_BITS must be positive
123 #endif
124
125 #define DELTA (LONG_BITS + LONG_QUICK - 1)
126 #if (MAX_LENGTH - 1) - (LONG_LENGTH - LONG_BITS) != DELTA
127 #error Hmmm
128 #endif
129
130 #define MAX_DISTANCES 24
131
132 #define LOG_MAX_DISTANCES 6 /* see check below */
133
134 #if MAX_DISTANCES > (1 << LOG_MAX_DISTANCES)
135 #error MAX_DISTANCES should not exceed (1 << LOG_MAX_DISTANCES)
136 #endif
137
138 #define ALPHABET_SIZE (256 + (MAX_DISTANCES << MAX_LENGTH_BITS))
139 #define MAX_ALPHABET ALPHABET_SIZE /* max. alphabet handled by */
140 /* Huffman coding routines */
141
142 #define USE_CRC32 1
143 /* 0 - use Fletcher's checksum, != 0 - use proper CRC32 */
144
145 static uchar header_title[64] =
146 "Compressed by DATACOMP v 1.0 (c) 1991--1998 Andrew Kadatch\r\n\0";
147
148 #define RET(n) ((n) + __LINE__ * 256)
149
150
151 /* ------------------------- CRC32 routines --------------------------- */
152 /* -------------- */
153
154 #if USE_CRC32
155
156 static unsigned CRC32_table[256];
157 static int CRC32_initialized = 0;
158
CRC32_init(void)159 static void CRC32_init (void)
160 {
161 int i, j;
162 unsigned k, m = (unsigned) 0xedb88320L;
163 if (CRC32_initialized) return;
164 for (i = 0; i < 256; ++i)
165 {
166 k = i; j = 8;
167 do
168 {
169 if ((k&1) != 0)
170 k >>= 1;
171 else
172 {
173 k >>= 1;
174 k ^= m;
175 };
176 }
177 while (--j);
178 CRC32_table[i] = k;
179 }
180 CRC32_initialized = 1;
181 }
182
CRC32(uchar * p,int n,unsigned k)183 static unsigned CRC32 (uchar *p, int n, unsigned k)
184 {
185 unsigned *table = CRC32_table;
186 uchar *e = p + n;
187 while (p + 16 < e)
188 {
189 # define X(i) k = table[((uchar) k) ^ p[i]] ^ (k >> 8)
190 X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8);
191 X(9); X(10); X(11); X(12); X(13); X(14); X(15);
192 # undef X
193 p += 16;
194 }
195 while (p < e)
196 k = table[((uchar) k) ^ *p++] ^ (k >> 8);
197 return (k);
198 }
199
200 #else
201
202 #define CRC32_init()
203
CRC32(uchar * p,int n,unsigned k1)204 static unsigned CRC32 (uchar *p, int n, unsigned k1)
205 {
206 unsigned k0 = k1 & 0xffff;
207 uchar *e = p + n;
208 k1 = (k1 >> 16) & 0xffff;
209 while (p + 16 < e)
210 {
211 # define X(i) k0 += p[i]; k1 += k0;
212 X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8);
213 X(9); X(10); X(11); X(12); X(13); X(14); X(15);
214 # undef X
215 k0 = (k0 & 0xffff) + (k0 >> 16);
216 k1 = (k1 & 0xffff) + (k1 >> 16);
217 p += 16;
218 }
219 while (p < e)
220 {
221 k0 += *p++;
222 k1 += k0;
223 }
224 k0 = (k0 & 0xffff) + (k0 >> 16);
225 k1 = (k1 & 0xffff) + (k1 >> 16);
226 k0 = (k0 & 0xffff) + (k0 >> 16);
227 k1 = (k1 & 0xffff) + (k1 >> 16);
228 assert (((k0 | k1) >> 16) == 0);
229 return (k0 + (k1 << 16));
230 }
231
232 #endif /* USE_CRC32 */
233
234
235
236 /* ------------------------ Bit IO interface -------------------------- */
237 /* ---------------- */
238
239 #define BITIO_LOCALS \
240 uint _mask; \
241 int _bits; \
242 uchar *_ptr
243
244 typedef struct
245 {
246 BITIO_LOCALS;
247 }
248 bitio_t;
249
250 #define BITIO_ENTER(p) do { \
251 _mask = (p)._mask; \
252 _bits = (p)._bits; \
253 _ptr = (p)._ptr; \
254 } while (0)
255
256 #define BITIO_LEAVE(p) do { \
257 (p)._mask = _mask; \
258 (p)._bits = _bits; \
259 (p)._ptr = _ptr; \
260 } while (0)
261
262 #define BIORD_START(from) do { \
263 _ptr = (uchar *) (from); \
264 _bits = sizeof (_mask); \
265 _mask = 0; \
266 do \
267 _mask = (_mask << 8) | *_ptr++; \
268 while (--_bits != 0); \
269 _bits = 16; \
270 } while (0)
271
272 /* read [1, 17] bits at once */
273 #define BIORD(bits) \
274 (_mask >> (8 * sizeof (_mask) - (bits)))
275
276 #define BIORD_MORE(bits) do { \
277 _mask <<= (bits); \
278 if ((_bits -= (bits)) <= 0) \
279 { \
280 _mask |= ((_ptr[0] << 8) + _ptr[1]) << (-_bits); \
281 _ptr += 2; _bits += 16; \
282 } \
283 } while (0)
284
285 /* ------------------------ Huffman coding ---------------------------- */
286 /* -------------- */
287
288 #if MAX_ALPHABET <= 0xffff
289 # if MAX_ALPHABET <= 1024
290 /* positive value takes 15 bits => symbol number occupies <= 10 bits */
291 # define huffman_decode_t short
292 # else
293 # define huffman_decode_t int
294 # endif
295 #else
296 # define huffman_decode_t int
297 #endif
298
299 #define HUFFMAN_DECODE(ch,table,start_bits) do { \
300 (ch) = table[BIORD (start_bits)]; \
301 if (((int) (ch)) >= 0) \
302 { \
303 BIORD_MORE ((ch) & 31); \
304 (ch) >>= 5; \
305 break; \
306 } \
307 BIORD_MORE (start_bits); \
308 do \
309 { \
310 (ch) = table[BIORD (1) - (ch)]; \
311 BIORD_MORE (1); \
312 } \
313 while (((int) (ch)) < 0); \
314 } while (0)
315
316 #define HUFFMAN_TABLE_SIZE(n,start_bits) \
317 ((1 << (start_bits)) + ((n) << 1))
318
huffman_decode_create(huffman_decode_t * table,uchar * length,int n,int start_bits)319 static int huffman_decode_create
320 (huffman_decode_t *table, uchar *length, int n, int start_bits)
321 {
322 int i, j, k, last, freq[32], sum[32];
323
324 /* calculate number of codewords */
325 memset (freq, 0, sizeof (freq));
326 for (i = 0; i < n; ++i)
327 {
328 if ((k = length[i]) > 31)
329 return RET (COMP_ERR_BROKEN);
330 ++freq[k];
331 }
332
333 /* handle special case(s) -- 0 and 1 symbols in alphabet */
334 if (freq[0] == n)
335 {
336 memset (table, 0, sizeof (table[0]) << start_bits);
337 return (0);
338 }
339 if (freq[0] == n-1)
340 {
341 if (freq[1] != 1)
342 return RET (COMP_ERR_BROKEN);
343 for (i = 0; length[i] == 0;) ++i;
344 i <<= 5;
345 for (k = 1 << start_bits; --k >= 0;)
346 *table++ = (huffman_decode_t) i;
347 return (0);
348 }
349
350 /* save frequences */
351 memcpy (sum, freq, sizeof (sum));
352
353 /* check code correctness */
354 k = 0;
355 for (i = 32; --i != 0;)
356 {
357 if ((k += freq[i]) & 1)
358 return RET (COMP_ERR_BROKEN);
359 k >>= 1;
360 }
361 if (k != 1)
362 return RET (COMP_ERR_BROKEN);
363
364 /* sort symbols */
365 k = 0;
366 for (i = 1; i < 32; ++i)
367 freq[i] = (k += freq[i]);
368 last = freq[31]; /* preserve number of symbols in alphabet */
369 for (i = n; --i >= 0;)
370 {
371 if ((k = length[i]) != 0)
372 table[--freq[k]] = (huffman_decode_t) i;
373 }
374
375 /* now create decoding table */
376 k = i = (1<<start_bits) + (n<<1);
377 for (n = 32; --n > start_bits;)
378 {
379 j = i;
380 while (k > j)
381 table[--i] = (huffman_decode_t) -(k -= 2);
382 for (k = sum[n]; --k >= 0;)
383 table[--i] = table[--last];
384 k = j;
385 }
386
387 j = i;
388 i = 1 << start_bits;
389 while (k > j)
390 table[--i] = (huffman_decode_t) -(k -= 2);
391
392 for (; n > 0; --n)
393 {
394 for (k = sum[n]; --k >= 0;)
395 {
396 assert (last <= i && last > 0);
397 j = i - (1 << (start_bits - n));
398 n |= table[--last] << 5;
399 do
400 table[--i] = (huffman_decode_t) n;
401 while (i != j);
402 n &= 31;
403 }
404 }
405 assert ((i | last) == 0);
406
407 return (0);
408 }
409
410 /* -------------------- Read/write Huffman code ----------------------- */
411 /* ----------------------- */
412
413 #define MIN_REPT 2
414
415 #if MIN_REPT <= 1
416 #error MIN_REPT must exceed 1
417 #endif
418
419 #define TEMP_TABLE_BITS 8
420
huffman_read_length(bitio_t * bitio,uchar * length,int n)421 static int huffman_read_length (bitio_t *bitio, uchar *length, int n)
422 {
423 BITIO_LOCALS;
424 huffman_decode_t table[2][HUFFMAN_TABLE_SIZE (64, TEMP_TABLE_BITS)];
425 uchar bits[128];
426 int i, j, k;
427
428 BITIO_ENTER (*bitio);
429 k = BIORD (1); BIORD_MORE (1);
430 if (k != 0)
431 {
432 memset (length, 0, n);
433 goto ret;
434 }
435
436 if (n <= 128)
437 {
438 k = BIORD (5); BIORD_MORE (5);
439 for (i = 0; i < n;)
440 {
441 length[i] = (uchar) BIORD (k); BIORD_MORE (k);
442 if (length[i++] == 0)
443 {
444 j = i + BIORD (4); BIORD_MORE (4);
445 if (j > n)
446 return RET (COMP_ERR_BROKEN);
447 while (i != j)
448 length[i++] = 0;
449 }
450 }
451 goto ret;
452 }
453
454 BITIO_LEAVE (*bitio);
455 i = huffman_read_length (bitio, bits, 128);
456 if (i != 0)
457 return (i);
458 i = huffman_decode_create (table[0], bits, 64, TEMP_TABLE_BITS);
459 if (i != 0)
460 return (i);
461 i = huffman_decode_create (table[1], bits + 64, 64, TEMP_TABLE_BITS);
462 if (i != 0)
463 return (i);
464 BITIO_ENTER (*bitio);
465
466 for (i = 0; i < n;)
467 {
468 HUFFMAN_DECODE (k, table[0], TEMP_TABLE_BITS);
469 if (k <= 31)
470 {
471 length[i++] = (uchar) k;
472 continue;
473 }
474 k &= 31;
475 HUFFMAN_DECODE (j, table[1], TEMP_TABLE_BITS);
476 if (j > 31)
477 {
478 int jj = j - 32;
479 j = 1 << jj;
480 if (jj != 0)
481 {
482 if (jj > 16)
483 {
484 j += BIORD (16) << (jj - 16); BIORD_MORE (16);
485 }
486 j += BIORD (jj); BIORD_MORE (jj);
487 }
488 j += 31;
489 }
490 j += MIN_REPT + i;
491 if (j > n)
492 return RET (COMP_ERR_BROKEN);
493 do
494 length[i] = (uchar) k;
495 while (++i != j);
496 }
497
498 ret:
499 BITIO_LEAVE (*bitio);
500 return (0);
501 }
502
503 /* ----------------------- Proper compression ------------------------- */
504 /* ------------------ */
505
506 #if MIN_BLOCK_BITS > MAX_BLOCK_BITS || MAX_BLOCK_BITS > MAX_BITS_HALF*2
507 #error condition MIN_BLOCK_BITS <= MAX_BLOCK_BITS <= MAX_BITS_HALF*2 failed
508 #endif
509
510 #define DECODE_MAGIC ((int) 0x5abc947fL)
511 #define BLOCK_MAGIC ((int) 0x79a3f29dL)
512
513 #define START_BITS 13
514
515 typedef struct
516 {
517 huffman_decode_t table[HUFFMAN_TABLE_SIZE (ALPHABET_SIZE, START_BITS)];
518 int distance[MAX_DISTANCES];
519 unsigned *crc, *blk;
520 int
521 block_size_log, /* block_size is integral power of 2 */
522 block_size, /* 1 << block_size_log */
523 last_block_size, /* [original] size of last block */
524 n_blk, /* total number of blocks */
525 comp_block_size, /* size of largest compressed block+32 */
526 check_crc; /* check CRC32? */
527 uchar *comp;
528 int magic;
529 }
530 decode_info;
531
532
533 typedef struct
534 {
535 unsigned char * ptr; /* pointer to the first decoded byte */
536 int decoded; /* number of bytes decoded so far */
537 int total; /* total number of bytes in block */
538 int number; /* number of this block */
539 } COMP_BLOCK_T;
540 /* Pointer to compressed data block */
541
542 typedef struct
543 {
544 COMP_BLOCK_T b;
545 struct
546 {
547 uchar *first;
548 int size;
549 } orig, comp;
550 struct
551 {
552 uchar *ptr, *src;
553 int rept;
554 } emit;
555 bitio_t bitio;
556 int n;
557 int magic;
558 }
559 decode_block;
560
do_decode(decode_info * info,decode_block * block,uchar * e)561 static void do_decode (decode_info *info, decode_block *block, uchar *e)
562 {
563 BITIO_LOCALS;
564 uchar *p, *s=0;
565 int ch;
566
567 if ((p = block->emit.ptr) >= e)
568 return;
569 if (p == block->orig.first)
570 {
571 BIORD_START (block->comp.first);
572 block->emit.rept = 0;
573 }
574 else
575 {
576 BITIO_ENTER (block->bitio);
577 if ((ch = block->emit.rept) != 0)
578 {
579 block->emit.rept = 0;
580 s = block->emit.src;
581 goto copy;
582 }
583 }
584 #define OVER if (p < e) goto over; break
585 do
586 {
587 over:
588 HUFFMAN_DECODE (ch, info->table, START_BITS);
589 if ((ch -= 256) < 0)
590 {
591 *p++ = (uchar) ch;
592 OVER;
593 }
594
595 s = p + info->distance[ch >> MAX_LENGTH_BITS];
596
597 ch &= MAX_LENGTH - 1;
598 if (ch <= 3)
599 {
600 p[0] = s[0]; p[1] = s[1]; p[2] = s[2]; p[3] = s[3]; p += ch+1; OVER;
601 }
602 else if (ch >= LONG_LENGTH)
603 {
604 ch -= LONG_LENGTH - LONG_BITS;
605 #if (MAX_BLOCK_BITS - 1) + (LONG_LENGTH - LONG_BITS) >= MAX_LENGTH
606 if (ch == DELTA)
607 {
608 ch = BIORD (5); BIORD_MORE (5);
609 ch += DELTA;
610 }
611 #endif
612 {
613 int n = 1 << ch;
614 if (ch > 16)
615 {
616 n += BIORD (16) << (ch -= 16); BIORD_MORE (16);
617 }
618 n += BIORD (ch); BIORD_MORE (ch);
619 ch = n;
620 }
621 ch += LONG_LENGTH - (1 << LONG_BITS);
622 }
623 ++ch;
624 copy:
625 if (ch > 16)
626 {
627 if (p + ch > e)
628 {
629 block->emit.rept = ch - (int) (e - p);
630 ch = (int) (e - p);
631 goto copy;
632 }
633 do
634 {
635 # define X(i) p[i] = s[i]
636 X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8);
637 X(9); X(10); X(11); X(12); X(13); X(14); X(15);
638 # undef X
639 p += 16; s += 16;
640 }
641 while ((ch -= 16) > 16);
642 }
643 p += ch; s += ch;
644 switch (ch)
645 {
646 # define X(i) case i: p[-i] = s[-i]
647 X(16); X(15); X(14); X(13); X(12); X(11); X(10);
648 X(9); X(8); X(7); X(6); X(5); X(4); X(3); X(2);
649 # undef X
650 }
651 p[-1] = s[-1];
652 }
653 while (p < e);
654 #undef OVER
655 block->emit.ptr = p;
656 block->emit.src = s;
657 BITIO_LEAVE (block->bitio);
658 }
659
660 /* pretty ugly */
comp_open_file(decode_info ** res,FILE * fd,int check_crc)661 static int comp_open_file (decode_info **res, FILE *fd, int check_crc)
662 {
663 BITIO_LOCALS;
664 bitio_t Bitio;
665 uchar temp[ALPHABET_SIZE >= HEADER_SIZE ? ALPHABET_SIZE : HEADER_SIZE];
666 uchar *ptr;
667 int header_size, block_size, block_size_log, n_blk, i, n;
668 decode_info *info;
669
670 if (res == 0)
671 return RET (COMP_ERR_PARAM);
672
673 CRC32_init ();
674
675 *res = 0;
676
677 if (fread (temp, 1, HEADER_SIZE, fd) != HEADER_SIZE)
678 return RET (COMP_ERR_READ);
679
680 if (memcmp (temp, header_title, 64) != 0)
681 return RET (COMP_ERR_READ);
682
683 ptr = temp;
684 #define R4(i) \
685 ((ptr[i] << 24) + (ptr[(i) + 1] << 16) + (ptr[(i) + 2] << 8) + (ptr[(i) + 3]))
686
687 header_size = R4 (64);
688 block_size_log = ptr[70];
689 if (block_size_log > MAX_BITS || header_size < 84)
690 return RET (COMP_ERR_BROKEN);
691 block_size = 1 << block_size_log;
692 if (ptr[71] != MAX_DISTANCES)
693 return RET (COMP_ERR_BROKEN);
694 n_blk = R4 (72);
695 if (R4 (76) != (ALPHABET_SIZE << 12) + (LONG_BITS << 8) + (LONG_LENGTH << 4) + MAX_LENGTH_BITS)
696 return RET (COMP_ERR_BROKEN);
697 #ifdef WINCE
698 if ((ptr = (uchar*) my_Tcl_Alloc (header_size)) == 0)
699 #else
700 if ((ptr = (uchar*) malloc (header_size)) == 0)
701 #endif
702 return RET (COMP_ERR_NOMEM);
703
704 if (fread (ptr + HEADER_SIZE, 1, header_size - HEADER_SIZE, fd) != (size_t) (header_size - HEADER_SIZE))
705 {
706 #ifdef WINCE
707 my_Tcl_Free ((char*)ptr);
708 #else
709 free (ptr);
710 #endif
711 return RET (COMP_ERR_NOMEM);
712 }
713 memcpy (ptr, temp, HEADER_SIZE);
714 header_size -= 4;
715 if (CRC32 (ptr, header_size, 0) != (unsigned) R4 (header_size))
716 {
717 #ifdef WINCE
718 my_Tcl_Free ((char*)ptr);
719 #else
720 free (ptr);
721 #endif
722 return RET (COMP_ERR_BROKEN);
723 }
724 header_size += 4;
725
726 n = sizeof (info->crc[0]) * (1 + (check_crc ? (3 * n_blk) : n_blk));
727 #ifdef WINCE
728 if ((info = (decode_info *) my_Tcl_Alloc (sizeof (*info) + n)) == 0)
729 #else
730 if ((info = (decode_info *) malloc (sizeof (*info) + n)) == 0)
731 #endif
732 {
733 #ifdef WINCE
734 my_Tcl_Free ((char*)ptr);
735 #else
736 free (ptr);
737 #endif
738 return RET (COMP_ERR_NOMEM);
739 }
740 cbEGTBCompBytes += sizeof (*info) + n;
741 info->blk = info->crc = (unsigned *) (info + 1);
742 if (check_crc) info->blk += 2 * n_blk;
743
744 info->check_crc = check_crc;
745 info->block_size_log = block_size_log;
746 info->block_size = block_size;
747 info->n_blk = n_blk;
748
749 if (check_crc)
750 {
751 n_blk <<= 1; i = HEADER_SIZE;
752 for (n = 0; n < n_blk; ++n)
753 {
754 info->crc[n] = R4 (i);
755 i += 4;
756 }
757 n_blk >>= 1;
758 }
759
760 i = HEADER_SIZE + (n_blk << 3);
761 BIORD_START (ptr + i);
762
763 info->comp_block_size = 0;
764 for (n = 0; n <= n_blk; ++n)
765 {
766 if ((info->blk[n] = BIORD (block_size_log)) == 0)
767 info->blk[n] = block_size;
768 if (info->comp_block_size < (int) (info->blk[n]))
769 info->comp_block_size = (int) (info->blk[n]);
770 BIORD_MORE (block_size_log);
771 }
772 info->comp_block_size += 32;
773
774 for (n = 0; n < MAX_DISTANCES; ++n)
775 {
776 info->distance[n] = - ((int) BIORD (block_size_log));
777 BIORD_MORE (block_size_log);
778 }
779
780 i += ((n_blk + 1 + MAX_DISTANCES) * block_size_log + 7) >> 3;
781 BIORD_START (ptr + i);
782 BITIO_LEAVE (Bitio);
783 if (huffman_read_length (&Bitio, temp, ALPHABET_SIZE) != 0)
784 {
785 #ifdef WINCE
786 my_Tcl_Free ((char*)info);
787 my_Tcl_Free ((char*)ptr);
788 #else
789 free (info);
790 free (ptr);
791 #endif
792 return RET (COMP_ERR_BROKEN);
793 }
794
795 if (huffman_decode_create (info->table, temp, ALPHABET_SIZE, START_BITS) != 0)
796 {
797 #ifdef WINCE
798 my_Tcl_Free ((char*)info);
799 my_Tcl_Free ((char*)ptr);
800 #else
801 free (info);
802 free (ptr);
803 #endif
804 return RET (COMP_ERR_BROKEN);
805 }
806
807 info->last_block_size = info->blk[n_blk];
808 info->blk[n_blk] = 0;
809 for (n = 0; n <= n_blk; ++n)
810 {
811 i = info->blk[n];
812 info->blk[n] = header_size;
813 header_size += i;
814 }
815
816 #ifdef WINCE
817 my_Tcl_Free ((char*)ptr);
818 #else
819 free (ptr);
820 #endif
821 info->comp = 0;
822 info->magic = DECODE_MAGIC;
823 *res = info;
824
825 return (COMP_ERR_NONE);
826 }
827
828 // static int comp_tell_blocks (decode_info *info)
829 // {
830 // if (info == 0 || info->magic != DECODE_MAGIC)
831 // return (-1);
832 // return (info->n_blk);
833 // }
834
comp_init_block(decode_block * block,int block_size,uchar * orig)835 static int comp_init_block (decode_block *block, int block_size, uchar *orig)
836 {
837 if (block == 0)
838 return RET (COMP_ERR_PARAM);
839 block->orig.first = orig;
840 block->comp.first = (uchar *) (block + 1);
841 block->b.ptr = 0;
842 block->b.decoded = -1;
843 block->b.total = -1;
844 block->b.number = -1;
845 block->n = -1;
846 block->magic = BLOCK_MAGIC;
847 return (COMP_ERR_NONE);
848 }
849
comp_alloc_block(decode_block ** ret_block,int block_size)850 static int comp_alloc_block (decode_block **ret_block, int block_size)
851 {
852 decode_block *block;
853
854 if (ret_block == 0)
855 return RET (COMP_ERR_PARAM);
856 *ret_block = 0;
857 #ifdef WINCE
858 if ((block = (decode_block *) my_Tcl_Alloc (sizeof (*block) + block_size)) == 0)
859 #else
860 if ((block = (decode_block *) malloc (sizeof (*block) + block_size)) == 0)
861 #endif
862 return RET (COMP_ERR_NOMEM);
863 cbEGTBCompBytes += sizeof (*block) + block_size;
864 if (0 != comp_init_block (block, block_size, NULL))
865 return RET (COMP_ERR_PARAM);
866 *ret_block = block;
867 return (COMP_ERR_NONE);
868 }
869
870 #define RETURN(n) \
871 return ((n) == COMP_ERR_NONE ? COMP_ERR_NONE : RET (n));
872
comp_read_block(decode_block * block,decode_info * info,FILE * fd,int n)873 static int comp_read_block (decode_block *block, decode_info *info, FILE *fd, int n)
874 {
875 int comp_size, orig_size;
876 uchar *comp, *orig;
877
878 if (block == 0 || block->magic != BLOCK_MAGIC)
879 return RET (COMP_ERR_PARAM);
880 assert (info->magic == DECODE_MAGIC);
881 if ((unsigned) n >= (unsigned) info->n_blk)
882 RETURN (COMP_ERR_PARAM);
883 comp = block->comp.first;
884 block->n = n;
885 orig = block->orig.first;
886 orig_size = info->block_size;
887 if (n == info->n_blk-1) orig_size = info->last_block_size;
888 block->orig.size = orig_size;
889 block->comp.size = comp_size = info->blk[n+1] - info->blk[n];
890 if (fseek (fd, info->blk[n], SEEK_SET) != 0)
891 RETURN (COMP_ERR_READ);
892 if (fread (comp, 1, comp_size, fd) != (size_t) comp_size)
893 RETURN (COMP_ERR_READ);
894 if (info->check_crc && info->crc[(n << 1) + 1] != CRC32 (block->comp.first, comp_size, 0))
895 RETURN (COMP_ERR_BROKEN);
896 block->emit.rept = 0;
897 if (comp_size == orig_size)
898 {
899 memcpy (orig, comp, comp_size);
900 block->emit.ptr = orig + comp_size;
901 block->b.decoded = comp_size;
902 }
903 else
904 {
905 block->emit.ptr = orig;
906 block->b.decoded = 0;
907 }
908 block->b.number = n;
909 block->b.ptr = orig;
910 block->b.total = orig_size;
911
912 RETURN (COMP_ERR_NONE);
913 }
914
comp_decode_and_check_crc(decode_block * block,decode_info * info,int n,int check_crc)915 static int comp_decode_and_check_crc (decode_block *block, decode_info *info, int n, int check_crc)
916 {
917 if (block == 0 || block->magic != BLOCK_MAGIC)
918 return RET (COMP_ERR_PARAM);
919 assert (info->magic == DECODE_MAGIC);
920 if ((unsigned) (n - 1) > (unsigned) (block->orig.size - 1))
921 RETURN (COMP_ERR_PARAM);
922 if (check_crc) n = block->orig.size;
923 do_decode (info, block, block->orig.first + n);
924 block->b.ptr = block->orig.first;
925 block->b.total = block->orig.size;
926 if (block->b.decoded >= block->b.total)
927 {
928 if (block->b.decoded > block->b.total)
929 RETURN (COMP_ERR_BROKEN);
930 if (block->emit.rept != 0)
931 RETURN (COMP_ERR_BROKEN);
932 }
933 if (check_crc && info->check_crc
934 && info->crc[block->n << 1] != CRC32 (block->orig.first, block->orig.size, 0))
935 RETURN (COMP_ERR_BROKEN);
936
937 RETURN (COMP_ERR_NONE);
938 }
939
940 #if !defined (COLOR_DECLARED)
941
942 /*
943 Test driver
944 */
945
946 #define CRC_CHECK 1
947
main(int argc,char * argv[])948 int main (int argc, char *argv[])
949 {
950 int i;
951 int size;
952 int result;
953 FILE *fp;
954 decode_info *comp_info;
955 decode_block *comp_block;
956 clock_t tStart, tEnd;
957 double dSeconds;
958 uchar rgbBuf [8192+32];
959
960 if (2 != argc)
961 {
962 printf ("Invalid arguments\n");
963 exit (1);
964 }
965 fp = fopen (argv[1], "rb");
966 if (0 == fp)
967 {
968 printf ("Unable to open file\n");
969 exit (1);
970 }
971 result = comp_open_file (&comp_info, fp, CRC_CHECK);
972 if (0 != result)
973 {
974 printf ("Unable to read file (1): %d\n", result);
975 exit (1);
976 }
977 if (8192 != comp_info->block_size)
978 {
979 printf ("Invalid block size: %d\n", comp_info->block_size);
980 exit (1);
981 }
982 result = comp_alloc_block (&comp_block, comp_info->block_size);
983 if (0 != result)
984 {
985 printf ("Unable to allocate block: %d\n", result);
986 exit (1);
987 }
988
989 size = 0;
990 tStart = clock ();
991 for (i = 0; i < comp_info->n_blk; i ++)
992 {
993 if (0 != (result = comp_init_block (comp_block, comp_info->block_size, rgbBuf)))
994 {
995 printf ("Unable to init block: %d\n", result);
996 exit (1);
997 }
998 if (0 != (result = comp_read_block (comp_block, comp_info, fp, i)))
999 {
1000 printf ("Unable to read block: %d\n", result);
1001 exit (1);
1002 }
1003 size += comp_block->orig.size;
1004 if (0 != (result = comp_decode_and_check_crc (comp_block, comp_info, comp_block->orig.size, CRC_CHECK)))
1005 {
1006 printf ("Unable to decode block: %d\n", result);
1007 exit (1);
1008 }
1009 }
1010 tEnd = clock ();
1011 dSeconds = (double) (tEnd - tStart) / CLOCKS_PER_SEC;
1012 printf ("Total memory allocated: %dKb\n", (cbEGTBCompBytes+1023)/1024);
1013 printf ("%g seconds, %dMb, %gMb/sec)\n", dSeconds, size/(1024*1024), size/(1024*1024) / dSeconds);
1014 return 0;
1015 }
1016
1017 #endif
1018 #endif
1019
1020 #endif // WINCE
1021