Example #1
0
        /// <summary>
        ///
        /// </summary>
        public static void DecompressBuffer(this BinaryReader binaryReader, Stream outstream, uint zSize, uint size)
        {
            if (zSize == size)
            {
                try
                {
                    var buffer = binaryReader.ReadBytes((int)zSize);
                    outstream.Write(buffer);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            }
            else
            {
                var pos = binaryReader.BaseStream.Position;
                var oodleCompression = binaryReader.ReadBytes(4);
                if ((oodleCompression.SequenceEqual(new byte[] { 0x4b, 0x41, 0x52, 0x4b })))
                {
                    var headerSize = binaryReader.ReadUInt32();

                    if (headerSize != size)
                    {
                        throw new Exception($"Buffer size doesn't match size in info table. {headerSize} vs {size}");
                    }

                    var inputBuffer = binaryReader.ReadBytes((int)zSize - 8);

                    try
                    {
                        var  outputBuffer = new byte[size];
                        long unpackedSize = OodleHelper.Decompress(inputBuffer, outputBuffer);

                        if (unpackedSize != size)
                        {
                            throw new DecompressionException(
                                      $"Unpacked size {unpackedSize} doesn't match real size {size}");
                        }
                        outstream.Write(outputBuffer);
                    }
                    catch (DecompressionException)
                    {
                        //logger.LogString(e.Message, Logtype.Error);
                        //logger.LogString(
                        //    $"Unable to decompress file {hash.ToString()}. Exporting uncompressed file",
                        //    Logtype.Error);
                        outstream.Write(inputBuffer);
                    }
                }
                else
                {
                    binaryReader.BaseStream.Seek(pos, SeekOrigin.Begin);
                    var buffer = binaryReader.ReadBytes((int)zSize);
                    outstream.Write(buffer);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Decompresses and copies a segment of zsize bytes from a stream to another stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="outStream"></param>
        /// <param name="zSize"></param>
        /// <param name="size"></param>
        /// <exception cref="Exception"></exception>
        /// <exception cref="DecompressionException"></exception>
        public static void DecompressAndCopySegment(this Stream stream, Stream outStream, uint zSize, uint size)
        {
            if (zSize == size)
            {
                stream.CopyToWithLength(outStream, (int)zSize);
            }
            else
            {
                var oodleCompression = stream.ReadStruct <uint>();
                if (oodleCompression == KARK)
                {
                    var headerSize = stream.ReadStruct <uint>();
                    if (headerSize != size)
                    {
                        throw new Exception($"Buffer size doesn't match size in info table. {headerSize} vs {size}");
                    }

                    var inputBuffer = new byte[(int)zSize - 8];
                    stream.Read(inputBuffer);
                    var outputBuffer = new byte[size];

                    long unpackedSize = OodleHelper.Decompress(inputBuffer, outputBuffer);

                    if (unpackedSize != size)
                    {
                        throw new DecompressionException(
                                  $"Unpacked size {unpackedSize} doesn't match real size {size}.");
                    }

                    outStream.Write(outputBuffer);

                    // try
                    // {
                    //
                    // }
                    // catch (DecompressionException)
                    // {
                    //     //logger.LogString(e.Message, Logtype.Error);
                    //     //logger.LogString(
                    //     //    $"Unable to decompress file {hash.ToString()}. Exporting uncompressed file",
                    //     //    Logtype.Error);
                    //     stream.CopyTo(outStream);
                    // }
                }
                else
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.CopyToWithLength(outStream, (int)zSize);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Decompresses and copies a segment of zsize bytes from a stream to another stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="outStream"></param>
        /// <param name="zSize"></param>
        /// <param name="size"></param>
        /// <exception cref="Exception"></exception>
        /// <exception cref="DecompressionException"></exception>
        public static void DecompressAndCopySegment(this Stream stream, Stream outStream, uint zSize, uint size)
        {
            if (zSize == size)
            {
                stream.CopyToWithLength(outStream, (int)zSize);
            }
            else
            {
                var oodleCompression = stream.ReadStruct <uint>();
                if (oodleCompression == KARK)
                {
                    var headerSize = stream.ReadStruct <uint>();
                    if (headerSize != size)
                    {
                        throw new DecompressionException($"Buffer size doesn't match size in info table. {headerSize} vs {size}");
                    }

                    const int SPAN_LEN = 5333;//32768;
                    var       length   = (int)zSize - 8;

                    var inputBufferSpan = length <= SPAN_LEN
                        ? stackalloc byte[length]
                        : new byte[length];
                    var outputBufferSpan = size <= SPAN_LEN ? stackalloc byte[(int)size] : new byte[size];

                    stream.Read(inputBufferSpan);

                    long unpackedSize = OodleHelper.Decompress(inputBufferSpan, outputBufferSpan);
                    if (unpackedSize != size)
                    {
                        throw new DecompressionException(
                                  $"Unpacked size {unpackedSize} doesn't match real size {size}.");
                    }

                    outStream.Write(outputBufferSpan);
                }
                else
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.CopyToWithLength(outStream, (int)zSize);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Decompresses and copies a segment of zsize bytes from a stream to another stream
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="outStream"></param>
        /// <param name="zSize"></param>
        /// <param name="size"></param>
        /// <exception cref="Exception"></exception>
        /// <exception cref="DecompressionException"></exception>
        public static async Task DecompressAndCopySegmentAsync(this Stream stream, Stream outStream, uint zSize, uint size)
        {
            if (zSize == size)
            {
                stream.CopyToWithLength(outStream, (int)zSize);
            }
            else
            {
                var oodleCompression = stream.ReadStruct <uint>();
                if (oodleCompression == KARK)
                {
                    var headerSize = stream.ReadStruct <uint>();
                    if (headerSize != size)
                    {
                        throw new Exception($"Buffer size doesn't match size in info table. {headerSize} vs {size}");
                    }

                    var inputBuffer = new byte[(int)zSize - 8];

                    stream.Read(inputBuffer);
                    var outputBuffer = new byte[size];

                    long unpackedSize = await Task.Run(() => OodleHelper.Decompress(inputBuffer, outputBuffer));

                    if (unpackedSize != size)
                    {
                        throw new DecompressionException(
                                  $"Unpacked size {unpackedSize} doesn't match real size {size}.");
                    }

                    outStream.Write(outputBuffer);
                }
                else
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.CopyToWithLength(outStream, (int)zSize);
                }
            }
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="inputBytes"></param>
        /// <param name="inputOffset"></param>
        /// <param name="inputCount"></param>
        /// <param name="outputBytes"></param>
        /// <param name="outputOffset"></param>
        /// <param name="outputCount"></param>
        /// <param name="algo"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="NotImplementedException"></exception>
        public static int Compress(
            byte[] inputBytes,
            // int inputOffset,
            int inputCount,
            ref IEnumerable <byte> outputBuffer,
            // int outputOffset,
            // int outputCount,
            OodleNative.OodleLZ_Compressor algo   = OodleNative.OodleLZ_Compressor.Kraken,
            OodleNative.OodleLZ_Compression level = OodleNative.OodleLZ_Compression.Normal)
        {
            if (inputBytes == null)
            {
                throw new ArgumentNullException(nameof(inputBytes));
            }
            if (inputCount <= 0 || inputCount > inputBytes.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(inputCount));
            }
            if (outputBuffer == null)
            {
                throw new ArgumentNullException(nameof(outputBuffer));
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var compressedBufferSizeNeeded = OodleHelper.GetCompressedBufferSizeNeeded((int)inputCount);
                var compressedBuffer           = new byte[compressedBufferSizeNeeded];

                var inputHandle   = GCHandle.Alloc(inputBytes, GCHandleType.Pinned);
                var inputAddress  = inputHandle.AddrOfPinnedObject();
                var outputHandle  = GCHandle.Alloc(compressedBuffer, GCHandleType.Pinned);
                var outputAddress = outputHandle.AddrOfPinnedObject();

                var result = (int)OodleNative.Compress(
                    (int)algo,
                    inputAddress,
                    inputCount,
                    outputAddress,
                    (int)level,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    (long)0
                    );

                inputHandle.Free();
                outputHandle.Free();

                //resize buffer
                var writelist = new List <byte>()
                {
                    0x4B, 0x41, 0x52, 0x4B  //KARK, TODO: make this dependent on the compression algo
                };
                writelist.AddRange(BitConverter.GetBytes(inputCount));
                writelist.AddRange(compressedBuffer.Take(result));

                outputBuffer = writelist;

                return(outputBuffer.Count());
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                //TODO: use ooz to compress
                outputBuffer = inputBytes;
                return(outputBuffer.Count());


                // try
                // {
                //     var result = OozNative.Compress(
                //         (int)algo,
                //         inputAddress,
                //         outputAddress,
                //         inputCount,
                //         IntPtr.Zero,
                //         IntPtr.Zero
                //     );
                //     inputHandle.Free();
                //     outputHandle.Free();
                //     return result;
                // }
                // catch (Exception e)
                // {
                //     Console.WriteLine(e);
                //     throw;
                // }
            }
            else
            {
                throw new NotImplementedException();
            }
        }