} /* size == U32 */ public static void InitDState(FSE_DState_t DStatePtr, BIT_DStream_t bitD, FSE_DTable *dt) { void * ptr = dt; FSE_DTableHeader *DTableH = (FSE_DTableHeader *)ptr; DStatePtr.state = ReadBits(bitD, DTableH->tableLog); ReloadDStream(bitD); DStatePtr.table = dt + 1; }
public static size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, uint maxLog) { BYTE *istart = (BYTE *)cSrc; BYTE *ip = istart; short[] counting = new short[Fse.FSE_MAX_SYMBOL_VALUE + 1]; uint tableLog; uint maxSymbolValue = FSE_MAX_SYMBOL_VALUE; /* normal FSE decoding mode */ size_t NCountLength = ReadNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); if (IsError(NCountLength)) { return(NCountLength); } //if (NCountLength >= cSrcSize) return ERROR( Error.srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ if (tableLog > maxLog) { return(ERROR(Error.tableLog_tooLarge)); } ip += NCountLength; cSrcSize -= NCountLength; { size_t errcod = BuildDTable(workSpace, counting, maxSymbolValue, tableLog); if (IsError(errcod)) { return(errcod); } } return(FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace)); /* always return, even if it is an error code */ }
public static size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, void *cSrc, size_t cSrcSize, FSE_DTable *dt) { void * ptr = dt; FSE_DTableHeader *DTableH = (FSE_DTableHeader *)ptr; U32 fastMode = DTableH->fastMode; /* select fast mode (static) */ if (fastMode != 0) { return(FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1)); } return(FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0)); }
//#ifndef FSE_COMMONDEFS_ONLY ///*-******************************************************* //* Decompression (Byte symbols) //*********************************************************/ //size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue) //{ // void* ptr = dt; // FSE_DTableHeader* DTableH = (FSE_DTableHeader*)ptr; // void* dPtr = dt + 1; // FSE_decode_t* cell = (FSE_decode_t*)dPtr; // DTableH->tableLog = 0; // DTableH->fastMode = 0; // cell->newState = 0; // cell->symbol = symbolValue; // cell->nbBits = 0; // return 0; //} //size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) //{ // void* ptr = dt; // FSE_DTableHeader* DTableH = (FSE_DTableHeader*)ptr; // void* dPtr = dt + 1; // FSE_decode_t* dinfo = (FSE_decode_t*)dPtr; // unsigned tableSize = 1 << nbBits; // unsigned tableMask = tableSize - 1; // unsigned maxSV1 = tableMask+1; // unsigned s; // /* Sanity checks */ // if (nbBits < 1) return ERROR( Error.GENERIC); /* min size */ // /* Build Decoding Table */ // DTableH->tableLog = (U16)nbBits; // DTableH->fastMode = 1; // for (s=0; s<maxSV1; s++) { // dinfo[s].newState = 0; // dinfo[s].symbol = (BYTE)s; // dinfo[s].nbBits = (BYTE)nbBits; // } // return 0; //} public static size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, void *cSrc, size_t cSrcSize, FSE_DTable *dt, uint fast) { BYTE *ostart = (BYTE *)dst; BYTE *op = ostart; BYTE *omax = op + maxDstSize; BYTE *olimit = omax - 3; BIT_DStream_t bitD = new BIT_DStream_t(); FSE_DState_t state1 = new FSE_DState_t(); FSE_DState_t state2 = new FSE_DState_t(); /* Init */ { size_t errcod = InitDStream(bitD, cSrc, cSrcSize); if (IsError(errcod)) { return(errcod); } } Fse.InitDState(state1, bitD, dt); Fse.InitDState(state2, bitD, dt); //#define FSE_GETSYMBOL(statePtr) fast ? DecodeSymbolFast(statePtr, &bitD) : DecodeSymbol(statePtr, &bitD) /* 4 symbols per loop */ for (; (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_unfinished) & (op < olimit); op += 4) { op[0] = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); //if (FSE_MAX_TABLELOG * 2 + 7 > sizeOfBitContainer * 8) /* This test must be static */ // ReloadDStream(bitD); op[1] = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); if (FSE_MAX_TABLELOG * 4 + 7 > sizeOfBitContainer * 8) /* This test must be static */ { if (ReloadDStream(bitD) > BIT_DStream_status.BIT_DStream_unfinished) { op += 2; break; } } op[2] = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); //if (FSE_MAX_TABLELOG * 2 + 7 > sizeOfBitContainer * 8) /* This test must be static */ // ReloadDStream(bitD); op[3] = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); } /* tail */ /* note : ReloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ while (true) { if (op > (omax - 2)) { return(ERROR(Error.dstSize_tooSmall)); } *op++ = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); if (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_overflow) { *op++ = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); break; } if (op > (omax - 2)) { return(ERROR(Error.dstSize_tooSmall)); } *op++ = fast != 0 ? DecodeSymbolFast(state2, bitD) : DecodeSymbol(state2, bitD); if (ReloadDStream(bitD) == BIT_DStream_status.BIT_DStream_overflow) { *op++ = fast != 0 ? DecodeSymbolFast(state1, bitD) : DecodeSymbol(state1, bitD); break; } } return((size_t)(op - ostart)); }
///* ************************************************************** //* Includes //****************************************************************/ //#include <stdlib.h> /* malloc, free, qsort */ //#include <string.h> /* memcpy, memset */ //#include "bitstream.h" //#include "compiler.h" //#define FSE_STATIC_LINKING_ONLY //#include "fse.h" //#include "error_private.h" ///* ************************************************************** //* Error Management //****************************************************************/ //#define FSE_isError ERR_isError //#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ ///* check and forward error code */ //#define CHECK_F(f) { size_t e = f; if (IsError(e)) return e; } ///* ************************************************************** //* Templates //****************************************************************/ ///* // designed to be included // for type-specific functions (template emulation in C) // Objective is to write these functions only once, for improved maintenance //*/ ///* safety checks */ //#ifndef FSE_FUNCTION_EXTENSION //# error "FSE_FUNCTION_EXTENSION must be defined" //#endif //#ifndef FSE_FUNCTION_TYPE //# error "FSE_FUNCTION_TYPE must be defined" //#endif ///* Function names */ //#define FSE_CAT(X,Y) X##Y //#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) //#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) ///* Function templates */ //FSE_DTable* CreateDTable(unsigned tableLog) //{ // if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; // return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); //} //void FreeDTable(FSE_DTable* dt) //{ // free(dt); //} public static size_t BuildDTable(FSE_DTable *dt, short[] normalizedCounter, uint maxSymbolValue, uint tableLog) { void * tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ FSE_DECODE_TYPE *tableDecode = (FSE_DECODE_TYPE *)(tdPtr); U16[] symbolNext = new U16[Fse.FSE_MAX_SYMBOL_VALUE + 1]; U32 maxSV1 = maxSymbolValue + 1; U32 tableSize = (U32)1 << (int)tableLog; U32 highThreshold = tableSize - 1; /* Sanity Checks */ if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) { return(ERROR(Error.maxSymbolValue_tooLarge)); } if (tableLog > FSE_MAX_TABLELOG) { return(ERROR(Error.tableLog_tooLarge)); } /* Init, lay down lowprob symbols */ { FSE_DTableHeader DTableH; DTableH.tableLog = (U16)tableLog; DTableH.fastMode = 1; { S16 largeLimit = (S16)(1 << (int)(tableLog - 1)); U32 s; for (s = 0; s < maxSV1; s++) { if (normalizedCounter[s] == -1) { tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; symbolNext[s] = 1; } else { if (normalizedCounter[s] >= largeLimit) { DTableH.fastMode = 0; } symbolNext[s] = (U16)normalizedCounter[s]; } } } *(FSE_DTableHeader *)dt = DTableH; // memcpy(dt, &DTableH, sizeof(DTableH)); } /* Spread symbols */ { U32 tableMask = tableSize - 1; U32 step = FSE_TABLESTEP(tableSize); U32 s, position = 0; for (s = 0; s < maxSV1; s++) { int i; for (i = 0; i < normalizedCounter[s]; i++) { tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s; position = (position + step) & tableMask; while (position > highThreshold) { position = (position + step) & tableMask; /* lowprob area */ } } } if (position != 0) { return(ERROR(Error.GENERIC)); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ } } /* Build Decoding table */ { U32 u; for (u = 0; u < tableSize; u++) { FSE_FUNCTION_TYPE symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol); U32 nextState = symbolNext[symbol]++; tableDecode[u].nbBits = (BYTE)(tableLog - BIT_highbit32(nextState)); tableDecode[u].newState = (U16)((nextState << tableDecode[u].nbBits) - tableSize); } } return(0); }
/*! ReadStats() : * Read compact Huffman tree, saved by 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 ReadCTable() and HUF_readDTableX?() . */ public static size_t ReadStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, void *src, size_t srcSize) { U32 weightTotal; BYTE * ip = (BYTE *)src; size_t iSize; size_t oSize; if (srcSize == 0) { return(ERROR(Error.srcSize_wrong)); } iSize = ip[0]; /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ if (iSize >= 128) { /* special header */ oSize = iSize - 127; iSize = ((oSize + 1) / 2); if (iSize + 1 > srcSize) { return(ERROR(Error.srcSize_wrong)); } if (oSize >= hwSize) { return(ERROR(Error.corruption_detected)); } ip += 1; { U32 n; for (n = 0; n < oSize; n += 2) { huffWeight[n] = (BYTE)(ip[n / 2] >> 4); huffWeight[n + 1] = (BYTE)(ip[n / 2] & 15); } } } else { /* header compressed with FSE (normal case) */ FSE_DTable *fseWorkspace = stackalloc FSE_DTable[Fse.FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ if (iSize + 1 > srcSize) { return(ERROR(Error.srcSize_wrong)); } oSize = FseDecompress.FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ if (IsError(oSize)) { return(oSize); } } /* collect weight stats */ memset(rankStats, 0, (Huf.HUF_TABLELOG_MAX + 1) * sizeof(U32)); weightTotal = 0; { U32 n; for (n = 0; n < oSize; n++) { if (huffWeight[n] >= Huf.HUF_TABLELOG_MAX) { return(ERROR(Error.corruption_detected)); } rankStats[huffWeight[n]]++; weightTotal += ((U32)1 << huffWeight[n]) >> 1; } } if (weightTotal == 0) { return(ERROR(Error.corruption_detected)); } /* get last non-null symbol weight (implied, total must be 2^n) */ { U32 tableLog = BitStream.BIT_highbit32(weightTotal) + 1; if (tableLog > Huf.HUF_TABLELOG_MAX) { return(ERROR(Error.corruption_detected)); } *tableLogPtr = tableLog; /* determine last weight */ { U32 total = (U32)1 << (int)tableLog; U32 rest = total - weightTotal; U32 verif = (U32)1 << (int)BitStream.BIT_highbit32(rest); U32 lastWeight = BitStream.BIT_highbit32(rest) + 1; if (verif != rest) { return(ERROR(Error.corruption_detected)); /* last value must be a clean power of 2 */ } huffWeight[oSize] = (BYTE)lastWeight; rankStats[lastWeight]++; } } /* check tree construction validity */ if ((rankStats[1] < 2) || ((rankStats[1] & 1) != 0)) { return(ERROR(Error.corruption_detected)); /* by construction : at least 2 elts of rank 1, must be even */ } /* results */ *nbSymbolsPtr = (U32)(oSize + 1); return(iSize + 1); }