xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/LzmsDecoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // LzmsDecoder.cpp
2*f6dc9357SAndroid Build Coastguard Worker // The code is based on LZMS description from wimlib code
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/Alloc.h"
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #include "LzmsDecoder.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker namespace NCompress {
11*f6dc9357SAndroid Build Coastguard Worker namespace NLzms {
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker class CBitDecoder
14*f6dc9357SAndroid Build Coastguard Worker {
15*f6dc9357SAndroid Build Coastguard Worker public:
16*f6dc9357SAndroid Build Coastguard Worker   const Byte *_buf;
17*f6dc9357SAndroid Build Coastguard Worker   unsigned _bitPos;
18*f6dc9357SAndroid Build Coastguard Worker 
Init(const Byte * buf,size_t size)19*f6dc9357SAndroid Build Coastguard Worker   void Init(const Byte *buf, size_t size) throw()
20*f6dc9357SAndroid Build Coastguard Worker   {
21*f6dc9357SAndroid Build Coastguard Worker     _buf = buf + size;
22*f6dc9357SAndroid Build Coastguard Worker     _bitPos = 0;
23*f6dc9357SAndroid Build Coastguard Worker   }
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
GetValue(unsigned numBits) const26*f6dc9357SAndroid Build Coastguard Worker   UInt32 GetValue(unsigned numBits) const
27*f6dc9357SAndroid Build Coastguard Worker   {
28*f6dc9357SAndroid Build Coastguard Worker     UInt32 v =
29*f6dc9357SAndroid Build Coastguard Worker         ((UInt32)_buf[-1] << 16) |
30*f6dc9357SAndroid Build Coastguard Worker         ((UInt32)_buf[-2] << 8) |
31*f6dc9357SAndroid Build Coastguard Worker          (UInt32)_buf[-3];
32*f6dc9357SAndroid Build Coastguard Worker     v >>= 24 - numBits - _bitPos;
33*f6dc9357SAndroid Build Coastguard Worker     return v & ((1u << numBits) - 1);
34*f6dc9357SAndroid Build Coastguard Worker   }
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
GetValue_InHigh32bits()37*f6dc9357SAndroid Build Coastguard Worker   UInt32 GetValue_InHigh32bits()
38*f6dc9357SAndroid Build Coastguard Worker   {
39*f6dc9357SAndroid Build Coastguard Worker     return GetUi32(_buf - 4) << _bitPos;
40*f6dc9357SAndroid Build Coastguard Worker   }
41*f6dc9357SAndroid Build Coastguard Worker 
MovePos(unsigned numBits)42*f6dc9357SAndroid Build Coastguard Worker   void MovePos(unsigned numBits)
43*f6dc9357SAndroid Build Coastguard Worker   {
44*f6dc9357SAndroid Build Coastguard Worker     _bitPos += numBits;
45*f6dc9357SAndroid Build Coastguard Worker     _buf -= (_bitPos >> 3);
46*f6dc9357SAndroid Build Coastguard Worker     _bitPos &= 7;
47*f6dc9357SAndroid Build Coastguard Worker   }
48*f6dc9357SAndroid Build Coastguard Worker 
ReadBits32(unsigned numBits)49*f6dc9357SAndroid Build Coastguard Worker   UInt32 ReadBits32(unsigned numBits)
50*f6dc9357SAndroid Build Coastguard Worker   {
51*f6dc9357SAndroid Build Coastguard Worker     UInt32 mask = (((UInt32)1 << numBits) - 1);
52*f6dc9357SAndroid Build Coastguard Worker     numBits += _bitPos;
53*f6dc9357SAndroid Build Coastguard Worker     const Byte *buf = _buf;
54*f6dc9357SAndroid Build Coastguard Worker     UInt32 v = GetUi32(buf - 4);
55*f6dc9357SAndroid Build Coastguard Worker     if (numBits > 32)
56*f6dc9357SAndroid Build Coastguard Worker     {
57*f6dc9357SAndroid Build Coastguard Worker       v <<= (numBits - 32);
58*f6dc9357SAndroid Build Coastguard Worker       v |= (UInt32)buf[-5] >> (40 - numBits);
59*f6dc9357SAndroid Build Coastguard Worker     }
60*f6dc9357SAndroid Build Coastguard Worker     else
61*f6dc9357SAndroid Build Coastguard Worker       v >>= (32 - numBits);
62*f6dc9357SAndroid Build Coastguard Worker     _buf = buf - (numBits >> 3);
63*f6dc9357SAndroid Build Coastguard Worker     _bitPos = numBits & 7;
64*f6dc9357SAndroid Build Coastguard Worker     return v & mask;
65*f6dc9357SAndroid Build Coastguard Worker   }
66*f6dc9357SAndroid Build Coastguard Worker };
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker static UInt32 g_PosBases[k_NumPosSyms /* + 1 */];
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker static Byte g_PosDirectBits[k_NumPosSyms];
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker static const Byte k_PosRuns[31] =
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker   8, 0, 9, 7, 10, 15, 15, 20, 20, 30, 33, 40, 42, 45, 60, 73,
75*f6dc9357SAndroid Build Coastguard Worker   80, 85, 95, 105, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
76*f6dc9357SAndroid Build Coastguard Worker };
77*f6dc9357SAndroid Build Coastguard Worker 
78*f6dc9357SAndroid Build Coastguard Worker static UInt32 g_LenBases[k_NumLenSyms];
79*f6dc9357SAndroid Build Coastguard Worker 
80*f6dc9357SAndroid Build Coastguard Worker static const Byte k_LenDirectBits[k_NumLenSyms] =
81*f6dc9357SAndroid Build Coastguard Worker {
82*f6dc9357SAndroid Build Coastguard Worker   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83*f6dc9357SAndroid Build Coastguard Worker   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
84*f6dc9357SAndroid Build Coastguard Worker   2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 6,
85*f6dc9357SAndroid Build Coastguard Worker   7, 8, 9, 10, 16, 30,
86*f6dc9357SAndroid Build Coastguard Worker };
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker static struct CInit
89*f6dc9357SAndroid Build Coastguard Worker {
CInitNCompress::NLzms::CInit90*f6dc9357SAndroid Build Coastguard Worker   CInit()
91*f6dc9357SAndroid Build Coastguard Worker   {
92*f6dc9357SAndroid Build Coastguard Worker     {
93*f6dc9357SAndroid Build Coastguard Worker       unsigned sum = 0;
94*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < sizeof(k_PosRuns); i++)
95*f6dc9357SAndroid Build Coastguard Worker       {
96*f6dc9357SAndroid Build Coastguard Worker         unsigned t = k_PosRuns[i];
97*f6dc9357SAndroid Build Coastguard Worker         for (unsigned y = 0; y < t; y++)
98*f6dc9357SAndroid Build Coastguard Worker           g_PosDirectBits[sum + y] = (Byte)i;
99*f6dc9357SAndroid Build Coastguard Worker         sum += t;
100*f6dc9357SAndroid Build Coastguard Worker       }
101*f6dc9357SAndroid Build Coastguard Worker     }
102*f6dc9357SAndroid Build Coastguard Worker     {
103*f6dc9357SAndroid Build Coastguard Worker       UInt32 sum = 1;
104*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < k_NumPosSyms; i++)
105*f6dc9357SAndroid Build Coastguard Worker       {
106*f6dc9357SAndroid Build Coastguard Worker         g_PosBases[i] = sum;
107*f6dc9357SAndroid Build Coastguard Worker         sum += (UInt32)1 << g_PosDirectBits[i];
108*f6dc9357SAndroid Build Coastguard Worker       }
109*f6dc9357SAndroid Build Coastguard Worker       // g_PosBases[k_NumPosSyms] = sum;
110*f6dc9357SAndroid Build Coastguard Worker     }
111*f6dc9357SAndroid Build Coastguard Worker     {
112*f6dc9357SAndroid Build Coastguard Worker       UInt32 sum = 1;
113*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < k_NumLenSyms; i++)
114*f6dc9357SAndroid Build Coastguard Worker       {
115*f6dc9357SAndroid Build Coastguard Worker         g_LenBases[i] = sum;
116*f6dc9357SAndroid Build Coastguard Worker         sum += (UInt32)1 << k_LenDirectBits[i];
117*f6dc9357SAndroid Build Coastguard Worker       }
118*f6dc9357SAndroid Build Coastguard Worker     }
119*f6dc9357SAndroid Build Coastguard Worker   }
120*f6dc9357SAndroid Build Coastguard Worker } g_Init;
121*f6dc9357SAndroid Build Coastguard Worker 
GetNumPosSlots(size_t size)122*f6dc9357SAndroid Build Coastguard Worker static unsigned GetNumPosSlots(size_t size)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker   if (size < 2)
125*f6dc9357SAndroid Build Coastguard Worker     return 0;
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker   size--;
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker   if (size >= g_PosBases[k_NumPosSyms - 1])
130*f6dc9357SAndroid Build Coastguard Worker     return k_NumPosSyms;
131*f6dc9357SAndroid Build Coastguard Worker   unsigned left = 0;
132*f6dc9357SAndroid Build Coastguard Worker   unsigned right = k_NumPosSyms;
133*f6dc9357SAndroid Build Coastguard Worker   for (;;)
134*f6dc9357SAndroid Build Coastguard Worker   {
135*f6dc9357SAndroid Build Coastguard Worker     const unsigned m = (left + right) / 2;
136*f6dc9357SAndroid Build Coastguard Worker     if (left == m)
137*f6dc9357SAndroid Build Coastguard Worker       return m + 1;
138*f6dc9357SAndroid Build Coastguard Worker     if (size >= g_PosBases[m])
139*f6dc9357SAndroid Build Coastguard Worker       left = m;
140*f6dc9357SAndroid Build Coastguard Worker     else
141*f6dc9357SAndroid Build Coastguard Worker       right = m;
142*f6dc9357SAndroid Build Coastguard Worker   }
143*f6dc9357SAndroid Build Coastguard Worker }
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker 
146*f6dc9357SAndroid Build Coastguard Worker static const Int32 k_x86_WindowSize = 65535;
147*f6dc9357SAndroid Build Coastguard Worker static const Int32 k_x86_TransOffset = 1023;
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker static const size_t k_x86_HistorySize = 1 << 16;
150*f6dc9357SAndroid Build Coastguard Worker 
x86_Filter(Byte * data,UInt32 size,Int32 * history)151*f6dc9357SAndroid Build Coastguard Worker static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
152*f6dc9357SAndroid Build Coastguard Worker {
153*f6dc9357SAndroid Build Coastguard Worker   if (size <= 17)
154*f6dc9357SAndroid Build Coastguard Worker     return;
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker   Byte isCode[256];
157*f6dc9357SAndroid Build Coastguard Worker   memset(isCode, 0, 256);
158*f6dc9357SAndroid Build Coastguard Worker   isCode[0x48] = 1;
159*f6dc9357SAndroid Build Coastguard Worker   isCode[0x4C] = 1;
160*f6dc9357SAndroid Build Coastguard Worker   isCode[0xE8] = 1;
161*f6dc9357SAndroid Build Coastguard Worker   isCode[0xE9] = 1;
162*f6dc9357SAndroid Build Coastguard Worker   isCode[0xF0] = 1;
163*f6dc9357SAndroid Build Coastguard Worker   isCode[0xFF] = 1;
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker   {
166*f6dc9357SAndroid Build Coastguard Worker     for (size_t i = 0; i < k_x86_HistorySize; i++)
167*f6dc9357SAndroid Build Coastguard Worker       history[i] = -(Int32)k_x86_WindowSize - 1;
168*f6dc9357SAndroid Build Coastguard Worker   }
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker   size -= 16;
171*f6dc9357SAndroid Build Coastguard Worker   const unsigned kSave = 6;
172*f6dc9357SAndroid Build Coastguard Worker   const Byte savedByte = data[(size_t)size + kSave];
173*f6dc9357SAndroid Build Coastguard Worker   data[(size_t)size + kSave] = 0xE8;
174*f6dc9357SAndroid Build Coastguard Worker   Int32 last_x86_pos = -k_x86_TransOffset - 1;
175*f6dc9357SAndroid Build Coastguard Worker 
176*f6dc9357SAndroid Build Coastguard Worker   // first byte is ignored
177*f6dc9357SAndroid Build Coastguard Worker   Int32 i = 0;
178*f6dc9357SAndroid Build Coastguard Worker 
179*f6dc9357SAndroid Build Coastguard Worker   for (;;)
180*f6dc9357SAndroid Build Coastguard Worker   {
181*f6dc9357SAndroid Build Coastguard Worker     Byte *p = data + (UInt32)i;
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker     for (;;)
184*f6dc9357SAndroid Build Coastguard Worker     {
185*f6dc9357SAndroid Build Coastguard Worker       if (isCode[*(++p)]) break;
186*f6dc9357SAndroid Build Coastguard Worker       if (isCode[*(++p)]) break;
187*f6dc9357SAndroid Build Coastguard Worker     }
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker     i = (Int32)(p - data);
190*f6dc9357SAndroid Build Coastguard Worker     if ((UInt32)i >= size)
191*f6dc9357SAndroid Build Coastguard Worker       break;
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker     UInt32 codeLen;
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker     Int32 maxTransOffset = k_x86_TransOffset;
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker     const Byte b = p[0];
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker     if ((b & 0x80) == 0) // REX (0x48 or 0x4c)
200*f6dc9357SAndroid Build Coastguard Worker     {
201*f6dc9357SAndroid Build Coastguard Worker       const unsigned b2 = p[2] - 0x5; // [RIP + disp32]
202*f6dc9357SAndroid Build Coastguard Worker       if (b2 & 0x7)
203*f6dc9357SAndroid Build Coastguard Worker         continue;
204*f6dc9357SAndroid Build Coastguard Worker       if (p[1] != 0x8d) // LEA
205*f6dc9357SAndroid Build Coastguard Worker       {
206*f6dc9357SAndroid Build Coastguard Worker         if (p[1] != 0x8b || b != 0x48 || (b2 & 0xf7))
207*f6dc9357SAndroid Build Coastguard Worker           continue;
208*f6dc9357SAndroid Build Coastguard Worker         // MOV RAX / RCX, [RIP + disp32]
209*f6dc9357SAndroid Build Coastguard Worker       }
210*f6dc9357SAndroid Build Coastguard Worker       codeLen = 3;
211*f6dc9357SAndroid Build Coastguard Worker     }
212*f6dc9357SAndroid Build Coastguard Worker     else if (b == 0xE8)
213*f6dc9357SAndroid Build Coastguard Worker     {
214*f6dc9357SAndroid Build Coastguard Worker       // CALL
215*f6dc9357SAndroid Build Coastguard Worker       codeLen = 1;
216*f6dc9357SAndroid Build Coastguard Worker       maxTransOffset /= 2;
217*f6dc9357SAndroid Build Coastguard Worker     }
218*f6dc9357SAndroid Build Coastguard Worker     else if (b == 0xE9)
219*f6dc9357SAndroid Build Coastguard Worker     {
220*f6dc9357SAndroid Build Coastguard Worker       // JUMP
221*f6dc9357SAndroid Build Coastguard Worker       i += 4;
222*f6dc9357SAndroid Build Coastguard Worker       continue;
223*f6dc9357SAndroid Build Coastguard Worker     }
224*f6dc9357SAndroid Build Coastguard Worker     else if (b == 0xF0)
225*f6dc9357SAndroid Build Coastguard Worker     {
226*f6dc9357SAndroid Build Coastguard Worker       if (p[1] != 0x83 || p[2] != 0x05)
227*f6dc9357SAndroid Build Coastguard Worker         continue;
228*f6dc9357SAndroid Build Coastguard Worker       // LOCK ADD [RIP + disp32], imm8
229*f6dc9357SAndroid Build Coastguard Worker       // LOCK ADD [disp32], imm8
230*f6dc9357SAndroid Build Coastguard Worker       codeLen = 3;
231*f6dc9357SAndroid Build Coastguard Worker     }
232*f6dc9357SAndroid Build Coastguard Worker     else
233*f6dc9357SAndroid Build Coastguard Worker     // if (b == 0xFF)
234*f6dc9357SAndroid Build Coastguard Worker     {
235*f6dc9357SAndroid Build Coastguard Worker       if (p[1] != 0x15)
236*f6dc9357SAndroid Build Coastguard Worker         continue;
237*f6dc9357SAndroid Build Coastguard Worker       // CALL [RIP + disp32];
238*f6dc9357SAndroid Build Coastguard Worker       // CALL [disp32];
239*f6dc9357SAndroid Build Coastguard Worker       codeLen = 2;
240*f6dc9357SAndroid Build Coastguard Worker     }
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker     Int32 *target;
243*f6dc9357SAndroid Build Coastguard Worker     {
244*f6dc9357SAndroid Build Coastguard Worker       Byte *p2 = p + codeLen;
245*f6dc9357SAndroid Build Coastguard Worker       UInt32 n = GetUi32(p2);
246*f6dc9357SAndroid Build Coastguard Worker       if (i - last_x86_pos <= maxTransOffset)
247*f6dc9357SAndroid Build Coastguard Worker       {
248*f6dc9357SAndroid Build Coastguard Worker         n = (UInt32)((Int32)n - i);
249*f6dc9357SAndroid Build Coastguard Worker         SetUi32(p2, n)
250*f6dc9357SAndroid Build Coastguard Worker       }
251*f6dc9357SAndroid Build Coastguard Worker       target = history + (((UInt32)i + n) & 0xFFFF);
252*f6dc9357SAndroid Build Coastguard Worker     }
253*f6dc9357SAndroid Build Coastguard Worker 
254*f6dc9357SAndroid Build Coastguard Worker     i += (Int32)(codeLen + sizeof(UInt32) - 1);
255*f6dc9357SAndroid Build Coastguard Worker 
256*f6dc9357SAndroid Build Coastguard Worker     if (i - *target <= k_x86_WindowSize)
257*f6dc9357SAndroid Build Coastguard Worker       last_x86_pos = i;
258*f6dc9357SAndroid Build Coastguard Worker     *target = i;
259*f6dc9357SAndroid Build Coastguard Worker   }
260*f6dc9357SAndroid Build Coastguard Worker 
261*f6dc9357SAndroid Build Coastguard Worker   data[(size_t)size + kSave] = savedByte;
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker 
265*f6dc9357SAndroid Build Coastguard Worker 
266*f6dc9357SAndroid Build Coastguard Worker // static const int kLenIdNeedInit = -2;
267*f6dc9357SAndroid Build Coastguard Worker 
CDecoder()268*f6dc9357SAndroid Build Coastguard Worker CDecoder::CDecoder():
269*f6dc9357SAndroid Build Coastguard Worker   _x86_history(NULL)
270*f6dc9357SAndroid Build Coastguard Worker {
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker 
~CDecoder()273*f6dc9357SAndroid Build Coastguard Worker CDecoder::~CDecoder()
274*f6dc9357SAndroid Build Coastguard Worker {
275*f6dc9357SAndroid Build Coastguard Worker   ::MidFree(_x86_history);
276*f6dc9357SAndroid Build Coastguard Worker }
277*f6dc9357SAndroid Build Coastguard Worker 
278*f6dc9357SAndroid Build Coastguard Worker // #define RIF(x) { if (!(x)) return false; }
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker #define LIMIT_CHECK if (_bs._buf < _rc.cur) return S_FALSE;
281*f6dc9357SAndroid Build Coastguard Worker // #define LIMIT_CHECK
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker #define READ_BITS_CHECK(numDirectBits) \
284*f6dc9357SAndroid Build Coastguard Worker   if (_bs._buf < _rc.cur) return S_FALSE; \
285*f6dc9357SAndroid Build Coastguard Worker   if ((size_t)(_bs._buf - _rc.cur) < (numDirectBits >> 3)) return S_FALSE;
286*f6dc9357SAndroid Build Coastguard Worker 
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker #define HUFF_DEC(sym, pp) \
289*f6dc9357SAndroid Build Coastguard Worker     sym = pp.DecodeFull(&_bs); \
290*f6dc9357SAndroid Build Coastguard Worker     pp.Freqs[sym]++; \
291*f6dc9357SAndroid Build Coastguard Worker     if (--pp.RebuildRem == 0) pp.Rebuild();
292*f6dc9357SAndroid Build Coastguard Worker 
293*f6dc9357SAndroid Build Coastguard Worker 
CodeReal(const Byte * in,size_t inSize,Byte * _win,size_t outSize)294*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t outSize)
295*f6dc9357SAndroid Build Coastguard Worker {
296*f6dc9357SAndroid Build Coastguard Worker   // size_t inSizeT = (size_t)(inSize);
297*f6dc9357SAndroid Build Coastguard Worker   // Byte *_win;
298*f6dc9357SAndroid Build Coastguard Worker   // size_t _pos;
299*f6dc9357SAndroid Build Coastguard Worker   _pos = 0;
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker   CBitDecoder _bs;
302*f6dc9357SAndroid Build Coastguard Worker   CRangeDecoder _rc;
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker   if (inSize < 8 || (inSize & 1) != 0)
305*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
306*f6dc9357SAndroid Build Coastguard Worker   _rc.Init(in, inSize);
307*f6dc9357SAndroid Build Coastguard Worker   if (_rc.code >= _rc.range)
308*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
309*f6dc9357SAndroid Build Coastguard Worker   _bs.Init(in, inSize);
310*f6dc9357SAndroid Build Coastguard Worker 
311*f6dc9357SAndroid Build Coastguard Worker   {
312*f6dc9357SAndroid Build Coastguard Worker     {
313*f6dc9357SAndroid Build Coastguard Worker       {
314*f6dc9357SAndroid Build Coastguard Worker         for (unsigned i = 0 ; i < k_NumReps + 1; i++)
315*f6dc9357SAndroid Build Coastguard Worker           _reps[i] = i + 1;
316*f6dc9357SAndroid Build Coastguard Worker       }
317*f6dc9357SAndroid Build Coastguard Worker 
318*f6dc9357SAndroid Build Coastguard Worker       {
319*f6dc9357SAndroid Build Coastguard Worker         for (unsigned i = 0 ; i < k_NumReps + 1; i++)
320*f6dc9357SAndroid Build Coastguard Worker           _deltaReps[i] = i + 1;
321*f6dc9357SAndroid Build Coastguard Worker       }
322*f6dc9357SAndroid Build Coastguard Worker 
323*f6dc9357SAndroid Build Coastguard Worker       mainState = 0;
324*f6dc9357SAndroid Build Coastguard Worker       matchState = 0;
325*f6dc9357SAndroid Build Coastguard Worker 
326*f6dc9357SAndroid Build Coastguard Worker       { for (size_t i = 0; i < k_NumMainProbs; i++) mainProbs[i].Init(); }
327*f6dc9357SAndroid Build Coastguard Worker       { for (size_t i = 0; i < k_NumMatchProbs; i++) matchProbs[i].Init(); }
328*f6dc9357SAndroid Build Coastguard Worker 
329*f6dc9357SAndroid Build Coastguard Worker       {
330*f6dc9357SAndroid Build Coastguard Worker         for (size_t k = 0; k < k_NumReps; k++)
331*f6dc9357SAndroid Build Coastguard Worker         {
332*f6dc9357SAndroid Build Coastguard Worker           lzRepStates[k] = 0;
333*f6dc9357SAndroid Build Coastguard Worker           for (size_t i = 0; i < k_NumRepProbs; i++)
334*f6dc9357SAndroid Build Coastguard Worker             lzRepProbs[k][i].Init();
335*f6dc9357SAndroid Build Coastguard Worker         }
336*f6dc9357SAndroid Build Coastguard Worker       }
337*f6dc9357SAndroid Build Coastguard Worker       {
338*f6dc9357SAndroid Build Coastguard Worker         for (size_t k = 0; k < k_NumReps; k++)
339*f6dc9357SAndroid Build Coastguard Worker         {
340*f6dc9357SAndroid Build Coastguard Worker           deltaRepStates[k] = 0;
341*f6dc9357SAndroid Build Coastguard Worker           for (size_t i = 0; i < k_NumRepProbs; i++)
342*f6dc9357SAndroid Build Coastguard Worker             deltaRepProbs[k][i].Init();
343*f6dc9357SAndroid Build Coastguard Worker         }
344*f6dc9357SAndroid Build Coastguard Worker       }
345*f6dc9357SAndroid Build Coastguard Worker 
346*f6dc9357SAndroid Build Coastguard Worker       m_LitDecoder.Init();
347*f6dc9357SAndroid Build Coastguard Worker       m_LenDecoder.Init();
348*f6dc9357SAndroid Build Coastguard Worker       m_PowerDecoder.Init();
349*f6dc9357SAndroid Build Coastguard Worker       unsigned numPosSyms = GetNumPosSlots(outSize);
350*f6dc9357SAndroid Build Coastguard Worker       if (numPosSyms < 2)
351*f6dc9357SAndroid Build Coastguard Worker         numPosSyms = 2;
352*f6dc9357SAndroid Build Coastguard Worker       m_PosDecoder.Init(numPosSyms);
353*f6dc9357SAndroid Build Coastguard Worker       m_DeltaDecoder.Init(numPosSyms);
354*f6dc9357SAndroid Build Coastguard Worker     }
355*f6dc9357SAndroid Build Coastguard Worker   }
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker   {
358*f6dc9357SAndroid Build Coastguard Worker     unsigned prevType = 0;
359*f6dc9357SAndroid Build Coastguard Worker 
360*f6dc9357SAndroid Build Coastguard Worker     while (_pos < outSize)
361*f6dc9357SAndroid Build Coastguard Worker     {
362*f6dc9357SAndroid Build Coastguard Worker       if (_rc.Decode(&mainState, k_NumMainProbs, mainProbs) == 0)
363*f6dc9357SAndroid Build Coastguard Worker       {
364*f6dc9357SAndroid Build Coastguard Worker         unsigned number;
365*f6dc9357SAndroid Build Coastguard Worker         HUFF_DEC(number, m_LitDecoder)
366*f6dc9357SAndroid Build Coastguard Worker         LIMIT_CHECK
367*f6dc9357SAndroid Build Coastguard Worker         _win[_pos++] = (Byte)number;
368*f6dc9357SAndroid Build Coastguard Worker         prevType = 0;
369*f6dc9357SAndroid Build Coastguard Worker       }
370*f6dc9357SAndroid Build Coastguard Worker       else if (_rc.Decode(&matchState, k_NumMatchProbs, matchProbs) == 0)
371*f6dc9357SAndroid Build Coastguard Worker       {
372*f6dc9357SAndroid Build Coastguard Worker         UInt32 distance;
373*f6dc9357SAndroid Build Coastguard Worker 
374*f6dc9357SAndroid Build Coastguard Worker         if (_rc.Decode(&lzRepStates[0], k_NumRepProbs, lzRepProbs[0]) == 0)
375*f6dc9357SAndroid Build Coastguard Worker         {
376*f6dc9357SAndroid Build Coastguard Worker           unsigned number;
377*f6dc9357SAndroid Build Coastguard Worker           HUFF_DEC(number, m_PosDecoder)
378*f6dc9357SAndroid Build Coastguard Worker           LIMIT_CHECK
379*f6dc9357SAndroid Build Coastguard Worker 
380*f6dc9357SAndroid Build Coastguard Worker           const unsigned numDirectBits = g_PosDirectBits[number];
381*f6dc9357SAndroid Build Coastguard Worker           distance = g_PosBases[number];
382*f6dc9357SAndroid Build Coastguard Worker           READ_BITS_CHECK(numDirectBits)
383*f6dc9357SAndroid Build Coastguard Worker           distance += _bs.ReadBits32(numDirectBits);
384*f6dc9357SAndroid Build Coastguard Worker           // LIMIT_CHECK
385*f6dc9357SAndroid Build Coastguard Worker           _reps[3] = _reps[2];
386*f6dc9357SAndroid Build Coastguard Worker           _reps[2] = _reps[1];
387*f6dc9357SAndroid Build Coastguard Worker           _reps[1] = _reps[0];
388*f6dc9357SAndroid Build Coastguard Worker           _reps[0] = distance;
389*f6dc9357SAndroid Build Coastguard Worker         }
390*f6dc9357SAndroid Build Coastguard Worker         else
391*f6dc9357SAndroid Build Coastguard Worker         {
392*f6dc9357SAndroid Build Coastguard Worker           if (_rc.Decode(&lzRepStates[1], k_NumRepProbs, lzRepProbs[1]) == 0)
393*f6dc9357SAndroid Build Coastguard Worker           {
394*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 1)
395*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[0];
396*f6dc9357SAndroid Build Coastguard Worker             else
397*f6dc9357SAndroid Build Coastguard Worker             {
398*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[1];
399*f6dc9357SAndroid Build Coastguard Worker               _reps[1] = _reps[0];
400*f6dc9357SAndroid Build Coastguard Worker               _reps[0] = distance;
401*f6dc9357SAndroid Build Coastguard Worker             }
402*f6dc9357SAndroid Build Coastguard Worker           }
403*f6dc9357SAndroid Build Coastguard Worker           else if (_rc.Decode(&lzRepStates[2], k_NumRepProbs, lzRepProbs[2]) == 0)
404*f6dc9357SAndroid Build Coastguard Worker           {
405*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 1)
406*f6dc9357SAndroid Build Coastguard Worker             {
407*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[1];
408*f6dc9357SAndroid Build Coastguard Worker               _reps[1] = _reps[0];
409*f6dc9357SAndroid Build Coastguard Worker               _reps[0] = distance;
410*f6dc9357SAndroid Build Coastguard Worker             }
411*f6dc9357SAndroid Build Coastguard Worker             else
412*f6dc9357SAndroid Build Coastguard Worker             {
413*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[2];
414*f6dc9357SAndroid Build Coastguard Worker               _reps[2] = _reps[1];
415*f6dc9357SAndroid Build Coastguard Worker               _reps[1] = _reps[0];
416*f6dc9357SAndroid Build Coastguard Worker               _reps[0] = distance;
417*f6dc9357SAndroid Build Coastguard Worker             }
418*f6dc9357SAndroid Build Coastguard Worker           }
419*f6dc9357SAndroid Build Coastguard Worker           else
420*f6dc9357SAndroid Build Coastguard Worker           {
421*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 1)
422*f6dc9357SAndroid Build Coastguard Worker             {
423*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[2];
424*f6dc9357SAndroid Build Coastguard Worker               _reps[2] = _reps[1];
425*f6dc9357SAndroid Build Coastguard Worker               _reps[1] = _reps[0];
426*f6dc9357SAndroid Build Coastguard Worker               _reps[0] = distance;
427*f6dc9357SAndroid Build Coastguard Worker             }
428*f6dc9357SAndroid Build Coastguard Worker             else
429*f6dc9357SAndroid Build Coastguard Worker             {
430*f6dc9357SAndroid Build Coastguard Worker               distance = _reps[3];
431*f6dc9357SAndroid Build Coastguard Worker               _reps[3] = _reps[2];
432*f6dc9357SAndroid Build Coastguard Worker               _reps[2] = _reps[1];
433*f6dc9357SAndroid Build Coastguard Worker               _reps[1] = _reps[0];
434*f6dc9357SAndroid Build Coastguard Worker               _reps[0] = distance;
435*f6dc9357SAndroid Build Coastguard Worker             }
436*f6dc9357SAndroid Build Coastguard Worker           }
437*f6dc9357SAndroid Build Coastguard Worker         }
438*f6dc9357SAndroid Build Coastguard Worker 
439*f6dc9357SAndroid Build Coastguard Worker         unsigned lenSlot;
440*f6dc9357SAndroid Build Coastguard Worker         HUFF_DEC(lenSlot, m_LenDecoder)
441*f6dc9357SAndroid Build Coastguard Worker         LIMIT_CHECK
442*f6dc9357SAndroid Build Coastguard Worker 
443*f6dc9357SAndroid Build Coastguard Worker         UInt32 len = g_LenBases[lenSlot];
444*f6dc9357SAndroid Build Coastguard Worker         {
445*f6dc9357SAndroid Build Coastguard Worker           const unsigned numDirectBits = k_LenDirectBits[lenSlot];
446*f6dc9357SAndroid Build Coastguard Worker           READ_BITS_CHECK(numDirectBits)
447*f6dc9357SAndroid Build Coastguard Worker           len += _bs.ReadBits32(numDirectBits);
448*f6dc9357SAndroid Build Coastguard Worker         }
449*f6dc9357SAndroid Build Coastguard Worker         // LIMIT_CHECK
450*f6dc9357SAndroid Build Coastguard Worker 
451*f6dc9357SAndroid Build Coastguard Worker         if (len > outSize - _pos)
452*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
453*f6dc9357SAndroid Build Coastguard Worker 
454*f6dc9357SAndroid Build Coastguard Worker         if (distance > _pos)
455*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
456*f6dc9357SAndroid Build Coastguard Worker 
457*f6dc9357SAndroid Build Coastguard Worker         Byte *dest = _win + _pos;
458*f6dc9357SAndroid Build Coastguard Worker         const Byte *src = dest - distance;
459*f6dc9357SAndroid Build Coastguard Worker         _pos += len;
460*f6dc9357SAndroid Build Coastguard Worker         do
461*f6dc9357SAndroid Build Coastguard Worker           *dest++ = *src++;
462*f6dc9357SAndroid Build Coastguard Worker         while (--len);
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker         prevType = 1;
465*f6dc9357SAndroid Build Coastguard Worker       }
466*f6dc9357SAndroid Build Coastguard Worker       else
467*f6dc9357SAndroid Build Coastguard Worker       {
468*f6dc9357SAndroid Build Coastguard Worker         UInt64 distance;
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker         unsigned power;
471*f6dc9357SAndroid Build Coastguard Worker         UInt32 distance32;
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker         if (_rc.Decode(&deltaRepStates[0], k_NumRepProbs, deltaRepProbs[0]) == 0)
474*f6dc9357SAndroid Build Coastguard Worker         {
475*f6dc9357SAndroid Build Coastguard Worker           HUFF_DEC(power, m_PowerDecoder)
476*f6dc9357SAndroid Build Coastguard Worker           LIMIT_CHECK
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker           unsigned number;
479*f6dc9357SAndroid Build Coastguard Worker           HUFF_DEC(number, m_DeltaDecoder)
480*f6dc9357SAndroid Build Coastguard Worker           LIMIT_CHECK
481*f6dc9357SAndroid Build Coastguard Worker 
482*f6dc9357SAndroid Build Coastguard Worker           const unsigned numDirectBits = g_PosDirectBits[number];
483*f6dc9357SAndroid Build Coastguard Worker           distance32 = g_PosBases[number];
484*f6dc9357SAndroid Build Coastguard Worker           READ_BITS_CHECK(numDirectBits)
485*f6dc9357SAndroid Build Coastguard Worker           distance32 += _bs.ReadBits32(numDirectBits);
486*f6dc9357SAndroid Build Coastguard Worker           // LIMIT_CHECK
487*f6dc9357SAndroid Build Coastguard Worker 
488*f6dc9357SAndroid Build Coastguard Worker           distance = ((UInt64)power << 32) | distance32;
489*f6dc9357SAndroid Build Coastguard Worker 
490*f6dc9357SAndroid Build Coastguard Worker           _deltaReps[3] = _deltaReps[2];
491*f6dc9357SAndroid Build Coastguard Worker           _deltaReps[2] = _deltaReps[1];
492*f6dc9357SAndroid Build Coastguard Worker           _deltaReps[1] = _deltaReps[0];
493*f6dc9357SAndroid Build Coastguard Worker           _deltaReps[0] = distance;
494*f6dc9357SAndroid Build Coastguard Worker         }
495*f6dc9357SAndroid Build Coastguard Worker         else
496*f6dc9357SAndroid Build Coastguard Worker         {
497*f6dc9357SAndroid Build Coastguard Worker           if (_rc.Decode(&deltaRepStates[1], k_NumRepProbs, deltaRepProbs[1]) == 0)
498*f6dc9357SAndroid Build Coastguard Worker           {
499*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 2)
500*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[0];
501*f6dc9357SAndroid Build Coastguard Worker             else
502*f6dc9357SAndroid Build Coastguard Worker             {
503*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[1];
504*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[1] = _deltaReps[0];
505*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[0] = distance;
506*f6dc9357SAndroid Build Coastguard Worker             }
507*f6dc9357SAndroid Build Coastguard Worker           }
508*f6dc9357SAndroid Build Coastguard Worker           else if (_rc.Decode(&deltaRepStates[2], k_NumRepProbs, deltaRepProbs[2]) == 0)
509*f6dc9357SAndroid Build Coastguard Worker           {
510*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 2)
511*f6dc9357SAndroid Build Coastguard Worker             {
512*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[1];
513*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[1] = _deltaReps[0];
514*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[0] = distance;
515*f6dc9357SAndroid Build Coastguard Worker             }
516*f6dc9357SAndroid Build Coastguard Worker             else
517*f6dc9357SAndroid Build Coastguard Worker             {
518*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[2];
519*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[2] = _deltaReps[1];
520*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[1] = _deltaReps[0];
521*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[0] = distance;
522*f6dc9357SAndroid Build Coastguard Worker             }
523*f6dc9357SAndroid Build Coastguard Worker           }
524*f6dc9357SAndroid Build Coastguard Worker           else
525*f6dc9357SAndroid Build Coastguard Worker           {
526*f6dc9357SAndroid Build Coastguard Worker             if (prevType != 2)
527*f6dc9357SAndroid Build Coastguard Worker             {
528*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[2];
529*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[2] = _deltaReps[1];
530*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[1] = _deltaReps[0];
531*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[0] = distance;
532*f6dc9357SAndroid Build Coastguard Worker             }
533*f6dc9357SAndroid Build Coastguard Worker             else
534*f6dc9357SAndroid Build Coastguard Worker             {
535*f6dc9357SAndroid Build Coastguard Worker               distance = _deltaReps[3];
536*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[3] = _deltaReps[2];
537*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[2] = _deltaReps[1];
538*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[1] = _deltaReps[0];
539*f6dc9357SAndroid Build Coastguard Worker               _deltaReps[0] = distance;
540*f6dc9357SAndroid Build Coastguard Worker             }
541*f6dc9357SAndroid Build Coastguard Worker           }
542*f6dc9357SAndroid Build Coastguard Worker           distance32 = (UInt32)_deltaReps[0] & 0xFFFFFFFF;
543*f6dc9357SAndroid Build Coastguard Worker           power = (UInt32)(_deltaReps[0] >> 32);
544*f6dc9357SAndroid Build Coastguard Worker         }
545*f6dc9357SAndroid Build Coastguard Worker 
546*f6dc9357SAndroid Build Coastguard Worker         const UInt32 dist = (distance32 << power);
547*f6dc9357SAndroid Build Coastguard Worker 
548*f6dc9357SAndroid Build Coastguard Worker         unsigned lenSlot;
549*f6dc9357SAndroid Build Coastguard Worker         HUFF_DEC(lenSlot, m_LenDecoder)
550*f6dc9357SAndroid Build Coastguard Worker         LIMIT_CHECK
551*f6dc9357SAndroid Build Coastguard Worker 
552*f6dc9357SAndroid Build Coastguard Worker         UInt32 len = g_LenBases[lenSlot];
553*f6dc9357SAndroid Build Coastguard Worker         {
554*f6dc9357SAndroid Build Coastguard Worker           const unsigned numDirectBits = k_LenDirectBits[lenSlot];
555*f6dc9357SAndroid Build Coastguard Worker           READ_BITS_CHECK(numDirectBits)
556*f6dc9357SAndroid Build Coastguard Worker           len += _bs.ReadBits32(numDirectBits);
557*f6dc9357SAndroid Build Coastguard Worker         }
558*f6dc9357SAndroid Build Coastguard Worker         // LIMIT_CHECK
559*f6dc9357SAndroid Build Coastguard Worker 
560*f6dc9357SAndroid Build Coastguard Worker         if (len > outSize - _pos)
561*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
562*f6dc9357SAndroid Build Coastguard Worker 
563*f6dc9357SAndroid Build Coastguard Worker         size_t span = (size_t)1 << power;
564*f6dc9357SAndroid Build Coastguard Worker         if ((UInt64)dist + span > _pos)
565*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
566*f6dc9357SAndroid Build Coastguard Worker         Byte *dest = _win + _pos - span;
567*f6dc9357SAndroid Build Coastguard Worker         const Byte *src = dest - dist;
568*f6dc9357SAndroid Build Coastguard Worker         _pos += len;
569*f6dc9357SAndroid Build Coastguard Worker         do
570*f6dc9357SAndroid Build Coastguard Worker         {
571*f6dc9357SAndroid Build Coastguard Worker           *(dest + span) = (Byte)(*(dest) + *(src + span) - *(src));
572*f6dc9357SAndroid Build Coastguard Worker           src++;
573*f6dc9357SAndroid Build Coastguard Worker           dest++;
574*f6dc9357SAndroid Build Coastguard Worker         }
575*f6dc9357SAndroid Build Coastguard Worker         while (--len);
576*f6dc9357SAndroid Build Coastguard Worker 
577*f6dc9357SAndroid Build Coastguard Worker         prevType = 2;
578*f6dc9357SAndroid Build Coastguard Worker       }
579*f6dc9357SAndroid Build Coastguard Worker     }
580*f6dc9357SAndroid Build Coastguard Worker   }
581*f6dc9357SAndroid Build Coastguard Worker 
582*f6dc9357SAndroid Build Coastguard Worker   _rc.Normalize();
583*f6dc9357SAndroid Build Coastguard Worker   if (_rc.code != 0)
584*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
585*f6dc9357SAndroid Build Coastguard Worker   if (_rc.cur > _bs._buf
586*f6dc9357SAndroid Build Coastguard Worker       || (_rc.cur == _bs._buf && _bs._bitPos != 0))
587*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
588*f6dc9357SAndroid Build Coastguard Worker 
589*f6dc9357SAndroid Build Coastguard Worker   /*
590*f6dc9357SAndroid Build Coastguard Worker   int delta = (int)(_bs._buf - _rc.cur);
591*f6dc9357SAndroid Build Coastguard Worker   if (_bs._bitPos != 0)
592*f6dc9357SAndroid Build Coastguard Worker     delta--;
593*f6dc9357SAndroid Build Coastguard Worker   if ((delta & 1))
594*f6dc9357SAndroid Build Coastguard Worker     delta--;
595*f6dc9357SAndroid Build Coastguard Worker   printf("%d ", delta);
596*f6dc9357SAndroid Build Coastguard Worker   */
597*f6dc9357SAndroid Build Coastguard Worker 
598*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
599*f6dc9357SAndroid Build Coastguard Worker }
600*f6dc9357SAndroid Build Coastguard Worker 
Code(const Byte * in,size_t inSize,Byte * out,size_t outSize)601*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::Code(const Byte *in, size_t inSize, Byte *out, size_t outSize)
602*f6dc9357SAndroid Build Coastguard Worker {
603*f6dc9357SAndroid Build Coastguard Worker   if (!_x86_history)
604*f6dc9357SAndroid Build Coastguard Worker   {
605*f6dc9357SAndroid Build Coastguard Worker     _x86_history = (Int32 *)::MidAlloc(sizeof(Int32) * k_x86_HistorySize);
606*f6dc9357SAndroid Build Coastguard Worker     if (!_x86_history)
607*f6dc9357SAndroid Build Coastguard Worker       return E_OUTOFMEMORY;
608*f6dc9357SAndroid Build Coastguard Worker   }
609*f6dc9357SAndroid Build Coastguard Worker   HRESULT res;
610*f6dc9357SAndroid Build Coastguard Worker   // try
611*f6dc9357SAndroid Build Coastguard Worker   {
612*f6dc9357SAndroid Build Coastguard Worker     res = CodeReal(in, inSize, out, outSize);
613*f6dc9357SAndroid Build Coastguard Worker   }
614*f6dc9357SAndroid Build Coastguard Worker   // catch (...) { res = S_FALSE; }
615*f6dc9357SAndroid Build Coastguard Worker   x86_Filter(out, (UInt32)_pos, _x86_history);
616*f6dc9357SAndroid Build Coastguard Worker   return res;
617*f6dc9357SAndroid Build Coastguard Worker }
618*f6dc9357SAndroid Build Coastguard Worker 
619*f6dc9357SAndroid Build Coastguard Worker }}
620