//#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)); }
/*! 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); }