mirror of
https://github.com/Barubary/dsdecmp.git
synced 2024-11-16 15:49:24 +01:00
C#: implemented a compression algorithm for the LZE/Le compression scheme. (although it appears to perform worse than the original compression algorithm, it should still work)
This commit is contained in:
parent
4302517e58
commit
a30a7ac3e3
@ -7,24 +7,58 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoldenSunDD", "GoldenSunDD\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuminousArc", "LuminousArc\LuminousArc.csproj", "{4BD8DF5C-E971-45D1-B170-340D22DDB351}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "Tester\Tester.csproj", "{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{4BD8DF5C-E971-45D1-B170-340D22DDB351}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Debug|x86.Build.0 = Debug|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Release|x86.ActiveCfg = Release|x86
|
||||
{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -11,7 +11,7 @@ namespace DSDecmp
|
||||
class NewestProgram
|
||||
{
|
||||
#if DEBUG
|
||||
public static string PluginFolder = "../../../PluginDistro/Debug";
|
||||
public static string PluginFolder = "./Plugins/Debug";
|
||||
#else
|
||||
public static string PluginFolder = "./Plugins";
|
||||
#endif
|
||||
@ -299,7 +299,6 @@ namespace DSDecmp
|
||||
inputData = new byte[inStream.Length];
|
||||
inStream.Read(inputData, 0, inputData.Length);
|
||||
}
|
||||
bool compressed = false;
|
||||
|
||||
#region try to compress
|
||||
|
||||
@ -315,7 +314,6 @@ namespace DSDecmp
|
||||
{
|
||||
outStr.WriteTo(output);
|
||||
}
|
||||
compressed = true;
|
||||
if (format is CompositeFormat)
|
||||
Console.Write((format as CompositeFormat).LastUsedCompressFormatString);
|
||||
else
|
||||
@ -323,24 +321,28 @@ namespace DSDecmp
|
||||
Console.WriteLine("-compressed " + input + " to " + outputFile);
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
#region copy or print and continue
|
||||
|
||||
if (copyErrors)
|
||||
{
|
||||
Copy(input, outputFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Could not " + format.ShortFormatString + "-compress " + input + ";");
|
||||
Console.WriteLine(ex.Message);
|
||||
#if DEBUG
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (!compressed)
|
||||
{
|
||||
#region copy or print and continue
|
||||
|
||||
if (copyErrors)
|
||||
{
|
||||
Copy(input, outputFile);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Could not " + format.ShortFormatString + "-compress " + input + ".");
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
|
@ -14,19 +14,21 @@ namespace DSDecmp
|
||||
/// starting at oldPtr. Takes O(inLength * oldLength) = O(n^2) time.
|
||||
/// </summary>
|
||||
/// <param name="newPtr">The start of the data that needs to be compressed.</param>
|
||||
/// <param name="newLength">The number of bytes that still need to be compressed.</param>
|
||||
/// <param name="newLength">The number of bytes that still need to be compressed.
|
||||
/// (or: the maximum number of bytes that _may_ be compressed into one block)</param>
|
||||
/// <param name="oldPtr">The start of the raw file.</param>
|
||||
/// <param name="oldLength">The number of bytes already compressed.</param>
|
||||
/// <param name="disp">The offset of the start of the longest block to refer to.</param>
|
||||
/// <param name="minDisp">The minimum allowed value for 'disp'.</param>
|
||||
/// <returns>The length of the longest sequence of bytes that can be copied from the already decompressed data.</returns>
|
||||
public static unsafe int GetOccurrenceLength(byte* newPtr, int newLength, byte* oldPtr, int oldLength, out int disp)
|
||||
public static unsafe int GetOccurrenceLength(byte* newPtr, int newLength, byte* oldPtr, int oldLength, out int disp, int minDisp = 1)
|
||||
{
|
||||
disp = 0;
|
||||
if (newLength == 0)
|
||||
return 0;
|
||||
int maxLength = 0;
|
||||
// try every possible 'disp' value (disp = oldLength - i)
|
||||
for (int i = 0; i < oldLength - 1; i++)
|
||||
for (int i = 0; i < oldLength - minDisp; i++)
|
||||
{
|
||||
// work from the start of the old data to the end, to mimic the original implementation's behaviour
|
||||
// (and going from start to end or from end to start does not influence the compression ratio anyway)
|
||||
@ -48,6 +50,10 @@ namespace DSDecmp
|
||||
{
|
||||
maxLength = currentLength;
|
||||
disp = oldLength - i;
|
||||
|
||||
// if we cannot do better anyway, stop trying.
|
||||
if (maxLength == newLength)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return maxLength;
|
||||
|
@ -29,9 +29,15 @@ namespace GameFormats
|
||||
|
||||
public override bool SupportsCompression
|
||||
{
|
||||
get { return false; }
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
private static bool lookAhead = false;
|
||||
/// <summary>
|
||||
/// Gets or sets if, when compressing using this format, the optimal compression scheme should be used.
|
||||
/// </summary>
|
||||
public static bool LookAhead { get { return lookAhead; } set { lookAhead = value; } }
|
||||
|
||||
/*
|
||||
* An LZE / Le file consists of the following:
|
||||
- A six byte header
|
||||
@ -97,6 +103,10 @@ namespace GameFormats
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Method: Decompress(instream, inLength, outstream)
|
||||
/// <summary>
|
||||
/// Decompresses the given stream using the LZE/Le compression format.
|
||||
/// </summary>
|
||||
public override long Decompress(System.IO.Stream instream, long inLength, System.IO.Stream outstream)
|
||||
{
|
||||
long readBytes = 0;
|
||||
@ -191,7 +201,7 @@ namespace GameFormats
|
||||
}
|
||||
#endregion
|
||||
case 1:
|
||||
#region 1 -> compact LZ10-like format
|
||||
#region 1 -> compact LZ10/RLE-like format
|
||||
{
|
||||
#region Get length and displacement('disp') values from next byte
|
||||
// there are < 2 bytes available when the end is at most 1 byte away
|
||||
@ -268,6 +278,7 @@ namespace GameFormats
|
||||
default:
|
||||
throw new Exception("BUG: Mask is not 2 bits long!");
|
||||
}
|
||||
|
||||
outstream.Flush();
|
||||
}
|
||||
|
||||
@ -281,22 +292,206 @@ namespace GameFormats
|
||||
|
||||
return decompressedSize;
|
||||
}
|
||||
#endregion
|
||||
|
||||
private int MaskRsh(int value, int mask)
|
||||
/// <summary>
|
||||
/// Checks if the given aguments have the '-opt' option, which makes this format
|
||||
/// compress using (near-)optimal compression instead of the original compression algorithm.
|
||||
/// </summary>
|
||||
public override int ParseCompressionOptions(string[] args)
|
||||
{
|
||||
int maskCopy = mask;
|
||||
int masked = value & mask;
|
||||
if (maskCopy == 0)
|
||||
return masked;
|
||||
while ((maskCopy & 1) == 0)
|
||||
{
|
||||
masked >>= 1;
|
||||
maskCopy >>= 1;
|
||||
}
|
||||
return masked;
|
||||
LookAhead = false;
|
||||
if (args.Length > 0)
|
||||
if (args[0] == "-opt")
|
||||
{
|
||||
LookAhead = true;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override int Compress(System.IO.Stream instream, long inLength, System.IO.Stream outstream)
|
||||
public unsafe override int Compress(System.IO.Stream instream, long inLength, System.IO.Stream outstream)
|
||||
{
|
||||
// block type 0: stores at most 3+0xF = 0x12 = 18 bytes (in 2 bytes)
|
||||
// block type 1: stores at most 2+0x3F = 0x41 = 65 bytes (in 1 byte)
|
||||
// block type 2: 1 raw byte
|
||||
// block type 3: 3 raw bytes
|
||||
|
||||
if (LookAhead)
|
||||
return CompressWithLA(instream, inLength, outstream);
|
||||
|
||||
|
||||
// save the input data in an array to prevent having to go back and forth in a file
|
||||
byte[] indata = new byte[inLength];
|
||||
int numReadBytes = instream.Read(indata, 0, (int)inLength);
|
||||
if (numReadBytes != inLength)
|
||||
throw new StreamTooShortException();
|
||||
|
||||
// write the compression head first
|
||||
outstream.WriteByte((byte)'L');
|
||||
outstream.WriteByte((byte)'e');
|
||||
outstream.WriteByte((byte)(inLength & 0xFF));
|
||||
outstream.WriteByte((byte)((inLength >> 8) & 0xFF));
|
||||
outstream.WriteByte((byte)((inLength >> 16) & 0xFF));
|
||||
outstream.WriteByte((byte)((inLength >> 24) & 0xFF));
|
||||
|
||||
int compressedLength = 6;
|
||||
|
||||
fixed (byte* instart = &indata[0])
|
||||
{
|
||||
// we do need to buffer the output, as the first byte indicates which blocks are compressed.
|
||||
// this version does not use a look-ahead, so we do not need to buffer more than 4 blocks at a time.
|
||||
// (a block is at most 3 bytes long)
|
||||
byte[] outbuffer = new byte[4 * 3 + 1];
|
||||
outbuffer[0] = 0;
|
||||
int bufferlength = 1, bufferedBlocks = 0;
|
||||
int readBytes = 0;
|
||||
|
||||
int cacheByte = -1;
|
||||
|
||||
while (readBytes < inLength)
|
||||
{
|
||||
#region If 4 blocks are bufferd, write them and reset the buffer
|
||||
// we can only buffer 4 blocks at a time.
|
||||
if (bufferedBlocks == 4)
|
||||
{
|
||||
outstream.Write(outbuffer, 0, bufferlength);
|
||||
compressedLength += bufferlength;
|
||||
// reset the buffer
|
||||
outbuffer[0] = 0;
|
||||
bufferlength = 1;
|
||||
bufferedBlocks = 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
// type 0: 3 <= len <= 18; 5 <= disp <= 0x1004
|
||||
// type 1: 2 <= len <= 65; 1 <= disp <= 4
|
||||
// type 2: 1 raw byte
|
||||
// type 3: 3 raw bytes
|
||||
|
||||
// check if we can compress it using type 1 first (only 1 byte-long block)
|
||||
int disp;
|
||||
int oldLength = Math.Min(readBytes, 0x1004);
|
||||
int length = LZUtil.GetOccurrenceLength(instart + readBytes, (int)Math.Min(inLength - readBytes, 65),
|
||||
instart + readBytes - oldLength, oldLength, out disp, 1);
|
||||
if (disp >= 1 && ((disp <= 4 && length >= 2) || (disp >= 5 && length >= 3)))
|
||||
{
|
||||
if (cacheByte >= 0)
|
||||
{
|
||||
// write a single raw byte block (the previous byte could not be the start of any compressed block)
|
||||
outbuffer[bufferlength++] = (byte)(cacheByte & 0xFF);
|
||||
outbuffer[0] |= (byte)(2 << (bufferedBlocks * 2));
|
||||
cacheByte = -1;
|
||||
bufferedBlocks++;
|
||||
// the block set may be full; just retry this iteration.
|
||||
continue;
|
||||
}
|
||||
if (disp >= 5)
|
||||
{
|
||||
#region compress using type 0
|
||||
|
||||
// type 0: store len/disp in 2 bytes:
|
||||
// AB CD, with len = C + 3, disp = DAB + 5
|
||||
|
||||
// make sure we do not try to compress more than fits into the block
|
||||
length = Math.Min(length, 0xF + 3);
|
||||
|
||||
readBytes += length;
|
||||
|
||||
outbuffer[bufferlength++] = (byte)((disp - 5) & 0xFF);
|
||||
outbuffer[bufferlength] = (byte)(((disp - 5) >> 8) & 0xF);
|
||||
outbuffer[bufferlength++] |= (byte)(((length - 3) & 0xF) << 4);
|
||||
|
||||
#endregion
|
||||
}
|
||||
else // 1 <= disp <= 4
|
||||
{
|
||||
#region compress using type 1
|
||||
|
||||
// type 1: store len/disp in 1 byte:
|
||||
// ABCDEFGH, wih len = ABCDEF + 2, disp = GH + 1
|
||||
|
||||
readBytes += length;
|
||||
|
||||
outbuffer[bufferlength] = (byte)(((length - 2) << 2) & 0xFC);
|
||||
outbuffer[bufferlength] |= (byte)((disp - 1) & 0x3);
|
||||
bufferlength++;
|
||||
|
||||
outbuffer[0] |= (byte)(1 << (bufferedBlocks * 2));
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cacheByte < 0)
|
||||
{
|
||||
// first fail? remember byte, try to compress starting at next byte
|
||||
cacheByte = *(instart + (readBytes++));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2 consecutive fails -> store 3 raw bytes (type 3) if possible.
|
||||
if (inLength - readBytes >= 2)
|
||||
{
|
||||
outbuffer[bufferlength++] = (byte)(cacheByte & 0xFF);
|
||||
outbuffer[bufferlength++] = *(instart + (readBytes++));
|
||||
outbuffer[bufferlength++] = *(instart + (readBytes++));
|
||||
outbuffer[0] |= (byte)(3 << (bufferedBlocks * 2));
|
||||
cacheByte = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// there are only two bytes remaining (incl. the cched byte)
|
||||
// so write the cached byte first as single raw byte.
|
||||
// keep the next/last byte as new cache, since the block buffer may be full.
|
||||
outbuffer[bufferlength++] = (byte)(cacheByte & 0xFF);
|
||||
outbuffer[0] |= (byte)(2 << (bufferedBlocks * 2));
|
||||
cacheByte = *(instart + (readBytes++));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufferedBlocks++;
|
||||
}
|
||||
|
||||
// there may be one cache-byte left.
|
||||
if (cacheByte >= 0)
|
||||
{
|
||||
// if the current set of blocks is full, empty it first
|
||||
if (bufferedBlocks == 4)
|
||||
{
|
||||
#region empty block buffer
|
||||
|
||||
outstream.Write(outbuffer, 0, bufferlength);
|
||||
compressedLength += bufferlength;
|
||||
// reset the buffer
|
||||
outbuffer[0] = 0;
|
||||
bufferlength = 1;
|
||||
bufferedBlocks = 0;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
outbuffer[bufferlength++] = (byte)(cacheByte & 0xFF);
|
||||
cacheByte = -1;
|
||||
outbuffer[0] |= (byte)(2 << (bufferedBlocks * 2));
|
||||
bufferedBlocks++;
|
||||
}
|
||||
|
||||
// copy any remaining blocks to the output
|
||||
if (bufferedBlocks > 0)
|
||||
{
|
||||
outstream.Write(outbuffer, 0, bufferlength);
|
||||
compressedLength += bufferlength;
|
||||
}
|
||||
}
|
||||
|
||||
return compressedLength;
|
||||
}
|
||||
|
||||
private unsafe int CompressWithLA(Stream instream, long inLength, Stream outstream)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -30,6 +31,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
@ -211,16 +211,18 @@
|
||||
Utility class for compression using LZ-like compression schemes.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:DSDecmp.LZUtil.GetOccurrenceLength(System.Byte*,System.Int32,System.Byte*,System.Int32,System.Int32@)">
|
||||
<member name="M:DSDecmp.LZUtil.GetOccurrenceLength(System.Byte*,System.Int32,System.Byte*,System.Int32,System.Int32@,System.Int32)">
|
||||
<summary>
|
||||
Determine the maximum size of a LZ-compressed block starting at newPtr, using the already compressed data
|
||||
starting at oldPtr. Takes O(inLength * oldLength) = O(n^2) time.
|
||||
</summary>
|
||||
<param name="newPtr">The start of the data that needs to be compressed.</param>
|
||||
<param name="newLength">The number of bytes that still need to be compressed.</param>
|
||||
<param name="newLength">The number of bytes that still need to be compressed.
|
||||
(or: the maximum number of bytes that _may_ be compressed into one block)</param>
|
||||
<param name="oldPtr">The start of the raw file.</param>
|
||||
<param name="oldLength">The number of bytes already compressed.</param>
|
||||
<param name="disp">The offset of the start of the longest block to refer to.</param>
|
||||
<param name="minDisp">The minimum allowed value for 'disp'.</param>
|
||||
<returns>The length of the longest sequence of bytes that can be copied from the already decompressed data.</returns>
|
||||
</member>
|
||||
<member name="T:DSDecmp.Formats.Nitro.NitroCFormat">
|
||||
|
Binary file not shown.
Binary file not shown.
27
CSharp/Tester/Program.cs
Normal file
27
CSharp/Tester/Program.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using GameFormats;
|
||||
|
||||
namespace Tester
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Start");
|
||||
|
||||
//new LuminousArc().Compress("D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/atcbg_dec.imb", "D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/atcbg_dec_cmp.imb");
|
||||
//new LuminousArc().Decompress("D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/atcbg_dec_cmp.imb", "D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/atcbg_dec_cmp_dec.imb");
|
||||
|
||||
new LuminousArc().Compress("D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/o_lmoji00_dec.bin", "D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/o_lmoji00_dec_cmp.bin");
|
||||
Console.WriteLine();
|
||||
new LuminousArc().Decompress("D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/o_lmoji00_dec_cmp.bin", "D:/tile molester/DSLazy/NDS_UNPACK_LUMARC/test/o_lmoji00_dec_cmp_dec.bin");
|
||||
|
||||
|
||||
Console.WriteLine("Success?");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
36
CSharp/Tester/Properties/AssemblyInfo.cs
Normal file
36
CSharp/Tester/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Tester")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Tester")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2011")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("abe40de2-686c-4757-83ff-375f54a21490")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
CSharp/Tester/Tester.csproj
Normal file
71
CSharp/Tester/Tester.csproj
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A4FABF4B-59F2-4D4B-9012-FF177980EAB7}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Tester</RootNamespace>
|
||||
<AssemblyName>Tester</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DSDecmp\DSDecmp.csproj">
|
||||
<Project>{E6F419F9-D6B5-4BE7-99BB-97C48C927FF3}</Project>
|
||||
<Name>DSDecmp</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GoldenSunDD\GoldenSunDD.csproj">
|
||||
<Project>{8CE72663-0036-4A94-BD70-99AFE7CEEC0C}</Project>
|
||||
<Name>GoldenSunDD</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LuminousArc\LuminousArc.csproj">
|
||||
<Project>{4BD8DF5C-E971-45D1-B170-340D22DDB351}</Project>
|
||||
<Name>LuminousArc</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user