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