blob: e74c1e833d404f50ced5344100775a276fe50689 [file] [log] [blame]
Yann Collet4856a002015-01-24 01:58:16 +01001/* ******************************************************************
2 FSE : Finite State Entropy coder
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#ifndef FSE_COMMONDEFS_ONLY
36
Yann Collet3b994cb2016-01-06 01:58:37 +010037/* **************************************************************
Yann Collet4856a002015-01-24 01:58:16 +010038* Tuning parameters
39****************************************************************/
Yann Collet3b994cb2016-01-06 01:58:37 +010040/*!MEMORY_USAGE :
Yann Collet4856a002015-01-24 01:58:16 +010041* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
42* Increasing memory usage improves compression ratio
43* Reduced memory usage can improve speed, due to cache effect
44* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
45#define FSE_MAX_MEMORY_USAGE 14
46#define FSE_DEFAULT_MEMORY_USAGE 13
47
Yann Collet3b994cb2016-01-06 01:58:37 +010048/*!FSE_MAX_SYMBOL_VALUE :
Yann Collet4856a002015-01-24 01:58:16 +010049* Maximum symbol value authorized.
50* Required for proper stack allocation */
51#define FSE_MAX_SYMBOL_VALUE 255
52
53
Yann Collet3b994cb2016-01-06 01:58:37 +010054/* **************************************************************
Yann Collete8c6bb12015-07-26 00:23:57 +010055* template functions type & suffix
Yann Collet4856a002015-01-24 01:58:16 +010056****************************************************************/
57#define FSE_FUNCTION_TYPE BYTE
58#define FSE_FUNCTION_EXTENSION
Yann Collet3b994cb2016-01-06 01:58:37 +010059#define FSE_DECODE_TYPE FSE_decode_t
Yann Collet4856a002015-01-24 01:58:16 +010060
Yann Collete8c6bb12015-07-26 00:23:57 +010061
Yann Collet4856a002015-01-24 01:58:16 +010062#endif /* !FSE_COMMONDEFS_ONLY */
63
Yann Collet3b994cb2016-01-06 01:58:37 +010064/* **************************************************************
Yann Collet4856a002015-01-24 01:58:16 +010065* Compiler specifics
66****************************************************************/
67#ifdef _MSC_VER /* Visual Studio */
68# define FORCE_INLINE static __forceinline
69# include <intrin.h> /* For Visual 2005 */
70# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
71# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
72#else
Yann Collet4856a002015-01-24 01:58:16 +010073# ifdef __GNUC__
Yann Colletb1f3f4b2015-10-18 22:18:32 +010074# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
Yann Collet4856a002015-01-24 01:58:16 +010075# define FORCE_INLINE static inline __attribute__((always_inline))
76# else
77# define FORCE_INLINE static inline
78# endif
79#endif
80
81
Yann Collet3b994cb2016-01-06 01:58:37 +010082/* **************************************************************
Yann Collet4856a002015-01-24 01:58:16 +010083* Includes
84****************************************************************/
85#include <stdlib.h> /* malloc, free, qsort */
86#include <string.h> /* memcpy, memset */
87#include <stdio.h> /* printf (debug) */
Yann Colletb1f3f4b2015-10-18 22:18:32 +010088#include "bitstream.h"
Yann Collet4856a002015-01-24 01:58:16 +010089#include "fse_static.h"
90
91
Yann Collet3b994cb2016-01-06 01:58:37 +010092/* ***************************************************************
Yann Collet4856a002015-01-24 01:58:16 +010093* Constants
94*****************************************************************/
95#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
96#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
97#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
98#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
99#define FSE_MIN_TABLELOG 5
100
101#define FSE_TABLELOG_ABSOLUTE_MAX 15
102#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
103#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
104#endif
105
106
Yann Collet3b994cb2016-01-06 01:58:37 +0100107/* **************************************************************
Yann Collet4856a002015-01-24 01:58:16 +0100108* Error Management
109****************************************************************/
110#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
111
112
Yann Collet3b994cb2016-01-06 01:58:37 +0100113/* **************************************************************
Yann Collet4856a002015-01-24 01:58:16 +0100114* Complex types
115****************************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -0800116typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
117typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
Yann Collet4856a002015-01-24 01:58:16 +0100118
Yann Collet4856a002015-01-24 01:58:16 +0100119
Yann Collet3b994cb2016-01-06 01:58:37 +0100120/* **************************************************************
Yann Collete8c6bb12015-07-26 00:23:57 +0100121* Templates
122****************************************************************/
123/*
124 designed to be included
125 for type-specific functions (template emulation in C)
126 Objective is to write these functions only once, for improved maintenance
127*/
128
129/* safety checks */
130#ifndef FSE_FUNCTION_EXTENSION
131# error "FSE_FUNCTION_EXTENSION must be defined"
132#endif
133#ifndef FSE_FUNCTION_TYPE
134# error "FSE_FUNCTION_TYPE must be defined"
135#endif
136
137/* Function names */
138#define FSE_CAT(X,Y) X##Y
139#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
140#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
141
142
143/* Function templates */
Yann Collet3b994cb2016-01-06 01:58:37 +0100144size_t FSE_count_generic(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize, unsigned safe)
Yann Collete8c6bb12015-07-26 00:23:57 +0100145{
146 const FSE_FUNCTION_TYPE* ip = source;
147 const FSE_FUNCTION_TYPE* const iend = ip+sourceSize;
148 unsigned maxSymbolValue = *maxSymbolValuePtr;
149 unsigned max=0;
150 int s;
151
152 U32 Counting1[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
153 U32 Counting2[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
154 U32 Counting3[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
155 U32 Counting4[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
156
157 /* safety checks */
158 if (!sourceSize)
159 {
160 memset(count, 0, (maxSymbolValue + 1) * sizeof(FSE_FUNCTION_TYPE));
161 *maxSymbolValuePtr = 0;
162 return 0;
163 }
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100164 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(GENERIC); /* maxSymbolValue too large : unsupported */
Yann Collete8c6bb12015-07-26 00:23:57 +0100165 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE; /* 0 == default */
166
167 if ((safe) || (sizeof(FSE_FUNCTION_TYPE)>1))
168 {
169 /* check input values, to avoid count table overflow */
170 while (ip < iend-3)
171 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100172 if (*ip>maxSymbolValue) return ERROR(GENERIC); Counting1[*ip++]++;
173 if (*ip>maxSymbolValue) return ERROR(GENERIC); Counting2[*ip++]++;
174 if (*ip>maxSymbolValue) return ERROR(GENERIC); Counting3[*ip++]++;
175 if (*ip>maxSymbolValue) return ERROR(GENERIC); Counting4[*ip++]++;
Yann Collete8c6bb12015-07-26 00:23:57 +0100176 }
177 }
178 else
179 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100180 U32 cached = MEM_read32(ip); ip += 4;
Yann Collete8c6bb12015-07-26 00:23:57 +0100181 while (ip < iend-15)
182 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100183 U32 c = cached; cached = MEM_read32(ip); ip += 4;
Yann Collete8c6bb12015-07-26 00:23:57 +0100184 Counting1[(BYTE) c ]++;
185 Counting2[(BYTE)(c>>8) ]++;
186 Counting3[(BYTE)(c>>16)]++;
187 Counting4[ c>>24 ]++;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100188 c = cached; cached = MEM_read32(ip); ip += 4;
Yann Collete8c6bb12015-07-26 00:23:57 +0100189 Counting1[(BYTE) c ]++;
190 Counting2[(BYTE)(c>>8) ]++;
191 Counting3[(BYTE)(c>>16)]++;
192 Counting4[ c>>24 ]++;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100193 c = cached; cached = MEM_read32(ip); ip += 4;
Yann Collete8c6bb12015-07-26 00:23:57 +0100194 Counting1[(BYTE) c ]++;
195 Counting2[(BYTE)(c>>8) ]++;
196 Counting3[(BYTE)(c>>16)]++;
197 Counting4[ c>>24 ]++;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100198 c = cached; cached = MEM_read32(ip); ip += 4;
Yann Collete8c6bb12015-07-26 00:23:57 +0100199 Counting1[(BYTE) c ]++;
200 Counting2[(BYTE)(c>>8) ]++;
201 Counting3[(BYTE)(c>>16)]++;
202 Counting4[ c>>24 ]++;
203 }
204 ip-=4;
205 }
206
207 /* finish last symbols */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100208 while (ip<iend) { if ((safe) && (*ip>maxSymbolValue)) return ERROR(GENERIC); Counting1[*ip++]++; }
Yann Collete8c6bb12015-07-26 00:23:57 +0100209
210 for (s=0; s<=(int)maxSymbolValue; s++)
211 {
212 count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
213 if (count[s] > max) max = count[s];
214 }
215
216 while (!count[maxSymbolValue]) maxSymbolValue--;
217 *maxSymbolValuePtr = maxSymbolValue;
218 return (size_t)max;
219}
220
221/* hidden fast variant (unsafe) */
222size_t FSE_FUNCTION_NAME(FSE_countFast, FSE_FUNCTION_EXTENSION)
223(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
224{
Yann Collet3b994cb2016-01-06 01:58:37 +0100225 return FSE_count_generic(count, maxSymbolValuePtr, source, sourceSize, 0);
Yann Collete8c6bb12015-07-26 00:23:57 +0100226}
227
228size_t FSE_FUNCTION_NAME(FSE_count, FSE_FUNCTION_EXTENSION)
229(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
230{
231 if ((sizeof(FSE_FUNCTION_TYPE)==1) && (*maxSymbolValuePtr >= 255))
232 {
233 *maxSymbolValuePtr = 255;
Yann Collet3b994cb2016-01-06 01:58:37 +0100234 return FSE_count_generic(count, maxSymbolValuePtr, source, sourceSize, 0);
Yann Collete8c6bb12015-07-26 00:23:57 +0100235 }
Yann Collet3b994cb2016-01-06 01:58:37 +0100236 return FSE_count_generic(count, maxSymbolValuePtr, source, sourceSize, 1);
Yann Collete8c6bb12015-07-26 00:23:57 +0100237}
238
239
240static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; }
241
Yann Collet3b994cb2016-01-06 01:58:37 +0100242size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collete8c6bb12015-07-26 00:23:57 +0100243{
244 const unsigned tableSize = 1 << tableLog;
245 const unsigned tableMask = tableSize - 1;
Yann Collet3b994cb2016-01-06 01:58:37 +0100246 void* const ptr = ct;
247 U16* const tableU16 = ( (U16*) ptr) + 2;
248 void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
249 FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
Yann Collete8c6bb12015-07-26 00:23:57 +0100250 const unsigned step = FSE_tableStep(tableSize);
251 unsigned cumul[FSE_MAX_SYMBOL_VALUE+2];
252 U32 position = 0;
Yann Collet3b994cb2016-01-06 01:58:37 +0100253 FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
Yann Collete8c6bb12015-07-26 00:23:57 +0100254 U32 highThreshold = tableSize-1;
255 unsigned symbol;
256 unsigned i;
257
258 /* header */
259 tableU16[-2] = (U16) tableLog;
260 tableU16[-1] = (U16) maxSymbolValue;
261
262 /* For explanations on how to distribute symbol values over the table :
263 * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
264
265 /* symbol start positions */
266 cumul[0] = 0;
267 for (i=1; i<=maxSymbolValue+1; i++)
268 {
Yann Collet3b994cb2016-01-06 01:58:37 +0100269 if (normalizedCounter[i-1]==-1) /* Low proba symbol */
Yann Collete8c6bb12015-07-26 00:23:57 +0100270 {
271 cumul[i] = cumul[i-1] + 1;
272 tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(i-1);
273 }
274 else
275 cumul[i] = cumul[i-1] + normalizedCounter[i-1];
276 }
277 cumul[maxSymbolValue+1] = tableSize+1;
278
279 /* Spread symbols */
280 for (symbol=0; symbol<=maxSymbolValue; symbol++)
281 {
282 int nbOccurences;
283 for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++)
284 {
285 tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
286 position = (position + step) & tableMask;
Yann Collet3b994cb2016-01-06 01:58:37 +0100287 while (position > highThreshold) position = (position + step) & tableMask; /* Low proba area */
Yann Collete8c6bb12015-07-26 00:23:57 +0100288 }
289 }
290
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100291 if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */
Yann Collete8c6bb12015-07-26 00:23:57 +0100292
293 /* Build table */
294 for (i=0; i<tableSize; i++)
295 {
Yann Collet3b994cb2016-01-06 01:58:37 +0100296 FSE_FUNCTION_TYPE s = tableSymbol[i]; /* note : static analyzer may not understand tableSymbol is properly initialized */
Yann Colleta7875502015-08-07 15:21:00 +0100297 tableU16[cumul[s]++] = (U16) (tableSize+i); /* TableU16 : sorted by symbol order; gives next state value */
Yann Collete8c6bb12015-07-26 00:23:57 +0100298 }
299
300 /* Build Symbol Transformation Table */
301 {
302 unsigned s;
303 unsigned total = 0;
304 for (s=0; s<=maxSymbolValue; s++)
305 {
306 switch (normalizedCounter[s])
307 {
Yann Collet77c82b62015-08-02 01:19:09 +0100308 case 0:
Yann Collete8c6bb12015-07-26 00:23:57 +0100309 break;
310 case -1:
Yann Collet77c82b62015-08-02 01:19:09 +0100311 case 1:
Yann Colleta7875502015-08-07 15:21:00 +0100312 symbolTT[s].deltaNbBits = tableLog << 16;
Yann Collete8c6bb12015-07-26 00:23:57 +0100313 symbolTT[s].deltaFindState = total - 1;
314 total ++;
Yann Collete8c6bb12015-07-26 00:23:57 +0100315 break;
316 default :
Yann Collet77c82b62015-08-02 01:19:09 +0100317 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100318 U32 maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
Yann Collet77c82b62015-08-02 01:19:09 +0100319 U32 minStatePlus = normalizedCounter[s] << maxBitsOut;
320 symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
321 symbolTT[s].deltaFindState = total - normalizedCounter[s];
322 total += normalizedCounter[s];
323 }
Yann Collete8c6bb12015-07-26 00:23:57 +0100324 }
325 }
326 }
327
328 return 0;
329}
330
331
Yann Collet3b994cb2016-01-06 01:58:37 +0100332FSE_DTable* FSE_createDTable (unsigned tableLog)
Yann Collete8c6bb12015-07-26 00:23:57 +0100333{
334 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
335 return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
336}
337
Yann Collet3b994cb2016-01-06 01:58:37 +0100338void FSE_freeDTable (FSE_DTable* dt)
Yann Collete8c6bb12015-07-26 00:23:57 +0100339{
340 free(dt);
341}
342
Yann Collet3b994cb2016-01-06 01:58:37 +0100343size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collete8c6bb12015-07-26 00:23:57 +0100344{
Yann Collet3b994cb2016-01-06 01:58:37 +0100345 FSE_DTableHeader DTableH;
346 void* const tdPtr = dt+1; /* because dt is unsigned, 32-bits aligned on 32-bits */
347 FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
Yann Collete8c6bb12015-07-26 00:23:57 +0100348 const U32 tableSize = 1 << tableLog;
349 const U32 tableMask = tableSize-1;
350 const U32 step = FSE_tableStep(tableSize);
351 U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
352 U32 position = 0;
353 U32 highThreshold = tableSize-1;
354 const S16 largeLimit= (S16)(1 << (tableLog-1));
355 U32 noLarge = 1;
356 U32 s;
357
358 /* Sanity Checks */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100359 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
360 if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
Yann Collete8c6bb12015-07-26 00:23:57 +0100361
362 /* Init, lay down lowprob symbols */
Yann Collet3b994cb2016-01-06 01:58:37 +0100363 DTableH.tableLog = (U16)tableLog;
Yann Collete8c6bb12015-07-26 00:23:57 +0100364 for (s=0; s<=maxSymbolValue; s++)
365 {
366 if (normalizedCounter[s]==-1)
367 {
368 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
369 symbolNext[s] = 1;
370 }
371 else
372 {
373 if (normalizedCounter[s] >= largeLimit) noLarge=0;
374 symbolNext[s] = normalizedCounter[s];
375 }
376 }
377
378 /* Spread symbols */
379 for (s=0; s<=maxSymbolValue; s++)
380 {
381 int i;
382 for (i=0; i<normalizedCounter[s]; i++)
383 {
384 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
385 position = (position + step) & tableMask;
386 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
387 }
388 }
389
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100390 if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
Yann Collete8c6bb12015-07-26 00:23:57 +0100391
392 /* Build Decoding table */
393 {
394 U32 i;
395 for (i=0; i<tableSize; i++)
396 {
397 FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[i].symbol);
398 U16 nextState = symbolNext[symbol]++;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100399 tableDecode[i].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );
Yann Collete8c6bb12015-07-26 00:23:57 +0100400 tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize);
401 }
402 }
403
Yann Collet3b994cb2016-01-06 01:58:37 +0100404 DTableH.fastMode = (U16)noLarge;
405 memcpy(dt, &DTableH, sizeof(DTableH));
Yann Colleta7875502015-08-07 15:21:00 +0100406 return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +0100407}
408
409
Yann Collet4856a002015-01-24 01:58:16 +0100410#ifndef FSE_COMMONDEFS_ONLY
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100411/******************************************
412* FSE helper functions
413******************************************/
414unsigned FSE_isError(size_t code) { return ERR_isError(code); }
Yann Collet4856a002015-01-24 01:58:16 +0100415
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100416const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
Yann Collet4856a002015-01-24 01:58:16 +0100417
418
419/****************************************************************
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100420* FSE NCount encoding-decoding
Yann Collet4856a002015-01-24 01:58:16 +0100421****************************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -0800422size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100423{
Yann Colletd02114e2015-08-21 03:59:31 +0100424 size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
Yann Collet23743532015-08-19 23:53:56 +0100425 return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
Yann Collet4856a002015-01-24 01:58:16 +0100426}
427
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100428static short FSE_abs(short a)
429{
430 return a<0 ? -a : a;
431}
432
Yann Collet1efa31f2015-07-04 15:56:41 -0800433static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
Yann Collet4856a002015-01-24 01:58:16 +0100434 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
Yann Collet23743532015-08-19 23:53:56 +0100435 unsigned writeIsSafe)
Yann Collet4856a002015-01-24 01:58:16 +0100436{
437 BYTE* const ostart = (BYTE*) header;
438 BYTE* out = ostart;
439 BYTE* const oend = ostart + headerBufferSize;
440 int nbBits;
441 const int tableSize = 1 << tableLog;
442 int remaining;
443 int threshold;
444 U32 bitStream;
445 int bitCount;
446 unsigned charnum = 0;
447 int previous0 = 0;
448
449 bitStream = 0;
450 bitCount = 0;
451 /* Table Size */
452 bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
453 bitCount += 4;
454
455 /* Init */
456 remaining = tableSize+1; /* +1 for extra accuracy */
457 threshold = tableSize;
458 nbBits = tableLog+1;
459
460 while (remaining>1) /* stops at 1 */
461 {
462 if (previous0)
463 {
464 unsigned start = charnum;
465 while (!normalizedCounter[charnum]) charnum++;
466 while (charnum >= start+24)
467 {
468 start+=24;
Yann Collet213089c2015-06-18 07:43:16 -0800469 bitStream += 0xFFFFU << bitCount;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100470 if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
Yann Collet213089c2015-06-18 07:43:16 -0800471 out[0] = (BYTE) bitStream;
Yann Collet4856a002015-01-24 01:58:16 +0100472 out[1] = (BYTE)(bitStream>>8);
473 out+=2;
474 bitStream>>=16;
475 }
476 while (charnum >= start+3)
477 {
478 start+=3;
479 bitStream += 3 << bitCount;
480 bitCount += 2;
481 }
482 bitStream += (charnum-start) << bitCount;
483 bitCount += 2;
484 if (bitCount>16)
485 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100486 if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100487 out[0] = (BYTE)bitStream;
488 out[1] = (BYTE)(bitStream>>8);
489 out += 2;
490 bitStream >>= 16;
491 bitCount -= 16;
492 }
493 }
494 {
495 short count = normalizedCounter[charnum++];
496 const short max = (short)((2*threshold-1)-remaining);
497 remaining -= FSE_abs(count);
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100498 if (remaining<1) return ERROR(GENERIC);
Yann Collet4856a002015-01-24 01:58:16 +0100499 count++; /* +1 for extra accuracy */
500 if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
501 bitStream += count << bitCount;
502 bitCount += nbBits;
503 bitCount -= (count<max);
504 previous0 = (count==1);
505 while (remaining<threshold) nbBits--, threshold>>=1;
506 }
507 if (bitCount>16)
508 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100509 if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100510 out[0] = (BYTE)bitStream;
511 out[1] = (BYTE)(bitStream>>8);
512 out += 2;
513 bitStream >>= 16;
514 bitCount -= 16;
515 }
516 }
517
518 /* flush remaining bitStream */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100519 if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100520 out[0] = (BYTE)bitStream;
521 out[1] = (BYTE)(bitStream>>8);
522 out+= (bitCount+7) /8;
523
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100524 if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
Yann Collet4856a002015-01-24 01:58:16 +0100525
526 return (out-ostart);
527}
528
529
Yann Collet997f9ee2015-08-21 02:44:20 +0100530size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100531{
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100532 if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC); /* Unsupported */
533 if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
Yann Collet4856a002015-01-24 01:58:16 +0100534
Yann Collet997f9ee2015-08-21 02:44:20 +0100535 if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
536 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
Yann Collet4856a002015-01-24 01:58:16 +0100537
Yann Collet997f9ee2015-08-21 02:44:20 +0100538 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
Yann Collet4856a002015-01-24 01:58:16 +0100539}
540
541
Yann Collet1efa31f2015-07-04 15:56:41 -0800542size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
Yann Collet4856a002015-01-24 01:58:16 +0100543 const void* headerBuffer, size_t hbSize)
544{
545 const BYTE* const istart = (const BYTE*) headerBuffer;
Yann Collet1efa31f2015-07-04 15:56:41 -0800546 const BYTE* const iend = istart + hbSize;
Yann Collet4856a002015-01-24 01:58:16 +0100547 const BYTE* ip = istart;
548 int nbBits;
549 int remaining;
550 int threshold;
551 U32 bitStream;
552 int bitCount;
553 unsigned charnum = 0;
554 int previous0 = 0;
555
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100556 if (hbSize < 4) return ERROR(srcSize_wrong);
557 bitStream = MEM_readLE32(ip);
Yann Collet4856a002015-01-24 01:58:16 +0100558 nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100559 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
Yann Collet4856a002015-01-24 01:58:16 +0100560 bitStream >>= 4;
561 bitCount = 4;
562 *tableLogPtr = nbBits;
563 remaining = (1<<nbBits)+1;
564 threshold = 1<<nbBits;
565 nbBits++;
566
567 while ((remaining>1) && (charnum<=*maxSVPtr))
568 {
569 if (previous0)
570 {
571 unsigned n0 = charnum;
572 while ((bitStream & 0xFFFF) == 0xFFFF)
573 {
574 n0+=24;
Yann Collet23743532015-08-19 23:53:56 +0100575 if (ip < iend-5)
576 {
577 ip+=2;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100578 bitStream = MEM_readLE32(ip) >> bitCount;
Yann Collet23743532015-08-19 23:53:56 +0100579 }
580 else
581 {
582 bitStream >>= 16;
583 bitCount+=16;
584 }
Yann Collet4856a002015-01-24 01:58:16 +0100585 }
586 while ((bitStream & 3) == 3)
587 {
588 n0+=3;
589 bitStream>>=2;
590 bitCount+=2;
591 }
592 n0 += bitStream & 3;
593 bitCount += 2;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100594 if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
Yann Collet4856a002015-01-24 01:58:16 +0100595 while (charnum < n0) normalizedCounter[charnum++] = 0;
Yann Collet23743532015-08-19 23:53:56 +0100596 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
597 {
598 ip += bitCount>>3;
599 bitCount &= 7;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100600 bitStream = MEM_readLE32(ip) >> bitCount;
Yann Collet23743532015-08-19 23:53:56 +0100601 }
602 else
603 bitStream >>= 2;
Yann Collet4856a002015-01-24 01:58:16 +0100604 }
605 {
606 const short max = (short)((2*threshold-1)-remaining);
607 short count;
608
609 if ((bitStream & (threshold-1)) < (U32)max)
610 {
611 count = (short)(bitStream & (threshold-1));
612 bitCount += nbBits-1;
613 }
614 else
615 {
616 count = (short)(bitStream & (2*threshold-1));
617 if (count >= threshold) count -= max;
618 bitCount += nbBits;
619 }
620
621 count--; /* extra accuracy */
622 remaining -= FSE_abs(count);
623 normalizedCounter[charnum++] = count;
624 previous0 = !count;
625 while (remaining < threshold)
626 {
627 nbBits--;
628 threshold >>= 1;
629 }
630
Yann Collet1efa31f2015-07-04 15:56:41 -0800631 {
Yann Collet23743532015-08-19 23:53:56 +0100632 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
Yann Collet1efa31f2015-07-04 15:56:41 -0800633 {
Yann Collet23743532015-08-19 23:53:56 +0100634 ip += bitCount>>3;
635 bitCount &= 7;
Yann Collet1efa31f2015-07-04 15:56:41 -0800636 }
637 else
638 {
Yann Collet23743532015-08-19 23:53:56 +0100639 bitCount -= (int)(8 * (iend - 4 - ip));
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100640 ip = iend - 4;
641 }
642 bitStream = MEM_readLE32(ip) >> (bitCount & 31);
Yann Collet1efa31f2015-07-04 15:56:41 -0800643 }
Yann Collet4856a002015-01-24 01:58:16 +0100644 }
645 }
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100646 if (remaining != 1) return ERROR(GENERIC);
Yann Collet4856a002015-01-24 01:58:16 +0100647 *maxSVPtr = charnum-1;
648
Yann Collet1efa31f2015-07-04 15:56:41 -0800649 ip += (bitCount+7)>>3;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100650 if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong);
Yann Collet4856a002015-01-24 01:58:16 +0100651 return ip-istart;
652}
653
654
655/****************************************************************
656* FSE Compression Code
657****************************************************************/
658/*
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100659FSE_CTable is a variable size structure which contains :
Yann Collet4856a002015-01-24 01:58:16 +0100660 U16 tableLog;
661 U16 maxSymbolValue;
662 U16 nextStateNumber[1 << tableLog]; // This size is variable
663 FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1]; // This size is variable
664Allocation is manual, since C standard does not support variable-size structures.
665*/
666
667size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
668{
669 size_t size;
670 FSE_STATIC_ASSERT((size_t)FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)*4 >= sizeof(CTable_max_t)); /* A compilation error here means FSE_CTABLE_SIZE_U32 is not large enough */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100671 if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);
Yann Collet4856a002015-01-24 01:58:16 +0100672 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
673 return size;
674}
675
Yann Collet1efa31f2015-07-04 15:56:41 -0800676FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100677{
678 size_t size;
679 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
680 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
Yann Collet1efa31f2015-07-04 15:56:41 -0800681 return (FSE_CTable*)malloc(size);
Yann Collet4856a002015-01-24 01:58:16 +0100682}
683
Yann Collet1efa31f2015-07-04 15:56:41 -0800684void FSE_freeCTable (FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +0100685{
Yann Collet1efa31f2015-07-04 15:56:41 -0800686 free(ct);
Yann Collet4856a002015-01-24 01:58:16 +0100687}
688
Yann Collet4856a002015-01-24 01:58:16 +0100689
Yann Colletd02114e2015-08-21 03:59:31 +0100690/* provides the minimum logSize to safely represent a distribution */
691static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
Yann Collet4856a002015-01-24 01:58:16 +0100692{
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100693 U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
694 U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
695 U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
696 return minBits;
Yann Colletd02114e2015-08-21 03:59:31 +0100697}
698
699unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
700{
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100701 U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - 2;
Yann Colletd02114e2015-08-21 03:59:31 +0100702 U32 tableLog = maxTableLog;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100703 U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
Yann Collet4856a002015-01-24 01:58:16 +0100704 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100705 if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
706 if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
Yann Collet4856a002015-01-24 01:58:16 +0100707 if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
708 if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
709 return tableLog;
710}
711
712
Yann Collet26aa1ec2015-02-24 09:05:58 +0100713/* Secondary normalization method.
714 To be used when primary method fails. */
715
716static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
Yann Colleta3c75ba2015-02-21 03:31:59 +0100717{
718 U32 s;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100719 U32 distributed = 0;
720 U32 ToDistribute;
721
722 /* Init */
Yann Colleta3c75ba2015-02-21 03:31:59 +0100723 U32 lowThreshold = (U32)(total >> tableLog);
724 U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
725
726 for (s=0; s<=maxSymbolValue; s++)
727 {
728 if (count[s] == 0)
729 {
730 norm[s]=0;
731 continue;
732 }
733 if (count[s] <= lowThreshold)
734 {
735 norm[s] = -1;
736 distributed++;
737 total -= count[s];
738 continue;
739 }
740 if (count[s] <= lowOne)
741 {
742 norm[s] = 1;
743 distributed++;
744 total -= count[s];
745 continue;
746 }
747 norm[s]=-2;
748 }
749 ToDistribute = (1 << tableLog) - distributed;
750
751 if ((total / ToDistribute) > lowOne)
752 {
753 /* risk of rounding to zero */
754 lowOne = (U32)((total * 3) / (ToDistribute * 2));
755 for (s=0; s<=maxSymbolValue; s++)
756 {
757 if ((norm[s] == -2) && (count[s] <= lowOne))
758 {
759 norm[s] = 1;
760 distributed++;
761 total -= count[s];
762 continue;
763 }
764 }
765 ToDistribute = (1 << tableLog) - distributed;
766 }
767
768 if (distributed == maxSymbolValue+1)
769 {
Yann Collet26aa1ec2015-02-24 09:05:58 +0100770 /* all values are pretty poor;
771 probably incompressible data (should have already been detected);
772 find max, then give all remaining points to max */
Yann Colleta3c75ba2015-02-21 03:31:59 +0100773 U32 maxV = 0, maxC =0;
774 for (s=0; s<=maxSymbolValue; s++)
775 if (count[s] > maxC) maxV=s, maxC=count[s];
Yann Collet1efa31f2015-07-04 15:56:41 -0800776 norm[maxV] += (short)ToDistribute;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100777 return 0;
778 }
779
780 {
781 U64 const vStepLog = 62 - tableLog;
782 U64 const mid = (1ULL << (vStepLog-1)) - 1;
783 U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
784 U64 tmpTotal = mid;
785 for (s=0; s<=maxSymbolValue; s++)
786 {
787 if (norm[s]==-2)
788 {
789 U64 end = tmpTotal + (count[s] * rStep);
790 U32 sStart = (U32)(tmpTotal >> vStepLog);
791 U32 sEnd = (U32)(end >> vStepLog);
792 U32 weight = sEnd - sStart;
793 if (weight < 1)
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100794 return ERROR(GENERIC);
Yann Collet213089c2015-06-18 07:43:16 -0800795 norm[s] = (short)weight;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100796 tmpTotal = end;
797 }
798 }
799 }
800
801 return 0;
802}
Yann Colleta3c75ba2015-02-21 03:31:59 +0100803
Yann Collet4856a002015-01-24 01:58:16 +0100804
805size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
806 const unsigned* count, size_t total,
807 unsigned maxSymbolValue)
808{
809 /* Sanity checks */
810 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100811 if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */
812 if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC); /* Unsupported size */
813 if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
Yann Collet4856a002015-01-24 01:58:16 +0100814
815 {
816 U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
817 U64 const scale = 62 - tableLog;
818 U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
819 U64 const vStep = 1ULL<<(scale-20);
820 int stillToDistribute = 1<<tableLog;
821 unsigned s;
822 unsigned largest=0;
823 short largestP=0;
824 U32 lowThreshold = (U32)(total >> tableLog);
825
826 for (s=0; s<=maxSymbolValue; s++)
827 {
828 if (count[s] == total) return 0;
829 if (count[s] == 0)
830 {
831 normalizedCounter[s]=0;
832 continue;
833 }
834 if (count[s] <= lowThreshold)
835 {
836 normalizedCounter[s] = -1;
837 stillToDistribute--;
838 }
839 else
840 {
841 short proba = (short)((count[s]*step) >> scale);
842 if (proba<8)
843 {
Yann Collet2ddf7e92015-02-08 20:26:47 +0100844 U64 restToBeat = vStep * rtbTable[proba];
Yann Collet4856a002015-01-24 01:58:16 +0100845 proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
846 }
847 if (proba > largestP)
848 {
849 largestP=proba;
850 largest=s;
851 }
852 normalizedCounter[s] = proba;
853 stillToDistribute -= proba;
854 }
855 }
Yann Collet4856a002015-01-24 01:58:16 +0100856 if (-stillToDistribute >= (normalizedCounter[largest] >> 1))
857 {
Yann Collet26aa1ec2015-02-24 09:05:58 +0100858 /* corner case, need another normalization method */
859 size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
Yann Collet565b81d2015-01-29 06:51:30 +0100860 if (FSE_isError(errorCode)) return errorCode;
Yann Collet4856a002015-01-24 01:58:16 +0100861 }
862 else normalizedCounter[largest] += (short)stillToDistribute;
863 }
864
865#if 0
866 { /* Print Table (debug) */
Yann Collet565b81d2015-01-29 06:51:30 +0100867 U32 s;
868 U32 nTotal = 0;
Yann Collet4856a002015-01-24 01:58:16 +0100869 for (s=0; s<=maxSymbolValue; s++)
870 printf("%3i: %4i \n", s, normalizedCounter[s]);
Yann Collet565b81d2015-01-29 06:51:30 +0100871 for (s=0; s<=maxSymbolValue; s++)
872 nTotal += abs(normalizedCounter[s]);
873 if (nTotal != (1U<<tableLog))
874 printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
Yann Collet4856a002015-01-24 01:58:16 +0100875 getchar();
876 }
877#endif
878
879 return tableLog;
880}
881
882
Yann Collet1efa31f2015-07-04 15:56:41 -0800883/* fake FSE_CTable, for raw (uncompressed) input */
884size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +0100885{
886 const unsigned tableSize = 1 << nbBits;
887 const unsigned tableMask = tableSize - 1;
888 const unsigned maxSymbolValue = tableMask;
Yann Collet3b994cb2016-01-06 01:58:37 +0100889 void* const ptr = ct;
890 U16* const tableU16 = ( (U16*) ptr) + 2;
891 void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1); /* assumption : tableLog >= 1 */
892 FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
Yann Collet4856a002015-01-24 01:58:16 +0100893 unsigned s;
894
895 /* Sanity checks */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100896 if (nbBits < 1) return ERROR(GENERIC); /* min size */
Yann Collet4856a002015-01-24 01:58:16 +0100897
898 /* header */
899 tableU16[-2] = (U16) nbBits;
900 tableU16[-1] = (U16) maxSymbolValue;
901
902 /* Build table */
903 for (s=0; s<tableSize; s++)
904 tableU16[s] = (U16)(tableSize + s);
905
906 /* Build Symbol Transformation Table */
907 for (s=0; s<=maxSymbolValue; s++)
908 {
Yann Collet77c82b62015-08-02 01:19:09 +0100909 symbolTT[s].deltaNbBits = nbBits << 16;
Yann Collet4856a002015-01-24 01:58:16 +0100910 symbolTT[s].deltaFindState = s-1;
Yann Collet4856a002015-01-24 01:58:16 +0100911 }
912
913 return 0;
914}
915
Yann Collet1efa31f2015-07-04 15:56:41 -0800916/* fake FSE_CTable, for rle (100% always same symbol) input */
917size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +0100918{
Yann Collet3b994cb2016-01-06 01:58:37 +0100919 void* ptr = ct;
920 U16* tableU16 = ( (U16*) ptr) + 2;
921 void* FSCTptr = (U32*)ptr + 2;
922 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) FSCTptr;
Yann Collet4856a002015-01-24 01:58:16 +0100923
924 /* header */
925 tableU16[-2] = (U16) 0;
926 tableU16[-1] = (U16) symbolValue;
927
928 /* Build table */
929 tableU16[0] = 0;
930 tableU16[1] = 0; /* just in case */
931
932 /* Build Symbol Transformation Table */
933 {
Yann Collet77c82b62015-08-02 01:19:09 +0100934 symbolTT[symbolValue].deltaNbBits = 0;
Yann Collet4856a002015-01-24 01:58:16 +0100935 symbolTT[symbolValue].deltaFindState = 0;
Yann Collet4856a002015-01-24 01:58:16 +0100936 }
937
938 return 0;
939}
940
941
Yann Colleta7875502015-08-07 15:21:00 +0100942static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
Yann Collet4856a002015-01-24 01:58:16 +0100943 const void* src, size_t srcSize,
Yann Colleta7875502015-08-07 15:21:00 +0100944 const FSE_CTable* ct, const unsigned fast)
Yann Collet4856a002015-01-24 01:58:16 +0100945{
946 const BYTE* const istart = (const BYTE*) src;
947 const BYTE* ip;
948 const BYTE* const iend = istart + srcSize;
949
Yann Colleta7875502015-08-07 15:21:00 +0100950 size_t errorCode;
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100951 BIT_CStream_t bitC;
Yann Collet4856a002015-01-24 01:58:16 +0100952 FSE_CState_t CState1, CState2;
953
954
955 /* init */
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100956 errorCode = BIT_initCStream(&bitC, dst, dstSize);
Yann Colleta7875502015-08-07 15:21:00 +0100957 if (FSE_isError(errorCode)) return 0;
Yann Collet1efa31f2015-07-04 15:56:41 -0800958 FSE_initCState(&CState1, ct);
Yann Collet4856a002015-01-24 01:58:16 +0100959 CState2 = CState1;
960
961 ip=iend;
962
Yann Colletb1f3f4b2015-10-18 22:18:32 +0100963#define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
Yann Colleta7875502015-08-07 15:21:00 +0100964
Yann Collet4856a002015-01-24 01:58:16 +0100965 /* join to even */
966 if (srcSize & 1)
967 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800968 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Colleta7875502015-08-07 15:21:00 +0100969 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +0100970 }
971
972 /* join to mod 4 */
Yann Collet77c82b62015-08-02 01:19:09 +0100973 if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) /* test bit 2 */
Yann Collet4856a002015-01-24 01:58:16 +0100974 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800975 FSE_encodeSymbol(&bitC, &CState2, *--ip);
976 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Colleta7875502015-08-07 15:21:00 +0100977 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +0100978 }
979
980 /* 2 or 4 encoding per loop */
Yann Colleta7875502015-08-07 15:21:00 +0100981 for ( ; ip>istart ; )
Yann Collet4856a002015-01-24 01:58:16 +0100982 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800983 FSE_encodeSymbol(&bitC, &CState2, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100984
Yann Collet77c82b62015-08-02 01:19:09 +0100985 if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */
Yann Colleta7875502015-08-07 15:21:00 +0100986 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +0100987
Yann Collet1efa31f2015-07-04 15:56:41 -0800988 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100989
Yann Collet77c82b62015-08-02 01:19:09 +0100990 if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) /* this test must be static */
Yann Collet4856a002015-01-24 01:58:16 +0100991 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800992 FSE_encodeSymbol(&bitC, &CState2, *--ip);
993 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100994 }
995
Yann Colleta7875502015-08-07 15:21:00 +0100996 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +0100997 }
998
999 FSE_flushCState(&bitC, &CState2);
1000 FSE_flushCState(&bitC, &CState1);
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001001 return BIT_closeCStream(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +01001002}
1003
Yann Colleta7875502015-08-07 15:21:00 +01001004size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
1005 const void* src, size_t srcSize,
1006 const FSE_CTable* ct)
1007{
1008 const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
1009
1010 if (fast)
1011 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
1012 else
1013 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
1014}
1015
Yann Collet4856a002015-01-24 01:58:16 +01001016
Yann Collet4856a002015-01-24 01:58:16 +01001017size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
1018
Yann Collet4856a002015-01-24 01:58:16 +01001019size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
1020{
1021 const BYTE* const istart = (const BYTE*) src;
1022 const BYTE* ip = istart;
1023
1024 BYTE* const ostart = (BYTE*) dst;
1025 BYTE* op = ostart;
1026 BYTE* const oend = ostart + dstSize;
1027
1028 U32 count[FSE_MAX_SYMBOL_VALUE+1];
1029 S16 norm[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -08001030 CTable_max_t ct;
Yann Collet4856a002015-01-24 01:58:16 +01001031 size_t errorCode;
1032
Yann Colleta7875502015-08-07 15:21:00 +01001033 /* init conditions */
1034 if (srcSize <= 1) return 0; /* Uncompressible */
Yann Collet4856a002015-01-24 01:58:16 +01001035 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
1036 if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
1037
1038 /* Scan input and build symbol stats */
Yann Collet1efa31f2015-07-04 15:56:41 -08001039 errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001040 if (FSE_isError(errorCode)) return errorCode;
Yann Colleta3c75ba2015-02-21 03:31:59 +01001041 if (errorCode == srcSize) return 1;
Yann Collet6b5198f2015-08-26 19:22:01 +01001042 if (errorCode == 1) return 0; /* each symbol only present once */
Yann Colleta3c75ba2015-02-21 03:31:59 +01001043 if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
Yann Collet4856a002015-01-24 01:58:16 +01001044
1045 tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
1046 errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
1047 if (FSE_isError(errorCode)) return errorCode;
1048
1049 /* Write table description header */
Yann Colleta7875502015-08-07 15:21:00 +01001050 errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001051 if (FSE_isError(errorCode)) return errorCode;
1052 op += errorCode;
1053
1054 /* Compress */
Yann Collet1efa31f2015-07-04 15:56:41 -08001055 errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001056 if (FSE_isError(errorCode)) return errorCode;
Yann Colleta7875502015-08-07 15:21:00 +01001057 errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
1058 if (errorCode == 0) return 0; /* not enough space for compressed data */
1059 op += errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001060
1061 /* check compressibility */
1062 if ( (size_t)(op-ostart) >= srcSize-1 )
1063 return 0;
1064
1065 return op-ostart;
1066}
1067
Yann Collet4856a002015-01-24 01:58:16 +01001068size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
1069{
1070 return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
1071}
1072
1073
1074/*********************************************************
1075* Decompression (Byte symbols)
1076*********************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -08001077size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +01001078{
Yann Collet3b994cb2016-01-06 01:58:37 +01001079 void* ptr = dt;
1080 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
1081 void* dPtr = dt + 1;
1082 FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
Yann Collet4856a002015-01-24 01:58:16 +01001083
Yann Colleta7875502015-08-07 15:21:00 +01001084 DTableH->tableLog = 0;
1085 DTableH->fastMode = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001086
1087 cell->newState = 0;
1088 cell->symbol = symbolValue;
1089 cell->nbBits = 0;
1090
1091 return 0;
1092}
1093
1094
Yann Collet1efa31f2015-07-04 15:56:41 -08001095size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001096{
Yann Collet3b994cb2016-01-06 01:58:37 +01001097 void* ptr = dt;
1098 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
1099 void* dPtr = dt + 1;
1100 FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
Yann Collet4856a002015-01-24 01:58:16 +01001101 const unsigned tableSize = 1 << nbBits;
1102 const unsigned tableMask = tableSize - 1;
1103 const unsigned maxSymbolValue = tableMask;
1104 unsigned s;
1105
1106 /* Sanity checks */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001107 if (nbBits < 1) return ERROR(GENERIC); /* min size */
Yann Collet4856a002015-01-24 01:58:16 +01001108
1109 /* Build Decoding Table */
Yann Colleta7875502015-08-07 15:21:00 +01001110 DTableH->tableLog = (U16)nbBits;
1111 DTableH->fastMode = 1;
Yann Collet4856a002015-01-24 01:58:16 +01001112 for (s=0; s<=maxSymbolValue; s++)
1113 {
1114 dinfo[s].newState = 0;
1115 dinfo[s].symbol = (BYTE)s;
1116 dinfo[s].nbBits = (BYTE)nbBits;
1117 }
1118
1119 return 0;
1120}
1121
Yann Collet4856a002015-01-24 01:58:16 +01001122FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
1123 void* dst, size_t maxDstSize,
1124 const void* cSrc, size_t cSrcSize,
Yann Colleta7875502015-08-07 15:21:00 +01001125 const FSE_DTable* dt, const unsigned fast)
Yann Collet4856a002015-01-24 01:58:16 +01001126{
1127 BYTE* const ostart = (BYTE*) dst;
1128 BYTE* op = ostart;
1129 BYTE* const omax = op + maxDstSize;
1130 BYTE* const olimit = omax-3;
1131
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001132 BIT_DStream_t bitD;
Yann Collet1efa31f2015-07-04 15:56:41 -08001133 FSE_DState_t state1;
1134 FSE_DState_t state2;
Yann Collet4856a002015-01-24 01:58:16 +01001135 size_t errorCode;
1136
1137 /* Init */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001138 errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
Yann Collet4856a002015-01-24 01:58:16 +01001139 if (FSE_isError(errorCode)) return errorCode;
1140
Yann Collet1efa31f2015-07-04 15:56:41 -08001141 FSE_initDState(&state1, &bitD, dt);
1142 FSE_initDState(&state2, &bitD, dt);
Yann Collet4856a002015-01-24 01:58:16 +01001143
Yann Collet77c82b62015-08-02 01:19:09 +01001144#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
Yann Collet4856a002015-01-24 01:58:16 +01001145
Yann Collet77c82b62015-08-02 01:19:09 +01001146 /* 4 symbols per loop */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001147 for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) && (op<olimit) ; op+=4)
Yann Collet4856a002015-01-24 01:58:16 +01001148 {
Yann Collet77c82b62015-08-02 01:19:09 +01001149 op[0] = FSE_GETSYMBOL(&state1);
Yann Collet4856a002015-01-24 01:58:16 +01001150
Yann Collet77c82b62015-08-02 01:19:09 +01001151 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001152 BIT_reloadDStream(&bitD);
Yann Collet4856a002015-01-24 01:58:16 +01001153
Yann Collet77c82b62015-08-02 01:19:09 +01001154 op[1] = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001155
Yann Collet77c82b62015-08-02 01:19:09 +01001156 if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001157 { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
Yann Collet77c82b62015-08-02 01:19:09 +01001158
1159 op[2] = FSE_GETSYMBOL(&state1);
1160
1161 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001162 BIT_reloadDStream(&bitD);
Yann Collet77c82b62015-08-02 01:19:09 +01001163
1164 op[3] = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001165 }
1166
1167 /* tail */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001168 /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
Yann Collet4856a002015-01-24 01:58:16 +01001169 while (1)
1170 {
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001171 if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) )
Yann Collet4856a002015-01-24 01:58:16 +01001172 break;
1173
Yann Collet77c82b62015-08-02 01:19:09 +01001174 *op++ = FSE_GETSYMBOL(&state1);
Yann Collet4856a002015-01-24 01:58:16 +01001175
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001176 if ( (BIT_reloadDStream(&bitD)>BIT_DStream_completed) || (op==omax) || (BIT_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) )
Yann Collet4856a002015-01-24 01:58:16 +01001177 break;
1178
Yann Collet77c82b62015-08-02 01:19:09 +01001179 *op++ = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001180 }
1181
1182 /* end ? */
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001183 if (BIT_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2))
Yann Collet4856a002015-01-24 01:58:16 +01001184 return op-ostart;
1185
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001186 if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */
Yann Collet4856a002015-01-24 01:58:16 +01001187
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001188 return ERROR(corruption_detected);
Yann Collet4856a002015-01-24 01:58:16 +01001189}
1190
1191
1192size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
1193 const void* cSrc, size_t cSrcSize,
Yann Colleta7875502015-08-07 15:21:00 +01001194 const FSE_DTable* dt)
Yann Collet4856a002015-01-24 01:58:16 +01001195{
Yann Collet3b994cb2016-01-06 01:58:37 +01001196 const void* ptr = dt;
1197 const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
Yann Colleta7875502015-08-07 15:21:00 +01001198 const U32 fastMode = DTableH->fastMode;
1199
Yann Collet4856a002015-01-24 01:58:16 +01001200 /* select fast mode (static) */
Yann Collet1efa31f2015-07-04 15:56:41 -08001201 if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
1202 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
Yann Collet4856a002015-01-24 01:58:16 +01001203}
1204
1205
1206size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
1207{
1208 const BYTE* const istart = (const BYTE*)cSrc;
1209 const BYTE* ip = istart;
1210 short counting[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -08001211 DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
Yann Collet4856a002015-01-24 01:58:16 +01001212 unsigned tableLog;
Yann Collet1efa31f2015-07-04 15:56:41 -08001213 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
Yann Colleta7875502015-08-07 15:21:00 +01001214 size_t errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001215
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001216 if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */
Yann Collet4856a002015-01-24 01:58:16 +01001217
1218 /* normal FSE decoding mode */
Yann Collet1efa31f2015-07-04 15:56:41 -08001219 errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001220 if (FSE_isError(errorCode)) return errorCode;
Yann Colletb1f3f4b2015-10-18 22:18:32 +01001221 if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */
Yann Collet4856a002015-01-24 01:58:16 +01001222 ip += errorCode;
1223 cSrcSize -= errorCode;
1224
Yann Colleta7875502015-08-07 15:21:00 +01001225 errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);
1226 if (FSE_isError(errorCode)) return errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001227
1228 /* always return, even if it is an error code */
Yann Colleta7875502015-08-07 15:21:00 +01001229 return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);
Yann Collet4856a002015-01-24 01:58:16 +01001230}
1231
1232
Yann Collet4856a002015-01-24 01:58:16 +01001233
Yann Collete8c6bb12015-07-26 00:23:57 +01001234#endif /* FSE_COMMONDEFS_ONLY */