#ifndef _RAR_UNPACK_ #define _RAR_UNPACK_ // Maximum allowed number of compressed bits processed in quick mode. #define MAX_QUICK_DECODE_BITS 10 // Maximum number of filters per entire data block. #define MAX_UNPACK_FILTERS 8192 // Maximum number of filters per entire data block for RAR3 unpack. #define MAX3_FILTERS 1024 // Write data in 4 MB or smaller blocks. #define UNPACK_MAX_WRITE 0x400000 // Decode compressed bit fields to alphabet numbers. struct DecodeTable:PackDef { // Real size of DecodeNum table. uint MaxNum; // Left aligned start and upper limit codes defining code space // ranges for bit lengths. DecodeLen[BitLength-1] defines the start of // range for bit length and DecodeLen[BitLength] defines next code // after the end of range or in other words the upper limit code // for specified bit length. uint DecodeLen[16]; // Every item of this array contains the sum of all preceding items. // So it contains the start position in code list for every bit length. uint DecodePos[16]; // Number of compressed bits processed in quick mode. // Must not exceed MAX_QUICK_DECODE_BITS. uint QuickBits; // Translates compressed bits (up to QuickBits length) // to bit length in quick mode. byte QuickLen[1< FilterSrcMemory; Array FilterDstMemory; // Filters code, one entry per filter. Array Filters; uint OldDist[4],OldDistPtr; uint LastLength; // LastDist is necessary only for RAR2 and older with circular OldDist // array. In RAR3 last distance is always stored in OldDist[0]. uint LastDist; size_t UnpPtr,WrPtr; // Top border of read packed data. int ReadTop; // Border to call UnpReadBuf. We use it instead of (ReadTop-C) // for optimization reasons. Ensures that we have C bytes in buffer // unless we are at the end of file. int ReadBorder; UnpackBlockHeader BlockHeader; UnpackBlockTables BlockTables; size_t WriteBorder; byte *Window; FragmentedWindow FragWindow; bool Fragmented; int64 DestUnpSize; bool Suspended; bool UnpAllBuf; bool UnpSomeRead; int64 WrittenFileSize; bool FileExtracted; /***************************** Unpack v 1.5 *********************************/ void Unpack15(bool Solid); void ShortLZ(); void LongLZ(); void HuffDecode(); void GetFlagsBuf(); void UnpInitData15(int Solid); void InitHuff(); void CorrHuff(ushort *CharSet,byte *NumToPlace); void CopyString15(uint Distance,uint Length); uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab); ushort ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256]; byte NToPl[256],NToPlB[256],NToPlC[256]; uint FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3; int Buf60,NumHuf,StMode,LCount,FlagsCnt; uint Nhfb,Nlzb,MaxDist3; /***************************** Unpack v 1.5 *********************************/ /***************************** Unpack v 2.0 *********************************/ void Unpack20(bool Solid); DecodeTable MD[4]; // Decode multimedia data, up to 4 channels. unsigned char UnpOldTable20[MC20*4]; int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta; void CopyString20(uint Length,uint Distance); bool ReadTables20(); void UnpWriteBuf20(); void UnpInitData20(int Solid); void ReadLastTables(); byte DecodeAudio(int Delta); struct AudioVariables AudV[4]; /***************************** Unpack v 2.0 *********************************/ /***************************** Unpack v 3.0 *********************************/ enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM}; void UnpInitData30(bool Solid); void Unpack29(bool Solid); void InitFilters30(); bool ReadEndOfBlock(); bool ReadVMCode(); bool ReadVMCodePPM(); bool AddVMCode(uint FirstByte,byte *Code,int CodeSize); int SafePPMDecodeChar(); bool ReadTables30(); bool UnpReadBuf30(); void UnpWriteBuf30(); void ExecuteCode(VM_PreparedProgram *Prg); int PrevLowDist,LowDistRepCount; ModelPPM PPM; int PPMEscChar; byte UnpOldTable[HUFF_TABLE_SIZE30]; int UnpBlockType; bool TablesRead; // Virtual machine to execute filters code. RarVM VM; // Buffer to read VM filters code. We moved it here from AddVMCode // function to reduce time spent in BitInput constructor. BitInput VMCodeInp; // Filters code, one entry per filter. Array Filters30; // Filters stack, several entrances of same filter are possible. Array PrgStack; // Lengths of preceding data blocks, one length of one last block // for every filter. Used to reduce the size required to write // the data block length if lengths are repeating. Array OldFilterLengths; int LastFilter; /***************************** Unpack v 3.0 *********************************/ public: Unpack(ComprDataIO *DataIO); ~Unpack(); void Init(size_t WinSize,bool Solid); void DoUnpack(int Method,bool Solid); bool IsFileExtracted() {return(FileExtracted);} void SetDestSize(int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;} void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;} #ifdef RAR_SMP // More than 8 threads are unlikely to provide a noticeable gain // for unpacking, but would use the additional memory. void SetThreads(uint Threads) {MaxUserThreads=Min(Threads,8);} void UnpackDecode(UnpackThreadData &D); #endif size_t MaxWinSize; size_t MaxWinMask; uint GetChar() { if (Inp.InAddr>BitInput::MAX_SIZE-30) UnpReadBuf(); return(Inp.InBuf[Inp.InAddr++]); } }; #endif