Exemplo n.º 1
0
        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 */
        }
Exemplo n.º 2
0
 [DllImport(dll)] public static extern unsafe void HoughCircles_my(BYTE *dxBuf, int dxBw, int dxBh, int dxType, int dxStep,
                                                                   BYTE *dyBuf, int dyBw, int dyBh, int dyType, int dyStep,
                                                                   BYTE *edgesBuf, int edgesBw, int edgesBh, int edgesType, int edgesStep,
                                                                   BYTE *accumBuf, int accumBw, int accumBh, int accumType, int accumStep,
                                                                   BYTE *nzBuf, int nzBw, int nzBh, int nzType, int nzStep,
                                                                   double dp, double minDist, double param2, int minRadius, int maxRadius,
                                                                   int *numCircles, float **circles_NewAlloc);
Exemplo n.º 3
0
        public static U64 XXH64_digest_endian(XXH64_state_t state /*, XXH_endianess endian*/)
        {
            BYTE *p    = (BYTE *)state.mem64;
            BYTE *bEnd = p + state.memsize;

            U64 h64;

            if (state.total_len >= 32)
            {
                U64 v1 = state.v1;
                U64 v2 = state.v2;
                U64 v3 = state.v3;
                U64 v4 = state.v4;

                h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
                h64 = XXH64_mergeRound(h64, v1);
                h64 = XXH64_mergeRound(h64, v2);
                h64 = XXH64_mergeRound(h64, v3);
                h64 = XXH64_mergeRound(h64, v4);
            }
            else
            {
                h64 = state.v3 + PRIME64_5;
            }

            h64 += (U64)state.total_len;

            while (p + 8 <= bEnd)
            {
                U64 k1 = XXH64_round(0, XXH_readLE64(p /*, endian*/));
                h64 ^= k1;
                h64  = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
                p   += 8;
            }

            if (p + 4 <= bEnd)
            {
                h64 ^= (U64)(XXH_readLE32(p /*, endian*/)) * PRIME64_1;
                h64  = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
                p   += 4;
            }

            while (p < bEnd)
            {
                h64 ^= (*p) * PRIME64_5;
                h64  = XXH_rotl64(h64, 11) * PRIME64_1;
                p++;
            }

            h64 ^= h64 >> 33;
            h64 *= PRIME64_2;
            h64 ^= h64 >> 29;
            h64 *= PRIME64_3;
            h64 ^= h64 >> 32;

            return(h64);
        }
Exemplo n.º 4
0
        public static void memset(void *dst, BYTE byteValue, size_t length)
        {
            BYTE *dstByte = (BYTE *)dst;

            for (size_t i = 0; i < length; ++i)
            {
                dstByte[i] = byteValue;
            }
        }
Exemplo n.º 5
0
        public static void memmove(BYTE[] dst, void *src, size_t length)
        {
            BYTE *srcByte = (BYTE *)src;

            for (size_t i = 0; i < length; ++i)
            {
                dst[i] = srcByte[i];
            }
        }
Exemplo n.º 6
0
        public static void Wildcopy(void *dst, void *src, int length)
        {
            BYTE *srcByte = (BYTE *)src;
            BYTE *dstByte = (BYTE *)dst;

            for (long i = 0; i < length; ++i)
            {
                dstByte[i] = srcByte[i];
            }
        }
Exemplo n.º 7
0
        public static void *memmove(void *dst, void *src, size_t length)
        {
            BYTE *srcByte = (BYTE *)src;
            BYTE *dstByte = (BYTE *)dst;

            for (size_t i = 0; i < length; ++i)
            {
                dstByte[i] = srcByte[i];
            }
            return(dst);
        }
Exemplo n.º 8
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));
        }
Exemplo n.º 9
0
        //FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state,  void* input, size_t len, XXH_endianess endian)
        //{
        //     BYTE* p = ( BYTE*)input;
        //     BYTE*  bEnd = p + len;

        //#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
        //    if (input==NULL) return XXH_ERROR;
        //#endif

        //    state->total_len_32 += (unsigned)len;
        //    state->large_len |= (len>=16) | (state->total_len_32>=16);

        //    if (state->memsize + len < 16)  {   /* fill in tmp buffer */
        //        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
        //        state->memsize += (unsigned)len;
        //        return XXH_OK;
        //    }

        //    if (state->memsize) {   /* some data left from previous update */
        //        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
        //        {    U32* p32 = state->mem32;
        //            state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
        //            state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
        //            state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
        //            state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
        //        }
        //        p += 16-state->memsize;
        //        state->memsize = 0;
        //    }

        //    if (p <= bEnd-16) {
        //         BYTE*  limit = bEnd - 16;
        //        U32 v1 = state->v1;
        //        U32 v2 = state->v2;
        //        U32 v3 = state->v3;
        //        U32 v4 = state->v4;

        //        do {
        //            v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
        //            v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
        //            v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
        //            v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
        //        } while (p<=limit);

        //        state->v1 = v1;
        //        state->v2 = v2;
        //        state->v3 = v3;
        //        state->v4 = v4;
        //    }

        //    if (p < bEnd) {
        //        XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
        //        state->memsize = (unsigned)(bEnd-p);
        //    }

        //    return XXH_OK;
        //}

        //XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in,  void* input, size_t len)
        //{
        //    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;

        //    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
        //        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
        //    else
        //        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
        //}



        //FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian ( XXH32_state_t* state, XXH_endianess endian)
        //{
        //     BYTE * p = ( BYTE*)state->mem32;
        //     BYTE*  bEnd = ( BYTE*)(state->mem32) + state->memsize;
        //    U32 h32;

        //    if (state->large_len) {
        //        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
        //    } else {
        //        h32 = state->v3 /* == seed */ + PRIME32_5;
        //    }

        //    h32 += state->total_len_32;

        //    while (p+4<=bEnd) {
        //        h32 += XXH_readLE32(p, endian) * PRIME32_3;
        //        h32  = XXH_rotl32(h32, 17) * PRIME32_4;
        //        p+=4;
        //    }

        //    while (p<bEnd) {
        //        h32 += (*p) * PRIME32_5;
        //        h32  = XXH_rotl32(h32, 11) * PRIME32_1;
        //        p++;
        //    }

        //    h32 ^= h32 >> 15;
        //    h32 *= PRIME32_2;
        //    h32 ^= h32 >> 13;
        //    h32 *= PRIME32_3;
        //    h32 ^= h32 >> 16;

        //    return h32;
        //}


        //XXH_PUBLIC_API unsigned int XXH32_digest ( XXH32_state_t* state_in)
        //{
        //    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;

        //    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
        //        return XXH32_digest_endian(state_in, XXH_littleEndian);
        //    else
        //        return XXH32_digest_endian(state_in, XXH_bigEndian);
        //}



        ///* **** XXH64 **** */

        public static XXH_errorcode XXH64_update_endian(XXH64_state_t state, void *input, size_t len /*, XXH_endianess endian*/)
        {
            BYTE *p    = (BYTE *)input;
            BYTE *bEnd = p + len;

            //#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
            //    if (input==NULL) return XXH_ERROR;
            //#endif

            state.total_len += len;

            if (state.memsize + len < 32)
            {
                /* fill in tmp buffer */
                XXH_memcpy(((BYTE *)state.mem64) + state.memsize, input, len);
                state.memsize += (U32)len;
                return(XXH_errorcode.XXH_OK);
            }

            if (state.memsize != 0)
            {
                /* tmp buffer is full */
                XXH_memcpy(((BYTE *)state.mem64) + state.memsize, input, 32 - state.memsize);
                state.v1      = XXH64_round(state.v1, XXH_readLE64(state.mem64 + 0 /*, endian*/));
                state.v2      = XXH64_round(state.v2, XXH_readLE64(state.mem64 + 1 /*, endian*/));
                state.v3      = XXH64_round(state.v3, XXH_readLE64(state.mem64 + 2 /*, endian*/));
                state.v4      = XXH64_round(state.v4, XXH_readLE64(state.mem64 + 3 /*, endian*/));
                p            += 32 - state.memsize;
                state.memsize = 0;
            }

            if (p + 32 <= bEnd)
            {
                BYTE *limit = bEnd - 32;
                U64   v1    = state.v1;
                U64   v2    = state.v2;
                U64   v3    = state.v3;
                U64   v4    = state.v4;

                do
                {
                    v1 = XXH64_round(v1, XXH_readLE64(p /*, endian*/));
                    p += 8;
                    v2 = XXH64_round(v2, XXH_readLE64(p /*, endian*/));
                    p += 8;
                    v3 = XXH64_round(v3, XXH_readLE64(p /*, endian*/));
                    p += 8;
                    v4 = XXH64_round(v4, XXH_readLE64(p /*, endian*/));
                    p += 8;
                } while (p <= limit);

                state.v1 = v1;
                state.v2 = v2;
                state.v3 = v3;
                state.v4 = v4;
            }

            if (p < bEnd)
            {
                XXH_memcpy(state.mem64, p, (size_t)(bEnd - p));
                state.memsize = (uint)(bEnd - p);
            }

            return(XXH_errorcode.XXH_OK);
        }
Exemplo n.º 10
0
        ///* *************************************
        //*  Dependencies
        //***************************************/
        //#include "mem.h"
        //#include "error_private.h"       /* ERR_*, ERROR */
        //#define FSE_STATIC_LINKING_ONLY  /* FSE_MIN_TABLELOG */
        //#include "fse.h"
        //#define HUF_STATIC_LINKING_ONLY  /* HUF_TABLELOG_ABSOLUTEMAX */
        //#include "huf.h"


        ///*===   Version   ===*/
        //unsigned VersionNumber(void) { return FSE_VERSION_NUMBER; }


        ///*===   Error Management   ===*/
        //unsigned IsError(size_t code) { return ERR_isError(code); }
        // char* GetErrorName(size_t code) { return ERR_getErrorName(code); }

        //unsigned IsError(size_t code) { return ERR_isError(code); }
        // char* GetErrorName(size_t code) { return ERR_getErrorName(code); }


        /*-**************************************************************
        *  FSE NCount encoding-decoding
        ****************************************************************/
        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));
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        public void WriteTagListWithPublishInfo(DataIO pData)
        {
            if (m_pliPublishingIPs == null || m_pliPublishingIPs.Count == 0)
            {
                Debug.Assert(false);
                WriteTagList(pData);
                return;
            }

            uint nAdditionalTags = 1;

            if (!m_aAICHHashs.IsEmpty())
            {
                nAdditionalTags++;
            }
            WriteTagListInc(pData, nAdditionalTags); // write the standard taglist but increase the tagcount by the count we wan to add

            // here we add a tag including how many publishers this entry has, the trustvalue and how many different names are known
            // this is supposed to get used in later versions as an indicator for the user how valid this result is (of course this tag
            // alone cannt be trusted 100%, because we could be a bad node, but its a part of the puzzle)
            uint uTrust      = (ushort)(GetTrustValue() * 100);
            uint uPublishers = m_pliPublishingIPs.Count % 256;
            uint uNames      = m_listFileNames.Count % 256;
            // 32 bit tag: <namecount uint8><publishers uint8><trustvalue*100 uint16>
            uint uTagValue = (uNames << 24) | (uPublishers << 16) | (uTrust << 0);

            KadTagUInt tag(TAG_PUBLISHINFO, uTagValue);

            pData.WriteTag(&tag);

            // Last but not least the AICH Hash tag, containing all reported (hopefulley exactly 1) AICH hashes for this file together
            // with the count of publishers who reported it
            if (!m_aAICHHashs.IsEmpty())
            {
                SafeMemFile fileAICHTag(100);

                byte byCount = 0;
                // get count of AICH tags with popularity > 0
                for (int i = 0; i < m_aAICHHashs.Count; i++)
                {
                    if (m_anAICHHashPopularity[i] > 0)
                    {
                        byCount++;
                    }
                    // bobs tags in kad are limited to 255 bytes, so no more than 12 AICH hashes can be written
                    // that shouldn't be an issue however, as the normal AICH hash count is 1, if we have more than
                    // 10 for some reason we can't use it most likely anyway
                    if (1 + (CAICHHash::GetHashSize() * (byCount + 1)) + (1 * (byCount + 1)) > 250)
                    {
                        DebugLogWarning("More than 12(!) AICH Hashs to send for search answer, have to truncate, entry: %s", m_uSourceID.ToHexString());
                        break;
                    }
                }
                // write tag even on 0 count now
                fileAICHTag.WriteUInt8(byCount);
                byte nWritten = 0;
                byte j;
                for (j = 0; nWritten < byCount && j < m_aAICHHashs.GetCount(); j++)
                {
                    if (m_anAICHHashPopularity[j] > 0)
                    {
                        fileAICHTag.WriteUInt8(m_anAICHHashPopularity[j]);
                        m_aAICHHashs[j].Write(&fileAICHTag);
                        nWritten++;
                    }
                }
                Debug.Assert(nWritten == byCount && nWritten <= j);
                Debug.Assert(fileAICHTag.GetLength() <= 255);
                byte  nSize    = (byte)fileAICHTag.GetLength();
                BYTE *byBuffer = fileAICHTag.Detach();
                KadTagBsob tag(TAG_KADAICHHASHRESULT, byBuffer, nSize);

                pData.WriteTag(&tag);
                free(byBuffer);
            }
        }