void Unpack::Unpack29(bool Solid) { static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; static int DDecode[DC]; static byte DBits[DC]; static unsigned int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12}; static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6}; unsigned int Bits; if (DDecode[1]==0) { int Dist=0,BitLength=0,Slot=0; for (unsigned int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++) for (unsigned int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength)) { DDecode[Slot]=Dist; DBits[Slot]=BitLength; } } FileExtracted=true; if (!Suspended) { UnpInitData(Solid); if (!UnpReadBuf()) return; if (!TablesRead) if (!ReadTables()) return; // if (!TablesRead && Solid) // if (!ReadTables()) // return; //if ((!Solid || !TablesRead) && !ReadTables()) // return; } if (PPMError) return; while (true) { if (UnpIO->bQuit) { FileExtracted=false; return; } UnpPtr&=MAXWINMASK; if (InAddr>ReadBorder) { if (!UnpReadBuf()) break; } if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr) { UnpWriteBuf(); if (WrittenFileSize>DestUnpSize) return; if (Suspended) { FileExtracted=false; return; } } if (UnpBlockType==BLOCK_PPM) { int Ch=PPM.DecodeChar(); if (Ch==-1) { PPMError=true; break; } if (Ch==PPMEscChar) { int NextCh=PPM.DecodeChar(); if (NextCh==0) { if (!ReadTables()) break; continue; } if (NextCh==2 || NextCh==-1) break; if (NextCh==3) { if (!ReadVMCodePPM()) break; continue; } if (NextCh==4) { unsigned int Distance=0,Length=0; bool Failed=false; for (int I=0;I<4 && !Failed;I++) { int Ch=PPM.DecodeChar(); if (Ch==-1) Failed=true; else if (I==3) Length=(byte)Ch; else Distance=(Distance<<8)+(byte)Ch; } if (Failed) break; CopyString(Length+32,Distance+2); continue; } if (NextCh==5) { int Length=PPM.DecodeChar(); if (Length==-1) break; CopyString(Length+4,1); continue; } } Window[UnpPtr++]=Ch; continue; } int Number=DecodeNumber((struct Decode *)&LD); if (Number<256) { Window[UnpPtr++]=(byte)Number; continue; } if (Number>=271) { int Length=LDecode[Number-=271]+3; if ((Bits=LBits[Number])>0) { Length+=getbits()>>(16-Bits); addbits(Bits); } int DistNumber=DecodeNumber((struct Decode *)&DD); unsigned int Distance=DDecode[DistNumber]+1; if ((Bits=DBits[DistNumber])>0) { if (DistNumber>9) { if (Bits>4) { Distance+=((getbits()>>(20-Bits))<<4); addbits(Bits-4); } if (LowDistRepCount>0) { LowDistRepCount--; Distance+=PrevLowDist; } else { int LowDist=DecodeNumber((struct Decode *)&LDD); if (LowDist==16) { LowDistRepCount=LOW_DIST_REP_COUNT-1; Distance+=PrevLowDist; } else { Distance+=LowDist; PrevLowDist=LowDist; } } } else {
void Unpack::Unpack5(bool Solid) { FileExtracted=true; if (!Suspended) { UnpInitData(Solid); if (!UnpReadBuf()) return; if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables)) return; } while (true) { UnpPtr&=MaxWinMask; if (Inp.InAddr>=ReadBorder) { bool FileDone=false; // We use 'while', because for empty block containing only Huffman table, // we'll be on the block border once again just after reading the table. while (Inp.InAddr>BlockHeader.BlockStart+BlockHeader.BlockSize-1 || Inp.InAddr==BlockHeader.BlockStart+BlockHeader.BlockSize-1 && Inp.InBit>=BlockHeader.BlockBitSize) { if (BlockHeader.LastBlockInFile) { FileDone=true; break; } if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables)) return; } if (FileDone || !UnpReadBuf()) break; } if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_LZ_MATCH+3 && WriteBorder!=UnpPtr) { UnpWriteBuf(); if (WrittenFileSize>DestUnpSize) return; if (Suspended) { FileExtracted=false; return; } } uint MainSlot=DecodeNumber(Inp,&BlockTables.LD); if (MainSlot<256) { if (Fragmented) FragWindow[UnpPtr++]=(byte)MainSlot; else Window[UnpPtr++]=(byte)MainSlot; continue; } if (MainSlot>=262) { uint Length=SlotToLength(Inp,MainSlot-262); uint DBits,Distance=1,DistSlot=DecodeNumber(Inp,&BlockTables.DD); if (DistSlot<4) { DBits=0; Distance+=DistSlot; } else { DBits=DistSlot/2 - 1; Distance+=(2 | (DistSlot & 1)) << DBits; } if (DBits>0) { if (DBits>=4) { if (DBits>4) { Distance+=((Inp.getbits32()>>(36-DBits))<<4); Inp.addbits(DBits-4); } uint LowDist=DecodeNumber(Inp,&BlockTables.LDD); Distance+=LowDist; } else { Distance+=Inp.getbits32()>>(32-DBits); Inp.addbits(DBits); } }
void Unpack::Unpack20(bool Solid) { static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6}; unsigned int Bits; if (Suspended) UnpPtr=WrPtr; else { UnpInitData(Solid); if (!UnpReadBuf()) return; if (!Solid) if (!ReadTables20()) return; --DestUnpSize; } while (DestUnpSize>=0) { UnpPtr&=MAXWINMASK; if (InAddr>ReadTop-30) if (!UnpReadBuf()) break; if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr) { OldUnpWriteBuf(); if (Suspended) return; } if (UnpAudioBlock) { int AudioNumber=DecodeNumber(&MD[UnpCurChannel]); if (AudioNumber==256) { if (!ReadTables20()) break; continue; } Window[UnpPtr++]=DecodeAudio(AudioNumber); if (++UnpCurChannel==UnpChannels) UnpCurChannel=0; --DestUnpSize; continue; } int Number=DecodeNumber(&LD); if (Number<256) { Window[UnpPtr++]=(byte)Number; --DestUnpSize; continue; } if (Number>269) { int Length=LDecode[Number-=270]+3; if ((Bits=LBits[Number])>0) { Length+=getbits()>>(16-Bits); addbits(Bits); } int DistNumber=DecodeNumber(&DD); unsigned int Distance=DDecode[DistNumber]+1; if ((Bits=DBits[DistNumber])>0) { Distance+=getbits()>>(16-Bits); addbits(Bits); }
void Unpack::Unpack29(bool Solid) { // tables moved outside function unsigned int Bits; FileExtracted=true; if (!Suspended) { UnpInitData(Solid); if (!UnpReadBuf()) return; if ((!Solid || !TablesRead) && !ReadTables()) return; } while (true) { UnpPtr&=MAXWINMASK; if (InAddr>ReadBorder) { if (!UnpReadBuf()) break; } if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr) { UnpWriteBuf(); if (WrittenFileSize>DestUnpSize) return; if (Suspended) { FileExtracted=false; return; } } if (UnpBlockType==BLOCK_PPM) { int Ch=PPM.DecodeChar(); if (Ch==-1) { PPM.CleanUp(); // turn off PPM compression mode in case of error, so UnRAR will // call PPM.DecodeInit in case it needs to turn it on back later. UnpBlockType=BLOCK_LZ; break; } if (Ch==PPMEscChar) { int NextCh=PPM.DecodeChar(); if (NextCh==0) { if (!ReadTables()) break; continue; } if (NextCh==2 || NextCh==-1) break; if (NextCh==3) { if (!ReadVMCodePPM()) break; continue; } if (NextCh==4) { unsigned int Distance=0,Length; Length = 0; // avoids warning bool Failed=false; for (int I=0;I<4 && !Failed;I++) { int Ch=PPM.DecodeChar(); if (Ch==-1) Failed=true; else if (I==3) Length=(byte)Ch; else Distance=(Distance<<8)+(byte)Ch; } if (Failed) break; #ifdef _MSC_VER // avoid a warning about uninitialized 'Length' variable #pragma warning( disable : 4701 ) #endif CopyString(Length+32,Distance+2); continue; } if (NextCh==5) { int Length=PPM.DecodeChar(); if (Length==-1) break; CopyString(Length+4,1); continue; } } Window[UnpPtr++]=Ch; continue; } int Number=DecodeNumber((struct Decode *)&LD); if (Number<256) { Window[UnpPtr++]=(byte)Number; continue; } if (Number>=271) { int Length=LDecode[Number-=271]+3; if ((Bits=LBits[Number])>0) { Length+=getbits()>>(16-Bits); addbits(Bits); } int DistNumber=DecodeNumber((struct Decode *)&DD); unsigned int Distance=DDecode[DistNumber]+1; if ((Bits=DBits[DistNumber])>0) { if (DistNumber>9) { if (Bits>4) { Distance+=((getbits()>>(20-Bits))<<4); addbits(Bits-4); } if (LowDistRepCount>0) { LowDistRepCount--; Distance+=PrevLowDist; } else { int LowDist=DecodeNumber((struct Decode *)&LDD); if (LowDist==16) { LowDistRepCount=LOW_DIST_REP_COUNT-1; Distance+=PrevLowDist; } else { Distance+=LowDist; PrevLowDist=LowDist; } } } else {
unsigned int GetChar() { if (InAddr>BitInput::MAX_SIZE-30) UnpReadBuf(); return(InBuf[InAddr++]); }
void Unpack::Unpack29(bool Solid) { static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; static int DDecode[DC]; static byte DBits[DC]; static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12}; static unsigned char SDDecode[]={0,4,8,16,32,64,128,192}; static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6}; unsigned int Bits; if (DDecode[1]==0) { int Dist=0,BitLength=0,Slot=0; for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++) for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength)) { DDecode[Slot]=Dist; DBits[Slot]=BitLength; } } FileExtracted=true; if (!Suspended) { UnpInitData(Solid); if (!UnpReadBuf()) return; if ((!Solid || !TablesRead) && !ReadTables()) return; } while (true) { UnpPtr&=MAXWINMASK; if (InAddr>ReadBorder) { if (!UnpReadBuf()) break; } if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr) { UnpWriteBuf(); if (WrittenFileSize>DestUnpSize) return; if (Suspended) { FileExtracted=false; return; } } if (UnpBlockType==BLOCK_PPM) { // Here speed is critical, so we do not use SafePPMDecodeChar, // because sometimes even the inline function can introduce // some additional penalty. int Ch=PPM.DecodeChar(); if (Ch==-1) // Corrupt PPM data found. { PPM.CleanUp(); // Reset possibly corrupt PPM data structures. UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode. break; } if (Ch==PPMEscChar) { int NextCh=SafePPMDecodeChar(); if (NextCh==0) // End of PPM encoding. { if (!ReadTables()) break; continue; } if (NextCh==-1) // Corrupt PPM data found. break; if (NextCh==2) // End of file in PPM mode.. break; if (NextCh==3) // Read VM code. { if (!ReadVMCodePPM()) break; continue; } if (NextCh==4) // LZ inside of PPM. { unsigned int Distance=0,Length; bool Failed=false; for (int I=0;I<4 && !Failed;I++) { int Ch=SafePPMDecodeChar(); if (Ch==-1) Failed=true; else if (I==3) Length=(byte)Ch; else Distance=(Distance<<8)+(byte)Ch; } if (Failed) break; CopyString(Length+32,Distance+2); continue; } if (NextCh==5) // One byte distance match (RLE) inside of PPM. { int Length=SafePPMDecodeChar(); if (Length==-1) break; CopyString(Length+4,1); continue; } // If we are here, NextCh must be 1, what means that current byte // is equal to our 'escape' byte, so we just store it to Window. } Window[UnpPtr++]=Ch; continue; } int Number=DecodeNumber((struct Decode *)&LD); if (Number<256) { Window[UnpPtr++]=(byte)Number; continue; } if (Number>=271) { int Length=LDecode[Number-=271]+3; if ((Bits=LBits[Number])>0) { Length+=getbits()>>(16-Bits); addbits(Bits); } int DistNumber=DecodeNumber((struct Decode *)&DD); unsigned int Distance=DDecode[DistNumber]+1; if ((Bits=DBits[DistNumber])>0) { if (DistNumber>9) { if (Bits>4) { Distance+=((getbits()>>(20-Bits))<<4); addbits(Bits-4); } if (LowDistRepCount>0) { LowDistRepCount--; Distance+=PrevLowDist; } else { int LowDist=DecodeNumber((struct Decode *)&LDD); if (LowDist==16) { LowDistRepCount=LOW_DIST_REP_COUNT-1; Distance+=PrevLowDist; } else { Distance+=LowDist; PrevLowDist=LowDist; } } } else {