public override int Read(IOfcNumberWriter writer, Block block, StreamBitReader reader)
        {
            // ReSharper disable once AssignmentInConditionalExpression
            if (block.OverrideGlobalNb = reader.ReadByte(1) > 0)
            {
                block.NeededBits = reader.ReadByte(Metadata.MaxNeededBitsNeededBitsNumber);
            }

            // ReSharper disable once AssignmentInConditionalExpression
            if (!Metadata.IsAbsolute)
            {
                if (block.AbsoluteSign = reader.ReadByte(1) > 0)
                {
                    block.IsSignNegative = reader.ReadByte(1) > 0;
                }
            }

            var hasAbsoluteSign = block.AbsoluteSign || Metadata.IsAbsolute;
            var isNegative      = block.AbsoluteSign && block.IsSignNegative || Metadata.IsAbsolute && Metadata.IsNegative;

            for (var i = 0; i < block.Length; i++)
            {
                var num = new OfcNumber();

                if (!hasAbsoluteSign)
                {
                    isNegative = reader.ReadByte(1) > 0;
                }

                num.Number = ((long)reader.Read(Metadata.MaxNeededBitsNumber)) * (isNegative ? -1 : 1);
                writer.Write(num);
            }

            return(block.Length);
        }
Exemple #2
0
        /// <summary>
        /// Reads a Single Value from its binary representation without the control bit (isBlock)
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public static OfcNumber ReadSingleValueWithoutControlBit(StreamBitReader reader, BlockyMetadata metadata)
        {
            var value = new OfcNumber();

            if (!metadata.IsAbsolute)
            {
                value.IsNegative = reader.ReadByte(1) > 0;
            }
            else
            {
                value.IsNegative = metadata.IsNegative;
            }
            value.Number = (long)reader.Read(metadata.MaxNeededBitsNumber);
            var isExpNegative = reader.ReadByte(1) > 0;

            value.Exponent = (short)reader.Read(metadata.MaxNeededBitsExponent); // Bug: Potentually reading exp even though NoExp is set. Same in writing method! (Ineffizient)
            if (isExpNegative)
            {
                value.Exponent *= -1;
            }
            return(value);
        }
Exemple #3
0
        /// <summary>
        /// Reads the metadata in its binary form
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static BlockyMetadata FromBitStream(StreamBitReader reader)
        {
            var metadata = new BlockyMetadata {
                ValueCount = (int)reader.Read(31)
            };

            // ReSharper disable once AssignmentInConditionalExpression
            if (metadata.IsAbsolute = reader.ReadByte(1) > 0)
            {
                metadata.IsNegative = reader.ReadByte(1) > 0;
            }
            metadata.MaxNeededBitsExponent         = reader.ReadByte(4);
            metadata.MaxNeededBitsNumber           = reader.ReadByte(6);
            metadata.MaxNeededBitsNeededBitsNumber = Utility.GetNeededBits(metadata.MaxNeededBitsNumber);
            metadata.LargestPossibleValue          = Utility.GetMaxValue(metadata.MaxNeededBitsNumber);
            return(metadata);
        }
Exemple #4
0
        /// <summary>
        /// Exclusive IsBlock
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public static Block ReadDefaultBlockHeader(StreamBitReader reader, BlockyMetadata metadata)
        {
            var block = new Block();

            // ReSharper disable once AssignmentInConditionalExpression
            if (block.HasExponent = reader.ReadByte(1) > 0)
            {
                var negative = reader.ReadByte(1) > 0;
                block.Exponent = (short)reader.Read(metadata.MaxNeededBitsExponent);
                if (negative)
                {
                    block.Exponent *= -1;
                }
            }

            // ReSharper disable once AssignmentInConditionalExpression
            if (block.HasPattern = reader.ReadByte(1) > 0)
            {
                block.Pattern = (Block.PatternType)reader.ReadByte(2);
            }

            block.Length = reader.ReadByte(8);
            return(block);
        }
        public bool DecompressNext()
        {
            var blockLength = (int)_streamBitReader.Read(32);

            if (blockLength == 0)
            {
                return(false);                  // The compression will write 0 as int32 at the end - a block with 0 length = the end
            }
            var numbers             = new char[blockLength][];
            var numberLengths       = new int[blockLength];
            var expLengths          = new int[blockLength];
            var averageNumberLength = _streamBitReader.ReadByte(8);
            var averageExpLength    = _streamBitReader.ReadByte(8);

            #region Reconstructing value lengths from bit mask and initializing numbers array
            for (var i = 0; i < blockLength; i++)
            {
                var isSmallerThanAvg = _streamBitReader.ReadByte(1) * -2 + 1; // * -2 + 1 transforms a 0 - 1 isNegative bool into a -1 or 1 multiplier ;)
                var diff             = 0;
                while (_streamBitReader.ReadByte(1) == 0)
                {
                    diff++;
                }
                numberLengths[i] = averageNumberLength + diff * isSmallerThanAvg;
            }

            for (var i = 0; i < blockLength; i++)
            {
                var isSmallerThanAvg = _streamBitReader.ReadByte(1) * -2 + 1; // * -2 + 1 transforms a 0 - 1 isNegative bool into a -1 or 1 multiplier ;)
                var diff             = 0;
                while (_streamBitReader.ReadByte(1) == 0)
                {
                    diff++;
                }
                expLengths[i] = averageExpLength + diff * isSmallerThanAvg;

                var thisNumLength = numberLengths[i];
                if (expLengths[i] > 0)
                {
                    thisNumLength += expLengths[i] + 1;
                }
                numbers[i] = new char[thisNumLength];
            }
            #endregion


            var changed = true;
            for (var digitIndex = 0; changed; digitIndex++)
            {
                changed = false;
                for (var i = 0; i < blockLength; i++)
                {
                    if (numberLengths[i] > digitIndex)
                    {
                        changed = true;
                        numbers[i][digitIndex] = (char)_stream.ReadByte();
                    }
                }
            }

            for (var i = 0; i < blockLength; i++)
            {
                if (expLengths[i] > 0)
                {
                    numbers[i][numberLengths[i]] = 'e';
                }
            }


            changed = true;
            for (var digitIndex = 0; changed; digitIndex++)
            {
                changed = false;
                for (var i = 0; i < blockLength; i++)
                {
                    if (expLengths[i] > digitIndex)
                    {
                        changed = true;
                        numbers[i][numberLengths[i] + 1 + digitIndex] = (char)_stream.ReadByte();
                    }
                }
            }

            for (var i = 0; i < numbers.Length; i++)
            {
                _output.Report(new string(numbers[i]));
            }
            return(true);
        }