mirror of
https://github.com/SabreTools/SabreTools.Compression.git
synced 2026-02-04 05:36:03 +00:00
Fix MS-ZIP, working
This commit is contained in:
@@ -1649,13 +1649,21 @@ namespace SabreTools.Compression.Deflate
|
||||
}
|
||||
|
||||
|
||||
internal int SetDictionary(byte[] dictionary)
|
||||
internal int SetDictionary(byte[] dictionary, bool check = true)
|
||||
{
|
||||
int length = dictionary.Length;
|
||||
int index = 0;
|
||||
|
||||
if (dictionary == null || status != INIT_STATE)
|
||||
throw new ZlibException("Stream error.");
|
||||
if (check)
|
||||
{
|
||||
if (dictionary == null || status != INIT_STATE)
|
||||
throw new ZlibException("Stream error.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dictionary == null)
|
||||
throw new ZlibException("Stream error.");
|
||||
}
|
||||
|
||||
_codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length);
|
||||
|
||||
|
||||
@@ -620,10 +620,11 @@ namespace SabreTools.Compression.Deflate
|
||||
/// Set the dictionary to be used for either Inflation or Deflation.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The dictionary bytes to use.</param>
|
||||
/// <param name="check">Determines if dictionary checks are run</param>
|
||||
/// <returns>Z_OK if all goes well.</returns>
|
||||
public int SetDictionary(byte[] dictionary)
|
||||
public int SetDictionary(byte[] dictionary, bool check = true)
|
||||
{
|
||||
return _baseStream.SetDictionary(dictionary);
|
||||
return _baseStream.SetDictionary(dictionary, check);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -363,16 +363,20 @@ namespace SabreTools.Compression.Deflate
|
||||
|
||||
|
||||
|
||||
internal int SetDictionary(byte[] dictionary)
|
||||
internal int SetDictionary(byte[] dictionary, bool check = true)
|
||||
{
|
||||
int index = 0;
|
||||
int length = dictionary.Length;
|
||||
if (mode != InflateManagerMode.DICT0)
|
||||
throw new ZlibException("Stream error.");
|
||||
|
||||
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
|
||||
if (check)
|
||||
{
|
||||
return ZlibConstants.Z_DATA_ERROR;
|
||||
if (mode != InflateManagerMode.DICT0)
|
||||
throw new ZlibException("Stream error.");
|
||||
|
||||
if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32)
|
||||
{
|
||||
return ZlibConstants.Z_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
_codec._Adler32 = Adler.Adler32(0, null, 0, 0);
|
||||
|
||||
@@ -624,10 +624,11 @@ namespace SabreTools.Compression.Deflate
|
||||
/// Set the dictionary to be used for either Inflation or Deflation.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The dictionary bytes to use.</param>
|
||||
/// <param name="check">Determines if dictionary checks are run</param>
|
||||
/// <returns>Z_OK if all goes well.</returns>
|
||||
public int SetDictionary(byte[] dictionary)
|
||||
public int SetDictionary(byte[] dictionary, bool check = true)
|
||||
{
|
||||
return z.SetDictionary(dictionary);
|
||||
return z.SetDictionary(dictionary, check);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -642,14 +642,15 @@ namespace SabreTools.Compression.Deflate
|
||||
/// Set the dictionary to be used for either Inflation or Deflation.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">The dictionary bytes to use.</param>
|
||||
/// <param name="check">Determines if dictionary checks are run</param>
|
||||
/// <returns>Z_OK if all goes well.</returns>
|
||||
public int SetDictionary(byte[] dictionary)
|
||||
public int SetDictionary(byte[] dictionary, bool check = true)
|
||||
{
|
||||
if (istate != null)
|
||||
return istate.SetDictionary(dictionary);
|
||||
return istate.SetDictionary(dictionary, check);
|
||||
|
||||
if (dstate != null)
|
||||
return dstate.SetDictionary(dictionary);
|
||||
return dstate.SetDictionary(dictionary, check);
|
||||
|
||||
throw new ZlibException("No Inflate or Deflate state!");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.Compression.MSZIP;
|
||||
|
||||
namespace SabreTools.Compression.MSZIP
|
||||
{
|
||||
@@ -8,89 +9,59 @@ namespace SabreTools.Compression.MSZIP
|
||||
public class Decompressor
|
||||
{
|
||||
/// <summary>
|
||||
/// Source stream for the decompressor
|
||||
/// Last uncompressed block data
|
||||
/// </summary>
|
||||
private readonly Stream _source;
|
||||
private byte[]? _history = null;
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Create a MS-ZIP decompressor
|
||||
/// </summary>
|
||||
private Decompressor(Stream source)
|
||||
{
|
||||
// Validate the inputs
|
||||
if (source.Length == 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(source));
|
||||
if (!source.CanRead)
|
||||
throw new InvalidOperationException(nameof(source));
|
||||
|
||||
_source = source;
|
||||
}
|
||||
private Decompressor() { }
|
||||
|
||||
/// <summary>
|
||||
/// Create a MS-ZIP decompressor
|
||||
/// </summary>
|
||||
public static Decompressor Create(byte[] source)
|
||||
=> Create(new MemoryStream(source));
|
||||
|
||||
/// <summary>
|
||||
/// Create a MS-ZIP decompressor
|
||||
/// </summary>
|
||||
public static Decompressor Create(Stream source)
|
||||
{
|
||||
// Create the decompressor
|
||||
var decompressor = new Decompressor(source);
|
||||
|
||||
// Validate the header
|
||||
var header = new Models.Compression.MSZIP.BlockHeader();
|
||||
header.Signature = source.ReadUInt16();
|
||||
if (header.Signature != 0x4B43)
|
||||
throw new InvalidDataException(nameof(source));
|
||||
|
||||
// Return
|
||||
return decompressor;
|
||||
}
|
||||
public static Decompressor Create() => new();
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Decompress source data to an output stream
|
||||
/// </summary>
|
||||
public bool CopyTo(Stream dest)
|
||||
public bool CopyTo(byte[] source, Stream dest)
|
||||
=> CopyTo(new MemoryStream(source), dest);
|
||||
|
||||
/// <summary>
|
||||
/// Decompress source data to an output stream
|
||||
/// </summary>
|
||||
public bool CopyTo(Stream source, Stream dest)
|
||||
{
|
||||
// Ignore unwritable streams
|
||||
if (!dest.CanWrite)
|
||||
return false;
|
||||
|
||||
byte[]? history = null;
|
||||
while (true)
|
||||
// Validate the header
|
||||
var header = new BlockHeader();
|
||||
header.Signature = source.ReadUInt16();
|
||||
if (header.Signature != 0x4B43)
|
||||
throw new InvalidDataException(nameof(source));
|
||||
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
var blockStream = new Deflate.DeflateStream(source, Deflate.CompressionMode.Decompress);
|
||||
if (_history != null)
|
||||
blockStream.SetDictionary(_history, check: false);
|
||||
|
||||
int read = blockStream.Read(buffer, 0, buffer.Length);
|
||||
if (read > 0)
|
||||
{
|
||||
byte[] buffer = new byte[32 * 1024];
|
||||
var blockStream = new Deflate.DeflateStream(_source, Deflate.CompressionMode.Decompress);
|
||||
if (history != null)
|
||||
blockStream.SetDictionary(history);
|
||||
|
||||
int read = blockStream.Read(buffer, 0, buffer.Length);
|
||||
if (read <= 0)
|
||||
break;
|
||||
|
||||
// Write to output
|
||||
dest.Write(buffer, 0, read);
|
||||
|
||||
// Save the history for rollover
|
||||
history = new byte[read];
|
||||
Array.Copy(buffer, history, read);
|
||||
|
||||
// Handle end of stream
|
||||
if (_source.Position >= _source.Length)
|
||||
break;
|
||||
|
||||
// Validate the header
|
||||
var header = new Models.Compression.MSZIP.BlockHeader();
|
||||
header.Signature = _source.ReadUInt16();
|
||||
if (header.Signature != 0x4B43)
|
||||
break;
|
||||
_history = new byte[read];
|
||||
Array.Copy(buffer, _history, read);
|
||||
}
|
||||
|
||||
// Flush and return
|
||||
|
||||
Reference in New Issue
Block a user