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[] Compress(Stream stream, Method method) { if (stream.Length > 0x1fffffff) { throw new Exception("File is too big to be compressed with Level5 compressions!"); } uint methodSize = (uint)stream.Length << 3; switch (method) { case Method.NoCompression: using (var bw = new BinaryWriterX(new MemoryStream())) { bw.Write(methodSize); stream.Position = 0; stream.CopyTo(bw.BaseStream); bw.BaseStream.Position = 0; return(new BinaryReaderX(bw.BaseStream).ReadBytes((int)bw.BaseStream.Length)); } case Method.LZ10: methodSize |= 0x1; using (var bw = new BinaryWriterX(new MemoryStream())) { bw.Write(methodSize); stream.Position = 0; var comp = LZ10.Compress(stream); bw.Write(comp); bw.BaseStream.Position = 0; return(new BinaryReaderX(bw.BaseStream).ReadBytes((int)bw.BaseStream.Length)); } case Method.Huffman4Bit: methodSize |= 0x2; using (var bw = new BinaryWriterX(new MemoryStream())) { bw.Write(methodSize); stream.Position = 0; var comp = Huffman.Compress(stream, 4); bw.Write(comp); bw.BaseStream.Position = 0; return(new BinaryReaderX(bw.BaseStream).ReadBytes((int)bw.BaseStream.Length)); } case Method.Huffman8Bit: methodSize |= 0x3; using (var bw = new BinaryWriterX(new MemoryStream())) { bw.Write(methodSize); stream.Position = 0; var comp = Huffman.Compress(stream, 8); bw.Write(comp); bw.BaseStream.Position = 0; return(new BinaryReaderX(bw.BaseStream).ReadBytes((int)bw.BaseStream.Length)); } case Method.RLE: methodSize |= 0x4; using (var bw = new BinaryWriterX(new MemoryStream())) { bw.Write(methodSize); stream.Position = 0; var comp = RLE.Compress(stream); bw.Write(comp); bw.BaseStream.Position = 0; return(new BinaryReaderX(bw.BaseStream).ReadBytes((int)bw.BaseStream.Length)); } default: throw new Exception($"Unsupported compression method {method}!"); } }