| 533 | |
| 534 | |
| 535 | bool Unpack::ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header) |
| 536 | { |
| 537 | Header.HeaderSize=0; |
| 538 | |
| 539 | if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-7) |
| 540 | if (!UnpReadBuf()) |
| 541 | return false; |
| 542 | Inp.faddbits((8-Inp.InBit)&7); |
| 543 | |
| 544 | byte BlockFlags=Inp.fgetbits()>>8; |
| 545 | Inp.faddbits(8); |
| 546 | uint ByteCount=((BlockFlags>>3)&3)+1; // Block size byte count. |
| 547 | |
| 548 | if (ByteCount==4) |
| 549 | return false; |
| 550 | |
| 551 | Header.HeaderSize=2+ByteCount; |
| 552 | |
| 553 | Header.BlockBitSize=(BlockFlags&7)+1; |
| 554 | |
| 555 | byte SavedCheckSum=Inp.fgetbits()>>8; |
| 556 | Inp.faddbits(8); |
| 557 | |
| 558 | int BlockSize=0; |
| 559 | for (uint I=0;I<ByteCount;I++) |
| 560 | { |
| 561 | BlockSize+=(Inp.fgetbits()>>8)<<(I*8); |
| 562 | Inp.addbits(8); |
| 563 | } |
| 564 | |
| 565 | Header.BlockSize=BlockSize; |
| 566 | byte CheckSum=byte(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16)); |
| 567 | if (CheckSum!=SavedCheckSum) |
| 568 | return false; |
| 569 | |
| 570 | Header.BlockStart=Inp.InAddr; |
| 571 | ReadBorder=Min(ReadBorder,Header.BlockStart+Header.BlockSize-1); |
| 572 | |
| 573 | Header.LastBlockInFile=(BlockFlags & 0x40)!=0; |
| 574 | Header.TablePresent=(BlockFlags & 0x80)!=0; |
| 575 | return true; |
| 576 | } |
| 577 | |
| 578 | |
| 579 | bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables) |