/* fake FSE_CTable, for rle input (always same symbol) */ public static nuint FSE_buildCTable_rle(uint *ct, byte symbolValue) { void * ptr = (void *)ct; ushort *tableU16 = ((ushort *)(ptr)) + 2; void * FSCTptr = (void *)((uint *)(ptr) + 2); FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)(FSCTptr); tableU16[-2] = (ushort)(0); tableU16[-1] = (ushort)(symbolValue); tableU16[0] = 0; tableU16[1] = 0; symbolTT[symbolValue].deltaNbBits = 0; symbolTT[symbolValue].deltaFindState = 0; return(0); }
private static uint FSE_bitCost(void *symbolTTPtr, uint tableLog, uint symbolValue, uint accuracyLog) { FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)(symbolTTPtr); uint minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; uint threshold = (minNbBits + 1) << 16; assert(tableLog < 16); assert(accuracyLog < 31 - tableLog); { uint tableSize = (uint)(1 << (int)tableLog); uint deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); uint normalizedDeltaFromThreshold = (deltaFromThreshold << (int)accuracyLog) >> (int)tableLog; uint bitMultiplier = (uint)(1 << (int)accuracyLog); assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); assert(normalizedDeltaFromThreshold <= bitMultiplier); return((minNbBits + 1) * bitMultiplier - normalizedDeltaFromThreshold); } }
/* fake FSE_CTable, for raw (uncompressed) input */ public static nuint FSE_buildCTable_raw(uint *ct, uint nbBits) { uint tableSize = (uint)(1 << (int)nbBits); uint tableMask = tableSize - 1; uint maxSymbolValue = tableMask; void * ptr = (void *)ct; ushort *tableU16 = ((ushort *)(ptr)) + 2; void * FSCT = (void *)(((uint *)(ptr)) + 1 + (tableSize >> 1)); FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)(FSCT); uint s; if (nbBits < 1) { return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_GENERIC))); } tableU16[-2] = (ushort)(nbBits); tableU16[-1] = (ushort)(maxSymbolValue); for (s = 0; s < tableSize; s++) { tableU16[s] = (ushort)(tableSize + s); } { uint deltaNbBits = (nbBits << 16) - (uint)((1 << (int)nbBits)); for (s = 0; s <= maxSymbolValue; s++) { symbolTT[s].deltaNbBits = deltaNbBits; symbolTT[s].deltaFindState = (int)(s - 1); } } return(0); }
private static uint FSE_getMaxNbBits(void *symbolTTPtr, uint symbolValue) { FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)(symbolTTPtr); return((symbolTT[symbolValue].deltaNbBits + (uint)(((1 << 16) - 1))) >> 16); }
/* FSE_buildCTable_wksp() : * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)` * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements */ public static nuint FSE_buildCTable_wksp(uint *ct, short *normalizedCounter, uint maxSymbolValue, uint tableLog, void *workSpace, nuint wkspSize) { uint tableSize = (uint)(1 << (int)tableLog); uint tableMask = tableSize - 1; void * ptr = (void *)ct; ushort *tableU16 = ((ushort *)(ptr)) + 2; void * FSCT = (void *)(((uint *)(ptr)) + 1 + (tableLog != 0 ? tableSize >> 1 : 1)); FSE_symbolCompressionTransform *symbolTT = (FSE_symbolCompressionTransform *)(FSCT); uint step = (((tableSize) >> 1) + ((tableSize) >> 3) + 3); uint *cumul = (uint *)(workSpace); byte *tableSymbol = (byte *)(cumul + (maxSymbolValue + 2)); uint highThreshold = tableSize - 1; if (((nuint)(workSpace) & 3) != 0) { return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_GENERIC))); } if (((nuint)(sizeof(uint)) * (maxSymbolValue + 2 + (1UL << (int)(tableLog - 2)))) > wkspSize) { return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_tableLog_tooLarge))); } tableU16[-2] = (ushort)(tableLog); tableU16[-1] = (ushort)(maxSymbolValue); assert(tableLog < 16); { uint u; cumul[0] = 0; for (u = 1; u <= maxSymbolValue + 1; u++) { if (normalizedCounter[u - 1] == -1) { cumul[u] = cumul[u - 1] + 1; tableSymbol[highThreshold--] = (byte)(u - 1); } else { cumul[u] = cumul[u - 1] + (ushort)(normalizedCounter[u - 1]); } } cumul[maxSymbolValue + 1] = tableSize + 1; } { uint position = 0; uint symbol; for (symbol = 0; symbol <= maxSymbolValue; symbol++) { int nbOccurrences; int freq = normalizedCounter[symbol]; for (nbOccurrences = 0; nbOccurrences < freq; nbOccurrences++) { tableSymbol[position] = (byte)(symbol); position = (position + step) & tableMask; while (position > highThreshold) { position = (position + step) & tableMask; } } } assert(position == 0); } { uint u; for (u = 0; u < tableSize; u++) { byte s = tableSymbol[u]; tableU16[cumul[s]++] = (ushort)(tableSize + u); } } { uint total = 0; uint s; for (s = 0; s <= maxSymbolValue; s++) { switch (normalizedCounter[s]) { case 0: { symbolTT[s].deltaNbBits = ((tableLog + 1) << 16) - (uint)((1 << (int)tableLog)); } break; case -1: case 1: { symbolTT[s].deltaNbBits = (tableLog << 16) - (uint)((1 << (int)tableLog)); } symbolTT[s].deltaFindState = (int)(total - 1); total++; break; default: { uint maxBitsOut = tableLog - BIT_highbit32((uint)(normalizedCounter[s] - 1)); uint minStatePlus = (uint)(normalizedCounter[s] << (int)maxBitsOut); symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; symbolTT[s].deltaFindState = (int)(total - (ushort)(normalizedCounter[s])); total += (uint)(normalizedCounter[s]); } break; } } } return(0); }