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