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