public static byte[] Compress(Stream input, Method method) { if (input.Length > 0xffffff) { throw new Exception("File too big to be compressed with Nintendo compression!"); } var res = new List <byte>(); res.AddRange(new byte[] { (byte)method, (byte)(input.Length & 0xff), (byte)(input.Length >> 8 & 0xff), (byte)(input.Length >> 16 & 0xff) }); switch (method) { case Method.LZ10: res.AddRange(LZ10.Compress(input)); return(res.ToArray()); case Method.LZ11: res.AddRange(LZ11.Compress(input)); return(res.ToArray()); case Method.Huff4: res.AddRange(Huffman.Compress(input, 4, ByteOrder.BigEndian)); return(res.ToArray()); case Method.Huff8: res.AddRange(Huffman.Compress(input, 8)); return(res.ToArray()); case Method.RLE: res.AddRange(RLE.Compress(input)); return(res.ToArray()); case Method.LZ40: res.AddRange(LZ40.Compress(input)); return(res.ToArray()); case Method.LZ60: //yes, LZ60 does indeed seem to be the exact same as LZ40 res.AddRange(LZ40.Compress(input)); return(res.ToArray()); default: return(input.StructToBytes()); } }
public static byte[] Decompress(Stream input) { using (var br = new BinaryReaderX(input, true)) { var methodSize = br.ReadUInt32(); var method = (Method)(methodSize & 0xff); int size = (int)((methodSize & 0xffffff00) >> 8); using (var brB = new BinaryReaderX(new MemoryStream(br.ReadBytes((int)input.Length - 4)))) switch (method) { case Method.LZ10: return(LZ10.Decompress(brB.BaseStream, size)); case Method.LZ11: return(LZ11.Decompress(brB.BaseStream, size)); case Method.Huff4: return(Huffman.Decompress(brB.BaseStream, 4, size, ByteOrder.BigEndian)); case Method.Huff8: return(Huffman.Decompress(brB.BaseStream, 8, size)); case Method.RLE: return(RLE.Decompress(brB.BaseStream, size)); case Method.LZ40: return(LZ40.Decompress(brB.BaseStream, size)); case Method.LZ60: //yes, LZ60 does indeed seem to be the exact same as LZ40 return(LZ40.Decompress(brB.BaseStream, size)); default: br.BaseStream.Position -= 4; return(br.BaseStream.StructToBytes()); } } }