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