Пример #1
0
            /// <summary>
            /// Even-Rodeh code
            ///
            ///  Encode a non-negative integer N :
            ///   1. If N is less than 4 then output N in 3 bits and stop.
            ///   2. If N is less than 8 then prepend the coded value with 3 bits containing the value of N and stop.
            ///   3. Prepend the coded value with the binary representation of N.
            ///   4. Store the number of bits prepended in step 3 as the new value of N.
            ///   5. Go back to step 2
            ///   6. Output a single 0 bit.
            ///
            /// </summary>
            /// <returns></returns>
            public static void Encode(Bitstream bitstream, uint value)
            {
                if (value < 4)
                {
                    bitstream.Write(value, 3);
                    return;
                }

                var  stack = new Stack <uint>();
                uint n     = value;

                while (true)
                {
                    if (n < 8)
                    {
                        stack.Push(n);
                        break;
                    }
                    stack.Push(n);
                    n = CodecBase.BitsRequired(n);
                }
                while (stack.Any())
                {
                    uint val = stack.Pop();
                    if (val < 8)
                    {
                        bitstream.Write(val, 3);
                    }
                    else
                    {
                        bitstream.Write(val);
                    }
                }
                bitstream.Write(0, 1);
            }
Пример #2
0
        /// <summary>
        /// Compress stream of numbers:
        /// Store length+1 using EliasDelta (to avoid 0 case)
        /// First number x0 requires b0 bits. Write b0 in EliasDelta. Write x0 in b0 bits.
        /// Each subsequent number xi requires bi bits. If bi leq b(i-1) then
        /// write a 0 bit, then xi in b(i-1) bits. Else write (bi-b(i-1)) 1 bits, then a 0,
        /// then the least sig bi - 1 bits of xi (the leading 1 in xi is implied, xi>0).
        /// TODO - alternatives - allow the bi to change slowly, removes some hiccups for odd data points, set b to avg of some prev values
        /// </summary>
        /// <param name="bitstream"></param>
        /// <param name="data"></param>
        /// <param name="universalCoder">How to encode/decode a data length and first bitlength items. Elias.EncodeDelta is useful</param>
        public static void BinaryAdaptiveSequentialEncode(Bitstream bitstream, Datastream data, Action <Bitstream, uint> universalCoder)
        {
            universalCoder(bitstream, (uint)data.Count + 1);
            if (data.Count == 0)
            {
                return;
            }
            uint b1 = CodecBase.BitsRequired(data[0]);

            universalCoder(bitstream, b1);
            bitstream.Write(data[0]);
            for (var i = 1; i < data.Count; ++i)
            {
                uint d  = data[i];
                uint b2 = CodecBase.BitsRequired(d);

                if (b2 <= b1)
                { // b1 is enough bits
                    bitstream.Write(0);
                    bitstream.Write(d, b1);
                }
                else
                { // b2 requires more bits, tell how many
                    Trace.Assert(d > 0);
                    for (var ik = 0; ik < b2 - b1; ++ik)
                    {
                        bitstream.Write(1);
                    }
                    bitstream.Write(0, 1);      // end of bit count
                    bitstream.Write(d, b2 - 1); // strip off leading '1'
                }
                b1 = CodecBase.BitsRequired(d); // for next pass
            }
        }
Пример #3
0
            /// <summary>
            /// Encode integer N via Sk(N) 0 B(N,floor(log_2 N)+1)
            ///
            /// Recursively define: for fixed integer k > 1
            /// Sk(n) = B(n,l) if n in [0,2^k-1], else = Sk(Floor[Log_2 n]-k) B(n,Floor[Log_2 n]+1)
            /// where B(n,l) writes n in k bits
            /// Note the final B value is 0 prefixed, which lets the decoder know this is the last block.
            /// </summary>
            public static void Encode(Bitstream bitstream, uint value, uint k)
            {
                uint bitLength = CodecBase.BitsRequired(value);

                Recurse(bitstream, bitLength, k);
                bitstream.Write(0);
                bitstream.Write(value);
            }
Пример #4
0
            /// <summary>
            /// L = bits needed to store value
            /// Write L-1 zero bits, then the value in binary (which necessarily starts with one)
            /// </summary>
            /// <param name="bitstream"></param>
            /// <param name="value32"></param>
            public static void EncodeGamma(Bitstream bitstream, uint value32)
            {
                Trace.Assert(value32 >= 1);
                uint n = CodecBase.BitsRequired(value32);

                for (var i = 0; i < n - 1; ++i)
                {
                    bitstream.Write(0);
                }
                bitstream.Write(value32, n);
            }
Пример #5
0
 /// <summary>
 /// Write the value to the bitstream in the minimum number of bits.
 /// Writes 0 using 1 bit.
 /// </summary>
 /// <param name="value"></param>
 public void Write(uint value)
 {
     if (value != 0)
     {
         Write(value, CodecBase.BitsRequired(value));
     }
     else
     {
         Write(0, 1);
     }
 }
Пример #6
0
            /// <summary>
            /// Encode a 32 bit value into the bitstream using Lomont method 3
            /// </summary>
            /// <param name="bitstream"></param>
            /// <param name="value32"></param>
            public static void EncodeLomont3(Bitstream bitstream, uint value32)
            {
                Trace.Assert(value32 > 0);
                uint n = CodecBase.BitsRequired(value32);

                for (var i = 0; i < n - 1; ++i)
                {
                    bitstream.Write(0, 1);       // n-1 of these
                }
                bitstream.Write(1, 1);           // end of n count
                bitstream.Write(value32, n - 1); // remove leading 1
            }
Пример #7
0
            /// <summary>
            /// Encode a 32 bit value into the bitstream using Elias Delta coding
            /// To encode a number X greater than 0:
            /// 1. N = number of bits needed to store X. N >=1
            /// 2. L = number of bits needed to store N. L >= 1
            /// 3. Write L-1 zeroes.
            /// 4. Write the L bit representation of N (which starts with a 1)
            /// 5. Write all but the leading 1 bit of X (i.e., the last N-1 bits)
            /// </summary>
            /// <param name="bitstream"></param>
            /// <param name="value32"></param>
            public static void EncodeDelta(Bitstream bitstream, uint value32)
            {
                Trace.Assert(value32 >= 1);
                uint n = CodecBase.BitsRequired(value32);
                uint l = CodecBase.BitsRequired(n);

                for (var i = 1; i <= l - 1; ++i)
                {
                    bitstream.Write(0, 1);
                }
                bitstream.Write(n, l);
                bitstream.Write(value32, n - 1);
            }
Пример #8
0
            /// <summary>
            /// Decodes truncated code item
            /// </summary>
            /// <param name="bitstream"></param>
            /// <param name="n"></param>
            /// <returns></returns>
            public static uint Decode(Bitstream bitstream, uint n)
            {
                uint k = CodecBase.BitsRequired(n);
                uint u = (1U << (int)k) - n; // u = number of unused codewords
                uint x = bitstream.Read(k - 1);

                if (x >= u)
                { // need another bit
                    x  = 2 * x + bitstream.Read(1);
                    x -= u;
                }
                return(x);
            }
Пример #9
0
 /// <summary>
 /// Write a universal compression header
 /// </summary>
 /// <param name="bitstream"></param>
 /// <param name="data"></param>
 /// <param name="headerFlags"></param>
 public static void WriteUniversalHeader(Bitstream bitstream, Datastream data, HeaderFlags headerFlags)
 {
     if (headerFlags.HasFlag(HeaderFlags.SymbolCount))
     {
         UniversalCodec.Lomont.EncodeLomont1(bitstream, (uint)data.Count, 6, 0);
     }
     if (headerFlags.HasFlag(HeaderFlags.BitsPerSymbol))
     {
         var max           = data.Any() ? data.Max() : 0;
         var bitsPerSymbol = CodecBase.BitsRequired(max);
         UniversalCodec.Lomont.EncodeLomont1(bitstream, bitsPerSymbol - 1, 3, 0);
     }
 }
Пример #10
0
 static void Recurse(Bitstream bitstream, uint n, uint k)
 {
     Trace.Assert(k > 1);
     if (n < (1U << (int)k))
     {
         bitstream.Write(n, k);
     }
     else
     {
         uint m = CodecBase.FloorLog2(n);
         Recurse(bitstream, m - k, k);
         bitstream.Write(n, m + 1);
     }
 }
Пример #11
0
 /// <summary>
 /// Exponential Golumb code for x geq 0
 /// 1. Write (x+1) in binary in n bits
 /// 2. Prepend n-1 zero bits
 ///
 /// Order k > 0, do above to Floor[x/2^k]
 /// Then x mod 2^k in binary
 /// </summary>
 /// <param name="bitstream"></param>
 /// <param name="value"></param>
 /// <param name="k"></param>
 public static void EncodeExp(Bitstream bitstream, uint value, uint k)
 {
     if (k > 0)
     {
         EncodeExp(bitstream, value >> (int)k, 0);
         uint mask = (1U << (int)k) - 1;
         bitstream.Write(value & mask, k);
     }
     else
     {
         uint n = CodecBase.BitsRequired(value + 1);
         bitstream.Write(0, n - 1);
         bitstream.Write(value + 1, n);
     }
 }
Пример #12
0
            /// <summary>
            /// Useful for encoding a value in [0,N).
            /// k = bit length N, k > 0
            /// If N is a power of 2, uses k bits.
            /// If N is not a power of two, encodes some choices in k-1 bits, others in k bits
            /// </summary>
            public static void Encode(Bitstream bitstream, uint value, uint n)
            {
                Trace.Assert(value < n);
                uint k = CodecBase.BitsRequired(n);
                uint u = (1U << (int)k) - n; // u = number of unused codewords

                if (value < u)
                {
                    bitstream.Write(value, k - 1);
                }
                else
                {
                    bitstream.Write(value + u, k);
                }
            }
Пример #13
0
            public static void EncodeOmega(Bitstream bitstream, uint value32)
            {
                Trace.Assert(value32 >= 1);
                var stack = new Stack <uint>();

                while (value32 != 1)
                {
                    stack.Push(value32);
                    value32 = CodecBase.BitsRequired(value32) - 1;
                }
                while (stack.Any())
                {
                    bitstream.Write(stack.Pop());
                }
                bitstream.Write(0);
            }
Пример #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="bitstream"></param>
        /// <param name="universalDecoder">The same encoder/decoder pair used to encode this</param>
        /// <returns></returns>
        public static List <uint> BinaryAdaptiveSequentialDecode(Bitstream bitstream, Func <Bitstream, uint> universalDecoder)
        {
            var  list   = new List <uint>();
            uint length = universalDecoder(bitstream) - 1;

            if (length == 0)
            {
                return(list);
            }
            uint b1 = universalDecoder(bitstream);
            uint xi = bitstream.Read(b1);

            list.Add(xi);
            while (list.Count < length)
            {
                var decision = bitstream.Read(1);
                if (decision == 0)
                { // bi is <= b(i-1), so enough bits
                    xi = bitstream.Read(b1);
                }
                else
                { // bi is bigger than b(i-1), must increase it
                    uint delta = 0;
                    do
                    {
                        decision = bitstream.Read(1);
                        delta++;
                    } while (decision != 0);
                    b1 += delta;
                    xi  = bitstream.Read(b1 - 1); // xi has implied leading 1
                    xi |= 1U << (int)(b1 - 1);
                }
                list.Add(xi);
                b1 = CodecBase.BitsRequired(xi);
            }
            return(list);
        }