/// <summary> /// GetDefCodec /// </summary> internal HuffCodec GetDefCodec(uint index) { HuffCodec huffCodec = null; if (AlgoModule.DefaultBAACount > index) { huffCodec = _defaultHuffCodecs[index]; if (huffCodec == null) { huffCodec = new HuffCodec(index); _defaultHuffCodecs[index] = huffCodec; } } else { throw new ArgumentOutOfRangeException("index"); } return huffCodec; }
/// <summary> /// GetDefCodec /// </summary> internal HuffCodec GetDefCodec(uint index) { HuffCodec huffCodec = null; if (AlgoModule.DefaultBAACount > index) { huffCodec = _defaultHuffCodecs[index]; if (huffCodec == null) { huffCodec = new HuffCodec(index); _defaultHuffCodecs[index] = huffCodec; } } else { throw new ArgumentOutOfRangeException("index"); } return(huffCodec); }
/// <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()); }
/// <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")); } } }