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