OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [compress/] [zlib/] [v2_0/] [src/] [inflate.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/* inflate.c -- zlib interface to inflate modules
2
 * Copyright (C) 1995-1998 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
 
6
#include "zutil.h"
7
#include "infblock.h"
8
 
9
struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
10
 
11
typedef enum {
12
      METHOD,   /* waiting for method byte */
13
#ifdef __ECOS__
14
      GZ_HDR2,
15
      GZ_METHOD,
16
      GZ_FLAG,
17
      GZ_TIME,
18
      GZ_EXTRA,
19
      GZ_EXTRA_HI,
20
      GZ_EXTRA_ZAP,
21
      GZ_NAME,
22
      GZ_COMMENT,
23
      GZ_HEAD_CRC_LO,
24
      GZ_HEAD_CRC_HI,
25
      GZ_DONE,
26
#endif // __ECOS__
27
      FLAG,     /* waiting for flag byte */
28
      DICT4,    /* four dictionary check bytes to go */
29
      DICT3,    /* three dictionary check bytes to go */
30
      DICT2,    /* two dictionary check bytes to go */
31
      DICT1,    /* one dictionary check byte to go */
32
      DICT0,    /* waiting for inflateSetDictionary */
33
      BLOCKS,   /* decompressing blocks */
34
      CHECK4,   /* four check bytes to go */
35
      CHECK3,   /* three check bytes to go */
36
      CHECK2,   /* two check bytes to go */
37
      CHECK1,   /* one check byte to go */
38
      DONE,     /* finished check, done */
39
      BAD}      /* got an error--stay here */
40
inflate_mode;
41
 
42
/* inflate private state */
43
struct internal_state {
44
 
45
  /* mode */
46
  inflate_mode  mode;   /* current inflate mode */
47
#ifdef __ECOS__
48
    inflate_mode gz_mode;
49
    uInt gz_flag;
50
    int gz_cnt;
51
    unsigned char* gz_start;
52
    uLong gz_sum;
53
#endif
54
 
55
  /* mode dependent information */
56
  union {
57
    uInt method;        /* if FLAGS, method byte */
58
    struct {
59
      uLong was;                /* computed check value */
60
      uLong need;               /* stream check value */
61
    } check;            /* if CHECK, check values to compare */
62
    uInt marker;        /* if BAD, inflateSync's marker bytes count */
63
  } sub;        /* submode */
64
 
65
  /* mode independent information */
66
  int  nowrap;          /* flag for no wrapper */
67
  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
68
  inflate_blocks_statef
69
    *blocks;            /* current inflate_blocks state */
70
 
71
};
72
 
73
#ifdef __ECOS__
74
/* gzip flag byte */
75
#define _GZ_ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
76
#define _GZ_HEAD_CRC     0x02 /* bit 1 set: header CRC present */
77
#define _GZ_EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
78
#define _GZ_ORIG_NAME    0x08 /* bit 3 set: original file name present */
79
#define _GZ_COMMENT      0x10 /* bit 4 set: file comment present */
80
#define _GZ_RESERVED     0xE0 /* bits 5..7: reserved */
81
#endif // __ECOS__
82
 
83
 
84
int ZEXPORT inflateReset(z)
85
z_streamp z;
86
{
87
  if (z == Z_NULL || z->state == Z_NULL)
88
    return Z_STREAM_ERROR;
89
  z->total_in = z->total_out = 0;
90
  z->msg = Z_NULL;
91
  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
92
  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
93
  Tracev((stderr, "inflate: reset\n"));
94
  return Z_OK;
95
}
96
 
97
 
98
int ZEXPORT inflateEnd(z)
99
z_streamp z;
100
{
101
  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
102
    return Z_STREAM_ERROR;
103
  if (z->state->blocks != Z_NULL)
104
    inflate_blocks_free(z->state->blocks, z);
105
  ZFREE(z, z->state);
106
  z->state = Z_NULL;
107
  Tracev((stderr, "inflate: end\n"));
108
  return Z_OK;
109
}
110
 
111
 
112
int ZEXPORT inflateInit2_(z, w, version, stream_size)
113
z_streamp z;
114
int w;
115
const char *version;
116
int stream_size;
117
{
118
  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
119
      stream_size != sizeof(z_stream))
120
      return Z_VERSION_ERROR;
121
 
122
  /* initialize state */
123
  if (z == Z_NULL)
124
    return Z_STREAM_ERROR;
125
  z->msg = Z_NULL;
126
  if (z->zalloc == Z_NULL)
127
  {
128
    z->zalloc = zcalloc;
129
    z->opaque = (voidpf)0;
130
  }
131
  if (z->zfree == Z_NULL) z->zfree = zcfree;
132
  if ((z->state = (struct internal_state FAR *)
133
       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
134
    return Z_MEM_ERROR;
135
  z->state->blocks = Z_NULL;
136
 
137
  /* handle undocumented nowrap option (no zlib header or check) */
138
  z->state->nowrap = 0;
139
  if (w < 0)
140
  {
141
    w = - w;
142
    z->state->nowrap = 1;
143
  }
144
 
145
  /* set window size */
146
  if (w < 8 || w > 15)
147
  {
148
    inflateEnd(z);
149
    return Z_STREAM_ERROR;
150
  }
151
  z->state->wbits = (uInt)w;
152
 
153
  /* create inflate_blocks state */
154
  if ((z->state->blocks =
155
      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
156
      == Z_NULL)
157
  {
158
    inflateEnd(z);
159
    return Z_MEM_ERROR;
160
  }
161
  Tracev((stderr, "inflate: allocated\n"));
162
 
163
  /* reset state */
164
  inflateReset(z);
165
  return Z_OK;
166
}
167
 
168
 
169
int ZEXPORT inflateInit_(z, version, stream_size)
170
z_streamp z;
171
const char *version;
172
int stream_size;
173
{
174
  return inflateInit2_(z, DEF_WBITS, version, stream_size);
175
}
176
 
177
 
178
#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
179
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
180
 
181
int ZEXPORT inflate(z, f)
182
z_streamp z;
183
int f;
184
{
185
  int r;
186
  uInt b;
187
 
188
  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
189
    return Z_STREAM_ERROR;
190
  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
191
  r = Z_BUF_ERROR;
192
  while (1) switch (z->state->mode)
193
  {
194
    case METHOD:
195
#ifdef __ECOS__
196
        // "Clear" gz_mode - if DONE at exit, this was a zlib stream.
197
        z->state->gz_mode = DONE;
198
#endif
199
      NEEDBYTE
200
      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
201
      {
202
#ifdef __ECOS__
203
          if (0x1f == z->state->sub.method) {
204
              z->state->mode = GZ_HDR2;
205
              break;
206
          }
207
          // This is a hack to get a reasonable error message in
208
          // RedBoot if the user tries to decompress raw data.
209
          z->state->mode = BAD;
210
          z->msg = (char*)"incorrect gzip header";
211
          z->state->sub.marker = 5;       /* can't try inflateSync */
212
#else
213
        z->state->mode = BAD;
214
        z->msg = (char*)"unknown compression method";
215
        z->state->sub.marker = 5;       /* can't try inflateSync */
216
#endif // __ECOS__
217
        break;
218
      }
219
      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
220
      {
221
        z->state->mode = BAD;
222
        z->msg = (char*)"invalid window size";
223
        z->state->sub.marker = 5;       /* can't try inflateSync */
224
        break;
225
      }
226
      z->state->mode = FLAG;
227
#ifdef __ECOS__
228
      break;
229
    case GZ_HDR2:
230
        NEEDBYTE;
231
        b = NEXTBYTE;
232
        if (0x8b != b) {
233
            z->state->mode = BAD;
234
            z->msg = (char*)"incorrect gzip header";
235
            z->state->sub.marker = 5;       /* can't try inflateSync */
236
            break;
237
        }
238
        z->state->mode = GZ_METHOD;
239
  case GZ_METHOD:
240
      NEEDBYTE
241
      if ((z->state->sub.method = NEXTBYTE) != Z_DEFLATED)
242
      {
243
        z->state->mode = BAD;
244
        z->msg = (char*)"unknown compression method";
245
        z->state->sub.marker = 5;       /* can't try inflateSync */
246
        break;
247
      }
248
      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
249
      {
250
        z->state->mode = BAD;
251
        z->msg = (char*)"invalid window size";
252
        z->state->sub.marker = 5;       /* can't try inflateSync */
253
        break;
254
      }
255
      z->state->mode = GZ_FLAG;
256
  case GZ_FLAG:
257
      NEEDBYTE
258
      z->state->gz_flag = NEXTBYTE;
259
      z->state->mode = GZ_TIME;
260
      z->state->gz_cnt = 6;             // for GZ_TIME
261
  case GZ_TIME:
262
      // Discard time, xflags and OS code
263
      while (z->state->gz_cnt-- > 0) {
264
          NEEDBYTE;
265
          b = NEXTBYTE;
266
      }
267
      z->state->mode = GZ_EXTRA;
268
  case GZ_EXTRA:
269
      if (!(z->state->gz_flag & _GZ_EXTRA_FIELD)) {
270
          z->state->mode = GZ_NAME;
271
          break;
272
      }
273
 
274
      NEEDBYTE;
275
      z->state->gz_cnt = NEXTBYTE;
276
      z->state->mode = GZ_EXTRA_HI;
277
  case GZ_EXTRA_HI:
278
      NEEDBYTE;
279
      z->state->gz_cnt += (((uInt)NEXTBYTE)<<8);
280
      z->state->mode = GZ_EXTRA_ZAP;
281
  case GZ_EXTRA_ZAP:
282
      // Discard extra field
283
      while (z->state->gz_cnt-- > 0) {
284
          NEEDBYTE;
285
          b = NEXTBYTE;
286
      }
287
      z->state->mode = GZ_NAME;
288
  case GZ_NAME:
289
      if (!(z->state->gz_flag & _GZ_ORIG_NAME)) {
290
          z->state->mode = GZ_COMMENT;
291
          break;
292
      }
293
      // Skip the name
294
      do {
295
          NEEDBYTE;
296
          b = NEXTBYTE;
297
      } while (0 != b);
298
      z->state->mode = GZ_COMMENT;
299
  case GZ_COMMENT:
300
      if (!(z->state->gz_flag & _GZ_COMMENT)) {
301
          z->state->mode = GZ_HEAD_CRC_LO;
302
          break;
303
      }
304
      // Skip the comment
305
      do {
306
          NEEDBYTE;
307
          b = NEXTBYTE;
308
      } while (0 != b);
309
      z->state->mode = GZ_HEAD_CRC_LO;
310
  case GZ_HEAD_CRC_LO:
311
      if (!(z->state->gz_flag & _GZ_HEAD_CRC)) {
312
          z->state->mode = GZ_DONE;
313
          break;
314
      }
315
      // skip lo byte
316
      NEEDBYTE;
317
      b = NEXTBYTE;
318
      z->state->mode = GZ_HEAD_CRC_HI;
319
  case GZ_HEAD_CRC_HI:
320
      // skip hi byte
321
      NEEDBYTE;
322
      b = NEXTBYTE;
323
      z->state->mode = GZ_DONE;
324
  case GZ_DONE:
325
      // Remember where output is written to and flag that this is a
326
      // gz stream by setting the gz_mode.
327
      z->state->gz_start = z->next_out;
328
      z->state->gz_mode = BLOCKS;
329
      z->state->gz_sum = 0;
330
 
331
      // Depending on the flag select correct next step
332
      // (clone of code in FLAG)
333
      if (!(z->state->gz_flag & PRESET_DICT))
334
          z->state->mode = BLOCKS;
335
      else
336
          z->state->mode = DICT4;
337
      break;
338
#endif // __ECOS__
339
    case FLAG:
340
      NEEDBYTE
341
      b = NEXTBYTE;
342
      if (((z->state->sub.method << 8) + b) % 31)
343
      {
344
        z->state->mode = BAD;
345
        z->msg = (char*)"incorrect header check";
346
        z->state->sub.marker = 5;       /* can't try inflateSync */
347
        break;
348
      }
349
      Tracev((stderr, "inflate: zlib header ok\n"));
350
      if (!(b & PRESET_DICT))
351
      {
352
        z->state->mode = BLOCKS;
353
        break;
354
      }
355
      z->state->mode = DICT4;
356
    case DICT4:
357
      NEEDBYTE
358
      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
359
      z->state->mode = DICT3;
360
    case DICT3:
361
      NEEDBYTE
362
      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
363
      z->state->mode = DICT2;
364
    case DICT2:
365
      NEEDBYTE
366
      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
367
      z->state->mode = DICT1;
368
    case DICT1:
369
      NEEDBYTE
370
      z->state->sub.check.need += (uLong)NEXTBYTE;
371
      z->adler = z->state->sub.check.need;
372
      z->state->mode = DICT0;
373
      return Z_NEED_DICT;
374
    case DICT0:
375
      z->state->mode = BAD;
376
      z->msg = (char*)"need dictionary";
377
      z->state->sub.marker = 0;       /* can try inflateSync */
378
      return Z_STREAM_ERROR;
379
    case BLOCKS:
380
#ifdef __ECOS__
381
      if (z->state->gz_mode != DONE)
382
        z->state->gz_start = z->next_out;
383
#endif
384
      r = inflate_blocks(z->state->blocks, z, r);
385
      if (r == Z_DATA_ERROR)
386
      {
387
        z->state->mode = BAD;
388
        z->state->sub.marker = 0;       /* can try inflateSync */
389
        break;
390
      }
391
      if (r == Z_OK)
392
        r = f;
393
#ifdef __ECOS__
394
      if (z->state->gz_mode != DONE)
395
        z->state->gz_sum = cyg_ether_crc32_accumulate(z->state->gz_sum,
396
                                                      z->state->gz_start,
397
                                                      z->next_out -
398
                                                      z->state->gz_start);
399
#endif
400
      if (r != Z_STREAM_END)
401
        return r;
402
      r = f;
403
      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
404
      if (z->state->nowrap)
405
      {
406
        z->state->mode = DONE;
407
        break;
408
      }
409
      z->state->mode = CHECK4;
410
    case CHECK4:
411
      NEEDBYTE
412
      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
413
      z->state->mode = CHECK3;
414
    case CHECK3:
415
      NEEDBYTE
416
      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
417
      z->state->mode = CHECK2;
418
    case CHECK2:
419
      NEEDBYTE
420
      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
421
      z->state->mode = CHECK1;
422
    case CHECK1:
423
      NEEDBYTE
424
      z->state->sub.check.need += (uLong)NEXTBYTE;
425
 
426
#ifdef __ECOS__
427
      if (z->state->gz_mode != DONE) {
428
          // Byte swap CRC since it is read in the opposite order as
429
          // written by gzip.
430
          unsigned long c = z->state->gz_sum;
431
          z->state->sub.check.was = (((c & 0xff000000) >> 24) | ((c & 0x00ff0000) >> 8)
432
                                     | ((c & 0x0000ff00) << 8) | ((c & 0x000000ff) << 24));
433
 
434
      }
435
#endif
436
 
437
      if (z->state->sub.check.was != z->state->sub.check.need)
438
      {
439
        z->state->mode = BAD;
440
        z->msg = (char*)"incorrect data check";
441
        z->state->sub.marker = 5;       /* can't try inflateSync */
442
        break;
443
      }
444
      Tracev((stderr, "inflate: zlib check ok\n"));
445
      z->state->mode = DONE;
446
    case DONE:
447
      return Z_STREAM_END;
448
    case BAD:
449
      return Z_DATA_ERROR;
450
    default:
451
      return Z_STREAM_ERROR;
452
  }
453
#ifdef NEED_DUMMY_RETURN
454
  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
455
#endif
456
}
457
 
458
 
459
int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
460
z_streamp z;
461
const Bytef *dictionary;
462
uInt  dictLength;
463
{
464
  uInt length = dictLength;
465
 
466
  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
467
    return Z_STREAM_ERROR;
468
 
469
  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
470
  z->adler = 1L;
471
 
472
  if (length >= ((uInt)1<<z->state->wbits))
473
  {
474
    length = (1<<z->state->wbits)-1;
475
    dictionary += dictLength - length;
476
  }
477
  inflate_set_dictionary(z->state->blocks, dictionary, length);
478
  z->state->mode = BLOCKS;
479
  return Z_OK;
480
}
481
 
482
 
483
int ZEXPORT inflateSync(z)
484
z_streamp z;
485
{
486
  uInt n;       /* number of bytes to look at */
487
  Bytef *p;     /* pointer to bytes */
488
  uInt m;       /* number of marker bytes found in a row */
489
  uLong r, w;   /* temporaries to save total_in and total_out */
490
 
491
  /* set up */
492
  if (z == Z_NULL || z->state == Z_NULL)
493
    return Z_STREAM_ERROR;
494
  if (z->state->mode != BAD)
495
  {
496
    z->state->mode = BAD;
497
    z->state->sub.marker = 0;
498
  }
499
  if ((n = z->avail_in) == 0)
500
    return Z_BUF_ERROR;
501
  p = z->next_in;
502
  m = z->state->sub.marker;
503
 
504
  /* search */
505
  while (n && m < 4)
506
  {
507
    static const Byte mark[4] = {0, 0, 0xff, 0xff};
508
    if (*p == mark[m])
509
      m++;
510
    else if (*p)
511
      m = 0;
512
    else
513
      m = 4 - m;
514
    p++, n--;
515
  }
516
 
517
  /* restore */
518
  z->total_in += p - z->next_in;
519
  z->next_in = p;
520
  z->avail_in = n;
521
  z->state->sub.marker = m;
522
 
523
  /* return no joy or set up to restart on a new block */
524
  if (m != 4)
525
    return Z_DATA_ERROR;
526
  r = z->total_in;  w = z->total_out;
527
  inflateReset(z);
528
  z->total_in = r;  z->total_out = w;
529
  z->state->mode = BLOCKS;
530
  return Z_OK;
531
}
532
 
533
 
534
/* Returns true if inflate is currently at the end of a block generated
535
 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
536
 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
537
 * but removes the length bytes of the resulting empty stored block. When
538
 * decompressing, PPP checks that at the end of input packet, inflate is
539
 * waiting for these length bytes.
540
 */
541
int ZEXPORT inflateSyncPoint(z)
542
z_streamp z;
543
{
544
  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
545
    return Z_STREAM_ERROR;
546
  return inflate_blocks_sync_point(z->state->blocks);
547
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.