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; } } }