// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : LZMA.cs // Author(s) : Natalia Portillo // // Component : Compression algorithms. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2022 Natalia Portillo // ****************************************************************************/ using System.IO; using System.Runtime.InteropServices; using Aaru.Helpers; using SharpCompress.Compressors.LZMA; namespace Aaru.Compression; /// Implements the LZMA compression algorithm public class LZMA { /// Set to true if this algorithm is supported, false otherwise. public static bool IsSupported => true; [DllImport("libAaru.Compression.Native", SetLastError = true)] static extern int AARU_lzma_decode_buffer(byte[] dstBuffer, ref nuint dstSize, byte[] srcBuffer, ref nuint srcSize, byte[] props, nuint propsSize); [DllImport("libAaru.Compression.Native", SetLastError = true)] static extern int AARU_lzma_encode_buffer(byte[] dstBuffer, ref nuint dstSize, byte[] srcBuffer, nuint srcSize, byte[] outProps, ref nuint outPropsSize, int level, uint dictSize, int lc, int lp, int pb, int fb, int numThreads); /// Decodes a buffer compressed with LZMA /// Encoded buffer /// Buffer where to write the decoded data /// LZMA stream properties /// The number of decoded bytes public static int DecodeBuffer(byte[] source, byte[] destination, byte[] properties) { if(Native.IsSupported) { nuint srcSize = (nuint)source.Length; nuint dstSize = (nuint)destination.Length; AARU_lzma_decode_buffer(destination, ref dstSize, source, ref srcSize, properties, (nuint)properties.Length); return (int)dstSize; } using var cmpMs = new MemoryStream(source); using var lzmaBlock = new LzmaStream(properties, cmpMs); lzmaBlock.EnsureRead(destination, 0, destination.Length); return destination.Length; } /// Compresses a buffer using BZIP2 /// Data to compress /// Buffer to store the compressed data /// LZMA stream properties /// Compression level /// Dictionary size /// Literal context bits /// Literal position bits /// Position bits /// Forward bits /// How many bytes have been written to the destination buffer public static int EncodeBuffer(byte[] source, byte[] destination, out byte[] properties, int level, uint dictSize, int lc, int lp, int pb, int fb) { if(Native.IsSupported) { properties = new byte[5]; nuint dstSize = (nuint)destination.Length; nuint propsSize = (nuint)properties.Length; nuint srcSize = (nuint)source.Length; AARU_lzma_encode_buffer(destination, ref dstSize, source, srcSize, properties, ref propsSize, level, dictSize, lc, lp, pb, fb, 0); return (int)dstSize; } var lzmaEncoderProperties = new LzmaEncoderProperties(true, (int)dictSize, fb); using var lzmaStream = new LzmaStream(lzmaEncoderProperties, false, new MemoryStream(destination)); lzmaStream.Write(source, 0, source.Length); properties = new byte[lzmaStream.Properties.Length]; lzmaStream.Properties.CopyTo(properties, 0); return destination.Length; } }