示例#1
0
        /// <summary>
        /// Calculates the metadata from the given values
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static BlockyMetadata FromData(List <OfcNumber> values)
        {
            if (values.Count == 0)
            {
                throw new InvalidOperationException("Cannot gather compression metadata with 0 values!");
            }
            var metadata = new BlockyMetadata()
            {
                IsNegative = values.First().IsNegative, IsAbsolute = true, ValueCount = values.Count
            };

            foreach (var ofcNumber in values)
            {
                if (ofcNumber.NeededBitsNumber > metadata.MaxNeededBitsNumber)
                {
                    metadata.MaxNeededBitsNumber  = ofcNumber.NeededBitsNumber;
                    metadata.LargestPossibleValue = Utility.GetMaxValue(ofcNumber.NeededBitsNumber);
                }
                if (ofcNumber.NeededBitsExponent > metadata.MaxNeededBitsExponent)
                {
                    metadata.MaxNeededBitsExponent = ofcNumber.NeededBitsExponent;                                                                //Todo: this is redundant af, we should be able to calculate it from the huffman creator
                }
                if (metadata.IsAbsolute && ofcNumber.IsNegative != metadata.IsNegative)
                {
                    metadata.IsAbsolute = false;
                }
                if (metadata.NoExponent && ofcNumber.Exponent != 0)
                {
                    metadata.NoExponent = false;
                }
            }
            return(metadata);
        }
示例#2
0
        protected BlockyDecompression([NotNull] Stream reader)
        {
            _bitReader = new StreamBitReader(reader);
            Metadata   = BlockyMetadata.FromBitStream(_bitReader);

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

            if (_bitReader.ReadByte(1) > 0) // use huffman
            {
                throw new NotImplementedException();
            }
        }
示例#3
0
        /// <summary>
        /// Will calculate everything and make it ready for writing
        /// </summary>
        public void Finish()
        {
            if (Values.Count == 0)
            {
                return;
            }

            Metadata = BlockyMetadata.FromData(Values);
            Metadata.MaxNeededBitsNeededBitsNumber = Utility.GetNeededBits(Metadata.MaxNeededBitsNumber);

            _blockfinding = new Blockfinding.Blockfinding(Values, Metadata);
            Blocks        = _blockfinding.FindAllBlocks();

            PostCompressionOptimisation();     //Todo: make optional

            Write();
        }
示例#4
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);
        }
示例#5
0
 /// <remarks>This will set OverrideGlobalNb but not the NeededBits</remarks>
 /// <param name="metadata"></param>
 /// <param name="newNb"></param>
 /// <returns>The bit difference that would occur when changing the NeededBits in the header to newNb</returns>
 public int DifferenceWithNb(BlockyMetadata metadata, ref byte newNb)                              //Bug: wrong calculatons if nb > maxNb ?
 {
     if (metadata.MaxNeededBitsNeededBitsNumber < (metadata.MaxNeededBitsNumber - newNb) * Length) // If the space we'd save in the header by not overriding the nb is smaller than the space we'd save at the values because of the overriden nb # TL;DR: If it's worth to override the nb in the header
     {
         if (!OverrideGlobalNb)
         {
             OverrideGlobalNb = true;
             return((NeededBits - newNb) * Length - metadata.MaxNeededBitsNeededBitsNumber); // The bits we'll save with the header change - the bits we'll waste by overriding the nb in the header (adds some overhead ...)
         }
     }
     else if (OverrideGlobalNb) // If the nb are overriden but it's not worth to override them (which is why we got to 'else' ...)
     {
         OverrideGlobalNb = false;
         newNb            = metadata.MaxNeededBitsNumber;                                // Bug: moved this from the if above. Not sure if i have missed something or fixed a bug :S
         return((NeededBits - newNb) * Length + metadata.MaxNeededBitsNeededBitsNumber); // The bits we'll save with the header change + the bits we'll save by not overriding the nb in the header (removes some overhead ...)
     }
     return((NeededBits - newNb) * Length);                                              // the bits we'll save if the nb were already overriden and have changed value
 }
示例#6
0
 public bool ShouldOverrideNb(BlockyMetadata metadata)
 {
     return(metadata.MaxNeededBitsNeededBitsNumber < (metadata.MaxNeededBitsNumber - NeededBits) * Length && !HasPattern);
 }