blob: a577e81ecb219d56d5164378c52305ba87f3b055 [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/****************************************************************
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
59
Yann Collete8c6bb12015-07-26 00:23:57 +010060
61/****************************************************************
62* Byte symbol type
63****************************************************************/
64typedef struct
65{
66 unsigned short newState;
67 unsigned char symbol;
68 unsigned char nbBits;
69} FSE_decode_t; /* size == U32 */
70
Yann Collet4856a002015-01-24 01:58:16 +010071#endif /* !FSE_COMMONDEFS_ONLY */
72
73
74/****************************************************************
75* Compiler specifics
76****************************************************************/
77#ifdef _MSC_VER /* Visual Studio */
78# define FORCE_INLINE static __forceinline
79# include <intrin.h> /* For Visual 2005 */
80# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
81# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
82#else
83# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
84# ifdef __GNUC__
85# define FORCE_INLINE static inline __attribute__((always_inline))
86# else
87# define FORCE_INLINE static inline
88# endif
89#endif
90
91
92/****************************************************************
93* Includes
94****************************************************************/
95#include <stdlib.h> /* malloc, free, qsort */
96#include <string.h> /* memcpy, memset */
97#include <stdio.h> /* printf (debug) */
98#include "fse_static.h"
99
100
Yann Colletad68a0e2015-02-26 00:29:15 +0100101#ifndef MEM_ACCESS_MODULE
102#define MEM_ACCESS_MODULE
Yann Collet4856a002015-01-24 01:58:16 +0100103/****************************************************************
104* Basic Types
105*****************************************************************/
106#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
107# include <stdint.h>
108typedef uint8_t BYTE;
109typedef uint16_t U16;
110typedef int16_t S16;
111typedef uint32_t U32;
112typedef int32_t S32;
113typedef uint64_t U64;
114typedef int64_t S64;
115#else
116typedef unsigned char BYTE;
117typedef unsigned short U16;
118typedef signed short S16;
119typedef unsigned int U32;
120typedef signed int S32;
121typedef unsigned long long U64;
122typedef signed long long S64;
123#endif
124
Yann Colletad68a0e2015-02-26 00:29:15 +0100125#endif /* MEM_ACCESS_MODULE */
Yann Collet4856a002015-01-24 01:58:16 +0100126
127/****************************************************************
128* Memory I/O
129*****************************************************************/
Yann Collet23743532015-08-19 23:53:56 +0100130/* FSE_FORCE_MEMORY_ACCESS
131 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
132 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
133 * The below switch allow to select different access method for improved performance.
134 * Method 0 (default) : use `memcpy()`. Safe and portable.
135 * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
136 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
137 * Method 2 : direct access. This method is portable but violate C standard.
138 * It can generate buggy code on targets which generate assembly depending on alignment.
139 * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
140 * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
141 * Prefer these methods in priority order (0 > 1 > 2)
142 */
143#ifndef FSE_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
144# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
145# define FSE_FORCE_MEMORY_ACCESS 2
146# elif defined(__INTEL_COMPILER) || \
147 (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
148# define FSE_FORCE_MEMORY_ACCESS 1
149# endif
150#endif
151
152
Yann Collete8c6bb12015-07-26 00:23:57 +0100153static unsigned FSE_32bits(void)
154{
155 return sizeof(void*)==4;
156}
157
Yann Collet4856a002015-01-24 01:58:16 +0100158static unsigned FSE_isLittleEndian(void)
159{
160 const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
161 return one.c[0];
162}
163
Yann Collet23743532015-08-19 23:53:56 +0100164#if defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==2)
165
166static U16 FSE_read16(const void* memPtr) { return *(const U16*) memPtr; }
167static U32 FSE_read32(const void* memPtr) { return *(const U32*) memPtr; }
168static U64 FSE_read64(const void* memPtr) { return *(const U64*) memPtr; }
169
170static void FSE_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
171static void FSE_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
172static void FSE_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
173
174#elif defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==1)
175
176/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
177/* currently only defined for gcc and icc */
178typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign;
179
180static U16 FSE_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
181static U32 FSE_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
182static U64 FSE_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
183
184static void FSE_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
185static void FSE_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
186static void FSE_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 = value; }
187
188#else
189
Yann Collet138db212015-07-27 20:19:21 +0100190static U16 FSE_read16(const void* memPtr)
191{
Yann Collet23743532015-08-19 23:53:56 +0100192 U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
Yann Collet138db212015-07-27 20:19:21 +0100193}
194
Yann Collet23743532015-08-19 23:53:56 +0100195static U32 FSE_read32(const void* memPtr)
196{
197 U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
198}
199
200static U64 FSE_read64(const void* memPtr)
201{
202 U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
203}
204
205static void FSE_write16(void* memPtr, U16 value)
206{
207 memcpy(memPtr, &value, sizeof(value));
208}
209
210static void FSE_write32(void* memPtr, U32 value)
211{
212 memcpy(memPtr, &value, sizeof(value));
213}
214
215static void FSE_write64(void* memPtr, U64 value)
216{
217 memcpy(memPtr, &value, sizeof(value));
218}
219
220#endif // FSE_FORCE_MEMORY_ACCESS
221
Yann Collet138db212015-07-27 20:19:21 +0100222static U16 FSE_readLE16(const void* memPtr)
223{
224 if (FSE_isLittleEndian())
225 return FSE_read16(memPtr);
226 else
227 {
228 const BYTE* p = (const BYTE*)memPtr;
229 return (U16)(p[0] + (p[1]<<8));
230 }
231}
232
233static void FSE_writeLE16(void* memPtr, U16 val)
234{
235 if (FSE_isLittleEndian())
236 {
Yann Collet23743532015-08-19 23:53:56 +0100237 FSE_write16(memPtr, val);
Yann Collet138db212015-07-27 20:19:21 +0100238 }
239 else
240 {
241 BYTE* p = (BYTE*)memPtr;
242 p[0] = (BYTE)val;
243 p[1] = (BYTE)(val>>8);
244 }
245}
246
Yann Collet4856a002015-01-24 01:58:16 +0100247static U32 FSE_readLE32(const void* memPtr)
248{
249 if (FSE_isLittleEndian())
250 return FSE_read32(memPtr);
251 else
252 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100253 const BYTE* p = (const BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100254 return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24));
255 }
256}
257
258static void FSE_writeLE32(void* memPtr, U32 val32)
259{
260 if (FSE_isLittleEndian())
261 {
Yann Collet23743532015-08-19 23:53:56 +0100262 FSE_write32(memPtr, val32);
Yann Collet4856a002015-01-24 01:58:16 +0100263 }
264 else
265 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100266 BYTE* p = (BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100267 p[0] = (BYTE)val32;
268 p[1] = (BYTE)(val32>>8);
269 p[2] = (BYTE)(val32>>16);
270 p[3] = (BYTE)(val32>>24);
271 }
272}
273
Yann Collet4856a002015-01-24 01:58:16 +0100274static U64 FSE_readLE64(const void* memPtr)
275{
276 if (FSE_isLittleEndian())
277 return FSE_read64(memPtr);
278 else
279 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100280 const BYTE* p = (const BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100281 return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24)
282 + ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56));
283 }
284}
285
286static void FSE_writeLE64(void* memPtr, U64 val64)
287{
288 if (FSE_isLittleEndian())
289 {
Yann Collet23743532015-08-19 23:53:56 +0100290 FSE_write64(memPtr, val64);
Yann Collet4856a002015-01-24 01:58:16 +0100291 }
292 else
293 {
Yann Collet1cc58de2015-01-29 07:13:54 +0100294 BYTE* p = (BYTE*)memPtr;
Yann Collet4856a002015-01-24 01:58:16 +0100295 p[0] = (BYTE)val64;
296 p[1] = (BYTE)(val64>>8);
297 p[2] = (BYTE)(val64>>16);
298 p[3] = (BYTE)(val64>>24);
299 p[4] = (BYTE)(val64>>32);
300 p[5] = (BYTE)(val64>>40);
301 p[6] = (BYTE)(val64>>48);
302 p[7] = (BYTE)(val64>>56);
303 }
304}
305
306static size_t FSE_readLEST(const void* memPtr)
307{
Yann Collete8c6bb12015-07-26 00:23:57 +0100308 if (FSE_32bits())
Yann Colletfb814172015-01-25 13:19:12 +0100309 return (size_t)FSE_readLE32(memPtr);
Yann Collet4856a002015-01-24 01:58:16 +0100310 else
Yann Colletfb814172015-01-25 13:19:12 +0100311 return (size_t)FSE_readLE64(memPtr);
Yann Collet4856a002015-01-24 01:58:16 +0100312}
313
314static void FSE_writeLEST(void* memPtr, size_t val)
315{
Yann Collete8c6bb12015-07-26 00:23:57 +0100316 if (FSE_32bits())
Yann Collet4856a002015-01-24 01:58:16 +0100317 FSE_writeLE32(memPtr, (U32)val);
318 else
319 FSE_writeLE64(memPtr, (U64)val);
320}
321
322
323/****************************************************************
324* Constants
325*****************************************************************/
326#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
327#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
328#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
329#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
330#define FSE_MIN_TABLELOG 5
331
332#define FSE_TABLELOG_ABSOLUTE_MAX 15
333#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
334#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
335#endif
336
337
338/****************************************************************
339* Error Management
340****************************************************************/
341#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
342
343
344/****************************************************************
345* Complex types
346****************************************************************/
347typedef struct
348{
Yann Collet77c82b62015-08-02 01:19:09 +0100349 int deltaFindState;
350 U32 deltaNbBits;
351} FSE_symbolCompressionTransform; /* total 8 bytes */
Yann Collet4856a002015-01-24 01:58:16 +0100352
Yann Collet1efa31f2015-07-04 15:56:41 -0800353typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
354typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
Yann Collet4856a002015-01-24 01:58:16 +0100355
356/****************************************************************
357* Internal functions
358****************************************************************/
359FORCE_INLINE unsigned FSE_highbit32 (register U32 val)
360{
361# if defined(_MSC_VER) /* Visual */
362 unsigned long r;
363 _BitScanReverse ( &r, val );
364 return (unsigned) r;
365# elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */
366 return 31 - __builtin_clz (val);
367# else /* Software version */
368 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 };
369 U32 v = val;
370 unsigned r;
371 v |= v >> 1;
372 v |= v >> 2;
373 v |= v >> 4;
374 v |= v >> 8;
375 v |= v >> 16;
376 r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
377 return r;
378# endif
379}
380
381
Yann Collete8c6bb12015-07-26 00:23:57 +0100382/****************************************************************
383* Templates
384****************************************************************/
385/*
386 designed to be included
387 for type-specific functions (template emulation in C)
388 Objective is to write these functions only once, for improved maintenance
389*/
390
391/* safety checks */
392#ifndef FSE_FUNCTION_EXTENSION
393# error "FSE_FUNCTION_EXTENSION must be defined"
394#endif
395#ifndef FSE_FUNCTION_TYPE
396# error "FSE_FUNCTION_TYPE must be defined"
397#endif
398
399/* Function names */
400#define FSE_CAT(X,Y) X##Y
401#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
402#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
403
404
405/* Function templates */
406size_t FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION)
407(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize, unsigned safe)
408{
409 const FSE_FUNCTION_TYPE* ip = source;
410 const FSE_FUNCTION_TYPE* const iend = ip+sourceSize;
411 unsigned maxSymbolValue = *maxSymbolValuePtr;
412 unsigned max=0;
413 int s;
414
415 U32 Counting1[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
416 U32 Counting2[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
417 U32 Counting3[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
418 U32 Counting4[FSE_MAX_SYMBOL_VALUE+1] = { 0 };
419
420 /* safety checks */
421 if (!sourceSize)
422 {
423 memset(count, 0, (maxSymbolValue + 1) * sizeof(FSE_FUNCTION_TYPE));
424 *maxSymbolValuePtr = 0;
425 return 0;
426 }
427 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_GENERIC; /* maxSymbolValue too large : unsupported */
428 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE; /* 0 == default */
429
430 if ((safe) || (sizeof(FSE_FUNCTION_TYPE)>1))
431 {
432 /* check input values, to avoid count table overflow */
433 while (ip < iend-3)
434 {
435 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting1[*ip++]++;
436 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting2[*ip++]++;
437 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting3[*ip++]++;
438 if (*ip>maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; Counting4[*ip++]++;
439 }
440 }
441 else
442 {
443 U32 cached = FSE_read32(ip); ip += 4;
444 while (ip < iend-15)
445 {
446 U32 c = cached; cached = FSE_read32(ip); ip += 4;
447 Counting1[(BYTE) c ]++;
448 Counting2[(BYTE)(c>>8) ]++;
449 Counting3[(BYTE)(c>>16)]++;
450 Counting4[ c>>24 ]++;
451 c = cached; cached = FSE_read32(ip); ip += 4;
452 Counting1[(BYTE) c ]++;
453 Counting2[(BYTE)(c>>8) ]++;
454 Counting3[(BYTE)(c>>16)]++;
455 Counting4[ c>>24 ]++;
456 c = cached; cached = FSE_read32(ip); ip += 4;
457 Counting1[(BYTE) c ]++;
458 Counting2[(BYTE)(c>>8) ]++;
459 Counting3[(BYTE)(c>>16)]++;
460 Counting4[ c>>24 ]++;
461 c = cached; cached = FSE_read32(ip); ip += 4;
462 Counting1[(BYTE) c ]++;
463 Counting2[(BYTE)(c>>8) ]++;
464 Counting3[(BYTE)(c>>16)]++;
465 Counting4[ c>>24 ]++;
466 }
467 ip-=4;
468 }
469
470 /* finish last symbols */
471 while (ip<iend) { if ((safe) && (*ip>maxSymbolValue)) return (size_t)-FSE_ERROR_GENERIC; Counting1[*ip++]++; }
472
473 for (s=0; s<=(int)maxSymbolValue; s++)
474 {
475 count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
476 if (count[s] > max) max = count[s];
477 }
478
479 while (!count[maxSymbolValue]) maxSymbolValue--;
480 *maxSymbolValuePtr = maxSymbolValue;
481 return (size_t)max;
482}
483
484/* hidden fast variant (unsafe) */
485size_t FSE_FUNCTION_NAME(FSE_countFast, FSE_FUNCTION_EXTENSION)
486(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
487{
488 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 0);
489}
490
491size_t FSE_FUNCTION_NAME(FSE_count, FSE_FUNCTION_EXTENSION)
492(unsigned* count, unsigned* maxSymbolValuePtr, const FSE_FUNCTION_TYPE* source, size_t sourceSize)
493{
494 if ((sizeof(FSE_FUNCTION_TYPE)==1) && (*maxSymbolValuePtr >= 255))
495 {
496 *maxSymbolValuePtr = 255;
497 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 0);
498 }
499 return FSE_FUNCTION_NAME(FSE_count_generic, FSE_FUNCTION_EXTENSION) (count, maxSymbolValuePtr, source, sourceSize, 1);
500}
501
502
503static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; }
504
505size_t FSE_FUNCTION_NAME(FSE_buildCTable, FSE_FUNCTION_EXTENSION)
506(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
507{
508 const unsigned tableSize = 1 << tableLog;
509 const unsigned tableMask = tableSize - 1;
510 U16* tableU16 = ( (U16*) ct) + 2;
511 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) (((U32*)ct) + 1 + (tableLog ? tableSize>>1 : 1) );
512 const unsigned step = FSE_tableStep(tableSize);
513 unsigned cumul[FSE_MAX_SYMBOL_VALUE+2];
514 U32 position = 0;
515 FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* init not necessary, but analyzer complain about it */
516 U32 highThreshold = tableSize-1;
517 unsigned symbol;
518 unsigned i;
519
520 /* header */
521 tableU16[-2] = (U16) tableLog;
522 tableU16[-1] = (U16) maxSymbolValue;
523
524 /* For explanations on how to distribute symbol values over the table :
525 * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
526
527 /* symbol start positions */
528 cumul[0] = 0;
529 for (i=1; i<=maxSymbolValue+1; i++)
530 {
531 if (normalizedCounter[i-1]==-1) /* Low prob symbol */
532 {
533 cumul[i] = cumul[i-1] + 1;
534 tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(i-1);
535 }
536 else
537 cumul[i] = cumul[i-1] + normalizedCounter[i-1];
538 }
539 cumul[maxSymbolValue+1] = tableSize+1;
540
541 /* Spread symbols */
542 for (symbol=0; symbol<=maxSymbolValue; symbol++)
543 {
544 int nbOccurences;
545 for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++)
546 {
547 tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
548 position = (position + step) & tableMask;
549 while (position > highThreshold) position = (position + step) & tableMask; /* Lowprob area */
550 }
551 }
552
553 if (position!=0) return (size_t)-FSE_ERROR_GENERIC; /* Must have gone through all positions */
554
555 /* Build table */
556 for (i=0; i<tableSize; i++)
557 {
558 FSE_FUNCTION_TYPE s = tableSymbol[i]; /* static analyzer doesn't understand tableSymbol is properly initialized */
Yann Colleta7875502015-08-07 15:21:00 +0100559 tableU16[cumul[s]++] = (U16) (tableSize+i); /* TableU16 : sorted by symbol order; gives next state value */
Yann Collete8c6bb12015-07-26 00:23:57 +0100560 }
561
562 /* Build Symbol Transformation Table */
563 {
564 unsigned s;
565 unsigned total = 0;
566 for (s=0; s<=maxSymbolValue; s++)
567 {
568 switch (normalizedCounter[s])
569 {
Yann Collet77c82b62015-08-02 01:19:09 +0100570 case 0:
Yann Collete8c6bb12015-07-26 00:23:57 +0100571 break;
572 case -1:
Yann Collet77c82b62015-08-02 01:19:09 +0100573 case 1:
Yann Colleta7875502015-08-07 15:21:00 +0100574 symbolTT[s].deltaNbBits = tableLog << 16;
Yann Collete8c6bb12015-07-26 00:23:57 +0100575 symbolTT[s].deltaFindState = total - 1;
576 total ++;
Yann Collete8c6bb12015-07-26 00:23:57 +0100577 break;
578 default :
Yann Collet77c82b62015-08-02 01:19:09 +0100579 {
580 U32 maxBitsOut = tableLog - FSE_highbit32 (normalizedCounter[s]-1);
581 U32 minStatePlus = normalizedCounter[s] << maxBitsOut;
582 symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
583 symbolTT[s].deltaFindState = total - normalizedCounter[s];
584 total += normalizedCounter[s];
585 }
Yann Collete8c6bb12015-07-26 00:23:57 +0100586 }
587 }
588 }
589
590 return 0;
591}
592
593
594#define FSE_DECODE_TYPE FSE_TYPE_NAME(FSE_decode_t, FSE_FUNCTION_EXTENSION)
595
596FSE_DTable* FSE_FUNCTION_NAME(FSE_createDTable, FSE_FUNCTION_EXTENSION) (unsigned tableLog)
597{
598 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
599 return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
600}
601
602void FSE_FUNCTION_NAME(FSE_freeDTable, FSE_FUNCTION_EXTENSION) (FSE_DTable* dt)
603{
604 free(dt);
605}
606
Yann Colleta7875502015-08-07 15:21:00 +0100607typedef struct {
608 U16 tableLog;
609 U16 fastMode;
610} FSE_DTableHeader; /* sizeof U32 */
Yann Collete8c6bb12015-07-26 00:23:57 +0100611
612size_t FSE_FUNCTION_NAME(FSE_buildDTable, FSE_FUNCTION_EXTENSION)
613(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
614{
Yann Colleta7875502015-08-07 15:21:00 +0100615 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)dt;
616 FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (dt+1); /* because dt is unsigned, 32-bits aligned on 32-bits */
Yann Collete8c6bb12015-07-26 00:23:57 +0100617 const U32 tableSize = 1 << tableLog;
618 const U32 tableMask = tableSize-1;
619 const U32 step = FSE_tableStep(tableSize);
620 U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
621 U32 position = 0;
622 U32 highThreshold = tableSize-1;
623 const S16 largeLimit= (S16)(1 << (tableLog-1));
624 U32 noLarge = 1;
625 U32 s;
626
627 /* Sanity Checks */
628 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_maxSymbolValue_tooLarge;
629 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_tableLog_tooLarge;
630
631 /* Init, lay down lowprob symbols */
Yann Colleta7875502015-08-07 15:21:00 +0100632 DTableH[0].tableLog = (U16)tableLog;
Yann Collete8c6bb12015-07-26 00:23:57 +0100633 for (s=0; s<=maxSymbolValue; s++)
634 {
635 if (normalizedCounter[s]==-1)
636 {
637 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
638 symbolNext[s] = 1;
639 }
640 else
641 {
642 if (normalizedCounter[s] >= largeLimit) noLarge=0;
643 symbolNext[s] = normalizedCounter[s];
644 }
645 }
646
647 /* Spread symbols */
648 for (s=0; s<=maxSymbolValue; s++)
649 {
650 int i;
651 for (i=0; i<normalizedCounter[s]; i++)
652 {
653 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
654 position = (position + step) & tableMask;
655 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
656 }
657 }
658
659 if (position!=0) return (size_t)-FSE_ERROR_GENERIC; /* position must reach all cells once, otherwise normalizedCounter is incorrect */
660
661 /* Build Decoding table */
662 {
663 U32 i;
664 for (i=0; i<tableSize; i++)
665 {
666 FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[i].symbol);
667 U16 nextState = symbolNext[symbol]++;
668 tableDecode[i].nbBits = (BYTE) (tableLog - FSE_highbit32 ((U32)nextState) );
669 tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize);
670 }
671 }
672
Yann Colleta7875502015-08-07 15:21:00 +0100673 DTableH->fastMode = (U16)noLarge;
674 return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +0100675}
676
677
678/******************************************
679* FSE byte symbol
680******************************************/
Yann Collet4856a002015-01-24 01:58:16 +0100681#ifndef FSE_COMMONDEFS_ONLY
682
683unsigned FSE_isError(size_t code) { return (code > (size_t)(-FSE_ERROR_maxCode)); }
684
685#define FSE_GENERATE_STRING(STRING) #STRING,
686static const char* FSE_errorStrings[] = { FSE_LIST_ERRORS(FSE_GENERATE_STRING) };
687
688const char* FSE_getErrorName(size_t code)
689{
690 static const char* codeError = "Unspecified error code";
691 if (FSE_isError(code)) return FSE_errorStrings[-(int)(code)];
692 return codeError;
693}
694
695static short FSE_abs(short a)
696{
697 return a<0? -a : a;
698}
699
700
701/****************************************************************
702* Header bitstream management
703****************************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -0800704size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100705{
Yann Collet997f9ee2015-08-21 02:44:20 +0100706 size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
Yann Collet23743532015-08-19 23:53:56 +0100707 return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
Yann Collet4856a002015-01-24 01:58:16 +0100708}
709
Yann Collet1efa31f2015-07-04 15:56:41 -0800710static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
Yann Collet4856a002015-01-24 01:58:16 +0100711 const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
Yann Collet23743532015-08-19 23:53:56 +0100712 unsigned writeIsSafe)
Yann Collet4856a002015-01-24 01:58:16 +0100713{
714 BYTE* const ostart = (BYTE*) header;
715 BYTE* out = ostart;
716 BYTE* const oend = ostart + headerBufferSize;
717 int nbBits;
718 const int tableSize = 1 << tableLog;
719 int remaining;
720 int threshold;
721 U32 bitStream;
722 int bitCount;
723 unsigned charnum = 0;
724 int previous0 = 0;
725
726 bitStream = 0;
727 bitCount = 0;
728 /* Table Size */
729 bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
730 bitCount += 4;
731
732 /* Init */
733 remaining = tableSize+1; /* +1 for extra accuracy */
734 threshold = tableSize;
735 nbBits = tableLog+1;
736
737 while (remaining>1) /* stops at 1 */
738 {
739 if (previous0)
740 {
741 unsigned start = charnum;
742 while (!normalizedCounter[charnum]) charnum++;
743 while (charnum >= start+24)
744 {
745 start+=24;
Yann Collet213089c2015-06-18 07:43:16 -0800746 bitStream += 0xFFFFU << bitCount;
Yann Collet23743532015-08-19 23:53:56 +0100747 if ((!writeIsSafe) && (out > oend-2)) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* Buffer overflow */
Yann Collet213089c2015-06-18 07:43:16 -0800748 out[0] = (BYTE) bitStream;
Yann Collet4856a002015-01-24 01:58:16 +0100749 out[1] = (BYTE)(bitStream>>8);
750 out+=2;
751 bitStream>>=16;
752 }
753 while (charnum >= start+3)
754 {
755 start+=3;
756 bitStream += 3 << bitCount;
757 bitCount += 2;
758 }
759 bitStream += (charnum-start) << bitCount;
760 bitCount += 2;
761 if (bitCount>16)
762 {
Yann Collet23743532015-08-19 23:53:56 +0100763 if ((!writeIsSafe) && (out > oend - 2)) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100764 out[0] = (BYTE)bitStream;
765 out[1] = (BYTE)(bitStream>>8);
766 out += 2;
767 bitStream >>= 16;
768 bitCount -= 16;
769 }
770 }
771 {
772 short count = normalizedCounter[charnum++];
773 const short max = (short)((2*threshold-1)-remaining);
774 remaining -= FSE_abs(count);
Yann Collet213089c2015-06-18 07:43:16 -0800775 if (remaining<1) return (size_t)-FSE_ERROR_GENERIC;
Yann Collet4856a002015-01-24 01:58:16 +0100776 count++; /* +1 for extra accuracy */
777 if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
778 bitStream += count << bitCount;
779 bitCount += nbBits;
780 bitCount -= (count<max);
781 previous0 = (count==1);
782 while (remaining<threshold) nbBits--, threshold>>=1;
783 }
784 if (bitCount>16)
785 {
Yann Collet23743532015-08-19 23:53:56 +0100786 if ((!writeIsSafe) && (out > oend - 2)) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100787 out[0] = (BYTE)bitStream;
788 out[1] = (BYTE)(bitStream>>8);
789 out += 2;
790 bitStream >>= 16;
791 bitCount -= 16;
792 }
793 }
794
795 /* flush remaining bitStream */
Yann Collet23743532015-08-19 23:53:56 +0100796 if ((!writeIsSafe) && (out > oend - 2)) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* Buffer overflow */
Yann Collet4856a002015-01-24 01:58:16 +0100797 out[0] = (BYTE)bitStream;
798 out[1] = (BYTE)(bitStream>>8);
799 out+= (bitCount+7) /8;
800
Yann Collete8c6bb12015-07-26 00:23:57 +0100801 if (charnum > maxSymbolValue + 1) return (size_t)-FSE_ERROR_GENERIC;
Yann Collet4856a002015-01-24 01:58:16 +0100802
803 return (out-ostart);
804}
805
806
Yann Collet997f9ee2015-08-21 02:44:20 +0100807size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100808{
809 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported */
810 if (tableLog < FSE_MIN_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported */
811
Yann Collet997f9ee2015-08-21 02:44:20 +0100812 if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
813 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
Yann Collet4856a002015-01-24 01:58:16 +0100814
Yann Collet997f9ee2015-08-21 02:44:20 +0100815 return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
Yann Collet4856a002015-01-24 01:58:16 +0100816}
817
818
Yann Collet1efa31f2015-07-04 15:56:41 -0800819size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
Yann Collet4856a002015-01-24 01:58:16 +0100820 const void* headerBuffer, size_t hbSize)
821{
822 const BYTE* const istart = (const BYTE*) headerBuffer;
Yann Collet1efa31f2015-07-04 15:56:41 -0800823 const BYTE* const iend = istart + hbSize;
Yann Collet4856a002015-01-24 01:58:16 +0100824 const BYTE* ip = istart;
825 int nbBits;
826 int remaining;
827 int threshold;
828 U32 bitStream;
829 int bitCount;
830 unsigned charnum = 0;
831 int previous0 = 0;
832
Yann Collet1efa31f2015-07-04 15:56:41 -0800833 if (hbSize < 4) return (size_t)-FSE_ERROR_srcSize_wrong;
Yann Collet4856a002015-01-24 01:58:16 +0100834 bitStream = FSE_readLE32(ip);
835 nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
836 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return (size_t)-FSE_ERROR_tableLog_tooLarge;
837 bitStream >>= 4;
838 bitCount = 4;
839 *tableLogPtr = nbBits;
840 remaining = (1<<nbBits)+1;
841 threshold = 1<<nbBits;
842 nbBits++;
843
844 while ((remaining>1) && (charnum<=*maxSVPtr))
845 {
846 if (previous0)
847 {
848 unsigned n0 = charnum;
849 while ((bitStream & 0xFFFF) == 0xFFFF)
850 {
851 n0+=24;
Yann Collet23743532015-08-19 23:53:56 +0100852 if (ip < iend-5)
853 {
854 ip+=2;
855 bitStream = FSE_readLE32(ip) >> bitCount;
856 }
857 else
858 {
859 bitStream >>= 16;
860 bitCount+=16;
861 }
Yann Collet4856a002015-01-24 01:58:16 +0100862 }
863 while ((bitStream & 3) == 3)
864 {
865 n0+=3;
866 bitStream>>=2;
867 bitCount+=2;
868 }
869 n0 += bitStream & 3;
870 bitCount += 2;
Yann Collet1efa31f2015-07-04 15:56:41 -0800871 if (n0 > *maxSVPtr) return (size_t)-FSE_ERROR_maxSymbolValue_tooSmall;
Yann Collet4856a002015-01-24 01:58:16 +0100872 while (charnum < n0) normalizedCounter[charnum++] = 0;
Yann Collet23743532015-08-19 23:53:56 +0100873 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
874 {
875 ip += bitCount>>3;
876 bitCount &= 7;
877 bitStream = FSE_readLE32(ip) >> bitCount;
878 }
879 else
880 bitStream >>= 2;
Yann Collet4856a002015-01-24 01:58:16 +0100881 }
882 {
883 const short max = (short)((2*threshold-1)-remaining);
884 short count;
885
886 if ((bitStream & (threshold-1)) < (U32)max)
887 {
888 count = (short)(bitStream & (threshold-1));
889 bitCount += nbBits-1;
890 }
891 else
892 {
893 count = (short)(bitStream & (2*threshold-1));
894 if (count >= threshold) count -= max;
895 bitCount += nbBits;
896 }
897
898 count--; /* extra accuracy */
899 remaining -= FSE_abs(count);
900 normalizedCounter[charnum++] = count;
901 previous0 = !count;
902 while (remaining < threshold)
903 {
904 nbBits--;
905 threshold >>= 1;
906 }
907
Yann Collet1efa31f2015-07-04 15:56:41 -0800908 {
Yann Collet23743532015-08-19 23:53:56 +0100909 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
Yann Collet1efa31f2015-07-04 15:56:41 -0800910 {
Yann Collet23743532015-08-19 23:53:56 +0100911 ip += bitCount>>3;
912 bitCount &= 7;
Yann Collet1efa31f2015-07-04 15:56:41 -0800913 }
914 else
915 {
Yann Collet23743532015-08-19 23:53:56 +0100916 bitCount -= (int)(8 * (iend - 4 - ip));
Yann Collet997f9ee2015-08-21 02:44:20 +0100917 ip = iend - 4;
918 }
Yann Collet1efa31f2015-07-04 15:56:41 -0800919 bitStream = FSE_readLE32(ip) >> (bitCount & 31);
920 }
Yann Collet4856a002015-01-24 01:58:16 +0100921 }
922 }
923 if (remaining != 1) return (size_t)-FSE_ERROR_GENERIC;
924 *maxSVPtr = charnum-1;
925
Yann Collet1efa31f2015-07-04 15:56:41 -0800926 ip += (bitCount+7)>>3;
927 if ((size_t)(ip-istart) > hbSize) return (size_t)-FSE_ERROR_srcSize_wrong;
Yann Collet4856a002015-01-24 01:58:16 +0100928 return ip-istart;
929}
930
931
932/****************************************************************
933* FSE Compression Code
934****************************************************************/
935/*
Yann Collet1efa31f2015-07-04 15:56:41 -0800936FSE_CTable[0] is a variable size structure which contains :
Yann Collet4856a002015-01-24 01:58:16 +0100937 U16 tableLog;
938 U16 maxSymbolValue;
939 U16 nextStateNumber[1 << tableLog]; // This size is variable
940 FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1]; // This size is variable
941Allocation is manual, since C standard does not support variable-size structures.
942*/
943
944size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
945{
946 size_t size;
947 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 */
948 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC;
949 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
950 return size;
951}
952
Yann Collet1efa31f2015-07-04 15:56:41 -0800953FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
Yann Collet4856a002015-01-24 01:58:16 +0100954{
955 size_t size;
956 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
957 size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
Yann Collet1efa31f2015-07-04 15:56:41 -0800958 return (FSE_CTable*)malloc(size);
Yann Collet4856a002015-01-24 01:58:16 +0100959}
960
Yann Collet1efa31f2015-07-04 15:56:41 -0800961void FSE_freeCTable (FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +0100962{
Yann Collet1efa31f2015-07-04 15:56:41 -0800963 free(ct);
Yann Collet4856a002015-01-24 01:58:16 +0100964}
965
Yann Collet4856a002015-01-24 01:58:16 +0100966
967unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
968{
969 U32 tableLog = maxTableLog;
Yann Collet997f9ee2015-08-21 02:44:20 +0100970 U32 minBitsSrc = FSE_highbit32((U32)(srcSize - 1)) + 1;
971 U32 minBitsSymbols = FSE_highbit32(maxSymbolValue) + 2;
972 U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
Yann Collet4856a002015-01-24 01:58:16 +0100973 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
Yann Collet997f9ee2015-08-21 02:44:20 +0100974 if (minBitsSrc < tableLog + 3) tableLog = minBitsSrc-3; /* Accuracy can be reduced */
975 if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
Yann Collet4856a002015-01-24 01:58:16 +0100976 if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
977 if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
978 return tableLog;
979}
980
981
Yann Collet26aa1ec2015-02-24 09:05:58 +0100982/* Secondary normalization method.
983 To be used when primary method fails. */
984
985static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
Yann Colleta3c75ba2015-02-21 03:31:59 +0100986{
987 U32 s;
Yann Colleta3c75ba2015-02-21 03:31:59 +0100988 U32 distributed = 0;
989 U32 ToDistribute;
990
991 /* Init */
Yann Colleta3c75ba2015-02-21 03:31:59 +0100992 U32 lowThreshold = (U32)(total >> tableLog);
993 U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
994
995 for (s=0; s<=maxSymbolValue; s++)
996 {
997 if (count[s] == 0)
998 {
999 norm[s]=0;
1000 continue;
1001 }
1002 if (count[s] <= lowThreshold)
1003 {
1004 norm[s] = -1;
1005 distributed++;
1006 total -= count[s];
1007 continue;
1008 }
1009 if (count[s] <= lowOne)
1010 {
1011 norm[s] = 1;
1012 distributed++;
1013 total -= count[s];
1014 continue;
1015 }
1016 norm[s]=-2;
1017 }
1018 ToDistribute = (1 << tableLog) - distributed;
1019
1020 if ((total / ToDistribute) > lowOne)
1021 {
1022 /* risk of rounding to zero */
1023 lowOne = (U32)((total * 3) / (ToDistribute * 2));
1024 for (s=0; s<=maxSymbolValue; s++)
1025 {
1026 if ((norm[s] == -2) && (count[s] <= lowOne))
1027 {
1028 norm[s] = 1;
1029 distributed++;
1030 total -= count[s];
1031 continue;
1032 }
1033 }
1034 ToDistribute = (1 << tableLog) - distributed;
1035 }
1036
1037 if (distributed == maxSymbolValue+1)
1038 {
Yann Collet26aa1ec2015-02-24 09:05:58 +01001039 /* all values are pretty poor;
1040 probably incompressible data (should have already been detected);
1041 find max, then give all remaining points to max */
Yann Colleta3c75ba2015-02-21 03:31:59 +01001042 U32 maxV = 0, maxC =0;
1043 for (s=0; s<=maxSymbolValue; s++)
1044 if (count[s] > maxC) maxV=s, maxC=count[s];
Yann Collet1efa31f2015-07-04 15:56:41 -08001045 norm[maxV] += (short)ToDistribute;
Yann Colleta3c75ba2015-02-21 03:31:59 +01001046 return 0;
1047 }
1048
1049 {
1050 U64 const vStepLog = 62 - tableLog;
1051 U64 const mid = (1ULL << (vStepLog-1)) - 1;
1052 U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
1053 U64 tmpTotal = mid;
1054 for (s=0; s<=maxSymbolValue; s++)
1055 {
1056 if (norm[s]==-2)
1057 {
1058 U64 end = tmpTotal + (count[s] * rStep);
1059 U32 sStart = (U32)(tmpTotal >> vStepLog);
1060 U32 sEnd = (U32)(end >> vStepLog);
1061 U32 weight = sEnd - sStart;
1062 if (weight < 1)
1063 return (size_t)-FSE_ERROR_GENERIC;
Yann Collet213089c2015-06-18 07:43:16 -08001064 norm[s] = (short)weight;
Yann Colleta3c75ba2015-02-21 03:31:59 +01001065 tmpTotal = end;
1066 }
1067 }
1068 }
1069
1070 return 0;
1071}
Yann Colleta3c75ba2015-02-21 03:31:59 +01001072
Yann Collet4856a002015-01-24 01:58:16 +01001073
1074size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
1075 const unsigned* count, size_t total,
1076 unsigned maxSymbolValue)
1077{
1078 /* Sanity checks */
1079 if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
1080 if (tableLog < FSE_MIN_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported size */
1081 if (tableLog > FSE_MAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; /* Unsupported size */
Yann Collet997f9ee2015-08-21 02:44:20 +01001082 //if ((1U<<tableLog) <= maxSymbolValue) return (size_t)-FSE_ERROR_GENERIC; /* Too small tableLog, compression potentially impossible */
Yann Collet4856a002015-01-24 01:58:16 +01001083
1084 {
1085 U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
1086 U64 const scale = 62 - tableLog;
1087 U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
1088 U64 const vStep = 1ULL<<(scale-20);
1089 int stillToDistribute = 1<<tableLog;
1090 unsigned s;
1091 unsigned largest=0;
1092 short largestP=0;
1093 U32 lowThreshold = (U32)(total >> tableLog);
1094
1095 for (s=0; s<=maxSymbolValue; s++)
1096 {
1097 if (count[s] == total) return 0;
1098 if (count[s] == 0)
1099 {
1100 normalizedCounter[s]=0;
1101 continue;
1102 }
1103 if (count[s] <= lowThreshold)
1104 {
1105 normalizedCounter[s] = -1;
1106 stillToDistribute--;
1107 }
1108 else
1109 {
1110 short proba = (short)((count[s]*step) >> scale);
1111 if (proba<8)
1112 {
Yann Collet2ddf7e92015-02-08 20:26:47 +01001113 U64 restToBeat = vStep * rtbTable[proba];
Yann Collet4856a002015-01-24 01:58:16 +01001114 proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
1115 }
1116 if (proba > largestP)
1117 {
1118 largestP=proba;
1119 largest=s;
1120 }
1121 normalizedCounter[s] = proba;
1122 stillToDistribute -= proba;
1123 }
1124 }
Yann Collet4856a002015-01-24 01:58:16 +01001125 if (-stillToDistribute >= (normalizedCounter[largest] >> 1))
1126 {
Yann Collet26aa1ec2015-02-24 09:05:58 +01001127 /* corner case, need another normalization method */
1128 size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
Yann Collet565b81d2015-01-29 06:51:30 +01001129 if (FSE_isError(errorCode)) return errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001130 }
1131 else normalizedCounter[largest] += (short)stillToDistribute;
1132 }
1133
1134#if 0
1135 { /* Print Table (debug) */
Yann Collet565b81d2015-01-29 06:51:30 +01001136 U32 s;
1137 U32 nTotal = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001138 for (s=0; s<=maxSymbolValue; s++)
1139 printf("%3i: %4i \n", s, normalizedCounter[s]);
Yann Collet565b81d2015-01-29 06:51:30 +01001140 for (s=0; s<=maxSymbolValue; s++)
1141 nTotal += abs(normalizedCounter[s]);
1142 if (nTotal != (1U<<tableLog))
1143 printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001144 getchar();
1145 }
1146#endif
1147
1148 return tableLog;
1149}
1150
1151
Yann Collet1efa31f2015-07-04 15:56:41 -08001152/* fake FSE_CTable, for raw (uncompressed) input */
1153size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001154{
1155 const unsigned tableSize = 1 << nbBits;
1156 const unsigned tableMask = tableSize - 1;
1157 const unsigned maxSymbolValue = tableMask;
Yann Collet1efa31f2015-07-04 15:56:41 -08001158 U16* tableU16 = ( (U16*) ct) + 2;
1159 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) ((((U32*)ct)+1) + (tableSize>>1));
Yann Collet4856a002015-01-24 01:58:16 +01001160 unsigned s;
1161
1162 /* Sanity checks */
1163 if (nbBits < 1) return (size_t)-FSE_ERROR_GENERIC; /* min size */
Yann Collet4856a002015-01-24 01:58:16 +01001164
1165 /* header */
1166 tableU16[-2] = (U16) nbBits;
1167 tableU16[-1] = (U16) maxSymbolValue;
1168
1169 /* Build table */
1170 for (s=0; s<tableSize; s++)
1171 tableU16[s] = (U16)(tableSize + s);
1172
1173 /* Build Symbol Transformation Table */
1174 for (s=0; s<=maxSymbolValue; s++)
1175 {
Yann Collet77c82b62015-08-02 01:19:09 +01001176 symbolTT[s].deltaNbBits = nbBits << 16;
Yann Collet4856a002015-01-24 01:58:16 +01001177 symbolTT[s].deltaFindState = s-1;
Yann Collet4856a002015-01-24 01:58:16 +01001178 }
1179
1180 return 0;
1181}
1182
1183
Yann Collet1efa31f2015-07-04 15:56:41 -08001184/* fake FSE_CTable, for rle (100% always same symbol) input */
1185size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +01001186{
Yann Collet1efa31f2015-07-04 15:56:41 -08001187 U16* tableU16 = ( (U16*) ct) + 2;
1188 FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) ((U32*)ct + 2);
Yann Collet4856a002015-01-24 01:58:16 +01001189
1190 /* header */
1191 tableU16[-2] = (U16) 0;
1192 tableU16[-1] = (U16) symbolValue;
1193
1194 /* Build table */
1195 tableU16[0] = 0;
1196 tableU16[1] = 0; /* just in case */
1197
1198 /* Build Symbol Transformation Table */
1199 {
Yann Collet77c82b62015-08-02 01:19:09 +01001200 symbolTT[symbolValue].deltaNbBits = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001201 symbolTT[symbolValue].deltaFindState = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001202 }
1203
1204 return 0;
1205}
1206
1207
Yann Colleta7875502015-08-07 15:21:00 +01001208size_t FSE_initCStream(FSE_CStream_t* bitC, void* start, size_t maxSize)
Yann Collet4856a002015-01-24 01:58:16 +01001209{
Yann Collete9853b22015-08-07 19:07:32 +01001210 if (maxSize < sizeof(bitC->ptr)) return (size_t)-FSE_ERROR_dstSize_tooSmall;
Yann Collet4856a002015-01-24 01:58:16 +01001211 bitC->bitContainer = 0;
Yann Colleta7875502015-08-07 15:21:00 +01001212 bitC->bitPos = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001213 bitC->startPtr = (char*)start;
1214 bitC->ptr = bitC->startPtr;
Yann Colleta7875502015-08-07 15:21:00 +01001215 bitC->endPtr = bitC->startPtr + maxSize - sizeof(bitC->ptr);
1216 return 0;
Yann Collet4856a002015-01-24 01:58:16 +01001217}
1218
Yann Collet1efa31f2015-07-04 15:56:41 -08001219void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
Yann Collet4856a002015-01-24 01:58:16 +01001220{
Yann Collet1efa31f2015-07-04 15:56:41 -08001221 const U32 tableLog = ( (const U16*) ct) [0];
Yann Collet4856a002015-01-24 01:58:16 +01001222 statePtr->value = (ptrdiff_t)1<<tableLog;
Yann Collet1efa31f2015-07-04 15:56:41 -08001223 statePtr->stateTable = ((const U16*) ct) + 2;
1224 statePtr->symbolTT = (const FSE_symbolCompressionTransform*)((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
Yann Collet4856a002015-01-24 01:58:16 +01001225 statePtr->stateLog = tableLog;
1226}
1227
Yann Collete8c6bb12015-07-26 00:23:57 +01001228void FSE_addBitsFast(FSE_CStream_t* bitC, size_t value, unsigned nbBits) /* only use if upper bits are clean 0 */
1229{
1230 bitC->bitContainer |= value << bitC->bitPos;
1231 bitC->bitPos += nbBits;
1232}
1233
Yann Collet4856a002015-01-24 01:58:16 +01001234void FSE_addBits(FSE_CStream_t* bitC, size_t value, unsigned nbBits)
1235{
1236 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 */
1237 bitC->bitContainer |= (value & mask[nbBits]) << bitC->bitPos;
1238 bitC->bitPos += nbBits;
1239}
1240
Yann Collet77c82b62015-08-02 01:19:09 +01001241void FSE_encodeSymbol(FSE_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
Yann Collet4856a002015-01-24 01:58:16 +01001242{
Yann Collet1efa31f2015-07-04 15:56:41 -08001243 const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
1244 const U16* const stateTable = (const U16*)(statePtr->stateTable);
Yann Collet77c82b62015-08-02 01:19:09 +01001245 U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
Yann Collet4856a002015-01-24 01:58:16 +01001246 FSE_addBits(bitC, statePtr->value, nbBitsOut);
Yann Collet1efa31f2015-07-04 15:56:41 -08001247 statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
Yann Collet4856a002015-01-24 01:58:16 +01001248}
1249
Yann Colleta7875502015-08-07 15:21:00 +01001250void FSE_flushBitsFast(FSE_CStream_t* bitC) /* only if dst buffer is large enough ( >= FSE_compressBound()) */
1251{
1252 size_t nbBytes = bitC->bitPos >> 3;
1253 FSE_writeLEST(bitC->ptr, bitC->bitContainer);
1254 bitC->ptr += nbBytes;
1255 bitC->bitPos &= 7;
1256 bitC->bitContainer >>= nbBytes*8;
1257}
1258
Yann Collet4856a002015-01-24 01:58:16 +01001259void FSE_flushBits(FSE_CStream_t* bitC)
1260{
1261 size_t nbBytes = bitC->bitPos >> 3;
1262 FSE_writeLEST(bitC->ptr, bitC->bitContainer);
Yann Collet4856a002015-01-24 01:58:16 +01001263 bitC->ptr += nbBytes;
Yann Collete9853b22015-08-07 19:07:32 +01001264 if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
1265 bitC->bitPos &= 7;
1266 bitC->bitContainer >>= nbBytes*8;
Yann Collet4856a002015-01-24 01:58:16 +01001267}
1268
1269void FSE_flushCState(FSE_CStream_t* bitC, const FSE_CState_t* statePtr)
1270{
1271 FSE_addBits(bitC, statePtr->value, statePtr->stateLog);
1272 FSE_flushBits(bitC);
1273}
1274
1275
1276size_t FSE_closeCStream(FSE_CStream_t* bitC)
1277{
1278 char* endPtr;
1279
Yann Colleta7875502015-08-07 15:21:00 +01001280 FSE_addBitsFast(bitC, 1, 1);
Yann Collet4856a002015-01-24 01:58:16 +01001281 FSE_flushBits(bitC);
1282
Yann Collete9853b22015-08-07 19:07:32 +01001283 if (bitC->ptr >= bitC->endPtr) /* too close to buffer's end */
Yann Colleta7875502015-08-07 15:21:00 +01001284 return 0; /* not compressible */
1285
Yann Collet4856a002015-01-24 01:58:16 +01001286 endPtr = bitC->ptr;
1287 endPtr += bitC->bitPos > 0;
1288
1289 return (endPtr - bitC->startPtr);
1290}
1291
1292
Yann Colleta7875502015-08-07 15:21:00 +01001293static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
Yann Collet4856a002015-01-24 01:58:16 +01001294 const void* src, size_t srcSize,
Yann Colleta7875502015-08-07 15:21:00 +01001295 const FSE_CTable* ct, const unsigned fast)
Yann Collet4856a002015-01-24 01:58:16 +01001296{
1297 const BYTE* const istart = (const BYTE*) src;
1298 const BYTE* ip;
1299 const BYTE* const iend = istart + srcSize;
1300
Yann Colleta7875502015-08-07 15:21:00 +01001301 size_t errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001302 FSE_CStream_t bitC;
1303 FSE_CState_t CState1, CState2;
1304
1305
1306 /* init */
Yann Colleta7875502015-08-07 15:21:00 +01001307 errorCode = FSE_initCStream(&bitC, dst, dstSize);
1308 if (FSE_isError(errorCode)) return 0;
Yann Collet1efa31f2015-07-04 15:56:41 -08001309 FSE_initCState(&CState1, ct);
Yann Collet4856a002015-01-24 01:58:16 +01001310 CState2 = CState1;
1311
1312 ip=iend;
1313
Yann Colleta7875502015-08-07 15:21:00 +01001314#define FSE_FLUSHBITS(s) (fast ? FSE_flushBitsFast(s) : FSE_flushBits(s))
1315
Yann Collet4856a002015-01-24 01:58:16 +01001316 /* join to even */
1317 if (srcSize & 1)
1318 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001319 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Colleta7875502015-08-07 15:21:00 +01001320 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +01001321 }
1322
1323 /* join to mod 4 */
Yann Collet77c82b62015-08-02 01:19:09 +01001324 if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) /* test bit 2 */
Yann Collet4856a002015-01-24 01:58:16 +01001325 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001326 FSE_encodeSymbol(&bitC, &CState2, *--ip);
1327 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Colleta7875502015-08-07 15:21:00 +01001328 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +01001329 }
1330
1331 /* 2 or 4 encoding per loop */
Yann Colleta7875502015-08-07 15:21:00 +01001332 for ( ; ip>istart ; )
Yann Collet4856a002015-01-24 01:58:16 +01001333 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001334 FSE_encodeSymbol(&bitC, &CState2, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +01001335
Yann Collet77c82b62015-08-02 01:19:09 +01001336 if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */
Yann Colleta7875502015-08-07 15:21:00 +01001337 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +01001338
Yann Collet1efa31f2015-07-04 15:56:41 -08001339 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +01001340
Yann Collet77c82b62015-08-02 01:19:09 +01001341 if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) /* this test must be static */
Yann Collet4856a002015-01-24 01:58:16 +01001342 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001343 FSE_encodeSymbol(&bitC, &CState2, *--ip);
1344 FSE_encodeSymbol(&bitC, &CState1, *--ip);
Yann Collet4856a002015-01-24 01:58:16 +01001345 }
1346
Yann Colleta7875502015-08-07 15:21:00 +01001347 FSE_FLUSHBITS(&bitC);
Yann Collet4856a002015-01-24 01:58:16 +01001348 }
1349
1350 FSE_flushCState(&bitC, &CState2);
1351 FSE_flushCState(&bitC, &CState1);
1352 return FSE_closeCStream(&bitC);
1353}
1354
Yann Colleta7875502015-08-07 15:21:00 +01001355size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
1356 const void* src, size_t srcSize,
1357 const FSE_CTable* ct)
1358{
1359 const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
1360
1361 if (fast)
1362 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
1363 else
1364 return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
1365}
1366
Yann Collet4856a002015-01-24 01:58:16 +01001367
Yann Collet4856a002015-01-24 01:58:16 +01001368size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
1369
Yann Collet4856a002015-01-24 01:58:16 +01001370size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
1371{
1372 const BYTE* const istart = (const BYTE*) src;
1373 const BYTE* ip = istart;
1374
1375 BYTE* const ostart = (BYTE*) dst;
1376 BYTE* op = ostart;
1377 BYTE* const oend = ostart + dstSize;
1378
1379 U32 count[FSE_MAX_SYMBOL_VALUE+1];
1380 S16 norm[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -08001381 CTable_max_t ct;
Yann Collet4856a002015-01-24 01:58:16 +01001382 size_t errorCode;
1383
Yann Colleta7875502015-08-07 15:21:00 +01001384 /* init conditions */
1385 if (srcSize <= 1) return 0; /* Uncompressible */
Yann Collet4856a002015-01-24 01:58:16 +01001386 if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
1387 if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
1388
1389 /* Scan input and build symbol stats */
Yann Collet1efa31f2015-07-04 15:56:41 -08001390 errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001391 if (FSE_isError(errorCode)) return errorCode;
Yann Colleta3c75ba2015-02-21 03:31:59 +01001392 if (errorCode == srcSize) return 1;
1393 if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
Yann Collet4856a002015-01-24 01:58:16 +01001394
1395 tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
1396 errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
1397 if (FSE_isError(errorCode)) return errorCode;
1398
1399 /* Write table description header */
Yann Colleta7875502015-08-07 15:21:00 +01001400 errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001401 if (FSE_isError(errorCode)) return errorCode;
1402 op += errorCode;
1403
1404 /* Compress */
Yann Collet1efa31f2015-07-04 15:56:41 -08001405 errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001406 if (FSE_isError(errorCode)) return errorCode;
Yann Colleta7875502015-08-07 15:21:00 +01001407 errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
1408 if (errorCode == 0) return 0; /* not enough space for compressed data */
1409 op += errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001410
1411 /* check compressibility */
1412 if ( (size_t)(op-ostart) >= srcSize-1 )
1413 return 0;
1414
1415 return op-ostart;
1416}
1417
Yann Collet4856a002015-01-24 01:58:16 +01001418size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
1419{
1420 return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
1421}
1422
1423
1424/*********************************************************
1425* Decompression (Byte symbols)
1426*********************************************************/
Yann Collet1efa31f2015-07-04 15:56:41 -08001427size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
Yann Collet4856a002015-01-24 01:58:16 +01001428{
Yann Colleta7875502015-08-07 15:21:00 +01001429 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)dt;
1430 FSE_decode_t* const cell = (FSE_decode_t*)(dt + 1); /* because dt is unsigned */
Yann Collet4856a002015-01-24 01:58:16 +01001431
Yann Colleta7875502015-08-07 15:21:00 +01001432 DTableH->tableLog = 0;
1433 DTableH->fastMode = 0;
Yann Collet4856a002015-01-24 01:58:16 +01001434
1435 cell->newState = 0;
1436 cell->symbol = symbolValue;
1437 cell->nbBits = 0;
1438
1439 return 0;
1440}
1441
1442
Yann Collet1efa31f2015-07-04 15:56:41 -08001443size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001444{
Yann Colleta7875502015-08-07 15:21:00 +01001445 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)dt;
1446 FSE_decode_t* const dinfo = (FSE_decode_t*)(dt + 1); /* because dt is unsigned */
Yann Collet4856a002015-01-24 01:58:16 +01001447 const unsigned tableSize = 1 << nbBits;
1448 const unsigned tableMask = tableSize - 1;
1449 const unsigned maxSymbolValue = tableMask;
1450 unsigned s;
1451
1452 /* Sanity checks */
1453 if (nbBits < 1) return (size_t)-FSE_ERROR_GENERIC; /* min size */
Yann Collet4856a002015-01-24 01:58:16 +01001454
1455 /* Build Decoding Table */
Yann Colleta7875502015-08-07 15:21:00 +01001456 DTableH->tableLog = (U16)nbBits;
1457 DTableH->fastMode = 1;
Yann Collet4856a002015-01-24 01:58:16 +01001458 for (s=0; s<=maxSymbolValue; s++)
1459 {
1460 dinfo[s].newState = 0;
1461 dinfo[s].symbol = (BYTE)s;
1462 dinfo[s].nbBits = (BYTE)nbBits;
1463 }
1464
1465 return 0;
1466}
1467
1468
1469/* FSE_initDStream
1470 * Initialize a FSE_DStream_t.
1471 * srcBuffer must point at the beginning of an FSE block.
1472 * The function result is the size of the FSE_block (== srcSize).
1473 * If srcSize is too small, the function will return an errorCode;
1474 */
1475size_t FSE_initDStream(FSE_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
1476{
1477 if (srcSize < 1) return (size_t)-FSE_ERROR_srcSize_wrong;
1478
Yann Collet1efa31f2015-07-04 15:56:41 -08001479 if (srcSize >= sizeof(size_t))
Yann Collet4856a002015-01-24 01:58:16 +01001480 {
1481 U32 contain32;
Yann Collet213089c2015-06-18 07:43:16 -08001482 bitD->start = (const char*)srcBuffer;
Yann Collet1efa31f2015-07-04 15:56:41 -08001483 bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t);
Yann Collet4856a002015-01-24 01:58:16 +01001484 bitD->bitContainer = FSE_readLEST(bitD->ptr);
Yann Collet213089c2015-06-18 07:43:16 -08001485 contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
Yann Collet4856a002015-01-24 01:58:16 +01001486 if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */
1487 bitD->bitsConsumed = 8 - FSE_highbit32(contain32);
1488 }
1489 else
1490 {
1491 U32 contain32;
Yann Collet213089c2015-06-18 07:43:16 -08001492 bitD->start = (const char*)srcBuffer;
Yann Collet4856a002015-01-24 01:58:16 +01001493 bitD->ptr = bitD->start;
Yann Collet213089c2015-06-18 07:43:16 -08001494 bitD->bitContainer = *(const BYTE*)(bitD->start);
Yann Collet4856a002015-01-24 01:58:16 +01001495 switch(srcSize)
1496 {
Yann Collet1efa31f2015-07-04 15:56:41 -08001497 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
1498 case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);
1499 case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);
1500 case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24;
1501 case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16;
1502 case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8;
Yann Collet4856a002015-01-24 01:58:16 +01001503 default:;
1504 }
Yann Collet213089c2015-06-18 07:43:16 -08001505 contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
Yann Collet4856a002015-01-24 01:58:16 +01001506 if (contain32 == 0) return (size_t)-FSE_ERROR_GENERIC; /* stop bit not present */
1507 bitD->bitsConsumed = 8 - FSE_highbit32(contain32);
Yann Collet1efa31f2015-07-04 15:56:41 -08001508 bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8;
Yann Collet4856a002015-01-24 01:58:16 +01001509 }
1510
1511 return srcSize;
1512}
1513
1514
Yann Collete8c6bb12015-07-26 00:23:57 +01001515/* FSE_lookBits
1516 * Provides next n bits from the bitContainer.
1517 * bitContainer is not modified (bits are still present for next read/look)
1518 * On 32-bits, maxNbBits==25
1519 * On 64-bits, maxNbBits==57
1520 * return : value extracted.
1521 */
1522static size_t FSE_lookBits(FSE_DStream_t* bitD, U32 nbBits)
1523{
1524 return ((bitD->bitContainer << (bitD->bitsConsumed & ((sizeof(bitD->bitContainer)*8)-1))) >> 1) >> (((sizeof(bitD->bitContainer)*8)-1)-nbBits);
1525}
1526
1527static size_t FSE_lookBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */
1528{
1529 return (bitD->bitContainer << bitD->bitsConsumed) >> ((sizeof(bitD->bitContainer)*8)-nbBits);
1530}
1531
1532static void FSE_skipBits(FSE_DStream_t* bitD, U32 nbBits)
1533{
1534 bitD->bitsConsumed += nbBits;
1535}
1536
1537
Yann Collet4856a002015-01-24 01:58:16 +01001538/* FSE_readBits
1539 * Read next n bits from the bitContainer.
Yann Collet213089c2015-06-18 07:43:16 -08001540 * On 32-bits, don't read more than maxNbBits==25
1541 * On 64-bits, don't read more than maxNbBits==57
1542 * Use the fast variant *only* if n >= 1.
Yann Collet4856a002015-01-24 01:58:16 +01001543 * return : value extracted.
1544 */
Yann Collet1efa31f2015-07-04 15:56:41 -08001545size_t FSE_readBits(FSE_DStream_t* bitD, U32 nbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001546{
Yann Collete8c6bb12015-07-26 00:23:57 +01001547 size_t value = FSE_lookBits(bitD, nbBits);
1548 FSE_skipBits(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001549 return value;
1550}
1551
Yann Collet1efa31f2015-07-04 15:56:41 -08001552size_t FSE_readBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */
Yann Collet4856a002015-01-24 01:58:16 +01001553{
Yann Collete8c6bb12015-07-26 00:23:57 +01001554 size_t value = FSE_lookBitsFast(bitD, nbBits);
1555 FSE_skipBits(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001556 return value;
1557}
1558
1559unsigned FSE_reloadDStream(FSE_DStream_t* bitD)
1560{
Yann Collet997f9ee2015-08-21 02:44:20 +01001561 if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
1562 return FSE_DStream_tooFar;
1563
Yann Collete8c6bb12015-07-26 00:23:57 +01001564 if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer))
Yann Collet4856a002015-01-24 01:58:16 +01001565 {
1566 bitD->ptr -= bitD->bitsConsumed >> 3;
1567 bitD->bitsConsumed &= 7;
1568 bitD->bitContainer = FSE_readLEST(bitD->ptr);
Yann Collete8c6bb12015-07-26 00:23:57 +01001569 return FSE_DStream_unfinished;
Yann Collet4856a002015-01-24 01:58:16 +01001570 }
1571 if (bitD->ptr == bitD->start)
1572 {
Yann Colleta7875502015-08-07 15:21:00 +01001573 if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return FSE_DStream_endOfBuffer;
Yann Collet997f9ee2015-08-21 02:44:20 +01001574 return FSE_DStream_completed;
Yann Collet4856a002015-01-24 01:58:16 +01001575 }
1576 {
1577 U32 nbBytes = bitD->bitsConsumed >> 3;
Yann Collete8c6bb12015-07-26 00:23:57 +01001578 U32 result = FSE_DStream_unfinished;
Yann Collet4856a002015-01-24 01:58:16 +01001579 if (bitD->ptr - nbBytes < bitD->start)
Yann Collete8c6bb12015-07-26 00:23:57 +01001580 {
Yann Collet997f9ee2015-08-21 02:44:20 +01001581 nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
Yann Colleta7875502015-08-07 15:21:00 +01001582 result = FSE_DStream_endOfBuffer;
Yann Collete8c6bb12015-07-26 00:23:57 +01001583 }
Yann Collet4856a002015-01-24 01:58:16 +01001584 bitD->ptr -= nbBytes;
1585 bitD->bitsConsumed -= nbBytes*8;
Yann Collet997f9ee2015-08-21 02:44:20 +01001586 bitD->bitContainer = FSE_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
Yann Collete8c6bb12015-07-26 00:23:57 +01001587 return result;
Yann Collet4856a002015-01-24 01:58:16 +01001588 }
1589}
1590
1591
Yann Collet1efa31f2015-07-04 15:56:41 -08001592void FSE_initDState(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD, const FSE_DTable* dt)
Yann Collet4856a002015-01-24 01:58:16 +01001593{
Yann Colleta7875502015-08-07 15:21:00 +01001594 const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)dt;
1595 DStatePtr->state = FSE_readBits(bitD, DTableH->tableLog);
Yann Collet4856a002015-01-24 01:58:16 +01001596 FSE_reloadDStream(bitD);
Yann Colleta7875502015-08-07 15:21:00 +01001597 DStatePtr->table = dt + 1;
Yann Collet4856a002015-01-24 01:58:16 +01001598}
1599
1600BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD)
1601{
1602 const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
1603 const U32 nbBits = DInfo.nbBits;
1604 BYTE symbol = DInfo.symbol;
Yann Collet1efa31f2015-07-04 15:56:41 -08001605 size_t lowBits = FSE_readBits(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001606
1607 DStatePtr->state = DInfo.newState + lowBits;
1608 return symbol;
1609}
1610
1611BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, FSE_DStream_t* bitD)
1612{
1613 const FSE_decode_t DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
1614 const U32 nbBits = DInfo.nbBits;
1615 BYTE symbol = DInfo.symbol;
Yann Collet1efa31f2015-07-04 15:56:41 -08001616 size_t lowBits = FSE_readBitsFast(bitD, nbBits);
Yann Collet4856a002015-01-24 01:58:16 +01001617
1618 DStatePtr->state = DInfo.newState + lowBits;
1619 return symbol;
1620}
1621
1622/* FSE_endOfDStream
1623 Tells if bitD has reached end of bitStream or not */
1624
1625unsigned FSE_endOfDStream(const FSE_DStream_t* bitD)
1626{
Yann Collete8c6bb12015-07-26 00:23:57 +01001627 return ((bitD->ptr == bitD->start) && (bitD->bitsConsumed == sizeof(bitD->bitContainer)*8));
Yann Collet4856a002015-01-24 01:58:16 +01001628}
1629
Yann Collet1efa31f2015-07-04 15:56:41 -08001630unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
Yann Collet4856a002015-01-24 01:58:16 +01001631{
Yann Collet1efa31f2015-07-04 15:56:41 -08001632 return DStatePtr->state == 0;
Yann Collet4856a002015-01-24 01:58:16 +01001633}
1634
1635
1636FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
1637 void* dst, size_t maxDstSize,
1638 const void* cSrc, size_t cSrcSize,
Yann Colleta7875502015-08-07 15:21:00 +01001639 const FSE_DTable* dt, const unsigned fast)
Yann Collet4856a002015-01-24 01:58:16 +01001640{
1641 BYTE* const ostart = (BYTE*) dst;
1642 BYTE* op = ostart;
1643 BYTE* const omax = op + maxDstSize;
1644 BYTE* const olimit = omax-3;
1645
1646 FSE_DStream_t bitD;
Yann Collet1efa31f2015-07-04 15:56:41 -08001647 FSE_DState_t state1;
1648 FSE_DState_t state2;
Yann Collet4856a002015-01-24 01:58:16 +01001649 size_t errorCode;
1650
1651 /* Init */
1652 errorCode = FSE_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */
1653 if (FSE_isError(errorCode)) return errorCode;
1654
Yann Collet1efa31f2015-07-04 15:56:41 -08001655 FSE_initDState(&state1, &bitD, dt);
1656 FSE_initDState(&state2, &bitD, dt);
Yann Collet4856a002015-01-24 01:58:16 +01001657
Yann Collet77c82b62015-08-02 01:19:09 +01001658#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
Yann Collet4856a002015-01-24 01:58:16 +01001659
Yann Collet77c82b62015-08-02 01:19:09 +01001660 /* 4 symbols per loop */
1661 for ( ; (FSE_reloadDStream(&bitD)==FSE_DStream_unfinished) && (op<olimit) ; op+=4)
Yann Collet4856a002015-01-24 01:58:16 +01001662 {
Yann Collet77c82b62015-08-02 01:19:09 +01001663 op[0] = FSE_GETSYMBOL(&state1);
Yann Collet4856a002015-01-24 01:58:16 +01001664
Yann Collet77c82b62015-08-02 01:19:09 +01001665 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
Yann Collet4856a002015-01-24 01:58:16 +01001666 FSE_reloadDStream(&bitD);
1667
Yann Collet77c82b62015-08-02 01:19:09 +01001668 op[1] = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001669
Yann Collet77c82b62015-08-02 01:19:09 +01001670 if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
1671 { if (FSE_reloadDStream(&bitD) > FSE_DStream_unfinished) { op+=2; break; } }
1672
1673 op[2] = FSE_GETSYMBOL(&state1);
1674
1675 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
1676 FSE_reloadDStream(&bitD);
1677
1678 op[3] = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001679 }
1680
1681 /* tail */
Yann Collete8c6bb12015-07-26 00:23:57 +01001682 /* note : FSE_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly FSE_DStream_completed */
Yann Collet4856a002015-01-24 01:58:16 +01001683 while (1)
1684 {
Yann Collete8c6bb12015-07-26 00:23:57 +01001685 if ( (FSE_reloadDStream(&bitD)>FSE_DStream_completed) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state1))) )
Yann Collet4856a002015-01-24 01:58:16 +01001686 break;
1687
Yann Collet77c82b62015-08-02 01:19:09 +01001688 *op++ = FSE_GETSYMBOL(&state1);
Yann Collet4856a002015-01-24 01:58:16 +01001689
Yann Collete8c6bb12015-07-26 00:23:57 +01001690 if ( (FSE_reloadDStream(&bitD)>FSE_DStream_completed) || (op==omax) || (FSE_endOfDStream(&bitD) && (fast || FSE_endOfDState(&state2))) )
Yann Collet4856a002015-01-24 01:58:16 +01001691 break;
1692
Yann Collet77c82b62015-08-02 01:19:09 +01001693 *op++ = FSE_GETSYMBOL(&state2);
Yann Collet4856a002015-01-24 01:58:16 +01001694 }
1695
1696 /* end ? */
Yann Collet77c82b62015-08-02 01:19:09 +01001697 if (FSE_endOfDStream(&bitD) && FSE_endOfDState(&state1) && FSE_endOfDState(&state2))
Yann Collet4856a002015-01-24 01:58:16 +01001698 return op-ostart;
1699
1700 if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
1701
1702 return (size_t)-FSE_ERROR_corruptionDetected;
1703}
1704
1705
1706size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
1707 const void* cSrc, size_t cSrcSize,
Yann Colleta7875502015-08-07 15:21:00 +01001708 const FSE_DTable* dt)
Yann Collet4856a002015-01-24 01:58:16 +01001709{
Yann Colleta7875502015-08-07 15:21:00 +01001710 const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)dt;
1711 const U32 fastMode = DTableH->fastMode;
1712
Yann Collet4856a002015-01-24 01:58:16 +01001713 /* select fast mode (static) */
Yann Collet1efa31f2015-07-04 15:56:41 -08001714 if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
1715 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
Yann Collet4856a002015-01-24 01:58:16 +01001716}
1717
1718
1719size_t FSE_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
1720{
1721 const BYTE* const istart = (const BYTE*)cSrc;
1722 const BYTE* ip = istart;
1723 short counting[FSE_MAX_SYMBOL_VALUE+1];
Yann Collet1efa31f2015-07-04 15:56:41 -08001724 DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
Yann Collet4856a002015-01-24 01:58:16 +01001725 unsigned tableLog;
Yann Collet1efa31f2015-07-04 15:56:41 -08001726 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
Yann Colleta7875502015-08-07 15:21:00 +01001727 size_t errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001728
1729 if (cSrcSize<2) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */
1730
1731 /* normal FSE decoding mode */
Yann Collet1efa31f2015-07-04 15:56:41 -08001732 errorCode = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
Yann Collet4856a002015-01-24 01:58:16 +01001733 if (FSE_isError(errorCode)) return errorCode;
1734 if (errorCode >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong; /* too small input size */
1735 ip += errorCode;
1736 cSrcSize -= errorCode;
1737
Yann Colleta7875502015-08-07 15:21:00 +01001738 errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog);
1739 if (FSE_isError(errorCode)) return errorCode;
Yann Collet4856a002015-01-24 01:58:16 +01001740
1741 /* always return, even if it is an error code */
Yann Colleta7875502015-08-07 15:21:00 +01001742 return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt);
Yann Collet4856a002015-01-24 01:58:16 +01001743}
1744
1745
Yann Collet4856a002015-01-24 01:58:16 +01001746
Yann Collete8c6bb12015-07-26 00:23:57 +01001747/*********************************************************
1748* Huff0 : Huffman block compression
1749*********************************************************/
Yann Collete8c6bb12015-07-26 00:23:57 +01001750#define HUF_MAX_SYMBOL_VALUE 255
Yann Colletfb8296f2015-07-27 19:34:27 +01001751#define HUF_DEFAULT_TABLELOG 12 /* used by default, when not specified */
1752#define HUF_MAX_TABLELOG 12 /* max possible tableLog; for allocation purpose; can be modified */
Yann Collet77c82b62015-08-02 01:19:09 +01001753#define HUF_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
Yann Colletfb8296f2015-07-27 19:34:27 +01001754#if (HUF_MAX_TABLELOG > HUF_ABSOLUTEMAX_TABLELOG)
1755# error "HUF_MAX_TABLELOG is too large !"
1756#endif
Yann Collet4856a002015-01-24 01:58:16 +01001757
Yann Collete8c6bb12015-07-26 00:23:57 +01001758typedef struct HUF_CElt_s {
1759 U16 val;
1760 BYTE nbBits;
1761} HUF_CElt ;
Yann Collet4856a002015-01-24 01:58:16 +01001762
Yann Collete8c6bb12015-07-26 00:23:57 +01001763typedef struct nodeElt_s {
1764 U32 count;
1765 U16 parent;
1766 BYTE byte;
1767 BYTE nbBits;
1768} nodeElt;
Yann Collet4856a002015-01-24 01:58:16 +01001769
Yann Colleta7875502015-08-07 15:21:00 +01001770/* HUF_writeCTable() :
1771 return : size of saved CTable */
Yann Collete8c6bb12015-07-26 00:23:57 +01001772size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* tree, U32 maxSymbolValue, U32 huffLog)
Yann Collet4856a002015-01-24 01:58:16 +01001773{
Yann Colleta7875502015-08-07 15:21:00 +01001774 BYTE bitsToWeight[HUF_ABSOLUTEMAX_TABLELOG + 1];
Yann Collete8c6bb12015-07-26 00:23:57 +01001775 BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];
1776 U32 n;
1777 BYTE* op = (BYTE*)dst;
1778 size_t size;
Yann Collet4856a002015-01-24 01:58:16 +01001779
Yann Colleta7875502015-08-07 15:21:00 +01001780 /* check conditions */
Yann Collete8c6bb12015-07-26 00:23:57 +01001781 if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE + 1)
1782 return (size_t)-FSE_ERROR_GENERIC;
Yann Collet4856a002015-01-24 01:58:16 +01001783
Yann Colleta7875502015-08-07 15:21:00 +01001784 /* convert to weight */
1785 bitsToWeight[0] = 0;
1786 for (n=1; n<=huffLog; n++)
1787 bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
Yann Collete8c6bb12015-07-26 00:23:57 +01001788 for (n=0; n<maxSymbolValue; n++)
Yann Colleta7875502015-08-07 15:21:00 +01001789 huffWeight[n] = bitsToWeight[tree[n].nbBits];
Yann Collet4856a002015-01-24 01:58:16 +01001790
Yann Colleta7875502015-08-07 15:21:00 +01001791 size = FSE_compress(op+1, maxDstSize-1, huffWeight, maxSymbolValue); /* don't need last symbol stat : implied */
Yann Collete8c6bb12015-07-26 00:23:57 +01001792 if (FSE_isError(size)) return size;
Yann Colleta7875502015-08-07 15:21:00 +01001793 if (size >= 128) return (size_t)-FSE_ERROR_GENERIC; /* should never happen, since maxSymbolValue <= 255 */
Yann Collet77c82b62015-08-02 01:19:09 +01001794 if ((size <= 1) || (size >= maxSymbolValue/2))
1795 {
Yann Colleta7875502015-08-07 15:21:00 +01001796 if (size==1) /* RLE */
Yann Collet77c82b62015-08-02 01:19:09 +01001797 {
Yann Colleta7875502015-08-07 15:21:00 +01001798 /* only possible case : serie of 1 (because there are at least 2) */
1799 /* can only be 2^n or (2^n-1), otherwise not an huffman tree */
1800 BYTE code;
1801 switch(maxSymbolValue)
1802 {
1803 case 1: code = 0; break;
1804 case 2: code = 1; break;
1805 case 3: code = 2; break;
1806 case 4: code = 3; break;
1807 case 7: code = 4; break;
1808 case 8: code = 5; break;
1809 case 15: code = 6; break;
1810 case 16: code = 7; break;
1811 case 31: code = 8; break;
1812 case 32: code = 9; break;
1813 case 63: code = 10; break;
1814 case 64: code = 11; break;
1815 case 127: code = 12; break;
1816 case 128: code = 13; break;
1817 default : return (size_t)-FSE_ERROR_corruptionDetected;
1818 }
1819 op[0] = (BYTE)(255-13 + code);
1820 return 1;
Yann Collet77c82b62015-08-02 01:19:09 +01001821 }
Yann Colleta7875502015-08-07 15:21:00 +01001822 /* Not compressible */
1823 if (maxSymbolValue > (241-128)) return (size_t)-FSE_ERROR_GENERIC; /* not implemented (not possible with current format) */
1824 if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* not enough space within dst buffer */
Yann Collet77c82b62015-08-02 01:19:09 +01001825 op[0] = (BYTE)(128 /*special case*/ + 0 /* Not Compressible */ + (maxSymbolValue-1));
Yann Colleta7875502015-08-07 15:21:00 +01001826 huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */
Yann Collet77c82b62015-08-02 01:19:09 +01001827 for (n=0; n<maxSymbolValue; n+=2)
1828 op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
1829 return ((maxSymbolValue+1)/2) + 1;
1830 }
Yann Collet4856a002015-01-24 01:58:16 +01001831
Yann Colleta7875502015-08-07 15:21:00 +01001832 /* normal header case */
Yann Collete8c6bb12015-07-26 00:23:57 +01001833 op[0] = (BYTE)size;
1834 return size+1;
Yann Collet4856a002015-01-24 01:58:16 +01001835}
1836
1837
Yann Collete8c6bb12015-07-26 00:23:57 +01001838static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001839{
Yann Collete8c6bb12015-07-26 00:23:57 +01001840 int totalCost = 0;
1841 const U32 largestBits = huffNode[lastNonNull].nbBits;
Yann Collet4856a002015-01-24 01:58:16 +01001842
Yann Colleta7875502015-08-07 15:21:00 +01001843 /* early exit : all is fine */
Yann Collete8c6bb12015-07-26 00:23:57 +01001844 if (largestBits <= maxNbBits) return largestBits;
Yann Collet4856a002015-01-24 01:58:16 +01001845
Yann Collete8c6bb12015-07-26 00:23:57 +01001846 // now we have a few too large elements (at least >= 2)
Yann Collet4856a002015-01-24 01:58:16 +01001847 {
Yann Collete8c6bb12015-07-26 00:23:57 +01001848 const U32 baseCost = 1 << (largestBits - maxNbBits);
1849 U32 n = lastNonNull;
1850
1851 while (huffNode[n].nbBits > maxNbBits)
Yann Collet4856a002015-01-24 01:58:16 +01001852 {
Yann Collete8c6bb12015-07-26 00:23:57 +01001853 totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
1854 huffNode[n].nbBits = (BYTE)maxNbBits;
1855 n --;
Yann Collet4856a002015-01-24 01:58:16 +01001856 }
Yann Collet4856a002015-01-24 01:58:16 +01001857
Yann Collete8c6bb12015-07-26 00:23:57 +01001858 /* renorm totalCost */
1859 totalCost >>= (largestBits - maxNbBits); /* note : totalCost necessarily multiple of baseCost */
1860
1861 // repay cost
1862 while (huffNode[n].nbBits == maxNbBits) n--; // n at last of rank (maxNbBits-1)
1863
Yann Collet4856a002015-01-24 01:58:16 +01001864 {
Yann Collete8c6bb12015-07-26 00:23:57 +01001865 const U32 noOne = 0xF0F0F0F0;
1866 // Get pos of last (smallest) symbol per rank
1867 U32 rankLast[HUF_MAX_TABLELOG];
1868 U32 currentNbBits = maxNbBits;
1869 int pos;
1870 memset(rankLast, 0xF0, sizeof(rankLast));
1871 for (pos=n ; pos >= 0; pos--)
Yann Collet4856a002015-01-24 01:58:16 +01001872 {
Yann Collete8c6bb12015-07-26 00:23:57 +01001873 if (huffNode[pos].nbBits >= currentNbBits) continue;
1874 currentNbBits = huffNode[pos].nbBits;
1875 rankLast[maxNbBits-currentNbBits] = pos;
1876 }
1877
1878 while (totalCost > 0)
1879 {
1880 U32 nBitsToDecrease = FSE_highbit32(totalCost) + 1;
1881 for ( ; nBitsToDecrease > 1; nBitsToDecrease--)
1882 {
1883 U32 highPos = rankLast[nBitsToDecrease];
1884 U32 lowPos = rankLast[nBitsToDecrease-1];
1885 if (highPos == noOne) continue;
1886 if (lowPos == noOne) break;
1887 {
1888 U32 highTotal = huffNode[highPos].count;
1889 U32 lowTotal = 2 * huffNode[lowPos].count;
1890 if (highTotal <= lowTotal) break;
1891 }
1892 }
1893 while (rankLast[nBitsToDecrease] == noOne)
1894 nBitsToDecrease ++; // In some rare cases, no more rank 1 left => overshoot to closest
1895 totalCost -= 1 << (nBitsToDecrease-1);
1896 if (rankLast[nBitsToDecrease-1] == noOne)
1897 rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; // now there is one elt
1898 huffNode[rankLast[nBitsToDecrease]].nbBits ++;
1899 rankLast[nBitsToDecrease]--;
1900 if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
1901 rankLast[nBitsToDecrease] = noOne; // rank list emptied
1902 }
1903 while (totalCost < 0) // Sometimes, cost correction overshoot
1904 {
1905 if (rankLast[1] == noOne) /* special case, no weight 1, let's find it back at n */
1906 {
1907 while (huffNode[n].nbBits == maxNbBits) n--;
1908 huffNode[n+1].nbBits--;
1909 rankLast[1] = n+1;
1910 totalCost++;
1911 continue;
1912 }
1913 huffNode[ rankLast[1] + 1 ].nbBits--;
1914 rankLast[1]++;
1915 totalCost ++;
1916 }
1917 }
1918 }
1919
1920 return maxNbBits;
1921}
1922
1923
1924typedef struct {
1925 U32 base;
1926 U32 current;
1927} rankPos;
1928
1929static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
1930{
1931 rankPos rank[32];
1932 U32 n;
1933
1934 memset(rank, 0, sizeof(rank));
1935 for (n=0; n<=maxSymbolValue; n++)
1936 {
1937 U32 r = FSE_highbit32(count[n] + 1);
1938 rank[r].base ++;
1939 }
1940 for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
1941 for (n=0; n<32; n++) rank[n].current = rank[n].base;
1942 for (n=0; n<=maxSymbolValue; n++)
1943 {
1944 U32 c = count[n];
1945 U32 r = FSE_highbit32(c+1) + 1;
1946 U32 pos = rank[r].current++;
1947 while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
1948 huffNode[pos].count = c;
1949 huffNode[pos].byte = (BYTE)n;
1950 }
1951}
1952
1953
1954#define STARTNODE (HUF_MAX_SYMBOL_VALUE+1)
1955size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
1956{
1957 nodeElt huffNode0[2*HUF_MAX_SYMBOL_VALUE+1 +1];
1958 nodeElt* huffNode = huffNode0 + 1;
1959 U32 n, nonNullRank;
1960 int lowS, lowN;
1961 U16 nodeNb = STARTNODE;
1962 U32 nodeRoot;
1963
Yann Collete9853b22015-08-07 19:07:32 +01001964 /* safety checks */
Yann Collet77c82b62015-08-02 01:19:09 +01001965 if (maxNbBits == 0) maxNbBits = HUF_DEFAULT_TABLELOG;
1966 if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_GENERIC;
Yann Collete8c6bb12015-07-26 00:23:57 +01001967 memset(huffNode0, 0, sizeof(huffNode0));
1968
1969 // sort, decreasing order
1970 HUF_sort(huffNode, count, maxSymbolValue);
1971
1972 // init for parents
1973 nonNullRank = maxSymbolValue;
1974 while(huffNode[nonNullRank].count == 0) nonNullRank--;
1975 lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
1976 huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
1977 huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
1978 nodeNb++; lowS-=2;
1979 for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
1980 huffNode0[0].count = (U32)(1U<<31);
1981
1982 // create parents
1983 while (nodeNb <= nodeRoot)
1984 {
1985 U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
1986 U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
1987 huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
1988 huffNode[n1].parent = huffNode[n2].parent = nodeNb;
1989 nodeNb++;
1990 }
1991
1992 // distribute weights (unlimited tree height)
1993 huffNode[nodeRoot].nbBits = 0;
1994 for (n=nodeRoot-1; n>=STARTNODE; n--)
1995 huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
1996 for (n=0; n<=nonNullRank; n++)
1997 huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
1998
1999 // enforce maxTableLog
2000 maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
2001
2002 // fill result into tree (val, nbBits)
2003 {
2004 U16 nbPerRank[HUF_ABSOLUTEMAX_TABLELOG+1] = {0};
2005 U16 valPerRank[HUF_ABSOLUTEMAX_TABLELOG+1];
2006 if (maxNbBits > HUF_ABSOLUTEMAX_TABLELOG) return (size_t)-FSE_ERROR_GENERIC; // check
2007 for (n=0; n<=nonNullRank; n++)
2008 nbPerRank[huffNode[n].nbBits]++;
2009 {
2010 // determine stating value per rank
2011 U16 min = 0;
2012 for (n=maxNbBits; n>0; n--)
2013 {
2014 valPerRank[n] = min; // get starting value within each rank
2015 min += nbPerRank[n];
2016 min >>= 1;
Yann Collet4856a002015-01-24 01:58:16 +01002017 }
2018 }
Yann Collete8c6bb12015-07-26 00:23:57 +01002019 for (n=0; n<=maxSymbolValue; n++)
2020 tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; // push nbBits per symbol, symbol order
2021 for (n=0; n<=maxSymbolValue; n++)
2022 tree[n].val = valPerRank[tree[n].nbBits]++; // assign value within rank, symbol order
Yann Collet4856a002015-01-24 01:58:16 +01002023 }
2024
Yann Collete8c6bb12015-07-26 00:23:57 +01002025 return maxNbBits;
Yann Collet4856a002015-01-24 01:58:16 +01002026}
2027
Yann Collet77c82b62015-08-02 01:19:09 +01002028static void HUF_encodeSymbol(FSE_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
2029{
2030 FSE_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
2031}
2032
2033#define FSE_FLUSHBITS_1(stream) \
Yann Colleta7875502015-08-07 15:21:00 +01002034 if (sizeof((stream)->bitContainer)*8 < HUF_MAX_TABLELOG*2+7) FSE_FLUSHBITS(stream)
Yann Collet77c82b62015-08-02 01:19:09 +01002035
2036#define FSE_FLUSHBITS_2(stream) \
Yann Colleta7875502015-08-07 15:21:00 +01002037 if (sizeof((stream)->bitContainer)*8 < HUF_MAX_TABLELOG*4+7) FSE_FLUSHBITS(stream)
Yann Collet4856a002015-01-24 01:58:16 +01002038
Yann Colleta7875502015-08-07 15:21:00 +01002039size_t HUF_compress_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, HUF_CElt* CTable)
Yann Collet4856a002015-01-24 01:58:16 +01002040{
Yann Collete8c6bb12015-07-26 00:23:57 +01002041 const BYTE* ip = (const BYTE*) src;
2042 BYTE* const ostart = (BYTE*)dst;
2043 BYTE* op = (BYTE*) ostart;
Yann Colleta7875502015-08-07 15:21:00 +01002044 BYTE* const oend = ostart + dstSize;
Yann Collete8c6bb12015-07-26 00:23:57 +01002045 U16* jumpTable = (U16*) dst;
2046 size_t n, streamSize;
Yann Colleta7875502015-08-07 15:21:00 +01002047 const unsigned fast = (dstSize >= HUF_BLOCKBOUND(srcSize));
2048 size_t errorCode;
Yann Collete8c6bb12015-07-26 00:23:57 +01002049 FSE_CStream_t bitC;
Yann Collet4856a002015-01-24 01:58:16 +01002050
Yann Collete8c6bb12015-07-26 00:23:57 +01002051 /* init */
Yann Collet997f9ee2015-08-21 02:44:20 +01002052 if (dstSize < 8) return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +01002053 op += 6; /* jump Table -- could be optimized by delta / deviation */
Yann Collete9853b22015-08-07 19:07:32 +01002054 errorCode = FSE_initCStream(&bitC, op, oend-op);
Yann Colleta7875502015-08-07 15:21:00 +01002055 if (FSE_isError(errorCode)) return 0;
Yann Collet4856a002015-01-24 01:58:16 +01002056
Yann Collete8c6bb12015-07-26 00:23:57 +01002057 n = srcSize & ~15; // mod 16
2058 switch (srcSize & 15)
Yann Collet4856a002015-01-24 01:58:16 +01002059 {
Yann Collet77c82b62015-08-02 01:19:09 +01002060 case 15: HUF_encodeSymbol(&bitC, ip[n+14], CTable);
2061 FSE_FLUSHBITS_1(&bitC);
2062 case 14: HUF_encodeSymbol(&bitC, ip[n+13], CTable);
2063 FSE_FLUSHBITS_2(&bitC);
2064 case 13: HUF_encodeSymbol(&bitC, ip[n+12], CTable);
2065 FSE_FLUSHBITS_1(&bitC);
2066 case 12: HUF_encodeSymbol(&bitC, ip[n+11], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002067 FSE_FLUSHBITS(&bitC);
Yann Collet77c82b62015-08-02 01:19:09 +01002068 case 11: HUF_encodeSymbol(&bitC, ip[n+10], CTable);
2069 FSE_FLUSHBITS_1(&bitC);
2070 case 10: HUF_encodeSymbol(&bitC, ip[n+ 9], CTable);
2071 FSE_FLUSHBITS_2(&bitC);
2072 case 9 : HUF_encodeSymbol(&bitC, ip[n+ 8], CTable);
2073 FSE_FLUSHBITS_1(&bitC);
2074 case 8 : HUF_encodeSymbol(&bitC, ip[n+ 7], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002075 FSE_FLUSHBITS(&bitC);
Yann Collet77c82b62015-08-02 01:19:09 +01002076 case 7 : HUF_encodeSymbol(&bitC, ip[n+ 6], CTable);
2077 FSE_FLUSHBITS_1(&bitC);
2078 case 6 : HUF_encodeSymbol(&bitC, ip[n+ 5], CTable);
2079 FSE_FLUSHBITS_2(&bitC);
2080 case 5 : HUF_encodeSymbol(&bitC, ip[n+ 4], CTable);
2081 FSE_FLUSHBITS_1(&bitC);
2082 case 4 : HUF_encodeSymbol(&bitC, ip[n+ 3], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002083 FSE_FLUSHBITS(&bitC);
Yann Collet77c82b62015-08-02 01:19:09 +01002084 case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
2085 FSE_FLUSHBITS_2(&bitC);
2086 case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
2087 FSE_FLUSHBITS_1(&bitC);
2088 case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002089 FSE_FLUSHBITS(&bitC);
Yann Collete8c6bb12015-07-26 00:23:57 +01002090 case 0 :
2091 default: ;
Yann Collet4856a002015-01-24 01:58:16 +01002092 }
2093
Yann Collete8c6bb12015-07-26 00:23:57 +01002094 for (; n>0; n-=16)
Yann Collet4856a002015-01-24 01:58:16 +01002095 {
Yann Collet77c82b62015-08-02 01:19:09 +01002096 HUF_encodeSymbol(&bitC, ip[n- 4], CTable);
2097 FSE_FLUSHBITS_1(&bitC);
2098 HUF_encodeSymbol(&bitC, ip[n- 8], CTable);
2099 FSE_FLUSHBITS_2(&bitC);
2100 HUF_encodeSymbol(&bitC, ip[n-12], CTable);
2101 FSE_FLUSHBITS_1(&bitC);
2102 HUF_encodeSymbol(&bitC, ip[n-16], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002103 FSE_FLUSHBITS(&bitC);
Yann Collete8c6bb12015-07-26 00:23:57 +01002104 }
2105 streamSize = FSE_closeCStream(&bitC);
Yann Colleta7875502015-08-07 15:21:00 +01002106 if (streamSize==0) return 0; /* not enough space within dst buffer == uncompressible */
Yann Collet138db212015-07-27 20:19:21 +01002107 FSE_writeLE16(jumpTable, (U16)streamSize);
Yann Collete8c6bb12015-07-26 00:23:57 +01002108 op += streamSize;
2109
Yann Colleta7875502015-08-07 15:21:00 +01002110 errorCode = FSE_initCStream(&bitC, op, oend-op);
2111 if (FSE_isError(errorCode)) return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +01002112 n = srcSize & ~15; // mod 16
2113 for (; n>0; n-=16)
2114 {
Yann Collet77c82b62015-08-02 01:19:09 +01002115 HUF_encodeSymbol(&bitC, ip[n- 3], CTable);
2116 FSE_FLUSHBITS_1(&bitC);
2117 HUF_encodeSymbol(&bitC, ip[n- 7], CTable);
2118 FSE_FLUSHBITS_2(&bitC);
2119 HUF_encodeSymbol(&bitC, ip[n-11], CTable);
2120 FSE_FLUSHBITS_1(&bitC);
2121 HUF_encodeSymbol(&bitC, ip[n-15], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002122 FSE_FLUSHBITS(&bitC);
Yann Collete8c6bb12015-07-26 00:23:57 +01002123 }
2124 streamSize = FSE_closeCStream(&bitC);
Yann Colleta7875502015-08-07 15:21:00 +01002125 if (streamSize==0) return 0; /* not enough space within dst buffer == uncompressible */
Yann Collet138db212015-07-27 20:19:21 +01002126 FSE_writeLE16(jumpTable+1, (U16)streamSize);
Yann Collete8c6bb12015-07-26 00:23:57 +01002127 op += streamSize;
2128
Yann Colleta7875502015-08-07 15:21:00 +01002129 errorCode = FSE_initCStream(&bitC, op, oend-op);
2130 if (FSE_isError(errorCode)) return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +01002131 n = srcSize & ~15; // mod 16
2132 for (; n>0; n-=16)
2133 {
Yann Collet77c82b62015-08-02 01:19:09 +01002134 HUF_encodeSymbol(&bitC, ip[n- 2], CTable);
2135 FSE_FLUSHBITS_1(&bitC);
2136 HUF_encodeSymbol(&bitC, ip[n- 6], CTable);
2137 FSE_FLUSHBITS_2(&bitC);
2138 HUF_encodeSymbol(&bitC, ip[n-10], CTable);
2139 FSE_FLUSHBITS_1(&bitC);
2140 HUF_encodeSymbol(&bitC, ip[n-14], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002141 FSE_FLUSHBITS(&bitC);
Yann Collete8c6bb12015-07-26 00:23:57 +01002142 }
2143 streamSize = FSE_closeCStream(&bitC);
Yann Colleta7875502015-08-07 15:21:00 +01002144 if (streamSize==0) return 0; /* not enough space within dst buffer == uncompressible */
Yann Collet138db212015-07-27 20:19:21 +01002145 FSE_writeLE16(jumpTable+2, (U16)streamSize);
Yann Collete8c6bb12015-07-26 00:23:57 +01002146 op += streamSize;
2147
Yann Colleta7875502015-08-07 15:21:00 +01002148 errorCode = FSE_initCStream(&bitC, op, oend-op);
2149 if (FSE_isError(errorCode)) return 0;
Yann Collete8c6bb12015-07-26 00:23:57 +01002150 n = srcSize & ~15; // mod 16
2151 for (; n>0; n-=16)
2152 {
Yann Collet77c82b62015-08-02 01:19:09 +01002153 HUF_encodeSymbol(&bitC, ip[n- 1], CTable);
2154 FSE_FLUSHBITS_1(&bitC);
2155 HUF_encodeSymbol(&bitC, ip[n- 5], CTable);
2156 FSE_FLUSHBITS_2(&bitC);
2157 HUF_encodeSymbol(&bitC, ip[n- 9], CTable);
2158 FSE_FLUSHBITS_1(&bitC);
2159 HUF_encodeSymbol(&bitC, ip[n-13], CTable);
Yann Colleta7875502015-08-07 15:21:00 +01002160 FSE_FLUSHBITS(&bitC);
Yann Collete8c6bb12015-07-26 00:23:57 +01002161 }
2162 streamSize = FSE_closeCStream(&bitC);
Yann Colleta7875502015-08-07 15:21:00 +01002163 if (streamSize==0) return 0; /* not enough space within dst buffer == uncompressible */
Yann Collete8c6bb12015-07-26 00:23:57 +01002164 op += streamSize;
2165
2166 return op-ostart;
2167}
2168
2169
2170size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog)
2171{
2172 BYTE* const ostart = (BYTE*)dst;
2173 BYTE* op = ostart;
2174 BYTE* const oend = ostart + dstSize;
2175
2176 U32 count[HUF_MAX_SYMBOL_VALUE+1];
2177 HUF_CElt CTable[HUF_MAX_SYMBOL_VALUE+1];
2178 size_t errorCode;
2179
2180 /* early out */
Yann Collete8c6bb12015-07-26 00:23:57 +01002181 if (srcSize <= 1) return srcSize; /* Uncompressed or RLE */
2182 if (!maxSymbolValue) maxSymbolValue = HUF_MAX_SYMBOL_VALUE;
2183 if (!huffLog) huffLog = HUF_DEFAULT_TABLELOG;
2184
2185 /* Scan input and build symbol stats */
2186 errorCode = FSE_count (count, &maxSymbolValue, (const BYTE*)src, srcSize);
2187 if (FSE_isError(errorCode)) return errorCode;
2188 if (errorCode == srcSize) return 1;
2189 if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
2190
2191 /* Build Huffman Tree */
2192 errorCode = HUF_buildCTable (CTable, count, maxSymbolValue, huffLog);
2193 if (FSE_isError(errorCode)) return errorCode;
2194 huffLog = (U32)errorCode;
2195
2196 /* Write table description header */
2197 errorCode = HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog); /* don't write last symbol, implied */
2198 if (FSE_isError(errorCode)) return errorCode;
2199 op += errorCode;
2200
2201 /* Compress */
Yann Collete9853b22015-08-07 19:07:32 +01002202 errorCode = HUF_compress_usingCTable(op, oend - op, src, srcSize, CTable);
2203 if (FSE_isError(errorCode)) return errorCode;
2204 if (errorCode==0) return 0;
2205 op += errorCode;
Yann Collete8c6bb12015-07-26 00:23:57 +01002206
2207 /* check compressibility */
2208 if ((size_t)(op-ostart) >= srcSize-1)
Yann Colleta7875502015-08-07 15:21:00 +01002209 return op-ostart;
Yann Collete8c6bb12015-07-26 00:23:57 +01002210
2211 return op-ostart;
2212}
2213
2214size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
2215{
2216 return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_DEFAULT_TABLELOG);
2217}
2218
2219
2220/*********************************************************
2221* Huff0 : Huffman block decompression
2222*********************************************************/
2223typedef struct {
2224 BYTE byte;
2225 BYTE nbBits;
2226} HUF_DElt;
2227
2228size_t HUF_readDTable (U16* DTable, const void* src, size_t srcSize)
2229{
2230 BYTE huffWeight[HUF_MAX_SYMBOL_VALUE + 1];
Yann Colleta7875502015-08-07 15:21:00 +01002231 U32 rankVal[HUF_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */
2232 U32 weightTotal;
Yann Collete8c6bb12015-07-26 00:23:57 +01002233 U32 maxBits;
2234 const BYTE* ip = (const BYTE*) src;
2235 size_t iSize = ip[0];
2236 size_t oSize;
2237 U32 n;
2238 U32 nextRankStart;
2239 HUF_DElt* const dt = (HUF_DElt*)(DTable + 1);
2240
Yann Colleta7875502015-08-07 15:21:00 +01002241 FSE_STATIC_ASSERT(sizeof(HUF_DElt) == sizeof(U16)); /* if compilation fails here, assertion is false */
2242 //memset(huffWeight, 0, sizeof(huffWeight)); /* should not be necessary, but some analyzer complain ... */
2243 if (iSize >= 128) /* special header */
Yann Collet77c82b62015-08-02 01:19:09 +01002244 {
Yann Colleta7875502015-08-07 15:21:00 +01002245 if (iSize >= (242)) /* RLE */
Yann Collet77c82b62015-08-02 01:19:09 +01002246 {
Yann Colleta7875502015-08-07 15:21:00 +01002247 static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 };
2248 oSize = l[iSize-242];
2249 memset(huffWeight, 1, oSize);
2250 iSize = 0;
Yann Collet77c82b62015-08-02 01:19:09 +01002251 }
Yann Colleta7875502015-08-07 15:21:00 +01002252 else /* Incompressible */
Yann Collet77c82b62015-08-02 01:19:09 +01002253 {
Yann Colleta7875502015-08-07 15:21:00 +01002254 oSize = iSize - 127;
Yann Collet77c82b62015-08-02 01:19:09 +01002255 iSize = ((oSize+1)/2);
2256 if (iSize+1 > srcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
2257 ip += 1;
2258 for (n=0; n<oSize; n+=2)
2259 {
Yann Colleta7875502015-08-07 15:21:00 +01002260 huffWeight[n] = ip[n/2] >> 4;
2261 huffWeight[n+1] = ip[n/2] & 15;
Yann Collet77c82b62015-08-02 01:19:09 +01002262 }
2263 }
2264 }
Yann Colleta7875502015-08-07 15:21:00 +01002265 else /* header compressed with FSE (normal case) */
Yann Collet77c82b62015-08-02 01:19:09 +01002266 {
2267 if (iSize+1 > srcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
Yann Colleta7875502015-08-07 15:21:00 +01002268 oSize = FSE_decompress(huffWeight, HUF_MAX_SYMBOL_VALUE, ip+1, iSize); /* max 255 values decoded, last one is implied */
Yann Collet77c82b62015-08-02 01:19:09 +01002269 if (FSE_isError(oSize)) return oSize;
2270 }
Yann Collete8c6bb12015-07-26 00:23:57 +01002271
Yann Colleta7875502015-08-07 15:21:00 +01002272 /* collect weight stats */
2273 memset(rankVal, 0, sizeof(rankVal));
2274 weightTotal = 0;
Yann Collete8c6bb12015-07-26 00:23:57 +01002275 for (n=0; n<oSize; n++)
2276 {
Yann Colleta7875502015-08-07 15:21:00 +01002277 if (huffWeight[n] >= HUF_ABSOLUTEMAX_TABLELOG) return (size_t)-FSE_ERROR_corruptionDetected;
Yann Collete8c6bb12015-07-26 00:23:57 +01002278 rankVal[huffWeight[n]]++;
2279 weightTotal += (1 << huffWeight[n]) >> 1;
Yann Collet4856a002015-01-24 01:58:16 +01002280 }
2281
Yann Colleta7875502015-08-07 15:21:00 +01002282 /* get last non-null symbol weight (implied, total must be 2^n) */
Yann Collete8c6bb12015-07-26 00:23:57 +01002283 maxBits = FSE_highbit32(weightTotal) + 1;
Yann Colleta7875502015-08-07 15:21:00 +01002284 if (maxBits > DTable[0]) return (size_t)-FSE_ERROR_tableLog_tooLarge; /* DTable is too small */
Yann Collete8c6bb12015-07-26 00:23:57 +01002285 DTable[0] = (U16)maxBits;
2286 {
2287 U32 total = 1 << maxBits;
2288 U32 rest = total - weightTotal;
2289 U32 verif = 1 << FSE_highbit32(rest);
Yann Colleta7875502015-08-07 15:21:00 +01002290 U32 lastWeight = FSE_highbit32(rest) + 1;
2291 if (verif != rest) return (size_t)-FSE_ERROR_corruptionDetected; /* last value must be a clean power of 2 */
2292 huffWeight[oSize] = (BYTE)lastWeight;
2293 rankVal[lastWeight]++;
Yann Collete8c6bb12015-07-26 00:23:57 +01002294 }
Yann Collet4856a002015-01-24 01:58:16 +01002295
Yann Colleta7875502015-08-07 15:21:00 +01002296 /* check tree construction validity */
2297 if ((rankVal[1] < 2) || (rankVal[1] & 1)) return (size_t)-FSE_ERROR_corruptionDetected; /* by construction : at least 2 elts of rank 1, must be even */
2298
2299 /* Prepare ranks */
Yann Collete8c6bb12015-07-26 00:23:57 +01002300 nextRankStart = 0;
2301 for (n=1; n<=maxBits; n++)
2302 {
2303 U32 current = nextRankStart;
2304 nextRankStart += (rankVal[n] << (n-1));
2305 rankVal[n] = current;
2306 }
2307
Yann Colleta7875502015-08-07 15:21:00 +01002308 /* fill DTable */
Yann Collete8c6bb12015-07-26 00:23:57 +01002309 for (n=0; n<=oSize; n++)
Yann Collet4856a002015-01-24 01:58:16 +01002310 {
Yann Collete8c6bb12015-07-26 00:23:57 +01002311 const U32 w = huffWeight[n];
2312 const U32 length = (1 << w) >> 1;
Yann Colleta7875502015-08-07 15:21:00 +01002313 U32 i;
Yann Collete8c6bb12015-07-26 00:23:57 +01002314 HUF_DElt D;
2315 D.byte = (BYTE)n; D.nbBits = (BYTE)(maxBits + 1 - w);
2316 for (i = rankVal[w]; i < rankVal[w] + length; i++)
2317 dt[i] = D;
2318 rankVal[w] += length;
Yann Collet4856a002015-01-24 01:58:16 +01002319 }
2320
Yann Collete8c6bb12015-07-26 00:23:57 +01002321 return iSize+1;
Yann Collet4856a002015-01-24 01:58:16 +01002322}
Yann Collete8c6bb12015-07-26 00:23:57 +01002323
Yann Colleta7875502015-08-07 15:21:00 +01002324
2325static BYTE HUF_decodeSymbol(FSE_DStream_t* Dstream, const HUF_DElt* dt, const U32 dtLog)
Yann Collete8c6bb12015-07-26 00:23:57 +01002326{
Yann Colleta7875502015-08-07 15:21:00 +01002327 const size_t val = FSE_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
2328 const BYTE c = dt[val].byte;
Yann Collete8c6bb12015-07-26 00:23:57 +01002329 FSE_skipBits(Dstream, dt[val].nbBits);
Yann Colleta7875502015-08-07 15:21:00 +01002330 return c;
Yann Collete8c6bb12015-07-26 00:23:57 +01002331}
2332
Yann Colleta7875502015-08-07 15:21:00 +01002333static size_t HUF_decompress_usingDTable( /* -3% slower when non static */
Yann Collete8c6bb12015-07-26 00:23:57 +01002334 void* dst, size_t maxDstSize,
2335 const void* cSrc, size_t cSrcSize,
2336 const U16* DTable)
2337{
2338 BYTE* const ostart = (BYTE*) dst;
2339 BYTE* op = ostart;
2340 BYTE* const omax = op + maxDstSize;
2341 BYTE* const olimit = omax-15;
2342
2343 const HUF_DElt* const dt = (const HUF_DElt*)(DTable+1);
2344 const U32 dtLog = DTable[0];
2345 size_t errorCode;
2346 U32 reloadStatus;
2347
2348 /* Init */
2349
2350 const U16* jumpTable = (const U16*)cSrc;
Yann Collet138db212015-07-27 20:19:21 +01002351 const size_t length1 = FSE_readLE16(jumpTable);
2352 const size_t length2 = FSE_readLE16(jumpTable+1);
2353 const size_t length3 = FSE_readLE16(jumpTable+2);
Yann Collete8c6bb12015-07-26 00:23:57 +01002354 const size_t length4 = cSrcSize - 6 - length1 - length2 - length3; // check coherency !!
2355 const char* const start1 = (const char*)(cSrc) + 6;
2356 const char* const start2 = start1 + length1;
2357 const char* const start3 = start2 + length2;
2358 const char* const start4 = start3 + length3;
2359 FSE_DStream_t bitD1, bitD2, bitD3, bitD4;
2360
Yann Colleta7875502015-08-07 15:21:00 +01002361 if (length1+length2+length3+6 >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
2362
Yann Collete8c6bb12015-07-26 00:23:57 +01002363 errorCode = FSE_initDStream(&bitD1, start1, length1);
2364 if (FSE_isError(errorCode)) return errorCode;
2365 errorCode = FSE_initDStream(&bitD2, start2, length2);
2366 if (FSE_isError(errorCode)) return errorCode;
2367 errorCode = FSE_initDStream(&bitD3, start3, length3);
2368 if (FSE_isError(errorCode)) return errorCode;
2369 errorCode = FSE_initDStream(&bitD4, start4, length4);
2370 if (FSE_isError(errorCode)) return errorCode;
2371
2372 reloadStatus=FSE_reloadDStream(&bitD2);
2373
2374 /* 16 symbols per loop */
2375 for ( ; (reloadStatus<FSE_DStream_completed) && (op<olimit); /* D2-3-4 are supposed to be synchronized and finish together */
2376 op+=16, reloadStatus = FSE_reloadDStream(&bitD2) | FSE_reloadDStream(&bitD3) | FSE_reloadDStream(&bitD4), FSE_reloadDStream(&bitD1))
2377 {
Yann Colletfb8296f2015-07-27 19:34:27 +01002378#define HUF_DECODE_SYMBOL_0(n, Dstream) \
Yann Colleta7875502015-08-07 15:21:00 +01002379 op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog);
Yann Colletfb8296f2015-07-27 19:34:27 +01002380
2381#define HUF_DECODE_SYMBOL_1(n, Dstream) \
Yann Colleta7875502015-08-07 15:21:00 +01002382 op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
Yann Colletfb8296f2015-07-27 19:34:27 +01002383 if (FSE_32bits() && (HUF_MAX_TABLELOG>12)) FSE_reloadDStream(&Dstream)
2384
2385#define HUF_DECODE_SYMBOL_2(n, Dstream) \
Yann Colleta7875502015-08-07 15:21:00 +01002386 op[n] = HUF_decodeSymbol(&Dstream, dt, dtLog); \
Yann Collete8c6bb12015-07-26 00:23:57 +01002387 if (FSE_32bits()) FSE_reloadDStream(&Dstream)
2388
Yann Colletfb8296f2015-07-27 19:34:27 +01002389 HUF_DECODE_SYMBOL_1( 0, bitD1);
2390 HUF_DECODE_SYMBOL_1( 1, bitD2);
2391 HUF_DECODE_SYMBOL_1( 2, bitD3);
2392 HUF_DECODE_SYMBOL_1( 3, bitD4);
2393 HUF_DECODE_SYMBOL_2( 4, bitD1);
2394 HUF_DECODE_SYMBOL_2( 5, bitD2);
2395 HUF_DECODE_SYMBOL_2( 6, bitD3);
2396 HUF_DECODE_SYMBOL_2( 7, bitD4);
2397 HUF_DECODE_SYMBOL_1( 8, bitD1);
2398 HUF_DECODE_SYMBOL_1( 9, bitD2);
2399 HUF_DECODE_SYMBOL_1(10, bitD3);
2400 HUF_DECODE_SYMBOL_1(11, bitD4);
2401 HUF_DECODE_SYMBOL_0(12, bitD1);
2402 HUF_DECODE_SYMBOL_0(13, bitD2);
2403 HUF_DECODE_SYMBOL_0(14, bitD3);
2404 HUF_DECODE_SYMBOL_0(15, bitD4);
Yann Collete8c6bb12015-07-26 00:23:57 +01002405 }
2406
Yann Colleta7875502015-08-07 15:21:00 +01002407 if (reloadStatus!=FSE_DStream_completed) /* not complete : some bitStream might be FSE_DStream_unfinished */
Yann Collete8c6bb12015-07-26 00:23:57 +01002408 return (size_t)-FSE_ERROR_corruptionDetected;
2409
2410 /* tail */
2411 {
2412 // bitTail = bitD1; // *much* slower : -20% !??!
2413 FSE_DStream_t bitTail;
2414 bitTail.ptr = bitD1.ptr;
2415 bitTail.bitsConsumed = bitD1.bitsConsumed;
Yann Colleta7875502015-08-07 15:21:00 +01002416 bitTail.bitContainer = bitD1.bitContainer; // required in case of FSE_DStream_endOfBuffer
Yann Collete8c6bb12015-07-26 00:23:57 +01002417 bitTail.start = start1;
2418 for ( ; (FSE_reloadDStream(&bitTail) < FSE_DStream_completed) && (op<omax) ; op++)
2419 {
Yann Colletfb8296f2015-07-27 19:34:27 +01002420 HUF_DECODE_SYMBOL_0(0, bitTail);
Yann Collete8c6bb12015-07-26 00:23:57 +01002421 }
2422
2423 if (FSE_endOfDStream(&bitTail))
2424 return op-ostart;
2425 }
2426
2427 if (op==omax) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* dst buffer is full, but cSrc unfinished */
2428
2429 return (size_t)-FSE_ERROR_corruptionDetected;
2430}
2431
2432
2433size_t HUF_decompress (void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize)
2434{
2435 HUF_CREATE_STATIC_DTABLE(DTable, HUF_MAX_TABLELOG);
2436 const BYTE* ip = (const BYTE*) cSrc;
2437 size_t errorCode;
2438
2439 errorCode = HUF_readDTable (DTable, cSrc, cSrcSize);
2440 if (FSE_isError(errorCode)) return errorCode;
2441 if (errorCode >= cSrcSize) return (size_t)-FSE_ERROR_srcSize_wrong;
2442 ip += errorCode;
2443 cSrcSize -= errorCode;
2444
2445 return HUF_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, DTable);
2446}
2447
2448
2449#endif /* FSE_COMMONDEFS_ONLY */