MCPcopy Create free account
hub / github.com/F-Stack/f-stack / HUF_readStats

Function HUF_readStats

freebsd/contrib/openzfs/module/zstd/lib/zstd.c:2632–2693  ·  view source on GitHub ↗

! HUF_readStats() : Read compact Huffman tree, saved by HUF_writeCTable(). `huffWeight` is destination buffer. `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. @return : size read from `src` , or an error Code . Note : Needed by HUF_readCTable() and HUF_readDTableX?() . */

Source from the content-addressed store, hash-verified

2630 Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
2631*/
2632size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
2633 U32* nbSymbolsPtr, U32* tableLogPtr,
2634 const void* src, size_t srcSize)
2635{
2636 U32 weightTotal;
2637 const BYTE* ip = (const BYTE*) src;
2638 size_t iSize;
2639 size_t oSize;
2640
2641 if (!srcSize) return ERROR(srcSize_wrong);
2642 iSize = ip[0];
2643 /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
2644
2645 if (iSize >= 128) { /* special header */
2646 oSize = iSize - 127;
2647 iSize = ((oSize+1)/2);
2648 if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
2649 if (oSize >= hwSize) return ERROR(corruption_detected);
2650 ip += 1;
2651 { U32 n;
2652 for (n=0; n<oSize; n+=2) {
2653 huffWeight[n] = ip[n/2] >> 4;
2654 huffWeight[n+1] = ip[n/2] & 15;
2655 } } }
2656 else { /* header compressed with FSE (normal case) */
2657 FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
2658 if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
2659 oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */
2660 if (FSE_isError(oSize)) return oSize;
2661 }
2662
2663 /* collect weight stats */
2664 memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
2665 weightTotal = 0;
2666 { U32 n; for (n=0; n<oSize; n++) {
2667 if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
2668 rankStats[huffWeight[n]]++;
2669 weightTotal += (1 << huffWeight[n]) >> 1;
2670 } }
2671 if (weightTotal == 0) return ERROR(corruption_detected);
2672
2673 /* get last non-null symbol weight (implied, total must be 2^n) */
2674 { U32 const tableLog = BIT_highbit32(weightTotal) + 1;
2675 if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
2676 *tableLogPtr = tableLog;
2677 /* determine last weight */
2678 { U32 const total = 1 << tableLog;
2679 U32 const rest = total - weightTotal;
2680 U32 const verif = 1 << BIT_highbit32(rest);
2681 U32 const lastWeight = BIT_highbit32(rest) + 1;
2682 if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
2683 huffWeight[oSize] = (BYTE)lastWeight;
2684 rankStats[lastWeight]++;
2685 } }
2686
2687 /* check tree construction validity */
2688 if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
2689

Callers 3

HUF_readCTableFunction · 0.70
HUF_readDTableX1_wkspFunction · 0.70
HUF_readDTableX2_wkspFunction · 0.70

Calls 4

memsetFunction · 0.85
FSE_decompress_wkspFunction · 0.70
FSE_isErrorFunction · 0.70
BIT_highbit32Function · 0.70

Tested by

no test coverage detected