2 * FSE : Finite State Entropy decoder
3 * Copyright (C) 2013-2015, Yann Collet.
5 * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
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
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.
30 * This program is free software; you can redistribute it and/or modify it under
31 * the terms of the GNU General Public License version 2 as published by the
32 * Free Software Foundation. This program is dual-licensed; you may select
33 * either version 2 of the GNU General Public License ("GPL") or BSD license
36 * You can contact the author at :
37 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
40 /* **************************************************************
42 ****************************************************************/
43 #define FORCE_INLINE static __always_inline
45 /* **************************************************************
47 ****************************************************************/
48 #include "bitstream.h"
50 #include "zstd_internal.h"
51 #include <linux/compiler.h>
52 #include <linux/kernel.h>
53 #include <linux/string.h> /* memcpy, memset */
55 /* **************************************************************
57 ****************************************************************/
58 #define FSE_isError ERR_isError
59 #define FSE_STATIC_ASSERT(c) \
61 enum { FSE_static_assert = 1 / (int)(!!(c)) }; \
62 } /* use only *after* variable declarations */
64 /* **************************************************************
66 ****************************************************************/
68 designed to be included
69 for type-specific functions (template emulation in C)
70 Objective is to write these functions only once, for improved maintenance
74 #ifndef FSE_FUNCTION_EXTENSION
75 #error "FSE_FUNCTION_EXTENSION must be defined"
77 #ifndef FSE_FUNCTION_TYPE
78 #error "FSE_FUNCTION_TYPE must be defined"
82 #define FSE_CAT(X, Y) X##Y
83 #define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y)
84 #define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y)
86 /* Function templates */
88 size_t FSE_buildDTable_wksp(FSE_DTable
*dt
, const short *normalizedCounter
, unsigned maxSymbolValue
, unsigned tableLog
, void *workspace
, size_t workspaceSize
)
90 void *const tdPtr
= dt
+ 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
91 FSE_DECODE_TYPE
*const tableDecode
= (FSE_DECODE_TYPE
*)(tdPtr
);
92 U16
*symbolNext
= (U16
*)workspace
;
94 U32
const maxSV1
= maxSymbolValue
+ 1;
95 U32
const tableSize
= 1 << tableLog
;
96 U32 highThreshold
= tableSize
- 1;
99 if (workspaceSize
< sizeof(U16
) * (FSE_MAX_SYMBOL_VALUE
+ 1))
100 return ERROR(tableLog_tooLarge
);
101 if (maxSymbolValue
> FSE_MAX_SYMBOL_VALUE
)
102 return ERROR(maxSymbolValue_tooLarge
);
103 if (tableLog
> FSE_MAX_TABLELOG
)
104 return ERROR(tableLog_tooLarge
);
106 /* Init, lay down lowprob symbols */
108 FSE_DTableHeader DTableH
;
109 DTableH
.tableLog
= (U16
)tableLog
;
110 DTableH
.fastMode
= 1;
112 S16
const largeLimit
= (S16
)(1 << (tableLog
- 1));
114 for (s
= 0; s
< maxSV1
; s
++) {
115 if (normalizedCounter
[s
] == -1) {
116 tableDecode
[highThreshold
--].symbol
= (FSE_FUNCTION_TYPE
)s
;
119 if (normalizedCounter
[s
] >= largeLimit
)
120 DTableH
.fastMode
= 0;
121 symbolNext
[s
] = normalizedCounter
[s
];
125 memcpy(dt
, &DTableH
, sizeof(DTableH
));
130 U32
const tableMask
= tableSize
- 1;
131 U32
const step
= FSE_TABLESTEP(tableSize
);
133 for (s
= 0; s
< maxSV1
; s
++) {
135 for (i
= 0; i
< normalizedCounter
[s
]; i
++) {
136 tableDecode
[position
].symbol
= (FSE_FUNCTION_TYPE
)s
;
137 position
= (position
+ step
) & tableMask
;
138 while (position
> highThreshold
)
139 position
= (position
+ step
) & tableMask
; /* lowprob area */
143 return ERROR(GENERIC
); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
146 /* Build Decoding table */
149 for (u
= 0; u
< tableSize
; u
++) {
150 FSE_FUNCTION_TYPE
const symbol
= (FSE_FUNCTION_TYPE
)(tableDecode
[u
].symbol
);
151 U16 nextState
= symbolNext
[symbol
]++;
152 tableDecode
[u
].nbBits
= (BYTE
)(tableLog
- BIT_highbit32((U32
)nextState
));
153 tableDecode
[u
].newState
= (U16
)((nextState
<< tableDecode
[u
].nbBits
) - tableSize
);
160 /*-*******************************************************
161 * Decompression (Byte symbols)
162 *********************************************************/
163 size_t FSE_buildDTable_rle(FSE_DTable
*dt
, BYTE symbolValue
)
166 FSE_DTableHeader
*const DTableH
= (FSE_DTableHeader
*)ptr
;
168 FSE_decode_t
*const cell
= (FSE_decode_t
*)dPtr
;
170 DTableH
->tableLog
= 0;
171 DTableH
->fastMode
= 0;
174 cell
->symbol
= symbolValue
;
180 size_t FSE_buildDTable_raw(FSE_DTable
*dt
, unsigned nbBits
)
183 FSE_DTableHeader
*const DTableH
= (FSE_DTableHeader
*)ptr
;
185 FSE_decode_t
*const dinfo
= (FSE_decode_t
*)dPtr
;
186 const unsigned tableSize
= 1 << nbBits
;
187 const unsigned tableMask
= tableSize
- 1;
188 const unsigned maxSV1
= tableMask
+ 1;
193 return ERROR(GENERIC
); /* min size */
195 /* Build Decoding Table */
196 DTableH
->tableLog
= (U16
)nbBits
;
197 DTableH
->fastMode
= 1;
198 for (s
= 0; s
< maxSV1
; s
++) {
199 dinfo
[s
].newState
= 0;
200 dinfo
[s
].symbol
= (BYTE
)s
;
201 dinfo
[s
].nbBits
= (BYTE
)nbBits
;
207 FORCE_INLINE
size_t FSE_decompress_usingDTable_generic(void *dst
, size_t maxDstSize
, const void *cSrc
, size_t cSrcSize
, const FSE_DTable
*dt
,
210 BYTE
*const ostart
= (BYTE
*)dst
;
212 BYTE
*const omax
= op
+ maxDstSize
;
213 BYTE
*const olimit
= omax
- 3;
220 CHECK_F(BIT_initDStream(&bitD
, cSrc
, cSrcSize
));
222 FSE_initDState(&state1
, &bitD
, dt
);
223 FSE_initDState(&state2
, &bitD
, dt
);
225 #define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
227 /* 4 symbols per loop */
228 for (; (BIT_reloadDStream(&bitD
) == BIT_DStream_unfinished
) & (op
< olimit
); op
+= 4) {
229 op
[0] = FSE_GETSYMBOL(&state1
);
231 if (FSE_MAX_TABLELOG
* 2 + 7 > sizeof(bitD
.bitContainer
) * 8) /* This test must be static */
232 BIT_reloadDStream(&bitD
);
234 op
[1] = FSE_GETSYMBOL(&state2
);
236 if (FSE_MAX_TABLELOG
* 4 + 7 > sizeof(bitD
.bitContainer
) * 8) /* This test must be static */
238 if (BIT_reloadDStream(&bitD
) > BIT_DStream_unfinished
) {
244 op
[2] = FSE_GETSYMBOL(&state1
);
246 if (FSE_MAX_TABLELOG
* 2 + 7 > sizeof(bitD
.bitContainer
) * 8) /* This test must be static */
247 BIT_reloadDStream(&bitD
);
249 op
[3] = FSE_GETSYMBOL(&state2
);
253 /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
256 return ERROR(dstSize_tooSmall
);
257 *op
++ = FSE_GETSYMBOL(&state1
);
258 if (BIT_reloadDStream(&bitD
) == BIT_DStream_overflow
) {
259 *op
++ = FSE_GETSYMBOL(&state2
);
264 return ERROR(dstSize_tooSmall
);
265 *op
++ = FSE_GETSYMBOL(&state2
);
266 if (BIT_reloadDStream(&bitD
) == BIT_DStream_overflow
) {
267 *op
++ = FSE_GETSYMBOL(&state1
);
275 size_t FSE_decompress_usingDTable(void *dst
, size_t originalSize
, const void *cSrc
, size_t cSrcSize
, const FSE_DTable
*dt
)
277 const void *ptr
= dt
;
278 const FSE_DTableHeader
*DTableH
= (const FSE_DTableHeader
*)ptr
;
279 const U32 fastMode
= DTableH
->fastMode
;
281 /* select fast mode (static) */
283 return FSE_decompress_usingDTable_generic(dst
, originalSize
, cSrc
, cSrcSize
, dt
, 1);
284 return FSE_decompress_usingDTable_generic(dst
, originalSize
, cSrc
, cSrcSize
, dt
, 0);
287 size_t FSE_decompress_wksp(void *dst
, size_t dstCapacity
, const void *cSrc
, size_t cSrcSize
, unsigned maxLog
, void *workspace
, size_t workspaceSize
)
289 const BYTE
*const istart
= (const BYTE
*)cSrc
;
290 const BYTE
*ip
= istart
;
292 unsigned maxSymbolValue
= FSE_MAX_SYMBOL_VALUE
;
297 size_t spaceUsed32
= 0;
299 FSE_STATIC_ASSERT(sizeof(FSE_DTable
) == sizeof(U32
));
301 dt
= (FSE_DTable
*)((U32
*)workspace
+ spaceUsed32
);
302 spaceUsed32
+= FSE_DTABLE_SIZE_U32(maxLog
);
303 counting
= (short *)((U32
*)workspace
+ spaceUsed32
);
304 spaceUsed32
+= ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE
+ 1), sizeof(U32
)) >> 2;
306 if ((spaceUsed32
<< 2) > workspaceSize
)
307 return ERROR(tableLog_tooLarge
);
308 workspace
= (U32
*)workspace
+ spaceUsed32
;
309 workspaceSize
-= (spaceUsed32
<< 2);
311 /* normal FSE decoding mode */
312 NCountLength
= FSE_readNCount(counting
, &maxSymbolValue
, &tableLog
, istart
, cSrcSize
);
313 if (FSE_isError(NCountLength
))
315 // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining
316 // case : NCountLength==cSrcSize */
317 if (tableLog
> maxLog
)
318 return ERROR(tableLog_tooLarge
);
320 cSrcSize
-= NCountLength
;
322 CHECK_F(FSE_buildDTable_wksp(dt
, counting
, maxSymbolValue
, tableLog
, workspace
, workspaceSize
));
324 return FSE_decompress_usingDTable(dst
, dstCapacity
, ip
, cSrcSize
, dt
); /* always return, even if it is an error code */