- #ifndef TBDECODE 
- /* *INDENT-OFF* */ 
- #  define       TBDECODE 
- #  include <stdio.h> 
- #  include <stdlib.h> 
- #  include <string.h> 
- #  include <time.h> 
- #  ifndef CLOCKS_PER_SEC 
- #    define CLOCKS_PER_SEC CLK_TCK 
- #  endif 
- /* ---------------------------- Error codes --------------------------- */ 
- /*                              -----------                             */ 
- #  define COMP_ERR_NONE     0   /* everything is OK                     */ 
- #  define COMP_ERR_READ     2   /* input file read error                */ 
- #  define COMP_ERR_NOMEM    5   /* no enough memory                     */ 
- #  define COMP_ERR_BROKEN   6   /* damaged compressed data              */ 
- #  define COMP_ERR_PARAM    7   /* incorrect function parameter         */ 
- #  define COMP_ERR_INTERNAL 9   /* everything else is internal error    */ 
-                                 /* hopefully it should never happen     */ 
- /* Almost all  functions listed further return one as  its result on of */ 
- /* codes given  above: if no  error occured then COMP_ERR_NONE (i.e. 0) */ 
- /* is returned, otherwise functions return  error  code  plus number of */ 
- /* line in "comp.c"  where the error  was detected multiplied  by  256; */ 
- /* line number may  be  used for exact specification  of  a place where */ 
- /* error was detected thus making debugging slightly simpler.           */ 
- /*                                                                      */ 
- /* Thus, "(code &  0xff)"  gives proper error code,  and  "(code >> 8)" */ 
- /* gives number of line where the error was raised.                     */ 
- /* -------------------------------------------------------------------- */ 
- /*                                                                      */ 
- /*                Compress/decompress some chess tables                 */ 
- /*                                                                      */ 
- /*               Copyright (c) 1991--1998 Andrew Kadatch                */ 
- /*                                                                      */ 
- /* The Limited-Reference  variant  of  Lempel-Ziv algorithm implemented */ 
- /* here was first described in  my  B.Sc.  thesis "Efficient algorithms */ 
- /* for image  compression",  Novosibirsk  State  University,  1992, and */ 
- /* cannot be  used in any product distributed in  Russia or CIS without */ 
- /* written permission from the author.                                  */ 
- /*                                                                      */ 
- /* Most of the code listed below is significantly  simplified code from */ 
- /* the PRS data compression library and therefore it should not be used */ 
- /* in any product (software or hardware, commercial or not, and  so on) */ 
- /* without written permission from the author.                          */ 
- /*                                                                      */ 
- /* -------------------------------------------------------------------- */ 
- /* ---------------------------- Debugging ----------------------------- */ 
- /*                              ---------                               */ 
- #  ifndef DEBUG 
- #    define DEBUG       0 
- #  endif 
- #  if DEBUG 
- #    define assert(cond) ((cond) ? (void) 0 : _local_assert (__LINE__)) 
- static void _local_assert(int lineno) 
- { 
-   fprintf(stderr, "assertion at line %u failed\n", lineno); 
-   exit(33); 
- } 
-   
- #    define debug(x) x 
- #    define dprintf(x) printf x 
- #  else 
- #    if !defined (assert) 
- #      define assert(cond) ((void) 0) 
- #    endif 
- #    define debug(x)     ((void) 0) 
- #    define dprintf(x)   ((void) 0) 
- #  endif 
- /* mob_pach */ 
- #  ifndef  __cplusplus 
- int cbEGTBCompBytes = 0; 
- #  else 
- extern "C" { 
-   int cbEGTBCompBytes = 0; 
- } 
- #  endif 
- /* --------------------- Constants, types, etc. ----------------------- */ 
- /*                       ----------------------                         */ 
- #  define MIN_BLOCK_BITS        8 
- /* LOG2 (min size of block to compress) */ 
- #  define MAX_BLOCK_BITS        16 
- /* LOG2 (max size of block to compress) */ 
- /* max. integer we can take LOG2 by table       */ 
- #  define MAX_BITS_HALF ((MAX_BLOCK_BITS + 1) >> 1) 
- #  define MAX_BITS      (MAX_BITS_HALF * 2) 
- /* assume that integer is at least 32 bits wide */ 
- #  ifndef uint 
- #    define uint unsigned 
- #  endif 
- #  ifndef uchar 
- #    define uchar unsigned char 
- #  endif 
- #  define HEADER_SIZE           80      /* number of reserved bytes     */ 
- #  define STOP_SEARCH_LENGTH    256     /* terminate search if match    */ 
-                                         /* length exceeds that value    */ 
- #  define MAX_LENGTH_BITS               5 
- #  define MAX_LENGTH              (1 << MAX_LENGTH_BITS) 
- #  define LONG_BITS               1 
- #  define LONG_LENGTH           (MAX_BLOCK_BITS - LONG_BITS) 
- #  define LONG_QUICK            (MAX_LENGTH - LONG_LENGTH) 
- #  if LONG_LENGTH > (MAX_BLOCK_BITS - LONG_BITS) 
- #    undef LONG_LENGTH 
- #    define LONG_LENGTH         (MAX_BLOCK_BITS - LONG_BITS) 
- #  endif 
- #  if LONG_LENGTH >= MAX_LENGTH || LONG_LENGTH <= 0 
- #    error LONG_LENGTH is out of range 
- #  endif 
- #  if LONG_BITS <= 0 
- #    error LONG_BITS must be positive 
- #  endif 
- #  define DELTA (LONG_BITS + LONG_QUICK - 1) 
- #  if (MAX_LENGTH - 1) - (LONG_LENGTH - LONG_BITS) != DELTA 
- #    error Hmmm 
- #  endif 
- #  define MAX_DISTANCES         24 
- #  define LOG_MAX_DISTANCES     6       /* see check below      */ 
- #  if MAX_DISTANCES > (1 << LOG_MAX_DISTANCES) 
- #    error MAX_DISTANCES should not exceed (1 << LOG_MAX_DISTANCES) 
- #  endif 
- #  define ALPHABET_SIZE         (256 + (MAX_DISTANCES << MAX_LENGTH_BITS)) 
- #  define MAX_ALPHABET  ALPHABET_SIZE   /* max. alphabet handled by     */ 
-                                         /* Huffman coding routines      */ 
- #  define USE_CRC32             1 
- /* 0 - use Fletcher's checksum, != 0 - use proper CRC32                 */ 
-     static uchar header_title[64] = 
-     "Compressed by DATACOMP v 1.0 (c) 1991--1998 Andrew Kadatch\r\n\0"; 
-   
- #  define RET(n) ((n) + __LINE__ * 256) 
- /* ------------------------- CRC32 routines --------------------------- */ 
- /*                           --------------                             */ 
- #  if USE_CRC32 
- static unsigned CRC32_table[256]; 
- static int CRC32_initialized = 0; 
- static void CRC32_init(void) 
- { 
-   int i, j; 
-   unsigned k, m = (unsigned) 0xedb88320L; 
-   
-   if (CRC32_initialized) 
-     return; 
-   for (i = 0; i < 256; ++i) { 
-     k = i; 
-     j = 8; 
-     do { 
-       if ((k & 1) != 0) 
-         k >>= 1; 
-       else { 
-         k >>= 1; 
-         k ^= m; 
-       }; 
-     } while (--j); 
-     CRC32_table[i] = k; 
-   } 
-   CRC32_initialized = 1; 
- } 
- static unsigned CRC32(uchar * p, int n, unsigned k) 
- { 
-   unsigned *table = CRC32_table; 
-   uchar *e = p + n; 
-   
-   while (p + 16 < e) { 
- #    define X(i) k = table[((uchar) k) ^ p[i]] ^ (k >> 8) 
-     X(0); 
-     X(1); 
-     X(2); 
-     X(3); 
-     X(4); 
-     X(5); 
-     X(6); 
-     X(7); 
-     X(8); 
-     X(9); 
-     X(10); 
-     X(11); 
-     X(12); 
-     X(13); 
-     X(14); 
-     X(15); 
- #    undef X 
-     p += 16; 
-   } 
-   while (p < e) 
-     k = table[((uchar) k) ^ *p++] ^ (k >> 8); 
-   return (k); 
- } 
- #  else 
- #    define CRC32_init() 
- static unsigned CRC32(uchar * p, int n, unsigned k1) 
- { 
-   unsigned k0 = k1 & 0xffff; 
-   uchar *e = p + n; 
-   
-   k1 = (k1 >> 16) & 0xffff; 
-   while (p + 16 < e) { 
- #    define X(i) k0 += p[i]; k1 += k0; 
-     X(0); 
-     X(1); 
-     X(2); 
-     X(3); 
-     X(4); 
-     X(5); 
-     X(6); 
-     X(7); 
-     X(8); 
-     X(9); 
-     X(10); 
-     X(11); 
-     X(12); 
-     X(13); 
-     X(14); 
-     X(15); 
- #    undef X 
-     k0 = (k0 & 0xffff) + (k0 >> 16); 
-     k1 = (k1 & 0xffff) + (k1 >> 16); 
-     p += 16; 
-   } 
-   while (p < e) { 
-     k0 += *p++; 
-     k1 += k0; 
-   } 
-   k0 = (k0 & 0xffff) + (k0 >> 16); 
-   k1 = (k1 & 0xffff) + (k1 >> 16); 
-   k0 = (k0 & 0xffff) + (k0 >> 16); 
-   k1 = (k1 & 0xffff) + (k1 >> 16); 
-   assert(((k0 | k1) >> 16) == 0); 
-   return (k0 + (k1 << 16)); 
- } 
- #  endif                        /* USE_CRC32    */ 
- /* ------------------------ Bit IO interface -------------------------- */ 
- /*                          ----------------                            */ 
- #  define BITIO_LOCALS  \ 
-   uint   _mask;         \ 
-   int    _bits;         \ 
-   uchar *_ptr 
- typedef struct { 
-   BITIO_LOCALS; 
- } bitio_t; 
-   
- #  define BITIO_ENTER(p) do {     \ 
-   _mask = (p)._mask;            \ 
-   _bits = (p)._bits;            \ 
-   _ptr  = (p)._ptr;             \ 
- } while (0) 
- #  define BITIO_LEAVE(p) do {     \ 
-   (p)._mask = _mask;            \ 
-   (p)._bits = _bits;            \ 
-   (p)._ptr  = _ptr;             \ 
- } while (0) 
- #  define BIORD_START(from) do {                \ 
-   _ptr = (uchar *) (from);              \ 
-   _bits = sizeof (_mask);               \ 
-   _mask = 0;                            \ 
-   do                                    \ 
-     _mask = (_mask << 8) | *_ptr++;     \ 
-   while (--_bits != 0);                 \ 
-   _bits = 16;                           \ 
- } while (0) 
- /* read [1, 17] bits at once */ 
- #  define BIORD(bits)      \ 
-   (_mask >> (8 * sizeof (_mask) - (bits))) 
- #  define BIORD_MORE(bits) do {         \ 
-   _mask <<= (bits);                     \ 
-   if ((_bits -= (bits)) <= 0)           \ 
-   {                                     \ 
-     _mask |= ((_ptr[0] << 8) + _ptr[1]) << (-_bits);    \ 
-     _ptr += 2; _bits += 16;             \ 
-   }                                     \ 
- } while (0) 
- /* ------------------------ Huffman coding ---------------------------- */ 
- /*                          --------------                              */ 
- #  if MAX_ALPHABET <= 0xffff 
- #    if MAX_ALPHABET <= 1024 
- /* positive value takes 15 bits => symbol number occupies <= 10 bits    */ 
- #      define huffman_decode_t  short 
- #    else 
- #      define huffman_decode_t  int 
- #    endif 
- #  else 
- #    define huffman_decode_t    int 
- #  endif 
- #  define HUFFMAN_DECODE(ch,table,start_bits) do {      \ 
-   (ch) = table[BIORD (start_bits)];                     \ 
-   if (((int) (ch)) >= 0)                                \ 
-   {                                                     \ 
-     BIORD_MORE ((ch) & 31);                             \ 
-     (ch) >>= 5;                                         \ 
-     break;                                              \ 
-   }                                                     \ 
-   BIORD_MORE (start_bits);                              \ 
-   do                                                    \ 
-   {                                                     \ 
-     (ch) = table[BIORD (1) - (ch)];                     \ 
-     BIORD_MORE (1);                                     \ 
-   }                                                     \ 
-   while (((int) (ch)) < 0);                             \ 
- } while (0) 
- #  define HUFFMAN_TABLE_SIZE(n,start_bits) \ 
-   ((1 << (start_bits)) + ((n) << 1)) 
- static int huffman_decode_create(huffman_decode_t * table, uchar * length, 
-     int n, int start_bits) 
- { 
-   int i, j, k, last, freq[32], sum[32]; 
-   
- /* calculate number of codewords                                      */ 
-   memset(freq, 0, sizeof(freq)); 
-   for (i = 0; i < n; ++i) { 
-     if ((k = length[i]) > 31) 
-       return RET(COMP_ERR_BROKEN); 
-     ++freq[k]; 
-   } 
- /* handle special case(s) -- 0 and 1 symbols in alphabet              */ 
-   if (freq[0] == n) { 
-     memset(table, 0, sizeof(table[0]) << start_bits); 
-     return (0); 
-   } 
-   if (freq[0] == n - 1) { 
-     if (freq[1] != 1) 
-       return RET(COMP_ERR_BROKEN); 
-     for (i = 0; length[i] == 0;) 
-       ++i; 
-     i <<= 5; 
-     for (k = 1 << start_bits; --k >= 0;) 
-       *table++ = (huffman_decode_t) i; 
-     return (0); 
-   } 
- /* save frequences                    */ 
-   memcpy(sum, freq, sizeof(sum)); 
- /* check code correctness             */ 
-   k = 0; 
-   for (i = 32; --i != 0;) { 
-     if ((k += freq[i]) & 1) 
-       return RET(COMP_ERR_BROKEN); 
-     k >>= 1; 
-   } 
-   if (k != 1) 
-     return RET(COMP_ERR_BROKEN); 
- /* sort symbols               */ 
-   k = 0; 
-   for (i = 1; i < 32; ++i) 
-     freq[i] = (k += freq[i]); 
-   last = freq[31];      /* preserve number of symbols in alphabet       */ 
-   for (i = n; --i >= 0;) { 
-     if ((k = length[i]) != 0) 
-       table[--freq[k]] = (huffman_decode_t) i; 
-   } 
- /* now create decoding table  */ 
-   k = i = (1 << start_bits) + (n << 1); 
-   for (n = 32; --n > start_bits;) { 
-     j = i; 
-     while (k > j) 
-       table[--i] = (huffman_decode_t) - (k -= 2); 
-     for (k = sum[n]; --k >= 0;) 
-       table[--i] = table[--last]; 
-     k = j; 
-   } 
-   j = i; 
-   i = 1 << start_bits; 
-   while (k > j) 
-     table[--i] = (huffman_decode_t) - (k -= 2); 
-   for (; n > 0; --n) { 
-     for (k = sum[n]; --k >= 0;) { 
-       assert(last <= i && last > 0); 
-       j = i - (1 << (start_bits - n)); 
-       n |= table[--last] << 5; 
-       do 
-         table[--i] = (huffman_decode_t) n; 
-       while (i != j); 
-       n &= 31; 
-     } 
-   } 
-   assert((i | last) == 0); 
-   return (0); 
- } 
-   
- /* -------------------- Read/write Huffman code ----------------------- */ 
- /*                      -----------------------                         */ 
- #  define MIN_REPT      2 
- #  if MIN_REPT <= 1 
- #    error MIN_REPT must exceed 1 
- #  endif 
- #  define TEMP_TABLE_BITS 8 
- static int huffman_read_length(bitio_t * bitio, uchar * length, int n) 
- { 
-   BITIO_LOCALS; 
-   huffman_decode_t table[2][HUFFMAN_TABLE_SIZE(64, TEMP_TABLE_BITS)]; 
-   uchar bits[128]; 
-   int i, j, k; 
-   
-   BITIO_ENTER(*bitio); 
-   k = BIORD(1); 
-   BIORD_MORE(1); 
-   if (k != 0) { 
-     memset(length, 0, n); 
-     goto ret; 
-   } 
-   if (n <= 128) { 
-     k = BIORD(5); 
-     BIORD_MORE(5); 
-     for (i = 0; i < n;) { 
-       length[i] = (uchar) BIORD(k); 
-       BIORD_MORE(k); 
-       if (length[i++] == 0) { 
-         j = i + BIORD(4); 
-         BIORD_MORE(4); 
-         if (j > n) 
-           return RET(COMP_ERR_BROKEN); 
-         while (i != j) 
-           length[i++] = 0; 
-       } 
-     } 
-     goto ret; 
-   } 
-   BITIO_LEAVE(*bitio); 
-   i = huffman_read_length(bitio, bits, 128); 
-   if (i != 0) 
-     return (i); 
-   i = huffman_decode_create(table[0], bits, 64, TEMP_TABLE_BITS); 
-   if (i != 0) 
-     return (i); 
-   i = huffman_decode_create(table[1], bits + 64, 64, TEMP_TABLE_BITS); 
-   if (i != 0) 
-     return (i); 
-   BITIO_ENTER(*bitio); 
-   for (i = 0; i < n;) { 
-     HUFFMAN_DECODE(k, table[0], TEMP_TABLE_BITS); 
-     if (k <= 31) { 
-       length[i++] = (uchar) k; 
-       continue; 
-     } 
-     k &= 31; 
-     HUFFMAN_DECODE(j, table[1], TEMP_TABLE_BITS); 
-     if (j > 31) { 
-       int jj = j - 32; 
-   
-       j = 1 << jj; 
-       if (jj != 0) { 
-         if (jj > 16) { 
-           j += BIORD(16) << (jj - 16); 
-           BIORD_MORE(16); 
-         } 
-         j += BIORD(jj); 
-         BIORD_MORE(jj); 
-       } 
-       j += 31; 
-     } 
-     j += MIN_REPT + i; 
-     if (j > n) 
-       return RET(COMP_ERR_BROKEN); 
-     do 
-       length[i] = (uchar) k; 
-     while (++i != j); 
-   } 
- ret: 
-   BITIO_LEAVE(*bitio); 
-   return (0); 
- } 
-   
- /* ----------------------- Proper compression ------------------------- */ 
- /*                         ------------------                           */ 
- #  if MIN_BLOCK_BITS > MAX_BLOCK_BITS || MAX_BLOCK_BITS > MAX_BITS_HALF*2 
- #    error condition MIN_BLOCK_BITS <= MAX_BLOCK_BITS <= MAX_BITS_HALF*2 failed 
- #  endif 
- #  define DECODE_MAGIC    ((int) 0x5abc947fL) 
- #  define BLOCK_MAGIC     ((int) 0x79a3f29dL) 
- #  define START_BITS      13 
- #  define SHORT_INDEX     8u 
- typedef struct { 
-   huffman_decode_t table[HUFFMAN_TABLE_SIZE(ALPHABET_SIZE, START_BITS)]; 
-   int distance[MAX_DISTANCES]; 
-   unsigned *crc, *blk_u; 
-   unsigned short *blk_s; 
-   int block_size_log,           /* block_size is integral power of 2    */ 
-    block_size,                  /* 1 << block_size_log                  */ 
-    last_block_size,             /* [original] size of last block        */ 
-    n_blk,                       /* total number of blocks               */ 
-    comp_block_size,             /* size of largest compressed block+32  */ 
-    check_crc;                   /* check CRC32?                         */ 
-   uchar *comp; 
-   int magic; 
- } decode_info; 
- typedef struct { 
-   unsigned char *ptr;           /* pointer to the first decoded byte */ 
-   int decoded;                  /* number of bytes decoded so far    */ 
-   int total;                    /* total number of bytes in block    */ 
-   int number;                   /* number of this block              */ 
- } COMP_BLOCK_T; 
-   
- /* Pointer to compressed data block                                     */ 
- typedef struct { 
-   COMP_BLOCK_T b; 
-   struct { 
-     uchar *first; 
-     int size; 
-   } orig, comp; 
-   struct { 
-     uchar *ptr, *src; 
-     int rept; 
-   } emit; 
-   bitio_t bitio; 
-   int n; 
-   int magic; 
- } decode_block; 
- static int calculate_offset(decode_info * info, unsigned n) 
- { 
-   unsigned i; 
-   
-   i = n / (2 * SHORT_INDEX); 
-   if (n & SHORT_INDEX) 
-     return info->blk_u[i + 1] - info->blk_s[n]; 
-   else 
-     return info->blk_u[i] + info->blk_s[n]; 
- } 
- static void do_decode(decode_info * info, decode_block * block, uchar * e) 
- { 
-   BITIO_LOCALS; 
-   uchar *p, *s = 0; 
-   int ch; 
-   
-   if ((p = block->emit.ptr) >= e) 
-     return; 
-   if (p == block->orig.first) { 
-     BIORD_START(block->comp.first); 
-     block->emit.rept = 0; 
-   } else { 
-     BITIO_ENTER(block->bitio); 
-     if ((ch = block->emit.rept) != 0) { 
-       block->emit.rept = 0; 
-       s = block->emit.src; 
-       goto copy; 
-     } 
-   } 
- #  define OVER if (p < e) goto over; break 
-   do { 
-   over: 
-     HUFFMAN_DECODE(ch, info->table, START_BITS); 
-     if ((ch -= 256) < 0) { 
-       *p++ = (uchar) ch; 
-       OVER; 
-     } 
-     s = p + info->distance[ch >> MAX_LENGTH_BITS]; 
-     ch &= MAX_LENGTH - 1; 
-     if (ch <= 3) { 
-       p[0] = s[0]; 
-       p[1] = s[1]; 
-       p[2] = s[2]; 
-       p[3] = s[3]; 
-       p += ch + 1; 
-       OVER; 
-     } else if (ch >= LONG_LENGTH) { 
-       ch -= LONG_LENGTH - LONG_BITS; 
- #  if (MAX_BLOCK_BITS - 1) + (LONG_LENGTH - LONG_BITS) >= MAX_LENGTH 
-       if (ch == DELTA) { 
-         ch = BIORD(5); 
-         BIORD_MORE(5); 
-         ch += DELTA; 
-       } 
- #  endif 
-       { 
-         int n = 1 << ch; 
-   
-         if (ch > 16) { 
-           n += BIORD(16) << (ch -= 16); 
-           BIORD_MORE(16); 
-         } 
-         n += BIORD(ch); 
-         BIORD_MORE(ch); 
-         ch = n; 
-       } 
-       ch += LONG_LENGTH - (1 << LONG_BITS); 
-     } 
-     ++ch; 
-   copy: 
-     if (ch > 16) { 
-       if (p + ch > e) { 
-         block->emit.rept = ch - (int) (e - p); 
-         ch = (int) (e - p); 
-         goto copy; 
-       } 
-       do { 
- #  define X(i) p[i] = s[i] 
-         X(0); 
-         X(1); 
-         X(2); 
-         X(3); 
-         X(4); 
-         X(5); 
-         X(6); 
-         X(7); 
-         X(8); 
-         X(9); 
-         X(10); 
-         X(11); 
-         X(12); 
-         X(13); 
-         X(14); 
-         X(15); 
- #  undef X 
-         p += 16; 
-         s += 16; 
-       } while ((ch -= 16) > 16); 
-     } 
-     p += ch; 
-     s += ch; 
-     switch (ch) { 
- #  define X(i) case i: p[-i] = s[-i] 
-       X(16); 
-       X(15); 
-       X(14); 
-       X(13); 
-       X(12); 
-       X(11); 
-       X(10); 
-       X(9); 
-       X(8); 
-       X(7); 
-       X(6); 
-       X(5); 
-       X(4); 
-       X(3); 
-       X(2); 
- #  undef X 
-     } 
-     p[-1] = s[-1]; 
-   } while (p < e); 
- #  undef OVER 
-   block->emit.ptr = p; 
-   block->emit.src = s; 
-   BITIO_LEAVE(block->bitio); 
- } 
-   
- /* pretty ugly */ 
- static int comp_open_file(decode_info ** res, FILE * fd, int check_crc) 
- { 
-   BITIO_LOCALS; 
-   bitio_t Bitio; 
-   uchar temp[ALPHABET_SIZE >= HEADER_SIZE ? ALPHABET_SIZE : HEADER_SIZE]; 
-   uchar *ptr; 
-   int header_size, block_size, block_size_log, n_blk, i, n, n_s, n_u; 
-   unsigned *blk_u, *blk; 
-   unsigned short *blk_s; 
-   decode_info *info; 
-   
-   if (res == 0) 
-     return RET(COMP_ERR_PARAM); 
-   CRC32_init(); 
-   *res = 0; 
-   if (fread(temp, 1, HEADER_SIZE, fd) != HEADER_SIZE) 
-     return RET(COMP_ERR_READ); 
-   if (memcmp(temp, header_title, 64) != 0) 
-     return RET(COMP_ERR_READ); 
-   ptr = temp; 
- #  define R4(i) \ 
-   ((ptr[i] << 24) + (ptr[(i) + 1] << 16) + (ptr[(i) + 2] << 8) + (ptr[(i) + 3])) 
-   header_size = R4(64); 
-   block_size_log = ptr[70]; 
-   if (block_size_log > MAX_BITS || header_size < 84) 
-     return RET(COMP_ERR_BROKEN); 
-   block_size = 1 << block_size_log; 
-   if (ptr[71] != MAX_DISTANCES) 
-     return RET(COMP_ERR_BROKEN); 
-   n_blk = R4(72); 
-   if (R4(76) != 
-       (ALPHABET_SIZE << 12) + (LONG_BITS << 8) + (LONG_LENGTH << 4) + 
-       MAX_LENGTH_BITS) 
-     return RET(COMP_ERR_BROKEN); 
-   if ((ptr = (uchar *) malloc(header_size)) == 0) 
-     return RET(COMP_ERR_NOMEM); 
-   if (fread(ptr + HEADER_SIZE, 1, header_size - HEADER_SIZE, 
-           fd) != (size_t) (header_size - HEADER_SIZE)) { 
-     free(ptr); 
-     return RET(COMP_ERR_NOMEM); 
-   } 
-   memcpy(ptr, temp, HEADER_SIZE); 
-   header_size -= 4; 
-   if (CRC32(ptr, header_size, 0) != (unsigned) R4(header_size)) { 
-     free(ptr); 
-     return RET(COMP_ERR_BROKEN); 
-   } 
-   header_size += 4; 
- /* 
-    blk = (unsigned *) malloc (sizeof (unsigned) * (1 + n_blk)); 
-  */ 
-   n = sizeof(unsigned) * (1 + n_blk); 
-   if (n < 4 * 1024 * 1024) 
-     n = 4 * 1024 * 1024; 
-   blk = (unsigned *) malloc(n); 
-   if (blk == 0) { 
-     free(ptr); 
-     return RET(COMP_ERR_NOMEM); 
-   } 
-   n = sizeof(info->crc[0]) * (1 + (check_crc ? (2 * n_blk) : 0)); 
-   n_u = sizeof(unsigned) * (2 + n_blk / (2 * SHORT_INDEX)); 
-   n_s = sizeof(unsigned short) * (1 + n_blk); 
-   if ((info = (decode_info *) malloc(sizeof(*info) + n + n_u + n_s)) == 0) { 
-     free(ptr); 
-     free(blk); 
-     return RET(COMP_ERR_NOMEM); 
-   } 
-   cbEGTBCompBytes += sizeof(*info) + n + n_s + n_u; 
-   info->crc = (unsigned *) (info + 1); 
-   if (check_crc) 
-     blk_u = info->blk_u = info->crc + 2 * n_blk; 
-   else 
-     blk_u = info->blk_u = info->crc; 
-   blk_s = info->blk_s = 
-       (unsigned short *) (blk_u + 2 + n_blk / (2 * SHORT_INDEX)); 
-   info->check_crc = check_crc; 
-   info->block_size_log = block_size_log; 
-   info->block_size = block_size; 
-   info->n_blk = n_blk; 
-   if (check_crc) { 
-     n_blk <<= 1; 
-     i = HEADER_SIZE; 
-     for (n = 0; n < n_blk; ++n) { 
-       info->crc[n] = R4(i); 
-       i += 4; 
-     } 
-     n_blk >>= 1; 
-   } 
-   i = HEADER_SIZE + (n_blk << 3); 
-   BIORD_START(ptr + i); 
-   info->comp_block_size = 0; 
-   for (n = 0; n <= n_blk; ++n) { 
-     if ((blk[n] = BIORD(block_size_log)) == 0) 
-       blk[n] = block_size; 
-     if (info->comp_block_size < (int) (blk[n])) 
-       info->comp_block_size = (int) (blk[n]); 
-     BIORD_MORE(block_size_log); 
-   } 
-   info->comp_block_size += 32; 
-   for (n = 0; n < MAX_DISTANCES; ++n) { 
-     info->distance[n] = -((int) BIORD(block_size_log)); 
-     BIORD_MORE(block_size_log); 
-   } 
-   i += ((n_blk + 1 + MAX_DISTANCES) * block_size_log + 7) >> 3; 
-   BIORD_START(ptr + i); 
-   BITIO_LEAVE(Bitio); 
-   if (huffman_read_length(&Bitio, temp, ALPHABET_SIZE) != 0) { 
-     free(blk); 
-     free(info); 
-     free(ptr); 
-     return RET(COMP_ERR_BROKEN); 
-   } 
-   if (huffman_decode_create(info->table, temp, ALPHABET_SIZE, START_BITS) != 0) { 
-     free(blk); 
-     free(info); 
-     free(ptr); 
-     return RET(COMP_ERR_BROKEN); 
-   } 
-   info->last_block_size = blk[n_blk]; 
-   blk[n_blk] = 0; 
-   for (n = 0; n <= n_blk; ++n) { 
-     i = blk[n]; 
-     blk[n] = header_size; 
-     header_size += i; 
-     if (0 == n % (2 * SHORT_INDEX)) 
-       blk_u[n / (2 * SHORT_INDEX)] = blk[n]; 
-   } 
-   blk_u[n_blk / (2 * SHORT_INDEX) + 1] = blk[n_blk]; 
-   for (n = 0; n <= n_blk; ++n) { 
-     i = n / (2 * SHORT_INDEX); 
-     if (n & SHORT_INDEX) 
-       blk_s[n] = blk_u[i + 1] - blk[n]; 
-     else 
-       blk_s[n] = blk[n] - blk_u[i]; 
-   } 
-   free(blk); 
-   free(ptr); 
-   info->comp = 0; 
-   info->magic = DECODE_MAGIC; 
-   *res = info; 
-   return (COMP_ERR_NONE); 
- } 
- static int comp_tell_blocks(decode_info * info) 
- { 
-   if (info == 0 || info->magic != DECODE_MAGIC) 
-     return (-1); 
-   return (info->n_blk); 
- } 
- static int comp_init_block(decode_block * block, int block_size, uchar * orig) 
- { 
-   if (block == 0) 
-     return RET(COMP_ERR_PARAM); 
-   block->orig.first = orig; 
-   block->comp.first = (uchar *) (block + 1); 
-   block->b.ptr = 0; 
-   block->b.decoded = -1; 
-   block->b.total = -1; 
-   block->b.number = -1; 
-   block->n = -1; 
-   block->magic = BLOCK_MAGIC; 
-   return (COMP_ERR_NONE); 
- } 
- static int comp_alloc_block(decode_block ** ret_block, int block_size) 
- { 
-   decode_block *block; 
-   
-   if (ret_block == 0) 
-     return RET(COMP_ERR_PARAM); 
-   *ret_block = 0; 
-   if ((block = (decode_block *) malloc(sizeof(*block) + block_size)) == 0) 
-     return RET(COMP_ERR_NOMEM); 
-   cbEGTBCompBytes += sizeof(*block) + block_size; 
-   if (0 != comp_init_block(block, block_size, NULL)) 
-     return RET(COMP_ERR_PARAM); 
-   *ret_block = block; 
-   return (COMP_ERR_NONE); 
- } 
-   
- #  define RETURN(n) \ 
-   return ((n) == COMP_ERR_NONE ? COMP_ERR_NONE : RET (n)); 
- static int comp_read_block(decode_block * block, decode_info * info, FILE * fd, 
-     int n) 
- { 
-   int comp_size, orig_size, comp_start; 
-   uchar *comp, *orig; 
-   
-   if (block == 0 || block->magic != BLOCK_MAGIC) 
-     return RET(COMP_ERR_PARAM); 
-   assert(info->magic == DECODE_MAGIC); 
-   if ((unsigned) n >= (unsigned) info->n_blk) 
-     RETURN(COMP_ERR_PARAM); 
-   comp = block->comp.first; 
-   block->n = n; 
-   orig = block->orig.first; 
-   orig_size = info->block_size; 
-   if (n == info->n_blk - 1) 
-     orig_size = info->last_block_size; 
-   block->orig.size = orig_size; 
-   comp_start = calculate_offset(info, n); 
-   block->comp.size = comp_size = calculate_offset(info, n + 1) - comp_start; 
-   if (fseek(fd, comp_start, SEEK_SET) != 0) 
-     RETURN(COMP_ERR_READ); 
-   if (fread(comp, 1, comp_size, fd) != (size_t) comp_size) 
-     RETURN(COMP_ERR_READ); 
-   if (info->check_crc && 
-       info->crc[(n << 1) + 1] != CRC32(block->comp.first, comp_size, 0)) 
-     RETURN(COMP_ERR_BROKEN); 
-   block->emit.rept = 0; 
-   if (comp_size == orig_size) { 
-     memcpy(orig, comp, comp_size); 
-     block->emit.ptr = orig + comp_size; 
-     block->b.decoded = comp_size; 
-   } else { 
-     block->emit.ptr = orig; 
-     block->b.decoded = 0; 
-   } 
-   block->b.number = n; 
-   block->b.ptr = orig; 
-   block->b.total = orig_size; 
-   RETURN(COMP_ERR_NONE); 
- } 
- static int comp_decode_and_check_crc(decode_block * block, decode_info * info, 
-     int n, int check_crc) 
- { 
-   if (block == 0 || block->magic != BLOCK_MAGIC) 
-     return RET(COMP_ERR_PARAM); 
-   assert(info->magic == DECODE_MAGIC); 
-   if ((unsigned) (n - 1) > (unsigned) (block->orig.size - 1)) 
-     RETURN(COMP_ERR_PARAM); 
-   if (check_crc) 
-     n = block->orig.size; 
-   do_decode(info, block, block->orig.first + n); 
-   block->b.ptr = block->orig.first; 
-   block->b.total = block->orig.size; 
-   if (block->b.decoded >= block->b.total) { 
-     if (block->b.decoded > block->b.total) 
-       RETURN(COMP_ERR_BROKEN); 
-     if (block->emit.rept != 0) 
-       RETURN(COMP_ERR_BROKEN); 
-   } 
-   if (check_crc && info->check_crc && 
-       info->crc[block->n << 1] != CRC32(block->orig.first, block->orig.size, 0)) 
-     RETURN(COMP_ERR_BROKEN); 
-   RETURN(COMP_ERR_NONE); 
- } 
-   
- #  if !defined (COLOR_DECLARED) 
- /* 
-    Test driver 
-  */ 
- #    define     CRC_CHECK       1 
- int main(int argc, char *argv[]) 
- { 
-   int i; 
-   int size; 
-   int result; 
-   FILE *fp; 
-   decode_info *comp_info; 
-   decode_block *comp_block; 
-   clock_t tStart, tEnd; 
-   double dSeconds; 
-   uchar rgbBuf[8192 + 32]; 
-   
-   if (2 != argc) { 
-     printf("Invalid arguments\n"); 
-     exit(1); 
-   } 
-   fp = fopen(argv[1], "rb"); 
-   if (0 == fp) { 
-     printf("Unable to open file\n"); 
-     exit(1); 
-   } 
-   result = comp_open_file(&comp_info, fp, CRC_CHECK); 
-   if (0 != result) { 
-     printf("Unable to read file (1): %d\n", result); 
-     exit(1); 
-   } 
-   if (8192 != comp_info->block_size) { 
-     printf("Invalid block size: %d\n", comp_info->block_size); 
-     exit(1); 
-   } 
-   result = comp_alloc_block(&comp_block, comp_info->block_size); 
-   if (0 != result) { 
-     printf("Unable to allocate block: %d\n", result); 
-     exit(1); 
-   } 
-   size = 0; 
-   tStart = clock(); 
-   for (i = 0; i < comp_info->n_blk; i++) { 
-     if (0 != (result = 
-             comp_init_block(comp_block, comp_info->block_size, rgbBuf))) { 
-       printf("Unable to init block: %d\n", result); 
-       exit(1); 
-     } 
-     if (0 != (result = comp_read_block(comp_block, comp_info, fp, i))) { 
-       printf("Unable to read block: %d\n", result); 
-       exit(1); 
-     } 
-     size += comp_block->orig.size; 
-     if (0 != (result = 
-             comp_decode_and_check_crc(comp_block, comp_info, 
-                 comp_block->orig.size, CRC_CHECK))) { 
-       printf("Unable to decode block: %d\n", result); 
-       exit(1); 
-     } 
-   } 
-   tEnd = clock(); 
-   dSeconds = (double) (tEnd - tStart) / CLOCKS_PER_SEC; 
-   printf("Total memory allocated: %dKb\n", (cbEGTBCompBytes + 1023) / 1024); 
-   printf("%g seconds, %dMb, %gMb/sec)\n", dSeconds, size / (1024 * 1024), 
-       size / (1024 * 1024) / dSeconds); 
-   return 0; 
- } 
- #  endif 
- /* *INDENT-ON* */ 
- #endif 
-