1 // LzfseDecoder.cpp
2 
3 /*
4 This code implements LZFSE data decompressing.
5 The code from "LZFSE compression library" was used.
6 
7 2018      : Igor Pavlov : BSD 3-clause License : the code in this file
8 2015-2017 : Apple Inc   : BSD 3-clause License : original "LZFSE compression library" code
9 
10 The code in the "LZFSE compression library" is licensed under the "BSD 3-clause License":
11 ----
12 Copyright (c) 2015-2016, Apple Inc. All rights reserved.
13 
14 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
15 
16 1.  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
17 
18 2.  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
19     in the documentation and/or other materials provided with the distribution.
20 
21 3.  Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
22     from this software without specific prior written permission.
23 
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ----
31 */
32 
33 #include "StdAfx.h"
34 
35 // #define SHOW_DEBUG_INFO
36 
37 #ifdef SHOW_DEBUG_INFO
38 #include <stdio.h>
39 #endif
40 
41 #ifdef SHOW_DEBUG_INFO
42 #define PRF(x) x
43 #else
44 #define PRF(x)
45 #endif
46 
47 #include "../../../C/CpuArch.h"
48 
49 #include "LzfseDecoder.h"
50 
51 namespace NCompress {
52 namespace NLzfse {
53 
54 static const Byte kSignature_LZFSE_V1 = 0x31; // '1'
55 static const Byte kSignature_LZFSE_V2 = 0x32; // '2'
56 
57 
GetUInt32(UInt32 & val)58 HRESULT CDecoder::GetUInt32(UInt32 &val)
59 {
60   Byte b[4];
61   for (unsigned i = 0; i < 4; i++)
62     if (!m_InStream.ReadByte(b[i]))
63       return S_FALSE;
64   val = GetUi32(b);
65   return S_OK;
66 }
67 
68 
69 
DecodeUncompressed(UInt32 unpackSize)70 HRESULT CDecoder::DecodeUncompressed(UInt32 unpackSize)
71 {
72   PRF(printf("\nUncompressed %7u\n", unpackSize));
73 
74   const unsigned kBufSize = 1 << 8;
75   Byte buf[kBufSize];
76   for (;;)
77   {
78     if (unpackSize == 0)
79       return S_OK;
80     UInt32 cur = unpackSize;
81     if (cur > kBufSize)
82       cur = kBufSize;
83     UInt32 cur2 = (UInt32)m_InStream.ReadBytes(buf, cur);
84     m_OutWindowStream.PutBytes(buf, cur2);
85     if (cur != cur2)
86       return S_FALSE;
87   }
88 }
89 
90 
91 
DecodeLzvn(UInt32 unpackSize)92 HRESULT CDecoder::DecodeLzvn(UInt32 unpackSize)
93 {
94   UInt32 packSize;
95   RINOK(GetUInt32(packSize));
96 
97   PRF(printf("\nLZVN %7u %7u", unpackSize, packSize));
98 
99   UInt32 D = 0;
100 
101   for (;;)
102   {
103     if (packSize == 0)
104       return S_FALSE;
105     Byte b;
106     if (!m_InStream.ReadByte(b))
107       return S_FALSE;
108     packSize--;
109 
110     UInt32 M;
111     UInt32 L;
112 
113     if (b >= 0xE0)
114     {
115       /*
116       large L   - 11100000 LLLLLLLL <LITERALS>
117       small L   - 1110LLLL <LITERALS>
118 
119       large Rep - 11110000 MMMMMMMM
120       small Rep - 1111MMMM
121       */
122 
123       M = b & 0xF;
124       if (M == 0)
125       {
126         if (packSize == 0)
127           return S_FALSE;
128         Byte b1;
129         if (!m_InStream.ReadByte(b1))
130           return S_FALSE;
131         packSize--;
132         M = (UInt32)b1 + 16;
133       }
134       L = 0;
135       if ((b & 0x10) == 0)
136       {
137         // Literals only
138         L = M;
139         M = 0;
140       }
141     }
142 
143     // ERROR codes
144     else if ((b & 0xF0) == 0x70) // 0111xxxx
145       return S_FALSE;
146     else if ((b & 0xF0) == 0xD0) // 1101xxxx
147       return S_FALSE;
148 
149     else
150     {
151       if ((b & 0xE0) == 0xA0)
152       {
153         // medium  - 101LLMMM DDDDDDMM DDDDDDDD <LITERALS>
154         if (packSize < 2)
155           return S_FALSE;
156         Byte b1;
157         if (!m_InStream.ReadByte(b1))
158           return S_FALSE;
159         packSize--;
160 
161         Byte b2;
162         if (!m_InStream.ReadByte(b2))
163           return S_FALSE;
164         packSize--;
165         L = (((UInt32)b >> 3) & 3);
166         M = (((UInt32)b & 7) << 2) + (b1 & 3);
167         D = ((UInt32)b1 >> 2) + ((UInt32)b2 << 6);
168       }
169       else
170       {
171         L = (UInt32)b >> 6;
172         M = ((UInt32)b >> 3) & 7;
173         if ((b & 0x7) == 6)
174         {
175           // REP - LLMMM110 <LITERALS>
176           if (L == 0)
177           {
178             // spec
179             if (M == 0)
180               break; // EOS
181             if (M <= 2)
182               continue; // NOP
183             return S_FALSE; // UNDEFINED
184           }
185         }
186         else
187         {
188           if (packSize == 0)
189             return S_FALSE;
190           Byte b1;
191           if (!m_InStream.ReadByte(b1))
192             return S_FALSE;
193           packSize--;
194 
195           // large - LLMMM111 DDDDDDDD DDDDDDDD <LITERALS>
196           // small - LLMMMDDD DDDDDDDD <LITERALS>
197           D  = ((UInt32)b & 7);
198           if (D == 7)
199           {
200             if (packSize == 0)
201               return S_FALSE;
202             Byte b2;
203             if (!m_InStream.ReadByte(b2))
204               return S_FALSE;
205             packSize--;
206             D = b2;
207           }
208           D = (D << 8) + b1;
209         }
210       }
211 
212       M += 3;
213     }
214     {
215       for (unsigned i = 0; i < L; i++)
216       {
217         if (packSize == 0 || unpackSize == 0)
218           return S_FALSE;
219         Byte b1;
220         if (!m_InStream.ReadByte(b1))
221           return S_FALSE;
222         packSize--;
223         m_OutWindowStream.PutByte(b1);
224         unpackSize--;
225       }
226     }
227 
228     if (M != 0)
229     {
230       if (unpackSize == 0 || D == 0)
231         return S_FALSE;
232       unsigned cur = M;
233       if (cur > unpackSize)
234         cur = (unsigned)unpackSize;
235       if (!m_OutWindowStream.CopyBlock(D - 1, cur))
236         return S_FALSE;
237       unpackSize -= cur;
238       if (cur != M)
239         return S_FALSE;
240     }
241   }
242 
243   if (unpackSize != 0)
244     return S_FALSE;
245 
246   // LZVN encoder writes 7 additional zero bytes
247   if (packSize != 7)
248     return S_FALSE;
249   do
250   {
251     Byte b;
252     if (!m_InStream.ReadByte(b))
253       return S_FALSE;
254     packSize--;
255     if (b != 0)
256       return S_FALSE;
257   }
258   while (packSize != 0);
259 
260   return S_OK;
261 }
262 
263 
264 
265 // ---------- LZFSE ----------
266 
267 #define MATCHES_PER_BLOCK 10000
268 #define LITERALS_PER_BLOCK (4 * MATCHES_PER_BLOCK)
269 
270 #define NUM_L_SYMBOLS 20
271 #define NUM_M_SYMBOLS 20
272 #define NUM_D_SYMBOLS 64
273 #define NUM_LIT_SYMBOLS 256
274 
275 #define NUM_SYMBOLS ( \
276     NUM_L_SYMBOLS + \
277     NUM_M_SYMBOLS + \
278     NUM_D_SYMBOLS + \
279     NUM_LIT_SYMBOLS)
280 
281 #define NUM_L_STATES (1 << 6)
282 #define NUM_M_STATES (1 << 6)
283 #define NUM_D_STATES (1 << 8)
284 #define NUM_LIT_STATES (1 << 10)
285 
286 
287 typedef UInt32 CFseState;
288 
289 
SumFreqs(const UInt16 * freqs,unsigned num)290 static UInt32 SumFreqs(const UInt16 *freqs, unsigned num)
291 {
292   UInt32 sum = 0;
293   for (unsigned i = 0; i < num; i++)
294     sum += (UInt32)freqs[i];
295   return sum;
296 }
297 
298 
CountZeroBits(UInt32 val,UInt32 mask)299 static MY_FORCE_INLINE unsigned CountZeroBits(UInt32 val, UInt32 mask)
300 {
301   for (unsigned i = 0;;)
302   {
303     if (val & mask)
304       return i;
305     i++;
306     mask >>= 1;
307   }
308 }
309 
310 
InitLitTable(const UInt16 * freqs,UInt32 * table)311 static MY_FORCE_INLINE void InitLitTable(const UInt16 *freqs, UInt32 *table)
312 {
313   for (unsigned i = 0; i < NUM_LIT_SYMBOLS; i++)
314   {
315     unsigned f = freqs[i];
316     if (f == 0)
317       continue;
318 
319     //         0 <   f     <= numStates
320     //         0 <=  k     <= numStatesLog
321     // numStates <= (f<<k) <  numStates * 2
322     //         0 <  j0     <= f
323     // (f + j0) = next_power_of_2 for f
324     unsigned k = CountZeroBits(f, NUM_LIT_STATES);
325     unsigned j0 = (((unsigned)NUM_LIT_STATES * 2) >> k) - f;
326 
327     /*
328     CEntry
329     {
330       Byte k;
331       Byte symbol;
332       UInt16 delta;
333     };
334     */
335 
336     UInt32 e = ((UInt32)i << 8) + k;
337     k += 16;
338     UInt32 d = e + ((UInt32)f << k) - ((UInt32)NUM_LIT_STATES << 16);
339     UInt32 step = (UInt32)1 << k;
340 
341     unsigned j = 0;
342     do
343     {
344       *table++ = d;
345       d += step;
346     }
347     while (++j < j0);
348 
349     e--;
350     step >>= 1;
351 
352     for (j = j0; j < f; j++)
353     {
354       *table++ = e;
355       e += step;
356     }
357   }
358 }
359 
360 
361 typedef struct
362 {
363   Byte totalBits;
364   Byte extraBits;
365   UInt16 delta;
366   UInt32 vbase;
367 } CExtraEntry;
368 
369 
InitExtraDecoderTable(unsigned numStates,unsigned numSymbols,const UInt16 * freqs,const Byte * vbits,CExtraEntry * table)370 static void InitExtraDecoderTable(unsigned numStates,
371     unsigned numSymbols,
372     const UInt16 *freqs,
373     const Byte *vbits,
374     CExtraEntry *table)
375 {
376   UInt32 vbase = 0;
377 
378   for (unsigned i = 0; i < numSymbols; i++)
379   {
380     unsigned f = freqs[i];
381     unsigned extraBits = vbits[i];
382 
383     if (f != 0)
384     {
385       unsigned k = CountZeroBits(f, numStates);
386       unsigned j0 = ((2 * numStates) >> k) - f;
387 
388       unsigned j = 0;
389       do
390       {
391         CExtraEntry *e = table++;
392         e->totalBits = (Byte)(k + extraBits);
393         e->extraBits = (Byte)extraBits;
394         e->delta = (UInt16)(((f + j) << k) - numStates);
395         e->vbase = vbase;
396       }
397       while (++j < j0);
398 
399       f -= j0;
400       k--;
401 
402       for (j = 0; j < f; j++)
403       {
404         CExtraEntry *e = table++;
405         e->totalBits = (Byte)(k + extraBits);
406         e->extraBits = (Byte)extraBits;
407         e->delta = (UInt16)(j << k);
408         e->vbase = vbase;
409       }
410     }
411 
412     vbase += ((UInt32)1 << extraBits);
413   }
414 }
415 
416 
417 static const Byte k_L_extra[NUM_L_SYMBOLS] =
418 {
419   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 8
420 };
421 
422 static const Byte k_M_extra[NUM_M_SYMBOLS] =
423 {
424   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11
425 };
426 
427 static const Byte k_D_extra[NUM_D_SYMBOLS] =
428 {
429    0,  0,  0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,
430    4,  4,  4,  4,  5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,
431    8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11, 11,
432   12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15
433 };
434 
435 
436 
437 // ---------- CBitStream ----------
438 
439 typedef struct
440 {
441   UInt32 accum;
442   unsigned numBits; // [0, 31] - Number of valid bits in (accum), other bits are 0
443 } CBitStream;
444 
445 
FseInStream_Init(CBitStream * s,int n,const Byte ** pbuf)446 static MY_FORCE_INLINE int FseInStream_Init(CBitStream *s,
447     int n, // [-7, 0], (-n == number_of_unused_bits) in last byte
448     const Byte **pbuf)
449 {
450   *pbuf -= 4;
451   s->accum = GetUi32(*pbuf);
452   if (n)
453   {
454     s->numBits = n + 32;
455     if ((s->accum >> s->numBits) != 0)
456       return -1; // ERROR, encoder should have zeroed the upper bits
457   }
458   else
459   {
460     *pbuf += 1;
461     s->accum >>= 8;
462     s->numBits = 24;
463   }
464   return 0; // OK
465 }
466 
467 
468 // 0 <= numBits < 32
469 #define mask31(x, numBits) ((x) & (((UInt32)1 << (numBits)) - 1))
470 
471 #define FseInStream_FLUSH \
472   { unsigned nbits = (31 - in.numBits) & -8; \
473   if (nbits) { \
474     buf -= (nbits >> 3); \
475     if (buf < buf_check) return S_FALSE; \
476     UInt32 v = GetUi32(buf); \
477     in.accum = (in.accum << nbits) | mask31(v, nbits); \
478     in.numBits += nbits; }}
479 
480 
481 
BitStream_Pull(CBitStream * s,unsigned numBits)482 static MY_FORCE_INLINE UInt32 BitStream_Pull(CBitStream *s, unsigned numBits)
483 {
484   s->numBits -= numBits;
485   UInt32 v = s->accum >> s->numBits;
486   s->accum = mask31(s->accum, s->numBits);
487   return v;
488 }
489 
490 
491 #define DECODE_LIT(dest, pstate) { \
492   UInt32 e = lit_decoder[pstate]; \
493   pstate = (CFseState)((e >> 16) + BitStream_Pull(&in, e & 0xff)); \
494   dest = (Byte)(e >> 8); }
495 
496 
FseDecodeExtra(CFseState * pstate,const CExtraEntry * table,CBitStream * s)497 static MY_FORCE_INLINE UInt32 FseDecodeExtra(CFseState *pstate,
498     const CExtraEntry *table,
499     CBitStream *s)
500 {
501   const CExtraEntry *e = &table[*pstate];
502   UInt32 v = BitStream_Pull(s, e->totalBits);
503   unsigned extraBits = e->extraBits;
504   *pstate = (CFseState)(e->delta + (v >> extraBits));
505   return e->vbase + mask31(v, extraBits);
506 }
507 
508 
509 #define freqs_L (freqs)
510 #define freqs_M (freqs_L + NUM_L_SYMBOLS)
511 #define freqs_D (freqs_M + NUM_M_SYMBOLS)
512 #define freqs_LIT (freqs_D + NUM_D_SYMBOLS)
513 
514 #define GET_BITS_64(v, offset, num, dest) dest = (UInt32)   ((v >> (offset)) & ((1 << (num)) - 1));
515 #define GET_BITS_32(v, offset, num, dest) dest = (CFseState)((v >> (offset)) & ((1 << (num)) - 1));
516 
517 
DecodeLzfse(UInt32 unpackSize,Byte version)518 HRESULT CDecoder::DecodeLzfse(UInt32 unpackSize, Byte version)
519 {
520   PRF(printf("\nLZFSE-%d %7u", version - '0', unpackSize));
521 
522   UInt32 numLiterals;
523   UInt32 litPayloadSize;
524   Int32 literal_bits;
525 
526   UInt32 lit_state_0;
527   UInt32 lit_state_1;
528   UInt32 lit_state_2;
529   UInt32 lit_state_3;
530 
531   UInt32 numMatches;
532   UInt32 lmdPayloadSize;
533   Int32 lmd_bits;
534 
535   CFseState l_state;
536   CFseState m_state;
537   CFseState d_state;
538 
539   UInt16 freqs[NUM_SYMBOLS];
540 
541   if (version == kSignature_LZFSE_V1)
542   {
543     return E_NOTIMPL;
544     // we need examples to test LZFSE-V1 code
545     /*
546     const unsigned k_v1_SubHeaderSize = 7 * 4 + 7 * 2;
547     const unsigned k_v1_HeaderSize = k_v1_SubHeaderSize + NUM_SYMBOLS * 2;
548     _buffer.AllocAtLeast(k_v1_HeaderSize);
549     if (m_InStream.ReadBytes(_buffer, k_v1_HeaderSize) != k_v1_HeaderSize)
550       return S_FALSE;
551 
552     const Byte *buf = _buffer;
553     #define GET_32(offs, dest) dest = GetUi32(buf + offs)
554     #define GET_16(offs, dest) dest = GetUi16(buf + offs)
555 
556     UInt32 payload_bytes;
557     GET_32(0, payload_bytes);
558     GET_32(4, numLiterals);
559     GET_32(8, numMatches);
560     GET_32(12, litPayloadSize);
561     GET_32(16, lmdPayloadSize);
562     if (litPayloadSize > (1 << 20) || lmdPayloadSize > (1 << 20))
563       return S_FALSE;
564     GET_32(20, literal_bits);
565     if (literal_bits < -7 || literal_bits > 0)
566       return S_FALSE;
567 
568     GET_16(24, lit_state_0);
569     GET_16(26, lit_state_1);
570     GET_16(28, lit_state_2);
571     GET_16(30, lit_state_3);
572 
573     GET_32(32, lmd_bits);
574     if (lmd_bits < -7 || lmd_bits > 0)
575       return S_FALSE;
576 
577     GET_16(36, l_state);
578     GET_16(38, m_state);
579     GET_16(40, d_state);
580 
581     for (unsigned i = 0; i < NUM_SYMBOLS; i++)
582       freqs[i] = GetUi16(buf + k_v1_SubHeaderSize + i * 2);
583     */
584   }
585   else
586   {
587     UInt32 headerSize;
588     {
589       const unsigned kPreHeaderSize = 4 * 2; // signature and upackSize
590       const unsigned kHeaderSize = 8 * 3;
591       Byte temp[kHeaderSize];
592       if (m_InStream.ReadBytes(temp, kHeaderSize) != kHeaderSize)
593         return S_FALSE;
594 
595       UInt64 v;
596 
597       v = GetUi64(temp);
598       GET_BITS_64(v,  0, 20, numLiterals);
599       GET_BITS_64(v, 20, 20, litPayloadSize);
600       GET_BITS_64(v, 40, 20, numMatches);
601       GET_BITS_64(v, 60, 3 + 1, literal_bits); // (NumberOfUsedBits - 1)
602       literal_bits -= 7; // (-NumberOfUnusedBits)
603       if (literal_bits > 0)
604         return S_FALSE;
605       // GET_BITS_64(v, 63, 1, unused);
606 
607       v = GetUi64(temp + 8);
608       GET_BITS_64(v,  0, 10, lit_state_0);
609       GET_BITS_64(v, 10, 10, lit_state_1);
610       GET_BITS_64(v, 20, 10, lit_state_2);
611       GET_BITS_64(v, 30, 10, lit_state_3);
612       GET_BITS_64(v, 40, 20, lmdPayloadSize);
613       GET_BITS_64(v, 60, 3 + 1, lmd_bits);
614       lmd_bits -= 7;
615       if (lmd_bits > 0)
616         return S_FALSE;
617       // GET_BITS_64(v, 63, 1, unused)
618 
619       UInt32 v32 = GetUi32(temp + 20);
620       // (total header size in bytes; this does not
621       // correspond to a field in the uncompressed header version,
622       // but is required; we wouldn't know the size of the
623       // compresssed header otherwise.
624       GET_BITS_32(v32, 0, 10, l_state);
625       GET_BITS_32(v32, 10, 10, m_state);
626       GET_BITS_32(v32, 20, 10 + 2, d_state);
627       // GET_BITS_64(v, 62, 2, unused);
628 
629       headerSize = GetUi32(temp + 16);
630       if (headerSize <= kPreHeaderSize + kHeaderSize)
631         return S_FALSE;
632       headerSize -= kPreHeaderSize + kHeaderSize;
633     }
634 
635     // no freqs case is not allowed ?
636     // memset(freqs, 0, sizeof(freqs));
637     // if (headerSize != 0)
638     {
639       static const Byte numBitsTable[32] =
640       {
641         2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14,
642         2, 3, 2, 5, 2, 3, 2, 8, 2, 3, 2, 5, 2, 3, 2, 14
643       };
644 
645       static const Byte valueTable[32] =
646       {
647         0, 2, 1, 4, 0, 3, 1, 8, 0, 2, 1, 5, 0, 3, 1, 24,
648         0, 2, 1, 6, 0, 3, 1, 8, 0, 2, 1, 7, 0, 3, 1, 24
649       };
650 
651       UInt32 accum = 0;
652       unsigned numBits = 0;
653 
654       for (unsigned i = 0; i < NUM_SYMBOLS; i++)
655       {
656         while (numBits <= 14 && headerSize != 0)
657         {
658           Byte b;
659           if (!m_InStream.ReadByte(b))
660             return S_FALSE;
661           accum |= (UInt32)b << numBits;
662           numBits += 8;
663           headerSize--;
664         }
665 
666         unsigned b = (unsigned)accum & 31;
667         unsigned n = numBitsTable[b];
668         if (numBits < n)
669           return S_FALSE;
670         numBits -= n;
671         UInt32 f = valueTable[b];
672         if (n >= 8)
673           f += ((accum >> 4) & (0x3ff >> (14 - n)));
674         accum >>= n;
675         freqs[i] = (UInt16)f;
676       }
677 
678       if (numBits >= 8 || headerSize != 0)
679         return S_FALSE;
680     }
681   }
682 
683   PRF(printf(" Literals=%6u Matches=%6u", numLiterals, numMatches));
684 
685   if (numLiterals > LITERALS_PER_BLOCK
686       || (numLiterals & 3) != 0
687       || numMatches > MATCHES_PER_BLOCK
688       || lit_state_0 >= NUM_LIT_STATES
689       || lit_state_1 >= NUM_LIT_STATES
690       || lit_state_2 >= NUM_LIT_STATES
691       || lit_state_3 >= NUM_LIT_STATES
692       || l_state >= NUM_L_STATES
693       || m_state >= NUM_M_STATES
694       || d_state >= NUM_D_STATES)
695     return S_FALSE;
696 
697   // only full table is allowed ?
698   if (   SumFreqs(freqs_L, NUM_L_SYMBOLS) != NUM_L_STATES
699       || SumFreqs(freqs_M, NUM_M_SYMBOLS) != NUM_M_STATES
700       || SumFreqs(freqs_D, NUM_D_SYMBOLS) != NUM_D_STATES
701       || SumFreqs(freqs_LIT, NUM_LIT_SYMBOLS) != NUM_LIT_STATES)
702     return S_FALSE;
703 
704 
705   const unsigned kPad = 16;
706 
707   // ---------- Decode literals ----------
708 
709   {
710     _literals.AllocAtLeast(LITERALS_PER_BLOCK + 16);
711     _buffer.AllocAtLeast(kPad + litPayloadSize);
712     memset(_buffer, 0, kPad);
713 
714     if (m_InStream.ReadBytes(_buffer + kPad, litPayloadSize) != litPayloadSize)
715       return S_FALSE;
716 
717     UInt32 lit_decoder[NUM_LIT_STATES];
718     InitLitTable(freqs_LIT, lit_decoder);
719 
720     const Byte *buf_start = _buffer + kPad;
721     const Byte *buf_check = buf_start - 4;
722     const Byte *buf = buf_start + litPayloadSize;
723     CBitStream in;
724     if (FseInStream_Init(&in, literal_bits, &buf) != 0)
725       return S_FALSE;
726 
727     Byte *lit = _literals;
728     const Byte *lit_limit = lit + numLiterals;
729     for (; lit < lit_limit; lit += 4)
730     {
731       FseInStream_FLUSH
732       DECODE_LIT (lit[0], lit_state_0);
733       DECODE_LIT (lit[1], lit_state_1);
734       FseInStream_FLUSH
735       DECODE_LIT (lit[2], lit_state_2);
736       DECODE_LIT (lit[3], lit_state_3);
737     }
738 
739     if ((buf_start - buf) * 8 != (int)in.numBits)
740       return S_FALSE;
741   }
742 
743 
744   // ---------- Decode LMD ----------
745 
746   _buffer.AllocAtLeast(kPad + lmdPayloadSize);
747   memset(_buffer, 0, kPad);
748   if (m_InStream.ReadBytes(_buffer + kPad, lmdPayloadSize) != lmdPayloadSize)
749     return S_FALSE;
750 
751   CExtraEntry l_decoder[NUM_L_STATES];
752   CExtraEntry m_decoder[NUM_M_STATES];
753   CExtraEntry d_decoder[NUM_D_STATES];
754 
755   InitExtraDecoderTable(NUM_L_STATES, NUM_L_SYMBOLS, freqs_L, k_L_extra, l_decoder);
756   InitExtraDecoderTable(NUM_M_STATES, NUM_M_SYMBOLS, freqs_M, k_M_extra, m_decoder);
757   InitExtraDecoderTable(NUM_D_STATES, NUM_D_SYMBOLS, freqs_D, k_D_extra, d_decoder);
758 
759   const Byte *buf_start = _buffer + kPad;
760   const Byte *buf_check = buf_start - 4;
761   const Byte *buf = buf_start + lmdPayloadSize;
762   CBitStream in;
763   if (FseInStream_Init(&in, lmd_bits, &buf))
764     return S_FALSE;
765 
766   const Byte *lit = _literals;
767   const Byte *lit_limit = lit + numLiterals;
768 
769   UInt32 D = 0;
770 
771   for (;;)
772   {
773     if (numMatches == 0)
774       break;
775     numMatches--;
776 
777     FseInStream_FLUSH
778 
779     unsigned L = (unsigned)FseDecodeExtra(&l_state, l_decoder, &in);
780 
781     FseInStream_FLUSH
782 
783     unsigned M = (unsigned)FseDecodeExtra(&m_state, m_decoder, &in);
784 
785     FseInStream_FLUSH
786 
787     {
788       UInt32 new_D = FseDecodeExtra(&d_state, d_decoder, &in);
789       if (new_D)
790         D = new_D;
791     }
792 
793     if (L != 0)
794     {
795       if (L > (size_t)(lit_limit - lit))
796         return S_FALSE;
797       unsigned cur = L;
798       if (cur > unpackSize)
799         cur = (unsigned)unpackSize;
800       m_OutWindowStream.PutBytes(lit, cur);
801       unpackSize -= cur;
802       lit += cur;
803       if (cur != L)
804         return S_FALSE;
805     }
806 
807     if (M != 0)
808     {
809       if (unpackSize == 0 || D == 0)
810         return S_FALSE;
811       unsigned cur = M;
812       if (cur > unpackSize)
813         cur = (unsigned)unpackSize;
814       if (!m_OutWindowStream.CopyBlock(D - 1, cur))
815         return S_FALSE;
816       unpackSize -= cur;
817       if (cur != M)
818         return S_FALSE;
819     }
820   }
821 
822   if (unpackSize != 0)
823     return S_FALSE;
824 
825   // LZFSE encoder writes 8 additional zero bytes before LMD payload
826   // We test it:
827   if ((buf - buf_start) * 8 + in.numBits != 64)
828     return S_FALSE;
829   if (GetUi64(buf_start) != 0)
830     return S_FALSE;
831 
832   return S_OK;
833 }
834 
835 
CodeReal(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 * inSize,const UInt64 * outSize,ICompressProgressInfo * progress)836 STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
837     const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
838 {
839   PRF(printf("\n\nLzfseDecoder %7u %7u\n", (unsigned)*outSize, (unsigned)*inSize));
840 
841   const UInt32 kLzfseDictSize = 1 << 18;
842   if (!m_OutWindowStream.Create(kLzfseDictSize))
843     return E_OUTOFMEMORY;
844   if (!m_InStream.Create(1 << 18))
845     return E_OUTOFMEMORY;
846 
847   m_OutWindowStream.SetStream(outStream);
848   m_OutWindowStream.Init(false);
849   m_InStream.SetStream(inStream);
850   m_InStream.Init();
851 
852   CCoderReleaser coderReleaser(this);
853 
854   UInt64 prevOut = 0;
855   UInt64 prevIn = 0;
856 
857   for (;;)
858   {
859     const UInt64 pos = m_OutWindowStream.GetProcessedSize();
860     const UInt64 packPos = m_InStream.GetProcessedSize();
861 
862     if (progress && ((pos - prevOut) >= (1 << 22) || (packPos - prevIn) >= (1 << 22)))
863     {
864       RINOK(progress->SetRatioInfo(&packPos, &pos));
865       prevIn = packPos;
866       prevOut = pos;
867     }
868 
869     const UInt64 rem = *outSize - pos;
870     UInt32 v;
871     RINOK(GetUInt32(v))
872     if ((v & 0xFFFFFF) != 0x787662) // bvx
873       return S_FALSE;
874     v >>= 24;
875 
876     if (v == 0x24) // '$', end of stream
877       break;
878 
879     UInt32 unpackSize;
880     RINOK(GetUInt32(unpackSize));
881 
882     UInt32 cur = unpackSize;
883     if (cur > rem)
884       cur = (UInt32)rem;
885 
886     unpackSize -= cur;
887 
888     HRESULT res;
889     if (v == kSignature_LZFSE_V1 || v == kSignature_LZFSE_V2)
890       res = DecodeLzfse(cur, (Byte)v);
891     else if (v == 0x6E) // 'n'
892       res = DecodeLzvn(cur);
893     else if (v == 0x2D) // '-'
894       res = DecodeUncompressed(cur);
895     else
896       return E_NOTIMPL;
897 
898     if (res != S_OK)
899       return res;
900 
901     if (unpackSize != 0)
902       return S_FALSE;
903   }
904 
905   coderReleaser.NeedFlush = false;
906   HRESULT res = m_OutWindowStream.Flush();
907   if (res == S_OK)
908     if (*inSize != m_InStream.GetProcessedSize()
909         || *outSize != m_OutWindowStream.GetProcessedSize())
910       res = S_FALSE;
911   return res;
912 }
913 
914 
Code(ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 * inSize,const UInt64 * outSize,ICompressProgressInfo * progress)915 STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
916     const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
917 {
918   try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
919   catch(const CInBufferException &e) { return e.ErrorCode; }
920   catch(const CLzOutWindowException &e) { return e.ErrorCode; }
921   catch(...) { return E_OUTOFMEMORY; }
922   // catch(...) { return S_FALSE; }
923 }
924 
925 }}
926