xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/DeflateDecoder.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // DeflateDecoder.h
2 
3 #ifndef ZIP7_INC_DEFLATE_DECODER_H
4 #define ZIP7_INC_DEFLATE_DECODER_H
5 
6 #include "../../Common/MyCom.h"
7 
8 #include "../ICoder.h"
9 
10 #include "../Common/InBuffer.h"
11 
12 #include "BitlDecoder.h"
13 #include "DeflateConst.h"
14 #include "HuffmanDecoder.h"
15 #include "LzOutWindow.h"
16 
17 namespace NCompress {
18 namespace NDeflate {
19 namespace NDecoder {
20 
21 const int kLenIdFinished = -1;
22 const int kLenIdNeedInit = -2;
23 
24 const unsigned kNumTableBits_Main = 10;
25 const unsigned kNumTableBits_Dist = 6;
26 
27 class CCoder:
28   public ICompressCoder,
29   public ICompressSetFinishMode,
30   public ICompressGetInStreamProcessedSize,
31   public ICompressReadUnusedFromInBuf,
32   public ICompressSetInStream,
33   public ICompressSetOutStreamSize,
34 #ifndef Z7_NO_READ_FROM_CODER
35   public ISequentialInStream,
36 #endif
37   public CMyUnknownImp
38 {
39   Z7_COM_QI_BEGIN2(ICompressCoder)
40   Z7_COM_QI_ENTRY(ICompressSetFinishMode)
41   Z7_COM_QI_ENTRY(ICompressGetInStreamProcessedSize)
42   Z7_COM_QI_ENTRY(ICompressReadUnusedFromInBuf)
43   Z7_COM_QI_ENTRY(ICompressSetInStream)
44   Z7_COM_QI_ENTRY(ICompressSetOutStreamSize)
45 #ifndef Z7_NO_READ_FROM_CODER
46   Z7_COM_QI_ENTRY(ISequentialInStream)
47 #endif
48   Z7_COM_QI_END
49   Z7_COM_ADDREF_RELEASE
50 
51   Z7_IFACE_COM7_IMP(ICompressCoder)
52   Z7_IFACE_COM7_IMP(ICompressSetFinishMode)
53   Z7_IFACE_COM7_IMP(ICompressGetInStreamProcessedSize)
54 public:
55   Z7_IFACE_COM7_IMP(ICompressReadUnusedFromInBuf)
56   Z7_IFACE_COM7_IMP(ICompressSetInStream)
57 private:
58   Z7_IFACE_COM7_IMP(ICompressSetOutStreamSize)
59 #ifndef Z7_NO_READ_FROM_CODER
60   Z7_IFACE_COM7_IMP(ISequentialInStream)
61 #endif
62 
63   CLzOutWindow m_OutWindowStream;
64   NBitl::CDecoder<CInBuffer> m_InBitStream;
65   NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize, kNumTableBits_Main> m_MainDecoder;
66   NCompress::NHuffman::CDecoder256<kNumHuffmanBits, kFixedDistTableSize, kNumTableBits_Dist> m_DistDecoder;
67   NCompress::NHuffman::CDecoder7b<kLevelTableSize> m_LevelDecoder;
68 
69   UInt32 m_StoredBlockSize;
70 
71   unsigned _numDistLevels;
72   bool m_FinalBlock;
73   bool m_StoredMode;
74 
75   bool _deflateNSIS;
76   bool _deflate64Mode;
77   bool _keepHistory;
78   bool _needFinishInput;
79 
80   bool _needInitInStream;
81   bool _needReadTable;
82   Int32 _remainLen;
83   UInt32 _rep0;
84 
85   bool _outSizeDefined;
86   CMyComPtr<ISequentialInStream> m_InStreamRef;
87   UInt64 _outSize;
88   UInt64 _outStartPos;
89 
90   void SetOutStreamSizeResume(const UInt64 *outSize);
GetOutProcessedCur()91   UInt64 GetOutProcessedCur() const { return m_OutWindowStream.GetProcessedSize() - _outStartPos; }
92 
93   UInt32 ReadBits(unsigned numBits);
94 
95   bool DecodeLevels(Byte *levels, unsigned numSymbols);
96   bool ReadTables();
97 
Flush()98   HRESULT Flush() { return m_OutWindowStream.Flush(); }
99   class CCoderReleaser
100   {
101     CCoder *_coder;
102   public:
103     bool NeedFlush;
CCoderReleaser(CCoder * coder)104     CCoderReleaser(CCoder *coder): _coder(coder), NeedFlush(true) {}
~CCoderReleaser()105     ~CCoderReleaser()
106     {
107       if (NeedFlush)
108         _coder->Flush();
109     }
110   };
111   friend class CCoderReleaser;
112 
113   HRESULT CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit = 0);
114 public:
115 
116   CCoder(bool deflate64Mode);
~CCoder()117   virtual ~CCoder() {}
118 
SetNsisMode(bool nsisMode)119   void SetNsisMode(bool nsisMode) { _deflateNSIS = nsisMode; }
120 
Set_KeepHistory(bool keepHistory)121   void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
Set_NeedFinishInput(bool needFinishInput)122   void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; }
123 
IsFinished()124   bool IsFinished() const { return _remainLen == kLenIdFinished; }
IsFinalBlock()125   bool IsFinalBlock() const { return m_FinalBlock; }
126 
127   HRESULT CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress);
128 
129 public:
130   HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
131   HRESULT InitInStream(bool needInit);
132 
AlignToByte()133   void AlignToByte() { m_InBitStream.AlignToByte(); }
134   Byte ReadAlignedByte();
ReadAligned_UInt16()135   UInt32 ReadAligned_UInt16() // aligned for Byte range
136   {
137     const UInt32 v = m_InBitStream.ReadAlignedByte();
138     return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8);
139   }
InputEofError()140   bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); }
141 
142   // size of used real data from input stream
GetStreamSize()143   UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); }
144 
145   // size of virtual input stream processed
GetInputProcessedSize()146   UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); }
147 };
148 
CCOMCoder()149 class CCOMCoder     : public CCoder { public: CCOMCoder(): CCoder(false) {} };
CCOMCoder64()150 class CCOMCoder64   : public CCoder { public: CCOMCoder64(): CCoder(true) {} };
151 
152 }}}
153 
154 #endif
155