/// <summary> /// This method returns an uncompressed version of the given compressed byte array /// </summary> /// <param name="inputBlob">the byte array to be decompressed</param> /// <param name="decompressedLength">the known length of the decompressed byte array</param> /// <param name="compressionCode">a generation number that indicates what compression technique to use</param> /// <returns>the decompressed byte array</returns> public static unsafe Byte[] DecompressBlob(Byte[] inputBlob, int decompressedLength, int compressionCode) { if (compressionCode == 1) { // the byte array of the output blob Byte[] decompressedBlob = new Byte[decompressedLength]; // Decompress using LZFX algorithm. // This method will throw an exception if the decompressed data does not // exactly fit into the allocated array size. LZFX.Decompress(inputBlob, decompressedBlob); return(decompressedBlob); } if (compressionCode == 2) { // the byte array of the output blob Byte[] decompressedBlob = new Byte[decompressedLength]; // Decompress using LZFX algorithm. // This method will throw an exception if the decompressed data does not // exactly fit into the allocated array size. LZ4.Decompress(inputBlob, decompressedBlob); return(decompressedBlob); } else { // return without doing any compression return(inputBlob); } }
/// <summary> /// This method computes the checksum for an individual trace of a time series, where the time /// series is understood to be an ensemble of one or more traces. The checksum of a trace is /// computed from the trace number and from the BLOB that contains the values for each time /// step of the time series. /// </summary> /// <param name="traceNumber">the number for identifying the trace</param> /// <param name="valueBlob">the BLOB that contains the values for each time step</param> /// <returns>the Checksum as a byte[16] array</returns> public static byte[] ComputeTraceChecksum(int traceNumber, byte[] valueBlob) { byte[] binArray = new byte[sizeof(Int32) + valueBlob.Length]; using (MemoryStream binStream = new MemoryStream(binArray)) using (BinaryWriter binWriter = new BinaryWriter(binStream)) { binWriter.Write(traceNumber); binWriter.Write(valueBlob); // Use of BlockCopy follows the example at https://stackoverflow.com/a/5896716/2998072. // 'longArray' pads the end with zeros and thereby create a 16-byte array in order // to avoid upsetting code that was established when this checksum was based // on 16-byte MurmurHash. ulong[] longArray = new ulong[] { LZ4.GetXXHash64(binArray), 0 }; // Convert the longArray into a Byte array Byte[] result = new Byte[16]; Buffer.BlockCopy(longArray, 0, result, 0, 16); return(result); } }
/// <summary> /// This returns a compressed version of the given byte array /// </summary> /// <param name="uncompressedBlob">the uncompressed byte array</param> /// <param name="compressionCode">a generation number that indicates what compression technique to use</param> /// <returns>the compressed byte array</returns> public static unsafe Byte[] CompressBlob(Byte[] uncompressedBlob, int compressionCode) { if (compressionCode == 1) { Byte[] compressedBlob; // the byte-array length of the input blob int inputLength = uncompressedBlob.Length; // The byte array that will be created by the compression. // Note that some incompressible BLOBs will actually be made larger by LZFX // compression. We have observed about 1% increase over the original BLOB, // so the factor of 1.05 is expected to be safe. We add 16 since the factor // of 1.05 is insufficient when the BLOB is very small. compressedBlob = new Byte[(int)(inputLength * 1.05) + 16]; // Compress using LZFX algorithm. // This method resizes the compressed byte array for us. LZFX.Compress(uncompressedBlob, ref compressedBlob); return(compressedBlob); } if (compressionCode == 2) { Byte[] compressedBlob; // the byte-array length of the input blob int inputLength = uncompressedBlob.Length; // The byte array that will be created by the compression. // Note that some incompressible BLOBs might actually be made larger by LZ4 // compression. The GetMaxSize method calls a function built into LZ4 which // returns the maximum possible size of the output array. LZ4 documentation suggests // that speed is optimized by allocating this max size. compressedBlob = new Byte[(int)LZ4.GetMaxSize(inputLength)]; // Compress using LZ4 algorithm. // This method resizes the compressed byte array for us. LZ4.Compress(uncompressedBlob, ref compressedBlob, 4); return(compressedBlob); } else { // return without doing any compression return(uncompressedBlob); } }