Yaz0 code must be rewritten

This commit is contained in:
Denis
2022-01-15 14:22:54 +01:00
parent 3386e8ff7a
commit 148839f15d
2 changed files with 0 additions and 150 deletions

View File

@@ -1,135 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BMGEditor
{
public static class Yaz0 // ONLY WORKS WITH BIG ENDIAN - TO REWRITE !!
{
// TODO: put compression in use?
// note: compression is slow when dealing with large files (eg. 3D models)
// it should be made optional, and show a progress dialog and all
private static void FindOccurence(byte[] data, int pos, ref int offset, ref int length)
{
offset = -1;
length = 0;
if (pos >= data.Length - 2) return;
Dictionary<int, int> occurences = new Dictionary<int, int>();
int len = 0;
int start = (pos > 4096) ? pos - 4096 : 0;
for (int i = start; i < pos; i++)
{
if (i >= data.Length - 2) break;
if (data[i] != data[pos] || data[i + 1] != data[pos + 1] || data[i + 2] != data[pos + 2])
continue;
len = 3;
while ((i + len < data.Length) && (pos + len < data.Length) && (data[i + len] == data[pos + len]))
len++;
occurences.Add(i, len);
}
foreach (KeyValuePair<int, int> occ in occurences)
{
if (occ.Value > length)
{
offset = occ.Key;
length = occ.Value;
}
}
}
public static void Compress(ref byte[] data)
{
if (data[0] == 'Y' && data[1] == 'a' && data[2] == 'z' && data[3] == '0')
return;
byte[] output = new byte[16 + data.Length + (data.Length / 8)];
output[0] = (byte)'Y';
output[1] = (byte)'a';
output[2] = (byte)'z';
output[3] = (byte)'0';
uint fullsize = (uint)data.Length;
output[4] = (byte)(fullsize >> 24);
output[5] = (byte)(fullsize >> 16);
output[6] = (byte)(fullsize >> 8);
output[7] = (byte)fullsize;
int inpos = 0, outpos = 16;
int occ_offset = -1, occ_length = 0;
while (inpos < fullsize)
{
int datastart = outpos + 1;
byte block = 0;
for (int i = 0; i < 8; i++)
{
block <<= 1;
if (inpos < data.Length)
{
if (occ_offset == -2)
FindOccurence(data, inpos, ref occ_offset, ref occ_length);
int next_offset = -1, next_length = 0;
FindOccurence(data, inpos + 1, ref next_offset, ref next_length);
if (next_length > occ_length + 1) occ_offset = -1;
if (occ_offset != -1)
{
int disp = inpos - occ_offset - 1;
if (disp > 4095) throw new Exception("DISP OUT OF RANGE!");
if (occ_length > 17)
{
if (occ_length > 273) occ_length = 273;
output[datastart++] = (byte)(disp >> 8);
output[datastart++] = (byte)disp;
output[datastart++] = (byte)(occ_length - 18);
}
else
{
output[datastart++] = (byte)(((occ_length - 2) << 4) | (disp >> 8));
output[datastart++] = (byte)disp;
}
inpos += occ_length;
occ_offset = -2;
}
else
{
output[datastart++] = data[inpos++];
block |= 0x01;
}
if (occ_offset != -2)
{
occ_offset = next_offset;
occ_length = next_length;
}
}
}
output[outpos] = block;
outpos = datastart;
}
Array.Resize(ref data, outpos);
Array.Resize(ref output, outpos);
output.CopyTo(data, 0);
}
// inspired from http://www.amnoid.de/gc/yaz0.txt
public static void Decompress(ref byte[] data)
{

View File

@@ -24,30 +24,6 @@ namespace BMGEditor
Write(buffer, 0, buffer.Length);
}
public void Flush(bool recompress)
{
byte[] buffer = new byte[Length];
Position = 0;
Read(buffer, 0, (int)Length);
if (recompress) Yaz0.Compress(ref buffer);
m_Backend.Position = 0;
m_Backend.SetLength(buffer.Length);
m_Backend.Write(buffer, 0, buffer.Length);
m_Backend.Flush();
}
public override void Flush()
{
Flush(false);
}
public override void Close()
{
m_Backend.Close();
base.Close();
}
private Stream m_Backend;
}