using System.IO;
namespace Syroot.Worms.Core
{
///
/// Represents methods to decompress data which is compressed using Team17's internal compression algorithm for
/// graphic file formats.
/// S. http://worms2d.info/Team17_compression.
///
internal static class Team17Compression
{
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
///
/// Decompresses the data available in the given into the provided
/// .
///
/// The to read the data from.
/// The byte array buffer to write the decompressed data to.
internal static void Decompress(Stream stream, ref byte[] buffer)
{
// TODO: This fails for compressed data in CD:\\Data\Mission\Training0-9.img.
int output = 0; // Offset of next write.
int cmd;
while ((cmd = stream.ReadByte()) != -1)
{
// Read a byte.
if ((cmd & 0x80) == 0)
{
// Command: 1 byte (color)
buffer[output++] = (byte)cmd;
}
else
{
// Arg1 = bits 2-5
int arg1 = (cmd >> 3) & 0xF;
int arg2 = stream.ReadByte();
if (arg2 == -1)
{
return;
}
// Arg2 = bits 6-16
arg2 = ((cmd << 8) | arg2) & 0x7FF;
if (arg1 == 0)
{
// Command: 0x80 0x00
if (arg2 == 0)
{
return;
}
int arg3 = stream.ReadByte();
if (arg3 == -1)
{
return;
}
// Command: 3 bytes
output = CopyData(output, arg2, arg3 + 18, ref buffer);
}
else
{
// Command: 2 bytes
output = CopyData(output, arg2 + 1, arg1 + 2, ref buffer);
}
}
}
}
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
private static int CopyData(int offset, int compressedOffset, int count, ref byte[] buffer)
{
for (; count > 0; count--)
{
buffer[offset] = buffer[offset++ - compressedOffset];
}
return offset;
}
}
}