other-licenses/7zstub/src/7zip/Compress/LZMA/LZMADecoder.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 // LZMA/Decoder.h
     3 #ifndef __LZMA_DECODER_H
     4 #define __LZMA_DECODER_H
     6 #include "../../../Common/MyCom.h"
     7 #include "../../../Common/Alloc.h"
     8 #include "../../ICoder.h"
     9 #include "../LZ/LZOutWindow.h"
    10 #include "../RangeCoder/RangeCoderBitTree.h"
    12 #include "LZMA.h"
    14 namespace NCompress {
    15 namespace NLZMA {
    17 typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
    19 class CLiteralDecoder2
    20 {
    21   CMyBitDecoder _decoders[0x300];
    22 public:
    23   void Init()
    24   {
    25     for (int i = 0; i < 0x300; i++)
    26       _decoders[i].Init();
    27   }
    28   Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
    29   {
    30     UInt32 symbol = 1;
    31     RC_INIT_VAR
    32     do
    33     {
    34       // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
    35       RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
    36     }
    37     while (symbol < 0x100);
    38     RC_FLUSH_VAR
    39     return (Byte)symbol;
    40   }
    41   Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
    42   {
    43     UInt32 symbol = 1;
    44     RC_INIT_VAR
    45     do
    46     {
    47       UInt32 matchBit = (matchByte >> 7) & 1;
    48       matchByte <<= 1;
    49       // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
    50       // symbol = (symbol << 1) | bit;
    51       UInt32 bit;
    52       RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, 
    53           bit = 0, bit = 1)
    54       if (matchBit != bit)
    55       {
    56         while (symbol < 0x100)
    57         {
    58           // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
    59           RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
    60         }
    61         break;
    62       }
    63     }
    64     while (symbol < 0x100);
    65     RC_FLUSH_VAR
    66     return (Byte)symbol;
    67   }
    68 };
    70 class CLiteralDecoder
    71 {
    72   CLiteralDecoder2 *_coders;
    73   int _numPrevBits;
    74   int _numPosBits;
    75   UInt32 _posMask;
    76 public:
    77   CLiteralDecoder(): _coders(0) {}
    78   ~CLiteralDecoder()  { Free(); }
    79   void Free()
    80   { 
    81     MyFree(_coders);
    82     _coders = 0;
    83   }
    84   bool Create(int numPosBits, int numPrevBits)
    85   {
    86     if (_coders == 0 || (numPosBits + numPrevBits) != 
    87         (_numPrevBits + _numPosBits) )
    88     {
    89       Free();
    90       UInt32 numStates = 1 << (numPosBits + numPrevBits);
    91       _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
    92     }
    93     _numPosBits = numPosBits;
    94     _posMask = (1 << numPosBits) - 1;
    95     _numPrevBits = numPrevBits;
    96     return (_coders != 0);
    97   }
    98   void Init()
    99   {
   100     UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
   101     for (UInt32 i = 0; i < numStates; i++)
   102       _coders[i].Init();
   103   }
   104   UInt32 GetState(UInt32 pos, Byte prevByte) const
   105     { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
   106   Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
   107     { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
   108   Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
   109     { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
   110 };
   112 namespace NLength {
   114 class CDecoder
   115 {
   116   CMyBitDecoder _choice;
   117   CMyBitDecoder _choice2;
   118   NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits>  _lowCoder[kNumPosStatesMax];
   119   NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits>  _midCoder[kNumPosStatesMax];
   120   NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder; 
   121 public:
   122   void Init(UInt32 numPosStates)
   123   {
   124     _choice.Init();
   125     _choice2.Init();
   126     for (UInt32 posState = 0; posState < numPosStates; posState++)
   127     {
   128       _lowCoder[posState].Init();
   129       _midCoder[posState].Init();
   130     }
   131     _highCoder.Init();
   132   }
   133   UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
   134   {
   135     if(_choice.Decode(rangeDecoder) == 0)
   136       return _lowCoder[posState].Decode(rangeDecoder);
   137     if(_choice2.Decode(rangeDecoder) == 0)
   138       return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
   139     return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
   140   }
   141 };
   143 }
   145 class CDecoder: 
   146   public ICompressCoder,
   147   public ICompressSetDecoderProperties2,
   148   public ICompressGetInStreamProcessedSize,
   149   #ifdef _ST_MODE
   150   public ICompressSetInStream,
   151   public ICompressSetOutStreamSize,
   152   public ISequentialInStream,
   153   #endif
   154   public CMyUnknownImp
   155 {
   156   CLZOutWindow _outWindowStream;
   157   NRangeCoder::CDecoder _rangeDecoder;
   159   CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
   160   CMyBitDecoder _isRep[kNumStates];
   161   CMyBitDecoder _isRepG0[kNumStates];
   162   CMyBitDecoder _isRepG1[kNumStates];
   163   CMyBitDecoder _isRepG2[kNumStates];
   164   CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
   166   NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
   168   CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
   169   NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
   171   NLength::CDecoder _lenDecoder;
   172   NLength::CDecoder _repMatchLenDecoder;
   174   CLiteralDecoder _literalDecoder;
   176   UInt32 _posStateMask;
   178   ///////////////////
   179   // State
   180   UInt32 _reps[4];
   181   CState _state;
   182   Int32 _remainLen; // -1 means end of stream. // -2 means need Init
   183   UInt64 _outSize;
   184   bool _outSizeDefined;
   186   void Init();
   187   HRESULT CodeSpec(UInt32 size);
   188 public:
   190   #ifdef _ST_MODE
   191   MY_UNKNOWN_IMP5(
   192       ICompressSetDecoderProperties2, 
   193       ICompressGetInStreamProcessedSize,
   194       ICompressSetInStream, 
   195       ICompressSetOutStreamSize, 
   196       ISequentialInStream)
   197   #else
   198   MY_UNKNOWN_IMP2(
   199       ICompressSetDecoderProperties2,
   200       ICompressGetInStreamProcessedSize)
   201   #endif
   203   void ReleaseStreams()
   204   {
   205     _outWindowStream.ReleaseStream();
   206     ReleaseInStream();
   207   }
   209   class CDecoderFlusher
   210   {
   211     CDecoder *_decoder;
   212   public:
   213     bool NeedFlush;
   214     CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
   215     ~CDecoderFlusher() 
   216     { 
   217       if (NeedFlush)
   218         _decoder->Flush();
   219       _decoder->ReleaseStreams(); 
   220     }
   221   };
   223   HRESULT Flush() {  return _outWindowStream.Flush(); }  
   225   STDMETHOD(CodeReal)(ISequentialInStream *inStream,
   226       ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
   227       ICompressProgressInfo *progress);
   229   STDMETHOD(Code)(ISequentialInStream *inStream,
   230       ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
   231       ICompressProgressInfo *progress);
   233   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
   235   STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
   237   STDMETHOD(SetInStream)(ISequentialInStream *inStream);
   238   STDMETHOD(ReleaseInStream)();
   239   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
   241   #ifdef _ST_MODE
   242   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
   243   #endif
   245   CDecoder(): _outSizeDefined(false) {}
   246   virtual ~CDecoder() {}
   247 };
   249 }}
   251 #endif

mercurial