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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [zlib/] [contrib/] [infback9/] [infback9.c] - Blame information for rev 833

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

Line No. Rev Author Line
1 745 jeremybenn
/* infback9.c -- inflate deflate64 data using a call-back interface
2
 * Copyright (C) 1995-2003 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
 
6
#include "zutil.h"
7
#include "infback9.h"
8
#include "inftree9.h"
9
#include "inflate9.h"
10
 
11
#define WSIZE 65536UL
12
 
13
/*
14
   strm provides memory allocation functions in zalloc and zfree, or
15
   Z_NULL to use the library memory allocation functions.
16
 
17
   window is a user-supplied window and output buffer that is 64K bytes.
18
 */
19
int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
20
z_stream FAR *strm;
21
unsigned char FAR *window;
22
const char *version;
23
int stream_size;
24
{
25
    struct inflate_state FAR *state;
26
 
27
    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
28
        stream_size != (int)(sizeof(z_stream)))
29
        return Z_VERSION_ERROR;
30
    if (strm == Z_NULL || window == Z_NULL)
31
        return Z_STREAM_ERROR;
32
    strm->msg = Z_NULL;                 /* in case we return an error */
33
    if (strm->zalloc == (alloc_func)0) {
34
        strm->zalloc = zcalloc;
35
        strm->opaque = (voidpf)0;
36
    }
37
    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
38
    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
39
                                               sizeof(struct inflate_state));
40
    if (state == Z_NULL) return Z_MEM_ERROR;
41
    Tracev((stderr, "inflate: allocated\n"));
42
    strm->state = (voidpf)state;
43
    state->window = window;
44
    return Z_OK;
45
}
46
 
47
/*
48
   Build and output length and distance decoding tables for fixed code
49
   decoding.
50
 */
51
#ifdef MAKEFIXED
52
#include <stdio.h>
53
 
54
void makefixed9(void)
55
{
56
    unsigned sym, bits, low, size;
57
    code *next, *lenfix, *distfix;
58
    struct inflate_state state;
59
    code fixed[544];
60
 
61
    /* literal/length table */
62
    sym = 0;
63
    while (sym < 144) state.lens[sym++] = 8;
64
    while (sym < 256) state.lens[sym++] = 9;
65
    while (sym < 280) state.lens[sym++] = 7;
66
    while (sym < 288) state.lens[sym++] = 8;
67
    next = fixed;
68
    lenfix = next;
69
    bits = 9;
70
    inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
71
 
72
    /* distance table */
73
    sym = 0;
74
    while (sym < 32) state.lens[sym++] = 5;
75
    distfix = next;
76
    bits = 5;
77
    inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
78
 
79
    /* write tables */
80
    puts("    /* inffix9.h -- table for decoding deflate64 fixed codes");
81
    puts("     * Generated automatically by makefixed9().");
82
    puts("     */");
83
    puts("");
84
    puts("    /* WARNING: this file should *not* be used by applications.");
85
    puts("       It is part of the implementation of this library and is");
86
    puts("       subject to change. Applications should only use zlib.h.");
87
    puts("     */");
88
    puts("");
89
    size = 1U << 9;
90
    printf("    static const code lenfix[%u] = {", size);
91
    low = 0;
92
    for (;;) {
93
        if ((low % 6) == 0) printf("\n        ");
94
        printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
95
               lenfix[low].val);
96
        if (++low == size) break;
97
        putchar(',');
98
    }
99
    puts("\n    };");
100
    size = 1U << 5;
101
    printf("\n    static const code distfix[%u] = {", size);
102
    low = 0;
103
    for (;;) {
104
        if ((low % 5) == 0) printf("\n        ");
105
        printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
106
               distfix[low].val);
107
        if (++low == size) break;
108
        putchar(',');
109
    }
110
    puts("\n    };");
111
}
112
#endif /* MAKEFIXED */
113
 
114
/* Macros for inflateBack(): */
115
 
116
/* Clear the input bit accumulator */
117
#define INITBITS() \
118
    do { \
119
        hold = 0; \
120
        bits = 0; \
121
    } while (0)
122
 
123
/* Assure that some input is available.  If input is requested, but denied,
124
   then return a Z_BUF_ERROR from inflateBack(). */
125
#define PULL() \
126
    do { \
127
        if (have == 0) { \
128
            have = in(in_desc, &next); \
129
            if (have == 0) { \
130
                next = Z_NULL; \
131
                ret = Z_BUF_ERROR; \
132
                goto inf_leave; \
133
            } \
134
        } \
135
    } while (0)
136
 
137
/* Get a byte of input into the bit accumulator, or return from inflateBack()
138
   with an error if there is no input available. */
139
#define PULLBYTE() \
140
    do { \
141
        PULL(); \
142
        have--; \
143
        hold += (unsigned long)(*next++) << bits; \
144
        bits += 8; \
145
    } while (0)
146
 
147
/* Assure that there are at least n bits in the bit accumulator.  If there is
148
   not enough available input to do that, then return from inflateBack() with
149
   an error. */
150
#define NEEDBITS(n) \
151
    do { \
152
        while (bits < (unsigned)(n)) \
153
            PULLBYTE(); \
154
    } while (0)
155
 
156
/* Return the low n bits of the bit accumulator (n <= 16) */
157
#define BITS(n) \
158
    ((unsigned)hold & ((1U << (n)) - 1))
159
 
160
/* Remove n bits from the bit accumulator */
161
#define DROPBITS(n) \
162
    do { \
163
        hold >>= (n); \
164
        bits -= (unsigned)(n); \
165
    } while (0)
166
 
167
/* Remove zero to seven bits as needed to go to a byte boundary */
168
#define BYTEBITS() \
169
    do { \
170
        hold >>= bits & 7; \
171
        bits -= bits & 7; \
172
    } while (0)
173
 
174
/* Assure that some output space is available, by writing out the window
175
   if it's full.  If the write fails, return from inflateBack() with a
176
   Z_BUF_ERROR. */
177
#define ROOM() \
178
    do { \
179
        if (left == 0) { \
180
            put = window; \
181
            left = WSIZE; \
182
            wrap = 1; \
183
            if (out(out_desc, put, (unsigned)left)) { \
184
                ret = Z_BUF_ERROR; \
185
                goto inf_leave; \
186
            } \
187
        } \
188
    } while (0)
189
 
190
/*
191
   strm provides the memory allocation functions and window buffer on input,
192
   and provides information on the unused input on return.  For Z_DATA_ERROR
193
   returns, strm will also provide an error message.
194
 
195
   in() and out() are the call-back input and output functions.  When
196
   inflateBack() needs more input, it calls in().  When inflateBack() has
197
   filled the window with output, or when it completes with data in the
198
   window, it calls out() to write out the data.  The application must not
199
   change the provided input until in() is called again or inflateBack()
200
   returns.  The application must not change the window/output buffer until
201
   inflateBack() returns.
202
 
203
   in() and out() are called with a descriptor parameter provided in the
204
   inflateBack() call.  This parameter can be a structure that provides the
205
   information required to do the read or write, as well as accumulated
206
   information on the input and output such as totals and check values.
207
 
208
   in() should return zero on failure.  out() should return non-zero on
209
   failure.  If either in() or out() fails, than inflateBack() returns a
210
   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
211
   was in() or out() that caused in the error.  Otherwise,  inflateBack()
212
   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
213
   error, or Z_MEM_ERROR if it could not allocate memory for the state.
214
   inflateBack() can also return Z_STREAM_ERROR if the input parameters
215
   are not correct, i.e. strm is Z_NULL or the state was not initialized.
216
 */
217
int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
218
z_stream FAR *strm;
219
in_func in;
220
void FAR *in_desc;
221
out_func out;
222
void FAR *out_desc;
223
{
224
    struct inflate_state FAR *state;
225
    unsigned char FAR *next;    /* next input */
226
    unsigned char FAR *put;     /* next output */
227
    unsigned have;              /* available input */
228
    unsigned long left;         /* available output */
229
    inflate_mode mode;          /* current inflate mode */
230
    int lastblock;              /* true if processing last block */
231
    int wrap;                   /* true if the window has wrapped */
232
    unsigned long write;        /* window write index */
233
    unsigned char FAR *window;  /* allocated sliding window, if needed */
234
    unsigned long hold;         /* bit buffer */
235
    unsigned bits;              /* bits in bit buffer */
236
    unsigned extra;             /* extra bits needed */
237
    unsigned long length;       /* literal or length of data to copy */
238
    unsigned long offset;       /* distance back to copy string from */
239
    unsigned long copy;         /* number of stored or match bytes to copy */
240
    unsigned char FAR *from;    /* where to copy match bytes from */
241
    code const FAR *lencode;    /* starting table for length/literal codes */
242
    code const FAR *distcode;   /* starting table for distance codes */
243
    unsigned lenbits;           /* index bits for lencode */
244
    unsigned distbits;          /* index bits for distcode */
245
    code this;                  /* current decoding table entry */
246
    code last;                  /* parent table entry */
247
    unsigned len;               /* length to copy for repeats, bits to drop */
248
    int ret;                    /* return code */
249
    static const unsigned short order[19] = /* permutation of code lengths */
250
        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
251
#include "inffix9.h"
252
 
253
    /* Check that the strm exists and that the state was initialized */
254
    if (strm == Z_NULL || strm->state == Z_NULL)
255
        return Z_STREAM_ERROR;
256
    state = (struct inflate_state FAR *)strm->state;
257
 
258
    /* Reset the state */
259
    strm->msg = Z_NULL;
260
    mode = TYPE;
261
    lastblock = 0;
262
    write = 0;
263
    wrap = 0;
264
    window = state->window;
265
    next = strm->next_in;
266
    have = next != Z_NULL ? strm->avail_in : 0;
267
    hold = 0;
268
    bits = 0;
269
    put = window;
270
    left = WSIZE;
271
    lencode = Z_NULL;
272
    distcode = Z_NULL;
273
 
274
    /* Inflate until end of block marked as last */
275
    for (;;)
276
        switch (mode) {
277
        case TYPE:
278
            /* determine and dispatch block type */
279
            if (lastblock) {
280
                BYTEBITS();
281
                mode = DONE;
282
                break;
283
            }
284
            NEEDBITS(3);
285
            lastblock = BITS(1);
286
            DROPBITS(1);
287
            switch (BITS(2)) {
288
            case 0:                             /* stored block */
289
                Tracev((stderr, "inflate:     stored block%s\n",
290
                        lastblock ? " (last)" : ""));
291
                mode = STORED;
292
                break;
293
            case 1:                             /* fixed block */
294
                lencode = lenfix;
295
                lenbits = 9;
296
                distcode = distfix;
297
                distbits = 5;
298
                Tracev((stderr, "inflate:     fixed codes block%s\n",
299
                        lastblock ? " (last)" : ""));
300
                mode = LEN;                     /* decode codes */
301
                break;
302
            case 2:                             /* dynamic block */
303
                Tracev((stderr, "inflate:     dynamic codes block%s\n",
304
                        lastblock ? " (last)" : ""));
305
                mode = TABLE;
306
                break;
307
            case 3:
308
                strm->msg = (char *)"invalid block type";
309
                mode = BAD;
310
            }
311
            DROPBITS(2);
312
            break;
313
 
314
        case STORED:
315
            /* get and verify stored block length */
316
            BYTEBITS();                         /* go to byte boundary */
317
            NEEDBITS(32);
318
            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
319
                strm->msg = (char *)"invalid stored block lengths";
320
                mode = BAD;
321
                break;
322
            }
323
            length = (unsigned)hold & 0xffff;
324
            Tracev((stderr, "inflate:       stored length %lu\n",
325
                    length));
326
            INITBITS();
327
 
328
            /* copy stored block from input to output */
329
            while (length != 0) {
330
                copy = length;
331
                PULL();
332
                ROOM();
333
                if (copy > have) copy = have;
334
                if (copy > left) copy = left;
335
                zmemcpy(put, next, copy);
336
                have -= copy;
337
                next += copy;
338
                left -= copy;
339
                put += copy;
340
                length -= copy;
341
            }
342
            Tracev((stderr, "inflate:       stored end\n"));
343
            mode = TYPE;
344
            break;
345
 
346
        case TABLE:
347
            /* get dynamic table entries descriptor */
348
            NEEDBITS(14);
349
            state->nlen = BITS(5) + 257;
350
            DROPBITS(5);
351
            state->ndist = BITS(5) + 1;
352
            DROPBITS(5);
353
            state->ncode = BITS(4) + 4;
354
            DROPBITS(4);
355
            if (state->nlen > 286) {
356
                strm->msg = (char *)"too many length symbols";
357
                mode = BAD;
358
                break;
359
            }
360
            Tracev((stderr, "inflate:       table sizes ok\n"));
361
 
362
            /* get code length code lengths (not a typo) */
363
            state->have = 0;
364
            while (state->have < state->ncode) {
365
                NEEDBITS(3);
366
                state->lens[order[state->have++]] = (unsigned short)BITS(3);
367
                DROPBITS(3);
368
            }
369
            while (state->have < 19)
370
                state->lens[order[state->have++]] = 0;
371
            state->next = state->codes;
372
            lencode = (code const FAR *)(state->next);
373
            lenbits = 7;
374
            ret = inflate_table9(CODES, state->lens, 19, &(state->next),
375
                                &(lenbits), state->work);
376
            if (ret) {
377
                strm->msg = (char *)"invalid code lengths set";
378
                mode = BAD;
379
                break;
380
            }
381
            Tracev((stderr, "inflate:       code lengths ok\n"));
382
 
383
            /* get length and distance code code lengths */
384
            state->have = 0;
385
            while (state->have < state->nlen + state->ndist) {
386
                for (;;) {
387
                    this = lencode[BITS(lenbits)];
388
                    if ((unsigned)(this.bits) <= bits) break;
389
                    PULLBYTE();
390
                }
391
                if (this.val < 16) {
392
                    NEEDBITS(this.bits);
393
                    DROPBITS(this.bits);
394
                    state->lens[state->have++] = this.val;
395
                }
396
                else {
397
                    if (this.val == 16) {
398
                        NEEDBITS(this.bits + 2);
399
                        DROPBITS(this.bits);
400
                        if (state->have == 0) {
401
                            strm->msg = (char *)"invalid bit length repeat";
402
                            mode = BAD;
403
                            break;
404
                        }
405
                        len = (unsigned)(state->lens[state->have - 1]);
406
                        copy = 3 + BITS(2);
407
                        DROPBITS(2);
408
                    }
409
                    else if (this.val == 17) {
410
                        NEEDBITS(this.bits + 3);
411
                        DROPBITS(this.bits);
412
                        len = 0;
413
                        copy = 3 + BITS(3);
414
                        DROPBITS(3);
415
                    }
416
                    else {
417
                        NEEDBITS(this.bits + 7);
418
                        DROPBITS(this.bits);
419
                        len = 0;
420
                        copy = 11 + BITS(7);
421
                        DROPBITS(7);
422
                    }
423
                    if (state->have + copy > state->nlen + state->ndist) {
424
                        strm->msg = (char *)"invalid bit length repeat";
425
                        mode = BAD;
426
                        break;
427
                    }
428
                    while (copy--)
429
                        state->lens[state->have++] = (unsigned short)len;
430
                }
431
            }
432
 
433
            /* handle error breaks in while */
434
            if (mode == BAD) break;
435
 
436
            /* build code tables */
437
            state->next = state->codes;
438
            lencode = (code const FAR *)(state->next);
439
            lenbits = 9;
440
            ret = inflate_table9(LENS, state->lens, state->nlen,
441
                            &(state->next), &(lenbits), state->work);
442
            if (ret) {
443
                strm->msg = (char *)"invalid literal/lengths set";
444
                mode = BAD;
445
                break;
446
            }
447
            distcode = (code const FAR *)(state->next);
448
            distbits = 6;
449
            ret = inflate_table9(DISTS, state->lens + state->nlen,
450
                            state->ndist, &(state->next), &(distbits),
451
                            state->work);
452
            if (ret) {
453
                strm->msg = (char *)"invalid distances set";
454
                mode = BAD;
455
                break;
456
            }
457
            Tracev((stderr, "inflate:       codes ok\n"));
458
            mode = LEN;
459
 
460
        case LEN:
461
            /* get a literal, length, or end-of-block code */
462
            for (;;) {
463
                this = lencode[BITS(lenbits)];
464
                if ((unsigned)(this.bits) <= bits) break;
465
                PULLBYTE();
466
            }
467
            if (this.op && (this.op & 0xf0) == 0) {
468
                last = this;
469
                for (;;) {
470
                    this = lencode[last.val +
471
                            (BITS(last.bits + last.op) >> last.bits)];
472
                    if ((unsigned)(last.bits + this.bits) <= bits) break;
473
                    PULLBYTE();
474
                }
475
                DROPBITS(last.bits);
476
            }
477
            DROPBITS(this.bits);
478
            length = (unsigned)this.val;
479
 
480
            /* process literal */
481
            if (this.op == 0) {
482
                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
483
                        "inflate:         literal '%c'\n" :
484
                        "inflate:         literal 0x%02x\n", this.val));
485
                ROOM();
486
                *put++ = (unsigned char)(length);
487
                left--;
488
                mode = LEN;
489
                break;
490
            }
491
 
492
            /* process end of block */
493
            if (this.op & 32) {
494
                Tracevv((stderr, "inflate:         end of block\n"));
495
                mode = TYPE;
496
                break;
497
            }
498
 
499
            /* invalid code */
500
            if (this.op & 64) {
501
                strm->msg = (char *)"invalid literal/length code";
502
                mode = BAD;
503
                break;
504
            }
505
 
506
            /* length code -- get extra bits, if any */
507
            extra = (unsigned)(this.op) & 31;
508
            if (extra != 0) {
509
                NEEDBITS(extra);
510
                length += BITS(extra);
511
                DROPBITS(extra);
512
            }
513
            Tracevv((stderr, "inflate:         length %lu\n", length));
514
 
515
            /* get distance code */
516
            for (;;) {
517
                this = distcode[BITS(distbits)];
518
                if ((unsigned)(this.bits) <= bits) break;
519
                PULLBYTE();
520
            }
521
            if ((this.op & 0xf0) == 0) {
522
                last = this;
523
                for (;;) {
524
                    this = distcode[last.val +
525
                            (BITS(last.bits + last.op) >> last.bits)];
526
                    if ((unsigned)(last.bits + this.bits) <= bits) break;
527
                    PULLBYTE();
528
                }
529
                DROPBITS(last.bits);
530
            }
531
            DROPBITS(this.bits);
532
            if (this.op & 64) {
533
                strm->msg = (char *)"invalid distance code";
534
                mode = BAD;
535
                break;
536
            }
537
            offset = (unsigned)this.val;
538
 
539
            /* get distance extra bits, if any */
540
            extra = (unsigned)(this.op) & 15;
541
            if (extra != 0) {
542
                NEEDBITS(extra);
543
                offset += BITS(extra);
544
                DROPBITS(extra);
545
            }
546
            if (offset > WSIZE - (wrap ? 0: left)) {
547
                strm->msg = (char *)"invalid distance too far back";
548
                mode = BAD;
549
                break;
550
            }
551
            Tracevv((stderr, "inflate:         distance %lu\n", offset));
552
 
553
            /* copy match from window to output */
554
            do {
555
                ROOM();
556
                copy = WSIZE - offset;
557
                if (copy < left) {
558
                    from = put + copy;
559
                    copy = left - copy;
560
                }
561
                else {
562
                    from = put - offset;
563
                    copy = left;
564
                }
565
                if (copy > length) copy = length;
566
                length -= copy;
567
                left -= copy;
568
                do {
569
                    *put++ = *from++;
570
                } while (--copy);
571
            } while (length != 0);
572
            break;
573
 
574
        case DONE:
575
            /* inflate stream terminated properly -- write leftover output */
576
            ret = Z_STREAM_END;
577
            if (left < WSIZE) {
578
                if (out(out_desc, window, (unsigned)(WSIZE - left)))
579
                    ret = Z_BUF_ERROR;
580
            }
581
            goto inf_leave;
582
 
583
        case BAD:
584
            ret = Z_DATA_ERROR;
585
            goto inf_leave;
586
 
587
        default:                /* can't happen, but makes compilers happy */
588
            ret = Z_STREAM_ERROR;
589
            goto inf_leave;
590
        }
591
 
592
    /* Return unused input */
593
  inf_leave:
594
    strm->next_in = next;
595
    strm->avail_in = have;
596
    return ret;
597
}
598
 
599
int ZEXPORT inflateBack9End(strm)
600
z_stream FAR *strm;
601
{
602
    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
603
        return Z_STREAM_ERROR;
604
    ZFREE(strm, strm->state);
605
    strm->state = Z_NULL;
606
    Tracev((stderr, "inflate: end\n"));
607
    return Z_OK;
608
}

powered by: WebSVN 2.1.0

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