ZSTD_buildFSETable() : * generate FSE decoding table for one symbol (ll, ml or off) * cannot fail if input is valid => * all inputs are presumed validated at this stage */
| 26758 | * cannot fail if input is valid => |
| 26759 | * all inputs are presumed validated at this stage */ |
| 26760 | void |
| 26761 | ZSTD_buildFSETable(ZSTD_seqSymbol* dt, |
| 26762 | const short* normalizedCounter, unsigned maxSymbolValue, |
| 26763 | const U32* baseValue, const U32* nbAdditionalBits, |
| 26764 | unsigned tableLog) |
| 26765 | { |
| 26766 | ZSTD_seqSymbol* const tableDecode = dt+1; |
| 26767 | U16 symbolNext[MaxSeq+1]; |
| 26768 | |
| 26769 | U32 const maxSV1 = maxSymbolValue + 1; |
| 26770 | U32 const tableSize = 1 << tableLog; |
| 26771 | U32 highThreshold = tableSize-1; |
| 26772 | |
| 26773 | /* Sanity Checks */ |
| 26774 | assert(maxSymbolValue <= MaxSeq); |
| 26775 | assert(tableLog <= MaxFSELog); |
| 26776 | |
| 26777 | /* Init, lay down lowprob symbols */ |
| 26778 | { ZSTD_seqSymbol_header DTableH; |
| 26779 | DTableH.tableLog = tableLog; |
| 26780 | DTableH.fastMode = 1; |
| 26781 | { S16 const largeLimit= (S16)(1 << (tableLog-1)); |
| 26782 | U32 s; |
| 26783 | for (s=0; s<maxSV1; s++) { |
| 26784 | if (normalizedCounter[s]==-1) { |
| 26785 | tableDecode[highThreshold--].baseValue = s; |
| 26786 | symbolNext[s] = 1; |
| 26787 | } else { |
| 26788 | if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; |
| 26789 | assert(normalizedCounter[s]>=0); |
| 26790 | symbolNext[s] = (U16)normalizedCounter[s]; |
| 26791 | } } } |
| 26792 | memcpy(dt, &DTableH, sizeof(DTableH)); |
| 26793 | } |
| 26794 | |
| 26795 | /* Spread symbols */ |
| 26796 | { U32 const tableMask = tableSize-1; |
| 26797 | U32 const step = FSE_TABLESTEP(tableSize); |
| 26798 | U32 s, position = 0; |
| 26799 | for (s=0; s<maxSV1; s++) { |
| 26800 | int i; |
| 26801 | for (i=0; i<normalizedCounter[s]; i++) { |
| 26802 | tableDecode[position].baseValue = s; |
| 26803 | position = (position + step) & tableMask; |
| 26804 | while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */ |
| 26805 | } } |
| 26806 | assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ |
| 26807 | } |
| 26808 | |
| 26809 | /* Build Decoding table */ |
| 26810 | { U32 u; |
| 26811 | for (u=0; u<tableSize; u++) { |
| 26812 | U32 const symbol = tableDecode[u].baseValue; |
| 26813 | U32 const nextState = symbolNext[symbol]++; |
| 26814 | tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) ); |
| 26815 | tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize); |
| 26816 | assert(nbAdditionalBits[symbol] < 255); |
| 26817 | tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol]; |
no test coverage detected