Beispiel #1
0
        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());
            }
        }
Beispiel #2
0
        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());
                    }
            }
        }
Beispiel #3
0
        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.LZ60:
                        throw new Exception("LZ60 isn't implemented yet");

                    //return LZ60.Decompress(brB.BaseStream);
                    default:
                        br.BaseStream.Position -= 4;
                        return(br.BaseStream.StructToBytes());
                    }
            }
        }
Beispiel #4
0
        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}!");
            }
        }