Пример #1
0
        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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
0
        public override int Read(IOfcNumberWriter writer, Block block, StreamBitReader reader)
        {
            var val1 = ReadSingleValueWithoutControlBit(reader, Metadata);
            var val2 = ReadSingleValueWithoutControlBit(reader, Metadata);

            var ppLength = reader.ReadByte(8);
            var total    = ppLength * block.Length;

            for (var i = 0; i < total; i++)
            {
                writer.Write(i % (ppLength * 2) >= ppLength ? val2 : val1);
            }

            return(total);
        }
Пример #5
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);
        }
Пример #6
0
        protected BlockyDecompression([NotNull] Stream reader)
        {
            _bitReader = new StreamBitReader(reader);
            Metadata   = BlockyMetadata.FromBitStream(_bitReader);

            _decompressionMethods[(int)Blockfinding.Blockfinding.Methods.PatternSame]     = new PatternSameDecompression(Metadata);
            _decompressionMethods[(int)Blockfinding.Blockfinding.Methods.PatternPingPong] = new PatternPingPongDecompression(Metadata);
            _decompressionMethods[(int)Blockfinding.Blockfinding.Methods.FloatSimmilar]   = new FloatSimmilarDecompression(Metadata);
            _decompressionMethods[(int)Blockfinding.Blockfinding.Methods.NumbersNoExp]    = new NumbersNoExpDecompression(Metadata);
            _decompressionMethods[(int)Blockfinding.Blockfinding.Methods.PatternOffset]   = new PatternOffsetDecompression(Metadata);

            if (_bitReader.ReadByte(1) > 0) // use huffman
            {
                throw new NotImplementedException();
            }
        }
Пример #7
0
        public void Decompress()
        {
            var valueCount = 0;

            while (valueCount < Metadata.ValueCount)
            {
                if (_bitReader.ReadByte(1) > 0) // isBlock
                {
                    var block  = DecompressionMethod.ReadDefaultBlockHeader(_bitReader, Metadata);
                    var method = GetMethodForBlock(block); // Get decompressor class for block type
                    valueCount += method.Read(_numberWriter, block, _bitReader);
                }
                else
                {
                    _numberWriter.Write(DecompressionMethod.ReadSingleValueWithoutControlBit(_bitReader, Metadata));
                    valueCount++;
                }
            }
            _writer?.Flush();
        }
Пример #8
0
        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);
        }