Example #1
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"));
            }
            }
        }
        /// <summary>
        /// Uncompress - uncompress a byte[] into an int[] of point data (x,x,x,x,x)
        /// </summary>
        /// <param name="bitCount">The number of bits each element uses in input</param>
        /// <param name="input">compressed data</param>
        /// <param name="inputIndex">index to begin decoding at</param>
        /// <param name="dtxf">data xf, can be null</param>
        /// <param name="outputBuffer">output buffer that is prealloc'd to write to</param>
        /// <param name="outputBufferIndex">the index of the output buffer to write to</param>
        internal uint Uncompress(int bitCount, byte[] input, int inputIndex, DeltaDelta dtxf, int[] outputBuffer, int outputBufferIndex)
        {
            if (null == input)
            {
                throw new ArgumentNullException("input");
            }
            if (inputIndex >= input.Length)
            {
                throw new ArgumentOutOfRangeException("inputIndex");
            }
            if (null == outputBuffer)
            {
                throw new ArgumentNullException("outputBuffer");
            }
            if (outputBufferIndex >= outputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException("outputBufferIndex");
            }

            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

            // Adjust bit count if 0 passed in
            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                bitCount = (int)(Native.SizeOfInt << 3);
            }

            // 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 = (unchecked((uint)~0) << (bitCount - 1));
            uint bitData = 0;
            BitStreamReader reader = new BitStreamReader(input, inputIndex);

            if(dtxf != null)
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    int result = dtxf.InverseTransform((int)bitData, 0);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = (int)bitData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }

            // Calculate how many bytes were read from input buffer
            return (uint)((outputBuffer.Length * bitCount + 7) >> 3);
        }
Example #3
0
        /// <summary>
        /// Uncompress - uncompress a byte[] into an int[] of point data (x,x,x,x,x)
        /// </summary>
        /// <param name="bitCount">The number of bits each element uses in input</param>
        /// <param name="input">compressed data</param>
        /// <param name="inputIndex">index to begin decoding at</param>
        /// <param name="dtxf">data xf, can be null</param>
        /// <param name="outputBuffer">output buffer that is prealloc'd to write to</param>
        /// <param name="outputBufferIndex">the index of the output buffer to write to</param>
        internal uint Uncompress(int bitCount, byte[] input, int inputIndex, DeltaDelta dtxf, int[] outputBuffer, int outputBufferIndex)
        {
            if (null == input)
            {
                throw new ArgumentNullException("input");
            }
            if (inputIndex >= input.Length)
            {
                throw new ArgumentOutOfRangeException("inputIndex");
            }
            if (null == outputBuffer)
            {
                throw new ArgumentNullException("outputBuffer");
            }
            if (outputBufferIndex >= outputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException("outputBufferIndex");
            }

            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

            // Adjust bit count if 0 passed in
            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                bitCount = (int)(Native.SizeOfInt << 3);
            }

            // 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 = (unchecked ((uint)~0) << (bitCount - 1));
            uint            bitData = 0;
            BitStreamReader reader  = new BitStreamReader(input, inputIndex);

            if (dtxf != null)
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    int result = dtxf.InverseTransform((int)bitData, 0);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = (int)bitData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }

            // Calculate how many bytes were read from input buffer
            return((uint)((outputBuffer.Length * bitCount + 7) >> 3));
        }