1 /* ******************************************* 1 /* ****************************************************************** 2 * Common functions of New Generation Entropy 2 * Common functions of New Generation Entropy library 3 * Copyright (c) Yann Collet, Facebook, Inc. 3 * Copyright (c) Yann Collet, Facebook, Inc. 4 * 4 * 5 * You can contact the author at : 5 * You can contact the author at : 6 * - FSE+HUF source repository : https://gith 6 * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy 7 * - Public forum : https://groups.google.com 7 * - Public forum : https://groups.google.com/forum/#!forum/lz4c 8 * 8 * 9 * This source code is licensed under both the 9 * This source code is licensed under both the BSD-style license (found in the 10 * LICENSE file in the root directory of this 10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 11 * in the COPYING file in the root directory o 11 * in the COPYING file in the root directory of this source tree). 12 * You may select, at your option, one of the 12 * You may select, at your option, one of the above-listed licenses. 13 ********************************************** 13 ****************************************************************** */ 14 14 15 /* ************************************* 15 /* ************************************* 16 * Dependencies 16 * Dependencies 17 ***************************************/ 17 ***************************************/ 18 #include "mem.h" 18 #include "mem.h" 19 #include "error_private.h" /* ERR_*, ERR 19 #include "error_private.h" /* ERR_*, ERROR */ 20 #define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TA 20 #define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ 21 #include "fse.h" 21 #include "fse.h" 22 #define HUF_STATIC_LINKING_ONLY /* HUF_TABLEL 22 #define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ 23 #include "huf.h" 23 #include "huf.h" 24 24 25 25 26 /*=== Version ===*/ 26 /*=== Version ===*/ 27 unsigned FSE_versionNumber(void) { return FSE_ 27 unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } 28 28 29 29 30 /*=== Error Management ===*/ 30 /*=== Error Management ===*/ 31 unsigned FSE_isError(size_t code) { return ERR 31 unsigned FSE_isError(size_t code) { return ERR_isError(code); } 32 const char* FSE_getErrorName(size_t code) { re 32 const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } 33 33 34 unsigned HUF_isError(size_t code) { return ERR 34 unsigned HUF_isError(size_t code) { return ERR_isError(code); } 35 const char* HUF_getErrorName(size_t code) { re 35 const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } 36 36 37 37 38 /*-******************************************* 38 /*-************************************************************** 39 * FSE NCount encoding-decoding 39 * FSE NCount encoding-decoding 40 ********************************************** 40 ****************************************************************/ 41 static U32 FSE_ctz(U32 val) 41 static U32 FSE_ctz(U32 val) 42 { 42 { 43 assert(val != 0); 43 assert(val != 0); 44 { 44 { 45 # if (__GNUC__ >= 3) /* GCC Intrinsic */ 45 # if (__GNUC__ >= 3) /* GCC Intrinsic */ 46 return __builtin_ctz(val); 46 return __builtin_ctz(val); 47 # else /* Software version */ 47 # else /* Software version */ 48 U32 count = 0; 48 U32 count = 0; 49 while ((val & 1) == 0) { 49 while ((val & 1) == 0) { 50 val >>= 1; 50 val >>= 1; 51 ++count; 51 ++count; 52 } 52 } 53 return count; 53 return count; 54 # endif 54 # endif 55 } 55 } 56 } 56 } 57 57 58 FORCE_INLINE_TEMPLATE 58 FORCE_INLINE_TEMPLATE 59 size_t FSE_readNCount_body(short* normalizedCo 59 size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 60 const void* headerB 60 const void* headerBuffer, size_t hbSize) 61 { 61 { 62 const BYTE* const istart = (const BYTE*) h 62 const BYTE* const istart = (const BYTE*) headerBuffer; 63 const BYTE* const iend = istart + hbSize; 63 const BYTE* const iend = istart + hbSize; 64 const BYTE* ip = istart; 64 const BYTE* ip = istart; 65 int nbBits; 65 int nbBits; 66 int remaining; 66 int remaining; 67 int threshold; 67 int threshold; 68 U32 bitStream; 68 U32 bitStream; 69 int bitCount; 69 int bitCount; 70 unsigned charnum = 0; 70 unsigned charnum = 0; 71 unsigned const maxSV1 = *maxSVPtr + 1; 71 unsigned const maxSV1 = *maxSVPtr + 1; 72 int previous0 = 0; 72 int previous0 = 0; 73 73 74 if (hbSize < 8) { 74 if (hbSize < 8) { 75 /* This function only works when hbSiz 75 /* This function only works when hbSize >= 8 */ 76 char buffer[8] = {0}; 76 char buffer[8] = {0}; 77 ZSTD_memcpy(buffer, headerBuffer, hbSi 77 ZSTD_memcpy(buffer, headerBuffer, hbSize); 78 { size_t const countSize = FSE_readN 78 { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, 79 79 buffer, sizeof(buffer)); 80 if (FSE_isError(countSize)) return 80 if (FSE_isError(countSize)) return countSize; 81 if (countSize > hbSize) return ERR 81 if (countSize > hbSize) return ERROR(corruption_detected); 82 return countSize; 82 return countSize; 83 } } 83 } } 84 assert(hbSize >= 8); 84 assert(hbSize >= 8); 85 85 86 /* init */ 86 /* init */ 87 ZSTD_memset(normalizedCounter, 0, (*maxSVP 87 ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ 88 bitStream = MEM_readLE32(ip); 88 bitStream = MEM_readLE32(ip); 89 nbBits = (bitStream & 0xF) + FSE_MIN_TABLE 89 nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ 90 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) re 90 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); 91 bitStream >>= 4; 91 bitStream >>= 4; 92 bitCount = 4; 92 bitCount = 4; 93 *tableLogPtr = nbBits; 93 *tableLogPtr = nbBits; 94 remaining = (1<<nbBits)+1; 94 remaining = (1<<nbBits)+1; 95 threshold = 1<<nbBits; 95 threshold = 1<<nbBits; 96 nbBits++; 96 nbBits++; 97 97 98 for (;;) { 98 for (;;) { 99 if (previous0) { 99 if (previous0) { 100 /* Count the number of repeats. Ea 100 /* Count the number of repeats. Each time the 101 * 2-bit repeat code is 0b11 there 101 * 2-bit repeat code is 0b11 there is another 102 * repeat. 102 * repeat. 103 * Avoid UB by setting the high bi 103 * Avoid UB by setting the high bit to 1. 104 */ 104 */ 105 int repeats = FSE_ctz(~bitStream | 105 int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; 106 while (repeats >= 12) { 106 while (repeats >= 12) { 107 charnum += 3 * 12; 107 charnum += 3 * 12; 108 if (LIKELY(ip <= iend-7)) { 108 if (LIKELY(ip <= iend-7)) { 109 ip += 3; 109 ip += 3; 110 } else { 110 } else { 111 bitCount -= (int)(8 * (ien 111 bitCount -= (int)(8 * (iend - 7 - ip)); 112 bitCount &= 31; 112 bitCount &= 31; 113 ip = iend - 4; 113 ip = iend - 4; 114 } 114 } 115 bitStream = MEM_readLE32(ip) > 115 bitStream = MEM_readLE32(ip) >> bitCount; 116 repeats = FSE_ctz(~bitStream | 116 repeats = FSE_ctz(~bitStream | 0x80000000) >> 1; 117 } 117 } 118 charnum += 3 * repeats; 118 charnum += 3 * repeats; 119 bitStream >>= 2 * repeats; 119 bitStream >>= 2 * repeats; 120 bitCount += 2 * repeats; 120 bitCount += 2 * repeats; 121 121 122 /* Add the final repeat which isn' 122 /* Add the final repeat which isn't 0b11. */ 123 assert((bitStream & 3) < 3); 123 assert((bitStream & 3) < 3); 124 charnum += bitStream & 3; 124 charnum += bitStream & 3; 125 bitCount += 2; 125 bitCount += 2; 126 126 127 /* This is an error, but break and 127 /* This is an error, but break and return an error 128 * at the end, because returning o 128 * at the end, because returning out of a loop makes 129 * it harder for the compiler to o 129 * it harder for the compiler to optimize. 130 */ 130 */ 131 if (charnum >= maxSV1) break; 131 if (charnum >= maxSV1) break; 132 132 133 /* We don't need to set the normal 133 /* We don't need to set the normalized count to 0 134 * because we already memset the w 134 * because we already memset the whole buffer to 0. 135 */ 135 */ 136 136 137 if (LIKELY(ip <= iend-7) || (ip + 137 if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 138 assert((bitCount >> 3) <= 3); 138 assert((bitCount >> 3) <= 3); /* For first condition to work */ 139 ip += bitCount>>3; 139 ip += bitCount>>3; 140 bitCount &= 7; 140 bitCount &= 7; 141 } else { 141 } else { 142 bitCount -= (int)(8 * (iend - 142 bitCount -= (int)(8 * (iend - 4 - ip)); 143 bitCount &= 31; 143 bitCount &= 31; 144 ip = iend - 4; 144 ip = iend - 4; 145 } 145 } 146 bitStream = MEM_readLE32(ip) >> bi 146 bitStream = MEM_readLE32(ip) >> bitCount; 147 } 147 } 148 { 148 { 149 int const max = (2*threshold-1) - 149 int const max = (2*threshold-1) - remaining; 150 int count; 150 int count; 151 151 152 if ((bitStream & (threshold-1)) < 152 if ((bitStream & (threshold-1)) < (U32)max) { 153 count = bitStream & (threshold 153 count = bitStream & (threshold-1); 154 bitCount += nbBits-1; 154 bitCount += nbBits-1; 155 } else { 155 } else { 156 count = bitStream & (2*thresho 156 count = bitStream & (2*threshold-1); 157 if (count >= threshold) count 157 if (count >= threshold) count -= max; 158 bitCount += nbBits; 158 bitCount += nbBits; 159 } 159 } 160 160 161 count--; /* extra accuracy */ 161 count--; /* extra accuracy */ 162 /* When it matters (small blocks), 162 /* When it matters (small blocks), this is a 163 * predictable branch, because we 163 * predictable branch, because we don't use -1. 164 */ 164 */ 165 if (count >= 0) { 165 if (count >= 0) { 166 remaining -= count; 166 remaining -= count; 167 } else { 167 } else { 168 assert(count == -1); 168 assert(count == -1); 169 remaining += count; 169 remaining += count; 170 } 170 } 171 normalizedCounter[charnum++] = (sh 171 normalizedCounter[charnum++] = (short)count; 172 previous0 = !count; 172 previous0 = !count; 173 173 174 assert(threshold > 1); 174 assert(threshold > 1); 175 if (remaining < threshold) { 175 if (remaining < threshold) { 176 /* This branch can be folded i 176 /* This branch can be folded into the 177 * threshold update condition 177 * threshold update condition because we 178 * know that threshold > 1. 178 * know that threshold > 1. 179 */ 179 */ 180 if (remaining <= 1) break; 180 if (remaining <= 1) break; 181 nbBits = BIT_highbit32(remaini 181 nbBits = BIT_highbit32(remaining) + 1; 182 threshold = 1 << (nbBits - 1); 182 threshold = 1 << (nbBits - 1); 183 } 183 } 184 if (charnum >= maxSV1) break; 184 if (charnum >= maxSV1) break; 185 185 186 if (LIKELY(ip <= iend-7) || (ip + 186 if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 187 ip += bitCount>>3; 187 ip += bitCount>>3; 188 bitCount &= 7; 188 bitCount &= 7; 189 } else { 189 } else { 190 bitCount -= (int)(8 * (iend - 190 bitCount -= (int)(8 * (iend - 4 - ip)); 191 bitCount &= 31; 191 bitCount &= 31; 192 ip = iend - 4; 192 ip = iend - 4; 193 } 193 } 194 bitStream = MEM_readLE32(ip) >> bi 194 bitStream = MEM_readLE32(ip) >> bitCount; 195 } } 195 } } 196 if (remaining != 1) return ERROR(corruptio 196 if (remaining != 1) return ERROR(corruption_detected); 197 /* Only possible when there are too many z 197 /* Only possible when there are too many zeros. */ 198 if (charnum > maxSV1) return ERROR(maxSymb 198 if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); 199 if (bitCount > 32) return ERROR(corruption 199 if (bitCount > 32) return ERROR(corruption_detected); 200 *maxSVPtr = charnum-1; 200 *maxSVPtr = charnum-1; 201 201 202 ip += (bitCount+7)>>3; 202 ip += (bitCount+7)>>3; 203 return ip-istart; 203 return ip-istart; 204 } 204 } 205 205 206 /* Avoids the FORCE_INLINE of the _body() func 206 /* Avoids the FORCE_INLINE of the _body() function. */ 207 static size_t FSE_readNCount_body_default( 207 static size_t FSE_readNCount_body_default( 208 short* normalizedCounter, unsigned* ma 208 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 209 const void* headerBuffer, size_t hbSiz 209 const void* headerBuffer, size_t hbSize) 210 { 210 { 211 return FSE_readNCount_body(normalizedCount 211 return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 212 } 212 } 213 213 214 #if DYNAMIC_BMI2 214 #if DYNAMIC_BMI2 215 BMI2_TARGET_ATTRIBUTE static size_t FSE_readNC 215 BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( 216 short* normalizedCounter, unsigned* ma 216 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 217 const void* headerBuffer, size_t hbSiz 217 const void* headerBuffer, size_t hbSize) 218 { 218 { 219 return FSE_readNCount_body(normalizedCount 219 return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 220 } 220 } 221 #endif 221 #endif 222 222 223 size_t FSE_readNCount_bmi2( 223 size_t FSE_readNCount_bmi2( 224 short* normalizedCounter, unsigned* ma 224 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 225 const void* headerBuffer, size_t hbSiz 225 const void* headerBuffer, size_t hbSize, int bmi2) 226 { 226 { 227 #if DYNAMIC_BMI2 227 #if DYNAMIC_BMI2 228 if (bmi2) { 228 if (bmi2) { 229 return FSE_readNCount_body_bmi2(normal 229 return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 230 } 230 } 231 #endif 231 #endif 232 (void)bmi2; 232 (void)bmi2; 233 return FSE_readNCount_body_default(normali 233 return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); 234 } 234 } 235 235 236 size_t FSE_readNCount( 236 size_t FSE_readNCount( 237 short* normalizedCounter, unsigned* ma 237 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 238 const void* headerBuffer, size_t hbSiz 238 const void* headerBuffer, size_t hbSize) 239 { 239 { 240 return FSE_readNCount_bmi2(normalizedCount 240 return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); 241 } 241 } 242 242 243 243 244 /*! HUF_readStats() : 244 /*! HUF_readStats() : 245 Read compact Huffman tree, saved by HUF_wr 245 Read compact Huffman tree, saved by HUF_writeCTable(). 246 `huffWeight` is destination buffer. 246 `huffWeight` is destination buffer. 247 `rankStats` is assumed to be a table of at 247 `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. 248 @return : size read from `src` , or an err 248 @return : size read from `src` , or an error Code . 249 Note : Needed by HUF_readCTable() and HUF_ 249 Note : Needed by HUF_readCTable() and HUF_readDTableX?() . 250 */ 250 */ 251 size_t HUF_readStats(BYTE* huffWeight, size_t 251 size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, 252 U32* nbSymbolsPtr, U32* t 252 U32* nbSymbolsPtr, U32* tableLogPtr, 253 const void* src, size_t s 253 const void* src, size_t srcSize) 254 { 254 { 255 U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32 255 U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; 256 return HUF_readStats_wksp(huffWeight, hwSi 256 return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0); 257 } 257 } 258 258 259 FORCE_INLINE_TEMPLATE size_t 259 FORCE_INLINE_TEMPLATE size_t 260 HUF_readStats_body(BYTE* huffWeight, size_t hw 260 HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, 261 U32* nbSymbolsPtr, U32* tab 261 U32* nbSymbolsPtr, U32* tableLogPtr, 262 const void* src, size_t src 262 const void* src, size_t srcSize, 263 void* workSpace, size_t wks 263 void* workSpace, size_t wkspSize, 264 int bmi2) 264 int bmi2) 265 { 265 { 266 U32 weightTotal; 266 U32 weightTotal; 267 const BYTE* ip = (const BYTE*) src; 267 const BYTE* ip = (const BYTE*) src; 268 size_t iSize; 268 size_t iSize; 269 size_t oSize; 269 size_t oSize; 270 270 271 if (!srcSize) return ERROR(srcSize_wrong); 271 if (!srcSize) return ERROR(srcSize_wrong); 272 iSize = ip[0]; 272 iSize = ip[0]; 273 /* ZSTD_memset(huffWeight, 0, hwSize); * 273 /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ 274 274 275 if (iSize >= 128) { /* special header */ 275 if (iSize >= 128) { /* special header */ 276 oSize = iSize - 127; 276 oSize = iSize - 127; 277 iSize = ((oSize+1)/2); 277 iSize = ((oSize+1)/2); 278 if (iSize+1 > srcSize) return ERROR(sr 278 if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 279 if (oSize >= hwSize) return ERROR(corr 279 if (oSize >= hwSize) return ERROR(corruption_detected); 280 ip += 1; 280 ip += 1; 281 { U32 n; 281 { U32 n; 282 for (n=0; n<oSize; n+=2) { 282 for (n=0; n<oSize; n+=2) { 283 huffWeight[n] = ip[n/2] >> 4 283 huffWeight[n] = ip[n/2] >> 4; 284 huffWeight[n+1] = ip[n/2] & 15 284 huffWeight[n+1] = ip[n/2] & 15; 285 } } } 285 } } } 286 else { /* header compressed with FSE (n 286 else { /* header compressed with FSE (normal case) */ 287 if (iSize+1 > srcSize) return ERROR(sr 287 if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 288 /* max (hwSize-1) values decoded, as l 288 /* max (hwSize-1) values decoded, as last one is implied */ 289 oSize = FSE_decompress_wksp_bmi2(huffW 289 oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); 290 if (FSE_isError(oSize)) return oSize; 290 if (FSE_isError(oSize)) return oSize; 291 } 291 } 292 292 293 /* collect weight stats */ 293 /* collect weight stats */ 294 ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MA 294 ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); 295 weightTotal = 0; 295 weightTotal = 0; 296 { U32 n; for (n=0; n<oSize; n++) { 296 { U32 n; for (n=0; n<oSize; n++) { 297 if (huffWeight[n] > HUF_TABLELOG_M 297 if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected); 298 rankStats[huffWeight[n]]++; 298 rankStats[huffWeight[n]]++; 299 weightTotal += (1 << huffWeight[n] 299 weightTotal += (1 << huffWeight[n]) >> 1; 300 } } 300 } } 301 if (weightTotal == 0) return ERROR(corrupt 301 if (weightTotal == 0) return ERROR(corruption_detected); 302 302 303 /* get last non-null symbol weight (implie 303 /* get last non-null symbol weight (implied, total must be 2^n) */ 304 { U32 const tableLog = BIT_highbit32(wei 304 { U32 const tableLog = BIT_highbit32(weightTotal) + 1; 305 if (tableLog > HUF_TABLELOG_MAX) retur 305 if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); 306 *tableLogPtr = tableLog; 306 *tableLogPtr = tableLog; 307 /* determine last weight */ 307 /* determine last weight */ 308 { U32 const total = 1 << tableLog; 308 { U32 const total = 1 << tableLog; 309 U32 const rest = total - weightTot 309 U32 const rest = total - weightTotal; 310 U32 const verif = 1 << BIT_highbit 310 U32 const verif = 1 << BIT_highbit32(rest); 311 U32 const lastWeight = BIT_highbit 311 U32 const lastWeight = BIT_highbit32(rest) + 1; 312 if (verif != rest) return ERROR(co 312 if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ 313 huffWeight[oSize] = (BYTE)lastWeig 313 huffWeight[oSize] = (BYTE)lastWeight; 314 rankStats[lastWeight]++; 314 rankStats[lastWeight]++; 315 } } 315 } } 316 316 317 /* check tree construction validity */ 317 /* check tree construction validity */ 318 if ((rankStats[1] < 2) || (rankStats[1] & 318 if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ 319 319 320 /* results */ 320 /* results */ 321 *nbSymbolsPtr = (U32)(oSize+1); 321 *nbSymbolsPtr = (U32)(oSize+1); 322 return iSize+1; 322 return iSize+1; 323 } 323 } 324 324 325 /* Avoids the FORCE_INLINE of the _body() func 325 /* Avoids the FORCE_INLINE of the _body() function. */ 326 static size_t HUF_readStats_body_default(BYTE* 326 static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, 327 U32* nbSymbolsPtr, U32* t 327 U32* nbSymbolsPtr, U32* tableLogPtr, 328 const void* src, size_t s 328 const void* src, size_t srcSize, 329 void* workSpace, size_t w 329 void* workSpace, size_t wkspSize) 330 { 330 { 331 return HUF_readStats_body(huffWeight, hwSi 331 return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); 332 } 332 } 333 333 334 #if DYNAMIC_BMI2 334 #if DYNAMIC_BMI2 335 static BMI2_TARGET_ATTRIBUTE size_t HUF_readSt 335 static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, 336 U32* nbSymbolsPtr, U32* t 336 U32* nbSymbolsPtr, U32* tableLogPtr, 337 const void* src, size_t s 337 const void* src, size_t srcSize, 338 void* workSpace, size_t w 338 void* workSpace, size_t wkspSize) 339 { 339 { 340 return HUF_readStats_body(huffWeight, hwSi 340 return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); 341 } 341 } 342 #endif 342 #endif 343 343 344 size_t HUF_readStats_wksp(BYTE* huffWeight, si 344 size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, 345 U32* nbSymbolsPtr, U32* t 345 U32* nbSymbolsPtr, U32* tableLogPtr, 346 const void* src, size_t s 346 const void* src, size_t srcSize, 347 void* workSpace, size_t w 347 void* workSpace, size_t wkspSize, 348 int bmi2) 348 int bmi2) 349 { 349 { 350 #if DYNAMIC_BMI2 350 #if DYNAMIC_BMI2 351 if (bmi2) { 351 if (bmi2) { 352 return HUF_readStats_body_bmi2(huffWei 352 return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); 353 } 353 } 354 #endif 354 #endif 355 (void)bmi2; 355 (void)bmi2; 356 return HUF_readStats_body_default(huffWeig 356 return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); 357 } 357 } 358 358
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.