mirror of
https://github.com/SabreTools/SabreTools.Compression.git
synced 2026-09-22 23:05:04 +00:00
Add everything from szddd.c
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace SabreTools.Compression.libmspack
|
||||
{
|
||||
@@ -16,7 +17,25 @@ namespace SabreTools.Compression.libmspack
|
||||
/// </summary>
|
||||
/// <param name="sys">A custom mspack_system structure, or NULL to use the default</param>
|
||||
/// <returns>A <see cref="mscab_decompressor"/> or NULL</returns>
|
||||
public static mscab_decompressor mspack_create_cab_decompressor(mspack_system sys) => throw new NotImplementedException();
|
||||
public static mscab_decompressor mspack_create_cab_decompressor(mspack_system sys)
|
||||
{
|
||||
if (sys == null)
|
||||
return null;
|
||||
|
||||
var self = new mscab_decompressor
|
||||
{
|
||||
system = sys,
|
||||
d = null,
|
||||
error = MSPACK_ERR.MSPACK_ERR_OK,
|
||||
|
||||
searchbuf_size = 32768,
|
||||
fix_mszip = 0,
|
||||
buf_size = 4096,
|
||||
salvage = 0,
|
||||
};
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys an existing CAB compressor.
|
||||
@@ -28,7 +47,21 @@ namespace SabreTools.Compression.libmspack
|
||||
/// Destroys an existing CAB decompressor.
|
||||
/// </summary>
|
||||
/// <param name="self">The <see cref="mscab_decompressor"/> to destroy</param>
|
||||
public static void mspack_destroy_cab_decompressor(mscab_decompressor self) => throw new NotImplementedException();
|
||||
public static void mspack_destroy_cab_decompressor(mscab_decompressor self)
|
||||
{
|
||||
if (self != null)
|
||||
{
|
||||
mspack_system sys = self.system;
|
||||
if (self.d != null)
|
||||
{
|
||||
if (self.d.infh != null) sys.close(self.d.infh);
|
||||
cabd_free_decomp(self);
|
||||
//sys.free(self.d);
|
||||
}
|
||||
|
||||
//sys.free(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new CHM compressor.
|
||||
@@ -120,7 +153,18 @@ namespace SabreTools.Compression.libmspack
|
||||
/// </summary>
|
||||
/// <param name="sys">A custom mspack_system structure, or NULL to use the default</param>
|
||||
/// <returns>A <see cref="msszdd_decompressor"/> or NULL</returns>
|
||||
public static msszdd_decompressor mspack_create_szdd_decompressor(mspack_system sys) => throw new NotImplementedException();
|
||||
public static msszdd_decompressor mspack_create_szdd_decompressor(mspack_system sys)
|
||||
{
|
||||
msszdd_decompressor self = null;
|
||||
|
||||
if (sys == null) sys = new mspack_default_system();
|
||||
|
||||
self = new msszdd_decompressor();
|
||||
self.system = sys;
|
||||
self.error = MSPACK_ERR.MSPACK_ERR_OK;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys an existing SZDD compressor.
|
||||
@@ -132,7 +176,14 @@ namespace SabreTools.Compression.libmspack
|
||||
/// Destroys an existing SZDD decompressor.
|
||||
/// </summary>
|
||||
/// <param name="self">The <see cref="msszdd_decompressor"/> to destroy</param>
|
||||
public static void mspack_destroy_szdd_decompressor(msszdd_decompressor self) => throw new NotImplementedException();
|
||||
public static void mspack_destroy_szdd_decompressor(msszdd_decompressor self)
|
||||
{
|
||||
if (self != null)
|
||||
{
|
||||
mspack_system sys = self.system;
|
||||
//sys.free(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new KWAJ compressor.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using System.Linq;
|
||||
using static SabreTools.Compression.libmspack.szdd;
|
||||
|
||||
namespace SabreTools.Compression.libmspack
|
||||
{
|
||||
/// <summary>
|
||||
@@ -7,7 +10,7 @@ namespace SabreTools.Compression.libmspack
|
||||
/// </summary>
|
||||
/// <see cref="mspack_create_szdd_decompressor()"/>
|
||||
/// <see cref="mspack_destroy_szdd_decompressor()"/>
|
||||
public abstract class msszdd_decompressor
|
||||
public unsafe class msszdd_decompressor
|
||||
{
|
||||
public mspack_system system { get; set; }
|
||||
|
||||
@@ -19,7 +22,7 @@ namespace SabreTools.Compression.libmspack
|
||||
/// If the file opened is a valid SZDD file, all headers will be read and
|
||||
/// a msszddd_header structure will be returned.
|
||||
///
|
||||
/// In the case of an error occuring, NULL is returned and the error code
|
||||
/// In the case of an error occuring, null is returned and the error code
|
||||
/// is available from last_error().
|
||||
///
|
||||
/// The filename pointer should be considered "in use" until close() is
|
||||
@@ -29,9 +32,26 @@ namespace SabreTools.Compression.libmspack
|
||||
/// The filename of the SZDD compressed file. This is
|
||||
/// passed directly to mspack_system::open().
|
||||
/// </param>
|
||||
/// <returns>A pointer to a msszddd_header structure, or NULL on failure</returns>
|
||||
/// <returns>A pointer to a msszddd_header structure, or null on failure</returns>
|
||||
/// <see cref="close(msszddd_header)"/>
|
||||
public abstract msszddd_header open(in string filename);
|
||||
public msszddd_header open(in string filename)
|
||||
{
|
||||
mspack_system sys = this.system;
|
||||
|
||||
mspack_file fh = sys.open(filename, MSPACK_SYS_OPEN.MSPACK_SYS_OPEN_READ);
|
||||
msszddd_header hdr = new msszddd_header();
|
||||
hdr.fh = fh;
|
||||
this.error = szddd_read_headers(sys, fh, hdr);
|
||||
|
||||
if (this.error != MSPACK_ERR.MSPACK_ERR_OK)
|
||||
{
|
||||
if (fh != null) sys.close(fh);
|
||||
//sys.free(hdr);
|
||||
hdr = null;
|
||||
}
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes a previously opened SZDD file.
|
||||
@@ -42,7 +62,69 @@ namespace SabreTools.Compression.libmspack
|
||||
/// The SZDD header pointer is now invalid and cannot be used again.
|
||||
/// </summary>
|
||||
/// <param name="szdd">The SZDD file to close</param>
|
||||
public abstract void close(msszddd_header szdd);
|
||||
public void close(msszddd_header szdd)
|
||||
{
|
||||
if (this.system == null) return;
|
||||
|
||||
// Close the file handle associated
|
||||
this.system.close(szdd.fh);
|
||||
|
||||
// Free the memory associated
|
||||
//this.system.free(hdr);
|
||||
|
||||
this.error = MSPACK_ERR.MSPACK_ERR_OK;
|
||||
}
|
||||
|
||||
private static readonly byte[] szdd_signature_expand = new byte[8]
|
||||
{
|
||||
0x53, 0x5A, 0x44, 0x44, 0x88, 0xF0, 0x27, 0x33
|
||||
};
|
||||
|
||||
private static readonly byte[] szdd_signature_qbasic = new byte[8]
|
||||
{
|
||||
0x53, 0x5A, 0x20, 0x88, 0xF0, 0x27, 0x33, 0xD1
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Reads the headers of an SZDD format file
|
||||
/// </summary>
|
||||
/// <param name="sys"></param>
|
||||
/// <param name="fh"></param>
|
||||
/// <param name="hdr"></param>
|
||||
/// <returns></returns>
|
||||
private static MSPACK_ERR szddd_read_headers(mspack_system sys, mspack_file fh, msszddd_header hdr)
|
||||
{
|
||||
byte[] buf = new byte[8];
|
||||
byte* bufPtr = libmspack.system.GetArrayPointer<byte>(buf);
|
||||
|
||||
// Read and check signature
|
||||
if (sys.read(fh, buffer: bufPtr, 8) != 8) return MSPACK_ERR.MSPACK_ERR_READ;
|
||||
|
||||
if (buf.SequenceEqual(szdd_signature_expand))
|
||||
{
|
||||
// Common SZDD
|
||||
hdr.format = MSSZDD_FMT.MSSZDD_FMT_NORMAL;
|
||||
|
||||
// Read the rest of the header
|
||||
if (sys.read(fh, bufPtr, 6) != 6) return MSPACK_ERR.MSPACK_ERR_READ;
|
||||
if (buf[0] != 0x41) return MSPACK_ERR.MSPACK_ERR_DATAFORMAT;
|
||||
hdr.missing_char = (char)buf[1];
|
||||
hdr.length = EndGetI32(&buf[2]);
|
||||
}
|
||||
else if (buf.SequenceEqual(szdd_signature_qbasic))
|
||||
{
|
||||
// Special QBasic SZDD
|
||||
hdr.format = MSSZDD_FMT.MSSZDD_FMT_QBASIC;
|
||||
if (sys.read(fh, bufPtr, 4) != 4) return MSPACK_ERR.MSPACK_ERR_READ;
|
||||
hdr.missing_char = '\0';
|
||||
hdr.length = EndGetI32(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
return MSPACK_ERR.MSPACK_ERR_SIGNATURE;
|
||||
}
|
||||
return MSPACK_ERR.MSPACK_ERR_OK;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the compressed data from a SZDD file.
|
||||
@@ -56,7 +138,38 @@ namespace SabreTools.Compression.libmspack
|
||||
/// is passed directly to mspack_system::open().
|
||||
/// </param>
|
||||
/// <returns>An error code, or MSPACK_ERR_OK if successful</returns>
|
||||
public abstract MSPACK_ERR extract(msszddd_header szdd, in string filename);
|
||||
public MSPACK_ERR extract(msszddd_header szdd, in string filename)
|
||||
{
|
||||
if (szdd == null) return this.error = MSPACK_ERR.MSPACK_ERR_ARGS;
|
||||
mspack_system sys = this.system;
|
||||
|
||||
mspack_file fh = szdd.fh;
|
||||
|
||||
// Seek to the compressed data
|
||||
long data_offset = (szdd.format == MSSZDD_FMT.MSSZDD_FMT_NORMAL) ? 14 : 12;
|
||||
if (sys.seek(fh, data_offset, MSPACK_SYS_SEEK.MSPACK_SYS_SEEK_START) != 0)
|
||||
{
|
||||
return this.error = MSPACK_ERR.MSPACK_ERR_SEEK;
|
||||
}
|
||||
|
||||
// Open file for output
|
||||
mspack_file outfh;
|
||||
if ((outfh = sys.open(filename, MSPACK_SYS_OPEN.MSPACK_SYS_OPEN_WRITE)) == null)
|
||||
{
|
||||
return this.error = MSPACK_ERR.MSPACK_ERR_OPEN;
|
||||
}
|
||||
|
||||
// Decompress the data
|
||||
this.error = lzss_decompress(sys, fh, outfh, SZDD_INPUT_SIZE,
|
||||
szdd.format == MSSZDD_FMT.MSSZDD_FMT_NORMAL
|
||||
? LZSS_MODE.LZSS_MODE_EXPAND
|
||||
: LZSS_MODE.LZSS_MODE_QBASIC);
|
||||
|
||||
// Close output file
|
||||
sys.close(outfh);
|
||||
|
||||
return this.error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decompresses an SZDD file to an output file in one step.
|
||||
@@ -76,7 +189,15 @@ namespace SabreTools.Compression.libmspack
|
||||
/// is passed directly to mspack_system::open().
|
||||
/// </param>
|
||||
/// <returns>An error code, or MSPACK_ERR_OK if successful</returns>
|
||||
public abstract MSPACK_ERR decompress(in string input, in string output);
|
||||
public MSPACK_ERR decompress(in string input, in string output)
|
||||
{
|
||||
msszddd_header hdr;
|
||||
|
||||
if ((hdr = open(input)) == null) return this.error;
|
||||
MSPACK_ERR error = extract(hdr, output);
|
||||
close(hdr);
|
||||
return this.error = error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the error code set by the most recently called method.
|
||||
@@ -88,6 +209,9 @@ namespace SabreTools.Compression.libmspack
|
||||
/// <see cref="open(in string)"/>
|
||||
/// <see cref="extract(msszddd_header, in string)"/>
|
||||
/// <see cref="decompress(in string, in string)"/>
|
||||
public abstract MSPACK_ERR last_error();
|
||||
public MSPACK_ERR last_error()
|
||||
{
|
||||
return this.error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
namespace SabreTools.Compression.libmspack
|
||||
{
|
||||
public static class system
|
||||
public unsafe static class system
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the length of a file opened for reading
|
||||
/// </summary>
|
||||
public unsafe static MSPACK_ERR mspack_sys_filelen(mspack_system system, mspack_file file, long* length)
|
||||
public static MSPACK_ERR mspack_sys_filelen(mspack_system system, mspack_file file, long* length)
|
||||
{
|
||||
if (system == null || file == null || length == null) return MSPACK_ERR.MSPACK_ERR_OPEN;
|
||||
|
||||
@@ -38,5 +38,18 @@ namespace SabreTools.Compression.libmspack
|
||||
|
||||
return MSPACK_ERR.MSPACK_ERR_OK;
|
||||
}
|
||||
|
||||
public static T* CreateArray<T>(int length)
|
||||
{
|
||||
T[] buf = new T[length];
|
||||
return GetArrayPointer(buf);
|
||||
}
|
||||
|
||||
public static T* GetArrayPointer<T>(T[] arr)
|
||||
{
|
||||
var bufRef = __makeref(arr);
|
||||
var bufPtr = **(System.IntPtr**)&bufRef;
|
||||
return (T*)bufPtr.ToPointer();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace SabreTools.Compression.libmspack
|
||||
{
|
||||
public static class SZDD
|
||||
public static class szdd
|
||||
{
|
||||
/// <summary>
|
||||
/// Input buffer size during decompression - not worth parameterising IMHO
|
||||
|
||||
Reference in New Issue
Block a user