5 #include "ArjDecoder2.h"
\r
9 namespace NDecoder2 {
\r
11 static const UInt32 kHistorySize = 26624;
\r
12 static const UInt32 kMatchMinLen = 3;
\r
14 HRESULT CCoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
\r
15 const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo * /* progress */)
\r
17 if (outSize == NULL)
\r
18 return E_INVALIDARG;
\r
20 if (!m_OutWindowStream.Create(kHistorySize))
\r
21 return E_OUTOFMEMORY;
\r
22 if (!m_InBitStream.Create(1 << 20))
\r
23 return E_OUTOFMEMORY;
\r
26 m_OutWindowStream.SetStream(outStream);
\r
27 m_OutWindowStream.Init(false);
\r
28 m_InBitStream.SetStream(inStream);
\r
29 m_InBitStream.Init();
\r
30 CCoderReleaser coderReleaser(this);
\r
32 while(pos < *outSize)
\r
34 const UInt32 kStartWidth = 0;
\r
35 const UInt32 kStopWidth = 7;
\r
36 UInt32 power = 1 << kStartWidth;
\r
39 for (width = kStartWidth; width < kStopWidth; width++)
\r
41 if (m_InBitStream.ReadBits(1) == 0)
\r
47 len += m_InBitStream.ReadBits(width);
\r
50 m_OutWindowStream.PutByte((Byte)m_InBitStream.ReadBits(8));
\r
56 len = len - 1 + kMatchMinLen;
\r
57 const UInt32 kStartWidth = 9;
\r
58 const UInt32 kStopWidth = 13;
\r
59 UInt32 power = 1 << kStartWidth;
\r
61 UInt32 distance = 0;
\r
62 for (width = kStartWidth; width < kStopWidth; width++)
\r
64 if (m_InBitStream.ReadBits(1) == 0)
\r
70 distance += m_InBitStream.ReadBits(width);
\r
71 if (distance >= pos)
\r
73 m_OutWindowStream.CopyBlock(distance, len);
\r
77 coderReleaser.NeedFlush = false;
\r
78 return m_OutWindowStream.Flush();
\r
81 STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
\r
82 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
\r
84 try { return CodeReal(inStream, outStream, inSize, outSize, progress);}
\r
85 catch(const CInBufferException &e) { return e.ErrorCode; }
\r
86 catch(const CLzOutWindowException &e) { return e.ErrorCode; }
\r
87 catch(...) { return S_FALSE; }
\r