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); }
/// <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); }
/// <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); }
/// <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); }