Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

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