Esempio n. 1
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);
            }
Esempio n. 2
0
            public static uint DecodeGamma(Bitstream bitstream)
            {
                uint n = 0, b;

                do
                {
                    b = bitstream.Read(1);
                    n++;
                } while (b != 1);
                n--;
                var t = bitstream.Read(n);

                return((1U << (int)n) + t);
            }
Esempio n. 3
0
            public static uint DecodeOmega(Bitstream bitstream)
            {
                uint n = 1, b;

                do
                {
                    b = bitstream.Read(1);
                    if (b != 0)
                    {
                        uint t = bitstream.Read(n);
                        n = (1U << (int)n) + t;
                    }
                } while (b != 0);
                return(n);
            }
Esempio n. 4
0
            public static uint DecodeDelta(Bitstream bitstream)
            {
                uint l = 0, b;

                do
                {
                    b = bitstream.Read(1);
                    l++;
                } while (b == 0);
                // get remaining l-1 digits of n, add back initial bit read in loop while determining L
                uint n = bitstream.Read(l - 1) + (1U << (int)(l - 1));
                // read last n-1 bits of x, add back leading bit
                uint x = bitstream.Read(n - 1) + (1U << (int)(n - 1));

                return(x);
            }
Esempio n. 5
0
            /// <summary>
            /// </summary>
            /// <returns></returns>
            public static uint Decode(Bitstream bitstream, uint k)
            {
                Trace.Assert(k > 1);
                uint v = bitstream.Read(k);

                while (true)
                {
                    uint b = bitstream.Read(1);
                    if (b == 0) // end of chain
                    {
                        return(bitstream.Read(v));
                    }
                    v += k;
                    v  = (1U << (int)v) + bitstream.Read(v);
                }
            }
Esempio n. 6
0
 // read one bit, return 0 when out of bits
 uint ReadBit(Bitstream bitstream)
 {
     ++bitsRead;
     if (bitsRead < bitLength)
     {
         return(bitstream.Read(1));
     }
     return(0);
 }
Esempio n. 7
0
            /// <summary>
            /// To decode an Even-Rodeh-coded integer:
            ///   1.Read 3 bits and store the value into N.If the first bit read was 0 then stop.The decoded number is N.
            ///     If the first bit read was 1 then continue to step 2.
            ///   2.Examine the next bit. If the bit is 0 then read 1 bit and stop.The decoded number is N.
            ///     If the bit is 1 then read N bits, store the value as the new value of N, and go back to step 2.
            /// </summary>
            /// <param name="bitstream"></param>
            /// <returns></returns>
            public static uint Decode(Bitstream bitstream)
            {
                uint n = bitstream.Read(3);

                if (n < 4)
                {
                    return(n);
                }
                while (true)
                {
                    uint nextBit = bitstream.Read(1);
                    if (nextBit == 0)
                    {
                        return(n);
                    }
                    uint m = bitstream.Read(n - 1);
                    n = m | (1U << (int)(n - 1));
                }
            }
Esempio n. 8
0
        /// <summary>
        /// Copy in the given BitStream
        /// </summary>
        /// <param name="bitstream"></param>
        public void WriteStream(Bitstream bitstream)
        {
            var temp = bitstream.Position;

            bitstream.Position = 0;
            while (bitstream.Position < bitstream.Length)
            {
                Write(bitstream.Read(1), 1);
            }
            bitstream.Position = temp;
        }
Esempio n. 9
0
        /// <summary>
        /// Read the header for the compression algorithm
        /// Return number of symbols in stream if known, else 0 if not present
        /// </summary>
        /// <param name="bitstream"></param>
        /// <param name="headerFlags">Flags telling what to put in the header. Useful when embedding in other streams.</param>
        /// <returns></returns>
        public override uint ReadHeader(Bitstream bitstream, Header.HeaderFlags headerFlags)
        {
            decoderState = new DecoderState();

            // read header values
            var header = Header.ReadUniversalHeader(bitstream, headerFlags);

            decoderState.SymbolCount = header.Item1;

            // get max distance occurring, used to encode tokens, very useful to users to know window needed size
            decoderState.ActualMaxDistance = UniversalCodec.Lomont.DecodeLomont1(bitstream, 10, 0);
            decoderState.ActualMinLength   = UniversalCodec.Lomont.DecodeLomont1(bitstream, 2, 0);

            // see if decisions or decision runs
            if (bitstream.Read(1) == 0)
            {
                decoderState.DecisionDecoder = ReadItem(bitstream);
            }
            else
            {
                // read initial value
                decoderState.InitialValue = bitstream.Read(1);
                // read item
                decoderState.DecisionRunDecoder = ReadItem(bitstream);
            }

            // literals
            decoderState.LiteralDecoder = ReadItem(bitstream);

            // tokens or separate distance, length pairs
            if (bitstream.Read(1) == 0)
            {
                decoderState.TokenDecoder = ReadItem(bitstream);
            }
            else
            {
                decoderState.DistanceDecoder = ReadItem(bitstream);
                decoderState.LengthDecoder   = ReadItem(bitstream);
            }
            return(decoderState.SymbolCount);
        }
Esempio n. 10
0
            public static uint Decode(Bitstream bitstream, uint m)
            {
                Trace.Assert(m > 0);
                var q = 0U;

                while (bitstream.Read(1) == 1)
                {
                    ++q;
                }
                uint r = Truncated.Decode(bitstream, m);

                return(q * m + r);
            }
Esempio n. 11
0
        /// <summary>
        /// Decompress a symbol in the compression algorithm
        /// </summary>
        /// <param name="bitstream"></param>
        public override uint DecompressSymbol(Bitstream bitstream)
        {
            var output = decoderState.DecoderStream;

            // decode some if needed
            while (output.Count <= decoderState.DatumIndex)
            {
                if (bitstream.Read(1) == 0)
                {
                    // literal
                    uint symbol = bitstream.Read(decoderState.ActualBitsPerSymbol);
                    if (Options.HasFlag(OptionFlags.DumpDebug))
                    {
                        Write($"{output.Count}:[{symbol}] ");
                    }

                    output.Add(symbol);
                    ++decoderState.DatumIndex;
                    return(symbol);
                }
                // run
                uint token = bitstream.Read(decoderState.ActualBitsPerToken);
                // decode token
                uint length   = token / (decoderState.ActualMaxDistance + 1) + decoderState.ActualMinLength;
                uint distance = token % (decoderState.ActualMaxDistance + 1);

                if (Options.HasFlag(OptionFlags.DumpDebug))
                {
                    Write($"[{distance},{length}] ");
                }

                // copy run
                for (uint i = 0; i < length; ++i)
                {
                    output.Add(output[(int)(output.Count - distance - 1)]);
                }
            }
            return(output[decoderState.DatumIndex++]);
        }
Esempio n. 12
0
            public static uint DecodeExp(Bitstream bitstream, uint k)
            {
                if (k > 0)
                {
                    // read value shifted by k
                    uint high = DecodeExp(bitstream, 0);
                    //read last k bits
                    uint low = bitstream.Read(k);
                    return((high << (int)k) | low);
                }
                uint n = 0, b;

                do
                {
                    b = bitstream.Read(1);
                    ++n;
                } while (b == 0);
                // b is high bit of value + 1
                uint value = bitstream.Read(n - 1);

                value |= b << (int)(n - 1);
                return(value - 1);
            }
Esempio n. 13
0
            /// <summary>
            /// Decode lomont method 1 with the given chunksize
            /// </summary>
            /// <param name="bitstream"></param>
            /// <param name="chunkSize"></param>
            /// <param name="deltaChunk"></param>
            public static uint DecodeLomont1(Bitstream bitstream, int chunkSize, int deltaChunk)
            {
                uint value = 0, b;
                int  shift = 0;

                do
                {
                    b = bitstream.Read(1); // decision
                    uint chunk = bitstream.Read((uint)chunkSize);
                    value += chunk << shift;
                    shift += chunkSize;

                    if (deltaChunk != 0)
                    {
                        chunkSize += deltaChunk;
                        if (chunkSize <= 0)
                        {
                            chunkSize = 1;
                        }
                    }
                } while (b != 0);
                return(value);
            }
Esempio n. 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);
        }
Esempio n. 15
0
        // Get codec type, a bitstream for it, read the header, advance the bitstream
        // the codec, the bit length, and the bitstream
        Decoder ReadItem(Bitstream bitstream)
        {
            var decoder = new Decoder();
            // save type
            uint type = bitstream.Read(2);

            if (type == 0)
            {
                decoder.Codec = new FixedSizeCodec();
            }
            else if (type == 1)
            {
                decoder.Codec = new ArithmeticCodec();
            }
            else if (type == 2)
            {
                decoder.Codec = new HuffmanCodec();
            }
            else if (type == 3)
            {
                decoder.Codec = new GolombCodec();
            }
            else
            {
                throw new NotImplementedException("Unknown compressor type");
            }
            decoder.BitLength = UniversalCodec.Lomont.DecodeLomont1(bitstream, 6, 0);
            if (Options.HasFlag(OptionFlags.DumpDebug))
            {
                WriteLine($"Compressor index {type}, length {decoder.BitLength}");
            }

            // prepare a bitstream for the codec
            decoder.Bitstream = new Bitstream();
            decoder.Bitstream.WriteStream(bitstream);
            decoder.Bitstream.Position = bitstream.Position;
            decoder.Codec.ReadHeader(decoder.Bitstream, internalFlags);
            bitstream.Position += decoder.BitLength;
            if (Options.HasFlag(OptionFlags.DumpDebug))
            {
                WriteLine($"Post read item position {bitstream.Position}");
            }
            return(decoder);
        }
Esempio n. 16
0
 /// <summary>
 /// Decompress a symbol in the compression algorithm
 /// </summary>
 /// <param name="bitstream"></param>
 public override uint DecompressSymbol(Bitstream bitstream)
 {
     return(bitstream.Read(BitsPerSymbol));
 }
Esempio n. 17
0
        // lookup symbol and probability range using table decoding
        uint LookupLowMemoryCount(Bitstream bitstream, uint cumCount, out uint lowCount, out uint highCount)
        {
            // BASC encoded, decode with same process
            // todo - merge with BASC Codec version, make cleaner

            // swap bit positions to access table
            uint tempPosition = bitstream.Position; // save this

            bitstream.Position = tableStartBitPosition;

            lowCount = highCount = 0;
            uint symbol = 0;

            uint length = UniversalCodec.Lomont.DecodeLomont1(bitstream, 6, 0);

            if (length != 0)
            {
                uint b1 = UniversalCodec.Lomont.DecodeLomont1(bitstream, 6, 0);
                uint xi = bitstream.Read(b1);

                lowCount  = 0;
                highCount = xi;
                symbol    = symbolMin;
                uint i = symbolMin;

                while (highCount <= cumCount)
                {
                    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);
                    }
                    b1 = BitsRequired(xi);

                    lowCount   = highCount;
                    highCount += xi;
                    ++i;
                    if (xi != 0)
                    {
                        symbol = i;
                    }
                }
            }

            // restore bit position
            bitstream.Position = tempPosition;
            return(symbol);
        }