Wouldn't you mind to share recompression alg code?
Don't have much patience to wait fully functioning tool
Code: Select all
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace LZSS
{
unsafe static class LZSS
{
const int N = 4096;
const int F = 16;
const int THRESHOLD = 2;
const int NIL = N;
static int textsize = 0, codesize = 0;
static byte* text_buf = (byte*)Marshal.AllocHGlobal(N + F - 1);
static int match_position, match_length;
static int[] lson = new int[N + 1], rson = new int[N + 257], dad = new int[N + 1];
static Stream infile, outfile;
private static void InitTree()
{
int i;
for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
for (i = 0; i < N; i++) dad[i] = NIL;
}
private static void InsertNode(int r)
{
int i, p, cmp;
byte* key;
cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
rson[r] = lson[r] = NIL; match_length = 0;
for (; ; )
{
if (cmp >= 0)
{
if (rson[p] != NIL) p = rson[p];
else { rson[p] = r; dad[r] = p; return; }
}
else
{
if (lson[p] != NIL) p = lson[p];
else { lson[p] = r; dad[r] = p; return; }
}
for (i = 1; i < F; i++)
if ((cmp = key[i] - text_buf[p + i]) != 0) break;
if (i > match_length)
{
match_position = p;
if ((match_length = i) >= F) break;
}
}
dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
dad[lson[p]] = r; dad[rson[p]] = r;
if (rson[dad[p]] == p) rson[dad[p]] = r;
else lson[dad[p]] = r;
dad[p] = NIL;
}
private static void DeleteNode(int p)
{
int q;
if (dad[p] == NIL) return;
if (rson[p] == NIL) q = lson[p];
else if (lson[p] == NIL) q = rson[p];
else
{
q = lson[p];
if (rson[q] != NIL)
{
do { q = rson[q]; } while (rson[q] != NIL);
rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
lson[q] = lson[p]; dad[lson[p]] = q;
}
rson[q] = rson[p]; dad[rson[p]] = q;
}
dad[q] = dad[p];
if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
dad[p] = NIL;
}
private static void Encode()
{
int i, c, len, r, s, last_match_length, code_buf_ptr;
byte[] code_buf = new byte[17];
byte mask;
InitTree();
code_buf[0] = 0;
code_buf_ptr = mask = 1;
s = 0; r = N - F;
for (i = s; i < r; i++) text_buf[i] = 0x00;
for (len = 0; len < F && infile.Position != infile.Length; len++)
{
c = infile.ReadByte();
text_buf[r + len] = (byte)c;
}
if ((textsize = len) == 0) return;
for (i = 1; i <= F; i++) InsertNode(r - i);
InsertNode(r);
do
{
if (match_length > len) match_length = len;
if (match_length <= THRESHOLD)
{
match_length = 1;
code_buf[0] |= mask;
code_buf[code_buf_ptr++] = text_buf[r];
}
else
{
code_buf[code_buf_ptr++] = (byte)match_position;
code_buf[code_buf_ptr++] = (byte)
(((match_position >> 4) & 0xf0)
| (match_length - (THRESHOLD + 1)));
}
if ((mask <<= 1) == 0)
{
for (i = 0; i < code_buf_ptr; i++)
outfile.WriteByte(code_buf[i]);
codesize += code_buf_ptr;
code_buf[0] = 0; code_buf_ptr = mask = 1;
}
last_match_length = match_length;
for (i = 0; i < last_match_length && infile.Position != infile.Length; i++)
{
c = infile.ReadByte();
DeleteNode(s);
text_buf[s] = (byte)c;
if (s < F - 1) text_buf[s + N] = (byte)c;
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
InsertNode(r);
}
while (i++ < last_match_length)
{
DeleteNode(s);
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
if (--len != 0) InsertNode(r);
}
} while (len > 0);
if (code_buf_ptr > 1)
{
for (i = 0; i < code_buf_ptr; i++) outfile.WriteByte(code_buf[i]);
codesize += code_buf_ptr;
}
}
private static void Decode()
{
int i, j, k, r, c, flags;
for (i = 0; i < N - F; i++) text_buf[i] = 0x00;
r = N - F; flags = 0;
for (; ; )
{
if (((flags >>= 1) & 256) == 0)
{
if (infile.Position == infile.Length) break;
c = infile.ReadByte();
flags = c | 0xff00;
}
if ((flags & 1) != 0)
{
if (infile.Position == infile.Length) break;
c = infile.ReadByte();
outfile.WriteByte((byte)(c)); text_buf[r++] = (byte)(c); r &= (N - 1);
}
else
{
if (infile.Position == infile.Length) break;
i = infile.ReadByte();
if (infile.Position == infile.Length) break;
j = infile.ReadByte();
i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
for (k = 0; k <= j; k++)
{
c = text_buf[(i + k) & (N - 1)];
outfile.WriteByte((byte)(c)); text_buf[r++] = (byte)(c); r &= (N - 1);
}
}
}
}
public static byte[] Decompress(byte[] inBuffer)
{
MemoryStream inStream = new MemoryStream(inBuffer);
BinaryReader reader = new BinaryReader(inStream);
reader.BaseStream.Seek(0x04, SeekOrigin.Begin);
int decSize = reader.ReadInt32();
infile = new MemoryStream(reader.ReadBytes(inBuffer.Length - 0x08));
outfile = new MemoryStream();
Decode();
if (outfile.Length == decSize)
return (outfile as MemoryStream).ToArray();
else throw new InvalidDataException("Decompression Error");
}
public static byte[] Compress(byte[] inBuffer)
{
int decSize = inBuffer.Length;
infile = new MemoryStream(inBuffer);
outfile = new MemoryStream();
Encode();
MemoryStream outStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(outStream);
writer.Write(0x53535a4c);
writer.Write(decSize);
writer.Write((outfile as MemoryStream).ToArray());
return outStream.ToArray();
}
public static void Decompress(String inFile, String outFile)
{
infile = new FileStream(inFile, FileMode.Open, FileAccess.Read);
outfile = new FileStream(outFile, FileMode.Create, FileAccess.Write);
Decode();
}
public static void Compress(String inFile, String outFile)
{
infile = new FileStream(inFile, FileMode.Open, FileAccess.Read);
outfile = new FileStream(outFile, FileMode.Create, FileAccess.Write);
Encode();
}
public static void Decompress(Stream inFileStream, Stream outFileStream)
{
infile = inFileStream;
outfile = outFileStream;
Decode();
}
public static void Compress(Stream inFileStream, Stream outFileStream)
{
infile = inFileStream;
outfile = outFileStream;
Encode();
}
}
}

You are right, I've tested it with full file and works O.K.finale00 wrote:The 10 MB sample most likely won't work cause it's trying to decompress or go to some offset that may or may not exist.
They're stored in SCRIPT folder. Check file SCRIPT_MAP5 (CHAP1) - these one have introduction of chapter 1.Any idea about were can I find text's files??