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