xref: /OK3568_Linux_fs/kernel/lib/zstd/fse_compress.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * FSE : Finite State Entropy encoder
3*4882a593Smuzhiyun  * Copyright (C) 2013-2015, Yann Collet.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Redistribution and use in source and binary forms, with or without
8*4882a593Smuzhiyun  * modification, are permitted provided that the following conditions are
9*4882a593Smuzhiyun  * met:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  *   * Redistributions of source code must retain the above copyright
12*4882a593Smuzhiyun  * notice, this list of conditions and the following disclaimer.
13*4882a593Smuzhiyun  *   * Redistributions in binary form must reproduce the above
14*4882a593Smuzhiyun  * copyright notice, this list of conditions and the following disclaimer
15*4882a593Smuzhiyun  * in the documentation and/or other materials provided with the
16*4882a593Smuzhiyun  * distribution.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19*4882a593Smuzhiyun  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20*4882a593Smuzhiyun  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21*4882a593Smuzhiyun  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22*4882a593Smuzhiyun  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23*4882a593Smuzhiyun  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24*4882a593Smuzhiyun  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*4882a593Smuzhiyun  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*4882a593Smuzhiyun  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*4882a593Smuzhiyun  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28*4882a593Smuzhiyun  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify it under
31*4882a593Smuzhiyun  * the terms of the GNU General Public License version 2 as published by the
32*4882a593Smuzhiyun  * Free Software Foundation. This program is dual-licensed; you may select
33*4882a593Smuzhiyun  * either version 2 of the GNU General Public License ("GPL") or BSD license
34*4882a593Smuzhiyun  * ("BSD").
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * You can contact the author at :
37*4882a593Smuzhiyun  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
38*4882a593Smuzhiyun  */
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* **************************************************************
41*4882a593Smuzhiyun *  Compiler specifics
42*4882a593Smuzhiyun ****************************************************************/
43*4882a593Smuzhiyun #define FORCE_INLINE static __always_inline
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* **************************************************************
46*4882a593Smuzhiyun *  Includes
47*4882a593Smuzhiyun ****************************************************************/
48*4882a593Smuzhiyun #include "bitstream.h"
49*4882a593Smuzhiyun #include "fse.h"
50*4882a593Smuzhiyun #include <linux/compiler.h>
51*4882a593Smuzhiyun #include <linux/kernel.h>
52*4882a593Smuzhiyun #include <linux/math64.h>
53*4882a593Smuzhiyun #include <linux/string.h> /* memcpy, memset */
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /* **************************************************************
56*4882a593Smuzhiyun *  Error Management
57*4882a593Smuzhiyun ****************************************************************/
58*4882a593Smuzhiyun #define FSE_STATIC_ASSERT(c)                                   \
59*4882a593Smuzhiyun 	{                                                      \
60*4882a593Smuzhiyun 		enum { FSE_static_assert = 1 / (int)(!!(c)) }; \
61*4882a593Smuzhiyun 	} /* use only *after* variable declarations */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /* **************************************************************
64*4882a593Smuzhiyun *  Templates
65*4882a593Smuzhiyun ****************************************************************/
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun   designed to be included
68*4882a593Smuzhiyun   for type-specific functions (template emulation in C)
69*4882a593Smuzhiyun   Objective is to write these functions only once, for improved maintenance
70*4882a593Smuzhiyun */
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /* safety checks */
73*4882a593Smuzhiyun #ifndef FSE_FUNCTION_EXTENSION
74*4882a593Smuzhiyun #error "FSE_FUNCTION_EXTENSION must be defined"
75*4882a593Smuzhiyun #endif
76*4882a593Smuzhiyun #ifndef FSE_FUNCTION_TYPE
77*4882a593Smuzhiyun #error "FSE_FUNCTION_TYPE must be defined"
78*4882a593Smuzhiyun #endif
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /* Function names */
81*4882a593Smuzhiyun #define FSE_CAT(X, Y) X##Y
82*4882a593Smuzhiyun #define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y)
83*4882a593Smuzhiyun #define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y)
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /* Function templates */
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun /* FSE_buildCTable_wksp() :
88*4882a593Smuzhiyun  * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
89*4882a593Smuzhiyun  * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
90*4882a593Smuzhiyun  * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
91*4882a593Smuzhiyun  */
FSE_buildCTable_wksp(FSE_CTable * ct,const short * normalizedCounter,unsigned maxSymbolValue,unsigned tableLog,void * workspace,size_t workspaceSize)92*4882a593Smuzhiyun size_t FSE_buildCTable_wksp(FSE_CTable *ct, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	U32 const tableSize = 1 << tableLog;
95*4882a593Smuzhiyun 	U32 const tableMask = tableSize - 1;
96*4882a593Smuzhiyun 	void *const ptr = ct;
97*4882a593Smuzhiyun 	U16 *const tableU16 = ((U16 *)ptr) + 2;
98*4882a593Smuzhiyun 	void *const FSCT = ((U32 *)ptr) + 1 /* header */ + (tableLog ? tableSize >> 1 : 1);
99*4882a593Smuzhiyun 	FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT);
100*4882a593Smuzhiyun 	U32 const step = FSE_TABLESTEP(tableSize);
101*4882a593Smuzhiyun 	U32 highThreshold = tableSize - 1;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	U32 *cumul;
104*4882a593Smuzhiyun 	FSE_FUNCTION_TYPE *tableSymbol;
105*4882a593Smuzhiyun 	size_t spaceUsed32 = 0;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	cumul = (U32 *)workspace + spaceUsed32;
108*4882a593Smuzhiyun 	spaceUsed32 += FSE_MAX_SYMBOL_VALUE + 2;
109*4882a593Smuzhiyun 	tableSymbol = (FSE_FUNCTION_TYPE *)((U32 *)workspace + spaceUsed32);
110*4882a593Smuzhiyun 	spaceUsed32 += ALIGN(sizeof(FSE_FUNCTION_TYPE) * ((size_t)1 << tableLog), sizeof(U32)) >> 2;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	if ((spaceUsed32 << 2) > workspaceSize)
113*4882a593Smuzhiyun 		return ERROR(tableLog_tooLarge);
114*4882a593Smuzhiyun 	workspace = (U32 *)workspace + spaceUsed32;
115*4882a593Smuzhiyun 	workspaceSize -= (spaceUsed32 << 2);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	/* CTable header */
118*4882a593Smuzhiyun 	tableU16[-2] = (U16)tableLog;
119*4882a593Smuzhiyun 	tableU16[-1] = (U16)maxSymbolValue;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	/* For explanations on how to distribute symbol values over the table :
122*4882a593Smuzhiyun 	*  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	/* symbol start positions */
125*4882a593Smuzhiyun 	{
126*4882a593Smuzhiyun 		U32 u;
127*4882a593Smuzhiyun 		cumul[0] = 0;
128*4882a593Smuzhiyun 		for (u = 1; u <= maxSymbolValue + 1; u++) {
129*4882a593Smuzhiyun 			if (normalizedCounter[u - 1] == -1) { /* Low proba symbol */
130*4882a593Smuzhiyun 				cumul[u] = cumul[u - 1] + 1;
131*4882a593Smuzhiyun 				tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u - 1);
132*4882a593Smuzhiyun 			} else {
133*4882a593Smuzhiyun 				cumul[u] = cumul[u - 1] + normalizedCounter[u - 1];
134*4882a593Smuzhiyun 			}
135*4882a593Smuzhiyun 		}
136*4882a593Smuzhiyun 		cumul[maxSymbolValue + 1] = tableSize + 1;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	/* Spread symbols */
140*4882a593Smuzhiyun 	{
141*4882a593Smuzhiyun 		U32 position = 0;
142*4882a593Smuzhiyun 		U32 symbol;
143*4882a593Smuzhiyun 		for (symbol = 0; symbol <= maxSymbolValue; symbol++) {
144*4882a593Smuzhiyun 			int nbOccurences;
145*4882a593Smuzhiyun 			for (nbOccurences = 0; nbOccurences < normalizedCounter[symbol]; nbOccurences++) {
146*4882a593Smuzhiyun 				tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
147*4882a593Smuzhiyun 				position = (position + step) & tableMask;
148*4882a593Smuzhiyun 				while (position > highThreshold)
149*4882a593Smuzhiyun 					position = (position + step) & tableMask; /* Low proba area */
150*4882a593Smuzhiyun 			}
151*4882a593Smuzhiyun 		}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 		if (position != 0)
154*4882a593Smuzhiyun 			return ERROR(GENERIC); /* Must have gone through all positions */
155*4882a593Smuzhiyun 	}
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	/* Build table */
158*4882a593Smuzhiyun 	{
159*4882a593Smuzhiyun 		U32 u;
160*4882a593Smuzhiyun 		for (u = 0; u < tableSize; u++) {
161*4882a593Smuzhiyun 			FSE_FUNCTION_TYPE s = tableSymbol[u];	/* note : static analyzer may not understand tableSymbol is properly initialized */
162*4882a593Smuzhiyun 			tableU16[cumul[s]++] = (U16)(tableSize + u); /* TableU16 : sorted by symbol order; gives next state value */
163*4882a593Smuzhiyun 		}
164*4882a593Smuzhiyun 	}
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	/* Build Symbol Transformation Table */
167*4882a593Smuzhiyun 	{
168*4882a593Smuzhiyun 		unsigned total = 0;
169*4882a593Smuzhiyun 		unsigned s;
170*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
171*4882a593Smuzhiyun 			switch (normalizedCounter[s]) {
172*4882a593Smuzhiyun 			case 0: break;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 			case -1:
175*4882a593Smuzhiyun 			case 1:
176*4882a593Smuzhiyun 				symbolTT[s].deltaNbBits = (tableLog << 16) - (1 << tableLog);
177*4882a593Smuzhiyun 				symbolTT[s].deltaFindState = total - 1;
178*4882a593Smuzhiyun 				total++;
179*4882a593Smuzhiyun 				break;
180*4882a593Smuzhiyun 			default: {
181*4882a593Smuzhiyun 				U32 const maxBitsOut = tableLog - BIT_highbit32(normalizedCounter[s] - 1);
182*4882a593Smuzhiyun 				U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;
183*4882a593Smuzhiyun 				symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
184*4882a593Smuzhiyun 				symbolTT[s].deltaFindState = total - normalizedCounter[s];
185*4882a593Smuzhiyun 				total += normalizedCounter[s];
186*4882a593Smuzhiyun 			}
187*4882a593Smuzhiyun 			}
188*4882a593Smuzhiyun 		}
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	return 0;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun /*-**************************************************************
195*4882a593Smuzhiyun *  FSE NCount encoding-decoding
196*4882a593Smuzhiyun ****************************************************************/
FSE_NCountWriteBound(unsigned maxSymbolValue,unsigned tableLog)197*4882a593Smuzhiyun size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun 	size_t const maxHeaderSize = (((maxSymbolValue + 1) * tableLog) >> 3) + 3;
200*4882a593Smuzhiyun 	return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
FSE_writeNCount_generic(void * header,size_t headerBufferSize,const short * normalizedCounter,unsigned maxSymbolValue,unsigned tableLog,unsigned writeIsSafe)203*4882a593Smuzhiyun static size_t FSE_writeNCount_generic(void *header, size_t headerBufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
204*4882a593Smuzhiyun 				      unsigned writeIsSafe)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun 	BYTE *const ostart = (BYTE *)header;
207*4882a593Smuzhiyun 	BYTE *out = ostart;
208*4882a593Smuzhiyun 	BYTE *const oend = ostart + headerBufferSize;
209*4882a593Smuzhiyun 	int nbBits;
210*4882a593Smuzhiyun 	const int tableSize = 1 << tableLog;
211*4882a593Smuzhiyun 	int remaining;
212*4882a593Smuzhiyun 	int threshold;
213*4882a593Smuzhiyun 	U32 bitStream;
214*4882a593Smuzhiyun 	int bitCount;
215*4882a593Smuzhiyun 	unsigned charnum = 0;
216*4882a593Smuzhiyun 	int previous0 = 0;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	bitStream = 0;
219*4882a593Smuzhiyun 	bitCount = 0;
220*4882a593Smuzhiyun 	/* Table Size */
221*4882a593Smuzhiyun 	bitStream += (tableLog - FSE_MIN_TABLELOG) << bitCount;
222*4882a593Smuzhiyun 	bitCount += 4;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	/* Init */
225*4882a593Smuzhiyun 	remaining = tableSize + 1; /* +1 for extra accuracy */
226*4882a593Smuzhiyun 	threshold = tableSize;
227*4882a593Smuzhiyun 	nbBits = tableLog + 1;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	while (remaining > 1) { /* stops at 1 */
230*4882a593Smuzhiyun 		if (previous0) {
231*4882a593Smuzhiyun 			unsigned start = charnum;
232*4882a593Smuzhiyun 			while (!normalizedCounter[charnum])
233*4882a593Smuzhiyun 				charnum++;
234*4882a593Smuzhiyun 			while (charnum >= start + 24) {
235*4882a593Smuzhiyun 				start += 24;
236*4882a593Smuzhiyun 				bitStream += 0xFFFFU << bitCount;
237*4882a593Smuzhiyun 				if ((!writeIsSafe) && (out > oend - 2))
238*4882a593Smuzhiyun 					return ERROR(dstSize_tooSmall); /* Buffer overflow */
239*4882a593Smuzhiyun 				out[0] = (BYTE)bitStream;
240*4882a593Smuzhiyun 				out[1] = (BYTE)(bitStream >> 8);
241*4882a593Smuzhiyun 				out += 2;
242*4882a593Smuzhiyun 				bitStream >>= 16;
243*4882a593Smuzhiyun 			}
244*4882a593Smuzhiyun 			while (charnum >= start + 3) {
245*4882a593Smuzhiyun 				start += 3;
246*4882a593Smuzhiyun 				bitStream += 3 << bitCount;
247*4882a593Smuzhiyun 				bitCount += 2;
248*4882a593Smuzhiyun 			}
249*4882a593Smuzhiyun 			bitStream += (charnum - start) << bitCount;
250*4882a593Smuzhiyun 			bitCount += 2;
251*4882a593Smuzhiyun 			if (bitCount > 16) {
252*4882a593Smuzhiyun 				if ((!writeIsSafe) && (out > oend - 2))
253*4882a593Smuzhiyun 					return ERROR(dstSize_tooSmall); /* Buffer overflow */
254*4882a593Smuzhiyun 				out[0] = (BYTE)bitStream;
255*4882a593Smuzhiyun 				out[1] = (BYTE)(bitStream >> 8);
256*4882a593Smuzhiyun 				out += 2;
257*4882a593Smuzhiyun 				bitStream >>= 16;
258*4882a593Smuzhiyun 				bitCount -= 16;
259*4882a593Smuzhiyun 			}
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 		{
262*4882a593Smuzhiyun 			int count = normalizedCounter[charnum++];
263*4882a593Smuzhiyun 			int const max = (2 * threshold - 1) - remaining;
264*4882a593Smuzhiyun 			remaining -= count < 0 ? -count : count;
265*4882a593Smuzhiyun 			count++; /* +1 for extra accuracy */
266*4882a593Smuzhiyun 			if (count >= threshold)
267*4882a593Smuzhiyun 				count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
268*4882a593Smuzhiyun 			bitStream += count << bitCount;
269*4882a593Smuzhiyun 			bitCount += nbBits;
270*4882a593Smuzhiyun 			bitCount -= (count < max);
271*4882a593Smuzhiyun 			previous0 = (count == 1);
272*4882a593Smuzhiyun 			if (remaining < 1)
273*4882a593Smuzhiyun 				return ERROR(GENERIC);
274*4882a593Smuzhiyun 			while (remaining < threshold)
275*4882a593Smuzhiyun 				nbBits--, threshold >>= 1;
276*4882a593Smuzhiyun 		}
277*4882a593Smuzhiyun 		if (bitCount > 16) {
278*4882a593Smuzhiyun 			if ((!writeIsSafe) && (out > oend - 2))
279*4882a593Smuzhiyun 				return ERROR(dstSize_tooSmall); /* Buffer overflow */
280*4882a593Smuzhiyun 			out[0] = (BYTE)bitStream;
281*4882a593Smuzhiyun 			out[1] = (BYTE)(bitStream >> 8);
282*4882a593Smuzhiyun 			out += 2;
283*4882a593Smuzhiyun 			bitStream >>= 16;
284*4882a593Smuzhiyun 			bitCount -= 16;
285*4882a593Smuzhiyun 		}
286*4882a593Smuzhiyun 	}
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* flush remaining bitStream */
289*4882a593Smuzhiyun 	if ((!writeIsSafe) && (out > oend - 2))
290*4882a593Smuzhiyun 		return ERROR(dstSize_tooSmall); /* Buffer overflow */
291*4882a593Smuzhiyun 	out[0] = (BYTE)bitStream;
292*4882a593Smuzhiyun 	out[1] = (BYTE)(bitStream >> 8);
293*4882a593Smuzhiyun 	out += (bitCount + 7) / 8;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	if (charnum > maxSymbolValue + 1)
296*4882a593Smuzhiyun 		return ERROR(GENERIC);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	return (out - ostart);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
FSE_writeNCount(void * buffer,size_t bufferSize,const short * normalizedCounter,unsigned maxSymbolValue,unsigned tableLog)301*4882a593Smuzhiyun size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun 	if (tableLog > FSE_MAX_TABLELOG)
304*4882a593Smuzhiyun 		return ERROR(tableLog_tooLarge); /* Unsupported */
305*4882a593Smuzhiyun 	if (tableLog < FSE_MIN_TABLELOG)
306*4882a593Smuzhiyun 		return ERROR(GENERIC); /* Unsupported */
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
309*4882a593Smuzhiyun 		return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun /*-**************************************************************
315*4882a593Smuzhiyun *  Counting histogram
316*4882a593Smuzhiyun ****************************************************************/
317*4882a593Smuzhiyun /*! FSE_count_simple
318*4882a593Smuzhiyun 	This function counts byte values within `src`, and store the histogram into table `count`.
319*4882a593Smuzhiyun 	It doesn't use any additional memory.
320*4882a593Smuzhiyun 	But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
321*4882a593Smuzhiyun 	For this reason, prefer using a table `count` with 256 elements.
322*4882a593Smuzhiyun 	@return : count of most numerous element
323*4882a593Smuzhiyun */
FSE_count_simple(unsigned * count,unsigned * maxSymbolValuePtr,const void * src,size_t srcSize)324*4882a593Smuzhiyun size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	const BYTE *ip = (const BYTE *)src;
327*4882a593Smuzhiyun 	const BYTE *const end = ip + srcSize;
328*4882a593Smuzhiyun 	unsigned maxSymbolValue = *maxSymbolValuePtr;
329*4882a593Smuzhiyun 	unsigned max = 0;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	memset(count, 0, (maxSymbolValue + 1) * sizeof(*count));
332*4882a593Smuzhiyun 	if (srcSize == 0) {
333*4882a593Smuzhiyun 		*maxSymbolValuePtr = 0;
334*4882a593Smuzhiyun 		return 0;
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	while (ip < end)
338*4882a593Smuzhiyun 		count[*ip++]++;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	while (!count[maxSymbolValue])
341*4882a593Smuzhiyun 		maxSymbolValue--;
342*4882a593Smuzhiyun 	*maxSymbolValuePtr = maxSymbolValue;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	{
345*4882a593Smuzhiyun 		U32 s;
346*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++)
347*4882a593Smuzhiyun 			if (count[s] > max)
348*4882a593Smuzhiyun 				max = count[s];
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	return (size_t)max;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun /* FSE_count_parallel_wksp() :
355*4882a593Smuzhiyun  * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
356*4882a593Smuzhiyun  * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
FSE_count_parallel_wksp(unsigned * count,unsigned * maxSymbolValuePtr,const void * source,size_t sourceSize,unsigned checkMax,unsigned * const workSpace)357*4882a593Smuzhiyun static size_t FSE_count_parallel_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned checkMax,
358*4882a593Smuzhiyun 				      unsigned *const workSpace)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	const BYTE *ip = (const BYTE *)source;
361*4882a593Smuzhiyun 	const BYTE *const iend = ip + sourceSize;
362*4882a593Smuzhiyun 	unsigned maxSymbolValue = *maxSymbolValuePtr;
363*4882a593Smuzhiyun 	unsigned max = 0;
364*4882a593Smuzhiyun 	U32 *const Counting1 = workSpace;
365*4882a593Smuzhiyun 	U32 *const Counting2 = Counting1 + 256;
366*4882a593Smuzhiyun 	U32 *const Counting3 = Counting2 + 256;
367*4882a593Smuzhiyun 	U32 *const Counting4 = Counting3 + 256;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	memset(Counting1, 0, 4 * 256 * sizeof(unsigned));
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	/* safety checks */
372*4882a593Smuzhiyun 	if (!sourceSize) {
373*4882a593Smuzhiyun 		memset(count, 0, maxSymbolValue + 1);
374*4882a593Smuzhiyun 		*maxSymbolValuePtr = 0;
375*4882a593Smuzhiyun 		return 0;
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 	if (!maxSymbolValue)
378*4882a593Smuzhiyun 		maxSymbolValue = 255; /* 0 == default */
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	/* by stripes of 16 bytes */
381*4882a593Smuzhiyun 	{
382*4882a593Smuzhiyun 		U32 cached = ZSTD_read32(ip);
383*4882a593Smuzhiyun 		ip += 4;
384*4882a593Smuzhiyun 		while (ip < iend - 15) {
385*4882a593Smuzhiyun 			U32 c = cached;
386*4882a593Smuzhiyun 			cached = ZSTD_read32(ip);
387*4882a593Smuzhiyun 			ip += 4;
388*4882a593Smuzhiyun 			Counting1[(BYTE)c]++;
389*4882a593Smuzhiyun 			Counting2[(BYTE)(c >> 8)]++;
390*4882a593Smuzhiyun 			Counting3[(BYTE)(c >> 16)]++;
391*4882a593Smuzhiyun 			Counting4[c >> 24]++;
392*4882a593Smuzhiyun 			c = cached;
393*4882a593Smuzhiyun 			cached = ZSTD_read32(ip);
394*4882a593Smuzhiyun 			ip += 4;
395*4882a593Smuzhiyun 			Counting1[(BYTE)c]++;
396*4882a593Smuzhiyun 			Counting2[(BYTE)(c >> 8)]++;
397*4882a593Smuzhiyun 			Counting3[(BYTE)(c >> 16)]++;
398*4882a593Smuzhiyun 			Counting4[c >> 24]++;
399*4882a593Smuzhiyun 			c = cached;
400*4882a593Smuzhiyun 			cached = ZSTD_read32(ip);
401*4882a593Smuzhiyun 			ip += 4;
402*4882a593Smuzhiyun 			Counting1[(BYTE)c]++;
403*4882a593Smuzhiyun 			Counting2[(BYTE)(c >> 8)]++;
404*4882a593Smuzhiyun 			Counting3[(BYTE)(c >> 16)]++;
405*4882a593Smuzhiyun 			Counting4[c >> 24]++;
406*4882a593Smuzhiyun 			c = cached;
407*4882a593Smuzhiyun 			cached = ZSTD_read32(ip);
408*4882a593Smuzhiyun 			ip += 4;
409*4882a593Smuzhiyun 			Counting1[(BYTE)c]++;
410*4882a593Smuzhiyun 			Counting2[(BYTE)(c >> 8)]++;
411*4882a593Smuzhiyun 			Counting3[(BYTE)(c >> 16)]++;
412*4882a593Smuzhiyun 			Counting4[c >> 24]++;
413*4882a593Smuzhiyun 		}
414*4882a593Smuzhiyun 		ip -= 4;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	/* finish last symbols */
418*4882a593Smuzhiyun 	while (ip < iend)
419*4882a593Smuzhiyun 		Counting1[*ip++]++;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (checkMax) { /* verify stats will fit into destination table */
422*4882a593Smuzhiyun 		U32 s;
423*4882a593Smuzhiyun 		for (s = 255; s > maxSymbolValue; s--) {
424*4882a593Smuzhiyun 			Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
425*4882a593Smuzhiyun 			if (Counting1[s])
426*4882a593Smuzhiyun 				return ERROR(maxSymbolValue_tooSmall);
427*4882a593Smuzhiyun 		}
428*4882a593Smuzhiyun 	}
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	{
431*4882a593Smuzhiyun 		U32 s;
432*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
433*4882a593Smuzhiyun 			count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
434*4882a593Smuzhiyun 			if (count[s] > max)
435*4882a593Smuzhiyun 				max = count[s];
436*4882a593Smuzhiyun 		}
437*4882a593Smuzhiyun 	}
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	while (!count[maxSymbolValue])
440*4882a593Smuzhiyun 		maxSymbolValue--;
441*4882a593Smuzhiyun 	*maxSymbolValuePtr = maxSymbolValue;
442*4882a593Smuzhiyun 	return (size_t)max;
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun /* FSE_countFast_wksp() :
446*4882a593Smuzhiyun  * Same as FSE_countFast(), but using an externally provided scratch buffer.
447*4882a593Smuzhiyun  * `workSpace` size must be table of >= `1024` unsigned */
FSE_countFast_wksp(unsigned * count,unsigned * maxSymbolValuePtr,const void * source,size_t sourceSize,unsigned * workSpace)448*4882a593Smuzhiyun size_t FSE_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace)
449*4882a593Smuzhiyun {
450*4882a593Smuzhiyun 	if (sourceSize < 1500)
451*4882a593Smuzhiyun 		return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
452*4882a593Smuzhiyun 	return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun /* FSE_count_wksp() :
456*4882a593Smuzhiyun  * Same as FSE_count(), but using an externally provided scratch buffer.
457*4882a593Smuzhiyun  * `workSpace` size must be table of >= `1024` unsigned */
FSE_count_wksp(unsigned * count,unsigned * maxSymbolValuePtr,const void * source,size_t sourceSize,unsigned * workSpace)458*4882a593Smuzhiyun size_t FSE_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun 	if (*maxSymbolValuePtr < 255)
461*4882a593Smuzhiyun 		return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
462*4882a593Smuzhiyun 	*maxSymbolValuePtr = 255;
463*4882a593Smuzhiyun 	return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun /*-**************************************************************
467*4882a593Smuzhiyun *  FSE Compression Code
468*4882a593Smuzhiyun ****************************************************************/
469*4882a593Smuzhiyun /*! FSE_sizeof_CTable() :
470*4882a593Smuzhiyun 	FSE_CTable is a variable size structure which contains :
471*4882a593Smuzhiyun 	`U16 tableLog;`
472*4882a593Smuzhiyun 	`U16 maxSymbolValue;`
473*4882a593Smuzhiyun 	`U16 nextStateNumber[1 << tableLog];`                         // This size is variable
474*4882a593Smuzhiyun 	`FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
475*4882a593Smuzhiyun Allocation is manual (C standard does not support variable-size structures).
476*4882a593Smuzhiyun */
FSE_sizeof_CTable(unsigned maxSymbolValue,unsigned tableLog)477*4882a593Smuzhiyun size_t FSE_sizeof_CTable(unsigned maxSymbolValue, unsigned tableLog)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun 	if (tableLog > FSE_MAX_TABLELOG)
480*4882a593Smuzhiyun 		return ERROR(tableLog_tooLarge);
481*4882a593Smuzhiyun 	return FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue) * sizeof(U32);
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun /* provides the minimum logSize to safely represent a distribution */
FSE_minTableLog(size_t srcSize,unsigned maxSymbolValue)485*4882a593Smuzhiyun static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun 	U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
488*4882a593Smuzhiyun 	U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
489*4882a593Smuzhiyun 	U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
490*4882a593Smuzhiyun 	return minBits;
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun 
FSE_optimalTableLog_internal(unsigned maxTableLog,size_t srcSize,unsigned maxSymbolValue,unsigned minus)493*4882a593Smuzhiyun unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun 	U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
496*4882a593Smuzhiyun 	U32 tableLog = maxTableLog;
497*4882a593Smuzhiyun 	U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
498*4882a593Smuzhiyun 	if (tableLog == 0)
499*4882a593Smuzhiyun 		tableLog = FSE_DEFAULT_TABLELOG;
500*4882a593Smuzhiyun 	if (maxBitsSrc < tableLog)
501*4882a593Smuzhiyun 		tableLog = maxBitsSrc; /* Accuracy can be reduced */
502*4882a593Smuzhiyun 	if (minBits > tableLog)
503*4882a593Smuzhiyun 		tableLog = minBits; /* Need a minimum to safely represent all symbol values */
504*4882a593Smuzhiyun 	if (tableLog < FSE_MIN_TABLELOG)
505*4882a593Smuzhiyun 		tableLog = FSE_MIN_TABLELOG;
506*4882a593Smuzhiyun 	if (tableLog > FSE_MAX_TABLELOG)
507*4882a593Smuzhiyun 		tableLog = FSE_MAX_TABLELOG;
508*4882a593Smuzhiyun 	return tableLog;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun 
FSE_optimalTableLog(unsigned maxTableLog,size_t srcSize,unsigned maxSymbolValue)511*4882a593Smuzhiyun unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
512*4882a593Smuzhiyun {
513*4882a593Smuzhiyun 	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun /* Secondary normalization method.
517*4882a593Smuzhiyun    To be used when primary method fails. */
518*4882a593Smuzhiyun 
FSE_normalizeM2(short * norm,U32 tableLog,const unsigned * count,size_t total,U32 maxSymbolValue)519*4882a593Smuzhiyun static size_t FSE_normalizeM2(short *norm, U32 tableLog, const unsigned *count, size_t total, U32 maxSymbolValue)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun 	short const NOT_YET_ASSIGNED = -2;
522*4882a593Smuzhiyun 	U32 s;
523*4882a593Smuzhiyun 	U32 distributed = 0;
524*4882a593Smuzhiyun 	U32 ToDistribute;
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	/* Init */
527*4882a593Smuzhiyun 	U32 const lowThreshold = (U32)(total >> tableLog);
528*4882a593Smuzhiyun 	U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	for (s = 0; s <= maxSymbolValue; s++) {
531*4882a593Smuzhiyun 		if (count[s] == 0) {
532*4882a593Smuzhiyun 			norm[s] = 0;
533*4882a593Smuzhiyun 			continue;
534*4882a593Smuzhiyun 		}
535*4882a593Smuzhiyun 		if (count[s] <= lowThreshold) {
536*4882a593Smuzhiyun 			norm[s] = -1;
537*4882a593Smuzhiyun 			distributed++;
538*4882a593Smuzhiyun 			total -= count[s];
539*4882a593Smuzhiyun 			continue;
540*4882a593Smuzhiyun 		}
541*4882a593Smuzhiyun 		if (count[s] <= lowOne) {
542*4882a593Smuzhiyun 			norm[s] = 1;
543*4882a593Smuzhiyun 			distributed++;
544*4882a593Smuzhiyun 			total -= count[s];
545*4882a593Smuzhiyun 			continue;
546*4882a593Smuzhiyun 		}
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun 		norm[s] = NOT_YET_ASSIGNED;
549*4882a593Smuzhiyun 	}
550*4882a593Smuzhiyun 	ToDistribute = (1 << tableLog) - distributed;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	if ((total / ToDistribute) > lowOne) {
553*4882a593Smuzhiyun 		/* risk of rounding to zero */
554*4882a593Smuzhiyun 		lowOne = (U32)((total * 3) / (ToDistribute * 2));
555*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
556*4882a593Smuzhiyun 			if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
557*4882a593Smuzhiyun 				norm[s] = 1;
558*4882a593Smuzhiyun 				distributed++;
559*4882a593Smuzhiyun 				total -= count[s];
560*4882a593Smuzhiyun 				continue;
561*4882a593Smuzhiyun 			}
562*4882a593Smuzhiyun 		}
563*4882a593Smuzhiyun 		ToDistribute = (1 << tableLog) - distributed;
564*4882a593Smuzhiyun 	}
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (distributed == maxSymbolValue + 1) {
567*4882a593Smuzhiyun 		/* all values are pretty poor;
568*4882a593Smuzhiyun 		   probably incompressible data (should have already been detected);
569*4882a593Smuzhiyun 		   find max, then give all remaining points to max */
570*4882a593Smuzhiyun 		U32 maxV = 0, maxC = 0;
571*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++)
572*4882a593Smuzhiyun 			if (count[s] > maxC)
573*4882a593Smuzhiyun 				maxV = s, maxC = count[s];
574*4882a593Smuzhiyun 		norm[maxV] += (short)ToDistribute;
575*4882a593Smuzhiyun 		return 0;
576*4882a593Smuzhiyun 	}
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	if (total == 0) {
579*4882a593Smuzhiyun 		/* all of the symbols were low enough for the lowOne or lowThreshold */
580*4882a593Smuzhiyun 		for (s = 0; ToDistribute > 0; s = (s + 1) % (maxSymbolValue + 1))
581*4882a593Smuzhiyun 			if (norm[s] > 0)
582*4882a593Smuzhiyun 				ToDistribute--, norm[s]++;
583*4882a593Smuzhiyun 		return 0;
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	{
587*4882a593Smuzhiyun 		U64 const vStepLog = 62 - tableLog;
588*4882a593Smuzhiyun 		U64 const mid = (1ULL << (vStepLog - 1)) - 1;
589*4882a593Smuzhiyun 		U64 const rStep = div_u64((((U64)1 << vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */
590*4882a593Smuzhiyun 		U64 tmpTotal = mid;
591*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
592*4882a593Smuzhiyun 			if (norm[s] == NOT_YET_ASSIGNED) {
593*4882a593Smuzhiyun 				U64 const end = tmpTotal + (count[s] * rStep);
594*4882a593Smuzhiyun 				U32 const sStart = (U32)(tmpTotal >> vStepLog);
595*4882a593Smuzhiyun 				U32 const sEnd = (U32)(end >> vStepLog);
596*4882a593Smuzhiyun 				U32 const weight = sEnd - sStart;
597*4882a593Smuzhiyun 				if (weight < 1)
598*4882a593Smuzhiyun 					return ERROR(GENERIC);
599*4882a593Smuzhiyun 				norm[s] = (short)weight;
600*4882a593Smuzhiyun 				tmpTotal = end;
601*4882a593Smuzhiyun 			}
602*4882a593Smuzhiyun 		}
603*4882a593Smuzhiyun 	}
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	return 0;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
FSE_normalizeCount(short * normalizedCounter,unsigned tableLog,const unsigned * count,size_t total,unsigned maxSymbolValue)608*4882a593Smuzhiyun size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t total, unsigned maxSymbolValue)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun 	/* Sanity checks */
611*4882a593Smuzhiyun 	if (tableLog == 0)
612*4882a593Smuzhiyun 		tableLog = FSE_DEFAULT_TABLELOG;
613*4882a593Smuzhiyun 	if (tableLog < FSE_MIN_TABLELOG)
614*4882a593Smuzhiyun 		return ERROR(GENERIC); /* Unsupported size */
615*4882a593Smuzhiyun 	if (tableLog > FSE_MAX_TABLELOG)
616*4882a593Smuzhiyun 		return ERROR(tableLog_tooLarge); /* Unsupported size */
617*4882a593Smuzhiyun 	if (tableLog < FSE_minTableLog(total, maxSymbolValue))
618*4882a593Smuzhiyun 		return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	{
621*4882a593Smuzhiyun 		U32 const rtbTable[] = {0, 473195, 504333, 520860, 550000, 700000, 750000, 830000};
622*4882a593Smuzhiyun 		U64 const scale = 62 - tableLog;
623*4882a593Smuzhiyun 		U64 const step = div_u64((U64)1 << 62, (U32)total); /* <== here, one division ! */
624*4882a593Smuzhiyun 		U64 const vStep = 1ULL << (scale - 20);
625*4882a593Smuzhiyun 		int stillToDistribute = 1 << tableLog;
626*4882a593Smuzhiyun 		unsigned s;
627*4882a593Smuzhiyun 		unsigned largest = 0;
628*4882a593Smuzhiyun 		short largestP = 0;
629*4882a593Smuzhiyun 		U32 lowThreshold = (U32)(total >> tableLog);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
632*4882a593Smuzhiyun 			if (count[s] == total)
633*4882a593Smuzhiyun 				return 0; /* rle special case */
634*4882a593Smuzhiyun 			if (count[s] == 0) {
635*4882a593Smuzhiyun 				normalizedCounter[s] = 0;
636*4882a593Smuzhiyun 				continue;
637*4882a593Smuzhiyun 			}
638*4882a593Smuzhiyun 			if (count[s] <= lowThreshold) {
639*4882a593Smuzhiyun 				normalizedCounter[s] = -1;
640*4882a593Smuzhiyun 				stillToDistribute--;
641*4882a593Smuzhiyun 			} else {
642*4882a593Smuzhiyun 				short proba = (short)((count[s] * step) >> scale);
643*4882a593Smuzhiyun 				if (proba < 8) {
644*4882a593Smuzhiyun 					U64 restToBeat = vStep * rtbTable[proba];
645*4882a593Smuzhiyun 					proba += (count[s] * step) - ((U64)proba << scale) > restToBeat;
646*4882a593Smuzhiyun 				}
647*4882a593Smuzhiyun 				if (proba > largestP)
648*4882a593Smuzhiyun 					largestP = proba, largest = s;
649*4882a593Smuzhiyun 				normalizedCounter[s] = proba;
650*4882a593Smuzhiyun 				stillToDistribute -= proba;
651*4882a593Smuzhiyun 			}
652*4882a593Smuzhiyun 		}
653*4882a593Smuzhiyun 		if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
654*4882a593Smuzhiyun 			/* corner case, need another normalization method */
655*4882a593Smuzhiyun 			size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
656*4882a593Smuzhiyun 			if (FSE_isError(errorCode))
657*4882a593Smuzhiyun 				return errorCode;
658*4882a593Smuzhiyun 		} else
659*4882a593Smuzhiyun 			normalizedCounter[largest] += (short)stillToDistribute;
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	return tableLog;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun /* fake FSE_CTable, for raw (uncompressed) input */
FSE_buildCTable_raw(FSE_CTable * ct,unsigned nbBits)666*4882a593Smuzhiyun size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits)
667*4882a593Smuzhiyun {
668*4882a593Smuzhiyun 	const unsigned tableSize = 1 << nbBits;
669*4882a593Smuzhiyun 	const unsigned tableMask = tableSize - 1;
670*4882a593Smuzhiyun 	const unsigned maxSymbolValue = tableMask;
671*4882a593Smuzhiyun 	void *const ptr = ct;
672*4882a593Smuzhiyun 	U16 *const tableU16 = ((U16 *)ptr) + 2;
673*4882a593Smuzhiyun 	void *const FSCT = ((U32 *)ptr) + 1 /* header */ + (tableSize >> 1); /* assumption : tableLog >= 1 */
674*4882a593Smuzhiyun 	FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT);
675*4882a593Smuzhiyun 	unsigned s;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	/* Sanity checks */
678*4882a593Smuzhiyun 	if (nbBits < 1)
679*4882a593Smuzhiyun 		return ERROR(GENERIC); /* min size */
680*4882a593Smuzhiyun 
681*4882a593Smuzhiyun 	/* header */
682*4882a593Smuzhiyun 	tableU16[-2] = (U16)nbBits;
683*4882a593Smuzhiyun 	tableU16[-1] = (U16)maxSymbolValue;
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	/* Build table */
686*4882a593Smuzhiyun 	for (s = 0; s < tableSize; s++)
687*4882a593Smuzhiyun 		tableU16[s] = (U16)(tableSize + s);
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 	/* Build Symbol Transformation Table */
690*4882a593Smuzhiyun 	{
691*4882a593Smuzhiyun 		const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
692*4882a593Smuzhiyun 		for (s = 0; s <= maxSymbolValue; s++) {
693*4882a593Smuzhiyun 			symbolTT[s].deltaNbBits = deltaNbBits;
694*4882a593Smuzhiyun 			symbolTT[s].deltaFindState = s - 1;
695*4882a593Smuzhiyun 		}
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	return 0;
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun /* fake FSE_CTable, for rle input (always same symbol) */
FSE_buildCTable_rle(FSE_CTable * ct,BYTE symbolValue)702*4882a593Smuzhiyun size_t FSE_buildCTable_rle(FSE_CTable *ct, BYTE symbolValue)
703*4882a593Smuzhiyun {
704*4882a593Smuzhiyun 	void *ptr = ct;
705*4882a593Smuzhiyun 	U16 *tableU16 = ((U16 *)ptr) + 2;
706*4882a593Smuzhiyun 	void *FSCTptr = (U32 *)ptr + 2;
707*4882a593Smuzhiyun 	FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)FSCTptr;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	/* header */
710*4882a593Smuzhiyun 	tableU16[-2] = (U16)0;
711*4882a593Smuzhiyun 	tableU16[-1] = (U16)symbolValue;
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	/* Build table */
714*4882a593Smuzhiyun 	tableU16[0] = 0;
715*4882a593Smuzhiyun 	tableU16[1] = 0; /* just in case */
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	/* Build Symbol Transformation Table */
718*4882a593Smuzhiyun 	symbolTT[symbolValue].deltaNbBits = 0;
719*4882a593Smuzhiyun 	symbolTT[symbolValue].deltaFindState = 0;
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	return 0;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun 
FSE_compress_usingCTable_generic(void * dst,size_t dstSize,const void * src,size_t srcSize,const FSE_CTable * ct,const unsigned fast)724*4882a593Smuzhiyun static size_t FSE_compress_usingCTable_generic(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct, const unsigned fast)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun 	const BYTE *const istart = (const BYTE *)src;
727*4882a593Smuzhiyun 	const BYTE *const iend = istart + srcSize;
728*4882a593Smuzhiyun 	const BYTE *ip = iend;
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun 	BIT_CStream_t bitC;
731*4882a593Smuzhiyun 	FSE_CState_t CState1, CState2;
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	/* init */
734*4882a593Smuzhiyun 	if (srcSize <= 2)
735*4882a593Smuzhiyun 		return 0;
736*4882a593Smuzhiyun 	{
737*4882a593Smuzhiyun 		size_t const initError = BIT_initCStream(&bitC, dst, dstSize);
738*4882a593Smuzhiyun 		if (FSE_isError(initError))
739*4882a593Smuzhiyun 			return 0; /* not enough space available to write a bitstream */
740*4882a593Smuzhiyun 	}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun #define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun 	if (srcSize & 1) {
745*4882a593Smuzhiyun 		FSE_initCState2(&CState1, ct, *--ip);
746*4882a593Smuzhiyun 		FSE_initCState2(&CState2, ct, *--ip);
747*4882a593Smuzhiyun 		FSE_encodeSymbol(&bitC, &CState1, *--ip);
748*4882a593Smuzhiyun 		FSE_FLUSHBITS(&bitC);
749*4882a593Smuzhiyun 	} else {
750*4882a593Smuzhiyun 		FSE_initCState2(&CState2, ct, *--ip);
751*4882a593Smuzhiyun 		FSE_initCState2(&CState1, ct, *--ip);
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	/* join to mod 4 */
755*4882a593Smuzhiyun 	srcSize -= 2;
756*4882a593Smuzhiyun 	if ((sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) && (srcSize & 2)) { /* test bit 2 */
757*4882a593Smuzhiyun 		FSE_encodeSymbol(&bitC, &CState2, *--ip);
758*4882a593Smuzhiyun 		FSE_encodeSymbol(&bitC, &CState1, *--ip);
759*4882a593Smuzhiyun 		FSE_FLUSHBITS(&bitC);
760*4882a593Smuzhiyun 	}
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	/* 2 or 4 encoding per loop */
763*4882a593Smuzhiyun 	while (ip > istart) {
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 		FSE_encodeSymbol(&bitC, &CState2, *--ip);
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 		if (sizeof(bitC.bitContainer) * 8 < FSE_MAX_TABLELOG * 2 + 7) /* this test must be static */
768*4882a593Smuzhiyun 			FSE_FLUSHBITS(&bitC);
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 		FSE_encodeSymbol(&bitC, &CState1, *--ip);
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 		if (sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) { /* this test must be static */
773*4882a593Smuzhiyun 			FSE_encodeSymbol(&bitC, &CState2, *--ip);
774*4882a593Smuzhiyun 			FSE_encodeSymbol(&bitC, &CState1, *--ip);
775*4882a593Smuzhiyun 		}
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 		FSE_FLUSHBITS(&bitC);
778*4882a593Smuzhiyun 	}
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun 	FSE_flushCState(&bitC, &CState2);
781*4882a593Smuzhiyun 	FSE_flushCState(&bitC, &CState1);
782*4882a593Smuzhiyun 	return BIT_closeCStream(&bitC);
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun 
FSE_compress_usingCTable(void * dst,size_t dstSize,const void * src,size_t srcSize,const FSE_CTable * ct)785*4882a593Smuzhiyun size_t FSE_compress_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun 	unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	if (fast)
790*4882a593Smuzhiyun 		return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
791*4882a593Smuzhiyun 	else
792*4882a593Smuzhiyun 		return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun 
FSE_compressBound(size_t size)795*4882a593Smuzhiyun size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
796