public static void FseBuildCTableRaw(ref FseCompressTable ct, int nbBits) { int tableSize = 1 << nbBits; int tableMask = tableSize - 1; int maxSymbolValue = tableMask; Span <FseSymbolCompressionTransform> symbolTT = ct.symbolTT; /* Sanity checks */ if (nbBits < 1) { throw new ArgumentOutOfRangeException(nameof(nbBits)); } /* header */ ct.tableLog = (ushort)nbBits; ct.maxSymbolValue = (ushort)maxSymbolValue; /* Build table */ Span <ushort> nextStateNumber = ct.nextStateNumber; for (int s = 0; s < tableSize; s++) { nextStateNumber[s] = (ushort)(tableSize + s); } /* Build Symbol Transformation Table */ int deltaNbBits = (nbBits << 16) - (1 << nbBits); for (int s = 0; s <= maxSymbolValue; s++) { symbolTT[s].deltaNbBits = (uint)deltaNbBits; symbolTT[s].deltaFindState = s - 1; } }
public static void FseBuildCTable(ref FseCompressTable ct, ReadOnlySpan <short> normalizedCounter, int maxSymbolValue, int tableLog) { byte[] buffer = ArrayPool <byte> .Shared.Rent(FSE_MAX_TABLESIZE); try { FseBuildCTableWksp(ref ct, normalizedCounter, maxSymbolValue, tableLog, buffer.AsSpan(0, FSE_MAX_TABLESIZE)); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
public static void FseBuildCTableRle(ref FseCompressTable ct, byte symbolValue) { /* header */ ct.tableLog = 0; ct.maxSymbolValue = symbolValue; /* Build table */ Span <ushort> nextStateNumber = ct.nextStateNumber; nextStateNumber[0] = 0; nextStateNumber[1] = 0; /* just in case */ /* Build Symbol Transformation Table */ Span <FseSymbolCompressionTransform> symbolTT = ct.symbolTT; symbolTT[symbolValue].deltaFindState = 0; symbolTT[symbolValue].deltaFindState = 0; }
public static void FseBuildCTableWksp(ref FseCompressTable ct, ReadOnlySpan <short> normalizedCounter, int maxSymbolValue, int tableLog, Span <byte> workSpace) { int tableSize = 1 << tableLog; int tableMask = tableSize - 1; int step = FseTableStep(tableSize); byte[] buffer = ArrayPool <byte> .Shared.Rent(4 *(FSE_MAX_SYMBOL_VALUE + 2)); try { Span <int> cumul = MemoryMarshal.Cast <byte, int>(buffer.AsSpan()).Slice(0, FSE_MAX_SYMBOL_VALUE + 2); Span <byte> tableSymbol = workSpace; int highThreshold = tableSize - 1; if ((1 << tableLog) > workSpace.Length) { throw new ArgumentException("Workspace is too small.", nameof(workSpace)); } ct.tableLog = (ushort)tableLog; ct.maxSymbolValue = (ushort)maxSymbolValue; Debug.Assert(tableLog < 16); /* symbol start positions */ { cumul[0] = 0; for (int u = 1; u <= maxSymbolValue + 1; u++) { if (normalizedCounter[u - 1] == -1) /* Low proba symbol */ { cumul[u] = cumul[u - 1] + 1; tableSymbol[highThreshold--] = (byte)(u - 1); } else { cumul[u] = cumul[u - 1] + normalizedCounter[u - 1]; } } cumul[maxSymbolValue + 1] = tableSize + 1; } /* Spread symbols */ { int position = 0; for (int symbol = 0; symbol <= maxSymbolValue; symbol++) { for (int nbOccurences = 0; nbOccurences < normalizedCounter[symbol]; nbOccurences++) { tableSymbol[position] = (byte)symbol; position = (position + step) & tableMask; while (position > highThreshold) /* Low proba area */ { position = (position + step) & tableMask; } } } if (position != 0) /* Must have gone through all positions */ { throw new InvalidDataException(); } } /* Build table */ var nextStateNumber = ct.nextStateNumber; { for (int u = 0; u < tableSize; u++) { byte s = tableSymbol[u]; nextStateNumber[cumul[s]++] = (ushort)(tableSize + u); } } /* Build Symbol Transformation Table */ var symbolTT = ct.symbolTT; { int total = 0; for (int s = 0; s <= maxSymbolValue; s++) { switch (normalizedCounter[s]) { case 0: /* filling nonetheless, for compatibility with FSE_getMaxNbBits() */ symbolTT[s].deltaNbBits = (uint)(((tableLog + 1) << 16) - (1 << tableLog)); break; case -1: case 1: symbolTT[s].deltaNbBits = (uint)((tableLog << 16) - (1 << tableLog)); symbolTT[s].deltaFindState = total - 1; total++; break; default: uint maxBitsOut = (uint)tableLog - (uint)MathHelper.Log2((uint)(normalizedCounter[s] - 1)); uint minStatePlus = (uint)normalizedCounter[s] << (int)maxBitsOut; symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; symbolTT[s].deltaFindState = total - normalizedCounter[s]; total += normalizedCounter[s]; break; } } } } finally { ArrayPool <byte> .Shared.Return(buffer); } }