// Compress/BZip2/Decoder.h #ifndef __COMPRESS_BZIP2_DECODER_H #define __COMPRESS_BZIP2_DECODER_H #include "../../ICoder.h" #include "../../../Common/MyCom.h" #include "../../Common/MSBFDecoder.h" #include "../../Common/InBuffer.h" #include "../../Common/OutBuffer.h" #include "../Huffman/HuffmanDecoder.h" #include "BZip2Const.h" namespace NCompress { namespace NBZip2 { typedef NCompress::NHuffman::CDecoder CHuffmanDecoder; struct CState { UInt32 *tt; bool BlockRandomised; UInt32 OrigPtr; UInt32 BlockSize; UInt32 CharCounters[256]; Byte m_Selectors[kNumSelectorsMax]; UInt32 StoredCRC; CState(): tt(0) {} ~CState(); bool Alloc(); HRESULT DecodeBlock(COutBuffer &m_OutStream); }; class CDecoder : public ICompressCoder, public ICompressGetInStreamProcessedSize, public CMyUnknownImp { NStream::NMSBF::CDecoder m_InStream; COutBuffer m_OutStream; CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax]; CState m_State; UInt32 ReadBits(int numBits); Byte ReadByte(); bool ReadBit(); UInt32 ReadCRC(); HRESULT ReadBlock(UInt32 blockSizeMax, CState &state); HRESULT PrepareBlock(CState &state); HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress); HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); class CDecoderFlusher { CDecoder *_decoder; public: bool NeedFlush; CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {} ~CDecoderFlusher() { if (NeedFlush) _decoder->Flush(); _decoder->ReleaseStreams(); } }; public: HRESULT Flush() { return m_OutStream.Flush(); } void ReleaseStreams() { m_InStream.ReleaseStream(); m_OutStream.ReleaseStream(); } MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize) STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); }; }} #endif