00001
00002
00003
00004
00005
00006 #include "zutil.h"
00007 #include "infback9.h"
00008 #include "inftree9.h"
00009 #include "inflate9.h"
00010
00011 #define WSIZE 65536UL
00012
00013
00014
00015
00016
00017
00018
00019 int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
00020 z_stream FAR *strm;
00021 unsigned char FAR *window;
00022 const char *version;
00023 int stream_size;
00024 {
00025 struct inflate_state FAR *state;
00026
00027 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
00028 stream_size != (int)(sizeof(z_stream)))
00029 return Z_VERSION_ERROR;
00030 if (strm == Z_NULL || window == Z_NULL)
00031 return Z_STREAM_ERROR;
00032 strm->msg = Z_NULL;
00033 if (strm->zalloc == (alloc_func)0) {
00034 strm->zalloc = zcalloc;
00035 strm->opaque = (voidpf)0;
00036 }
00037 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
00038 state = (struct inflate_state FAR *)ZALLOC(strm, 1,
00039 sizeof(struct inflate_state));
00040 if (state == Z_NULL) return Z_MEM_ERROR;
00041 Tracev((stderr, "inflate: allocated\n"));
00042 strm->state = (voidpf)state;
00043 state->window = window;
00044 return Z_OK;
00045 }
00046
00047
00048
00049
00050
00051 #ifdef MAKEFIXED
00052 #include <stdio.h>
00053
00054 void makefixed9(void)
00055 {
00056 unsigned sym, bits, low, size;
00057 code *next, *lenfix, *distfix;
00058 struct inflate_state state;
00059 code fixed[544];
00060
00061
00062 sym = 0;
00063 while (sym < 144) state.lens[sym++] = 8;
00064 while (sym < 256) state.lens[sym++] = 9;
00065 while (sym < 280) state.lens[sym++] = 7;
00066 while (sym < 288) state.lens[sym++] = 8;
00067 next = fixed;
00068 lenfix = next;
00069 bits = 9;
00070 inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
00071
00072
00073 sym = 0;
00074 while (sym < 32) state.lens[sym++] = 5;
00075 distfix = next;
00076 bits = 5;
00077 inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
00078
00079
00080 puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
00081 puts(" * Generated automatically by makefixed9().");
00082 puts(" */");
00083 puts("");
00084 puts(" /* WARNING: this file should *not* be used by applications.");
00085 puts(" It is part of the implementation of this library and is");
00086 puts(" subject to change. Applications should only use zlib.h.");
00087 puts(" */");
00088 puts("");
00089 size = 1U << 9;
00090 printf(" static const code lenfix[%u] = {", size);
00091 low = 0;
00092 for (;;) {
00093 if ((low % 6) == 0) printf("\n ");
00094 printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
00095 lenfix[low].val);
00096 if (++low == size) break;
00097 putchar(',');
00098 }
00099 puts("\n };");
00100 size = 1U << 5;
00101 printf("\n static const code distfix[%u] = {", size);
00102 low = 0;
00103 for (;;) {
00104 if ((low % 5) == 0) printf("\n ");
00105 printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
00106 distfix[low].val);
00107 if (++low == size) break;
00108 putchar(',');
00109 }
00110 puts("\n };");
00111 }
00112 #endif
00113
00114
00115
00116
00117 #define INITBITS() \
00118 do { \
00119 hold = 0; \
00120 bits = 0; \
00121 } while (0)
00122
00123
00124
00125 #define PULL() \
00126 do { \
00127 if (have == 0) { \
00128 have = in(in_desc, &next); \
00129 if (have == 0) { \
00130 next = Z_NULL; \
00131 ret = Z_BUF_ERROR; \
00132 goto inf_leave; \
00133 } \
00134 } \
00135 } while (0)
00136
00137
00138
00139 #define PULLBYTE() \
00140 do { \
00141 PULL(); \
00142 have--; \
00143 hold += (unsigned long)(*next++) << bits; \
00144 bits += 8; \
00145 } while (0)
00146
00147
00148
00149
00150 #define NEEDBITS(n) \
00151 do { \
00152 while (bits < (unsigned)(n)) \
00153 PULLBYTE(); \
00154 } while (0)
00155
00156
00157 #define BITS(n) \
00158 ((unsigned)hold & ((1U << (n)) - 1))
00159
00160
00161 #define DROPBITS(n) \
00162 do { \
00163 hold >>= (n); \
00164 bits -= (unsigned)(n); \
00165 } while (0)
00166
00167
00168 #define BYTEBITS() \
00169 do { \
00170 hold >>= bits & 7; \
00171 bits -= bits & 7; \
00172 } while (0)
00173
00174
00175
00176
00177 #define ROOM() \
00178 do { \
00179 if (left == 0) { \
00180 put = window; \
00181 left = WSIZE; \
00182 wrap = 1; \
00183 if (out(out_desc, put, (unsigned)left)) { \
00184 ret = Z_BUF_ERROR; \
00185 goto inf_leave; \
00186 } \
00187 } \
00188 } while (0)
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
00218 z_stream FAR *strm;
00219 in_func in;
00220 void FAR *in_desc;
00221 out_func out;
00222 void FAR *out_desc;
00223 {
00224 struct inflate_state FAR *state;
00225 unsigned char FAR *next;
00226 unsigned char FAR *put;
00227 unsigned have;
00228 unsigned long left;
00229 inflate_mode mode;
00230 int lastblock;
00231 int wrap;
00232 unsigned long write;
00233 unsigned char FAR *window;
00234 unsigned long hold;
00235 unsigned bits;
00236 unsigned extra;
00237 unsigned long length;
00238 unsigned long offset;
00239 unsigned long copy;
00240 unsigned char FAR *from;
00241 code const FAR *lencode;
00242 code const FAR *distcode;
00243 unsigned lenbits;
00244 unsigned distbits;
00245 code this;
00246 code last;
00247 unsigned len;
00248 int ret;
00249 static const unsigned short order[19] =
00250 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
00251 #include "inffix9.h"
00252
00253
00254 if (strm == Z_NULL || strm->state == Z_NULL)
00255 return Z_STREAM_ERROR;
00256 state = (struct inflate_state FAR *)strm->state;
00257
00258
00259 strm->msg = Z_NULL;
00260 mode = TYPE;
00261 lastblock = 0;
00262 write = 0;
00263 wrap = 0;
00264 window = state->window;
00265 next = strm->next_in;
00266 have = next != Z_NULL ? strm->avail_in : 0;
00267 hold = 0;
00268 bits = 0;
00269 put = window;
00270 left = WSIZE;
00271 lencode = Z_NULL;
00272 distcode = Z_NULL;
00273
00274
00275 for (;;)
00276 switch (mode) {
00277 case TYPE:
00278
00279 if (lastblock) {
00280 BYTEBITS();
00281 mode = DONE;
00282 break;
00283 }
00284 NEEDBITS(3);
00285 lastblock = BITS(1);
00286 DROPBITS(1);
00287 switch (BITS(2)) {
00288 case 0:
00289 Tracev((stderr, "inflate: stored block%s\n",
00290 lastblock ? " (last)" : ""));
00291 mode = STORED;
00292 break;
00293 case 1:
00294 lencode = lenfix;
00295 lenbits = 9;
00296 distcode = distfix;
00297 distbits = 5;
00298 Tracev((stderr, "inflate: fixed codes block%s\n",
00299 lastblock ? " (last)" : ""));
00300 mode = LEN;
00301 break;
00302 case 2:
00303 Tracev((stderr, "inflate: dynamic codes block%s\n",
00304 lastblock ? " (last)" : ""));
00305 mode = TABLE;
00306 break;
00307 case 3:
00308 strm->msg = (char *)"invalid block type";
00309 mode = BAD;
00310 }
00311 DROPBITS(2);
00312 break;
00313
00314 case STORED:
00315
00316 BYTEBITS();
00317 NEEDBITS(32);
00318 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
00319 strm->msg = (char *)"invalid stored block lengths";
00320 mode = BAD;
00321 break;
00322 }
00323 length = (unsigned)hold & 0xffff;
00324 Tracev((stderr, "inflate: stored length %lu\n",
00325 length));
00326 INITBITS();
00327
00328
00329 while (length != 0) {
00330 copy = length;
00331 PULL();
00332 ROOM();
00333 if (copy > have) copy = have;
00334 if (copy > left) copy = left;
00335 zmemcpy(put, next, copy);
00336 have -= copy;
00337 next += copy;
00338 left -= copy;
00339 put += copy;
00340 length -= copy;
00341 }
00342 Tracev((stderr, "inflate: stored end\n"));
00343 mode = TYPE;
00344 break;
00345
00346 case TABLE:
00347
00348 NEEDBITS(14);
00349 state->nlen = BITS(5) + 257;
00350 DROPBITS(5);
00351 state->ndist = BITS(5) + 1;
00352 DROPBITS(5);
00353 state->ncode = BITS(4) + 4;
00354 DROPBITS(4);
00355 if (state->nlen > 286) {
00356 strm->msg = (char *)"too many length symbols";
00357 mode = BAD;
00358 break;
00359 }
00360 Tracev((stderr, "inflate: table sizes ok\n"));
00361
00362
00363 state->have = 0;
00364 while (state->have < state->ncode) {
00365 NEEDBITS(3);
00366 state->lens[order[state->have++]] = (unsigned short)BITS(3);
00367 DROPBITS(3);
00368 }
00369 while (state->have < 19)
00370 state->lens[order[state->have++]] = 0;
00371 state->next = state->codes;
00372 lencode = (code const FAR *)(state->next);
00373 lenbits = 7;
00374 ret = inflate_table9(CODES, state->lens, 19, &(state->next),
00375 &(lenbits), state->work);
00376 if (ret) {
00377 strm->msg = (char *)"invalid code lengths set";
00378 mode = BAD;
00379 break;
00380 }
00381 Tracev((stderr, "inflate: code lengths ok\n"));
00382
00383
00384 state->have = 0;
00385 while (state->have < state->nlen + state->ndist) {
00386 for (;;) {
00387 this = lencode[BITS(lenbits)];
00388 if ((unsigned)(this.bits) <= bits) break;
00389 PULLBYTE();
00390 }
00391 if (this.val < 16) {
00392 NEEDBITS(this.bits);
00393 DROPBITS(this.bits);
00394 state->lens[state->have++] = this.val;
00395 }
00396 else {
00397 if (this.val == 16) {
00398 NEEDBITS(this.bits + 2);
00399 DROPBITS(this.bits);
00400 if (state->have == 0) {
00401 strm->msg = (char *)"invalid bit length repeat";
00402 mode = BAD;
00403 break;
00404 }
00405 len = (unsigned)(state->lens[state->have - 1]);
00406 copy = 3 + BITS(2);
00407 DROPBITS(2);
00408 }
00409 else if (this.val == 17) {
00410 NEEDBITS(this.bits + 3);
00411 DROPBITS(this.bits);
00412 len = 0;
00413 copy = 3 + BITS(3);
00414 DROPBITS(3);
00415 }
00416 else {
00417 NEEDBITS(this.bits + 7);
00418 DROPBITS(this.bits);
00419 len = 0;
00420 copy = 11 + BITS(7);
00421 DROPBITS(7);
00422 }
00423 if (state->have + copy > state->nlen + state->ndist) {
00424 strm->msg = (char *)"invalid bit length repeat";
00425 mode = BAD;
00426 break;
00427 }
00428 while (copy--)
00429 state->lens[state->have++] = (unsigned short)len;
00430 }
00431 }
00432
00433
00434 if (mode == BAD) break;
00435
00436
00437 state->next = state->codes;
00438 lencode = (code const FAR *)(state->next);
00439 lenbits = 9;
00440 ret = inflate_table9(LENS, state->lens, state->nlen,
00441 &(state->next), &(lenbits), state->work);
00442 if (ret) {
00443 strm->msg = (char *)"invalid literal/lengths set";
00444 mode = BAD;
00445 break;
00446 }
00447 distcode = (code const FAR *)(state->next);
00448 distbits = 6;
00449 ret = inflate_table9(DISTS, state->lens + state->nlen,
00450 state->ndist, &(state->next), &(distbits),
00451 state->work);
00452 if (ret) {
00453 strm->msg = (char *)"invalid distances set";
00454 mode = BAD;
00455 break;
00456 }
00457 Tracev((stderr, "inflate: codes ok\n"));
00458 mode = LEN;
00459
00460 case LEN:
00461
00462 for (;;) {
00463 this = lencode[BITS(lenbits)];
00464 if ((unsigned)(this.bits) <= bits) break;
00465 PULLBYTE();
00466 }
00467 if (this.op && (this.op & 0xf0) == 0) {
00468 last = this;
00469 for (;;) {
00470 this = lencode[last.val +
00471 (BITS(last.bits + last.op) >> last.bits)];
00472 if ((unsigned)(last.bits + this.bits) <= bits) break;
00473 PULLBYTE();
00474 }
00475 DROPBITS(last.bits);
00476 }
00477 DROPBITS(this.bits);
00478 length = (unsigned)this.val;
00479
00480
00481 if (this.op == 0) {
00482 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
00483 "inflate: literal '%c'\n" :
00484 "inflate: literal 0x%02x\n", this.val));
00485 ROOM();
00486 *put++ = (unsigned char)(length);
00487 left--;
00488 mode = LEN;
00489 break;
00490 }
00491
00492
00493 if (this.op & 32) {
00494 Tracevv((stderr, "inflate: end of block\n"));
00495 mode = TYPE;
00496 break;
00497 }
00498
00499
00500 if (this.op & 64) {
00501 strm->msg = (char *)"invalid literal/length code";
00502 mode = BAD;
00503 break;
00504 }
00505
00506
00507 extra = (unsigned)(this.op) & 31;
00508 if (extra != 0) {
00509 NEEDBITS(extra);
00510 length += BITS(extra);
00511 DROPBITS(extra);
00512 }
00513 Tracevv((stderr, "inflate: length %lu\n", length));
00514
00515
00516 for (;;) {
00517 this = distcode[BITS(distbits)];
00518 if ((unsigned)(this.bits) <= bits) break;
00519 PULLBYTE();
00520 }
00521 if ((this.op & 0xf0) == 0) {
00522 last = this;
00523 for (;;) {
00524 this = distcode[last.val +
00525 (BITS(last.bits + last.op) >> last.bits)];
00526 if ((unsigned)(last.bits + this.bits) <= bits) break;
00527 PULLBYTE();
00528 }
00529 DROPBITS(last.bits);
00530 }
00531 DROPBITS(this.bits);
00532 if (this.op & 64) {
00533 strm->msg = (char *)"invalid distance code";
00534 mode = BAD;
00535 break;
00536 }
00537 offset = (unsigned)this.val;
00538
00539
00540 extra = (unsigned)(this.op) & 15;
00541 if (extra != 0) {
00542 NEEDBITS(extra);
00543 offset += BITS(extra);
00544 DROPBITS(extra);
00545 }
00546 if (offset > WSIZE - (wrap ? 0: left)) {
00547 strm->msg = (char *)"invalid distance too far back";
00548 mode = BAD;
00549 break;
00550 }
00551 Tracevv((stderr, "inflate: distance %lu\n", offset));
00552
00553
00554 do {
00555 ROOM();
00556 copy = WSIZE - offset;
00557 if (copy < left) {
00558 from = put + copy;
00559 copy = left - copy;
00560 }
00561 else {
00562 from = put - offset;
00563 copy = left;
00564 }
00565 if (copy > length) copy = length;
00566 length -= copy;
00567 left -= copy;
00568 do {
00569 *put++ = *from++;
00570 } while (--copy);
00571 } while (length != 0);
00572 break;
00573
00574 case DONE:
00575
00576 ret = Z_STREAM_END;
00577 if (left < WSIZE) {
00578 if (out(out_desc, window, (unsigned)(WSIZE - left)))
00579 ret = Z_BUF_ERROR;
00580 }
00581 goto inf_leave;
00582
00583 case BAD:
00584 ret = Z_DATA_ERROR;
00585 goto inf_leave;
00586
00587 default:
00588 ret = Z_STREAM_ERROR;
00589 goto inf_leave;
00590 }
00591
00592
00593 inf_leave:
00594 strm->next_in = next;
00595 strm->avail_in = have;
00596 return ret;
00597 }
00598
00599 int ZEXPORT inflateBack9End(strm)
00600 z_stream FAR *strm;
00601 {
00602 if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
00603 return Z_STREAM_ERROR;
00604 ZFREE(strm, strm->state);
00605 strm->state = Z_NULL;
00606 Tracev((stderr, "inflate: end\n"));
00607 return Z_OK;
00608 }