示例#1
0
        /// <summary>
        /// Private helper used to read an int, short or byte (in reverse order) from the reader
        /// and return an int
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private int GetDataFromReader(BitStreamReader reader, GorillaEncodingType type)
        {
            switch (type)
            {
            case GorillaEncodingType.Int:
            {
                return((int)reader.ReadUInt32Reverse(Native.BitsPerInt));
            }

            case GorillaEncodingType.Short:
            {
                return((int)reader.ReadUInt16Reverse(Native.BitsPerShort));
            }

            case GorillaEncodingType.Byte:
            {
                return((int)reader.ReadByte(Native.BitsPerByte));
            }

            default:
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to GetDataFromReader"));
            }
            }
        }
示例#2
0
        /// <summary>
        /// Compress - compresses the byte[] being read by the BitStreamReader into compressed data
        /// </summary>
        /// <param name="bitCount">the number of bits to use for each element</param>
        /// <param name="reader">a reader over the byte[] to compress</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToEncode">number of logical units to encoded</param>
        /// <param name="compressedData">output write buffer</param>
        internal void Compress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToEncode, List <byte> compressedData)
        {
            if (null == reader || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("reader or compressedData was null in compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToEncode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToEncode");
            }

            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                switch (encodingType)
                {
                case GorillaEncodingType.Int:
                {
                    bitCount = Native.BitsPerInt;
                    break;
                }

                case GorillaEncodingType.Short:
                {
                    bitCount = Native.BitsPerShort;
                    break;
                }

                case GorillaEncodingType.Byte:
                {
                    bitCount = Native.BitsPerByte;
                    break;
                }

                default:
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to compress"));
                }
                }
            }

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);

            while (!reader.EndOfStream && unitsToEncode > 0)
            {
                int data = GetDataFromReader(reader, encodingType);
                writer.Write((uint)data, bitCount);
                unitsToEncode--;
            }
        }
示例#3
0
        /// <summary>
        /// Compresses property data which is already in the form of a byte[]
        /// into a compressed byte[]
        /// </summary>
        /// <param name="input">byte[] data ready to be compressed</param>
        /// <param name="compression">the compression to use</param>
        /// <returns></returns>
        internal byte[] CompressPropertyData(byte[] input, byte compression)
        {
            List <byte> compressedData = new List <byte>(input.Length + 1); //reasonable default based on profiling.

            //leave room at the beginning of
            //compressedData for the compression header byte
            compressedData.Add((byte)0);

            if (DefaultCompression == (DefaultCompression & compression))
            {
                compression = this.GorillaCodec.FindPropAlgoByte(input);
            }

            //validate that we never lzencode
            if (LempelZiv == (compression & LempelZiv))
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid compression specified or computed by FindPropAlgoByte"));
            }

            //determine what the optimal way to compress the data is.  Should we treat
            //the byte[] as a series of Int's, Short's or Byte's?
            int countPerItem = 0, bitCount = 0, padCount = 0;

            this.GorillaCodec.GetPropertyBitCount(compression, ref countPerItem, ref bitCount, ref padCount);

            Debug.Assert(countPerItem == 4 || countPerItem == 2 || countPerItem == 1);

            GorillaEncodingType type = GorillaEncodingType.Byte;
            int unitCount            = input.Length;

            if (countPerItem == 4)
            {
                type        = GorillaEncodingType.Int;
                unitCount >>= 2;
            }
            else if (countPerItem == 2)
            {
                type        = GorillaEncodingType.Short;
                unitCount >>= 1;
            }


            BitStreamReader reader = new BitStreamReader(input);

            //encode, gorilla style
            this.GorillaCodec.Compress(bitCount,            //the max count of bits required for each int
                                       reader,              //the reader, which can read int, byte, short
                                       type,                //informs how the reader reads
                                       unitCount,           //just how many items do we need to compress?
                                       compressedData);     //a ref to the compressed data that will be written to

            compressedData[0] = compression;
            return(compressedData.ToArray());
        }
示例#4
0
        /// <summary>
        /// Decompresses property data (from a compressed byte[] to an uncompressed byte[])
        /// </summary>
        /// <param name="input">The byte[] to decompress</param>
        /// <returns></returns>
        internal byte[] DecompressPropertyData(byte[] input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (input.Length < 2)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("input.Length must be at least 2"));
            }

            byte compression = input[0];
            int  inputIndex  = 1;

            if (LempelZiv == (compression & LempelZiv))
            {
                if (0 != (compression & (~LempelZiv)))
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus isf, we don't decompress property data with lz"));
                }
                return(this.LZCodec.Uncompress(input, inputIndex));
            }
            else
            {
                //gorilla

                //determine what the way to uncompress the data.  Should we treat
                //the byte[] as a series of Int's, Short's or Byte's?
                int countPerItem = 0, bitCount = 0, padCount = 0;
                this.GorillaCodec.GetPropertyBitCount(compression, ref countPerItem, ref bitCount, ref padCount);
                Debug.Assert(countPerItem == 4 || countPerItem == 2 || countPerItem == 1);

                GorillaEncodingType type = GorillaEncodingType.Byte;
                if (countPerItem == 4)
                {
                    type = GorillaEncodingType.Int;
                }
                else if (countPerItem == 2)
                {
                    type = GorillaEncodingType.Short;
                }

                //determine how many units (of int, short or byte) that there are to decompress
                int             unitsToDecode = ((input.Length - inputIndex << 3) / bitCount) - padCount;
                BitStreamReader reader        = new BitStreamReader(input, inputIndex);
                return(this.GorillaCodec.Uncompress(bitCount, reader, type, unitsToDecode));
            }
        }
        /// <summary>
        /// Uncompress - uncompress the byte[] in the reader to a byte[] to return
        /// </summary>
        /// <param name="bitCount">number of bits each element is compressed to</param>
        /// <param name="reader">a reader over the compressed byte[]</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToDecode">number of logical units to decode</param>
        /// <returns>Uncompressed byte[]</returns>
        internal byte[] Uncompress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToDecode)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToDecode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToDecode");
            }

            int bitsToWrite = 0;

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint bitMask = 0;
            //adjust if the bitcount is 0
            //(this makes bitCount 32)
            switch (encodingType)
            {
                case GorillaEncodingType.Int:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerInt;
                        }
                        bitsToWrite = Native.BitsPerInt;
                        //we decode int's as unsigned, so we need to create a mask
                        bitMask = (unchecked((uint)~0) << (bitCount - 1));
                        break;
                    }
                case GorillaEncodingType.Short:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerShort;
                        }
                        bitsToWrite = Native.BitsPerShort;
                        //shorts are decoded as unsigned values, no mask required
                        bitMask = 0;
                        break;
                    }
                case GorillaEncodingType.Byte:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerByte;
                        }
                        bitsToWrite = Native.BitsPerByte;
                        //bytes are decoded as unsigned values, no mask required
                        bitMask = 0;
                        break;
                    }
                default:
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to Uncompress"));
                    }
            }
            List<byte> output = new List<byte>((bitsToWrite / 8) * unitsToDecode);
            BitStreamWriter writer = new BitStreamWriter(output);
            uint bitData = 0;

            while (!reader.EndOfStream && unitsToDecode > 0)
            {
                //we're going to cast to an uint anyway, just read as one
                bitData = reader.ReadUInt32(bitCount);
                // Construct the item
                bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                writer.WriteReverse(bitData, bitsToWrite);
                unitsToDecode--;
            }

            return output.ToArray();
        }
 /// <summary>
 /// Private helper used to read an int, short or byte (in reverse order) from the reader
 /// and return an int
 /// </summary>
 /// <param name="reader"></param>
 /// <param name="type"></param>
 /// <returns></returns>
 private int GetDataFromReader(BitStreamReader reader, GorillaEncodingType type)
 {
     switch (type)
     {
         case GorillaEncodingType.Int:
             {
                 return (int)reader.ReadUInt32Reverse(Native.BitsPerInt);
             }
         case GorillaEncodingType.Short:
             {
                 return (int)reader.ReadUInt16Reverse(Native.BitsPerShort);
             }
         case GorillaEncodingType.Byte:
             {
                 return (int)reader.ReadByte(Native.BitsPerByte);
             }
         default:
             {
                 throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to GetDataFromReader"));
             }
     }
 }
        /// <summary>
        /// Compress - compresses the byte[] being read by the BitStreamReader into compressed data
        /// </summary>
        /// <param name="bitCount">the number of bits to use for each element</param>
        /// <param name="reader">a reader over the byte[] to compress</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToEncode">number of logical units to encoded</param>
        /// <param name="compressedData">output write buffer</param>
        internal void Compress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToEncode, List<byte> compressedData)
        {
            if (null == reader || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("reader or compressedData was null in compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToEncode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToEncode");
            }

            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                switch (encodingType)
                {
                    case GorillaEncodingType.Int:
                        {
                            bitCount = Native.BitsPerInt;
                            break;
                        }
                    case GorillaEncodingType.Short:
                        {
                            bitCount = Native.BitsPerShort;
                            break;
                        }
                    case GorillaEncodingType.Byte:
                        {
                            bitCount = Native.BitsPerByte;
                            break;
                        }
                    default:
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to compress"));
                        }
                }
            }

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);
            while (!reader.EndOfStream && unitsToEncode > 0)
            {
                int data = GetDataFromReader(reader, encodingType);
                writer.Write((uint)data, bitCount);
                unitsToEncode--;
            }
        }
示例#8
0
        /// <summary>
        /// Uncompress - uncompress the byte[] in the reader to a byte[] to return
        /// </summary>
        /// <param name="bitCount">number of bits each element is compressed to</param>
        /// <param name="reader">a reader over the compressed byte[]</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToDecode">number of logical units to decode</param>
        /// <returns>Uncompressed byte[]</returns>
        internal byte[] Uncompress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToDecode)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToDecode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToDecode");
            }

            int bitsToWrite = 0;

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint bitMask = 0;

            //adjust if the bitcount is 0
            //(this makes bitCount 32)
            switch (encodingType)
            {
            case GorillaEncodingType.Int:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerInt;
                }
                bitsToWrite = Native.BitsPerInt;
                //we decode int's as unsigned, so we need to create a mask
                bitMask = (unchecked ((uint)~0) << (bitCount - 1));
                break;
            }

            case GorillaEncodingType.Short:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerShort;
                }
                bitsToWrite = Native.BitsPerShort;
                //shorts are decoded as unsigned values, no mask required
                bitMask = 0;
                break;
            }

            case GorillaEncodingType.Byte:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerByte;
                }
                bitsToWrite = Native.BitsPerByte;
                //bytes are decoded as unsigned values, no mask required
                bitMask = 0;
                break;
            }

            default:
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to Uncompress"));
            }
            }
            List <byte>     output  = new List <byte>((bitsToWrite / 8) * unitsToDecode);
            BitStreamWriter writer  = new BitStreamWriter(output);
            uint            bitData = 0;

            while (!reader.EndOfStream && unitsToDecode > 0)
            {
                //we're going to cast to an uint anyway, just read as one
                bitData = reader.ReadUInt32(bitCount);
                // Construct the item
                bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                writer.WriteReverse(bitData, bitsToWrite);
                unitsToDecode--;
            }

            return(output.ToArray());
        }