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