"Fossies" - the Fresh Open Source Software Archive

Member "unrar/unpack.hpp" (4 May 2022, 11678 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "unpack.hpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 6.1.2_vs_6.1.3.

    1 #ifndef _RAR_UNPACK_
    2 #define _RAR_UNPACK_
    3 
    4 // Maximum allowed number of compressed bits processed in quick mode.
    5 #define MAX_QUICK_DECODE_BITS      10
    6 
    7 // Maximum number of filters per entire data block. Must be at least
    8 // twice more than MAX_PACK_FILTERS to store filters from two data blocks.
    9 #define MAX_UNPACK_FILTERS       8192
   10 
   11 // Maximum number of filters per entire data block for RAR3 unpack.
   12 // Must be at least twice more than v3_MAX_PACK_FILTERS to store filters
   13 // from two data blocks.
   14 #define MAX3_UNPACK_FILTERS      8192
   15 
   16 // Limit maximum number of channels in RAR3 delta filter to some reasonable
   17 // value to prevent too slow processing of corrupt archives with invalid
   18 // channels number. Must be equal or larger than v3_MAX_FILTER_CHANNELS.
   19 // No need to provide it for RAR5, which uses only 5 bits to store channels.
   20 #define MAX3_UNPACK_CHANNELS      1024
   21 
   22 // Maximum size of single filter block. We restrict it to limit memory
   23 // allocation. Must be equal or larger than MAX_ANALYZE_SIZE.
   24 #define MAX_FILTER_BLOCK_SIZE 0x400000
   25 
   26 // Write data in 4 MB or smaller blocks. Must not exceed PACK_MAX_READ,
   27 // so we keep the number of buffered filters in unpacker reasonable.
   28 #define UNPACK_MAX_WRITE      0x400000
   29 
   30 // Decode compressed bit fields to alphabet numbers.
   31 struct DecodeTable:PackDef
   32 {
   33   // Real size of DecodeNum table.
   34   uint MaxNum;
   35 
   36   // Left aligned start and upper limit codes defining code space 
   37   // ranges for bit lengths. DecodeLen[BitLength-1] defines the start of
   38   // range for bit length and DecodeLen[BitLength] defines next code
   39   // after the end of range or in other words the upper limit code
   40   // for specified bit length.
   41   uint DecodeLen[16]; 
   42 
   43   // Every item of this array contains the sum of all preceding items.
   44   // So it contains the start position in code list for every bit length. 
   45   uint DecodePos[16];
   46 
   47   // Number of compressed bits processed in quick mode.
   48   // Must not exceed MAX_QUICK_DECODE_BITS.
   49   uint QuickBits;
   50 
   51   // Translates compressed bits (up to QuickBits length)
   52   // to bit length in quick mode.
   53   byte QuickLen[1<<MAX_QUICK_DECODE_BITS];
   54 
   55   // Translates compressed bits (up to QuickBits length)
   56   // to position in alphabet in quick mode.
   57   // 'ushort' saves some memory and even provides a little speed gain
   58   // comparting to 'uint' here.
   59   ushort QuickNum[1<<MAX_QUICK_DECODE_BITS];
   60 
   61   // Translate the position in code list to position in alphabet.
   62   // We do not allocate it dynamically to avoid performance overhead
   63   // introduced by pointer, so we use the largest possible table size
   64   // as array dimension. Real size of this array is defined in MaxNum.
   65   // We use this array if compressed bit field is too lengthy
   66   // for QuickLen based translation.
   67   // 'ushort' saves some memory and even provides a little speed gain
   68   // comparting to 'uint' here.
   69   ushort DecodeNum[LARGEST_TABLE_SIZE];
   70 };
   71 
   72 
   73 struct UnpackBlockHeader
   74 {
   75   int BlockSize;
   76   int BlockBitSize;
   77   int BlockStart;
   78   int HeaderSize;
   79   bool LastBlockInFile;
   80   bool TablePresent;
   81 };
   82 
   83 
   84 struct UnpackBlockTables
   85 {
   86   DecodeTable LD;  // Decode literals.
   87   DecodeTable DD;  // Decode distances.
   88   DecodeTable LDD; // Decode lower bits of distances.
   89   DecodeTable RD;  // Decode repeating distances.
   90   DecodeTable BD;  // Decode bit lengths in Huffman table.
   91 };
   92 
   93 
   94 #ifdef RAR_SMP
   95 enum UNP_DEC_TYPE {
   96   UNPDT_LITERAL,UNPDT_MATCH,UNPDT_FULLREP,UNPDT_REP,UNPDT_FILTER
   97 };
   98 
   99 struct UnpackDecodedItem
  100 {
  101   UNP_DEC_TYPE Type;
  102   ushort Length;
  103   union
  104   {
  105     uint Distance;
  106     byte Literal[4];
  107   };
  108 };
  109 
  110 
  111 struct UnpackThreadData
  112 {
  113   Unpack *UnpackPtr;
  114   BitInput Inp;
  115   bool HeaderRead;
  116   UnpackBlockHeader BlockHeader;
  117   bool TableRead;
  118   UnpackBlockTables BlockTables;
  119   int DataSize;    // Data left in buffer. Can be less than block size.
  120   bool DamagedData;
  121   bool LargeBlock;
  122   bool NoDataLeft; // 'true' if file is read completely.
  123   bool Incomplete; // Not entire block was processed, need to read more data.
  124 
  125   UnpackDecodedItem *Decoded;
  126   uint DecodedSize;
  127   uint DecodedAllocated;
  128   uint ThreadNumber; // For debugging.
  129 
  130   UnpackThreadData()
  131   :Inp(false)
  132   {
  133     Decoded=NULL;
  134   }
  135   ~UnpackThreadData()
  136   {
  137     if (Decoded!=NULL)
  138       free(Decoded);
  139   }
  140 };
  141 #endif
  142 
  143 
  144 struct UnpackFilter
  145 {
  146   byte Type;
  147   uint BlockStart;
  148   uint BlockLength;
  149   byte Channels;
  150 //  uint Width;
  151 //  byte PosR;
  152   bool NextWindow;
  153 };
  154 
  155 
  156 struct UnpackFilter30
  157 {
  158   unsigned int BlockStart;
  159   unsigned int BlockLength;
  160   bool NextWindow;
  161 
  162   // Position of parent filter in Filters array used as prototype for filter
  163   // in PrgStack array. Not defined for filters in Filters array.
  164   unsigned int ParentFilter;
  165 
  166   VM_PreparedProgram Prg;
  167 };
  168 
  169 
  170 struct AudioVariables // For RAR 2.0 archives only.
  171 {
  172   int K1,K2,K3,K4,K5;
  173   int D1,D2,D3,D4;
  174   int LastDelta;
  175   unsigned int Dif[11];
  176   unsigned int ByteCount;
  177   int LastChar;
  178 };
  179 
  180 
  181 // We can use the fragmented dictionary in case heap does not have the single
  182 // large enough memory block. It is slower than normal dictionary.
  183 class FragmentedWindow
  184 {
  185   private:
  186     enum {MAX_MEM_BLOCKS=32};
  187 
  188     void Reset();
  189     byte *Mem[MAX_MEM_BLOCKS];
  190     size_t MemSize[MAX_MEM_BLOCKS];
  191   public:
  192     FragmentedWindow();
  193     ~FragmentedWindow();
  194     void Init(size_t WinSize);
  195     byte& operator [](size_t Item);
  196     void CopyString(uint Length,uint Distance,size_t &UnpPtr,size_t MaxWinMask);
  197     void CopyData(byte *Dest,size_t WinPos,size_t Size);
  198     size_t GetBlockSize(size_t StartPos,size_t RequiredSize);
  199 };
  200 
  201 
  202 class Unpack:PackDef
  203 {
  204   private:
  205 
  206     void Unpack5(bool Solid);
  207     void Unpack5MT(bool Solid);
  208     bool UnpReadBuf();
  209     void UnpWriteBuf();
  210     byte* ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt);
  211     void UnpWriteArea(size_t StartPtr,size_t EndPtr);
  212     void UnpWriteData(byte *Data,size_t Size);
  213     _forceinline uint SlotToLength(BitInput &Inp,uint Slot);
  214     void UnpInitData50(bool Solid);
  215     bool ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header);
  216     bool ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables);
  217     void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size);
  218     _forceinline uint DecodeNumber(BitInput &Inp,DecodeTable *Dec);
  219     void CopyString();
  220     inline void InsertOldDist(unsigned int Distance);
  221     void UnpInitData(bool Solid);
  222     _forceinline void CopyString(uint Length,uint Distance);
  223     uint ReadFilterData(BitInput &Inp);
  224     bool ReadFilter(BitInput &Inp,UnpackFilter &Filter);
  225     bool AddFilter(UnpackFilter &Filter);
  226     bool AddFilter();
  227     void InitFilters();
  228 
  229     ComprDataIO *UnpIO;
  230     BitInput Inp;
  231 
  232 #ifdef RAR_SMP
  233     void InitMT();
  234     bool UnpackLargeBlock(UnpackThreadData &D);
  235     bool ProcessDecoded(UnpackThreadData &D);
  236 
  237     ThreadPool *UnpThreadPool;
  238     UnpackThreadData *UnpThreadData;
  239     uint MaxUserThreads;
  240     byte *ReadBufMT;
  241 #endif
  242 
  243     Array<byte> FilterSrcMemory;
  244     Array<byte> FilterDstMemory;
  245 
  246     // Filters code, one entry per filter.
  247     Array<UnpackFilter> Filters;
  248 
  249     uint OldDist[4],OldDistPtr;
  250     uint LastLength;
  251 
  252     // LastDist is necessary only for RAR2 and older with circular OldDist
  253     // array. In RAR3 last distance is always stored in OldDist[0].
  254     uint LastDist;
  255 
  256     size_t UnpPtr,WrPtr;
  257     
  258     // Top border of read packed data.
  259     int ReadTop; 
  260 
  261     // Border to call UnpReadBuf. We use it instead of (ReadTop-C)
  262     // for optimization reasons. Ensures that we have C bytes in buffer
  263     // unless we are at the end of file.
  264     int ReadBorder;
  265 
  266     UnpackBlockHeader BlockHeader;
  267     UnpackBlockTables BlockTables;
  268 
  269     size_t WriteBorder;
  270 
  271     byte *Window;
  272 
  273     FragmentedWindow FragWindow;
  274     bool Fragmented;
  275 
  276 
  277     int64 DestUnpSize;
  278 
  279     bool Suspended;
  280     bool UnpAllBuf;
  281     bool UnpSomeRead;
  282     int64 WrittenFileSize;
  283     bool FileExtracted;
  284 
  285 
  286 /***************************** Unpack v 1.5 *********************************/
  287     void Unpack15(bool Solid);
  288     void ShortLZ();
  289     void LongLZ();
  290     void HuffDecode();
  291     void GetFlagsBuf();
  292     void UnpInitData15(int Solid);
  293     void InitHuff();
  294     void CorrHuff(ushort *CharSet,byte *NumToPlace);
  295     void CopyString15(uint Distance,uint Length);
  296     uint DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab);
  297 
  298     ushort ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
  299     byte NToPl[256],NToPlB[256],NToPlC[256];
  300     uint FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
  301     int Buf60,NumHuf,StMode,LCount,FlagsCnt;
  302     uint Nhfb,Nlzb,MaxDist3;
  303 /***************************** Unpack v 1.5 *********************************/
  304 
  305 /***************************** Unpack v 2.0 *********************************/
  306     void Unpack20(bool Solid);
  307 
  308     DecodeTable MD[4]; // Decode multimedia data, up to 4 channels.
  309 
  310     unsigned char UnpOldTable20[MC20*4];
  311     bool UnpAudioBlock;
  312     uint UnpChannels,UnpCurChannel;
  313     int UnpChannelDelta;
  314     void CopyString20(uint Length,uint Distance);
  315     bool ReadTables20();
  316     void UnpWriteBuf20();
  317     void UnpInitData20(int Solid);
  318     void ReadLastTables();
  319     byte DecodeAudio(int Delta);
  320     struct AudioVariables AudV[4];
  321 /***************************** Unpack v 2.0 *********************************/
  322 
  323 /***************************** Unpack v 3.0 *********************************/
  324     enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM};
  325 
  326     void UnpInitData30(bool Solid);
  327     void Unpack29(bool Solid);
  328     void InitFilters30(bool Solid);
  329     bool ReadEndOfBlock();
  330     bool ReadVMCode();
  331     bool ReadVMCodePPM();
  332     bool AddVMCode(uint FirstByte,byte *Code,uint CodeSize);
  333     int SafePPMDecodeChar();
  334     bool ReadTables30();
  335     bool UnpReadBuf30();
  336     void UnpWriteBuf30();
  337     void ExecuteCode(VM_PreparedProgram *Prg);
  338 
  339     int PrevLowDist,LowDistRepCount;
  340 
  341     ModelPPM PPM;
  342     int PPMEscChar;
  343 
  344     byte UnpOldTable[HUFF_TABLE_SIZE30];
  345     int UnpBlockType;
  346 
  347     // If we already read decoding tables for Unpack v2,v3,v5.
  348     // We should not use a single variable for all algorithm versions,
  349     // because we can have a corrupt archive with one algorithm file
  350     // followed by another algorithm file with "solid" flag and we do not
  351     // want to reuse tables from one algorithm in another.
  352     bool TablesRead2,TablesRead3,TablesRead5;
  353 
  354     // Virtual machine to execute filters code.
  355     RarVM VM;
  356   
  357     // Buffer to read VM filters code. We moved it here from AddVMCode
  358     // function to reduce time spent in BitInput constructor.
  359     BitInput VMCodeInp;
  360 
  361     // Filters code, one entry per filter.
  362     Array<UnpackFilter30 *> Filters30;
  363 
  364     // Filters stack, several entrances of same filter are possible.
  365     Array<UnpackFilter30 *> PrgStack;
  366 
  367     // Lengths of preceding data blocks, one length of one last block
  368     // for every filter. Used to reduce the size required to write
  369     // the data block length if lengths are repeating.
  370     Array<int> OldFilterLengths;
  371 
  372     int LastFilter;
  373 /***************************** Unpack v 3.0 *********************************/
  374 
  375   public:
  376     Unpack(ComprDataIO *DataIO);
  377     ~Unpack();
  378     void Init(size_t WinSize,bool Solid);
  379     void DoUnpack(uint Method,bool Solid);
  380     bool IsFileExtracted() {return(FileExtracted);}
  381     void SetDestSize(int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
  382     void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;}
  383 
  384 #ifdef RAR_SMP
  385     void SetThreads(uint Threads);
  386     void UnpackDecode(UnpackThreadData &D);
  387 #endif
  388 
  389     size_t MaxWinSize;
  390     size_t MaxWinMask;
  391 
  392     uint GetChar()
  393     {
  394       if (Inp.InAddr>BitInput::MAX_SIZE-30)
  395       {
  396         UnpReadBuf();
  397         if (Inp.InAddr>=BitInput::MAX_SIZE) // If nothing was read.
  398           return 0;
  399       }
  400       return Inp.InBuf[Inp.InAddr++];
  401     }
  402 };
  403 
  404 #endif