~ubuntu-branches/ubuntu/precise/p7zip/precise-updates

« back to all changes in this revision

Viewing changes to CPP/7zip/Compress/Quantum/QuantumDecoder.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2009-02-14 20:12:27 UTC
  • mfrom: (1.1.11 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090214201227-go63qxm9ozfdma60
Tags: 4.65~dfsg.1-1
* New upstream release.
* Remove wx2.8 Build-Depends added by mistakes (7zG is not yet
  intended to be built).
* Use dh_clean without -k.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// QuantumDecoder.cpp
2
 
 
3
 
#include "StdAfx.h"
4
 
 
5
 
#include "QuantumDecoder.h"
6
 
#include "../../../Common/Defs.h"
7
 
 
8
 
namespace NCompress {
9
 
namespace NQuantum {
10
 
 
11
 
// const UInt32 kDictionarySizeMax = (1 << 21);
12
 
 
13
 
const int kLenIdNeedInit = -2;
14
 
 
15
 
void CDecoder::Init()
16
 
{
17
 
  m_Selector.Init(kNumSelectors);
18
 
  for (unsigned int i = 0; i < kNumLitSelectors; i++)
19
 
    m_Literals[i].Init(kNumLitSymbols);
20
 
  unsigned int numItems = _numDictBits << 1;
21
 
  m_PosSlot[0].Init(MyMin(numItems, kNumLen3PosSymbolsMax));
22
 
  m_PosSlot[1].Init(MyMin(numItems, kNumLen4PosSymbolsMax));
23
 
  m_PosSlot[2].Init(MyMin(numItems, kNumLen5PosSymbolsMax));
24
 
  m_LenSlot.Init(kNumLenSymbols);
25
 
}
26
 
 
27
 
HRESULT CDecoder::CodeSpec(UInt32 curSize)
28
 
{
29
 
  if (_remainLen == kLenIdNeedInit)
30
 
  {
31
 
    if (!_keepHistory)
32
 
    {
33
 
      if (!_outWindowStream.Create(_dictionarySize))
34
 
        return E_OUTOFMEMORY;
35
 
      Init();
36
 
    }
37
 
    if (!_rangeDecoder.Create(1 << 20))
38
 
      return E_OUTOFMEMORY;
39
 
    _rangeDecoder.Init();
40
 
    _remainLen = 0;
41
 
  }
42
 
  if (curSize == 0)
43
 
    return S_OK;
44
 
 
45
 
  while(_remainLen > 0 && curSize > 0)
46
 
  {
47
 
    _remainLen--;
48
 
    Byte b = _outWindowStream.GetByte(_rep0);
49
 
    _outWindowStream.PutByte(b);
50
 
    curSize--;
51
 
  }
52
 
 
53
 
  while(curSize > 0)
54
 
  {
55
 
    if (_rangeDecoder.Stream.WasFinished())
56
 
      return S_FALSE;
57
 
 
58
 
    unsigned int selector = m_Selector.Decode(&_rangeDecoder);
59
 
    if (selector < kNumLitSelectors)
60
 
    {
61
 
      Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&_rangeDecoder));
62
 
      _outWindowStream.PutByte(b);
63
 
      curSize--;
64
 
    }
65
 
    else             
66
 
    {
67
 
      selector -= kNumLitSelectors;
68
 
      unsigned int len = selector + kMatchMinLen;
69
 
      if (selector == 2)
70
 
      {
71
 
        unsigned int lenSlot = m_LenSlot.Decode(&_rangeDecoder);;
72
 
        if (lenSlot >= kNumSimpleLenSlots)
73
 
        {
74
 
          lenSlot -= 2;
75
 
          int numDirectBits = (int)(lenSlot >> 2);
76
 
          len +=  ((4 | (lenSlot & 3)) << numDirectBits) - 2;
77
 
          if (numDirectBits < 6)
78
 
            len += _rangeDecoder.Stream.ReadBits(numDirectBits);
79
 
        }
80
 
        else
81
 
          len += lenSlot;
82
 
      }
83
 
      UInt32 rep0 = m_PosSlot[selector].Decode(&_rangeDecoder);;
84
 
      if (rep0 >= kNumSimplePosSlots)
85
 
      {
86
 
        int numDirectBits = (int)((rep0 >> 1) - 1);
87
 
        rep0 = ((2 | (rep0 & 1)) << numDirectBits) + _rangeDecoder.Stream.ReadBits(numDirectBits);
88
 
      }
89
 
      unsigned int locLen = len;
90
 
      if (len > curSize)
91
 
        locLen = (unsigned int)curSize;
92
 
      if (!_outWindowStream.CopyBlock(rep0, locLen))
93
 
        return S_FALSE;
94
 
      curSize -= locLen;
95
 
      len -= locLen;
96
 
      if (len != 0)
97
 
      {
98
 
        _remainLen = (int)len;
99
 
        _rep0 = rep0;
100
 
        break;
101
 
      }
102
 
    }
103
 
  }
104
 
  return _rangeDecoder.Stream.WasFinished() ? S_FALSE : S_OK;
105
 
}
106
 
 
107
 
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
108
 
    ISequentialOutStream *outStream, 
109
 
    const UInt64 *, const UInt64 *outSize,
110
 
    ICompressProgressInfo *progress)
111
 
{
112
 
  if (outSize == NULL)
113
 
    return E_INVALIDARG;
114
 
  UInt64 size = *outSize;
115
 
 
116
 
  SetInStream(inStream);
117
 
  _outWindowStream.SetStream(outStream);
118
 
  SetOutStreamSize(outSize);
119
 
  CDecoderFlusher flusher(this);
120
 
 
121
 
  const UInt64 start = _outWindowStream.GetProcessedSize();
122
 
  for (;;)
123
 
  {
124
 
    UInt32 curSize = 1 << 18;
125
 
    UInt64 rem = size - (_outWindowStream.GetProcessedSize() - start);
126
 
    if (curSize > rem)
127
 
      curSize = (UInt32)rem;
128
 
    if (curSize == 0)
129
 
      break;
130
 
    RINOK(CodeSpec(curSize));
131
 
    if (progress != NULL)
132
 
    {
133
 
      UInt64 inSize = _rangeDecoder.GetProcessedSize();
134
 
      UInt64 nowPos64 = _outWindowStream.GetProcessedSize() - start;
135
 
      RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
136
 
    }
137
 
  } 
138
 
  flusher.NeedFlush = false;
139
 
  return Flush();
140
 
}
141
 
 
142
 
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
143
 
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
144
 
      ICompressProgressInfo *progress)
145
 
{
146
 
  try  { return CodeReal(inStream, outStream, inSize, outSize, progress); }
147
 
  catch(const CInBufferException &e)  { return e.ErrorCode; }
148
 
  catch(const CLZOutWindowException &e)  { return e.ErrorCode; }
149
 
  catch(...) { return S_FALSE; }
150
 
}
151
 
 
152
 
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
153
 
{
154
 
  _rangeDecoder.SetStream(inStream);
155
 
  return S_OK;
156
 
}
157
 
 
158
 
STDMETHODIMP CDecoder::ReleaseInStream()
159
 
{
160
 
  _rangeDecoder.ReleaseStream();
161
 
  return S_OK;
162
 
}
163
 
 
164
 
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
165
 
{
166
 
  if (outSize == NULL)
167
 
    return E_FAIL;
168
 
  _remainLen = kLenIdNeedInit;
169
 
  _outWindowStream.Init(_keepHistory);
170
 
  return S_OK;
171
 
}
172
 
 
173
 
}}