Пример #1
0
 /// <summary>
 /// Compress
 /// </summary>
 /// <param name="dataXf">can be null</param>
 /// <param name="input">input array to compress</param>
 /// <param name="compressedData"></param>
 internal void Compress(DataXform dataXf, int[] input, List<byte> compressedData)
 {
     //
     // use the writer to write to the list<byte>
     //
     BitStreamWriter writer = new BitStreamWriter(compressedData);
     if (null != dataXf)
     {
         dataXf.ResetState();
         int xfData = 0;
         int xfExtra = 0;
         for (uint i = 0; i < input.Length; i++)
         {
             dataXf.Transform(input[i], ref xfData, ref xfExtra);
             Encode(xfData, xfExtra, writer);
         }
     }
     else
     {
         for (uint i = 0; i < input.Length; i++)
         {
             Encode(input[i], 0, writer);
         }
     }
 }
Пример #2
0
        /// <summary>
        /// Compress
        /// </summary>
        /// <param name="dataXf">can be null</param>
        /// <param name="input">input array to compress</param>
        /// <param name="compressedData"></param>
        internal void Compress(DataXform dataXf, int[] input, List <byte> compressedData)
        {
            //
            // use the writer to write to the list<byte>
            //
            BitStreamWriter writer = new BitStreamWriter(compressedData);

            if (null != dataXf)
            {
                dataXf.ResetState();
                int xfData  = 0;
                int xfExtra = 0;
                for (uint i = 0; i < input.Length; i++)
                {
                    dataXf.Transform(input[i], ref xfData, ref xfExtra);
                    Encode(xfData, xfExtra, writer);
                }
            }
            else
            {
                for (uint i = 0; i < input.Length; i++)
                {
                    Encode(input[i], 0, writer);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Uncompress
        /// </summary>
        /// <param name="dtxf"></param>
        /// <param name="input"></param>
        /// <param name="startIndex"></param>
        /// <param name="outputBuffer"></param>
        internal uint Uncompress(DataXform dtxf, byte[] input, int startIndex, int[] outputBuffer)
        {
            Debug.Assert(input != null);
            Debug.Assert(input.Length >= 2);
            Debug.Assert(startIndex == 1);
            Debug.Assert(outputBuffer != null);
            Debug.Assert(outputBuffer.Length != 0);

            BitStreamReader reader = new BitStreamReader(input, startIndex);
            int             xfExtra = 0, xfData = 0;
            int             outputBufferIndex = 0;

            if (null != dtxf)
            {
                dtxf.ResetState();
                while (!reader.EndOfStream)
                {
                    Decode(ref xfData, ref xfExtra, reader);
                    int uncompressed = dtxf.InverseTransform(xfData, xfExtra);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = uncompressed;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    Decode(ref xfData, ref xfExtra, reader);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = xfData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            return((uint)((reader.CurrentIndex + 1) - startIndex)); //we include startIndex in the read count
        }
Пример #4
0
        /// <summary>
        /// Uncompress
        /// </summary>
        /// <param name="dtxf"></param>
        /// <param name="input"></param>
        /// <param name="startIndex"></param>
        /// <param name="outputBuffer"></param>
        internal uint Uncompress(DataXform dtxf, byte[] input, int startIndex, int[] outputBuffer)
        {
            Debug.Assert(input != null);
            Debug.Assert(input.Length >= 2);
            Debug.Assert(startIndex == 1);
            Debug.Assert(outputBuffer != null);
            Debug.Assert(outputBuffer.Length != 0);

            BitStreamReader reader = new BitStreamReader(input, startIndex);
            int xfExtra = 0, xfData = 0;
            int outputBufferIndex = 0;
            if (null != dtxf)
            {
                dtxf.ResetState();
                while (!reader.EndOfStream)
                {
                    Decode(ref xfData, ref xfExtra, reader);
                    int uncompressed = dtxf.InverseTransform(xfData, xfExtra);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = uncompressed;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    Decode(ref xfData, ref xfExtra, reader);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = xfData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            return (uint)((reader.CurrentIndex + 1) - startIndex); //we include startIndex in the read count
        }
Пример #5
0
        /// <summary>
        /// Compresses int[] packet data, returns it as a byte[]
        /// </summary>
        /// <param name="input">assumed to be point data (x,x,x,x,x,x,x)</param>
        /// <param name="compression">magic byte specifying the compression to use</param>
        /// <returns></returns>
        internal byte[] CompressPacketData(int[] input, byte compression)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            List <byte> compressedData = new List <byte>();

            //leave room at the beginning of
            //compressedData for the compression header byte
            //which we will add at the end
            compressedData.Add((byte)0);

            if (DefaultCompression == (DefaultCompression & compression))
            {
                compression = GetBestDefHuff(input);
            }
            if (IndexedHuffman == (DefaultCompression & compression))
            {
                DataXform dtxf      = this.HuffModule.FindDtXf(compression);
                HuffCodec huffCodec = this.HuffModule.FindCodec(compression);
                huffCodec.Compress(dtxf, input, compressedData);
                if (((compressedData.Count - 1 /*for the algo byte we just made room for*/) >> 2) > input.Length)
                {
                    //recompress with no compression (gorilla)
                    compression = NoCompression;
                    //reset
                    compressedData.Clear();
                    compressedData.Add((byte)0);
                }
            }
            if (NoCompression == (DefaultCompression & compression))
            {
                bool testDelDel = ((compression & 0x20) != 0);
                compression =
                    this.GorillaCodec.FindPacketAlgoByte(input, testDelDel);

                DeltaDelta dtxf = null;
                if ((compression & 0x20) != 0)
                {
                    dtxf = this.DeltaDelta;
                }

                int inputIndex = 0;
                if (null != dtxf)
                {
                    //multibyteencode the first two values
                    int xfData  = 0;
                    int xfExtra = 0;

                    dtxf.ResetState();
                    dtxf.Transform(input[0], ref xfData, ref xfExtra);
                    this.MultiByteCodec.SignEncode(xfData, compressedData);

                    dtxf.Transform(input[1], ref xfData, ref xfExtra);
                    this.MultiByteCodec.SignEncode(xfData, compressedData);

                    //advance to the third member, we've already read the first two
                    inputIndex = 2;
                }

                //Gorllia time
                int bitCount = (compression & 0x1F);
                this.GorillaCodec.Compress(bitCount,            //the max count of bits required for each int
                                           input,               //the input array to compress
                                           inputIndex,          //the index to start compressing at
                                           dtxf,                //data transform to use when compressing, can be null
                                           compressedData);     //a ref to the compressed data that will be written to
            }

            // compression / algo data always goes in index 0
            compressedData[0] = compression;
            return(compressedData.ToArray());
        }
Пример #6
0
        /// <summary>
        /// DecompressPacketData - given a compressed byte[], uncompress it to the outputBuffer
        /// </summary>
        /// <param name="input">compressed byte from the ISF stream</param>
        /// <param name="outputBuffer">prealloc'd buffer to write to</param>
        /// <returns></returns>
        internal uint DecompressPacketData(byte[] input, int[] outputBuffer)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (input.Length < 2)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Input buffer passed was shorter than expected"));
            }
            if (outputBuffer == null)
            {
                throw new ArgumentNullException("outputBuffer");
            }
            if (outputBuffer.Length == 0)
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("output buffer length was zero"));
            }

            byte compression    = input[0];
            uint totalBytesRead = 1; //we just read one
            int  inputIndex     = 1;

            switch (compression & 0xC0)
            {
            case 0x80:    //IndexedHuffman
            {
                DataXform dtxf      = this.HuffModule.FindDtXf(compression);
                HuffCodec huffCodec = this.HuffModule.FindCodec(compression);
                totalBytesRead += huffCodec.Uncompress(dtxf, input, inputIndex, outputBuffer);
                return(totalBytesRead);
            }

            case 0x00:     //NoCompression
            {
                int        outputBufferIndex = 0;
                DeltaDelta dtxf = null;
                if ((compression & 0x20) != 0)
                {
                    dtxf = this.DeltaDelta;
                }

                int bitCount = 0;
                if ((compression & 0x1F) == 0)
                {
                    bitCount = Native.BitsPerInt;        //32
                }
                else
                {
                    bitCount = (compression & 0x1F);
                }

                if (null != dtxf)
                {
                    //must have at least two more bytes besides the
                    //initial algo byte
                    if (input.Length < 3)
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Input buffer was too short (must be at least 3 bytes)"));
                    }

                    //multibyteencode the first two values
                    int xfData  = 0;
                    int xfExtra = 0;

                    dtxf.ResetState();

                    uint bytesRead =
                        this.MultiByteCodec.SignDecode(input, inputIndex, ref xfData);
                    //advance our index
                    inputIndex     += (int)bytesRead;
                    totalBytesRead += bytesRead;
                    int result = dtxf.InverseTransform(xfData, xfExtra);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;

                    bytesRead =
                        this.MultiByteCodec.SignDecode(input, inputIndex, ref xfData);
                    //advance our index
                    inputIndex     += (int)bytesRead;
                    totalBytesRead += bytesRead;
                    result          = dtxf.InverseTransform(xfData, xfExtra);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;
                }

                totalBytesRead +=
                    this.GorillaCodec.Uncompress(bitCount,              //the max count of bits required for each int
                                                 input,                 //the input array to uncompress
                                                 inputIndex,            //the index to start uncompressing at
                                                 dtxf,                  //data transform to use when compressing, can be null
                                                 outputBuffer,          //a ref to the output buffer to write to
                                                 outputBufferIndex);    //the index of the output buffer to write to

                return(totalBytesRead);
            }

            default:
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid decompression algo byte"));
            }
            }
        }