source: thirdparty/blosc/internal-complibs/zstd-0.7.4/common/fse_decompress.c @ 8ebc79b

Revision 8ebc79b, 11.5 KB checked in by Hal Finkel <hfinkel@…>, 8 years ago (diff)

Add the other internal compression libraries from blocs

  • Property mode set to 100644
Line 
1/* ******************************************************************
2   FSE : Finite State Entropy decoder
3   Copyright (C) 2013-2015, Yann Collet.
4
5   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions are
9   met:
10
11       * Redistributions of source code must retain the above copyright
12   notice, this list of conditions and the following disclaimer.
13       * Redistributions in binary form must reproduce the above
14   copyright notice, this list of conditions and the following disclaimer
15   in the documentation and/or other materials provided with the
16   distribution.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30    You can contact the author at :
31    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
32    - Public forum : https://groups.google.com/forum/#!forum/lz4c
33****************************************************************** */
34
35
36/* **************************************************************
37*  Compiler specifics
38****************************************************************/
39#ifdef _MSC_VER    /* Visual Studio */
40#  define FORCE_INLINE static __forceinline
41#  include <intrin.h>                    /* For Visual 2005 */
42#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
43#  pragma warning(disable : 4214)        /* disable: C4214: non-int bitfields */
44#else
45#  ifdef __GNUC__
46#    define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
47#    define FORCE_INLINE static inline __attribute__((always_inline))
48#  else
49#    define FORCE_INLINE static inline
50#  endif
51#endif
52
53
54/* **************************************************************
55*  Includes
56****************************************************************/
57#include <stdlib.h>     /* malloc, free, qsort */
58#include <string.h>     /* memcpy, memset */
59#include <stdio.h>      /* printf (debug) */
60#include "bitstream.h"
61#define FSE_STATIC_LINKING_ONLY
62#include "fse.h"
63
64
65/* **************************************************************
66*  Error Management
67****************************************************************/
68#define FSE_isError ERR_isError
69#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
70
71
72/* **************************************************************
73*  Complex types
74****************************************************************/
75typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
76
77
78/* **************************************************************
79*  Templates
80****************************************************************/
81/*
82  designed to be included
83  for type-specific functions (template emulation in C)
84  Objective is to write these functions only once, for improved maintenance
85*/
86
87/* safety checks */
88#ifndef FSE_FUNCTION_EXTENSION
89#  error "FSE_FUNCTION_EXTENSION must be defined"
90#endif
91#ifndef FSE_FUNCTION_TYPE
92#  error "FSE_FUNCTION_TYPE must be defined"
93#endif
94
95/* Function names */
96#define FSE_CAT(X,Y) X##Y
97#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
98#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
99
100
101/* Function templates */
102FSE_DTable* FSE_createDTable (unsigned tableLog)
103{
104    if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
105    return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
106}
107
108void FSE_freeDTable (FSE_DTable* dt)
109{
110    free(dt);
111}
112
113size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
114{
115    void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */
116    FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
117    U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
118
119    U32 const maxSV1 = maxSymbolValue + 1;
120    U32 const tableSize = 1 << tableLog;
121    U32 highThreshold = tableSize-1;
122
123    /* Sanity Checks */
124    if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
125    if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
126
127    /* Init, lay down lowprob symbols */
128    {   FSE_DTableHeader DTableH;
129        DTableH.tableLog = (U16)tableLog;
130        DTableH.fastMode = 1;
131        {   S16 const largeLimit= (S16)(1 << (tableLog-1));
132            U32 s;
133            for (s=0; s<maxSV1; s++) {
134                if (normalizedCounter[s]==-1) {
135                    tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
136                    symbolNext[s] = 1;
137                } else {
138                    if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
139                    symbolNext[s] = normalizedCounter[s];
140        }   }   }
141        memcpy(dt, &DTableH, sizeof(DTableH));
142    }
143
144    /* Spread symbols */
145    {   U32 const tableMask = tableSize-1;
146        U32 const step = FSE_TABLESTEP(tableSize);
147        U32 s, position = 0;
148        for (s=0; s<maxSV1; s++) {
149            int i;
150            for (i=0; i<normalizedCounter[s]; i++) {
151                tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
152                position = (position + step) & tableMask;
153                while (position > highThreshold) position = (position + step) & tableMask;   /* lowprob area */
154        }   }
155
156        if (position!=0) return ERROR(GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */
157    }
158
159    /* Build Decoding table */
160    {   U32 u;
161        for (u=0; u<tableSize; u++) {
162            FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
163            U16 nextState = symbolNext[symbol]++;
164            tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );
165            tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
166    }   }
167
168    return 0;
169}
170
171
172
173#ifndef FSE_COMMONDEFS_ONLY
174
175/*-*******************************************************
176*  Decompression (Byte symbols)
177*********************************************************/
178size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
179{
180    void* ptr = dt;
181    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
182    void* dPtr = dt + 1;
183    FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
184
185    DTableH->tableLog = 0;
186    DTableH->fastMode = 0;
187
188    cell->newState = 0;
189    cell->symbol = symbolValue;
190    cell->nbBits = 0;
191
192    return 0;
193}
194
195
196size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
197{
198    void* ptr = dt;
199    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
200    void* dPtr = dt + 1;
201    FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
202    const unsigned tableSize = 1 << nbBits;
203    const unsigned tableMask = tableSize - 1;
204    const unsigned maxSV1 = tableMask+1;
205    unsigned s;
206
207    /* Sanity checks */
208    if (nbBits < 1) return ERROR(GENERIC);         /* min size */
209
210    /* Build Decoding Table */
211    DTableH->tableLog = (U16)nbBits;
212    DTableH->fastMode = 1;
213    for (s=0; s<maxSV1; s++) {
214        dinfo[s].newState = 0;
215        dinfo[s].symbol = (BYTE)s;
216        dinfo[s].nbBits = (BYTE)nbBits;
217    }
218
219    return 0;
220}
221
222FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
223          void* dst, size_t maxDstSize,
224    const void* cSrc, size_t cSrcSize,
225    const FSE_DTable* dt, const unsigned fast)
226{
227    BYTE* const ostart = (BYTE*) dst;
228    BYTE* op = ostart;
229    BYTE* const omax = op + maxDstSize;
230    BYTE* const olimit = omax-3;
231
232    BIT_DStream_t bitD;
233    FSE_DState_t state1;
234    FSE_DState_t state2;
235
236    /* Init */
237    { size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);   /* replaced last arg by maxCompressed Size */
238      if (FSE_isError(errorCode)) return errorCode; }
239
240    FSE_initDState(&state1, &bitD, dt);
241    FSE_initDState(&state2, &bitD, dt);
242
243#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
244
245    /* 4 symbols per loop */
246    for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op<olimit) ; op+=4) {
247        op[0] = FSE_GETSYMBOL(&state1);
248
249        if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
250            BIT_reloadDStream(&bitD);
251
252        op[1] = FSE_GETSYMBOL(&state2);
253
254        if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
255            { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
256
257        op[2] = FSE_GETSYMBOL(&state1);
258
259        if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
260            BIT_reloadDStream(&bitD);
261
262        op[3] = FSE_GETSYMBOL(&state2);
263    }
264
265    /* tail */
266    /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
267    while (1) {
268        if (op>(omax-2)) return ERROR(dstSize_tooSmall);
269
270        *op++ = FSE_GETSYMBOL(&state1);
271
272        if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
273            *op++ = FSE_GETSYMBOL(&state2);
274            break;
275        }
276
277        if (op>(omax-2)) return ERROR(dstSize_tooSmall);
278
279        *op++ = FSE_GETSYMBOL(&state2);
280
281        if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
282            *op++ = FSE_GETSYMBOL(&state1);
283            break;
284    }   }
285
286    return op-ostart;
287}
288
289
290size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
291                            const void* cSrc, size_t cSrcSize,
292                            const FSE_DTable* dt)
293{
294    const void* ptr = dt;
295    const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
296    const U32 fastMode = DTableH->fastMode;
297
298    /* select fast mode (static) */
299    if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
300    return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
301}
302
303
304size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
305{
306    const BYTE* const istart = (const BYTE*)cSrc;
307    const BYTE* ip = istart;
308    short counting[FSE_MAX_SYMBOL_VALUE+1];
309    DTable_max_t dt;   /* Static analyzer seems unable to understand this table will be properly initialized later */
310    unsigned tableLog;
311    unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
312
313    if (cSrcSize<2) return ERROR(srcSize_wrong);   /* too small input size */
314
315    /* normal FSE decoding mode */
316    {   size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
317        if (FSE_isError(NCountLength)) return NCountLength;
318        if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size */
319        ip += NCountLength;
320        cSrcSize -= NCountLength;
321    }
322
323    { size_t const errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);
324      if (FSE_isError(errorCode)) return errorCode; }
325
326    return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);   /* always return, even if it is an error code */
327}
328
329
330
331#endif   /* FSE_COMMONDEFS_ONLY */
Note: See TracBrowser for help on using the repository browser.