blob: b0318f15f2d00bee24a5f829a944b1a8dcb167d8 [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
37/****************************************************************
38* Tuning parameters
39****************************************************************/
40/* MEMORY_USAGE :
41* 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
48/* FSE_MAX_SYMBOL_VALUE :
49* Maximum symbol value authorized.
50* Required for proper stack allocation */
51#define FSE_MAX_SYMBOL_VALUE 255
52
53
54/****************************************************************
55* Generic function type & suffix (C template emulation)
56****************************************************************/
57#define FSE_FUNCTION_TYPE BYTE
58#define FSE_FUNCTION_EXTENSION
59
60#endif /* !FSE_COMMONDEFS_ONLY */
61
62
63/****************************************************************
64* Compiler specifics
65****************************************************************/
66#ifdef _MSC_VER /* Visual Studio */
67# define FORCE_INLINE static __forceinline
68# include <intrin.h> /* For Visual 2005 */
69# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
70# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
71#else
72# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
73# ifdef __GNUC__
74# define FORCE_INLINE static inline __attribute__((always_inline))
75# else
76# define FORCE_INLINE static inline
77# endif
78#endif
79
80
81/****************************************************************
82* Includes
83****************************************************************/
84#include <stdlib.h> /* malloc, free, qsort */
85#include <string.h> /* memcpy, memset */
86#include <stdio.h> /* printf (debug) */
87#include "fse_static.h"
88
89
Yann Colletad68a0e2015-02-26 00:29:15 +010090#ifndef MEM_ACCESS_MODULE
91#define MEM_ACCESS_MODULE
Yann Collet4856a002015-01-24 01:58:16 +010092/****************************************************************
93* Basic Types
94*****************************************************************/
95#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
96# include <stdint.h>
97typedef uint8_t BYTE;
98typedef uint16_t U16;
99typedef int16_t S16;
100typedef uint32_t U32;
101typedef int32_t S32;
102typedef uint64_t U64;
103typedef int64_t S64;
104#else
105typedef unsigned char BYTE;
106typedef unsigned short U16;
107typedef signed short S16;
108typedef unsigned int U32;
109typedef signed int S32;
110typedef unsigned long long U64;
111typedef signed long long S64;
112#endif
113
Yann Colletad68a0e2015-02-26 00:29:15 +0100114#endif /* MEM_ACCESS_MODULE */
Yann Collet4856a002015-01-24 01:58:16 +0100115
116/****************************************************************
117* Memory I/O
118*****************************************************************/
119static unsigned FSE_isLittleEndian(void)
120{
121 const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
122 return one.c[0];
123}
124
125static U32 FSE_read32(const void* memPtr)
126{
127 U32 val32;
128 memcpy(&val32, memPtr, 4);
129 return val32;
130}
131
132static U32 FSE_readLE32(const void* memPtr)
133{
134 if (FSE_isLittleEndian())
135 return FSE_read32(memPtr);
136 else
137 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100138 const BYTE* p = (const BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100139 return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24));
140 }
141}
142
143static void FSE_writeLE32(void* memPtr, U32 val32)
144{
145 if (FSE_isLittleEndian())
146 {
147 memcpy(memPtr, &val32, 4);
148 }
149 else
150 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100151 BYTE* p = (BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100152 p[0] = (BYTE)val32;
153 p[1] = (BYTE)(val32>>8);
154 p[2] = (BYTE)(val32>>16);
155 p[3] = (BYTE)(val32>>24);
156 }
157}
158
159static U64 FSE_read64(const void* memPtr)
160{
161 U64 val64;
162 memcpy(&val64, memPtr, 8);
163 return val64;
164}
165
166static U64 FSE_readLE64(const void* memPtr)
167{
168 if (FSE_isLittleEndian())
169 return FSE_read64(memPtr);
170 else
171 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100172 const BYTE* p = (const BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100173 return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24)
174 + ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56));
175 }
176}
177
178static void FSE_writeLE64(void* memPtr, U64 val64)
179{
180 if (FSE_isLittleEndian())
181 {
182 memcpy(memPtr, &val64, 8);
183 }
184 else
185 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100186 BYTE* p = (BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100187 p[0] = (BYTE)val64;
188 p[1] = (BYTE)(val64>>8);
189 p[2] = (BYTE)(val64>>16);
190 p[3] = (BYTE)(val64>>24);
191 p[4] = (BYTE)(val64>>32);
192 p[5] = (BYTE)(val64>>40);
193 p[6] = (BYTE)(val64>>48);
194 p[7] = (BYTE)(val64>>56);
195 }
196}
197
198static size_t FSE_readLEST(const void* memPtr)
199{
200 if (sizeof(size_t)==4)
Yann Colletfb814172015-01-25 13:19:12 +0100201 return (size_t)FSE_readLE32(memPtr);
Yann Collet4856a002015-01-24 01:58:16 +0100202 else
Yann Colletfb814172015-01-25 13:19:12 +0100203 return (size_t)FSE_readLE64(memPtr);
Yann Collet4856a002015-01-24 01:58:16 +0100204}
205
206static void FSE_writeLEST(void* memPtr, size_t val)
207{
208 if (sizeof(size_t)==4)
209 FSE_writeLE32(memPtr, (U32)val);
210 else
211 FSE_writeLE64(memPtr, (U64)val);
212}
213
214
215/****************************************************************
216* Constants
217*****************************************************************/
218#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
219#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
220#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
221#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
222#define FSE_MIN_TABLELOG 5
223
224#define FSE_TABLELOG_ABSOLUTE_MAX 15
225#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
226#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
227#endif
228
229
230/****************************************************************
231* Error Management
232****************************************************************/
233#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
234
235
236/****************************************************************
237* Complex types
238****************************************************************/
239typedef struct
240{
241 int deltaFindState;
242 U16 maxState;
243 BYTE minBitsOut;
Yann Collet1efa31f2015-07-04 15:56:41 -0800244 /* one byte padding ; total 8 bytes */
Yann Collet4856a002015-01-24 01:58:16 +0100245} FSE_symbolCompressionTransform;
246
Yann Collet1efa31f2015-07-04 15:56:41 -0800247typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
248typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
Yann Collet4856a002015-01-24 01:58:16 +0100249
250/****************************************************************
251* Internal functions
252****************************************************************/
253FORCE_INLINE unsigned FSE_highbit32 (register U32 val)
254{
255# if defined(_MSC_VER) /* Visual */
256 unsigned long r;
257 _BitScanReverse ( &r, val );
258 return (unsigned) r;
259# elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */
260 return 31 - __builtin_clz (val);
261# else /* Software version */
262 static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
263 U32 v = val;
264 unsigned r;
265 v |= v >> 1;
266 v |= v >> 2;
267 v |= v >> 4;
268 v |= v >> 8;
269 v |= v >> 16;
270 r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
271 return r;
272# endif
273}
274
275
276#ifndef FSE_COMMONDEFS_ONLY
277
278unsigned FSE_isError(size_t code) { return (code > (size_t)(-FSE_ERROR_maxCode)); }
279
280#define FSE_GENERATE_STRING(STRING) #STRING,
281static const char* FSE_errorStrings[] = { FSE_LIST_ERRORS(FSE_GENERATE_STRING) };
282
283const char* FSE_getErrorName(size_t code)
284{
285 static const char* codeError = "Unspecified error code";
286 if (FSE_isError(code)) return FSE_errorStrings[-(int)(code)];
287 return codeError;
288}
289
290static short FSE_abs(short a)
291{
292 return a<0? -a : a;
293}
294
295
296/****************************************************************
297* Header bitstream management
298****************************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -0800299size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100300{
301 size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 1;
302 return maxSymbolValue ? maxHeaderSize : FSE_MAX_HEADERSIZE;
303}
304
Yann Collet213089c2015-06-18 07:43:16 -0800305#ifndef __clang_analyzer__ /* clang static analyzer has difficulties with this function : seems to believe normalizedCounter is uninitialized */
306
Yann Collet1efa31f2015-07-04 15:56:41 -0800307static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
Yann Collet4856a002015-01-24 01:58:16 +0100308 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
309 unsigned safeWrite)
310{
311 BYTE* const ostart = (BYTE*) header;
312 BYTE* out = ostart;
313 BYTE* const oend = ostart + headerBufferSize;
314 int nbBits;
315 const int tableSize = 1 << tableLog;
316 int remaining;
317 int threshold;
318 U32 bitStream;
319 int bitCount;
320 unsigned charnum = 0;
321 int previous0 = 0;
322
323 bitStream = 0;
324 bitCount = 0;
325 /* Table Size */
326 bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
327 bitCount += 4;
328
329 /* Init */
330 remaining = tableSize+1; /* +1 for extra accuracy */
331 threshold = tableSize;
332 nbBits = tableLog+1;
333
334 while (remaining>1) /* stops at 1 */
335 {
336 if (previous0)
337 {
338 unsigned start = charnum;
339 while (!normalizedCounter[charnum]) charnum++;
340 while (charnum >= start+24)
341 {
342 start+=24;
Yann Collet213089c2015-06-18 07:43:16 -0800343 bitStream += 0xFFFFU << bitCount;
Yann Collet4856a002015-01-24 01:58:16 +0100344 if ((!safeWrite) && (out > oend-2)) return (size_t)-FSE_ERROR_GENERIC; /* Buffer overflow */
Yann Collet213089c2015-06-18 07:43:16 -0800345 out[0] = (BYTE) bitStream;
Yann Collet4856a002015-01-24 01:58:16 +0100346 out[1] = (BYTE)(bitStream>>8);
347 out+=2;
348 bitStream>>=16;
349 }
350 while (charnum >= start+3)
351 {
352 start+=3;
353 bitStream += 3 << bitCount;
354 bitCount += 2;
355 }
356 bitStream += (charnum-start) << bitCount;
357 bitCount += 2;
358 if (bitCount>16)
359 {
360 if ((!safeWrite) && (out > oend - 2)) return (size_t)-FSE_ERROR_GENERIC; /* Buffer overflow */
361 out[0] = (BYTE)bitStream;
362 out[1] = (BYTE)(bitStream>>8);
363 out += 2;
364 bitStream >>= 16;
365 bitCount -= 16;
366 }
367 }
368 {
369 short count = normalizedCounter[charnum++];
370 const short max = (short)((2*threshold-1)-remaining);
371 remaining -= FSE_abs(count);
Yann Collet213089c2015-06-18 07:43:16 -0800372 if (remaining<1) return (size_t)-FSE_ERROR_GENERIC;
Yann Collet4856a002015-01-24 01:58:16 +0100373 count++; /* +1 for extra accuracy */
374 if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
375 bitStream += count << bitCount;
376 bitCount += nbBits;
377 bitCount -= (count<max);
378 previous0 = (count==1);
379 while (remaining<threshold) nbBits--, threshold>>=1;
380 }
381 if (bitCount>16)
382 {
383 if ((!safeWrite) && (out > oend - 2)) return (size_t)-FSE_ERROR_GENERIC; /* Buffer overflow */
384 out[0] = (BYTE)bitStream;
385 out[1] = (BYTE)(bitStream>>8);
386 out += 2;
387 bitStream >>= 16;
388 bitCount -= 16;
389 }
390 }
391
392 /* flush remaining bitStream */
393 if ((!safeWrite) && (out > oend - 2)) return (size_t)-FSE_ERROR_GENERIC; /* Buffer overflow */
394 out[0] = (BYTE)bitStream;
395 out[1] = (BYTE)(bitStream>>8);
396 out+= (bitCount+7) /8;
397
398 if (charnum > maxSymbolValue + 1) return (size_t)-FSE_ERROR_GENERIC; /* Too many symbols written (a bit too late?) */
399
400 return (out-ostart);
401}
Yann Collet213089c2015-06-18 07:43:16 -0800402#endif // __clang_analyzer__
Yann Collet4856a002015-01-24 01:58:16 +0100403
404
Yann Collet1efa31f2015-07-04 15:56:41 -0800405size_t FSE_writeNCount (void* header, size_t headerBufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100406{
407 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported */
408 if (tableLog < FSE_MIN_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported */
409
Yann Collet1efa31f2015-07-04 15:56:41 -0800410 if (headerBufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
411 return FSE_writeNCount_generic(header, headerBufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
Yann Collet4856a002015-01-24 01:58:16 +0100412
Yann Collet1efa31f2015-07-04 15:56:41 -0800413 return FSE_writeNCount_generic(header, headerBufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
Yann Collet4856a002015-01-24 01:58:16 +0100414}
415
416
Yann Collet1efa31f2015-07-04 15:56:41 -0800417size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
Yann Collet4856a002015-01-24 01:58:16 +0100418 const void* headerBuffer, size_t hbSize)
419{
420 const BYTE* const istart = (const BYTE*) headerBuffer;
Yann Collet1efa31f2015-07-04 15:56:41 -0800421 const BYTE* const iend = istart + hbSize;
Yann Collet4856a002015-01-24 01:58:16 +0100422 const BYTE* ip = istart;
423 int nbBits;
424 int remaining;
425 int threshold;
426 U32 bitStream;
427 int bitCount;
428 unsigned charnum = 0;
429 int previous0 = 0;
430
Yann Collet1efa31f2015-07-04 15:56:41 -0800431 if (hbSize < 4) return (size_t)-FSE_ERROR_srcSize_wrong;
Yann Collet4856a002015-01-24 01:58:16 +0100432 bitStream = FSE_readLE32(ip);
433 nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
434 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return (size_t)-FSE_ERROR_tableLog_tooLarge;
435 bitStream >>= 4;
436 bitCount = 4;
437 *tableLogPtr = nbBits;
438 remaining = (1<<nbBits)+1;
439 threshold = 1<<nbBits;
440 nbBits++;
441
442 while ((remaining>1) && (charnum<=*maxSVPtr))
443 {
444 if (previous0)
445 {
446 unsigned n0 = charnum;
447 while ((bitStream & 0xFFFF) == 0xFFFF)
448 {
449 n0+=24;
450 ip+=2;
451 bitStream = FSE_readLE32(ip) >> bitCount;
452 }
453 while ((bitStream & 3) == 3)
454 {
455 n0+=3;
456 bitStream>>=2;
457 bitCount+=2;
458 }
459 n0 += bitStream & 3;
460 bitCount += 2;
Yann Collet1efa31f2015-07-04 15:56:41 -0800461 if (n0 > *maxSVPtr) return (size_t)-FSE_ERROR_maxSymbolValue_tooSmall;
Yann Collet4856a002015-01-24 01:58:16 +0100462 while (charnum < n0) normalizedCounter[charnum++] = 0;
463 ip += bitCount>>3;
464 bitCount &= 7;
465 bitStream = FSE_readLE32(ip) >> bitCount;
466 }
467 {
468 const short max = (short)((2*threshold-1)-remaining);
469 short count;
470
471 if ((bitStream & (threshold-1)) < (U32)max)
472 {
473 count = (short)(bitStream & (threshold-1));
474 bitCount += nbBits-1;
475 }
476 else
477 {
478 count = (short)(bitStream & (2*threshold-1));
479 if (count >= threshold) count -= max;
480 bitCount += nbBits;
481 }
482
483 count--; /* extra accuracy */
484 remaining -= FSE_abs(count);
485 normalizedCounter[charnum++] = count;
486 previous0 = !count;
487 while (remaining < threshold)
488 {
489 nbBits--;
490 threshold >>= 1;
491 }
492
Yann Collet1efa31f2015-07-04 15:56:41 -0800493 {
494 const BYTE* itarget = ip + (bitCount>>3);
495 if (itarget > iend - 4)
496 {
497 ip = iend - 4;
498 bitCount -= (int)(8 * (iend - 4 - ip));
499 }
500 else
501 {
502 ip = itarget;
503 bitCount &= 7;
504 }
505 bitStream = FSE_readLE32(ip) >> (bitCount & 31);
506 }
Yann Collet4856a002015-01-24 01:58:16 +0100507 }
508 }
509 if (remaining != 1) return (size_t)-FSE_ERROR_GENERIC;
510 *maxSVPtr = charnum-1;
511
Yann Collet1efa31f2015-07-04 15:56:41 -0800512 ip += (bitCount+7)>>3;
513 if ((size_t)(ip-istart) > hbSize) return (size_t)-FSE_ERROR_srcSize_wrong;
Yann Collet4856a002015-01-24 01:58:16 +0100514 return ip-istart;
515}
516
517
518/****************************************************************
519* FSE Compression Code
520****************************************************************/
521/*
Yann Collet1efa31f2015-07-04 15:56:41 -0800522FSE_CTable[0] is a variable size structure which contains :
Yann Collet4856a002015-01-24 01:58:16 +0100523 U16 tableLog;
524 U16 maxSymbolValue;
525 U16 nextStateNumber[1 << tableLog]; // This size is variable
526 FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1]; // This size is variable
527Allocation is manual, since C standard does not support variable-size structures.
528*/
529
530size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
531{
532 size_t size;
533 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 */
534 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC;
535 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
536 return size;
537}
538
Yann Collet1efa31f2015-07-04 15:56:41 -0800539FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100540{
541 size_t size;
542 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
543 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
Yann Collet1efa31f2015-07-04 15:56:41 -0800544 return (FSE_CTable*)malloc(size);
Yann Collet4856a002015-01-24 01:58:16 +0100545}
546
Yann Collet1efa31f2015-07-04 15:56:41 -0800547void FSE_freeCTable (FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +0100548{
Yann Collet1efa31f2015-07-04 15:56:41 -0800549 free(ct);
Yann Collet4856a002015-01-24 01:58:16 +0100550}
551
Yann Collet4856a002015-01-24 01:58:16 +0100552
553unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
554{
555 U32 tableLog = maxTableLog;
556 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
557 if ((FSE_highbit32((U32)(srcSize - 1)) - 2) < tableLog) tableLog = FSE_highbit32((U32)(srcSize - 1)) - 2; /* Accuracy can be reduced */
Yann Colletbbfa7d72015-03-23 23:15:22 +0100558 if ((FSE_highbit32(maxSymbolValue)+2) > tableLog) tableLog = FSE_highbit32(maxSymbolValue)+2; /* Need a minimum to safely represent all symbol values */
Yann Collet4856a002015-01-24 01:58:16 +0100559 if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
560 if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
561 return tableLog;
562}
563
564
565typedef struct
566{
567 U32 id;
568 U32 count;
569} rank_t;
570
571int FSE_compareRankT(const void* r1, const void* r2)
572{
Yann Collet1cc58de2015-01-29 07:13:54 +0100573 const rank_t* R1 = (const rank_t*)r1;
574 const rank_t* R2 = (const rank_t*)r2;
Yann Collet4856a002015-01-24 01:58:16 +0100575
576 return 2 * (R1->count < R2->count) - 1;
577}
578
Yann Colleta3c75ba2015-02-21 03:31:59 +0100579
580#if 0
Yann Collet565b81d2015-01-29 06:51:30 +0100581static size_t FSE_adjustNormSlow(short* norm, int pointsToRemove, const unsigned* count, U32 maxSymbolValue)
582{
Yann Collet2ddf7e92015-02-08 20:26:47 +0100583 rank_t rank[FSE_MAX_SYMBOL_VALUE+2];
Yann Collet565b81d2015-01-29 06:51:30 +0100584 U32 s;
585
586 /* Init */
587 for (s=0; s<=maxSymbolValue; s++)
588 {
589 rank[s].id = s;
590 rank[s].count = count[s];
591 if (norm[s] <= 1) rank[s].count = 0;
592 }
Yann Collet2ddf7e92015-02-08 20:26:47 +0100593 rank[maxSymbolValue+1].id = 0;
594 rank[maxSymbolValue+1].count = 0; /* ensures comparison ends here in worst case */
Yann Collet565b81d2015-01-29 06:51:30 +0100595
596 /* Sort according to count */
597 qsort(rank, maxSymbolValue+1, sizeof(rank_t), FSE_compareRankT);
598
599 while(pointsToRemove)
600 {
601 int newRank = 1;
602 rank_t savedR;
603 if (norm[rank[0].id] == 1)
604 return (size_t)-FSE_ERROR_GENERIC;
605 norm[rank[0].id]--;
606 pointsToRemove--;
607 rank[0].count -= (rank[0].count + 6) >> 3;
608 if (norm[rank[0].id] == 1)
609 rank[0].count=0;
610 savedR = rank[0];
611 while (rank[newRank].count > savedR.count)
612 {
613 rank[newRank-1] = rank[newRank];
614 newRank++;
615 }
616 rank[newRank-1] = savedR;
617 }
618
619 return 0;
620}
Yann Collet565b81d2015-01-29 06:51:30 +0100621
Yann Colleta3c75ba2015-02-21 03:31:59 +0100622#else
623
Yann Collet26aa1ec2015-02-24 09:05:58 +0100624/* Secondary normalization method.
625 To be used when primary method fails. */
626
627static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
Yann Colleta3c75ba2015-02-21 03:31:59 +0100628{
629 U32 s;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100630 U32 distributed = 0;
631 U32 ToDistribute;
632
633 /* Init */
Yann Colleta3c75ba2015-02-21 03:31:59 +0100634 U32 lowThreshold = (U32)(total >> tableLog);
635 U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
636
637 for (s=0; s<=maxSymbolValue; s++)
638 {
639 if (count[s] == 0)
640 {
641 norm[s]=0;
642 continue;
643 }
644 if (count[s] <= lowThreshold)
645 {
646 norm[s] = -1;
647 distributed++;
648 total -= count[s];
649 continue;
650 }
651 if (count[s] <= lowOne)
652 {
653 norm[s] = 1;
654 distributed++;
655 total -= count[s];
656 continue;
657 }
658 norm[s]=-2;
659 }
660 ToDistribute = (1 << tableLog) - distributed;
661
662 if ((total / ToDistribute) > lowOne)
663 {
664 /* risk of rounding to zero */
665 lowOne = (U32)((total * 3) / (ToDistribute * 2));
666 for (s=0; s<=maxSymbolValue; s++)
667 {
668 if ((norm[s] == -2) && (count[s] <= lowOne))
669 {
670 norm[s] = 1;
671 distributed++;
672 total -= count[s];
673 continue;
674 }
675 }
676 ToDistribute = (1 << tableLog) - distributed;
677 }
678
679 if (distributed == maxSymbolValue+1)
680 {
Yann Collet26aa1ec2015-02-24 09:05:58 +0100681 /* all values are pretty poor;
682 probably incompressible data (should have already been detected);
683 find max, then give all remaining points to max */
Yann Colleta3c75ba2015-02-21 03:31:59 +0100684 U32 maxV = 0, maxC =0;
685 for (s=0; s<=maxSymbolValue; s++)
686 if (count[s] > maxC) maxV=s, maxC=count[s];
Yann Collet1efa31f2015-07-04 15:56:41 -0800687 norm[maxV] += (short)ToDistribute;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100688 return 0;
689 }
690
691 {
692 U64 const vStepLog = 62 - tableLog;
693 U64 const mid = (1ULL << (vStepLog-1)) - 1;
694 U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
695 U64 tmpTotal = mid;
696 for (s=0; s<=maxSymbolValue; s++)
697 {
698 if (norm[s]==-2)
699 {
700 U64 end = tmpTotal + (count[s] * rStep);
701 U32 sStart = (U32)(tmpTotal >> vStepLog);
702 U32 sEnd = (U32)(end >> vStepLog);
703 U32 weight = sEnd - sStart;
704 if (weight < 1)
705 return (size_t)-FSE_ERROR_GENERIC;
Yann Collet213089c2015-06-18 07:43:16 -0800706 norm[s] = (short)weight;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100707 tmpTotal = end;
708 }
709 }
710 }
711
712 return 0;
713}
714#endif
715
Yann Collet4856a002015-01-24 01:58:16 +0100716
717size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
718 const unsigned* count, size_t total,
719 unsigned maxSymbolValue)
720{
721 /* Sanity checks */
722 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
723 if (tableLog < FSE_MIN_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported size */
724 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported size */
725 if ((1U<<tableLog) <= maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; /* Too small tableLog, compression potentially impossible */
726
727 {
728 U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
729 U64 const scale = 62 - tableLog;
730 U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
731 U64 const vStep = 1ULL<<(scale-20);
732 int stillToDistribute = 1<<tableLog;
733 unsigned s;
734 unsigned largest=0;
735 short largestP=0;
736 U32 lowThreshold = (U32)(total >> tableLog);
737
738 for (s=0; s<=maxSymbolValue; s++)
739 {
740 if (count[s] == total) return 0;
741 if (count[s] == 0)
742 {
743 normalizedCounter[s]=0;
744 continue;
745 }
746 if (count[s] <= lowThreshold)
747 {
748 normalizedCounter[s] = -1;
749 stillToDistribute--;
750 }
751 else
752 {
753 short proba = (short)((count[s]*step) >> scale);
754 if (proba<8)
755 {
Yann Collet2ddf7e92015-02-08 20:26:47 +0100756 U64 restToBeat = vStep * rtbTable[proba];
Yann Collet4856a002015-01-24 01:58:16 +0100757 proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
758 }
759 if (proba > largestP)
760 {
761 largestP=proba;
762 largest=s;
763 }
764 normalizedCounter[s] = proba;
765 stillToDistribute -= proba;
766 }
767 }
Yann Collet4856a002015-01-24 01:58:16 +0100768 if (-stillToDistribute >= (normalizedCounter[largest] >> 1))
769 {
Yann Collet26aa1ec2015-02-24 09:05:58 +0100770 /* corner case, need another normalization method */
771 size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
Yann Collet565b81d2015-01-29 06:51:30 +0100772 if (FSE_isError(errorCode)) return errorCode;
Yann Collet4856a002015-01-24 01:58:16 +0100773 }
774 else normalizedCounter[largest] += (short)stillToDistribute;
775 }
776
777#if 0
778 { /* Print Table (debug) */
Yann Collet565b81d2015-01-29 06:51:30 +0100779 U32 s;
780 U32 nTotal = 0;
Yann Collet4856a002015-01-24 01:58:16 +0100781 for (s=0; s<=maxSymbolValue; s++)
782 printf("%3i: %4i \n", s, normalizedCounter[s]);
Yann Collet565b81d2015-01-29 06:51:30 +0100783 for (s=0; s<=maxSymbolValue; s++)
784 nTotal += abs(normalizedCounter[s]);
785 if (nTotal != (1U<<tableLog))
786 printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
Yann Collet4856a002015-01-24 01:58:16 +0100787 getchar();
788 }
789#endif
790
791 return tableLog;
792}
793
794
Yann Collet1efa31f2015-07-04 15:56:41 -0800795/* fake FSE_CTable, for raw (uncompressed) input */
796size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +0100797{
798 const unsigned tableSize = 1 << nbBits;
799 const unsigned tableMask = tableSize - 1;
800 const unsigned maxSymbolValue = tableMask;
Yann Collet1efa31f2015-07-04 15:56:41 -0800801 U16* tableU16 = ( (U16*) ct) + 2;
802 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) ((((U32*)ct)+1) + (tableSize>>1));
Yann Collet4856a002015-01-24 01:58:16 +0100803 unsigned s;
804
805 /* Sanity checks */
806 if (nbBits < 1) return (size_t)-FSE_ERROR_GENERIC; /* min size */
Yann Collet4856a002015-01-24 01:58:16 +0100807
808 /* header */
809 tableU16[-2] = (U16) nbBits;
810 tableU16[-1] = (U16) maxSymbolValue;
811
812 /* Build table */
813 for (s=0; s<tableSize; s++)
814 tableU16[s] = (U16)(tableSize + s);
815
816 /* Build Symbol Transformation Table */
817 for (s=0; s<=maxSymbolValue; s++)
818 {
819 symbolTT[s].minBitsOut = (BYTE)nbBits;
820 symbolTT[s].deltaFindState = s-1;
821 symbolTT[s].maxState = (U16)( (tableSize*2) - 1); /* ensures state <= maxState */
822 }
823
824 return 0;
825}
826
827
Yann Collet1efa31f2015-07-04 15:56:41 -0800828/* fake FSE_CTable, for rle (100% always same symbol) input */
829size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +0100830{
831 const unsigned tableSize = 1;
Yann Collet1efa31f2015-07-04 15:56:41 -0800832 U16* tableU16 = ( (U16*) ct) + 2;
833 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) ((U32*)ct + 2);
Yann Collet4856a002015-01-24 01:58:16 +0100834
835 /* header */
836 tableU16[-2] = (U16) 0;
837 tableU16[-1] = (U16) symbolValue;
838
839 /* Build table */
840 tableU16[0] = 0;
841 tableU16[1] = 0; /* just in case */
842
843 /* Build Symbol Transformation Table */
844 {
845 symbolTT[symbolValue].minBitsOut = 0;
846 symbolTT[symbolValue].deltaFindState = 0;
847 symbolTT[symbolValue].maxState = (U16)(2*tableSize-1); /* ensures state <= maxState */
848 }
849
850 return 0;
851}
852
853
854void FSE_initCStream(FSE_CStream_t* bitC, void* start)
855{
856 bitC->bitContainer = 0;
857 bitC->bitPos = 0; /* reserved for unusedBits */
858 bitC->startPtr = (char*)start;
859 bitC->ptr = bitC->startPtr;
860}
861
Yann Collet1efa31f2015-07-04 15:56:41 -0800862void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +0100863{
Yann Collet1efa31f2015-07-04 15:56:41 -0800864 const U32 tableLog = ( (const U16*) ct) [0];
Yann Collet4856a002015-01-24 01:58:16 +0100865 statePtr->value = (ptrdiff_t)1<<tableLog;
Yann Collet1efa31f2015-07-04 15:56:41 -0800866 statePtr->stateTable = ((const U16*) ct) + 2;
867 statePtr->symbolTT = (const FSE_symbolCompressionTransform*)((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
Yann Collet4856a002015-01-24 01:58:16 +0100868 statePtr->stateLog = tableLog;
869}
870
871void FSE_addBits(FSE_CStream_t* bitC, size_t value, unsigned nbBits)
872{
873 static const unsigned mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF }; /* up to 25 bits */
874 bitC->bitContainer |= (value & mask[nbBits]) << bitC->bitPos;
875 bitC->bitPos += nbBits;
876}
877
Yann Collet1efa31f2015-07-04 15:56:41 -0800878void FSE_encodeSymbol(FSE_CStream_t* bitC, FSE_CState_t* statePtr, BYTE symbol)
Yann Collet4856a002015-01-24 01:58:16 +0100879{
Yann Collet1efa31f2015-07-04 15:56:41 -0800880 const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
881 const U16* const stateTable = (const U16*)(statePtr->stateTable);
882 int nbBitsOut = symbolTT.minBitsOut;
883 nbBitsOut -= (int)((symbolTT.maxState - statePtr->value) >> 31);
Yann Collet4856a002015-01-24 01:58:16 +0100884 FSE_addBits(bitC, statePtr->value, nbBitsOut);
Yann Collet1efa31f2015-07-04 15:56:41 -0800885 statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
Yann Collet4856a002015-01-24 01:58:16 +0100886}
887
888void FSE_flushBits(FSE_CStream_t* bitC)
889{
890 size_t nbBytes = bitC->bitPos >> 3;
891 FSE_writeLEST(bitC->ptr, bitC->bitContainer);
892 bitC->bitPos &= 7;
893 bitC->ptr += nbBytes;
894 bitC->bitContainer >>= nbBytes*8;
895}
896
897void FSE_flushCState(FSE_CStream_t* bitC, const FSE_CState_t* statePtr)
898{
899 FSE_addBits(bitC, statePtr->value, statePtr->stateLog);
900 FSE_flushBits(bitC);
901}
902
903
904size_t FSE_closeCStream(FSE_CStream_t* bitC)
905{
906 char* endPtr;
907
908 FSE_addBits(bitC, 1, 1);
909 FSE_flushBits(bitC);
910
911 endPtr = bitC->ptr;
912 endPtr += bitC->bitPos > 0;
913
914 return (endPtr - bitC->startPtr);
915}
916
917
918size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
919 const void* src, size_t srcSize,
Yann Collet1efa31f2015-07-04 15:56:41 -0800920 const FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +0100921{
922 const BYTE* const istart = (const BYTE*) src;
923 const BYTE* ip;
924 const BYTE* const iend = istart + srcSize;
925
926 FSE_CStream_t bitC;
927 FSE_CState_t CState1, CState2;
928
929
930 /* init */
931 (void)dstSize; /* objective : ensure it fits into dstBuffer (Todo) */
932 FSE_initCStream(&bitC, dst);
Yann Collet1efa31f2015-07-04 15:56:41 -0800933 FSE_initCState(&CState1, ct);
Yann Collet4856a002015-01-24 01:58:16 +0100934 CState2 = CState1;
935
936 ip=iend;
937
938 /* join to even */
939 if (srcSize & 1)
940 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800941 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100942 FSE_flushBits(&bitC);
943 }
944
945 /* join to mod 4 */
946 if ((sizeof(size_t)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) /* test bit 2 */
947 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800948 FSE_encodeSymbol(&bitC, &CState2, *--ip);
949 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100950 FSE_flushBits(&bitC);
951 }
952
953 /* 2 or 4 encoding per loop */
954 while (ip>istart)
955 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800956 FSE_encodeSymbol(&bitC, &CState2, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100957
958 if (sizeof(size_t)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */
959 FSE_flushBits(&bitC);
960
Yann Collet1efa31f2015-07-04 15:56:41 -0800961 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100962
963 if (sizeof(size_t)*8 > FSE_MAX_TABLELOG*4+7 ) /* this test must be static */
964 {
Yann Collet1efa31f2015-07-04 15:56:41 -0800965 FSE_encodeSymbol(&bitC, &CState2, *--ip);
966 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +0100967 }
968
969 FSE_flushBits(&bitC);
970 }
971
972 FSE_flushCState(&bitC, &CState2);
973 FSE_flushCState(&bitC, &CState1);
974 return FSE_closeCStream(&bitC);
975}
976
977
Yann Collet4856a002015-01-24 01:58:16 +0100978size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
979
980
981size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
982{
983 const BYTE* const istart = (const BYTE*) src;
984 const BYTE* ip = istart;
985
986 BYTE* const ostart = (BYTE*) dst;
987 BYTE* op = ostart;
988 BYTE* const oend = ostart + dstSize;
989
990 U32 count[FSE_MAX_SYMBOL_VALUE+1];
991 S16 norm[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -0800992 CTable_max_t ct;
Yann Collet4856a002015-01-24 01:58:16 +0100993 size_t errorCode;
994
995 /* early out */
996 if (dstSize < FSE_compressBound(srcSize)) return (size_t)-FSE_ERROR_dstSize_tooSmall;
997 if (srcSize <= 1) return srcSize; /* Uncompressed or RLE */
998 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
999 if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
1000
1001 /* Scan input and build symbol stats */
Yann Collet1efa31f2015-07-04 15:56:41 -08001002 errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001003 if (FSE_isError(errorCode)) return errorCode;
Yann Colleta3c75ba2015-02-21 03:31:59 +01001004 if (errorCode == srcSize) return 1;
1005 if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
Yann Collet4856a002015-01-24 01:58:16 +01001006
1007 tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
1008 errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
1009 if (FSE_isError(errorCode)) return errorCode;
1010
1011 /* Write table description header */
Yann Collet1efa31f2015-07-04 15:56:41 -08001012 errorCode = FSE_writeNCount (op, FSE_MAX_HEADERSIZE, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001013 if (FSE_isError(errorCode)) return errorCode;
1014 op += errorCode;
1015
1016 /* Compress */
Yann Collet1efa31f2015-07-04 15:56:41 -08001017 errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001018 if (FSE_isError(errorCode)) return errorCode;
Yann Collet1efa31f2015-07-04 15:56:41 -08001019 op += FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
Yann Collet4856a002015-01-24 01:58:16 +01001020
1021 /* check compressibility */
1022 if ( (size_t)(op-ostart) >= srcSize-1 )
1023 return 0;
1024
1025 return op-ostart;
1026}
1027
1028
1029size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
1030{
1031 return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
1032}
1033
1034
1035/*********************************************************
1036* Decompression (Byte symbols)
1037*********************************************************/
1038typedef struct
1039{
1040 U16 newState;
1041 BYTE symbol;
1042 BYTE nbBits;
1043} FSE_decode_t; /* size == U32 */
1044
Yann Collet4856a002015-01-24 01:58:16 +01001045
Yann Collet1efa31f2015-07-04 15:56:41 -08001046size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +01001047{
Yann Collet1efa31f2015-07-04 15:56:41 -08001048 U32* const base32 = (U32*)dt;
Yann Collet4856a002015-01-24 01:58:16 +01001049 FSE_decode_t* const cell = (FSE_decode_t*)(base32 + 1);
1050
Yann Collet4856a002015-01-24 01:58:16 +01001051 base32[0] = 0;
1052
1053 cell->newState = 0;
1054 cell->symbol = symbolValue;
1055 cell->nbBits = 0;
1056
1057 return 0;
1058}
1059
1060
Yann Collet1efa31f2015-07-04 15:56:41 -08001061size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001062{
Yann Collet1efa31f2015-07-04 15:56:41 -08001063 U32* const base32 = (U32*)dt;
Yann Collet4856a002015-01-24 01:58:16 +01001064 FSE_decode_t* dinfo = (FSE_decode_t*)(base32 + 1);
1065 const unsigned tableSize = 1 << nbBits;
1066 const unsigned tableMask = tableSize - 1;
1067 const unsigned maxSymbolValue = tableMask;
1068 unsigned s;
1069
1070 /* Sanity checks */
1071 if (nbBits < 1) return (size_t)-FSE_ERROR_GENERIC; /* min size */
Yann Collet4856a002015-01-24 01:58:16 +01001072
1073 /* Build Decoding Table */
1074 base32[0] = nbBits;
1075 for (s=0; s<=maxSymbolValue; s++)
1076 {
1077 dinfo[s].newState = 0;
1078 dinfo[s].symbol = (BYTE)s;
1079 dinfo[s].nbBits = (BYTE)nbBits;
1080 }
1081
1082 return 0;
1083}
1084
1085
1086/* FSE_initDStream
1087 * Initialize a FSE_DStream_t.
1088 * srcBuffer must point at the beginning of an FSE block.
1089 * The function result is the size of the FSE_block (== srcSize).
1090 * If srcSize is too small, the function will return an errorCode;
1091 */
1092size_t FSE_initDStream(FSE_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
1093{
1094 if (srcSize < 1) return (size_t)-FSE_ERROR_srcSize_wrong;
1095
Yann Collet1efa31f2015-07-04 15:56:41 -08001096 if (srcSize >= sizeof(size_t))
Yann Collet4856a002015-01-24 01:58:16 +01001097 {
1098 U32 contain32;
Yann Collet213089c2015-06-18 07:43:16 -08001099 bitD->start = (const char*)srcBuffer;
Yann Collet1efa31f2015-07-04 15:56:41 -08001100 bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t);
Yann Collet4856a002015-01-24 01:58:16 +01001101 bitD->bitContainer = FSE_readLEST(bitD->ptr);
Yann Collet213089c2015-06-18 07:43:16 -08001102 contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
Yann Collet4856a002015-01-24 01:58:16 +01001103 if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */
1104 bitD->bitsConsumed = 8 - FSE_highbit32(contain32);
1105 }
1106 else
1107 {
1108 U32 contain32;
Yann Collet213089c2015-06-18 07:43:16 -08001109 bitD->start = (const char*)srcBuffer;
Yann Collet4856a002015-01-24 01:58:16 +01001110 bitD->ptr = bitD->start;
Yann Collet213089c2015-06-18 07:43:16 -08001111 bitD->bitContainer = *(const BYTE*)(bitD->start);
Yann Collet4856a002015-01-24 01:58:16 +01001112 switch(srcSize)
1113 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001114 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
1115 case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);
1116 case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);
1117 case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24;
1118 case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16;
1119 case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8;
Yann Collet4856a002015-01-24 01:58:16 +01001120 default:;
1121 }
Yann Collet213089c2015-06-18 07:43:16 -08001122 contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
Yann Collet4856a002015-01-24 01:58:16 +01001123 if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */
1124 bitD->bitsConsumed = 8 - FSE_highbit32(contain32);
Yann Collet1efa31f2015-07-04 15:56:41 -08001125 bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8;
Yann Collet4856a002015-01-24 01:58:16 +01001126 }
1127
1128 return srcSize;
1129}
1130
1131
1132/* FSE_readBits
1133 * Read next n bits from the bitContainer.
Yann Collet213089c2015-06-18 07:43:16 -08001134 * On 32-bits, don't read more than maxNbBits==25
1135 * On 64-bits, don't read more than maxNbBits==57
1136 * Use the fast variant *only* if n >= 1.
Yann Collet4856a002015-01-24 01:58:16 +01001137 * return : value extracted.
1138 */
Yann Collet1efa31f2015-07-04 15:56:41 -08001139size_t FSE_readBits(FSE_DStream_t* bitD, U32 nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001140{
Yann Collet1efa31f2015-07-04 15:56:41 -08001141 size_t value = ((bitD->bitContainer << (bitD->bitsConsumed & ((sizeof(size_t)*8)-1))) >> 1) >> (((sizeof(size_t)*8)-1)-nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001142 bitD->bitsConsumed += nbBits;
1143 return value;
1144}
1145
Yann Collet1efa31f2015-07-04 15:56:41 -08001146size_t FSE_readBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */
Yann Collet4856a002015-01-24 01:58:16 +01001147{
Yann Collet1efa31f2015-07-04 15:56:41 -08001148 size_t value = (bitD->bitContainer << bitD->bitsConsumed) >> ((sizeof(size_t)*8)-nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001149 bitD->bitsConsumed += nbBits;
1150 return value;
1151}
1152
1153unsigned FSE_reloadDStream(FSE_DStream_t* bitD)
1154{
Yann Collet1efa31f2015-07-04 15:56:41 -08001155 if (bitD->ptr >= bitD->start + sizeof(size_t))
Yann Collet4856a002015-01-24 01:58:16 +01001156 {
1157 bitD->ptr -= bitD->bitsConsumed >> 3;
1158 bitD->bitsConsumed &= 7;
1159 bitD->bitContainer = FSE_readLEST(bitD->ptr);
1160 return 0;
1161 }
1162 if (bitD->ptr == bitD->start)
1163 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001164 if (bitD->bitsConsumed < sizeof(size_t)*8) return 1;
1165 if (bitD->bitsConsumed == sizeof(size_t)*8) return 2;
Yann Collet4856a002015-01-24 01:58:16 +01001166 return 3;
1167 }
1168 {
1169 U32 nbBytes = bitD->bitsConsumed >> 3;
1170 if (bitD->ptr - nbBytes < bitD->start)
1171 nbBytes = (U32)(bitD->ptr - bitD->start); /* note : necessarily ptr > start */
1172 bitD->ptr -= nbBytes;
1173 bitD->bitsConsumed -= nbBytes*8;
1174 bitD->bitContainer = FSE_readLEST(bitD->ptr); /* note : necessarily srcSize > sizeof(bitD) */
1175 return (bitD->ptr == bitD->start);
1176 }
1177}
1178
1179
Yann Collet1efa31f2015-07-04 15:56:41 -08001180void FSE_initDState(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD, const FSE_DTable* dt)
Yann Collet4856a002015-01-24 01:58:16 +01001181{
Yann Collet1efa31f2015-07-04 15:56:41 -08001182 const U32* const base32 = (const U32*)dt;
Yann Collet4856a002015-01-24 01:58:16 +01001183 DStatePtr->state = FSE_readBits(bitD, base32[0]);
1184 FSE_reloadDStream(bitD);
1185 DStatePtr->table = base32 + 1;
1186}
1187
1188BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD)
1189{
1190 const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
1191 const U32 nbBits = DInfo.nbBits;
1192 BYTE symbol = DInfo.symbol;
Yann Collet1efa31f2015-07-04 15:56:41 -08001193 size_t lowBits = FSE_readBits(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001194
1195 DStatePtr->state = DInfo.newState + lowBits;
1196 return symbol;
1197}
1198
1199BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD)
1200{
1201 const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
1202 const U32 nbBits = DInfo.nbBits;
1203 BYTE symbol = DInfo.symbol;
Yann Collet1efa31f2015-07-04 15:56:41 -08001204 size_t lowBits = FSE_readBitsFast(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001205
1206 DStatePtr->state = DInfo.newState + lowBits;
1207 return symbol;
1208}
1209
1210/* FSE_endOfDStream
1211 Tells if bitD has reached end of bitStream or not */
1212
1213unsigned FSE_endOfDStream(const FSE_DStream_t* bitD)
1214{
Yann Collet1efa31f2015-07-04 15:56:41 -08001215 return ((bitD->ptr == bitD->start) && (bitD->bitsConsumed == sizeof(size_t)*8));
Yann Collet4856a002015-01-24 01:58:16 +01001216}
1217
Yann Collet1efa31f2015-07-04 15:56:41 -08001218unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
Yann Collet4856a002015-01-24 01:58:16 +01001219{
Yann Collet1efa31f2015-07-04 15:56:41 -08001220 return DStatePtr->state == 0;
Yann Collet4856a002015-01-24 01:58:16 +01001221}
1222
1223
1224FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
1225 void* dst, size_t maxDstSize,
1226 const void* cSrc, size_t cSrcSize,
Yann Collet1efa31f2015-07-04 15:56:41 -08001227 const FSE_DTable* dt, unsigned fast)
Yann Collet4856a002015-01-24 01:58:16 +01001228{
1229 BYTE* const ostart = (BYTE*) dst;
1230 BYTE* op = ostart;
1231 BYTE* const omax = op + maxDstSize;
1232 BYTE* const olimit = omax-3;
1233
1234 FSE_DStream_t bitD;
Yann Collet1efa31f2015-07-04 15:56:41 -08001235 FSE_DState_t state1;
1236 FSE_DState_t state2;
Yann Collet4856a002015-01-24 01:58:16 +01001237 size_t errorCode;
1238
1239 /* Init */
1240 errorCode = FSE_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
1241 if (FSE_isError(errorCode)) return errorCode;
1242
Yann Collet1efa31f2015-07-04 15:56:41 -08001243 FSE_initDState(&state1, &bitD, dt);
1244 FSE_initDState(&state2, &bitD, dt);
Yann Collet4856a002015-01-24 01:58:16 +01001245
1246
1247 /* 2 symbols per loop */
1248 while (!FSE_reloadDStream(&bitD) && (op<olimit))
1249 {
1250 *op++ = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
1251
Yann Collet1efa31f2015-07-04 15:56:41 -08001252 if (FSE_MAX_TABLELOG*2+7 > sizeof(size_t)*8) /* This test must be static */
Yann Collet4856a002015-01-24 01:58:16 +01001253 FSE_reloadDStream(&bitD);
1254
1255 *op++ = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
1256
Yann Collet1efa31f2015-07-04 15:56:41 -08001257 if (FSE_MAX_TABLELOG*4+7 < sizeof(size_t)*8) /* This test must be static */
Yann Collet4856a002015-01-24 01:58:16 +01001258 {
1259 *op++ = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
1260 *op++ = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
1261 }
1262 }
1263
1264 /* tail */
Yann Collet213089c2015-06-18 07:43:16 -08001265 /* note : FSE_reloadDStream(&bitD) >= 1; Ends at exactly 2 */
Yann Collet4856a002015-01-24 01:58:16 +01001266 while (1)
1267 {
Yann Collet213089c2015-06-18 07:43:16 -08001268 if ( (FSE_reloadDStream(&bitD)>2) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) )
Yann Collet4856a002015-01-24 01:58:16 +01001269 break;
1270
1271 *op++ = fast ? FSE_decodeSymbolFast(&state1, &bitD) : FSE_decodeSymbol(&state1, &bitD);
1272
Yann Collet213089c2015-06-18 07:43:16 -08001273 if ( (FSE_reloadDStream(&bitD)>2) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) )
Yann Collet4856a002015-01-24 01:58:16 +01001274 break;
1275
1276 *op++ = fast ? FSE_decodeSymbolFast(&state2, &bitD) : FSE_decodeSymbol(&state2, &bitD);
1277 }
1278
1279 /* end ? */
1280 if (FSE_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2) )
1281 return op-ostart;
1282
1283 if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
1284
1285 return (size_t)-FSE_ERROR_corruptionDetected;
1286}
1287
1288
1289size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
1290 const void* cSrc, size_t cSrcSize,
Yann Collet1efa31f2015-07-04 15:56:41 -08001291 const FSE_DTable* dt, size_t fastMode)
Yann Collet4856a002015-01-24 01:58:16 +01001292{
1293 /* select fast mode (static) */
Yann Collet1efa31f2015-07-04 15:56:41 -08001294 if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
1295 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
Yann Collet4856a002015-01-24 01:58:16 +01001296}
1297
1298
1299size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
1300{
1301 const BYTE* const istart = (const BYTE*)cSrc;
1302 const BYTE* ip = istart;
1303 short counting[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -08001304 DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
Yann Collet4856a002015-01-24 01:58:16 +01001305 unsigned tableLog;
Yann Collet1efa31f2015-07-04 15:56:41 -08001306 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
Yann Collet4856a002015-01-24 01:58:16 +01001307 size_t errorCode, fastMode;
1308
1309 if (cSrcSize<2) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */
1310
1311 /* normal FSE decoding mode */
Yann Collet1efa31f2015-07-04 15:56:41 -08001312 errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001313 if (FSE_isError(errorCode)) return errorCode;
1314 if (errorCode >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */
1315 ip += errorCode;
1316 cSrcSize -= errorCode;
1317
Yann Collet1efa31f2015-07-04 15:56:41 -08001318 fastMode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001319 if (FSE_isError(fastMode)) return fastMode;
1320
1321 /* always return, even if it is an error code */
Yann Collet1efa31f2015-07-04 15:56:41 -08001322 return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt, fastMode);
Yann Collet4856a002015-01-24 01:58:16 +01001323}
1324
1325
1326#endif /* FSE_COMMONDEFS_ONLY */
1327
1328/*
1329 2nd part of the file
1330 designed to be included
Yann Collet1efa31f2015-07-04 15:56:41 -08001331 for type-specific functions (template emulation in C)
1332 Objective is to write these functions only once, for improved maintenance
Yann Collet4856a002015-01-24 01:58:16 +01001333*/
1334
1335/* safety checks */
1336#ifndef FSE_FUNCTION_EXTENSION
1337# error "FSE_FUNCTION_EXTENSION must be defined"
1338#endif
1339#ifndef FSE_FUNCTION_TYPE
1340# error "FSE_FUNCTION_TYPE must be defined"
1341#endif
1342
1343/* Function names */
1344#define FSE_CAT(X,Y) X##Y
1345#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
1346#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
1347
1348
1349/* Function templates */
Yann Collet1efa31f2015-07-04 15:56:41 -08001350size_t FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION)
1351(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize, unsigned safe)
Yann Collet4856a002015-01-24 01:58:16 +01001352{
1353 const FSE_FUNCTION_TYPE* ip = source;
1354 const FSE_FUNCTION_TYPE* const iend = ip+sourceSize;
1355 unsigned maxSymbolValue = *maxSymbolValuePtr;
1356 unsigned max=0;
1357 int s;
1358
1359 U32 Counting1[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
1360 U32 Counting2[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
1361 U32 Counting3[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
1362 U32 Counting4[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
1363
1364 /* safety checks */
1365 if (!sourceSize)
1366 {
1367 memset(count, 0, (maxSymbolValue + 1) * sizeof(FSE_FUNCTION_TYPE));
1368 *maxSymbolValuePtr = 0;
1369 return 0;
1370 }
1371 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_GENERIC; /* maxSymbolValue too large : unsupported */
1372 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE; /* 0 == default */
1373
1374 if ((safe) || (sizeof(FSE_FUNCTION_TYPE)>1))
1375 {
1376 /* check input values, to avoid count table overflow */
1377 while (ip < iend-3)
1378 {
1379 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting1[*ip++]++;
1380 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting2[*ip++]++;
1381 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting3[*ip++]++;
1382 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting4[*ip++]++;
1383 }
1384 }
1385 else
1386 {
1387 U32 cached = FSE_read32(ip); ip += 4;
1388 while (ip < iend-15)
1389 {
1390 U32 c = cached; cached = FSE_read32(ip); ip += 4;
1391 Counting1[(BYTE) c ]++;
1392 Counting2[(BYTE)(c>>8) ]++;
1393 Counting3[(BYTE)(c>>16)]++;
1394 Counting4[ c>>24 ]++;
1395 c = cached; cached = FSE_read32(ip); ip += 4;
1396 Counting1[(BYTE) c ]++;
1397 Counting2[(BYTE)(c>>8) ]++;
1398 Counting3[(BYTE)(c>>16)]++;
1399 Counting4[ c>>24 ]++;
1400 c = cached; cached = FSE_read32(ip); ip += 4;
1401 Counting1[(BYTE) c ]++;
1402 Counting2[(BYTE)(c>>8) ]++;
1403 Counting3[(BYTE)(c>>16)]++;
1404 Counting4[ c>>24 ]++;
1405 c = cached; cached = FSE_read32(ip); ip += 4;
1406 Counting1[(BYTE) c ]++;
1407 Counting2[(BYTE)(c>>8) ]++;
1408 Counting3[(BYTE)(c>>16)]++;
1409 Counting4[ c>>24 ]++;
1410 }
1411 ip-=4;
1412 }
1413
1414 /* finish last symbols */
1415 while (ip<iend) { if ((safe) && (*ip>maxSymbolValue)) return (size_t)-FSE_ERROR_GENERIC; Counting1[*ip++]++; }
1416
1417 for (s=0; s<=(int)maxSymbolValue; s++)
1418 {
1419 count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
1420 if (count[s] > max) max = count[s];
1421 }
1422
1423 while (!count[maxSymbolValue]) maxSymbolValue--;
1424 *maxSymbolValuePtr = maxSymbolValue;
Yann Collet1efa31f2015-07-04 15:56:41 -08001425 return (size_t)max;
Yann Collet4856a002015-01-24 01:58:16 +01001426}
1427
1428/* hidden fast variant (unsafe) */
Yann Collet1efa31f2015-07-04 15:56:41 -08001429size_t FSE_FUNCTION_NAME(FSE_countFast, FSE_FUNCTION_EXTENSION)
1430(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
Yann Collet4856a002015-01-24 01:58:16 +01001431{
Yann Collet1efa31f2015-07-04 15:56:41 -08001432 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 0);
Yann Collet4856a002015-01-24 01:58:16 +01001433}
1434
Yann Collet1efa31f2015-07-04 15:56:41 -08001435size_t FSE_FUNCTION_NAME(FSE_count, FSE_FUNCTION_EXTENSION)
1436(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
Yann Collet4856a002015-01-24 01:58:16 +01001437{
1438 if ((sizeof(FSE_FUNCTION_TYPE)==1) && (*maxSymbolValuePtr >= 255))
1439 {
1440 *maxSymbolValuePtr = 255;
Yann Collet1efa31f2015-07-04 15:56:41 -08001441 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 0);
Yann Collet4856a002015-01-24 01:58:16 +01001442 }
Yann Collet1efa31f2015-07-04 15:56:41 -08001443 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 1);
Yann Collet4856a002015-01-24 01:58:16 +01001444}
1445
1446
1447static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; }
1448
1449size_t FSE_FUNCTION_NAME(FSE_buildCTable, FSE_FUNCTION_EXTENSION)
Yann Collet1efa31f2015-07-04 15:56:41 -08001450(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +01001451{
1452 const unsigned tableSize = 1 << tableLog;
1453 const unsigned tableMask = tableSize - 1;
Yann Collet1efa31f2015-07-04 15:56:41 -08001454 U16* tableU16 = ( (U16*) ct) + 2;
1455 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) (((U32*)ct) + 1 + (tableLog ? tableSize>>1 : 1) );
Yann Collet4856a002015-01-24 01:58:16 +01001456 const unsigned step = FSE_tableStep(tableSize);
1457 unsigned cumul[FSE_MAX_SYMBOL_VALUE+2];
1458 U32 position = 0;
Yann Collet1efa31f2015-07-04 15:56:41 -08001459 FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE] = {0}; /* should not be necessary, but analyzer complain without it, and performance loss is negligible with it */
Yann Collet4856a002015-01-24 01:58:16 +01001460 U32 highThreshold = tableSize-1;
1461 unsigned symbol;
1462 unsigned i;
1463
Yann Collet4856a002015-01-24 01:58:16 +01001464 /* header */
1465 tableU16[-2] = (U16) tableLog;
1466 tableU16[-1] = (U16) maxSymbolValue;
1467
1468 /* For explanations on how to distribute symbol values over the table :
1469 * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
1470
1471 /* symbol start positions */
1472 cumul[0] = 0;
1473 for (i=1; i<=maxSymbolValue+1; i++)
1474 {
1475 if (normalizedCounter[i-1]==-1) /* Low prob symbol */
1476 {
1477 cumul[i] = cumul[i-1] + 1;
1478 tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(i-1);
1479 }
1480 else
1481 cumul[i] = cumul[i-1] + normalizedCounter[i-1];
1482 }
1483 cumul[maxSymbolValue+1] = tableSize+1;
1484
1485 /* Spread symbols */
1486 for (symbol=0; symbol<=maxSymbolValue; symbol++)
1487 {
1488 int nbOccurences;
1489 for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++)
1490 {
1491 tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
1492 position = (position + step) & tableMask;
1493 while (position > highThreshold) position = (position + step) & tableMask; /* Lowprob area */
1494 }
1495 }
1496
1497 if (position!=0) return (size_t)-FSE_ERROR_GENERIC; /* Must have gone through all positions */
1498
1499 /* Build table */
1500 for (i=0; i<tableSize; i++)
1501 {
1502 FSE_FUNCTION_TYPE s = tableSymbol[i];
Yann Collet1efa31f2015-07-04 15:56:41 -08001503 tableU16[cumul[s]++] = (U16) (tableSize+i); /* Table U16 : sorted by symbol order; gives next state value */
Yann Collet4856a002015-01-24 01:58:16 +01001504 }
1505
Yann Collet1efa31f2015-07-04 15:56:41 -08001506 /* Build Symbol Transformation Table */
Yann Collet4856a002015-01-24 01:58:16 +01001507 {
1508 unsigned s;
1509 unsigned total = 0;
1510 for (s=0; s<=maxSymbolValue; s++)
1511 {
1512 switch (normalizedCounter[s])
1513 {
1514 case 0:
1515 break;
1516 case -1:
1517 case 1:
1518 symbolTT[s].minBitsOut = (BYTE)tableLog;
1519 symbolTT[s].deltaFindState = total - 1;
1520 total ++;
1521 symbolTT[s].maxState = (U16)( (tableSize*2) - 1); /* ensures state <= maxState */
1522 break;
1523 default :
1524 symbolTT[s].minBitsOut = (BYTE)( (tableLog-1) - FSE_highbit32 (normalizedCounter[s]-1) );
1525 symbolTT[s].deltaFindState = total - normalizedCounter[s];
1526 total += normalizedCounter[s];
1527 symbolTT[s].maxState = (U16)( (normalizedCounter[s] << (symbolTT[s].minBitsOut+1)) - 1);
1528 }
1529 }
1530 }
1531
1532 return 0;
1533}
1534
1535
1536#define FSE_DECODE_TYPE FSE_TYPE_NAME(FSE_decode_t, FSE_FUNCTION_EXTENSION)
1537
Yann Collet1efa31f2015-07-04 15:56:41 -08001538FSE_DTable* FSE_FUNCTION_NAME(FSE_createDTable, FSE_FUNCTION_EXTENSION) (unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +01001539{
1540 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
Yann Collet1efa31f2015-07-04 15:56:41 -08001541 return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
Yann Collet4856a002015-01-24 01:58:16 +01001542}
1543
Yann Collet1efa31f2015-07-04 15:56:41 -08001544void FSE_FUNCTION_NAME(FSE_freeDTable, FSE_FUNCTION_EXTENSION) (FSE_DTable* dt)
Yann Collet4856a002015-01-24 01:58:16 +01001545{
Yann Collet1efa31f2015-07-04 15:56:41 -08001546 free(dt);
Yann Collet4856a002015-01-24 01:58:16 +01001547}
1548
1549
1550size_t FSE_FUNCTION_NAME(FSE_buildDTable, FSE_FUNCTION_EXTENSION)
Yann Collet1efa31f2015-07-04 15:56:41 -08001551(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +01001552{
Yann Collet1efa31f2015-07-04 15:56:41 -08001553 U32* const base32 = (U32*)dt;
Yann Collet4856a002015-01-24 01:58:16 +01001554 FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (base32+1);
1555 const U32 tableSize = 1 << tableLog;
1556 const U32 tableMask = tableSize-1;
1557 const U32 step = FSE_tableStep(tableSize);
1558 U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
1559 U32 position = 0;
1560 U32 highThreshold = tableSize-1;
Yann Collet213089c2015-06-18 07:43:16 -08001561 const S16 largeLimit= (S16)(1 << (tableLog-1));
Yann Collet4856a002015-01-24 01:58:16 +01001562 U32 noLarge = 1;
1563 U32 s;
1564
1565 /* Sanity Checks */
1566 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_maxSymbolValue_tooLarge;
1567 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_tableLog_tooLarge;
1568
1569 /* Init, lay down lowprob symbols */
1570 base32[0] = tableLog;
1571 for (s=0; s<=maxSymbolValue; s++)
1572 {
1573 if (normalizedCounter[s]==-1)
1574 {
1575 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
1576 symbolNext[s] = 1;
1577 }
1578 else
1579 {
1580 if (normalizedCounter[s] >= largeLimit) noLarge=0;
1581 symbolNext[s] = normalizedCounter[s];
1582 }
1583 }
1584
1585 /* Spread symbols */
1586 for (s=0; s<=maxSymbolValue; s++)
1587 {
1588 int i;
1589 for (i=0; i<normalizedCounter[s]; i++)
1590 {
1591 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
1592 position = (position + step) & tableMask;
1593 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
1594 }
1595 }
1596
1597 if (position!=0) return (size_t)-FSE_ERROR_GENERIC; /* position must reach all cells once, otherwise normalizedCounter is incorrect */
1598
1599 /* Build Decoding table */
1600 {
1601 U32 i;
1602 for (i=0; i<tableSize; i++)
1603 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001604 FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[i].symbol);
Yann Collet4856a002015-01-24 01:58:16 +01001605 U16 nextState = symbolNext[symbol]++;
1606 tableDecode[i].nbBits = (BYTE) (tableLog - FSE_highbit32 ((U32)nextState) );
1607 tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize);
1608 }
1609 }
1610
1611 return noLarge;
1612}