// SPDX-License-Identifier: (GPL-2.0 or BSD-2-Clause)
/*
 * Huffman decoder, part of New Generation Entropy library
 * Copyright (C) 2013-2016, Yann Collet.
 *
 * You can contact the author at :
 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
 */

/* **************************************************************
*  Compiler specifics
****************************************************************/
#define FORCE_INLINE static __always_inline

/* **************************************************************
*  Dependencies
****************************************************************/
#include "bitstream.h" /* BIT_* */
#include "fse.h"       /* header compression */
#include "huf.h"
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/string.h> /* memcpy, memset */

/* **************************************************************
*  Error Management
****************************************************************/
#define HUF_STATIC_ASSERT(c)                                   \
	{                                                      \
		enum { HUF_static_assert = 1 / (int)(!!(c)) }; \
	} /* use only *after* variable declarations */

/*-***************************/
/*  generic DTableDesc       */
/*-***************************/

typedef struct {
	BYTE maxTableLog;
	BYTE tableType;
	BYTE tableLog;
	BYTE reserved;
} DTableDesc;

static DTableDesc HUF_getDTableDesc(const HUF_DTable *table)
{
	DTableDesc dtd;
	memcpy(&dtd, table, sizeof(dtd));
	return dtd;
}

/*-***************************/
/*  single-symbol decoding   */
/*-***************************/

typedef struct {
	BYTE byte;
	BYTE nbBits;
} HUF_DEltX2; /* single-symbol decoding */

size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize)
{
	U32 tableLog = 0;
	U32 nbSymbols = 0;
	size_t iSize;
	void *const dtPtr = DTable + 1;
	HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr;

	U32 *rankVal;
	BYTE *huffWeight;
	size_t spaceUsed32 = 0;

	rankVal = (U32 *)workspace + spaceUsed32;
	spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
	huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;

	if ((spaceUsed32 << 2) > workspaceSize)
		return ERROR(tableLog_tooLarge);
	workspace = (U32 *)workspace + spaceUsed32;
	workspaceSize -= (spaceUsed32 << 2);

	HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
	/* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */

	iSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize);
	if (HUF_isError(iSize))
		return iSize;

	/* Table header */
	{
		DTableDesc dtd = HUF_getDTableDesc(DTable);
		if (tableLog > (U32)(dtd.maxTableLog + 1))
			return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
		dtd.tableType = 0;
		dtd.tableLog = (BYTE)tableLog;
		memcpy(DTable, &dtd, sizeof(dtd));
	}

	/* Calculate starting value for each rank */
	{
		U32 n, nextRankStart = 0;
		for (n = 1; n < tableLog + 1; n++) {
			U32 const curr = nextRankStart;
			nextRankStart += (rankVal[n] << (n - 1));
			rankVal[n] = curr;
		}
	}

	/* fill DTable */
	{
		U32 n;
		for (n = 0; n < nbSymbols; n++) {
			U32 const w = huffWeight[n];
			U32 const length = (1 << w) >> 1;
			U32 u;
			HUF_DEltX2 D;
			D.byte = (BYTE)n;
			D.nbBits = (BYTE)(tableLog + 1 - w);
			for (u = rankVal[w]; u < rankVal[w] + length; u++)
				dt[u] = D;
			rankVal[w] += length;
		}
	}

	return iSize;
}

static BYTE HUF_decodeSymbolX2(BIT_DStream_t *Dstream, const HUF_DEltX2 *dt, const U32 dtLog)
{
	size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
	BYTE const c = dt[val].byte;
	BIT_skipBits(Dstream, dt[val].nbBits);
	return c;
}

#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)

#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr)         \
	if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
	HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)

#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
	if (ZSTD_64bits())                     \
	HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)

FORCE_INLINE size_t HUF_decodeStreamX2(BYTE *p, BIT_DStream_t *const bitDPtr, BYTE *const pEnd, const HUF_DEltX2 *const dt, const U32 dtLog)
{
	BYTE *const pStart = p;

	/* up to 4 symbols at a time */
	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd - 4)) {
		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
		HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
	}

	/* closer to the end */
	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))
		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);

	/* no more data to retrieve from bitstream, hence no need to reload */
	while (p < pEnd)
		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);

	return pEnd - pStart;
}

static size_t HUF_decompress1X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	BYTE *op = (BYTE *)dst;
	BYTE *const oend = op + dstSize;
	const void *dtPtr = DTable + 1;
	const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;
	BIT_DStream_t bitD;
	DTableDesc const dtd = HUF_getDTableDesc(DTable);
	U32 const dtLog = dtd.tableLog;

	{
		size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
		if (HUF_isError(errorCode))
			return errorCode;
	}

	HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);

	/* check */
	if (!BIT_endOfDStream(&bitD))
		return ERROR(corruption_detected);

	return dstSize;
}

size_t HUF_decompress1X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc dtd = HUF_getDTableDesc(DTable);
	if (dtd.tableType != 0)
		return ERROR(GENERIC);
	return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
}

size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	const BYTE *ip = (const BYTE *)cSrc;

	size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize);
	if (HUF_isError(hSize))
		return hSize;
	if (hSize >= cSrcSize)
		return ERROR(srcSize_wrong);
	ip += hSize;
	cSrcSize -= hSize;

	return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
}

static size_t HUF_decompress4X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	/* Check */
	if (cSrcSize < 10)
		return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */

	{
		const BYTE *const istart = (const BYTE *)cSrc;
		BYTE *const ostart = (BYTE *)dst;
		BYTE *const oend = ostart + dstSize;
		const void *const dtPtr = DTable + 1;
		const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;

		/* Init */
		BIT_DStream_t bitD1;
		BIT_DStream_t bitD2;
		BIT_DStream_t bitD3;
		BIT_DStream_t bitD4;
		size_t const length1 = ZSTD_readLE16(istart);
		size_t const length2 = ZSTD_readLE16(istart + 2);
		size_t const length3 = ZSTD_readLE16(istart + 4);
		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
		const BYTE *const istart1 = istart + 6; /* jumpTable */
		const BYTE *const istart2 = istart1 + length1;
		const BYTE *const istart3 = istart2 + length2;
		const BYTE *const istart4 = istart3 + length3;
		const size_t segmentSize = (dstSize + 3) / 4;
		BYTE *const opStart2 = ostart + segmentSize;
		BYTE *const opStart3 = opStart2 + segmentSize;
		BYTE *const opStart4 = opStart3 + segmentSize;
		BYTE *op1 = ostart;
		BYTE *op2 = opStart2;
		BYTE *op3 = opStart3;
		BYTE *op4 = opStart4;
		U32 endSignal;
		DTableDesc const dtd = HUF_getDTableDesc(DTable);
		U32 const dtLog = dtd.tableLog;

		if (length4 > cSrcSize)
			return ERROR(corruption_detected); /* overflow */
		{
			size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
			if (HUF_isError(errorCode))
				return errorCode;
		}

		/* 16-32 symbols per loop (4-8 symbols per stream) */
		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
		for (; (endSignal == BIT_DStream_unfinished) && (op4 < (oend - 7));) {
			HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
			HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
			HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
			HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
			HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
			HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
			HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
			HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
			HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
			HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
			HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
			HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
			HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
			HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
			HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
			HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
			endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
		}

		/* check corruption */
		if (op1 > opStart2)
			return ERROR(corruption_detected);
		if (op2 > opStart3)
			return ERROR(corruption_detected);
		if (op3 > opStart4)
			return ERROR(corruption_detected);
		/* note : op4 supposed already verified within main loop */

		/* finish bitStreams one by one */
		HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
		HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
		HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
		HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);

		/* check */
		endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
		if (!endSignal)
			return ERROR(corruption_detected);

		/* decoded size */
		return dstSize;
	}
}

size_t HUF_decompress4X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc dtd = HUF_getDTableDesc(DTable);
	if (dtd.tableType != 0)
		return ERROR(GENERIC);
	return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
}

size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	const BYTE *ip = (const BYTE *)cSrc;

	size_t const hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize);
	if (HUF_isError(hSize))
		return hSize;
	if (hSize >= cSrcSize)
		return ERROR(srcSize_wrong);
	ip += hSize;
	cSrcSize -= hSize;

	return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
}

/* *************************/
/* double-symbols decoding */
/* *************************/
typedef struct {
	U16 sequence;
	BYTE nbBits;
	BYTE length;
} HUF_DEltX4; /* double-symbols decoding */

typedef struct {
	BYTE symbol;
	BYTE weight;
} sortedSymbol_t;

/* HUF_fillDTableX4Level2() :
 * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
static void HUF_fillDTableX4Level2(HUF_DEltX4 *DTable, U32 sizeLog, const U32 consumed, const U32 *rankValOrigin, const int minWeight,
				   const sortedSymbol_t *sortedSymbols, const U32 sortedListSize, U32 nbBitsBaseline, U16 baseSeq)
{
	HUF_DEltX4 DElt;
	U32 rankVal[HUF_TABLELOG_MAX + 1];

	/* get pre-calculated rankVal */
	memcpy(rankVal, rankValOrigin, sizeof(rankVal));

	/* fill skipped values */
	if (minWeight > 1) {
		U32 i, skipSize = rankVal[minWeight];
		ZSTD_writeLE16(&(DElt.sequence), baseSeq);
		DElt.nbBits = (BYTE)(consumed);
		DElt.length = 1;
		for (i = 0; i < skipSize; i++)
			DTable[i] = DElt;
	}

	/* fill DTable */
	{
		U32 s;
		for (s = 0; s < sortedListSize; s++) { /* note : sortedSymbols already skipped */
			const U32 symbol = sortedSymbols[s].symbol;
			const U32 weight = sortedSymbols[s].weight;
			const U32 nbBits = nbBitsBaseline - weight;
			const U32 length = 1 << (sizeLog - nbBits);
			const U32 start = rankVal[weight];
			U32 i = start;
			const U32 end = start + length;

			ZSTD_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
			DElt.nbBits = (BYTE)(nbBits + consumed);
			DElt.length = 2;
			do {
				DTable[i++] = DElt;
			} while (i < end); /* since length >= 1 */

			rankVal[weight] += length;
		}
	}
}

typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];

static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart,
			     rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline)
{
	U32 rankVal[HUF_TABLELOG_MAX + 1];
	const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
	const U32 minBits = nbBitsBaseline - maxWeight;
	U32 s;

	memcpy(rankVal, rankValOrigin, sizeof(rankVal));

	/* fill DTable */
	for (s = 0; s < sortedListSize; s++) {
		const U16 symbol = sortedList[s].symbol;
		const U32 weight = sortedList[s].weight;
		const U32 nbBits = nbBitsBaseline - weight;
		const U32 start = rankVal[weight];
		const U32 length = 1 << (targetLog - nbBits);

		if (targetLog - nbBits >= minBits) { /* enough room for a second symbol */
			U32 sortedRank;
			int minWeight = nbBits + scaleLog;
			if (minWeight < 1)
				minWeight = 1;
			sortedRank = rankStart[minWeight];
			HUF_fillDTableX4Level2(DTable + start, targetLog - nbBits, nbBits, rankValOrigin[nbBits], minWeight, sortedList + sortedRank,
					       sortedListSize - sortedRank, nbBitsBaseline, symbol);
		} else {
			HUF_DEltX4 DElt;
			ZSTD_writeLE16(&(DElt.sequence), symbol);
			DElt.nbBits = (BYTE)(nbBits);
			DElt.length = 1;
			{
				U32 const end = start + length;
				U32 u;
				for (u = start; u < end; u++)
					DTable[u] = DElt;
			}
		}
		rankVal[weight] += length;
	}
}

size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize)
{
	U32 tableLog, maxW, sizeOfSort, nbSymbols;
	DTableDesc dtd = HUF_getDTableDesc(DTable);
	U32 const maxTableLog = dtd.maxTableLog;
	size_t iSize;
	void *dtPtr = DTable + 1; /* force compiler to avoid strict-aliasing */
	HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr;
	U32 *rankStart;

	rankValCol_t *rankVal;
	U32 *rankStats;
	U32 *rankStart0;
	sortedSymbol_t *sortedSymbol;
	BYTE *weightList;
	size_t spaceUsed32 = 0;

	HUF_STATIC_ASSERT((sizeof(rankValCol_t) & 3) == 0);

	rankVal = (rankValCol_t *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
	rankStats = (U32 *)workspace + spaceUsed32;
	spaceUsed32 += HUF_TABLELOG_MAX + 1;
	rankStart0 = (U32 *)workspace + spaceUsed32;
	spaceUsed32 += HUF_TABLELOG_MAX + 2;
	sortedSymbol = (sortedSymbol_t *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
	weightList = (BYTE *)((U32 *)workspace + spaceUsed32);
	spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;

	if ((spaceUsed32 << 2) > workspaceSize)
		return ERROR(tableLog_tooLarge);
	workspace = (U32 *)workspace + spaceUsed32;
	workspaceSize -= (spaceUsed32 << 2);

	rankStart = rankStart0 + 1;
	memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));

	HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
	if (maxTableLog > HUF_TABLELOG_MAX)
		return ERROR(tableLog_tooLarge);
	/* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */

	iSize = HUF_readStats_wksp(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize);
	if (HUF_isError(iSize))
		return iSize;

	/* check result */
	if (tableLog > maxTableLog)
		return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */

	/* find maxWeight */
	for (maxW = tableLog; rankStats[maxW] == 0; maxW--) {
	} /* necessarily finds a solution before 0 */

	/* Get start index of each weight */
	{
		U32 w, nextRankStart = 0;
		for (w = 1; w < maxW + 1; w++) {
			U32 curr = nextRankStart;
			nextRankStart += rankStats[w];
			rankStart[w] = curr;
		}
		rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
		sizeOfSort = nextRankStart;
	}

	/* sort symbols by weight */
	{
		U32 s;
		for (s = 0; s < nbSymbols; s++) {
			U32 const w = weightList[s];
			U32 const r = rankStart[w]++;
			sortedSymbol[r].symbol = (BYTE)s;
			sortedSymbol[r].weight = (BYTE)w;
		}
		rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
	}

	/* Build rankVal */
	{
		U32 *const rankVal0 = rankVal[0];
		{
			int const rescale = (maxTableLog - tableLog) - 1; /* tableLog <= maxTableLog */
			U32 nextRankVal = 0;
			U32 w;
			for (w = 1; w < maxW + 1; w++) {
				U32 curr = nextRankVal;
				nextRankVal += rankStats[w] << (w + rescale);
				rankVal0[w] = curr;
			}
		}
		{
			U32 const minBits = tableLog + 1 - maxW;
			U32 consumed;
			for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
				U32 *const rankValPtr = rankVal[consumed];
				U32 w;
				for (w = 1; w < maxW + 1; w++) {
					rankValPtr[w] = rankVal0[w] >> consumed;
				}
			}
		}
	}

	HUF_fillDTableX4(dt, maxTableLog, sortedSymbol, sizeOfSort, rankStart0, rankVal, maxW, tableLog + 1);

	dtd.tableLog = (BYTE)maxTableLog;
	dtd.tableType = 1;
	memcpy(DTable, &dtd, sizeof(dtd));
	return iSize;
}

static U32 HUF_decodeSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
{
	size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
	memcpy(op, dt + val, 2);
	BIT_skipBits(DStream, dt[val].nbBits);
	return dt[val].length;
}

static U32 HUF_decodeLastSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
{
	size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
	memcpy(op, dt + val, 1);
	if (dt[val].length == 1)
		BIT_skipBits(DStream, dt[val].nbBits);
	else {
		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) {
			BIT_skipBits(DStream, dt[val].nbBits);
			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8))
				/* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
				DStream->bitsConsumed = (sizeof(DStream->bitContainer) * 8);
		}
	}
	return 1;
}

#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)

#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr)         \
	if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)

#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
	if (ZSTD_64bits())                     \
	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)

FORCE_INLINE size_t HUF_decodeStreamX4(BYTE *p, BIT_DStream_t *bitDPtr, BYTE *const pEnd, const HUF_DEltX4 *const dt, const U32 dtLog)
{
	BYTE *const pStart = p;

	/* up to 8 symbols at a time */
	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd - (sizeof(bitDPtr->bitContainer) - 1))) {
		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
		HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
	}

	/* closer to end : up to 2 symbols at a time */
	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd - 2))
		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);

	while (p <= pEnd - 2)
		HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */

	if (p < pEnd)
		p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);

	return p - pStart;
}

static size_t HUF_decompress1X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	BIT_DStream_t bitD;

	/* Init */
	{
		size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
		if (HUF_isError(errorCode))
			return errorCode;
	}

	/* decode */
	{
		BYTE *const ostart = (BYTE *)dst;
		BYTE *const oend = ostart + dstSize;
		const void *const dtPtr = DTable + 1; /* force compiler to not use strict-aliasing */
		const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;
		DTableDesc const dtd = HUF_getDTableDesc(DTable);
		HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
	}

	/* check */
	if (!BIT_endOfDStream(&bitD))
		return ERROR(corruption_detected);

	/* decoded size */
	return dstSize;
}

size_t HUF_decompress1X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc dtd = HUF_getDTableDesc(DTable);
	if (dtd.tableType != 1)
		return ERROR(GENERIC);
	return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
}

size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	const BYTE *ip = (const BYTE *)cSrc;

	size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize);
	if (HUF_isError(hSize))
		return hSize;
	if (hSize >= cSrcSize)
		return ERROR(srcSize_wrong);
	ip += hSize;
	cSrcSize -= hSize;

	return HUF_decompress1X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
}

static size_t HUF_decompress4X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	if (cSrcSize < 10)
		return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */

	{
		const BYTE *const istart = (const BYTE *)cSrc;
		BYTE *const ostart = (BYTE *)dst;
		BYTE *const oend = ostart + dstSize;
		const void *const dtPtr = DTable + 1;
		const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;

		/* Init */
		BIT_DStream_t bitD1;
		BIT_DStream_t bitD2;
		BIT_DStream_t bitD3;
		BIT_DStream_t bitD4;
		size_t const length1 = ZSTD_readLE16(istart);
		size_t const length2 = ZSTD_readLE16(istart + 2);
		size_t const length3 = ZSTD_readLE16(istart + 4);
		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
		const BYTE *const istart1 = istart + 6; /* jumpTable */
		const BYTE *const istart2 = istart1 + length1;
		const BYTE *const istart3 = istart2 + length2;
		const BYTE *const istart4 = istart3 + length3;
		size_t const segmentSize = (dstSize + 3) / 4;
		BYTE *const opStart2 = ostart + segmentSize;
		BYTE *const opStart3 = opStart2 + segmentSize;
		BYTE *const opStart4 = opStart3 + segmentSize;
		BYTE *op1 = ostart;
		BYTE *op2 = opStart2;
		BYTE *op3 = opStart3;
		BYTE *op4 = opStart4;
		U32 endSignal;
		DTableDesc const dtd = HUF_getDTableDesc(DTable);
		U32 const dtLog = dtd.tableLog;

		if (length4 > cSrcSize)
			return ERROR(corruption_detected); /* overflow */
		{
			size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
			if (HUF_isError(errorCode))
				return errorCode;
		}
		{
			size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
			if (HUF_isError(errorCode))
				return errorCode;
		}

		/* 16-32 symbols per loop (4-8 symbols per stream) */
		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
		for (; (endSignal == BIT_DStream_unfinished) & (op4 < (oend - (sizeof(bitD4.bitContainer) - 1)));) {
			HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
			HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
			HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
			HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
			HUF_DECODE_SYMBOLX4_1(op1, &bitD1);
			HUF_DECODE_SYMBOLX4_1(op2, &bitD2);
			HUF_DECODE_SYMBOLX4_1(op3, &bitD3);
			HUF_DECODE_SYMBOLX4_1(op4, &bitD4);
			HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
			HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
			HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
			HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
			HUF_DECODE_SYMBOLX4_0(op1, &bitD1);
			HUF_DECODE_SYMBOLX4_0(op2, &bitD2);
			HUF_DECODE_SYMBOLX4_0(op3, &bitD3);
			HUF_DECODE_SYMBOLX4_0(op4, &bitD4);

			endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
		}

		/* check corruption */
		if (op1 > opStart2)
			return ERROR(corruption_detected);
		if (op2 > opStart3)
			return ERROR(corruption_detected);
		if (op3 > opStart4)
			return ERROR(corruption_detected);
		/* note : op4 already verified within main loop */

		/* finish bitStreams one by one */
		HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
		HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
		HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
		HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);

		/* check */
		{
			U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
			if (!endCheck)
				return ERROR(corruption_detected);
		}

		/* decoded size */
		return dstSize;
	}
}

size_t HUF_decompress4X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc dtd = HUF_getDTableDesc(DTable);
	if (dtd.tableType != 1)
		return ERROR(GENERIC);
	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
}

size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	const BYTE *ip = (const BYTE *)cSrc;

	size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize);
	if (HUF_isError(hSize))
		return hSize;
	if (hSize >= cSrcSize)
		return ERROR(srcSize_wrong);
	ip += hSize;
	cSrcSize -= hSize;

	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
}

/* ********************************/
/* Generic decompression selector */
/* ********************************/

size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc const dtd = HUF_getDTableDesc(DTable);
	return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
			     : HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
}

size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
{
	DTableDesc const dtd = HUF_getDTableDesc(DTable);
	return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
			     : HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
}

typedef struct {
	U32 tableTime;
	U32 decode256Time;
} algo_time_t;
static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = {
    /* single, double, quad */
    {{0, 0}, {1, 1}, {2, 2}},		     /* Q==0 : impossible */
    {{0, 0}, {1, 1}, {2, 2}},		     /* Q==1 : impossible */
    {{38, 130}, {1313, 74}, {2151, 38}},     /* Q == 2 : 12-18% */
    {{448, 128}, {1353, 74}, {2238, 41}},    /* Q == 3 : 18-25% */
    {{556, 128}, {1353, 74}, {2238, 47}},    /* Q == 4 : 25-32% */
    {{714, 128}, {1418, 74}, {2436, 53}},    /* Q == 5 : 32-38% */
    {{883, 128}, {1437, 74}, {2464, 61}},    /* Q == 6 : 38-44% */
    {{897, 128}, {1515, 75}, {2622, 68}},    /* Q == 7 : 44-50% */
    {{926, 128}, {1613, 75}, {2730, 75}},    /* Q == 8 : 50-56% */
    {{947, 128}, {1729, 77}, {3359, 77}},    /* Q == 9 : 56-62% */
    {{1107, 128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
    {{1177, 128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
    {{1242, 128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
    {{1349, 128}, {2644, 106}, {5260, 106}}, /* Q ==13 : 81-87% */
    {{1455, 128}, {2422, 124}, {4174, 124}}, /* Q ==14 : 87-93% */
    {{722, 128}, {1891, 145}, {1936, 146}},  /* Q ==15 : 93-99% */
};

/** HUF_selectDecoder() :
*   Tells which decoder is likely to decode faster,
*   based on a set of pre-determined metrics.
*   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
*   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize)
{
	/* decoder timing evaluation */
	U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
	U32 const D256 = (U32)(dstSize >> 8);
	U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
	U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
	DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, for cache eviction */

	return DTime1 < DTime0;
}

typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize);

size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	/* validation checks */
	if (dstSize == 0)
		return ERROR(dstSize_tooSmall);
	if (cSrcSize > dstSize)
		return ERROR(corruption_detected); /* invalid */
	if (cSrcSize == dstSize) {
		memcpy(dst, cSrc, dstSize);
		return dstSize;
	} /* not compressed */
	if (cSrcSize == 1) {
		memset(dst, *(const BYTE *)cSrc, dstSize);
		return dstSize;
	} /* RLE */

	{
		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
		return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
			      : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
	}
}

size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	/* validation checks */
	if (dstSize == 0)
		return ERROR(dstSize_tooSmall);
	if ((cSrcSize >= dstSize) || (cSrcSize <= 1))
		return ERROR(corruption_detected); /* invalid */

	{
		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
		return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
			      : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
	}
}

size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
{
	/* validation checks */
	if (dstSize == 0)
		return ERROR(dstSize_tooSmall);
	if (cSrcSize > dstSize)
		return ERROR(corruption_detected); /* invalid */
	if (cSrcSize == dstSize) {
		memcpy(dst, cSrc, dstSize);
		return dstSize;
	} /* not compressed */
	if (cSrcSize == 1) {
		memset(dst, *(const BYTE *)cSrc, dstSize);
		return dstSize;
	} /* RLE */

	{
		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
		return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
			      : HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
	}
}
