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