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