Subversion Repositories Kolibri OS

Rev

Rev 1896 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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