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