Upload 2.0.2
[physicsfs] / lzma / CPP / 7zip / Compress / LZMA / LZMADecoder.h
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