162306a36Sopenharmony_ci/* ****************************************************************** 262306a36Sopenharmony_ci * Common functions of New Generation Entropy library 362306a36Sopenharmony_ci * Copyright (c) Yann Collet, Facebook, Inc. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * You can contact the author at : 662306a36Sopenharmony_ci * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy 762306a36Sopenharmony_ci * - Public forum : https://groups.google.com/forum/#!forum/lz4c 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * This source code is licensed under both the BSD-style license (found in the 1062306a36Sopenharmony_ci * LICENSE file in the root directory of this source tree) and the GPLv2 (found 1162306a36Sopenharmony_ci * in the COPYING file in the root directory of this source tree). 1262306a36Sopenharmony_ci * You may select, at your option, one of the above-listed licenses. 1362306a36Sopenharmony_ci****************************************************************** */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* ************************************* 1662306a36Sopenharmony_ci* Dependencies 1762306a36Sopenharmony_ci***************************************/ 1862306a36Sopenharmony_ci#include "mem.h" 1962306a36Sopenharmony_ci#include "error_private.h" /* ERR_*, ERROR */ 2062306a36Sopenharmony_ci#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ 2162306a36Sopenharmony_ci#include "fse.h" 2262306a36Sopenharmony_ci#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ 2362306a36Sopenharmony_ci#include "huf.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci/*=== Version ===*/ 2762306a36Sopenharmony_ciunsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/*=== Error Management ===*/ 3162306a36Sopenharmony_ciunsigned FSE_isError(size_t code) { return ERR_isError(code); } 3262306a36Sopenharmony_ciconst char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciunsigned HUF_isError(size_t code) { return ERR_isError(code); } 3562306a36Sopenharmony_ciconst char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/*-************************************************************** 3962306a36Sopenharmony_ci* FSE NCount encoding-decoding 4062306a36Sopenharmony_ci****************************************************************/ 4162306a36Sopenharmony_cistatic U32 FSE_ctz(U32 val) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci assert(val != 0); 4462306a36Sopenharmony_ci { 4562306a36Sopenharmony_ci# if (__GNUC__ >= 3) /* GCC Intrinsic */ 4662306a36Sopenharmony_ci return __builtin_ctz(val); 4762306a36Sopenharmony_ci# else /* Software version */ 4862306a36Sopenharmony_ci U32 count = 0; 4962306a36Sopenharmony_ci while ((val & 1) == 0) { 5062306a36Sopenharmony_ci val >>= 1; 5162306a36Sopenharmony_ci ++count; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci return count; 5462306a36Sopenharmony_ci# endif 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ciFORCE_INLINE_TEMPLATE 5962306a36Sopenharmony_cisize_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 6062306a36Sopenharmony_ci const void* headerBuffer, size_t hbSize) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci const BYTE* const istart = (const BYTE*) headerBuffer; 6362306a36Sopenharmony_ci const BYTE* const iend = istart + hbSize; 6462306a36Sopenharmony_ci const BYTE* ip = istart; 6562306a36Sopenharmony_ci int nbBits; 6662306a36Sopenharmony_ci int remaining; 6762306a36Sopenharmony_ci int threshold; 6862306a36Sopenharmony_ci U32 bitStream; 6962306a36Sopenharmony_ci int bitCount; 7062306a36Sopenharmony_ci unsigned charnum = 0; 7162306a36Sopenharmony_ci unsigned const maxSV1 = *maxSVPtr + 1; 7262306a36Sopenharmony_ci int previous0 = 0; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if (hbSize < 8) { 7562306a36Sopenharmony_ci /* This function only works when hbSize >= 8 */ 7662306a36Sopenharmony_ci char buffer[8] = {0}; 7762306a36Sopenharmony_ci ZSTD_memcpy(buffer, headerBuffer, hbSize); 7862306a36Sopenharmony_ci { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, 7962306a36Sopenharmony_ci buffer, sizeof(buffer)); 8062306a36Sopenharmony_ci if (FSE_isError(countSize)) return countSize; 8162306a36Sopenharmony_ci if (countSize > hbSize) return ERROR(corruption_detected); 8262306a36Sopenharmony_ci return countSize; 8362306a36Sopenharmony_ci } } 8462306a36Sopenharmony_ci assert(hbSize >= 8); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci /* init */ 8762306a36Sopenharmony_ci ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ 8862306a36Sopenharmony_ci bitStream = MEM_readLE32(ip); 8962306a36Sopenharmony_ci nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ 9062306a36Sopenharmony_ci if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); 9162306a36Sopenharmony_ci bitStream >>= 4; 9262306a36Sopenharmony_ci bitCount = 4; 9362306a36Sopenharmony_ci *tableLogPtr = nbBits; 9462306a36Sopenharmony_ci remaining = (1<<nbBits)+1; 9562306a36Sopenharmony_ci threshold = 1<<nbBits; 9662306a36Sopenharmony_ci nbBits++; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci for (;;) { 9962306a36Sopenharmony_ci if (previous0) { 10062306a36Sopenharmony_ci /* Count the number of repeats. Each time the 10162306a36Sopenharmony_ci * 2-bit repeat code is 0b11 there is another 10262306a36Sopenharmony_ci * repeat. 10362306a36Sopenharmony_ci * Avoid UB by setting the high bit to 1. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; 10662306a36Sopenharmony_ci while (repeats >= 12) { 10762306a36Sopenharmony_ci charnum += 3 * 12; 10862306a36Sopenharmony_ci if (LIKELY(ip <= iend-7)) { 10962306a36Sopenharmony_ci ip += 3; 11062306a36Sopenharmony_ci } else { 11162306a36Sopenharmony_ci bitCount -= (int)(8 * (iend - 7 - ip)); 11262306a36Sopenharmony_ci bitCount &= 31; 11362306a36Sopenharmony_ci ip = iend - 4; 11462306a36Sopenharmony_ci } 11562306a36Sopenharmony_ci bitStream = MEM_readLE32(ip) >> bitCount; 11662306a36Sopenharmony_ci repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci charnum += 3 * repeats; 11962306a36Sopenharmony_ci bitStream >>= 2 * repeats; 12062306a36Sopenharmony_ci bitCount += 2 * repeats; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci /* Add the final repeat which isn't 0b11. */ 12362306a36Sopenharmony_ci assert((bitStream & 3) < 3); 12462306a36Sopenharmony_ci charnum += bitStream & 3; 12562306a36Sopenharmony_ci bitCount += 2; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci /* This is an error, but break and return an error 12862306a36Sopenharmony_ci * at the end, because returning out of a loop makes 12962306a36Sopenharmony_ci * it harder for the compiler to optimize. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci if (charnum >= maxSV1) break; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* We don't need to set the normalized count to 0 13462306a36Sopenharmony_ci * because we already memset the whole buffer to 0. 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 13862306a36Sopenharmony_ci assert((bitCount >> 3) <= 3); /* For first condition to work */ 13962306a36Sopenharmony_ci ip += bitCount>>3; 14062306a36Sopenharmony_ci bitCount &= 7; 14162306a36Sopenharmony_ci } else { 14262306a36Sopenharmony_ci bitCount -= (int)(8 * (iend - 4 - ip)); 14362306a36Sopenharmony_ci bitCount &= 31; 14462306a36Sopenharmony_ci ip = iend - 4; 14562306a36Sopenharmony_ci } 14662306a36Sopenharmony_ci bitStream = MEM_readLE32(ip) >> bitCount; 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci { 14962306a36Sopenharmony_ci int const max = (2*threshold-1) - remaining; 15062306a36Sopenharmony_ci int count; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if ((bitStream & (threshold-1)) < (U32)max) { 15362306a36Sopenharmony_ci count = bitStream & (threshold-1); 15462306a36Sopenharmony_ci bitCount += nbBits-1; 15562306a36Sopenharmony_ci } else { 15662306a36Sopenharmony_ci count = bitStream & (2*threshold-1); 15762306a36Sopenharmony_ci if (count >= threshold) count -= max; 15862306a36Sopenharmony_ci bitCount += nbBits; 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci count--; /* extra accuracy */ 16262306a36Sopenharmony_ci /* When it matters (small blocks), this is a 16362306a36Sopenharmony_ci * predictable branch, because we don't use -1. 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_ci if (count >= 0) { 16662306a36Sopenharmony_ci remaining -= count; 16762306a36Sopenharmony_ci } else { 16862306a36Sopenharmony_ci assert(count == -1); 16962306a36Sopenharmony_ci remaining += count; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci normalizedCounter[charnum++] = (short)count; 17262306a36Sopenharmony_ci previous0 = !count; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci assert(threshold > 1); 17562306a36Sopenharmony_ci if (remaining < threshold) { 17662306a36Sopenharmony_ci /* This branch can be folded into the 17762306a36Sopenharmony_ci * threshold update condition because we 17862306a36Sopenharmony_ci * know that threshold > 1. 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci if (remaining <= 1) break; 18162306a36Sopenharmony_ci nbBits = BIT_highbit32(remaining) + 1; 18262306a36Sopenharmony_ci threshold = 1 << (nbBits - 1); 18362306a36Sopenharmony_ci } 18462306a36Sopenharmony_ci if (charnum >= maxSV1) break; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 18762306a36Sopenharmony_ci ip += bitCount>>3; 18862306a36Sopenharmony_ci bitCount &= 7; 18962306a36Sopenharmony_ci } else { 19062306a36Sopenharmony_ci bitCount -= (int)(8 * (iend - 4 - ip)); 19162306a36Sopenharmony_ci bitCount &= 31; 19262306a36Sopenharmony_ci ip = iend - 4; 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci bitStream = MEM_readLE32(ip) >> bitCount; 19562306a36Sopenharmony_ci } } 19662306a36Sopenharmony_ci if (remaining != 1) return ERROR(corruption_detected); 19762306a36Sopenharmony_ci /* Only possible when there are too many zeros. */ 19862306a36Sopenharmony_ci if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); 19962306a36Sopenharmony_ci if (bitCount > 32) return ERROR(corruption_detected); 20062306a36Sopenharmony_ci *maxSVPtr = charnum-1; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci ip += (bitCount+7)>>3; 20362306a36Sopenharmony_ci return ip-istart; 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci/* Avoids the FORCE_INLINE of the _body() function. */ 20762306a36Sopenharmony_cistatic size_t FSE_readNCount_body_default( 20862306a36Sopenharmony_ci short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 20962306a36Sopenharmony_ci const void* headerBuffer, size_t hbSize) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#if DYNAMIC_BMI2 21562306a36Sopenharmony_ciBMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( 21662306a36Sopenharmony_ci short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 21762306a36Sopenharmony_ci const void* headerBuffer, size_t hbSize) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci#endif 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cisize_t FSE_readNCount_bmi2( 22462306a36Sopenharmony_ci short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 22562306a36Sopenharmony_ci const void* headerBuffer, size_t hbSize, int bmi2) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci#if DYNAMIC_BMI2 22862306a36Sopenharmony_ci if (bmi2) { 22962306a36Sopenharmony_ci return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci#endif 23262306a36Sopenharmony_ci (void)bmi2; 23362306a36Sopenharmony_ci return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cisize_t FSE_readNCount( 23762306a36Sopenharmony_ci short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 23862306a36Sopenharmony_ci const void* headerBuffer, size_t hbSize) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci/*! HUF_readStats() : 24562306a36Sopenharmony_ci Read compact Huffman tree, saved by HUF_writeCTable(). 24662306a36Sopenharmony_ci `huffWeight` is destination buffer. 24762306a36Sopenharmony_ci `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. 24862306a36Sopenharmony_ci @return : size read from `src` , or an error Code . 24962306a36Sopenharmony_ci Note : Needed by HUF_readCTable() and HUF_readDTableX?() . 25062306a36Sopenharmony_ci*/ 25162306a36Sopenharmony_cisize_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, 25262306a36Sopenharmony_ci U32* nbSymbolsPtr, U32* tableLogPtr, 25362306a36Sopenharmony_ci const void* src, size_t srcSize) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; 25662306a36Sopenharmony_ci return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0); 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ciFORCE_INLINE_TEMPLATE size_t 26062306a36Sopenharmony_ciHUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, 26162306a36Sopenharmony_ci U32* nbSymbolsPtr, U32* tableLogPtr, 26262306a36Sopenharmony_ci const void* src, size_t srcSize, 26362306a36Sopenharmony_ci void* workSpace, size_t wkspSize, 26462306a36Sopenharmony_ci int bmi2) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci U32 weightTotal; 26762306a36Sopenharmony_ci const BYTE* ip = (const BYTE*) src; 26862306a36Sopenharmony_ci size_t iSize; 26962306a36Sopenharmony_ci size_t oSize; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (!srcSize) return ERROR(srcSize_wrong); 27262306a36Sopenharmony_ci iSize = ip[0]; 27362306a36Sopenharmony_ci /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci if (iSize >= 128) { /* special header */ 27662306a36Sopenharmony_ci oSize = iSize - 127; 27762306a36Sopenharmony_ci iSize = ((oSize+1)/2); 27862306a36Sopenharmony_ci if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 27962306a36Sopenharmony_ci if (oSize >= hwSize) return ERROR(corruption_detected); 28062306a36Sopenharmony_ci ip += 1; 28162306a36Sopenharmony_ci { U32 n; 28262306a36Sopenharmony_ci for (n=0; n<oSize; n+=2) { 28362306a36Sopenharmony_ci huffWeight[n] = ip[n/2] >> 4; 28462306a36Sopenharmony_ci huffWeight[n+1] = ip[n/2] & 15; 28562306a36Sopenharmony_ci } } } 28662306a36Sopenharmony_ci else { /* header compressed with FSE (normal case) */ 28762306a36Sopenharmony_ci if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 28862306a36Sopenharmony_ci /* max (hwSize-1) values decoded, as last one is implied */ 28962306a36Sopenharmony_ci oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); 29062306a36Sopenharmony_ci if (FSE_isError(oSize)) return oSize; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* collect weight stats */ 29462306a36Sopenharmony_ci ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); 29562306a36Sopenharmony_ci weightTotal = 0; 29662306a36Sopenharmony_ci { U32 n; for (n=0; n<oSize; n++) { 29762306a36Sopenharmony_ci if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected); 29862306a36Sopenharmony_ci rankStats[huffWeight[n]]++; 29962306a36Sopenharmony_ci weightTotal += (1 << huffWeight[n]) >> 1; 30062306a36Sopenharmony_ci } } 30162306a36Sopenharmony_ci if (weightTotal == 0) return ERROR(corruption_detected); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci /* get last non-null symbol weight (implied, total must be 2^n) */ 30462306a36Sopenharmony_ci { U32 const tableLog = BIT_highbit32(weightTotal) + 1; 30562306a36Sopenharmony_ci if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); 30662306a36Sopenharmony_ci *tableLogPtr = tableLog; 30762306a36Sopenharmony_ci /* determine last weight */ 30862306a36Sopenharmony_ci { U32 const total = 1 << tableLog; 30962306a36Sopenharmony_ci U32 const rest = total - weightTotal; 31062306a36Sopenharmony_ci U32 const verif = 1 << BIT_highbit32(rest); 31162306a36Sopenharmony_ci U32 const lastWeight = BIT_highbit32(rest) + 1; 31262306a36Sopenharmony_ci if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ 31362306a36Sopenharmony_ci huffWeight[oSize] = (BYTE)lastWeight; 31462306a36Sopenharmony_ci rankStats[lastWeight]++; 31562306a36Sopenharmony_ci } } 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci /* check tree construction validity */ 31862306a36Sopenharmony_ci if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci /* results */ 32162306a36Sopenharmony_ci *nbSymbolsPtr = (U32)(oSize+1); 32262306a36Sopenharmony_ci return iSize+1; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci/* Avoids the FORCE_INLINE of the _body() function. */ 32662306a36Sopenharmony_cistatic size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, 32762306a36Sopenharmony_ci U32* nbSymbolsPtr, U32* tableLogPtr, 32862306a36Sopenharmony_ci const void* src, size_t srcSize, 32962306a36Sopenharmony_ci void* workSpace, size_t wkspSize) 33062306a36Sopenharmony_ci{ 33162306a36Sopenharmony_ci return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci#if DYNAMIC_BMI2 33562306a36Sopenharmony_cistatic BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, 33662306a36Sopenharmony_ci U32* nbSymbolsPtr, U32* tableLogPtr, 33762306a36Sopenharmony_ci const void* src, size_t srcSize, 33862306a36Sopenharmony_ci void* workSpace, size_t wkspSize) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci#endif 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cisize_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, 34562306a36Sopenharmony_ci U32* nbSymbolsPtr, U32* tableLogPtr, 34662306a36Sopenharmony_ci const void* src, size_t srcSize, 34762306a36Sopenharmony_ci void* workSpace, size_t wkspSize, 34862306a36Sopenharmony_ci int bmi2) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci#if DYNAMIC_BMI2 35162306a36Sopenharmony_ci if (bmi2) { 35262306a36Sopenharmony_ci return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci#endif 35562306a36Sopenharmony_ci (void)bmi2; 35662306a36Sopenharmony_ci return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); 35762306a36Sopenharmony_ci} 358