xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/BZip2Decoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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