Beispiel #1
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));
        }
Beispiel #2
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);
        }