misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h
changeset 12218 bb5522e88ab2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,255 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+extern "C"
+{
+  #include "../../../../C/Alloc.h"
+}
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+  CMyBitDecoder _decoders[0x300];
+public:
+  void Init()
+  {
+    for (int i = 0; i < 0x300; i++)
+      _decoders[i].Init();
+  }
+  Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+  {
+    UInt32 symbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+      RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+    }
+    while (symbol < 0x100);
+    RC_FLUSH_VAR
+    return (Byte)symbol;
+  }
+  Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+  {
+    UInt32 symbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      UInt32 matchBit = (matchByte >> 7) & 1;
+      matchByte <<= 1;
+      // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+      // symbol = (symbol << 1) | bit;
+      UInt32 bit;
+      RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, 
+          bit = 0, bit = 1)
+      if (matchBit != bit)
+      {
+        while (symbol < 0x100)
+        {
+          // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+          RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+        }
+        break;
+      }
+    }
+    while (symbol < 0x100);
+    RC_FLUSH_VAR
+    return (Byte)symbol;
+  }
+};
+
+class CLiteralDecoder
+{
+  CLiteralDecoder2 *_coders;
+  int _numPrevBits;
+  int _numPosBits;
+  UInt32 _posMask;
+public:
+  CLiteralDecoder(): _coders(0) {}
+  ~CLiteralDecoder()  { Free(); }
+  void Free()
+  { 
+    MyFree(_coders);
+    _coders = 0;
+  }
+  bool Create(int numPosBits, int numPrevBits)
+  {
+    if (_coders == 0 || (numPosBits + numPrevBits) != 
+        (_numPrevBits + _numPosBits) )
+    {
+      Free();
+      UInt32 numStates = 1 << (numPosBits + numPrevBits);
+      _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+    }
+    _numPosBits = numPosBits;
+    _posMask = (1 << numPosBits) - 1;
+    _numPrevBits = numPrevBits;
+    return (_coders != 0);
+  }
+  void Init()
+  {
+    UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+    for (UInt32 i = 0; i < numStates; i++)
+      _coders[i].Init();
+  }
+  UInt32 GetState(UInt32 pos, Byte prevByte) const
+    { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+  Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+    { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+  Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+    { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+  CMyBitDecoder _choice;
+  CMyBitDecoder _choice2;
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits>  _lowCoder[kNumPosStatesMax];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits>  _midCoder[kNumPosStatesMax];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder; 
+public:
+  void Init(UInt32 numPosStates)
+  {
+    _choice.Init();
+    _choice2.Init();
+    for (UInt32 posState = 0; posState < numPosStates; posState++)
+    {
+      _lowCoder[posState].Init();
+      _midCoder[posState].Init();
+    }
+    _highCoder.Init();
+  }
+  UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+  {
+    if(_choice.Decode(rangeDecoder) == 0)
+      return _lowCoder[posState].Decode(rangeDecoder);
+    if(_choice2.Decode(rangeDecoder) == 0)
+      return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+    return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+  }
+};
+
+}
+
+class CDecoder: 
+  public ICompressCoder,
+  public ICompressSetDecoderProperties2,
+  public ICompressGetInStreamProcessedSize,
+  #ifndef NO_READ_FROM_CODER
+  public ICompressSetInStream,
+  public ICompressSetOutStreamSize,
+  public ISequentialInStream,
+  #endif
+  public CMyUnknownImp
+{
+  CLZOutWindow _outWindowStream;
+  NRangeCoder::CDecoder _rangeDecoder;
+
+  CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+  CMyBitDecoder _isRep[kNumStates];
+  CMyBitDecoder _isRepG0[kNumStates];
+  CMyBitDecoder _isRepG1[kNumStates];
+  CMyBitDecoder _isRepG2[kNumStates];
+  CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+  CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+  
+  NLength::CDecoder _lenDecoder;
+  NLength::CDecoder _repMatchLenDecoder;
+
+  CLiteralDecoder _literalDecoder;
+
+  UInt32 _posStateMask;
+
+  ///////////////////
+  // State
+  UInt32 _reps[4];
+  CState _state;
+  Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+  UInt64 _outSize;
+  bool _outSizeDefined;
+
+  void Init();
+  HRESULT CodeSpec(UInt32 size);
+public:
+
+  #ifndef NO_READ_FROM_CODER
+  MY_UNKNOWN_IMP5(
+      ICompressSetDecoderProperties2, 
+      ICompressGetInStreamProcessedSize,
+      ICompressSetInStream, 
+      ICompressSetOutStreamSize, 
+      ISequentialInStream)
+  #else
+  MY_UNKNOWN_IMP2(
+      ICompressSetDecoderProperties2,
+      ICompressGetInStreamProcessedSize)
+  #endif
+
+  void ReleaseStreams()
+  {
+    _outWindowStream.ReleaseStream();
+    ReleaseInStream();
+  }
+
+  class CDecoderFlusher
+  {
+    CDecoder *_decoder;
+  public:
+    bool NeedFlush;
+    CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+    ~CDecoderFlusher() 
+    { 
+      if (NeedFlush)
+        _decoder->Flush();
+      _decoder->ReleaseStreams(); 
+    }
+  };
+
+  HRESULT Flush() {  return _outWindowStream.Flush(); }  
+
+  STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+  
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+  STDMETHOD(ReleaseInStream)();
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+  #ifndef NO_READ_FROM_CODER
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  #endif
+
+  CDecoder(): _outSizeDefined(false) {}
+  virtual ~CDecoder() {}
+};
+
+}}
+
+#endif