예제 #1
0
        public void MustBeGreaterThan_IsLessOrEqual_ThrowsNoException(int value, int min)
        {
            ArgumentOutOfRangeException exception = Assert.Throws <ArgumentOutOfRangeException>(
                () => DebugGuard.MustBeGreaterThan(value, min, "myParamName"));

            Assert.Equal("myParamName", exception.ParamName);
            Assert.Contains($"Value {value} must be greater than {min}.", exception.Message);
        }
예제 #2
0
        public int ReadSignedValue(int nBits)
        {
            DebugGuard.MustBeGreaterThan(nBits, 0, nameof(nBits));
            DebugGuard.MustBeLessThanOrEqualTo(nBits, 32, nameof(nBits));

            int value = (int)this.ReadValue(nBits);

            return(this.ReadValue(1) != 0 ? -value : value);
        }
예제 #3
0
        public uint ReadValue(int nBits)
        {
            DebugGuard.MustBeGreaterThan(nBits, 0, nameof(nBits));
            DebugGuard.MustBeLessThanOrEqualTo(nBits, 32, nameof(nBits));

            uint v = 0;

            while (nBits-- > 0)
            {
                v |= (uint)this.GetBit(0x80) << nBits;
            }

            return(v);
        }
예제 #4
0
        public uint ReadValue(int nBits)
        {
            DebugGuard.MustBeGreaterThan(nBits, 0, nameof(nBits));

            if (!this.Eos && nBits <= Vp8LMaxNumBitRead)
            {
                ulong val = this.PrefetchBits() & BitMask[nBits];
                this.bitPos += nBits;
                this.ShiftBytes();
                return((uint)val);
            }

            return(0);
        }
예제 #5
0
        /// <summary>
        /// Reads the next value.
        /// </summary>
        /// <param name="nBits">The number of bits to read.</param>
        /// <returns>The value read.</returns>
        protected uint ReadValue(int nBits)
        {
            DebugGuard.MustBeGreaterThan(nBits, 0, nameof(nBits));

            uint v     = 0;
            int  shift = nBits;

            while (shift-- > 0)
            {
                uint bit = this.GetBit();
                v |= bit << shift;
                this.CurValueBitsRead++;
            }

            return(v);
        }
예제 #6
0
        private static Vector4 Compose(Vector4 backdrop, Vector4 source, Vector4 xform)
        {
            DebugGuard.MustBeGreaterThan(source.W, 0, nameof(source.W));

            // calculate weights
            float xw = backdrop.W * source.W;
            float bw = backdrop.W - xw;
            float sw = source.W - xw;

            // calculate final alpha
            float a = xw + bw + sw;

            // calculate final value
            xform   = ((xform * xw) + (backdrop * bw) + (source * sw)) / a;
            xform.W = a;

            return(xform);
        }
예제 #7
0
 public void MustBeGreaterThan_IsGreater_ThrowsNoException()
 {
     DebugGuard.MustBeGreaterThan(2, 1, "myParamName");
 }
예제 #8
0
        public static int BuildHuffmanTable(Span <HuffmanCode> table, int rootBits, int[] codeLengths, int codeLengthsSize)
        {
            DebugGuard.MustBeGreaterThan(rootBits, 0, nameof(rootBits));
            DebugGuard.NotNull(codeLengths, nameof(codeLengths));
            DebugGuard.MustBeGreaterThan(codeLengthsSize, 0, nameof(codeLengthsSize));

            // sorted[codeLengthsSize] is a pre-allocated array for sorting symbols by code length.
            int[] sorted    = new int[codeLengthsSize];
            int   totalSize = 1 << rootBits;                                 // total size root table + 2nd level table.
            int   len;                                                       // current code length.
            int   symbol;                                                    // symbol index in original or sorted table.

            int[] counts  = new int[WebpConstants.MaxAllowedCodeLength + 1]; // number of codes of each length.
            int[] offsets = new int[WebpConstants.MaxAllowedCodeLength + 1]; // offsets in sorted table for each length.

            // Build histogram of code lengths.
            for (symbol = 0; symbol < codeLengthsSize; ++symbol)
            {
                int codeLengthOfSymbol = codeLengths[symbol];
                if (codeLengthOfSymbol > WebpConstants.MaxAllowedCodeLength)
                {
                    return(0);
                }

                counts[codeLengthOfSymbol]++;
            }

            // Error, all code lengths are zeros.
            if (counts[0] == codeLengthsSize)
            {
                return(0);
            }

            // Generate offsets into sorted symbol table by code length.
            offsets[1] = 0;
            for (len = 1; len < WebpConstants.MaxAllowedCodeLength; ++len)
            {
                int codesOfLength = counts[len];
                if (codesOfLength > 1 << len)
                {
                    return(0);
                }

                offsets[len + 1] = offsets[len] + codesOfLength;
            }

            // Sort symbols by length, by symbol order within each length.
            for (symbol = 0; symbol < codeLengthsSize; ++symbol)
            {
                int symbolCodeLength = codeLengths[symbol];
                if (symbolCodeLength > 0)
                {
                    sorted[offsets[symbolCodeLength]++] = symbol;
                }
            }

            // Special case code with only one value.
            if (offsets[WebpConstants.MaxAllowedCodeLength] == 1)
            {
                var huffmanCode = new HuffmanCode()
                {
                    BitsUsed = 0,
                    Value    = (uint)sorted[0]
                };
                ReplicateValue(table, 1, totalSize, huffmanCode);
                return(totalSize);
            }

            int step;                       // step size to replicate values in current table
            int low       = -1;             // low bits for current root entry
            int mask      = totalSize - 1;  // mask for low bits
            int key       = 0;              // reversed prefix code
            int numNodes  = 1;              // number of Huffman tree nodes
            int numOpen   = 1;              // number of open branches in current tree level
            int tableBits = rootBits;       // key length of current table
            int tableSize = 1 << tableBits; // size of current table

            symbol = 0;

            // Fill in root table.
            for (len = 1, step = 2; len <= rootBits; ++len, step <<= 1)
            {
                int countsLen = counts[len];
                numOpen <<= 1;
                numNodes += numOpen;
                numOpen  -= counts[len];
                if (numOpen < 0)
                {
                    return(0);
                }

                for (; countsLen > 0; countsLen--)
                {
                    var huffmanCode = new HuffmanCode()
                    {
                        BitsUsed = len,
                        Value    = (uint)sorted[symbol++]
                    };
                    ReplicateValue(table.Slice(key), step, tableSize, huffmanCode);
                    key = GetNextKey(key, len);
                }

                counts[len] = countsLen;
            }

            // Fill in 2nd level tables and add pointers to root table.
            Span <HuffmanCode> tableSpan = table;
            int tablePos = 0;

            for (len = rootBits + 1, step = 2; len <= WebpConstants.MaxAllowedCodeLength; ++len, step <<= 1)
            {
                numOpen <<= 1;
                numNodes += numOpen;
                numOpen  -= counts[len];
                if (numOpen < 0)
                {
                    return(0);
                }

                for (; counts[len] > 0; --counts[len])
                {
                    if ((key & mask) != low)
                    {
                        tableSpan  = tableSpan.Slice(tableSize);
                        tablePos  += tableSize;
                        tableBits  = NextTableBitSize(counts, len, rootBits);
                        tableSize  = 1 << tableBits;
                        totalSize += tableSize;
                        low        = key & mask;
                        table[low] = new HuffmanCode
                        {
                            BitsUsed = tableBits + rootBits,
                            Value    = (uint)(tablePos - low)
                        };
                    }

                    var huffmanCode = new HuffmanCode
                    {
                        BitsUsed = len - rootBits,
                        Value    = (uint)sorted[symbol++]
                    };
                    ReplicateValue(tableSpan.Slice(key >> rootBits), step, tableSize, huffmanCode);
                    key = GetNextKey(key, len);
                }
            }

            return(totalSize);
        }