in csharp/src/EntropyCommon.cs [79:188]
public static size_t ReadNCount(short[] normalizedCounter, uint* maxSVPtr, uint* tableLogPtr, void* headerBuffer, size_t hbSize)
{
BYTE* istart = (BYTE*)headerBuffer;
BYTE* iend = istart + hbSize;
BYTE* ip = istart;
int nbBits;
int remaining;
int threshold;
U32 bitStream;
int bitCount;
uint charnum = 0;
int previous0 = 0;
if (hbSize < 4) return ERROR(Error.srcSize_wrong);
bitStream = MEM_readLE32(ip);
nbBits = (int)(bitStream & 0xF) + Fse.FSE_MIN_TABLELOG; /* extract tableLog */
if (nbBits > Fse.FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(Error.tableLog_tooLarge);
bitStream >>= 4;
bitCount = 4;
*tableLogPtr = (size_t)nbBits;
remaining = (1 << nbBits) + 1;
threshold = 1 << nbBits;
nbBits++;
while ((remaining > 1) & (charnum <= *maxSVPtr))
{
if (previous0 != 0)
{
uint n0 = charnum;
while ((bitStream & 0xFFFF) == 0xFFFF)
{
n0 += 24;
if (ip < iend - 5)
{
ip += 2;
bitStream = MEM_readLE32(ip) >> bitCount;
}
else
{
bitStream >>= 16;
bitCount += 16;
}
}
while ((bitStream & 3) == 3)
{
n0 += 3;
bitStream >>= 2;
bitCount += 2;
}
n0 += bitStream & 3;
bitCount += 2;
if (n0 > *maxSVPtr) return ERROR(Error.maxSymbolValue_tooSmall);
while (charnum < n0) normalizedCounter[charnum++] = 0;
if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4))
{
ip += bitCount >> 3;
bitCount &= 7;
bitStream = MEM_readLE32(ip) >> bitCount;
}
else
{
bitStream >>= 2;
}
}
{
int max = (2 * threshold - 1) - remaining;
int count;
if ((bitStream & (threshold - 1)) < (U32)max)
{
count = (int)bitStream & (threshold - 1);
bitCount += nbBits - 1;
}
else
{
count = (int)bitStream & (2 * threshold - 1);
if (count >= threshold) count -= max;
bitCount += nbBits;
}
count--; /* extra accuracy */
remaining -= count < 0 ? -count : count; /* -1 means +1 */
normalizedCounter[charnum++] = (short)count;
previous0 = count == 0 ? 1 : 0;
while (remaining < threshold)
{
nbBits--;
threshold >>= 1;
}
if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4))
{
ip += bitCount >> 3;
bitCount &= 7;
}
else
{
bitCount -= (int)(8 * (iend - 4 - ip));
ip = iend - 4;
}
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
}
} /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
if (remaining != 1) return ERROR(Error.corruption_detected);
if (bitCount > 32) return ERROR(Error.corruption_detected);
*maxSVPtr = charnum - 1;
ip += (bitCount + 7) >> 3;
return (size_t)(ip - istart);
}