xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/BZip2Decoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // BZip2Decoder.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #include "CopyCoder.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker /*
8*f6dc9357SAndroid Build Coastguard Worker #include <stdio.h>
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuTicks.h"
10*f6dc9357SAndroid Build Coastguard Worker */
11*f6dc9357SAndroid Build Coastguard Worker #define TICKS_START
12*f6dc9357SAndroid Build Coastguard Worker #define TICKS_UPDATE(n)
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker /*
16*f6dc9357SAndroid Build Coastguard Worker #define PRIN(s) printf(s "\n"); fflush(stdout);
17*f6dc9357SAndroid Build Coastguard Worker #define PRIN_VAL(s, val) printf(s " = %u \n", val); fflush(stdout);
18*f6dc9357SAndroid Build Coastguard Worker */
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #define PRIN(s)
21*f6dc9357SAndroid Build Coastguard Worker #define PRIN_VAL(s, val)
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/Alloc.h"
25*f6dc9357SAndroid Build Coastguard Worker 
26*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
27*f6dc9357SAndroid Build Coastguard Worker 
28*f6dc9357SAndroid Build Coastguard Worker #include "BZip2Decoder.h"
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker namespace NCompress {
32*f6dc9357SAndroid Build Coastguard Worker namespace NBZip2 {
33*f6dc9357SAndroid Build Coastguard Worker 
34*f6dc9357SAndroid Build Coastguard Worker // #undef NO_INLINE
35*f6dc9357SAndroid Build Coastguard Worker #define NO_INLINE Z7_NO_INLINE
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #define BZIP2_BYTE_MODE
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kInBufSize = (UInt32)1 << 17;
41*f6dc9357SAndroid Build Coastguard Worker static const size_t kOutBufSize = (size_t)1 << 20;
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kProgressStep = (UInt32)1 << 16;
44*f6dc9357SAndroid Build Coastguard Worker 
45*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN(64)
46*f6dc9357SAndroid Build Coastguard Worker static const UInt16 kRandNums[512] = {
47*f6dc9357SAndroid Build Coastguard Worker    619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
48*f6dc9357SAndroid Build Coastguard Worker    985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
49*f6dc9357SAndroid Build Coastguard Worker    733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
50*f6dc9357SAndroid Build Coastguard Worker    419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
51*f6dc9357SAndroid Build Coastguard Worker    878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
52*f6dc9357SAndroid Build Coastguard Worker    862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
53*f6dc9357SAndroid Build Coastguard Worker    150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
54*f6dc9357SAndroid Build Coastguard Worker    170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
55*f6dc9357SAndroid Build Coastguard Worker    73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
56*f6dc9357SAndroid Build Coastguard Worker    909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
57*f6dc9357SAndroid Build Coastguard Worker    641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
58*f6dc9357SAndroid Build Coastguard Worker    161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
59*f6dc9357SAndroid Build Coastguard Worker    382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
60*f6dc9357SAndroid Build Coastguard Worker    98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
61*f6dc9357SAndroid Build Coastguard Worker    227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
62*f6dc9357SAndroid Build Coastguard Worker    469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
63*f6dc9357SAndroid Build Coastguard Worker    184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
64*f6dc9357SAndroid Build Coastguard Worker    715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
65*f6dc9357SAndroid Build Coastguard Worker    951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
66*f6dc9357SAndroid Build Coastguard Worker    652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
67*f6dc9357SAndroid Build Coastguard Worker    645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
68*f6dc9357SAndroid Build Coastguard Worker    609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
69*f6dc9357SAndroid Build Coastguard Worker    653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
70*f6dc9357SAndroid Build Coastguard Worker    411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
71*f6dc9357SAndroid Build Coastguard Worker    170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
72*f6dc9357SAndroid Build Coastguard Worker    857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
73*f6dc9357SAndroid Build Coastguard Worker    669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
74*f6dc9357SAndroid Build Coastguard Worker    944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
75*f6dc9357SAndroid Build Coastguard Worker    344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
76*f6dc9357SAndroid Build Coastguard Worker    897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
77*f6dc9357SAndroid Build Coastguard Worker    433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
78*f6dc9357SAndroid Build Coastguard Worker    686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
79*f6dc9357SAndroid Build Coastguard Worker    946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
80*f6dc9357SAndroid Build Coastguard Worker    978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
81*f6dc9357SAndroid Build Coastguard Worker    680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
82*f6dc9357SAndroid Build Coastguard Worker    707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
83*f6dc9357SAndroid Build Coastguard Worker    297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
84*f6dc9357SAndroid Build Coastguard Worker    134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
85*f6dc9357SAndroid Build Coastguard Worker    343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
86*f6dc9357SAndroid Build Coastguard Worker    140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
87*f6dc9357SAndroid Build Coastguard Worker    170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
88*f6dc9357SAndroid Build Coastguard Worker    369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
89*f6dc9357SAndroid Build Coastguard Worker    804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
90*f6dc9357SAndroid Build Coastguard Worker    896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
91*f6dc9357SAndroid Build Coastguard Worker    661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
92*f6dc9357SAndroid Build Coastguard Worker    768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
93*f6dc9357SAndroid Build Coastguard Worker    61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
94*f6dc9357SAndroid Build Coastguard Worker    372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
95*f6dc9357SAndroid Build Coastguard Worker    780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
96*f6dc9357SAndroid Build Coastguard Worker    920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
97*f6dc9357SAndroid Build Coastguard Worker    645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
98*f6dc9357SAndroid Build Coastguard Worker    936, 638
99*f6dc9357SAndroid Build Coastguard Worker };
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker enum EState
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker   STATE_STREAM_SIGNATURE,
106*f6dc9357SAndroid Build Coastguard Worker   STATE_BLOCK_SIGNATURE,
107*f6dc9357SAndroid Build Coastguard Worker 
108*f6dc9357SAndroid Build Coastguard Worker   STATE_BLOCK_START,
109*f6dc9357SAndroid Build Coastguard Worker   STATE_ORIG_BITS,
110*f6dc9357SAndroid Build Coastguard Worker   STATE_IN_USE,
111*f6dc9357SAndroid Build Coastguard Worker   STATE_IN_USE2,
112*f6dc9357SAndroid Build Coastguard Worker   STATE_NUM_TABLES,
113*f6dc9357SAndroid Build Coastguard Worker   STATE_NUM_SELECTORS,
114*f6dc9357SAndroid Build Coastguard Worker   STATE_SELECTORS,
115*f6dc9357SAndroid Build Coastguard Worker   STATE_LEVELS,
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker   STATE_BLOCK_SYMBOLS,
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   STATE_STREAM_FINISHED
120*f6dc9357SAndroid Build Coastguard Worker };
121*f6dc9357SAndroid Build Coastguard Worker 
122*f6dc9357SAndroid Build Coastguard Worker 
123*f6dc9357SAndroid Build Coastguard Worker #define UPDATE_VAL_2(val, num_bits) { \
124*f6dc9357SAndroid Build Coastguard Worker   val |= (UInt32)(*_buf) << (24 - num_bits); \
125*f6dc9357SAndroid Build Coastguard Worker   num_bits += 8; \
126*f6dc9357SAndroid Build Coastguard Worker  _buf++; \
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker 
129*f6dc9357SAndroid Build Coastguard Worker #define UPDATE_VAL  UPDATE_VAL_2(VAL, NUM_BITS)
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker #define READ_BITS(res, num) { \
132*f6dc9357SAndroid Build Coastguard Worker   while (_numBits < num) { \
133*f6dc9357SAndroid Build Coastguard Worker     if (_buf == _lim) return SZ_OK; \
134*f6dc9357SAndroid Build Coastguard Worker     UPDATE_VAL_2(_value, _numBits) } \
135*f6dc9357SAndroid Build Coastguard Worker   res = _value >> (32 - num); \
136*f6dc9357SAndroid Build Coastguard Worker   _value <<= num; \
137*f6dc9357SAndroid Build Coastguard Worker   _numBits -= num; \
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker #define READ_BITS_8(res, num) { \
141*f6dc9357SAndroid Build Coastguard Worker   if (_numBits < num) { \
142*f6dc9357SAndroid Build Coastguard Worker     if (_buf == _lim) return SZ_OK; \
143*f6dc9357SAndroid Build Coastguard Worker     UPDATE_VAL_2(_value, _numBits) } \
144*f6dc9357SAndroid Build Coastguard Worker   res = _value >> (32 - num); \
145*f6dc9357SAndroid Build Coastguard Worker   _value <<= num; \
146*f6dc9357SAndroid Build Coastguard Worker   _numBits -= num; \
147*f6dc9357SAndroid Build Coastguard Worker }
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker #define READ_BIT(res) READ_BITS_8(res, 1)
150*f6dc9357SAndroid Build Coastguard Worker 
151*f6dc9357SAndroid Build Coastguard Worker 
152*f6dc9357SAndroid Build Coastguard Worker 
153*f6dc9357SAndroid Build Coastguard Worker #define VAL _value2
154*f6dc9357SAndroid Build Coastguard Worker // #define NUM_BITS _numBits2
155*f6dc9357SAndroid Build Coastguard Worker #define NUM_BITS _numBits
156*f6dc9357SAndroid Build Coastguard Worker #define BLOCK_SIZE blockSize2
157*f6dc9357SAndroid Build Coastguard Worker #define RUN_COUNTER runCounter2
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker #define LOAD_LOCAL \
160*f6dc9357SAndroid Build Coastguard Worker     UInt32 VAL = this->_value; \
161*f6dc9357SAndroid Build Coastguard Worker     /* unsigned NUM_BITS = this->_numBits; */ \
162*f6dc9357SAndroid Build Coastguard Worker     UInt32 BLOCK_SIZE = this->blockSize; \
163*f6dc9357SAndroid Build Coastguard Worker     UInt32 RUN_COUNTER = this->runCounter; \
164*f6dc9357SAndroid Build Coastguard Worker 
165*f6dc9357SAndroid Build Coastguard Worker #define SAVE_LOCAL \
166*f6dc9357SAndroid Build Coastguard Worker     this->_value = VAL; \
167*f6dc9357SAndroid Build Coastguard Worker     /* this->_numBits = NUM_BITS; */ \
168*f6dc9357SAndroid Build Coastguard Worker     this->blockSize = BLOCK_SIZE; \
169*f6dc9357SAndroid Build Coastguard Worker     this->runCounter = RUN_COUNTER; \
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker 
ReadByte(int & b)173*f6dc9357SAndroid Build Coastguard Worker SRes CBitDecoder::ReadByte(int &b)
174*f6dc9357SAndroid Build Coastguard Worker {
175*f6dc9357SAndroid Build Coastguard Worker   b = -1;
176*f6dc9357SAndroid Build Coastguard Worker   READ_BITS_8(b, 8)
177*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
178*f6dc9357SAndroid Build Coastguard Worker }
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
ReadStreamSignature2()182*f6dc9357SAndroid Build Coastguard Worker SRes CBase::ReadStreamSignature2()
183*f6dc9357SAndroid Build Coastguard Worker {
184*f6dc9357SAndroid Build Coastguard Worker   for (;;)
185*f6dc9357SAndroid Build Coastguard Worker   {
186*f6dc9357SAndroid Build Coastguard Worker     unsigned b;
187*f6dc9357SAndroid Build Coastguard Worker     READ_BITS_8(b, 8)
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker     if (   (state2 == 0 && b != kArSig0)
190*f6dc9357SAndroid Build Coastguard Worker         || (state2 == 1 && b != kArSig1)
191*f6dc9357SAndroid Build Coastguard Worker         || (state2 == 2 && b != kArSig2)
192*f6dc9357SAndroid Build Coastguard Worker         || (state2 == 3 && (b <= kArSig3 || b > kArSig3 + kBlockSizeMultMax)))
193*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_DATA;
194*f6dc9357SAndroid Build Coastguard Worker     state2++;
195*f6dc9357SAndroid Build Coastguard Worker 
196*f6dc9357SAndroid Build Coastguard Worker     if (state2 == 4)
197*f6dc9357SAndroid Build Coastguard Worker     {
198*f6dc9357SAndroid Build Coastguard Worker       blockSizeMax = (UInt32)(b - kArSig3) * kBlockSizeStep;
199*f6dc9357SAndroid Build Coastguard Worker       CombinedCrc.Init();
200*f6dc9357SAndroid Build Coastguard Worker       state = STATE_BLOCK_SIGNATURE;
201*f6dc9357SAndroid Build Coastguard Worker       state2 = 0;
202*f6dc9357SAndroid Build Coastguard Worker       return SZ_OK;
203*f6dc9357SAndroid Build Coastguard Worker     }
204*f6dc9357SAndroid Build Coastguard Worker   }
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker 
IsEndSig(const Byte * p)208*f6dc9357SAndroid Build Coastguard Worker bool IsEndSig(const Byte *p) throw()
209*f6dc9357SAndroid Build Coastguard Worker {
210*f6dc9357SAndroid Build Coastguard Worker   return
211*f6dc9357SAndroid Build Coastguard Worker     p[0] == kFinSig0 &&
212*f6dc9357SAndroid Build Coastguard Worker     p[1] == kFinSig1 &&
213*f6dc9357SAndroid Build Coastguard Worker     p[2] == kFinSig2 &&
214*f6dc9357SAndroid Build Coastguard Worker     p[3] == kFinSig3 &&
215*f6dc9357SAndroid Build Coastguard Worker     p[4] == kFinSig4 &&
216*f6dc9357SAndroid Build Coastguard Worker     p[5] == kFinSig5;
217*f6dc9357SAndroid Build Coastguard Worker }
218*f6dc9357SAndroid Build Coastguard Worker 
IsBlockSig(const Byte * p)219*f6dc9357SAndroid Build Coastguard Worker bool IsBlockSig(const Byte *p) throw()
220*f6dc9357SAndroid Build Coastguard Worker {
221*f6dc9357SAndroid Build Coastguard Worker   return
222*f6dc9357SAndroid Build Coastguard Worker     p[0] == kBlockSig0 &&
223*f6dc9357SAndroid Build Coastguard Worker     p[1] == kBlockSig1 &&
224*f6dc9357SAndroid Build Coastguard Worker     p[2] == kBlockSig2 &&
225*f6dc9357SAndroid Build Coastguard Worker     p[3] == kBlockSig3 &&
226*f6dc9357SAndroid Build Coastguard Worker     p[4] == kBlockSig4 &&
227*f6dc9357SAndroid Build Coastguard Worker     p[5] == kBlockSig5;
228*f6dc9357SAndroid Build Coastguard Worker }
229*f6dc9357SAndroid Build Coastguard Worker 
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
ReadBlockSignature2()232*f6dc9357SAndroid Build Coastguard Worker SRes CBase::ReadBlockSignature2()
233*f6dc9357SAndroid Build Coastguard Worker {
234*f6dc9357SAndroid Build Coastguard Worker   while (state2 < 10)
235*f6dc9357SAndroid Build Coastguard Worker   {
236*f6dc9357SAndroid Build Coastguard Worker     unsigned b;
237*f6dc9357SAndroid Build Coastguard Worker     READ_BITS_8(b, 8)
238*f6dc9357SAndroid Build Coastguard Worker     temp[state2] = (Byte)b;
239*f6dc9357SAndroid Build Coastguard Worker     state2++;
240*f6dc9357SAndroid Build Coastguard Worker   }
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker   crc = 0;
243*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < 4; i++)
244*f6dc9357SAndroid Build Coastguard Worker   {
245*f6dc9357SAndroid Build Coastguard Worker     crc <<= 8;
246*f6dc9357SAndroid Build Coastguard Worker     crc |= temp[6 + i];
247*f6dc9357SAndroid Build Coastguard Worker   }
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker   if (IsBlockSig(temp))
250*f6dc9357SAndroid Build Coastguard Worker   {
251*f6dc9357SAndroid Build Coastguard Worker     if (!IsBz)
252*f6dc9357SAndroid Build Coastguard Worker       NumStreams++;
253*f6dc9357SAndroid Build Coastguard Worker     NumBlocks++;
254*f6dc9357SAndroid Build Coastguard Worker     IsBz = true;
255*f6dc9357SAndroid Build Coastguard Worker     CombinedCrc.Update(crc);
256*f6dc9357SAndroid Build Coastguard Worker     state = STATE_BLOCK_START;
257*f6dc9357SAndroid Build Coastguard Worker     return SZ_OK;
258*f6dc9357SAndroid Build Coastguard Worker   }
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker   if (!IsEndSig(temp))
261*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_DATA;
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker   if (!IsBz)
264*f6dc9357SAndroid Build Coastguard Worker     NumStreams++;
265*f6dc9357SAndroid Build Coastguard Worker   IsBz = true;
266*f6dc9357SAndroid Build Coastguard Worker 
267*f6dc9357SAndroid Build Coastguard Worker   if (_value != 0)
268*f6dc9357SAndroid Build Coastguard Worker     MinorError = true;
269*f6dc9357SAndroid Build Coastguard Worker 
270*f6dc9357SAndroid Build Coastguard Worker   AlignToByte();
271*f6dc9357SAndroid Build Coastguard Worker 
272*f6dc9357SAndroid Build Coastguard Worker   state = STATE_STREAM_FINISHED;
273*f6dc9357SAndroid Build Coastguard Worker   if (crc != CombinedCrc.GetDigest())
274*f6dc9357SAndroid Build Coastguard Worker   {
275*f6dc9357SAndroid Build Coastguard Worker     StreamCrcError = true;
276*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_DATA;
277*f6dc9357SAndroid Build Coastguard Worker   }
278*f6dc9357SAndroid Build Coastguard Worker   return SZ_OK;
279*f6dc9357SAndroid Build Coastguard Worker }
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker 
282*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
ReadBlock2()283*f6dc9357SAndroid Build Coastguard Worker SRes CBase::ReadBlock2()
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker   if (state != STATE_BLOCK_SYMBOLS) {
286*f6dc9357SAndroid Build Coastguard Worker   PRIN("ReadBlock2")
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_BLOCK_START)
289*f6dc9357SAndroid Build Coastguard Worker   {
290*f6dc9357SAndroid Build Coastguard Worker     if (Props.randMode)
291*f6dc9357SAndroid Build Coastguard Worker     {
292*f6dc9357SAndroid Build Coastguard Worker       READ_BIT(Props.randMode)
293*f6dc9357SAndroid Build Coastguard Worker     }
294*f6dc9357SAndroid Build Coastguard Worker     state = STATE_ORIG_BITS;
295*f6dc9357SAndroid Build Coastguard Worker     // g_Tick = GetCpuTicks();
296*f6dc9357SAndroid Build Coastguard Worker   }
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_ORIG_BITS)
299*f6dc9357SAndroid Build Coastguard Worker   {
300*f6dc9357SAndroid Build Coastguard Worker     READ_BITS(Props.origPtr, kNumOrigBits)
301*f6dc9357SAndroid Build Coastguard Worker     if (Props.origPtr >= blockSizeMax)
302*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_DATA;
303*f6dc9357SAndroid Build Coastguard Worker     state = STATE_IN_USE;
304*f6dc9357SAndroid Build Coastguard Worker   }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker   // why original code compares origPtr to (UInt32)(10 + blockSizeMax)) ?
307*f6dc9357SAndroid Build Coastguard Worker 
308*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_IN_USE)
309*f6dc9357SAndroid Build Coastguard Worker   {
310*f6dc9357SAndroid Build Coastguard Worker     READ_BITS(state2, 16)
311*f6dc9357SAndroid Build Coastguard Worker     state = STATE_IN_USE2;
312*f6dc9357SAndroid Build Coastguard Worker     state3 = 0;
313*f6dc9357SAndroid Build Coastguard Worker     numInUse = 0;
314*f6dc9357SAndroid Build Coastguard Worker     mtf.StartInit();
315*f6dc9357SAndroid Build Coastguard Worker   }
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_IN_USE2)
318*f6dc9357SAndroid Build Coastguard Worker   {
319*f6dc9357SAndroid Build Coastguard Worker     for (; state3 < 256; state3++)
320*f6dc9357SAndroid Build Coastguard Worker       if (state2 & ((UInt32)0x8000 >> (state3 >> 4)))
321*f6dc9357SAndroid Build Coastguard Worker       {
322*f6dc9357SAndroid Build Coastguard Worker         unsigned b;
323*f6dc9357SAndroid Build Coastguard Worker         READ_BIT(b)
324*f6dc9357SAndroid Build Coastguard Worker         if (b)
325*f6dc9357SAndroid Build Coastguard Worker           mtf.Add(numInUse++, (Byte)state3);
326*f6dc9357SAndroid Build Coastguard Worker       }
327*f6dc9357SAndroid Build Coastguard Worker     if (numInUse == 0)
328*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_DATA;
329*f6dc9357SAndroid Build Coastguard Worker     state = STATE_NUM_TABLES;
330*f6dc9357SAndroid Build Coastguard Worker   }
331*f6dc9357SAndroid Build Coastguard Worker 
332*f6dc9357SAndroid Build Coastguard Worker 
333*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_NUM_TABLES)
334*f6dc9357SAndroid Build Coastguard Worker   {
335*f6dc9357SAndroid Build Coastguard Worker     READ_BITS_8(numTables, kNumTablesBits)
336*f6dc9357SAndroid Build Coastguard Worker     state = STATE_NUM_SELECTORS;
337*f6dc9357SAndroid Build Coastguard Worker     if (numTables < kNumTablesMin || numTables > kNumTablesMax)
338*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_DATA;
339*f6dc9357SAndroid Build Coastguard Worker   }
340*f6dc9357SAndroid Build Coastguard Worker 
341*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_NUM_SELECTORS)
342*f6dc9357SAndroid Build Coastguard Worker   {
343*f6dc9357SAndroid Build Coastguard Worker     READ_BITS(numSelectors, kNumSelectorsBits)
344*f6dc9357SAndroid Build Coastguard Worker     state = STATE_SELECTORS;
345*f6dc9357SAndroid Build Coastguard Worker     state2 = 0x543210;
346*f6dc9357SAndroid Build Coastguard Worker     state3 = 0;
347*f6dc9357SAndroid Build Coastguard Worker     state4 = 0;
348*f6dc9357SAndroid Build Coastguard Worker     // lbzip2 can write small number of additional selectors,
349*f6dc9357SAndroid Build Coastguard Worker     // 20.01: we allow big number of selectors here like bzip2-1.0.8
350*f6dc9357SAndroid Build Coastguard Worker     if (numSelectors == 0
351*f6dc9357SAndroid Build Coastguard Worker       // || numSelectors > kNumSelectorsMax_Decoder
352*f6dc9357SAndroid Build Coastguard Worker       )
353*f6dc9357SAndroid Build Coastguard Worker       return SZ_ERROR_DATA;
354*f6dc9357SAndroid Build Coastguard Worker   }
355*f6dc9357SAndroid Build Coastguard Worker 
356*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_SELECTORS)
357*f6dc9357SAndroid Build Coastguard Worker   {
358*f6dc9357SAndroid Build Coastguard Worker     const unsigned kMtfBits = 4;
359*f6dc9357SAndroid Build Coastguard Worker     const UInt32 kMtfMask = (1 << kMtfBits) - 1;
360*f6dc9357SAndroid Build Coastguard Worker     do
361*f6dc9357SAndroid Build Coastguard Worker     {
362*f6dc9357SAndroid Build Coastguard Worker       for (;;)
363*f6dc9357SAndroid Build Coastguard Worker       {
364*f6dc9357SAndroid Build Coastguard Worker         unsigned b;
365*f6dc9357SAndroid Build Coastguard Worker         READ_BIT(b)
366*f6dc9357SAndroid Build Coastguard Worker         if (!b)
367*f6dc9357SAndroid Build Coastguard Worker           break;
368*f6dc9357SAndroid Build Coastguard Worker         if (++state4 >= numTables)
369*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_DATA;
370*f6dc9357SAndroid Build Coastguard Worker       }
371*f6dc9357SAndroid Build Coastguard Worker       const UInt32 tmp = (state2 >> (kMtfBits * state4)) & kMtfMask;
372*f6dc9357SAndroid Build Coastguard Worker       const UInt32 mask = ((UInt32)1 << ((state4 + 1) * kMtfBits)) - 1;
373*f6dc9357SAndroid Build Coastguard Worker       state4 = 0;
374*f6dc9357SAndroid Build Coastguard Worker       state2 = ((state2 << kMtfBits) & mask) | (state2 & ~mask) | tmp;
375*f6dc9357SAndroid Build Coastguard Worker       // 20.01: here we keep compatibility with bzip2-1.0.8 decoder:
376*f6dc9357SAndroid Build Coastguard Worker       if (state3 < kNumSelectorsMax)
377*f6dc9357SAndroid Build Coastguard Worker         selectors[state3] = (Byte)tmp;
378*f6dc9357SAndroid Build Coastguard Worker     }
379*f6dc9357SAndroid Build Coastguard Worker     while (++state3 < numSelectors);
380*f6dc9357SAndroid Build Coastguard Worker 
381*f6dc9357SAndroid Build Coastguard Worker     // we allowed additional dummy selector records filled above to support lbzip2's archives.
382*f6dc9357SAndroid Build Coastguard Worker     // but we still don't allow to use these additional dummy selectors in the code bellow
383*f6dc9357SAndroid Build Coastguard Worker     // bzip2 1.0.8 decoder also has similar restriction.
384*f6dc9357SAndroid Build Coastguard Worker 
385*f6dc9357SAndroid Build Coastguard Worker     if (numSelectors > kNumSelectorsMax)
386*f6dc9357SAndroid Build Coastguard Worker       numSelectors = kNumSelectorsMax;
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker     state = STATE_LEVELS;
389*f6dc9357SAndroid Build Coastguard Worker     state2 = 0;
390*f6dc9357SAndroid Build Coastguard Worker     state3 = 0;
391*f6dc9357SAndroid Build Coastguard Worker   }
392*f6dc9357SAndroid Build Coastguard Worker 
393*f6dc9357SAndroid Build Coastguard Worker   if (state == STATE_LEVELS)
394*f6dc9357SAndroid Build Coastguard Worker   {
395*f6dc9357SAndroid Build Coastguard Worker     do
396*f6dc9357SAndroid Build Coastguard Worker     {
397*f6dc9357SAndroid Build Coastguard Worker       if (state3 == 0)
398*f6dc9357SAndroid Build Coastguard Worker       {
399*f6dc9357SAndroid Build Coastguard Worker         READ_BITS_8(state3, kNumLevelsBits)
400*f6dc9357SAndroid Build Coastguard Worker         state4 = 0;
401*f6dc9357SAndroid Build Coastguard Worker         state5 = 0;
402*f6dc9357SAndroid Build Coastguard Worker       }
403*f6dc9357SAndroid Build Coastguard Worker       const unsigned alphaSize = numInUse + 2;
404*f6dc9357SAndroid Build Coastguard Worker       for (; state4 < alphaSize; state4++)
405*f6dc9357SAndroid Build Coastguard Worker       {
406*f6dc9357SAndroid Build Coastguard Worker         for (;;)
407*f6dc9357SAndroid Build Coastguard Worker         {
408*f6dc9357SAndroid Build Coastguard Worker           if (state3 < 1 || state3 > kMaxHuffmanLen)
409*f6dc9357SAndroid Build Coastguard Worker             return SZ_ERROR_DATA;
410*f6dc9357SAndroid Build Coastguard Worker 
411*f6dc9357SAndroid Build Coastguard Worker           if (state5 == 0)
412*f6dc9357SAndroid Build Coastguard Worker           {
413*f6dc9357SAndroid Build Coastguard Worker             unsigned b;
414*f6dc9357SAndroid Build Coastguard Worker             READ_BIT(b)
415*f6dc9357SAndroid Build Coastguard Worker             if (!b)
416*f6dc9357SAndroid Build Coastguard Worker               break;
417*f6dc9357SAndroid Build Coastguard Worker           }
418*f6dc9357SAndroid Build Coastguard Worker 
419*f6dc9357SAndroid Build Coastguard Worker           state5 = 1;
420*f6dc9357SAndroid Build Coastguard Worker           unsigned b;
421*f6dc9357SAndroid Build Coastguard Worker           READ_BIT(b)
422*f6dc9357SAndroid Build Coastguard Worker 
423*f6dc9357SAndroid Build Coastguard Worker           state5 = 0;
424*f6dc9357SAndroid Build Coastguard Worker           state3++;
425*f6dc9357SAndroid Build Coastguard Worker           state3 -= (b << 1);
426*f6dc9357SAndroid Build Coastguard Worker         }
427*f6dc9357SAndroid Build Coastguard Worker         lens[state4] = (Byte)state3;
428*f6dc9357SAndroid Build Coastguard Worker         state5 = 0;
429*f6dc9357SAndroid Build Coastguard Worker       }
430*f6dc9357SAndroid Build Coastguard Worker 
431*f6dc9357SAndroid Build Coastguard Worker       // 19.03: we use non-full Build() to support lbzip2 archives.
432*f6dc9357SAndroid Build Coastguard Worker       // lbzip2 2.5 can produce dummy tree, where lens[i] = kMaxHuffmanLen
433*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = state4; i < kMaxAlphaSize; i++)
434*f6dc9357SAndroid Build Coastguard Worker         lens[i] = 0;
435*f6dc9357SAndroid Build Coastguard Worker       if (!huffs[state2].Build(lens)) // k_BuildMode_Partial
436*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_DATA;
437*f6dc9357SAndroid Build Coastguard Worker       state3 = 0;
438*f6dc9357SAndroid Build Coastguard Worker     }
439*f6dc9357SAndroid Build Coastguard Worker     while (++state2 < numTables);
440*f6dc9357SAndroid Build Coastguard Worker 
441*f6dc9357SAndroid Build Coastguard Worker     {
442*f6dc9357SAndroid Build Coastguard Worker       UInt32 *counters = this->Counters;
443*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < 256; i++)
444*f6dc9357SAndroid Build Coastguard Worker         counters[i] = 0;
445*f6dc9357SAndroid Build Coastguard Worker     }
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker     state = STATE_BLOCK_SYMBOLS;
448*f6dc9357SAndroid Build Coastguard Worker 
449*f6dc9357SAndroid Build Coastguard Worker     groupIndex = 0;
450*f6dc9357SAndroid Build Coastguard Worker     groupSize = kGroupSize;
451*f6dc9357SAndroid Build Coastguard Worker     runPower = 0;
452*f6dc9357SAndroid Build Coastguard Worker     runCounter = 0;
453*f6dc9357SAndroid Build Coastguard Worker     blockSize = 0;
454*f6dc9357SAndroid Build Coastguard Worker   }
455*f6dc9357SAndroid Build Coastguard Worker 
456*f6dc9357SAndroid Build Coastguard Worker   if (state != STATE_BLOCK_SYMBOLS)
457*f6dc9357SAndroid Build Coastguard Worker     return SZ_ERROR_DATA;
458*f6dc9357SAndroid Build Coastguard Worker 
459*f6dc9357SAndroid Build Coastguard Worker   // g_Ticks[3] += GetCpuTicks() - g_Tick;
460*f6dc9357SAndroid Build Coastguard Worker 
461*f6dc9357SAndroid Build Coastguard Worker   }
462*f6dc9357SAndroid Build Coastguard Worker 
463*f6dc9357SAndroid Build Coastguard Worker   {
464*f6dc9357SAndroid Build Coastguard Worker     LOAD_LOCAL
465*f6dc9357SAndroid Build Coastguard Worker     const CHuffmanDecoder *huf = &huffs[selectors[groupIndex]];
466*f6dc9357SAndroid Build Coastguard Worker 
467*f6dc9357SAndroid Build Coastguard Worker     for (;;)
468*f6dc9357SAndroid Build Coastguard Worker     {
469*f6dc9357SAndroid Build Coastguard Worker       if (groupSize == 0)
470*f6dc9357SAndroid Build Coastguard Worker       {
471*f6dc9357SAndroid Build Coastguard Worker         if (++groupIndex >= numSelectors)
472*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_DATA;
473*f6dc9357SAndroid Build Coastguard Worker         huf = &huffs[selectors[groupIndex]];
474*f6dc9357SAndroid Build Coastguard Worker         groupSize = kGroupSize;
475*f6dc9357SAndroid Build Coastguard Worker       }
476*f6dc9357SAndroid Build Coastguard Worker 
477*f6dc9357SAndroid Build Coastguard Worker       if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL
478*f6dc9357SAndroid Build Coastguard Worker       if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL
479*f6dc9357SAndroid Build Coastguard Worker       if (NUM_BITS < kMaxHuffmanLen && _buf != _lim) { UPDATE_VAL }}}
480*f6dc9357SAndroid Build Coastguard Worker 
481*f6dc9357SAndroid Build Coastguard Worker       unsigned sym;
482*f6dc9357SAndroid Build Coastguard Worker 
483*f6dc9357SAndroid Build Coastguard Worker       #define MOV_POS(bs, len) \
484*f6dc9357SAndroid Build Coastguard Worker       { \
485*f6dc9357SAndroid Build Coastguard Worker         if (NUM_BITS < len) \
486*f6dc9357SAndroid Build Coastguard Worker         { \
487*f6dc9357SAndroid Build Coastguard Worker           SAVE_LOCAL \
488*f6dc9357SAndroid Build Coastguard Worker           return SZ_OK; \
489*f6dc9357SAndroid Build Coastguard Worker         } \
490*f6dc9357SAndroid Build Coastguard Worker         VAL <<= len; \
491*f6dc9357SAndroid Build Coastguard Worker         NUM_BITS -= (unsigned)len; \
492*f6dc9357SAndroid Build Coastguard Worker       }
493*f6dc9357SAndroid Build Coastguard Worker 
494*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kMaxHuffmanLen, kNumTableBits,
495*f6dc9357SAndroid Build Coastguard Worker           VAL,
496*f6dc9357SAndroid Build Coastguard Worker           Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES,
497*f6dc9357SAndroid Build Coastguard Worker           { return SZ_ERROR_DATA; },
498*f6dc9357SAndroid Build Coastguard Worker           MOV_POS, {}, bs)
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker       groupSize--;
501*f6dc9357SAndroid Build Coastguard Worker 
502*f6dc9357SAndroid Build Coastguard Worker       if (sym < 2)
503*f6dc9357SAndroid Build Coastguard Worker       {
504*f6dc9357SAndroid Build Coastguard Worker         RUN_COUNTER += (UInt32)(sym + 1) << runPower;
505*f6dc9357SAndroid Build Coastguard Worker         runPower++;
506*f6dc9357SAndroid Build Coastguard Worker         if (blockSizeMax - BLOCK_SIZE < RUN_COUNTER)
507*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_DATA;
508*f6dc9357SAndroid Build Coastguard Worker         continue;
509*f6dc9357SAndroid Build Coastguard Worker       }
510*f6dc9357SAndroid Build Coastguard Worker 
511*f6dc9357SAndroid Build Coastguard Worker       UInt32 *counters = this->Counters;
512*f6dc9357SAndroid Build Coastguard Worker       if (RUN_COUNTER != 0)
513*f6dc9357SAndroid Build Coastguard Worker       {
514*f6dc9357SAndroid Build Coastguard Worker         UInt32 b = (UInt32)(mtf.Buf[0] & 0xFF);
515*f6dc9357SAndroid Build Coastguard Worker         counters[b] += RUN_COUNTER;
516*f6dc9357SAndroid Build Coastguard Worker         runPower = 0;
517*f6dc9357SAndroid Build Coastguard Worker         #ifdef BZIP2_BYTE_MODE
518*f6dc9357SAndroid Build Coastguard Worker           Byte *dest = (Byte *)(&counters[256 + kBlockSizeMax]) + BLOCK_SIZE;
519*f6dc9357SAndroid Build Coastguard Worker           const Byte *limit = dest + RUN_COUNTER;
520*f6dc9357SAndroid Build Coastguard Worker           BLOCK_SIZE += RUN_COUNTER;
521*f6dc9357SAndroid Build Coastguard Worker           RUN_COUNTER = 0;
522*f6dc9357SAndroid Build Coastguard Worker           do
523*f6dc9357SAndroid Build Coastguard Worker           {
524*f6dc9357SAndroid Build Coastguard Worker             dest[0] = (Byte)b;
525*f6dc9357SAndroid Build Coastguard Worker             dest[1] = (Byte)b;
526*f6dc9357SAndroid Build Coastguard Worker             dest[2] = (Byte)b;
527*f6dc9357SAndroid Build Coastguard Worker             dest[3] = (Byte)b;
528*f6dc9357SAndroid Build Coastguard Worker             dest += 4;
529*f6dc9357SAndroid Build Coastguard Worker           }
530*f6dc9357SAndroid Build Coastguard Worker           while (dest < limit);
531*f6dc9357SAndroid Build Coastguard Worker         #else
532*f6dc9357SAndroid Build Coastguard Worker           UInt32 *dest = &counters[256 + BLOCK_SIZE];
533*f6dc9357SAndroid Build Coastguard Worker           const UInt32 *limit = dest + RUN_COUNTER;
534*f6dc9357SAndroid Build Coastguard Worker           BLOCK_SIZE += RUN_COUNTER;
535*f6dc9357SAndroid Build Coastguard Worker           RUN_COUNTER = 0;
536*f6dc9357SAndroid Build Coastguard Worker           do
537*f6dc9357SAndroid Build Coastguard Worker           {
538*f6dc9357SAndroid Build Coastguard Worker             dest[0] = b;
539*f6dc9357SAndroid Build Coastguard Worker             dest[1] = b;
540*f6dc9357SAndroid Build Coastguard Worker             dest[2] = b;
541*f6dc9357SAndroid Build Coastguard Worker             dest[3] = b;
542*f6dc9357SAndroid Build Coastguard Worker             dest += 4;
543*f6dc9357SAndroid Build Coastguard Worker           }
544*f6dc9357SAndroid Build Coastguard Worker           while (dest < limit);
545*f6dc9357SAndroid Build Coastguard Worker         #endif
546*f6dc9357SAndroid Build Coastguard Worker       }
547*f6dc9357SAndroid Build Coastguard Worker 
548*f6dc9357SAndroid Build Coastguard Worker       sym -= 1;
549*f6dc9357SAndroid Build Coastguard Worker       if (sym < numInUse)
550*f6dc9357SAndroid Build Coastguard Worker       {
551*f6dc9357SAndroid Build Coastguard Worker         if (BLOCK_SIZE >= blockSizeMax)
552*f6dc9357SAndroid Build Coastguard Worker           return SZ_ERROR_DATA;
553*f6dc9357SAndroid Build Coastguard Worker 
554*f6dc9357SAndroid Build Coastguard Worker         // UInt32 b = (UInt32)mtf.GetAndMove((unsigned)sym);
555*f6dc9357SAndroid Build Coastguard Worker 
556*f6dc9357SAndroid Build Coastguard Worker         const unsigned lim = sym >> Z7_MTF_MOVS;
557*f6dc9357SAndroid Build Coastguard Worker         const unsigned pos = (sym & Z7_MTF_MASK) << 3;
558*f6dc9357SAndroid Build Coastguard Worker         CMtfVar next = mtf.Buf[lim];
559*f6dc9357SAndroid Build Coastguard Worker         CMtfVar prev = (next >> pos) & 0xFF;
560*f6dc9357SAndroid Build Coastguard Worker 
561*f6dc9357SAndroid Build Coastguard Worker         #ifdef BZIP2_BYTE_MODE
562*f6dc9357SAndroid Build Coastguard Worker           ((Byte *)(counters + 256 + kBlockSizeMax))[BLOCK_SIZE++] = (Byte)prev;
563*f6dc9357SAndroid Build Coastguard Worker         #else
564*f6dc9357SAndroid Build Coastguard Worker           (counters + 256)[BLOCK_SIZE++] = (UInt32)prev;
565*f6dc9357SAndroid Build Coastguard Worker         #endif
566*f6dc9357SAndroid Build Coastguard Worker         counters[prev]++;
567*f6dc9357SAndroid Build Coastguard Worker 
568*f6dc9357SAndroid Build Coastguard Worker         CMtfVar *m = mtf.Buf;
569*f6dc9357SAndroid Build Coastguard Worker         CMtfVar *mLim = m + lim;
570*f6dc9357SAndroid Build Coastguard Worker         if (lim != 0)
571*f6dc9357SAndroid Build Coastguard Worker         {
572*f6dc9357SAndroid Build Coastguard Worker           do
573*f6dc9357SAndroid Build Coastguard Worker           {
574*f6dc9357SAndroid Build Coastguard Worker             CMtfVar n0 = *m;
575*f6dc9357SAndroid Build Coastguard Worker             *m = (n0 << 8) | prev;
576*f6dc9357SAndroid Build Coastguard Worker             prev = (n0 >> (Z7_MTF_MASK << 3));
577*f6dc9357SAndroid Build Coastguard Worker           }
578*f6dc9357SAndroid Build Coastguard Worker           while (++m != mLim);
579*f6dc9357SAndroid Build Coastguard Worker         }
580*f6dc9357SAndroid Build Coastguard Worker 
581*f6dc9357SAndroid Build Coastguard Worker         CMtfVar mask = (((CMtfVar)0x100 << pos) - 1);
582*f6dc9357SAndroid Build Coastguard Worker         *mLim = (next & ~mask) | (((next << 8) | prev) & mask);
583*f6dc9357SAndroid Build Coastguard Worker         continue;
584*f6dc9357SAndroid Build Coastguard Worker       }
585*f6dc9357SAndroid Build Coastguard Worker 
586*f6dc9357SAndroid Build Coastguard Worker       if (sym != numInUse)
587*f6dc9357SAndroid Build Coastguard Worker         return SZ_ERROR_DATA;
588*f6dc9357SAndroid Build Coastguard Worker       break;
589*f6dc9357SAndroid Build Coastguard Worker     }
590*f6dc9357SAndroid Build Coastguard Worker 
591*f6dc9357SAndroid Build Coastguard Worker     // we write additional item that will be read in DecodeBlock1 for prefetching
592*f6dc9357SAndroid Build Coastguard Worker     #ifdef BZIP2_BYTE_MODE
593*f6dc9357SAndroid Build Coastguard Worker       ((Byte *)(Counters + 256 + kBlockSizeMax))[BLOCK_SIZE] = 0;
594*f6dc9357SAndroid Build Coastguard Worker     #else
595*f6dc9357SAndroid Build Coastguard Worker       (counters + 256)[BLOCK_SIZE] = 0;
596*f6dc9357SAndroid Build Coastguard Worker     #endif
597*f6dc9357SAndroid Build Coastguard Worker 
598*f6dc9357SAndroid Build Coastguard Worker     SAVE_LOCAL
599*f6dc9357SAndroid Build Coastguard Worker     Props.blockSize = blockSize;
600*f6dc9357SAndroid Build Coastguard Worker     state = STATE_BLOCK_SIGNATURE;
601*f6dc9357SAndroid Build Coastguard Worker     state2 = 0;
602*f6dc9357SAndroid Build Coastguard Worker 
603*f6dc9357SAndroid Build Coastguard Worker     PRIN_VAL("origPtr", Props.origPtr);
604*f6dc9357SAndroid Build Coastguard Worker     PRIN_VAL("blockSize", Props.blockSize);
605*f6dc9357SAndroid Build Coastguard Worker 
606*f6dc9357SAndroid Build Coastguard Worker     return (Props.origPtr < Props.blockSize) ? SZ_OK : SZ_ERROR_DATA;
607*f6dc9357SAndroid Build Coastguard Worker   }
608*f6dc9357SAndroid Build Coastguard Worker }
609*f6dc9357SAndroid Build Coastguard Worker 
610*f6dc9357SAndroid Build Coastguard Worker 
611*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
DecodeBlock1(UInt32 * counters,UInt32 blockSize)612*f6dc9357SAndroid Build Coastguard Worker static void DecodeBlock1(UInt32 *counters, UInt32 blockSize)
613*f6dc9357SAndroid Build Coastguard Worker {
614*f6dc9357SAndroid Build Coastguard Worker   {
615*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum = 0;
616*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < 256; i++)
617*f6dc9357SAndroid Build Coastguard Worker     {
618*f6dc9357SAndroid Build Coastguard Worker       const UInt32 v = counters[i];
619*f6dc9357SAndroid Build Coastguard Worker       counters[i] = sum;
620*f6dc9357SAndroid Build Coastguard Worker       sum += v;
621*f6dc9357SAndroid Build Coastguard Worker     }
622*f6dc9357SAndroid Build Coastguard Worker   }
623*f6dc9357SAndroid Build Coastguard Worker 
624*f6dc9357SAndroid Build Coastguard Worker   UInt32 *tt = counters + 256;
625*f6dc9357SAndroid Build Coastguard Worker   // Compute the T^(-1) vector
626*f6dc9357SAndroid Build Coastguard Worker 
627*f6dc9357SAndroid Build Coastguard Worker   // blockSize--;
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker   #ifdef BZIP2_BYTE_MODE
630*f6dc9357SAndroid Build Coastguard Worker 
631*f6dc9357SAndroid Build Coastguard Worker   unsigned c = ((const Byte *)(tt + kBlockSizeMax))[0];
632*f6dc9357SAndroid Build Coastguard Worker 
633*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < blockSize; i++)
634*f6dc9357SAndroid Build Coastguard Worker   {
635*f6dc9357SAndroid Build Coastguard Worker     unsigned c1 = c;
636*f6dc9357SAndroid Build Coastguard Worker     const UInt32 pos = counters[c];
637*f6dc9357SAndroid Build Coastguard Worker     c = ((const Byte *)(tt + kBlockSizeMax))[(size_t)i + 1];
638*f6dc9357SAndroid Build Coastguard Worker     counters[c1] = pos + 1;
639*f6dc9357SAndroid Build Coastguard Worker     tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
640*f6dc9357SAndroid Build Coastguard Worker   }
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker   /*
643*f6dc9357SAndroid Build Coastguard Worker   // last iteration without next character prefetching
644*f6dc9357SAndroid Build Coastguard Worker   {
645*f6dc9357SAndroid Build Coastguard Worker     const UInt32 pos = counters[c];
646*f6dc9357SAndroid Build Coastguard Worker     counters[c] = pos + 1;
647*f6dc9357SAndroid Build Coastguard Worker     tt[pos] = (blockSize << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
648*f6dc9357SAndroid Build Coastguard Worker   }
649*f6dc9357SAndroid Build Coastguard Worker   */
650*f6dc9357SAndroid Build Coastguard Worker 
651*f6dc9357SAndroid Build Coastguard Worker   #else
652*f6dc9357SAndroid Build Coastguard Worker 
653*f6dc9357SAndroid Build Coastguard Worker   unsigned c = (unsigned)(tt[0] & 0xFF);
654*f6dc9357SAndroid Build Coastguard Worker 
655*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < blockSize; i++)
656*f6dc9357SAndroid Build Coastguard Worker   {
657*f6dc9357SAndroid Build Coastguard Worker     unsigned c1 = c;
658*f6dc9357SAndroid Build Coastguard Worker     const UInt32 pos = counters[c];
659*f6dc9357SAndroid Build Coastguard Worker     c = (unsigned)(tt[(size_t)i + 1] & 0xFF);
660*f6dc9357SAndroid Build Coastguard Worker     counters[c1] = pos + 1;
661*f6dc9357SAndroid Build Coastguard Worker     tt[pos] |= (i << 8);
662*f6dc9357SAndroid Build Coastguard Worker   }
663*f6dc9357SAndroid Build Coastguard Worker 
664*f6dc9357SAndroid Build Coastguard Worker   /*
665*f6dc9357SAndroid Build Coastguard Worker   {
666*f6dc9357SAndroid Build Coastguard Worker     const UInt32 pos = counters[c];
667*f6dc9357SAndroid Build Coastguard Worker     counters[c] = pos + 1;
668*f6dc9357SAndroid Build Coastguard Worker     tt[pos] |= (blockSize << 8);
669*f6dc9357SAndroid Build Coastguard Worker   }
670*f6dc9357SAndroid Build Coastguard Worker   */
671*f6dc9357SAndroid Build Coastguard Worker 
672*f6dc9357SAndroid Build Coastguard Worker   #endif
673*f6dc9357SAndroid Build Coastguard Worker 
674*f6dc9357SAndroid Build Coastguard Worker 
675*f6dc9357SAndroid Build Coastguard Worker   /*
676*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < blockSize; i++)
677*f6dc9357SAndroid Build Coastguard Worker   {
678*f6dc9357SAndroid Build Coastguard Worker     #ifdef BZIP2_BYTE_MODE
679*f6dc9357SAndroid Build Coastguard Worker       const unsigned c = ((const Byte *)(tt + kBlockSizeMax))[i];
680*f6dc9357SAndroid Build Coastguard Worker       const UInt32 pos = counters[c]++;
681*f6dc9357SAndroid Build Coastguard Worker       tt[pos] = (i << 8) | ((const Byte *)(tt + kBlockSizeMax))[pos];
682*f6dc9357SAndroid Build Coastguard Worker     #else
683*f6dc9357SAndroid Build Coastguard Worker       const unsigned c = (unsigned)(tt[i] & 0xFF);
684*f6dc9357SAndroid Build Coastguard Worker       const UInt32 pos = counters[c]++;
685*f6dc9357SAndroid Build Coastguard Worker       tt[pos] |= (i << 8);
686*f6dc9357SAndroid Build Coastguard Worker     #endif
687*f6dc9357SAndroid Build Coastguard Worker   }
688*f6dc9357SAndroid Build Coastguard Worker   */
689*f6dc9357SAndroid Build Coastguard Worker }
690*f6dc9357SAndroid Build Coastguard Worker 
691*f6dc9357SAndroid Build Coastguard Worker 
Init(UInt32 origPtr,unsigned randMode)692*f6dc9357SAndroid Build Coastguard Worker void CSpecState::Init(UInt32 origPtr, unsigned randMode) throw()
693*f6dc9357SAndroid Build Coastguard Worker {
694*f6dc9357SAndroid Build Coastguard Worker   _tPos = _tt[_tt[origPtr] >> 8];
695*f6dc9357SAndroid Build Coastguard Worker    _prevByte = (unsigned)(_tPos & 0xFF);
696*f6dc9357SAndroid Build Coastguard Worker   _reps = 0;
697*f6dc9357SAndroid Build Coastguard Worker   _randIndex = 0;
698*f6dc9357SAndroid Build Coastguard Worker   _randToGo = -1;
699*f6dc9357SAndroid Build Coastguard Worker   if (randMode)
700*f6dc9357SAndroid Build Coastguard Worker   {
701*f6dc9357SAndroid Build Coastguard Worker     _randIndex = 1;
702*f6dc9357SAndroid Build Coastguard Worker     _randToGo = kRandNums[0] - 2;
703*f6dc9357SAndroid Build Coastguard Worker   }
704*f6dc9357SAndroid Build Coastguard Worker   _crc.Init();
705*f6dc9357SAndroid Build Coastguard Worker }
706*f6dc9357SAndroid Build Coastguard Worker 
707*f6dc9357SAndroid Build Coastguard Worker 
708*f6dc9357SAndroid Build Coastguard Worker 
709*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
Decode(Byte * data,size_t size)710*f6dc9357SAndroid Build Coastguard Worker Byte * CSpecState::Decode(Byte *data, size_t size) throw()
711*f6dc9357SAndroid Build Coastguard Worker {
712*f6dc9357SAndroid Build Coastguard Worker   if (size == 0)
713*f6dc9357SAndroid Build Coastguard Worker     return data;
714*f6dc9357SAndroid Build Coastguard Worker 
715*f6dc9357SAndroid Build Coastguard Worker   unsigned prevByte = _prevByte;
716*f6dc9357SAndroid Build Coastguard Worker   int reps = _reps;
717*f6dc9357SAndroid Build Coastguard Worker   CBZip2Crc crc = _crc;
718*f6dc9357SAndroid Build Coastguard Worker   const Byte *lim = data + size;
719*f6dc9357SAndroid Build Coastguard Worker 
720*f6dc9357SAndroid Build Coastguard Worker   while (reps > 0)
721*f6dc9357SAndroid Build Coastguard Worker   {
722*f6dc9357SAndroid Build Coastguard Worker     reps--;
723*f6dc9357SAndroid Build Coastguard Worker     *data++ = (Byte)prevByte;
724*f6dc9357SAndroid Build Coastguard Worker     crc.UpdateByte(prevByte);
725*f6dc9357SAndroid Build Coastguard Worker     if (data == lim)
726*f6dc9357SAndroid Build Coastguard Worker       break;
727*f6dc9357SAndroid Build Coastguard Worker   }
728*f6dc9357SAndroid Build Coastguard Worker 
729*f6dc9357SAndroid Build Coastguard Worker   UInt32 tPos = _tPos;
730*f6dc9357SAndroid Build Coastguard Worker   UInt32 blockSize = _blockSize;
731*f6dc9357SAndroid Build Coastguard Worker   const UInt32 *tt = _tt;
732*f6dc9357SAndroid Build Coastguard Worker 
733*f6dc9357SAndroid Build Coastguard Worker   if (data != lim && blockSize)
734*f6dc9357SAndroid Build Coastguard Worker 
735*f6dc9357SAndroid Build Coastguard Worker   for (;;)
736*f6dc9357SAndroid Build Coastguard Worker   {
737*f6dc9357SAndroid Build Coastguard Worker     unsigned b = (unsigned)(tPos & 0xFF);
738*f6dc9357SAndroid Build Coastguard Worker     tPos = tt[tPos >> 8];
739*f6dc9357SAndroid Build Coastguard Worker     blockSize--;
740*f6dc9357SAndroid Build Coastguard Worker 
741*f6dc9357SAndroid Build Coastguard Worker     if (_randToGo >= 0)
742*f6dc9357SAndroid Build Coastguard Worker     {
743*f6dc9357SAndroid Build Coastguard Worker       if (_randToGo == 0)
744*f6dc9357SAndroid Build Coastguard Worker       {
745*f6dc9357SAndroid Build Coastguard Worker         b ^= 1;
746*f6dc9357SAndroid Build Coastguard Worker         _randToGo = kRandNums[_randIndex];
747*f6dc9357SAndroid Build Coastguard Worker         _randIndex++;
748*f6dc9357SAndroid Build Coastguard Worker         _randIndex &= 0x1FF;
749*f6dc9357SAndroid Build Coastguard Worker       }
750*f6dc9357SAndroid Build Coastguard Worker       _randToGo--;
751*f6dc9357SAndroid Build Coastguard Worker     }
752*f6dc9357SAndroid Build Coastguard Worker 
753*f6dc9357SAndroid Build Coastguard Worker     if (reps != -(int)kRleModeRepSize)
754*f6dc9357SAndroid Build Coastguard Worker     {
755*f6dc9357SAndroid Build Coastguard Worker       if (b != prevByte)
756*f6dc9357SAndroid Build Coastguard Worker         reps = 0;
757*f6dc9357SAndroid Build Coastguard Worker       reps--;
758*f6dc9357SAndroid Build Coastguard Worker       prevByte = b;
759*f6dc9357SAndroid Build Coastguard Worker       *data++ = (Byte)b;
760*f6dc9357SAndroid Build Coastguard Worker       crc.UpdateByte(b);
761*f6dc9357SAndroid Build Coastguard Worker       if (data == lim || blockSize == 0)
762*f6dc9357SAndroid Build Coastguard Worker         break;
763*f6dc9357SAndroid Build Coastguard Worker       continue;
764*f6dc9357SAndroid Build Coastguard Worker     }
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker     reps = (int)b;
767*f6dc9357SAndroid Build Coastguard Worker     while (reps)
768*f6dc9357SAndroid Build Coastguard Worker     {
769*f6dc9357SAndroid Build Coastguard Worker       reps--;
770*f6dc9357SAndroid Build Coastguard Worker       *data++ = (Byte)prevByte;
771*f6dc9357SAndroid Build Coastguard Worker       crc.UpdateByte(prevByte);
772*f6dc9357SAndroid Build Coastguard Worker       if (data == lim)
773*f6dc9357SAndroid Build Coastguard Worker         break;
774*f6dc9357SAndroid Build Coastguard Worker     }
775*f6dc9357SAndroid Build Coastguard Worker     if (data == lim)
776*f6dc9357SAndroid Build Coastguard Worker       break;
777*f6dc9357SAndroid Build Coastguard Worker     if (blockSize == 0)
778*f6dc9357SAndroid Build Coastguard Worker       break;
779*f6dc9357SAndroid Build Coastguard Worker   }
780*f6dc9357SAndroid Build Coastguard Worker 
781*f6dc9357SAndroid Build Coastguard Worker   if (blockSize == 1 && reps == -(int)kRleModeRepSize)
782*f6dc9357SAndroid Build Coastguard Worker   {
783*f6dc9357SAndroid Build Coastguard Worker     unsigned b = (unsigned)(tPos & 0xFF);
784*f6dc9357SAndroid Build Coastguard Worker     tPos = tt[tPos >> 8];
785*f6dc9357SAndroid Build Coastguard Worker     blockSize--;
786*f6dc9357SAndroid Build Coastguard Worker 
787*f6dc9357SAndroid Build Coastguard Worker     if (_randToGo >= 0)
788*f6dc9357SAndroid Build Coastguard Worker     {
789*f6dc9357SAndroid Build Coastguard Worker       if (_randToGo == 0)
790*f6dc9357SAndroid Build Coastguard Worker       {
791*f6dc9357SAndroid Build Coastguard Worker         b ^= 1;
792*f6dc9357SAndroid Build Coastguard Worker         _randToGo = kRandNums[_randIndex];
793*f6dc9357SAndroid Build Coastguard Worker         _randIndex++;
794*f6dc9357SAndroid Build Coastguard Worker         _randIndex &= 0x1FF;
795*f6dc9357SAndroid Build Coastguard Worker       }
796*f6dc9357SAndroid Build Coastguard Worker       _randToGo--;
797*f6dc9357SAndroid Build Coastguard Worker     }
798*f6dc9357SAndroid Build Coastguard Worker 
799*f6dc9357SAndroid Build Coastguard Worker     reps = (int)b;
800*f6dc9357SAndroid Build Coastguard Worker   }
801*f6dc9357SAndroid Build Coastguard Worker 
802*f6dc9357SAndroid Build Coastguard Worker   _tPos = tPos;
803*f6dc9357SAndroid Build Coastguard Worker   _prevByte = prevByte;
804*f6dc9357SAndroid Build Coastguard Worker   _reps = reps;
805*f6dc9357SAndroid Build Coastguard Worker   _crc = crc;
806*f6dc9357SAndroid Build Coastguard Worker   _blockSize = blockSize;
807*f6dc9357SAndroid Build Coastguard Worker 
808*f6dc9357SAndroid Build Coastguard Worker   return data;
809*f6dc9357SAndroid Build Coastguard Worker }
810*f6dc9357SAndroid Build Coastguard Worker 
811*f6dc9357SAndroid Build Coastguard Worker 
Flush()812*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::Flush()
813*f6dc9357SAndroid Build Coastguard Worker {
814*f6dc9357SAndroid Build Coastguard Worker   if (_writeRes == S_OK)
815*f6dc9357SAndroid Build Coastguard Worker   {
816*f6dc9357SAndroid Build Coastguard Worker     _writeRes = WriteStream(_outStream, _outBuf, _outPos);
817*f6dc9357SAndroid Build Coastguard Worker     _outWritten += _outPos;
818*f6dc9357SAndroid Build Coastguard Worker     _outPos = 0;
819*f6dc9357SAndroid Build Coastguard Worker   }
820*f6dc9357SAndroid Build Coastguard Worker   return _writeRes;
821*f6dc9357SAndroid Build Coastguard Worker }
822*f6dc9357SAndroid Build Coastguard Worker 
823*f6dc9357SAndroid Build Coastguard Worker 
824*f6dc9357SAndroid Build Coastguard Worker NO_INLINE
DecodeBlock(const CBlockProps & props)825*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::DecodeBlock(const CBlockProps &props)
826*f6dc9357SAndroid Build Coastguard Worker {
827*f6dc9357SAndroid Build Coastguard Worker   _calcedBlockCrc = 0;
828*f6dc9357SAndroid Build Coastguard Worker   _blockFinished = false;
829*f6dc9357SAndroid Build Coastguard Worker 
830*f6dc9357SAndroid Build Coastguard Worker   CSpecState block;
831*f6dc9357SAndroid Build Coastguard Worker 
832*f6dc9357SAndroid Build Coastguard Worker   block._blockSize = props.blockSize;
833*f6dc9357SAndroid Build Coastguard Worker   block._tt = _counters + 256;
834*f6dc9357SAndroid Build Coastguard Worker 
835*f6dc9357SAndroid Build Coastguard Worker   block.Init(props.origPtr, props.randMode);
836*f6dc9357SAndroid Build Coastguard Worker 
837*f6dc9357SAndroid Build Coastguard Worker   for (;;)
838*f6dc9357SAndroid Build Coastguard Worker   {
839*f6dc9357SAndroid Build Coastguard Worker     Byte *data = _outBuf + _outPos;
840*f6dc9357SAndroid Build Coastguard Worker     size_t size = kOutBufSize - _outPos;
841*f6dc9357SAndroid Build Coastguard Worker 
842*f6dc9357SAndroid Build Coastguard Worker     if (_outSizeDefined)
843*f6dc9357SAndroid Build Coastguard Worker     {
844*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = _outSize - _outPosTotal;
845*f6dc9357SAndroid Build Coastguard Worker       if (size >= rem)
846*f6dc9357SAndroid Build Coastguard Worker       {
847*f6dc9357SAndroid Build Coastguard Worker         size = (size_t)rem;
848*f6dc9357SAndroid Build Coastguard Worker         if (size == 0)
849*f6dc9357SAndroid Build Coastguard Worker           return FinishMode ? S_FALSE : S_OK;
850*f6dc9357SAndroid Build Coastguard Worker       }
851*f6dc9357SAndroid Build Coastguard Worker     }
852*f6dc9357SAndroid Build Coastguard Worker 
853*f6dc9357SAndroid Build Coastguard Worker     TICKS_START
854*f6dc9357SAndroid Build Coastguard Worker     const size_t processed = (size_t)(block.Decode(data, size) - data);
855*f6dc9357SAndroid Build Coastguard Worker     TICKS_UPDATE(2)
856*f6dc9357SAndroid Build Coastguard Worker 
857*f6dc9357SAndroid Build Coastguard Worker     _outPosTotal += processed;
858*f6dc9357SAndroid Build Coastguard Worker     _outPos += processed;
859*f6dc9357SAndroid Build Coastguard Worker 
860*f6dc9357SAndroid Build Coastguard Worker     if (processed >= size)
861*f6dc9357SAndroid Build Coastguard Worker     {
862*f6dc9357SAndroid Build Coastguard Worker       RINOK(Flush())
863*f6dc9357SAndroid Build Coastguard Worker     }
864*f6dc9357SAndroid Build Coastguard Worker 
865*f6dc9357SAndroid Build Coastguard Worker     if (block.Finished())
866*f6dc9357SAndroid Build Coastguard Worker     {
867*f6dc9357SAndroid Build Coastguard Worker       _blockFinished = true;
868*f6dc9357SAndroid Build Coastguard Worker       _calcedBlockCrc = block._crc.GetDigest();
869*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
870*f6dc9357SAndroid Build Coastguard Worker     }
871*f6dc9357SAndroid Build Coastguard Worker   }
872*f6dc9357SAndroid Build Coastguard Worker }
873*f6dc9357SAndroid Build Coastguard Worker 
874*f6dc9357SAndroid Build Coastguard Worker 
CDecoder()875*f6dc9357SAndroid Build Coastguard Worker CDecoder::CDecoder():
876*f6dc9357SAndroid Build Coastguard Worker     _outBuf(NULL),
877*f6dc9357SAndroid Build Coastguard Worker     FinishMode(false),
878*f6dc9357SAndroid Build Coastguard Worker     _outSizeDefined(false),
879*f6dc9357SAndroid Build Coastguard Worker     _counters(NULL),
880*f6dc9357SAndroid Build Coastguard Worker     _inBuf(NULL),
881*f6dc9357SAndroid Build Coastguard Worker     _inProcessed(0)
882*f6dc9357SAndroid Build Coastguard Worker {
883*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
884*f6dc9357SAndroid Build Coastguard Worker   MtMode = false;
885*f6dc9357SAndroid Build Coastguard Worker   NeedWaitScout = false;
886*f6dc9357SAndroid Build Coastguard Worker   // ScoutRes = S_OK;
887*f6dc9357SAndroid Build Coastguard Worker   #endif
888*f6dc9357SAndroid Build Coastguard Worker }
889*f6dc9357SAndroid Build Coastguard Worker 
890*f6dc9357SAndroid Build Coastguard Worker 
~CDecoder()891*f6dc9357SAndroid Build Coastguard Worker CDecoder::~CDecoder()
892*f6dc9357SAndroid Build Coastguard Worker {
893*f6dc9357SAndroid Build Coastguard Worker   PRIN("\n~CDecoder()");
894*f6dc9357SAndroid Build Coastguard Worker 
895*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
896*f6dc9357SAndroid Build Coastguard Worker 
897*f6dc9357SAndroid Build Coastguard Worker   if (Thread.IsCreated())
898*f6dc9357SAndroid Build Coastguard Worker   {
899*f6dc9357SAndroid Build Coastguard Worker     WaitScout();
900*f6dc9357SAndroid Build Coastguard Worker 
901*f6dc9357SAndroid Build Coastguard Worker     _block.StopScout = true;
902*f6dc9357SAndroid Build Coastguard Worker 
903*f6dc9357SAndroid Build Coastguard Worker     PRIN("\nScoutEvent.Set()");
904*f6dc9357SAndroid Build Coastguard Worker     ScoutEvent.Set();
905*f6dc9357SAndroid Build Coastguard Worker 
906*f6dc9357SAndroid Build Coastguard Worker     PRIN("\nThread.Wait()()");
907*f6dc9357SAndroid Build Coastguard Worker     Thread.Wait_Close();
908*f6dc9357SAndroid Build Coastguard Worker     PRIN("\n after Thread.Wait()()");
909*f6dc9357SAndroid Build Coastguard Worker 
910*f6dc9357SAndroid Build Coastguard Worker     // if (ScoutRes != S_OK) throw ScoutRes;
911*f6dc9357SAndroid Build Coastguard Worker   }
912*f6dc9357SAndroid Build Coastguard Worker 
913*f6dc9357SAndroid Build Coastguard Worker   #endif
914*f6dc9357SAndroid Build Coastguard Worker 
915*f6dc9357SAndroid Build Coastguard Worker   BigFree(_counters);
916*f6dc9357SAndroid Build Coastguard Worker   MidFree(_outBuf);
917*f6dc9357SAndroid Build Coastguard Worker   MidFree(_inBuf);
918*f6dc9357SAndroid Build Coastguard Worker }
919*f6dc9357SAndroid Build Coastguard Worker 
920*f6dc9357SAndroid Build Coastguard Worker 
ReadInput()921*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::ReadInput()
922*f6dc9357SAndroid Build Coastguard Worker {
923*f6dc9357SAndroid Build Coastguard Worker   if (Base._buf != Base._lim || _inputFinished || _inputRes != S_OK)
924*f6dc9357SAndroid Build Coastguard Worker     return _inputRes;
925*f6dc9357SAndroid Build Coastguard Worker 
926*f6dc9357SAndroid Build Coastguard Worker   _inProcessed += (size_t)(Base._buf - _inBuf);
927*f6dc9357SAndroid Build Coastguard Worker   Base._buf = _inBuf;
928*f6dc9357SAndroid Build Coastguard Worker   Base._lim = _inBuf;
929*f6dc9357SAndroid Build Coastguard Worker   UInt32 size = 0;
930*f6dc9357SAndroid Build Coastguard Worker   _inputRes = Base.InStream->Read(_inBuf, kInBufSize, &size);
931*f6dc9357SAndroid Build Coastguard Worker   _inputFinished = (size == 0);
932*f6dc9357SAndroid Build Coastguard Worker   Base._lim = _inBuf + size;
933*f6dc9357SAndroid Build Coastguard Worker   return _inputRes;
934*f6dc9357SAndroid Build Coastguard Worker }
935*f6dc9357SAndroid Build Coastguard Worker 
936*f6dc9357SAndroid Build Coastguard Worker 
StartNewStream()937*f6dc9357SAndroid Build Coastguard Worker void CDecoder::StartNewStream()
938*f6dc9357SAndroid Build Coastguard Worker {
939*f6dc9357SAndroid Build Coastguard Worker   Base.state = STATE_STREAM_SIGNATURE;
940*f6dc9357SAndroid Build Coastguard Worker   Base.state2 = 0;
941*f6dc9357SAndroid Build Coastguard Worker   Base.IsBz = false;
942*f6dc9357SAndroid Build Coastguard Worker }
943*f6dc9357SAndroid Build Coastguard Worker 
944*f6dc9357SAndroid Build Coastguard Worker 
ReadStreamSignature()945*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::ReadStreamSignature()
946*f6dc9357SAndroid Build Coastguard Worker {
947*f6dc9357SAndroid Build Coastguard Worker   for (;;)
948*f6dc9357SAndroid Build Coastguard Worker   {
949*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadInput())
950*f6dc9357SAndroid Build Coastguard Worker     SRes res = Base.ReadStreamSignature2();
951*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK)
952*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
953*f6dc9357SAndroid Build Coastguard Worker     if (Base.state == STATE_BLOCK_SIGNATURE)
954*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
955*f6dc9357SAndroid Build Coastguard Worker     if (_inputFinished)
956*f6dc9357SAndroid Build Coastguard Worker     {
957*f6dc9357SAndroid Build Coastguard Worker       Base.NeedMoreInput = true;
958*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
959*f6dc9357SAndroid Build Coastguard Worker     }
960*f6dc9357SAndroid Build Coastguard Worker   }
961*f6dc9357SAndroid Build Coastguard Worker }
962*f6dc9357SAndroid Build Coastguard Worker 
963*f6dc9357SAndroid Build Coastguard Worker 
StartRead()964*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::StartRead()
965*f6dc9357SAndroid Build Coastguard Worker {
966*f6dc9357SAndroid Build Coastguard Worker   StartNewStream();
967*f6dc9357SAndroid Build Coastguard Worker   return ReadStreamSignature();
968*f6dc9357SAndroid Build Coastguard Worker }
969*f6dc9357SAndroid Build Coastguard Worker 
970*f6dc9357SAndroid Build Coastguard Worker 
ReadBlockSignature()971*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::ReadBlockSignature()
972*f6dc9357SAndroid Build Coastguard Worker {
973*f6dc9357SAndroid Build Coastguard Worker   for (;;)
974*f6dc9357SAndroid Build Coastguard Worker   {
975*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadInput())
976*f6dc9357SAndroid Build Coastguard Worker 
977*f6dc9357SAndroid Build Coastguard Worker     SRes res = Base.ReadBlockSignature2();
978*f6dc9357SAndroid Build Coastguard Worker 
979*f6dc9357SAndroid Build Coastguard Worker     if (Base.state == STATE_STREAM_FINISHED)
980*f6dc9357SAndroid Build Coastguard Worker       Base.FinishedPackSize = GetInputProcessedSize();
981*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK)
982*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
983*f6dc9357SAndroid Build Coastguard Worker     if (Base.state != STATE_BLOCK_SIGNATURE)
984*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
985*f6dc9357SAndroid Build Coastguard Worker     if (_inputFinished)
986*f6dc9357SAndroid Build Coastguard Worker     {
987*f6dc9357SAndroid Build Coastguard Worker       Base.NeedMoreInput = true;
988*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
989*f6dc9357SAndroid Build Coastguard Worker     }
990*f6dc9357SAndroid Build Coastguard Worker   }
991*f6dc9357SAndroid Build Coastguard Worker }
992*f6dc9357SAndroid Build Coastguard Worker 
993*f6dc9357SAndroid Build Coastguard Worker 
ReadBlock()994*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::ReadBlock()
995*f6dc9357SAndroid Build Coastguard Worker {
996*f6dc9357SAndroid Build Coastguard Worker   for (;;)
997*f6dc9357SAndroid Build Coastguard Worker   {
998*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadInput())
999*f6dc9357SAndroid Build Coastguard Worker 
1000*f6dc9357SAndroid Build Coastguard Worker     SRes res = Base.ReadBlock2();
1001*f6dc9357SAndroid Build Coastguard Worker 
1002*f6dc9357SAndroid Build Coastguard Worker     if (res != SZ_OK)
1003*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
1004*f6dc9357SAndroid Build Coastguard Worker     if (Base.state == STATE_BLOCK_SIGNATURE)
1005*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1006*f6dc9357SAndroid Build Coastguard Worker     if (_inputFinished)
1007*f6dc9357SAndroid Build Coastguard Worker     {
1008*f6dc9357SAndroid Build Coastguard Worker       Base.NeedMoreInput = true;
1009*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
1010*f6dc9357SAndroid Build Coastguard Worker     }
1011*f6dc9357SAndroid Build Coastguard Worker   }
1012*f6dc9357SAndroid Build Coastguard Worker }
1013*f6dc9357SAndroid Build Coastguard Worker 
1014*f6dc9357SAndroid Build Coastguard Worker 
1015*f6dc9357SAndroid Build Coastguard Worker 
DecodeStreams(ICompressProgressInfo * progress)1016*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::DecodeStreams(ICompressProgressInfo *progress)
1017*f6dc9357SAndroid Build Coastguard Worker {
1018*f6dc9357SAndroid Build Coastguard Worker   {
1019*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1020*f6dc9357SAndroid Build Coastguard Worker     _block.StopScout = false;
1021*f6dc9357SAndroid Build Coastguard Worker     #endif
1022*f6dc9357SAndroid Build Coastguard Worker   }
1023*f6dc9357SAndroid Build Coastguard Worker 
1024*f6dc9357SAndroid Build Coastguard Worker   RINOK(StartRead())
1025*f6dc9357SAndroid Build Coastguard Worker 
1026*f6dc9357SAndroid Build Coastguard Worker   UInt64 inPrev = 0;
1027*f6dc9357SAndroid Build Coastguard Worker   UInt64 outPrev = 0;
1028*f6dc9357SAndroid Build Coastguard Worker 
1029*f6dc9357SAndroid Build Coastguard Worker   {
1030*f6dc9357SAndroid Build Coastguard Worker     #ifndef Z7_ST
1031*f6dc9357SAndroid Build Coastguard Worker     CWaitScout_Releaser waitScout_Releaser(this);
1032*f6dc9357SAndroid Build Coastguard Worker 
1033*f6dc9357SAndroid Build Coastguard Worker     bool useMt = false;
1034*f6dc9357SAndroid Build Coastguard Worker     #endif
1035*f6dc9357SAndroid Build Coastguard Worker 
1036*f6dc9357SAndroid Build Coastguard Worker     bool wasFinished = false;
1037*f6dc9357SAndroid Build Coastguard Worker 
1038*f6dc9357SAndroid Build Coastguard Worker     UInt32 crc = 0;
1039*f6dc9357SAndroid Build Coastguard Worker     UInt32 nextCrc = 0;
1040*f6dc9357SAndroid Build Coastguard Worker     HRESULT nextRes = S_OK;
1041*f6dc9357SAndroid Build Coastguard Worker 
1042*f6dc9357SAndroid Build Coastguard Worker     UInt64 packPos = 0;
1043*f6dc9357SAndroid Build Coastguard Worker 
1044*f6dc9357SAndroid Build Coastguard Worker     CBlockProps props;
1045*f6dc9357SAndroid Build Coastguard Worker 
1046*f6dc9357SAndroid Build Coastguard Worker     props.blockSize = 0;
1047*f6dc9357SAndroid Build Coastguard Worker 
1048*f6dc9357SAndroid Build Coastguard Worker     for (;;)
1049*f6dc9357SAndroid Build Coastguard Worker     {
1050*f6dc9357SAndroid Build Coastguard Worker       if (progress)
1051*f6dc9357SAndroid Build Coastguard Worker       {
1052*f6dc9357SAndroid Build Coastguard Worker         const UInt64 outCur = GetOutProcessedSize();
1053*f6dc9357SAndroid Build Coastguard Worker         if (packPos - inPrev >= kProgressStep || outCur - outPrev >= kProgressStep)
1054*f6dc9357SAndroid Build Coastguard Worker         {
1055*f6dc9357SAndroid Build Coastguard Worker           RINOK(progress->SetRatioInfo(&packPos, &outCur))
1056*f6dc9357SAndroid Build Coastguard Worker           inPrev = packPos;
1057*f6dc9357SAndroid Build Coastguard Worker           outPrev = outCur;
1058*f6dc9357SAndroid Build Coastguard Worker         }
1059*f6dc9357SAndroid Build Coastguard Worker       }
1060*f6dc9357SAndroid Build Coastguard Worker 
1061*f6dc9357SAndroid Build Coastguard Worker       if (props.blockSize == 0)
1062*f6dc9357SAndroid Build Coastguard Worker         if (wasFinished || nextRes != S_OK)
1063*f6dc9357SAndroid Build Coastguard Worker           return nextRes;
1064*f6dc9357SAndroid Build Coastguard Worker 
1065*f6dc9357SAndroid Build Coastguard Worker       if (
1066*f6dc9357SAndroid Build Coastguard Worker           #ifndef Z7_ST
1067*f6dc9357SAndroid Build Coastguard Worker           !useMt &&
1068*f6dc9357SAndroid Build Coastguard Worker           #endif
1069*f6dc9357SAndroid Build Coastguard Worker           !wasFinished && Base.state == STATE_BLOCK_SIGNATURE)
1070*f6dc9357SAndroid Build Coastguard Worker       {
1071*f6dc9357SAndroid Build Coastguard Worker         nextRes = ReadBlockSignature();
1072*f6dc9357SAndroid Build Coastguard Worker         nextCrc = Base.crc;
1073*f6dc9357SAndroid Build Coastguard Worker         packPos = GetInputProcessedSize();
1074*f6dc9357SAndroid Build Coastguard Worker 
1075*f6dc9357SAndroid Build Coastguard Worker         wasFinished = true;
1076*f6dc9357SAndroid Build Coastguard Worker 
1077*f6dc9357SAndroid Build Coastguard Worker         if (nextRes != S_OK)
1078*f6dc9357SAndroid Build Coastguard Worker           continue;
1079*f6dc9357SAndroid Build Coastguard Worker 
1080*f6dc9357SAndroid Build Coastguard Worker         if (Base.state == STATE_STREAM_FINISHED)
1081*f6dc9357SAndroid Build Coastguard Worker         {
1082*f6dc9357SAndroid Build Coastguard Worker           if (!Base.DecodeAllStreams)
1083*f6dc9357SAndroid Build Coastguard Worker           {
1084*f6dc9357SAndroid Build Coastguard Worker             wasFinished = true;
1085*f6dc9357SAndroid Build Coastguard Worker             continue;
1086*f6dc9357SAndroid Build Coastguard Worker           }
1087*f6dc9357SAndroid Build Coastguard Worker 
1088*f6dc9357SAndroid Build Coastguard Worker           nextRes = StartRead();
1089*f6dc9357SAndroid Build Coastguard Worker 
1090*f6dc9357SAndroid Build Coastguard Worker           if (Base.NeedMoreInput)
1091*f6dc9357SAndroid Build Coastguard Worker           {
1092*f6dc9357SAndroid Build Coastguard Worker             if (Base.state2 == 0)
1093*f6dc9357SAndroid Build Coastguard Worker               Base.NeedMoreInput = false;
1094*f6dc9357SAndroid Build Coastguard Worker             wasFinished = true;
1095*f6dc9357SAndroid Build Coastguard Worker             nextRes = S_OK;
1096*f6dc9357SAndroid Build Coastguard Worker             continue;
1097*f6dc9357SAndroid Build Coastguard Worker           }
1098*f6dc9357SAndroid Build Coastguard Worker 
1099*f6dc9357SAndroid Build Coastguard Worker           if (nextRes != S_OK)
1100*f6dc9357SAndroid Build Coastguard Worker             continue;
1101*f6dc9357SAndroid Build Coastguard Worker 
1102*f6dc9357SAndroid Build Coastguard Worker           wasFinished = false;
1103*f6dc9357SAndroid Build Coastguard Worker           continue;
1104*f6dc9357SAndroid Build Coastguard Worker         }
1105*f6dc9357SAndroid Build Coastguard Worker 
1106*f6dc9357SAndroid Build Coastguard Worker         wasFinished = false;
1107*f6dc9357SAndroid Build Coastguard Worker 
1108*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
1109*f6dc9357SAndroid Build Coastguard Worker         if (MtMode)
1110*f6dc9357SAndroid Build Coastguard Worker         if (props.blockSize != 0)
1111*f6dc9357SAndroid Build Coastguard Worker         {
1112*f6dc9357SAndroid Build Coastguard Worker           // we start multithreading, if next block is big enough.
1113*f6dc9357SAndroid Build Coastguard Worker           const UInt32 k_Mt_BlockSize_Threshold = (1 << 12);  // (1 << 13)
1114*f6dc9357SAndroid Build Coastguard Worker           if (props.blockSize > k_Mt_BlockSize_Threshold)
1115*f6dc9357SAndroid Build Coastguard Worker           {
1116*f6dc9357SAndroid Build Coastguard Worker             if (!Thread.IsCreated())
1117*f6dc9357SAndroid Build Coastguard Worker             {
1118*f6dc9357SAndroid Build Coastguard Worker               PRIN("=== MT_MODE");
1119*f6dc9357SAndroid Build Coastguard Worker               RINOK(CreateThread())
1120*f6dc9357SAndroid Build Coastguard Worker             }
1121*f6dc9357SAndroid Build Coastguard Worker             useMt = true;
1122*f6dc9357SAndroid Build Coastguard Worker           }
1123*f6dc9357SAndroid Build Coastguard Worker         }
1124*f6dc9357SAndroid Build Coastguard Worker         #endif
1125*f6dc9357SAndroid Build Coastguard Worker       }
1126*f6dc9357SAndroid Build Coastguard Worker 
1127*f6dc9357SAndroid Build Coastguard Worker       if (props.blockSize == 0)
1128*f6dc9357SAndroid Build Coastguard Worker       {
1129*f6dc9357SAndroid Build Coastguard Worker         crc = nextCrc;
1130*f6dc9357SAndroid Build Coastguard Worker 
1131*f6dc9357SAndroid Build Coastguard Worker         #ifndef Z7_ST
1132*f6dc9357SAndroid Build Coastguard Worker         if (useMt)
1133*f6dc9357SAndroid Build Coastguard Worker         {
1134*f6dc9357SAndroid Build Coastguard Worker           PRIN("DecoderEvent.Lock()");
1135*f6dc9357SAndroid Build Coastguard Worker           {
1136*f6dc9357SAndroid Build Coastguard Worker             WRes wres = DecoderEvent.Lock();
1137*f6dc9357SAndroid Build Coastguard Worker             if (wres != 0)
1138*f6dc9357SAndroid Build Coastguard Worker               return HRESULT_FROM_WIN32(wres);
1139*f6dc9357SAndroid Build Coastguard Worker           }
1140*f6dc9357SAndroid Build Coastguard Worker           NeedWaitScout = false;
1141*f6dc9357SAndroid Build Coastguard Worker           PRIN("-- DecoderEvent.Lock()");
1142*f6dc9357SAndroid Build Coastguard Worker           props = _block.Props;
1143*f6dc9357SAndroid Build Coastguard Worker           nextCrc = _block.NextCrc;
1144*f6dc9357SAndroid Build Coastguard Worker           if (_block.Crc_Defined)
1145*f6dc9357SAndroid Build Coastguard Worker             crc = _block.Crc;
1146*f6dc9357SAndroid Build Coastguard Worker           packPos = _block.PackPos;
1147*f6dc9357SAndroid Build Coastguard Worker           wasFinished = _block.WasFinished;
1148*f6dc9357SAndroid Build Coastguard Worker           RINOK(_block.Res)
1149*f6dc9357SAndroid Build Coastguard Worker         }
1150*f6dc9357SAndroid Build Coastguard Worker         else
1151*f6dc9357SAndroid Build Coastguard Worker         #endif
1152*f6dc9357SAndroid Build Coastguard Worker         {
1153*f6dc9357SAndroid Build Coastguard Worker           if (Base.state != STATE_BLOCK_START)
1154*f6dc9357SAndroid Build Coastguard Worker             return E_FAIL;
1155*f6dc9357SAndroid Build Coastguard Worker 
1156*f6dc9357SAndroid Build Coastguard Worker           TICKS_START
1157*f6dc9357SAndroid Build Coastguard Worker           Base.Props.randMode = 1;
1158*f6dc9357SAndroid Build Coastguard Worker           RINOK(ReadBlock())
1159*f6dc9357SAndroid Build Coastguard Worker           TICKS_UPDATE(0)
1160*f6dc9357SAndroid Build Coastguard Worker 
1161*f6dc9357SAndroid Build Coastguard Worker           props = Base.Props;
1162*f6dc9357SAndroid Build Coastguard Worker           continue;
1163*f6dc9357SAndroid Build Coastguard Worker         }
1164*f6dc9357SAndroid Build Coastguard Worker       }
1165*f6dc9357SAndroid Build Coastguard Worker 
1166*f6dc9357SAndroid Build Coastguard Worker       if (props.blockSize != 0)
1167*f6dc9357SAndroid Build Coastguard Worker       {
1168*f6dc9357SAndroid Build Coastguard Worker         TICKS_START
1169*f6dc9357SAndroid Build Coastguard Worker         DecodeBlock1(_counters, props.blockSize);
1170*f6dc9357SAndroid Build Coastguard Worker         TICKS_UPDATE(1)
1171*f6dc9357SAndroid Build Coastguard Worker       }
1172*f6dc9357SAndroid Build Coastguard Worker 
1173*f6dc9357SAndroid Build Coastguard Worker       #ifndef Z7_ST
1174*f6dc9357SAndroid Build Coastguard Worker       if (useMt && !wasFinished)
1175*f6dc9357SAndroid Build Coastguard Worker       {
1176*f6dc9357SAndroid Build Coastguard Worker         /*
1177*f6dc9357SAndroid Build Coastguard Worker         if (props.blockSize == 0)
1178*f6dc9357SAndroid Build Coastguard Worker         {
1179*f6dc9357SAndroid Build Coastguard Worker           // this codes switches back to single-threadMode
1180*f6dc9357SAndroid Build Coastguard Worker           useMt = false;
1181*f6dc9357SAndroid Build Coastguard Worker           PRIN("=== ST_MODE");
1182*f6dc9357SAndroid Build Coastguard Worker           continue;
1183*f6dc9357SAndroid Build Coastguard Worker           }
1184*f6dc9357SAndroid Build Coastguard Worker         */
1185*f6dc9357SAndroid Build Coastguard Worker 
1186*f6dc9357SAndroid Build Coastguard Worker         PRIN("ScoutEvent.Set()");
1187*f6dc9357SAndroid Build Coastguard Worker         {
1188*f6dc9357SAndroid Build Coastguard Worker           WRes wres = ScoutEvent.Set();
1189*f6dc9357SAndroid Build Coastguard Worker           if (wres != 0)
1190*f6dc9357SAndroid Build Coastguard Worker             return HRESULT_FROM_WIN32(wres);
1191*f6dc9357SAndroid Build Coastguard Worker         }
1192*f6dc9357SAndroid Build Coastguard Worker         NeedWaitScout = true;
1193*f6dc9357SAndroid Build Coastguard Worker       }
1194*f6dc9357SAndroid Build Coastguard Worker       #endif
1195*f6dc9357SAndroid Build Coastguard Worker 
1196*f6dc9357SAndroid Build Coastguard Worker       if (props.blockSize == 0)
1197*f6dc9357SAndroid Build Coastguard Worker         continue;
1198*f6dc9357SAndroid Build Coastguard Worker 
1199*f6dc9357SAndroid Build Coastguard Worker       RINOK(DecodeBlock(props))
1200*f6dc9357SAndroid Build Coastguard Worker 
1201*f6dc9357SAndroid Build Coastguard Worker       if (!_blockFinished)
1202*f6dc9357SAndroid Build Coastguard Worker         return nextRes;
1203*f6dc9357SAndroid Build Coastguard Worker 
1204*f6dc9357SAndroid Build Coastguard Worker       props.blockSize = 0;
1205*f6dc9357SAndroid Build Coastguard Worker       if (_calcedBlockCrc != crc)
1206*f6dc9357SAndroid Build Coastguard Worker       {
1207*f6dc9357SAndroid Build Coastguard Worker         BlockCrcError = true;
1208*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
1209*f6dc9357SAndroid Build Coastguard Worker       }
1210*f6dc9357SAndroid Build Coastguard Worker     }
1211*f6dc9357SAndroid Build Coastguard Worker   }
1212*f6dc9357SAndroid Build Coastguard Worker }
1213*f6dc9357SAndroid Build Coastguard Worker 
1214*f6dc9357SAndroid Build Coastguard Worker 
1215*f6dc9357SAndroid Build Coastguard Worker 
1216*f6dc9357SAndroid Build Coastguard Worker 
CreateInputBufer()1217*f6dc9357SAndroid Build Coastguard Worker bool CDecoder::CreateInputBufer()
1218*f6dc9357SAndroid Build Coastguard Worker {
1219*f6dc9357SAndroid Build Coastguard Worker   if (!_inBuf)
1220*f6dc9357SAndroid Build Coastguard Worker   {
1221*f6dc9357SAndroid Build Coastguard Worker     _inBuf = (Byte *)MidAlloc(kInBufSize);
1222*f6dc9357SAndroid Build Coastguard Worker     if (!_inBuf)
1223*f6dc9357SAndroid Build Coastguard Worker       return false;
1224*f6dc9357SAndroid Build Coastguard Worker     Base._buf = _inBuf;
1225*f6dc9357SAndroid Build Coastguard Worker     Base._lim = _inBuf;
1226*f6dc9357SAndroid Build Coastguard Worker   }
1227*f6dc9357SAndroid Build Coastguard Worker   if (!_counters)
1228*f6dc9357SAndroid Build Coastguard Worker   {
1229*f6dc9357SAndroid Build Coastguard Worker     const size_t size = (256 + kBlockSizeMax) * sizeof(UInt32)
1230*f6dc9357SAndroid Build Coastguard Worker       #ifdef BZIP2_BYTE_MODE
1231*f6dc9357SAndroid Build Coastguard Worker         + kBlockSizeMax
1232*f6dc9357SAndroid Build Coastguard Worker       #endif
1233*f6dc9357SAndroid Build Coastguard Worker         + 256;
1234*f6dc9357SAndroid Build Coastguard Worker     _counters = (UInt32 *)::BigAlloc(size);
1235*f6dc9357SAndroid Build Coastguard Worker     if (!_counters)
1236*f6dc9357SAndroid Build Coastguard Worker       return false;
1237*f6dc9357SAndroid Build Coastguard Worker     Base.Counters = _counters;
1238*f6dc9357SAndroid Build Coastguard Worker   }
1239*f6dc9357SAndroid Build Coastguard Worker   return true;
1240*f6dc9357SAndroid Build Coastguard Worker }
1241*f6dc9357SAndroid Build Coastguard Worker 
1242*f6dc9357SAndroid Build Coastguard Worker 
InitOutSize(const UInt64 * outSize)1243*f6dc9357SAndroid Build Coastguard Worker void CDecoder::InitOutSize(const UInt64 *outSize)
1244*f6dc9357SAndroid Build Coastguard Worker {
1245*f6dc9357SAndroid Build Coastguard Worker   _outPosTotal = 0;
1246*f6dc9357SAndroid Build Coastguard Worker 
1247*f6dc9357SAndroid Build Coastguard Worker   _outSizeDefined = false;
1248*f6dc9357SAndroid Build Coastguard Worker   _outSize = 0;
1249*f6dc9357SAndroid Build Coastguard Worker   if (outSize)
1250*f6dc9357SAndroid Build Coastguard Worker   {
1251*f6dc9357SAndroid Build Coastguard Worker     _outSize = *outSize;
1252*f6dc9357SAndroid Build Coastguard Worker     _outSizeDefined = true;
1253*f6dc9357SAndroid Build Coastguard Worker   }
1254*f6dc9357SAndroid Build Coastguard Worker 
1255*f6dc9357SAndroid Build Coastguard Worker   BlockCrcError = false;
1256*f6dc9357SAndroid Build Coastguard Worker 
1257*f6dc9357SAndroid Build Coastguard Worker   Base.InitNumStreams2();
1258*f6dc9357SAndroid Build Coastguard Worker }
1259*f6dc9357SAndroid Build Coastguard Worker 
1260*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::Code (ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 * outSize,ICompressProgressInfo * progress))1261*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
1262*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress))
1263*f6dc9357SAndroid Build Coastguard Worker {
1264*f6dc9357SAndroid Build Coastguard Worker   /*
1265*f6dc9357SAndroid Build Coastguard Worker   {
1266*f6dc9357SAndroid Build Coastguard Worker     RINOK(SetInStream(inStream));
1267*f6dc9357SAndroid Build Coastguard Worker     RINOK(SetOutStreamSize(outSize));
1268*f6dc9357SAndroid Build Coastguard Worker 
1269*f6dc9357SAndroid Build Coastguard Worker     RINOK(CopyStream(this, outStream, progress));
1270*f6dc9357SAndroid Build Coastguard Worker     return ReleaseInStream();
1271*f6dc9357SAndroid Build Coastguard Worker   }
1272*f6dc9357SAndroid Build Coastguard Worker   */
1273*f6dc9357SAndroid Build Coastguard Worker 
1274*f6dc9357SAndroid Build Coastguard Worker   _inputFinished = false;
1275*f6dc9357SAndroid Build Coastguard Worker   _inputRes = S_OK;
1276*f6dc9357SAndroid Build Coastguard Worker   _writeRes = S_OK;
1277*f6dc9357SAndroid Build Coastguard Worker 
1278*f6dc9357SAndroid Build Coastguard Worker   try {
1279*f6dc9357SAndroid Build Coastguard Worker 
1280*f6dc9357SAndroid Build Coastguard Worker   InitOutSize(outSize);
1281*f6dc9357SAndroid Build Coastguard Worker 
1282*f6dc9357SAndroid Build Coastguard Worker   // we can request data from InputBuffer after Code().
1283*f6dc9357SAndroid Build Coastguard Worker   // so we init InputBuffer before any function return.
1284*f6dc9357SAndroid Build Coastguard Worker 
1285*f6dc9357SAndroid Build Coastguard Worker   InitInputBuffer();
1286*f6dc9357SAndroid Build Coastguard Worker 
1287*f6dc9357SAndroid Build Coastguard Worker   if (!CreateInputBufer())
1288*f6dc9357SAndroid Build Coastguard Worker     return E_OUTOFMEMORY;
1289*f6dc9357SAndroid Build Coastguard Worker 
1290*f6dc9357SAndroid Build Coastguard Worker   if (!_outBuf)
1291*f6dc9357SAndroid Build Coastguard Worker   {
1292*f6dc9357SAndroid Build Coastguard Worker     _outBuf = (Byte *)MidAlloc(kOutBufSize);
1293*f6dc9357SAndroid Build Coastguard Worker     if (!_outBuf)
1294*f6dc9357SAndroid Build Coastguard Worker       return E_OUTOFMEMORY;
1295*f6dc9357SAndroid Build Coastguard Worker   }
1296*f6dc9357SAndroid Build Coastguard Worker 
1297*f6dc9357SAndroid Build Coastguard Worker   Base.InStream = inStream;
1298*f6dc9357SAndroid Build Coastguard Worker 
1299*f6dc9357SAndroid Build Coastguard Worker   // InitInputBuffer();
1300*f6dc9357SAndroid Build Coastguard Worker 
1301*f6dc9357SAndroid Build Coastguard Worker   _outStream = outStream;
1302*f6dc9357SAndroid Build Coastguard Worker   _outWritten = 0;
1303*f6dc9357SAndroid Build Coastguard Worker   _outPos = 0;
1304*f6dc9357SAndroid Build Coastguard Worker 
1305*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = DecodeStreams(progress);
1306*f6dc9357SAndroid Build Coastguard Worker 
1307*f6dc9357SAndroid Build Coastguard Worker   Flush();
1308*f6dc9357SAndroid Build Coastguard Worker 
1309*f6dc9357SAndroid Build Coastguard Worker   Base.InStream = NULL;
1310*f6dc9357SAndroid Build Coastguard Worker   _outStream = NULL;
1311*f6dc9357SAndroid Build Coastguard Worker 
1312*f6dc9357SAndroid Build Coastguard Worker   /*
1313*f6dc9357SAndroid Build Coastguard Worker   if (res == S_OK)
1314*f6dc9357SAndroid Build Coastguard Worker     if (FinishMode && inSize && *inSize != GetInputProcessedSize())
1315*f6dc9357SAndroid Build Coastguard Worker       res = S_FALSE;
1316*f6dc9357SAndroid Build Coastguard Worker   */
1317*f6dc9357SAndroid Build Coastguard Worker 
1318*f6dc9357SAndroid Build Coastguard Worker   if (res != S_OK)
1319*f6dc9357SAndroid Build Coastguard Worker     return res;
1320*f6dc9357SAndroid Build Coastguard Worker 
1321*f6dc9357SAndroid Build Coastguard Worker   } catch(...) { return E_FAIL; }
1322*f6dc9357SAndroid Build Coastguard Worker 
1323*f6dc9357SAndroid Build Coastguard Worker   return _writeRes;
1324*f6dc9357SAndroid Build Coastguard Worker }
1325*f6dc9357SAndroid Build Coastguard Worker 
1326*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::SetFinishMode (UInt32 finishMode))1327*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::SetFinishMode(UInt32 finishMode))
1328*f6dc9357SAndroid Build Coastguard Worker {
1329*f6dc9357SAndroid Build Coastguard Worker   FinishMode = (finishMode != 0);
1330*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1331*f6dc9357SAndroid Build Coastguard Worker }
1332*f6dc9357SAndroid Build Coastguard Worker 
1333*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize (UInt64 * value))1334*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::GetInStreamProcessedSize(UInt64 *value))
1335*f6dc9357SAndroid Build Coastguard Worker {
1336*f6dc9357SAndroid Build Coastguard Worker   *value = GetInStreamSize();
1337*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1338*f6dc9357SAndroid Build Coastguard Worker }
1339*f6dc9357SAndroid Build Coastguard Worker 
1340*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf (void * data,UInt32 size,UInt32 * processedSize))1341*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::ReadUnusedFromInBuf(void *data, UInt32 size, UInt32 *processedSize))
1342*f6dc9357SAndroid Build Coastguard Worker {
1343*f6dc9357SAndroid Build Coastguard Worker   Base.AlignToByte();
1344*f6dc9357SAndroid Build Coastguard Worker   UInt32 i;
1345*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < size; i++)
1346*f6dc9357SAndroid Build Coastguard Worker   {
1347*f6dc9357SAndroid Build Coastguard Worker     int b;
1348*f6dc9357SAndroid Build Coastguard Worker     Base.ReadByte(b);
1349*f6dc9357SAndroid Build Coastguard Worker     if (b < 0)
1350*f6dc9357SAndroid Build Coastguard Worker       break;
1351*f6dc9357SAndroid Build Coastguard Worker     ((Byte *)data)[i] = (Byte)b;
1352*f6dc9357SAndroid Build Coastguard Worker   }
1353*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
1354*f6dc9357SAndroid Build Coastguard Worker     *processedSize = i;
1355*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1356*f6dc9357SAndroid Build Coastguard Worker }
1357*f6dc9357SAndroid Build Coastguard Worker 
1358*f6dc9357SAndroid Build Coastguard Worker 
1359*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
1360*f6dc9357SAndroid Build Coastguard Worker 
1361*f6dc9357SAndroid Build Coastguard Worker #define PRIN_MT(s) PRIN("    " s)
1362*f6dc9357SAndroid Build Coastguard Worker 
1363*f6dc9357SAndroid Build Coastguard Worker // #define RINOK_THREAD(x) { WRes __result_ = (x); if (__result_ != 0) return __result_; }
1364*f6dc9357SAndroid Build Coastguard Worker 
RunScout2(void * p)1365*f6dc9357SAndroid Build Coastguard Worker static THREAD_FUNC_DECL RunScout2(void *p) { ((CDecoder *)p)->RunScout(); return 0; }
1366*f6dc9357SAndroid Build Coastguard Worker 
CreateThread()1367*f6dc9357SAndroid Build Coastguard Worker HRESULT CDecoder::CreateThread()
1368*f6dc9357SAndroid Build Coastguard Worker {
1369*f6dc9357SAndroid Build Coastguard Worker   WRes             wres = DecoderEvent.CreateIfNotCreated_Reset();
1370*f6dc9357SAndroid Build Coastguard Worker   if (wres == 0) { wres = ScoutEvent.CreateIfNotCreated_Reset();
1371*f6dc9357SAndroid Build Coastguard Worker   if (wres == 0) { wres = Thread.Create(RunScout2, this); }}
1372*f6dc9357SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(wres);
1373*f6dc9357SAndroid Build Coastguard Worker }
1374*f6dc9357SAndroid Build Coastguard Worker 
RunScout()1375*f6dc9357SAndroid Build Coastguard Worker void CDecoder::RunScout()
1376*f6dc9357SAndroid Build Coastguard Worker {
1377*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1378*f6dc9357SAndroid Build Coastguard Worker   {
1379*f6dc9357SAndroid Build Coastguard Worker     {
1380*f6dc9357SAndroid Build Coastguard Worker       PRIN_MT("ScoutEvent.Lock()")
1381*f6dc9357SAndroid Build Coastguard Worker       WRes wres = ScoutEvent.Lock();
1382*f6dc9357SAndroid Build Coastguard Worker       PRIN_MT("-- ScoutEvent.Lock()")
1383*f6dc9357SAndroid Build Coastguard Worker       if (wres != 0)
1384*f6dc9357SAndroid Build Coastguard Worker       {
1385*f6dc9357SAndroid Build Coastguard Worker         // ScoutRes = wres;
1386*f6dc9357SAndroid Build Coastguard Worker         return;
1387*f6dc9357SAndroid Build Coastguard Worker       }
1388*f6dc9357SAndroid Build Coastguard Worker     }
1389*f6dc9357SAndroid Build Coastguard Worker 
1390*f6dc9357SAndroid Build Coastguard Worker     CBlock &block = _block;
1391*f6dc9357SAndroid Build Coastguard Worker 
1392*f6dc9357SAndroid Build Coastguard Worker     if (block.StopScout)
1393*f6dc9357SAndroid Build Coastguard Worker     {
1394*f6dc9357SAndroid Build Coastguard Worker       // ScoutRes = S_OK;
1395*f6dc9357SAndroid Build Coastguard Worker       return;
1396*f6dc9357SAndroid Build Coastguard Worker     }
1397*f6dc9357SAndroid Build Coastguard Worker 
1398*f6dc9357SAndroid Build Coastguard Worker     block.Res = S_OK;
1399*f6dc9357SAndroid Build Coastguard Worker     block.WasFinished = false;
1400*f6dc9357SAndroid Build Coastguard Worker 
1401*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = S_OK;
1402*f6dc9357SAndroid Build Coastguard Worker 
1403*f6dc9357SAndroid Build Coastguard Worker     try
1404*f6dc9357SAndroid Build Coastguard Worker     {
1405*f6dc9357SAndroid Build Coastguard Worker       UInt64 packPos = GetInputProcessedSize();
1406*f6dc9357SAndroid Build Coastguard Worker 
1407*f6dc9357SAndroid Build Coastguard Worker       block.Props.blockSize = 0;
1408*f6dc9357SAndroid Build Coastguard Worker       block.Crc_Defined = false;
1409*f6dc9357SAndroid Build Coastguard Worker       // block.NextCrc_Defined = false;
1410*f6dc9357SAndroid Build Coastguard Worker       block.NextCrc = 0;
1411*f6dc9357SAndroid Build Coastguard Worker 
1412*f6dc9357SAndroid Build Coastguard Worker       for (;;)
1413*f6dc9357SAndroid Build Coastguard Worker       {
1414*f6dc9357SAndroid Build Coastguard Worker         if (Base.state == STATE_BLOCK_SIGNATURE)
1415*f6dc9357SAndroid Build Coastguard Worker         {
1416*f6dc9357SAndroid Build Coastguard Worker           res = ReadBlockSignature();
1417*f6dc9357SAndroid Build Coastguard Worker 
1418*f6dc9357SAndroid Build Coastguard Worker           if (res != S_OK)
1419*f6dc9357SAndroid Build Coastguard Worker             break;
1420*f6dc9357SAndroid Build Coastguard Worker 
1421*f6dc9357SAndroid Build Coastguard Worker           if (block.Props.blockSize == 0)
1422*f6dc9357SAndroid Build Coastguard Worker           {
1423*f6dc9357SAndroid Build Coastguard Worker             block.Crc = Base.crc;
1424*f6dc9357SAndroid Build Coastguard Worker             block.Crc_Defined = true;
1425*f6dc9357SAndroid Build Coastguard Worker           }
1426*f6dc9357SAndroid Build Coastguard Worker           else
1427*f6dc9357SAndroid Build Coastguard Worker           {
1428*f6dc9357SAndroid Build Coastguard Worker             block.NextCrc = Base.crc;
1429*f6dc9357SAndroid Build Coastguard Worker             // block.NextCrc_Defined = true;
1430*f6dc9357SAndroid Build Coastguard Worker           }
1431*f6dc9357SAndroid Build Coastguard Worker 
1432*f6dc9357SAndroid Build Coastguard Worker           continue;
1433*f6dc9357SAndroid Build Coastguard Worker         }
1434*f6dc9357SAndroid Build Coastguard Worker 
1435*f6dc9357SAndroid Build Coastguard Worker         if (Base.state == STATE_BLOCK_START)
1436*f6dc9357SAndroid Build Coastguard Worker         {
1437*f6dc9357SAndroid Build Coastguard Worker           if (block.Props.blockSize != 0)
1438*f6dc9357SAndroid Build Coastguard Worker             break;
1439*f6dc9357SAndroid Build Coastguard Worker 
1440*f6dc9357SAndroid Build Coastguard Worker           Base.Props.randMode = 1;
1441*f6dc9357SAndroid Build Coastguard Worker 
1442*f6dc9357SAndroid Build Coastguard Worker           res = ReadBlock();
1443*f6dc9357SAndroid Build Coastguard Worker 
1444*f6dc9357SAndroid Build Coastguard Worker           PRIN_MT("-- Base.ReadBlock")
1445*f6dc9357SAndroid Build Coastguard Worker           if (res != S_OK)
1446*f6dc9357SAndroid Build Coastguard Worker             break;
1447*f6dc9357SAndroid Build Coastguard Worker           block.Props = Base.Props;
1448*f6dc9357SAndroid Build Coastguard Worker           continue;
1449*f6dc9357SAndroid Build Coastguard Worker         }
1450*f6dc9357SAndroid Build Coastguard Worker 
1451*f6dc9357SAndroid Build Coastguard Worker         if (Base.state == STATE_STREAM_FINISHED)
1452*f6dc9357SAndroid Build Coastguard Worker         {
1453*f6dc9357SAndroid Build Coastguard Worker           if (!Base.DecodeAllStreams)
1454*f6dc9357SAndroid Build Coastguard Worker           {
1455*f6dc9357SAndroid Build Coastguard Worker             block.WasFinished = true;
1456*f6dc9357SAndroid Build Coastguard Worker             break;
1457*f6dc9357SAndroid Build Coastguard Worker           }
1458*f6dc9357SAndroid Build Coastguard Worker 
1459*f6dc9357SAndroid Build Coastguard Worker           res = StartRead();
1460*f6dc9357SAndroid Build Coastguard Worker 
1461*f6dc9357SAndroid Build Coastguard Worker           if (Base.NeedMoreInput)
1462*f6dc9357SAndroid Build Coastguard Worker           {
1463*f6dc9357SAndroid Build Coastguard Worker             if (Base.state2 == 0)
1464*f6dc9357SAndroid Build Coastguard Worker               Base.NeedMoreInput = false;
1465*f6dc9357SAndroid Build Coastguard Worker             block.WasFinished = true;
1466*f6dc9357SAndroid Build Coastguard Worker             res = S_OK;
1467*f6dc9357SAndroid Build Coastguard Worker             break;
1468*f6dc9357SAndroid Build Coastguard Worker           }
1469*f6dc9357SAndroid Build Coastguard Worker 
1470*f6dc9357SAndroid Build Coastguard Worker           if (res != S_OK)
1471*f6dc9357SAndroid Build Coastguard Worker             break;
1472*f6dc9357SAndroid Build Coastguard Worker 
1473*f6dc9357SAndroid Build Coastguard Worker           if (GetInputProcessedSize() - packPos > 0) // kProgressStep
1474*f6dc9357SAndroid Build Coastguard Worker             break;
1475*f6dc9357SAndroid Build Coastguard Worker           continue;
1476*f6dc9357SAndroid Build Coastguard Worker         }
1477*f6dc9357SAndroid Build Coastguard Worker 
1478*f6dc9357SAndroid Build Coastguard Worker         // throw 1;
1479*f6dc9357SAndroid Build Coastguard Worker         res = E_FAIL;
1480*f6dc9357SAndroid Build Coastguard Worker         break;
1481*f6dc9357SAndroid Build Coastguard Worker       }
1482*f6dc9357SAndroid Build Coastguard Worker     }
1483*f6dc9357SAndroid Build Coastguard Worker 
1484*f6dc9357SAndroid Build Coastguard Worker     catch (...) { res = E_FAIL; }
1485*f6dc9357SAndroid Build Coastguard Worker 
1486*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
1487*f6dc9357SAndroid Build Coastguard Worker     {
1488*f6dc9357SAndroid Build Coastguard Worker       PRIN_MT("error")
1489*f6dc9357SAndroid Build Coastguard Worker       block.Res = res;
1490*f6dc9357SAndroid Build Coastguard Worker       block.WasFinished = true;
1491*f6dc9357SAndroid Build Coastguard Worker     }
1492*f6dc9357SAndroid Build Coastguard Worker 
1493*f6dc9357SAndroid Build Coastguard Worker     block.PackPos = GetInputProcessedSize();
1494*f6dc9357SAndroid Build Coastguard Worker     PRIN_MT("DecoderEvent.Set()")
1495*f6dc9357SAndroid Build Coastguard Worker     WRes wres = DecoderEvent.Set();
1496*f6dc9357SAndroid Build Coastguard Worker     if (wres != 0)
1497*f6dc9357SAndroid Build Coastguard Worker     {
1498*f6dc9357SAndroid Build Coastguard Worker       // ScoutRes = wres;
1499*f6dc9357SAndroid Build Coastguard Worker       return;
1500*f6dc9357SAndroid Build Coastguard Worker     }
1501*f6dc9357SAndroid Build Coastguard Worker   }
1502*f6dc9357SAndroid Build Coastguard Worker }
1503*f6dc9357SAndroid Build Coastguard Worker 
1504*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::SetNumberOfThreads (UInt32 numThreads))1505*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::SetNumberOfThreads(UInt32 numThreads))
1506*f6dc9357SAndroid Build Coastguard Worker {
1507*f6dc9357SAndroid Build Coastguard Worker   MtMode = (numThreads > 1);
1508*f6dc9357SAndroid Build Coastguard Worker 
1509*f6dc9357SAndroid Build Coastguard Worker   #ifndef BZIP2_BYTE_MODE
1510*f6dc9357SAndroid Build Coastguard Worker   MtMode = false;
1511*f6dc9357SAndroid Build Coastguard Worker   #endif
1512*f6dc9357SAndroid Build Coastguard Worker 
1513*f6dc9357SAndroid Build Coastguard Worker   // MtMode = false;
1514*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1515*f6dc9357SAndroid Build Coastguard Worker }
1516*f6dc9357SAndroid Build Coastguard Worker 
1517*f6dc9357SAndroid Build Coastguard Worker #endif
1518*f6dc9357SAndroid Build Coastguard Worker 
1519*f6dc9357SAndroid Build Coastguard Worker 
1520*f6dc9357SAndroid Build Coastguard Worker 
1521*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_NO_READ_FROM_CODER
1522*f6dc9357SAndroid Build Coastguard Worker 
1523*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::SetInStream (ISequentialInStream * inStream))1524*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::SetInStream(ISequentialInStream *inStream))
1525*f6dc9357SAndroid Build Coastguard Worker {
1526*f6dc9357SAndroid Build Coastguard Worker   Base.InStreamRef = inStream;
1527*f6dc9357SAndroid Build Coastguard Worker   Base.InStream = inStream;
1528*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1529*f6dc9357SAndroid Build Coastguard Worker }
1530*f6dc9357SAndroid Build Coastguard Worker 
1531*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::ReleaseInStream ())1532*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::ReleaseInStream())
1533*f6dc9357SAndroid Build Coastguard Worker {
1534*f6dc9357SAndroid Build Coastguard Worker   Base.InStreamRef.Release();
1535*f6dc9357SAndroid Build Coastguard Worker   Base.InStream = NULL;
1536*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1537*f6dc9357SAndroid Build Coastguard Worker }
1538*f6dc9357SAndroid Build Coastguard Worker 
1539*f6dc9357SAndroid Build Coastguard Worker 
1540*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::SetOutStreamSize (const UInt64 * outSize))1541*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::SetOutStreamSize(const UInt64 *outSize))
1542*f6dc9357SAndroid Build Coastguard Worker {
1543*f6dc9357SAndroid Build Coastguard Worker   InitOutSize(outSize);
1544*f6dc9357SAndroid Build Coastguard Worker 
1545*f6dc9357SAndroid Build Coastguard Worker   InitInputBuffer();
1546*f6dc9357SAndroid Build Coastguard Worker 
1547*f6dc9357SAndroid Build Coastguard Worker   if (!CreateInputBufer())
1548*f6dc9357SAndroid Build Coastguard Worker     return E_OUTOFMEMORY;
1549*f6dc9357SAndroid Build Coastguard Worker 
1550*f6dc9357SAndroid Build Coastguard Worker   // InitInputBuffer();
1551*f6dc9357SAndroid Build Coastguard Worker 
1552*f6dc9357SAndroid Build Coastguard Worker   StartNewStream();
1553*f6dc9357SAndroid Build Coastguard Worker 
1554*f6dc9357SAndroid Build Coastguard Worker   _blockFinished = true;
1555*f6dc9357SAndroid Build Coastguard Worker 
1556*f6dc9357SAndroid Build Coastguard Worker   ErrorResult = S_OK;
1557*f6dc9357SAndroid Build Coastguard Worker 
1558*f6dc9357SAndroid Build Coastguard Worker   _inputFinished = false;
1559*f6dc9357SAndroid Build Coastguard Worker   _inputRes = S_OK;
1560*f6dc9357SAndroid Build Coastguard Worker 
1561*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
1562*f6dc9357SAndroid Build Coastguard Worker }
1563*f6dc9357SAndroid Build Coastguard Worker 
1564*f6dc9357SAndroid Build Coastguard Worker 
1565*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CDecoder::Read (void * data,UInt32 size,UInt32 * processedSize))1566*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize))
1567*f6dc9357SAndroid Build Coastguard Worker {
1568*f6dc9357SAndroid Build Coastguard Worker   *processedSize = 0;
1569*f6dc9357SAndroid Build Coastguard Worker 
1570*f6dc9357SAndroid Build Coastguard Worker   try {
1571*f6dc9357SAndroid Build Coastguard Worker 
1572*f6dc9357SAndroid Build Coastguard Worker   if (ErrorResult != S_OK)
1573*f6dc9357SAndroid Build Coastguard Worker     return ErrorResult;
1574*f6dc9357SAndroid Build Coastguard Worker 
1575*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1576*f6dc9357SAndroid Build Coastguard Worker   {
1577*f6dc9357SAndroid Build Coastguard Worker     if (Base.state == STATE_STREAM_FINISHED)
1578*f6dc9357SAndroid Build Coastguard Worker     {
1579*f6dc9357SAndroid Build Coastguard Worker       if (!Base.DecodeAllStreams)
1580*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1581*f6dc9357SAndroid Build Coastguard Worker       StartNewStream();
1582*f6dc9357SAndroid Build Coastguard Worker       continue;
1583*f6dc9357SAndroid Build Coastguard Worker     }
1584*f6dc9357SAndroid Build Coastguard Worker 
1585*f6dc9357SAndroid Build Coastguard Worker     if (Base.state == STATE_STREAM_SIGNATURE)
1586*f6dc9357SAndroid Build Coastguard Worker     {
1587*f6dc9357SAndroid Build Coastguard Worker       ErrorResult = ReadStreamSignature();
1588*f6dc9357SAndroid Build Coastguard Worker 
1589*f6dc9357SAndroid Build Coastguard Worker       if (Base.NeedMoreInput)
1590*f6dc9357SAndroid Build Coastguard Worker         if (Base.state2 == 0 && Base.NumStreams != 0)
1591*f6dc9357SAndroid Build Coastguard Worker         {
1592*f6dc9357SAndroid Build Coastguard Worker           Base.NeedMoreInput = false;
1593*f6dc9357SAndroid Build Coastguard Worker           ErrorResult = S_OK;
1594*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
1595*f6dc9357SAndroid Build Coastguard Worker         }
1596*f6dc9357SAndroid Build Coastguard Worker       if (ErrorResult != S_OK)
1597*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1598*f6dc9357SAndroid Build Coastguard Worker       continue;
1599*f6dc9357SAndroid Build Coastguard Worker     }
1600*f6dc9357SAndroid Build Coastguard Worker 
1601*f6dc9357SAndroid Build Coastguard Worker     if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE)
1602*f6dc9357SAndroid Build Coastguard Worker     {
1603*f6dc9357SAndroid Build Coastguard Worker       ErrorResult = ReadBlockSignature();
1604*f6dc9357SAndroid Build Coastguard Worker 
1605*f6dc9357SAndroid Build Coastguard Worker       if (ErrorResult != S_OK)
1606*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1607*f6dc9357SAndroid Build Coastguard Worker 
1608*f6dc9357SAndroid Build Coastguard Worker       continue;
1609*f6dc9357SAndroid Build Coastguard Worker     }
1610*f6dc9357SAndroid Build Coastguard Worker 
1611*f6dc9357SAndroid Build Coastguard Worker     if (_outSizeDefined)
1612*f6dc9357SAndroid Build Coastguard Worker     {
1613*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = _outSize - _outPosTotal;
1614*f6dc9357SAndroid Build Coastguard Worker       if (size >= rem)
1615*f6dc9357SAndroid Build Coastguard Worker         size = (UInt32)rem;
1616*f6dc9357SAndroid Build Coastguard Worker     }
1617*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
1618*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1619*f6dc9357SAndroid Build Coastguard Worker 
1620*f6dc9357SAndroid Build Coastguard Worker     if (_blockFinished)
1621*f6dc9357SAndroid Build Coastguard Worker     {
1622*f6dc9357SAndroid Build Coastguard Worker       if (Base.state != STATE_BLOCK_START)
1623*f6dc9357SAndroid Build Coastguard Worker       {
1624*f6dc9357SAndroid Build Coastguard Worker         ErrorResult = E_FAIL;
1625*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1626*f6dc9357SAndroid Build Coastguard Worker       }
1627*f6dc9357SAndroid Build Coastguard Worker 
1628*f6dc9357SAndroid Build Coastguard Worker       Base.Props.randMode = 1;
1629*f6dc9357SAndroid Build Coastguard Worker       ErrorResult = ReadBlock();
1630*f6dc9357SAndroid Build Coastguard Worker 
1631*f6dc9357SAndroid Build Coastguard Worker       if (ErrorResult != S_OK)
1632*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1633*f6dc9357SAndroid Build Coastguard Worker 
1634*f6dc9357SAndroid Build Coastguard Worker       DecodeBlock1(_counters, Base.Props.blockSize);
1635*f6dc9357SAndroid Build Coastguard Worker 
1636*f6dc9357SAndroid Build Coastguard Worker       _spec._blockSize = Base.Props.blockSize;
1637*f6dc9357SAndroid Build Coastguard Worker       _spec._tt = _counters + 256;
1638*f6dc9357SAndroid Build Coastguard Worker       _spec.Init(Base.Props.origPtr, Base.Props.randMode);
1639*f6dc9357SAndroid Build Coastguard Worker 
1640*f6dc9357SAndroid Build Coastguard Worker       _blockFinished = false;
1641*f6dc9357SAndroid Build Coastguard Worker     }
1642*f6dc9357SAndroid Build Coastguard Worker 
1643*f6dc9357SAndroid Build Coastguard Worker     {
1644*f6dc9357SAndroid Build Coastguard Worker       Byte *ptr = _spec.Decode((Byte *)data, size);
1645*f6dc9357SAndroid Build Coastguard Worker 
1646*f6dc9357SAndroid Build Coastguard Worker       const UInt32 processed = (UInt32)(ptr - (Byte *)data);
1647*f6dc9357SAndroid Build Coastguard Worker       data = ptr;
1648*f6dc9357SAndroid Build Coastguard Worker       size -= processed;
1649*f6dc9357SAndroid Build Coastguard Worker       (*processedSize) += processed;
1650*f6dc9357SAndroid Build Coastguard Worker       _outPosTotal += processed;
1651*f6dc9357SAndroid Build Coastguard Worker 
1652*f6dc9357SAndroid Build Coastguard Worker       if (_spec.Finished())
1653*f6dc9357SAndroid Build Coastguard Worker       {
1654*f6dc9357SAndroid Build Coastguard Worker         _blockFinished = true;
1655*f6dc9357SAndroid Build Coastguard Worker         if (Base.crc != _spec._crc.GetDigest())
1656*f6dc9357SAndroid Build Coastguard Worker         {
1657*f6dc9357SAndroid Build Coastguard Worker           BlockCrcError = true;
1658*f6dc9357SAndroid Build Coastguard Worker           ErrorResult = S_FALSE;
1659*f6dc9357SAndroid Build Coastguard Worker           return ErrorResult;
1660*f6dc9357SAndroid Build Coastguard Worker         }
1661*f6dc9357SAndroid Build Coastguard Worker       }
1662*f6dc9357SAndroid Build Coastguard Worker     }
1663*f6dc9357SAndroid Build Coastguard Worker   }
1664*f6dc9357SAndroid Build Coastguard Worker 
1665*f6dc9357SAndroid Build Coastguard Worker   } catch(...) { ErrorResult = S_FALSE; return S_FALSE; }
1666*f6dc9357SAndroid Build Coastguard Worker }
1667*f6dc9357SAndroid Build Coastguard Worker 
1668*f6dc9357SAndroid Build Coastguard Worker 
1669*f6dc9357SAndroid Build Coastguard Worker 
1670*f6dc9357SAndroid Build Coastguard Worker // ---------- NSIS ----------
1671*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CNsisDecoder::Read (void * data,UInt32 size,UInt32 * processedSize))1672*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CNsisDecoder::Read(void *data, UInt32 size, UInt32 *processedSize))
1673*f6dc9357SAndroid Build Coastguard Worker {
1674*f6dc9357SAndroid Build Coastguard Worker   *processedSize = 0;
1675*f6dc9357SAndroid Build Coastguard Worker 
1676*f6dc9357SAndroid Build Coastguard Worker   try {
1677*f6dc9357SAndroid Build Coastguard Worker 
1678*f6dc9357SAndroid Build Coastguard Worker   if (ErrorResult != S_OK)
1679*f6dc9357SAndroid Build Coastguard Worker     return ErrorResult;
1680*f6dc9357SAndroid Build Coastguard Worker 
1681*f6dc9357SAndroid Build Coastguard Worker   if (Base.state == STATE_STREAM_FINISHED)
1682*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
1683*f6dc9357SAndroid Build Coastguard Worker 
1684*f6dc9357SAndroid Build Coastguard Worker   if (Base.state == STATE_STREAM_SIGNATURE)
1685*f6dc9357SAndroid Build Coastguard Worker   {
1686*f6dc9357SAndroid Build Coastguard Worker     Base.blockSizeMax = 9 * kBlockSizeStep;
1687*f6dc9357SAndroid Build Coastguard Worker     Base.state = STATE_BLOCK_SIGNATURE;
1688*f6dc9357SAndroid Build Coastguard Worker     // Base.state2 = 0;
1689*f6dc9357SAndroid Build Coastguard Worker   }
1690*f6dc9357SAndroid Build Coastguard Worker 
1691*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1692*f6dc9357SAndroid Build Coastguard Worker   {
1693*f6dc9357SAndroid Build Coastguard Worker     if (_blockFinished && Base.state == STATE_BLOCK_SIGNATURE)
1694*f6dc9357SAndroid Build Coastguard Worker     {
1695*f6dc9357SAndroid Build Coastguard Worker       ErrorResult = ReadInput();
1696*f6dc9357SAndroid Build Coastguard Worker       if (ErrorResult != S_OK)
1697*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1698*f6dc9357SAndroid Build Coastguard Worker 
1699*f6dc9357SAndroid Build Coastguard Worker       int b;
1700*f6dc9357SAndroid Build Coastguard Worker       Base.ReadByte(b);
1701*f6dc9357SAndroid Build Coastguard Worker       if (b < 0)
1702*f6dc9357SAndroid Build Coastguard Worker       {
1703*f6dc9357SAndroid Build Coastguard Worker         ErrorResult = S_FALSE;
1704*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1705*f6dc9357SAndroid Build Coastguard Worker       }
1706*f6dc9357SAndroid Build Coastguard Worker 
1707*f6dc9357SAndroid Build Coastguard Worker       if (b == kFinSig0)
1708*f6dc9357SAndroid Build Coastguard Worker       {
1709*f6dc9357SAndroid Build Coastguard Worker         /*
1710*f6dc9357SAndroid Build Coastguard Worker         if (!Base.AreRemainByteBitsEmpty())
1711*f6dc9357SAndroid Build Coastguard Worker           ErrorResult = S_FALSE;
1712*f6dc9357SAndroid Build Coastguard Worker         */
1713*f6dc9357SAndroid Build Coastguard Worker         Base.state = STATE_STREAM_FINISHED;
1714*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1715*f6dc9357SAndroid Build Coastguard Worker       }
1716*f6dc9357SAndroid Build Coastguard Worker 
1717*f6dc9357SAndroid Build Coastguard Worker       if (b != kBlockSig0)
1718*f6dc9357SAndroid Build Coastguard Worker       {
1719*f6dc9357SAndroid Build Coastguard Worker         ErrorResult = S_FALSE;
1720*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1721*f6dc9357SAndroid Build Coastguard Worker       }
1722*f6dc9357SAndroid Build Coastguard Worker 
1723*f6dc9357SAndroid Build Coastguard Worker       Base.state = STATE_BLOCK_START;
1724*f6dc9357SAndroid Build Coastguard Worker     }
1725*f6dc9357SAndroid Build Coastguard Worker 
1726*f6dc9357SAndroid Build Coastguard Worker     if (_outSizeDefined)
1727*f6dc9357SAndroid Build Coastguard Worker     {
1728*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = _outSize - _outPosTotal;
1729*f6dc9357SAndroid Build Coastguard Worker       if (size >= rem)
1730*f6dc9357SAndroid Build Coastguard Worker         size = (UInt32)rem;
1731*f6dc9357SAndroid Build Coastguard Worker     }
1732*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
1733*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
1734*f6dc9357SAndroid Build Coastguard Worker 
1735*f6dc9357SAndroid Build Coastguard Worker     if (_blockFinished)
1736*f6dc9357SAndroid Build Coastguard Worker     {
1737*f6dc9357SAndroid Build Coastguard Worker       if (Base.state != STATE_BLOCK_START)
1738*f6dc9357SAndroid Build Coastguard Worker       {
1739*f6dc9357SAndroid Build Coastguard Worker         ErrorResult = E_FAIL;
1740*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1741*f6dc9357SAndroid Build Coastguard Worker       }
1742*f6dc9357SAndroid Build Coastguard Worker 
1743*f6dc9357SAndroid Build Coastguard Worker       Base.Props.randMode = 0;
1744*f6dc9357SAndroid Build Coastguard Worker       ErrorResult = ReadBlock();
1745*f6dc9357SAndroid Build Coastguard Worker 
1746*f6dc9357SAndroid Build Coastguard Worker       if (ErrorResult != S_OK)
1747*f6dc9357SAndroid Build Coastguard Worker         return ErrorResult;
1748*f6dc9357SAndroid Build Coastguard Worker 
1749*f6dc9357SAndroid Build Coastguard Worker       DecodeBlock1(_counters, Base.Props.blockSize);
1750*f6dc9357SAndroid Build Coastguard Worker 
1751*f6dc9357SAndroid Build Coastguard Worker       _spec._blockSize = Base.Props.blockSize;
1752*f6dc9357SAndroid Build Coastguard Worker       _spec._tt = _counters + 256;
1753*f6dc9357SAndroid Build Coastguard Worker       _spec.Init(Base.Props.origPtr, Base.Props.randMode);
1754*f6dc9357SAndroid Build Coastguard Worker 
1755*f6dc9357SAndroid Build Coastguard Worker       _blockFinished = false;
1756*f6dc9357SAndroid Build Coastguard Worker     }
1757*f6dc9357SAndroid Build Coastguard Worker 
1758*f6dc9357SAndroid Build Coastguard Worker     {
1759*f6dc9357SAndroid Build Coastguard Worker       Byte *ptr = _spec.Decode((Byte *)data, size);
1760*f6dc9357SAndroid Build Coastguard Worker 
1761*f6dc9357SAndroid Build Coastguard Worker       const UInt32 processed = (UInt32)(ptr - (Byte *)data);
1762*f6dc9357SAndroid Build Coastguard Worker       data = ptr;
1763*f6dc9357SAndroid Build Coastguard Worker       size -= processed;
1764*f6dc9357SAndroid Build Coastguard Worker       (*processedSize) += processed;
1765*f6dc9357SAndroid Build Coastguard Worker       _outPosTotal += processed;
1766*f6dc9357SAndroid Build Coastguard Worker 
1767*f6dc9357SAndroid Build Coastguard Worker       if (_spec.Finished())
1768*f6dc9357SAndroid Build Coastguard Worker         _blockFinished = true;
1769*f6dc9357SAndroid Build Coastguard Worker     }
1770*f6dc9357SAndroid Build Coastguard Worker   }
1771*f6dc9357SAndroid Build Coastguard Worker 
1772*f6dc9357SAndroid Build Coastguard Worker   } catch(...) { ErrorResult = S_FALSE; return S_FALSE; }
1773*f6dc9357SAndroid Build Coastguard Worker }
1774*f6dc9357SAndroid Build Coastguard Worker 
1775*f6dc9357SAndroid Build Coastguard Worker #endif
1776*f6dc9357SAndroid Build Coastguard Worker 
1777*f6dc9357SAndroid Build Coastguard Worker }}
1778