// Decompress into MemoryStream private void Decompress(Stream stream, int decompressedSize, int compressedSize) { //thanks to ShinAli (https://bitbucket.org/alisci01/xnbdecompressor) // default window size for XNB encoded files is 64Kb (need 16 bits to represent it) decompressedStream = new MemoryStream(decompressedSize); long startPos = stream.Position; long pos = startPos; while (pos - startPos < compressedSize) { // the compressed stream is seperated into blocks that will decompress // into 32Kb or some other size if specified. // normal, 32Kb output blocks will have a short indicating the size // of the block before the block starts // blocks that have a defined output will be preceded by a byte of value // 0xFF (255), then a short indicating the output size and another // for the block size // all shorts for these cases are encoded in big endian order int hi = stream.ReadByte(); int lo = stream.ReadByte(); int block_size = (hi << 8) | lo; int frame_size = 0x8000; // frame size is 32Kb by default // does this block define a frame size? if (hi == 0xFF) { hi = lo; lo = (byte)stream.ReadByte(); frame_size = (hi << 8) | lo; hi = (byte)stream.ReadByte(); lo = (byte)stream.ReadByte(); block_size = (hi << 8) | lo; pos += 5; } else { pos += 2; } // either says there is nothing to decode if (block_size == 0 || frame_size == 0) { break; } dec.Decompress(stream, block_size, decompressedStream, frame_size); pos += block_size; // reset the position of the input just incase the bit buffer // read in some unused bytes stream.Seek(pos, SeekOrigin.Begin); } if (decompressedStream.Position != decompressedSize) { throw new InvalidDataException("Decompression failed."); } decompressedStream.Seek(0, SeekOrigin.Begin); }
private static Stream GetDecompressed(Stream stream, uint sizeCompressed) { LzxDecoder decoder = new LzxDecoder(16); Stream outStream = new MemoryStream(); long seekPos = stream.Position; while (stream.Position - 14 < sizeCompressed) { stream.Seek(seekPos, SeekOrigin.Begin); int a = stream.ReadByte(); int b = stream.ReadByte(); seekPos += 2; int chunk = 0x8000; int block = (a << 8) | b; if (a == 0xFF) { chunk = (b << 8) | stream.ReadByte(); block = (stream.ReadByte() << 8) | stream.ReadByte(); seekPos += 3; } if (chunk == 0 || block == 0) { break; } int err = decoder.Decompress(stream, block, outStream, chunk); if (err != 0) { break; } seekPos += block; } return(outStream); }
private void ExpandBlock(Stream uncompressedDataBlockStream, Stream compressedDataBlockStream, CFFOLDER.CFTYPECOMPRESS compressionType, LzxDecoder lzx, Inflater inf) { switch (compressionType) { case CFFOLDER.CFTYPECOMPRESS.TYPE_LZX: { lzx.Decompress(compressedDataBlockStream, (int)compressedDataBlockStream.Length, uncompressedDataBlockStream, (int)uncompressedDataBlockStream.Length); break; } case CFFOLDER.CFTYPECOMPRESS.TYPE_NONE: { compressedDataBlockStream.CopyTo(uncompressedDataBlockStream); break; } case CFFOLDER.CFTYPECOMPRESS.TYPE_MSZIP: { using (var br = new BinaryReader(compressedDataBlockStream)) using (var bw = new BinaryWriter(uncompressedDataBlockStream)) { byte[] inBuffer = br.ReadBytes((int)br.BaseStream.Length); inf.SetInput(inBuffer); byte[] outBuffer = new byte[bw.BaseStream.Length]; int ret = inf.Inflate(outBuffer); if (ret == 0) { throw new Exception("Inflate failed"); } bw.Write(outBuffer); inf.Reset(); } break; } } }
protected new T ReadAsset <T>(string assetName, Action <IDisposable> recordDisposableObject, object existingPrimaryObject = null) where T : class { if (string.IsNullOrEmpty(assetName)) { throw new ArgumentNullException("assetName"); } object obj = null; using (Stream stream = this.OpenStream(assetName)) { using (BinaryReader binaryReader = new BinaryReader(stream)) { byte b = binaryReader.ReadByte(); byte b2 = binaryReader.ReadByte(); byte b3 = binaryReader.ReadByte(); byte b4 = binaryReader.ReadByte(); if (b != 88 || b2 != 78 || b3 != 66 || (b4 != 119 && b4 != 120 && b4 != 109 && b4 != 112)) { throw new ContentLoadException("Asset does not appear to be a valid XNB file. Did you process your content for Windows?"); } byte b5 = binaryReader.ReadByte(); byte b6 = binaryReader.ReadByte(); bool flag = (b6 & 128) != 0; if (b5 != 5 && b5 != 4) { throw new ContentLoadException("Invalid XNB version"); } int num = binaryReader.ReadInt32(); ContentReader contentReader; if (flag) { LzxDecoder lzxDecoder = new LzxDecoder(16); int num2 = num - 14; int num3 = binaryReader.ReadInt32(); int num4 = num3 + 10; MemoryStream memoryStream = new MemoryStream(num3); int num5 = 0; int i = 0; while (i < num2) { stream.Seek((long)(i + 14), SeekOrigin.Begin); int num6 = stream.ReadByte(); int num7 = stream.ReadByte(); int num8 = num6 << 8 | num7; int num9 = 32768; if (num6 == 255) { num6 = num7; num7 = (int)((byte)stream.ReadByte()); num9 = (num6 << 8 | num7); num6 = (int)((byte)stream.ReadByte()); num7 = (int)((byte)stream.ReadByte()); num8 = (num6 << 8 | num7); i += 5; } else { i += 2; } if (num8 == 0 || num9 == 0) { break; } int num10 = lzxDecoder.Decompress(stream, num8, memoryStream, num9); i += num8; num5 += num9; } if (memoryStream.Position != (long)num3) { throw new ContentLoadException("Decompression of " + assetName + "failed. Try decompressing with nativeDecompressXnb first."); } memoryStream.Seek(0L, SeekOrigin.Begin); contentReader = new ContentReader(this, memoryStream, null, assetName); } else { Console.WriteLine("Reading: " + assetName + ".dds"); contentReader = new ContentReader(this, stream, null, assetName); } using (contentReader) { obj = contentReader.ReadAsset <T>(assetName); } } } return((T)((object)obj)); }
public static object ReadObject(GraphicsDevice device, string path) { BinaryFileReader reader = Serialize.OpenReader(path); byte[] magic = reader.ReadBytes(4); byte xnb_format_version = reader.ReadByte(); // 5 = XNA GS 4.0 byte flag_bits = reader.ReadByte(); bool isCompressed = ((flag_bits & 0x80) == 0x80); int file_size_on_disk = reader.ReadInt(); // size of file, including the header block if (isCompressed) { int file_size_decompressed = reader.ReadInt(); // does not include size of header block (14 bytes) MemoryStream decompressedStream = null; // default window size for XNB encoded files is 64Kb (need 16 bits to represent it) LzxDecoder lzx = new LzxDecoder(16); decompressedStream = new MemoryStream(file_size_decompressed); int compressedSize = file_size_on_disk - 14; long startPos = reader.Position; long pos = startPos; while (pos - startPos < compressedSize) { // the compressed stream is seperated into blocks that will decompress // into 32Kb or some other size if specified. // normal, 32Kb output blocks will have a short indicating the size // of the block before the block starts // blocks that have a defined output will be preceded by a byte of value // 0xFF (255), then a short indicating the output size and another // for the block size // all shorts for these cases are encoded in big endian order int hi = reader.ReadByte(); int lo = reader.ReadByte(); int block_size = (hi << 8) | lo; int frame_size = 0x8000; // frame size is 32Kb by default // does this block define a frame size? if (hi == 0xFF) { hi = lo; lo = (byte)reader.ReadByte(); frame_size = (hi << 8) | lo; hi = (byte)reader.ReadByte(); lo = (byte)reader.ReadByte(); block_size = (hi << 8) | lo; pos += 5; } else pos += 2; // either says there is nothing to decode if (block_size == 0 || frame_size == 0) break; lzx.Decompress(reader.Stream, block_size, decompressedStream, frame_size); pos += block_size; // reset the position of the input just incase the bit buffer // read in some unused bytes reader.Seek(pos, SeekOrigin.Begin); } if (decompressedStream.Position != file_size_decompressed) { Logging.Fatal("Decompression of " + path + " failed. "); } decompressedStream.Seek(0, SeekOrigin.Begin); reader = new BinaryFileReader(new BinaryReader(decompressedStream)); } List<Encoder> encoders = InternalGetEncoders(device, reader); int shared_resource_count = reader.Read7BitEncodedInt(); Object value = InternalReadObject(device, reader, encoders); reader.Close(); return value; }
public int Decompress(Stream inData, int inLen, Stream outData, int outLen) { return(lzx.Decompress(inData, inLen, outData, outLen)); }
static MemoryStream DecompressLzx(Stream input) { var reader = new BinaryReader(input); long num = reader.ReadInt32(); // ... let's decompress it! // get the decompressed size (num is our compressed size) int decompressedSize = reader.ReadInt32(); Console.WriteLine("{0} / {1}", num, decompressedSize); // create a memory stream of that size MemoryStream output = new MemoryStream(decompressedSize); // save our initial position long pos = input.Position; // default window size for XNB encoded files is 64Kb (need 16 bits to represent it) LzxDecoder decoder = new LzxDecoder(16); // start our decode process while (pos < num) { // the compressed stream is seperated into blocks that will decompress // into 32Kb or some other size if specified. // normal, 32Kb output blocks will have a short indicating the size // of the block before the block starts // blocks that have a defined output will be preceded by a byte of value // 0xFF (255), then a short indicating the output size and another // for the block size // all shorts for these cases are encoded in big endian order int hi, lo, block_size, frame_size; // let's get the first byte hi = reader.ReadByte(); // does this block define a frame size? if (hi == 0xFF) { // get our bytes hi = reader.ReadByte(); lo = reader.ReadByte(); // make a beautiful short baby together frame_size = (hi << 8) | lo; // let's read the block size hi = reader.ReadByte(); lo = reader.ReadByte(); block_size = (hi << 8) | lo; // add the read in bytes to the position pos += 5; } else { // just block size, so let's read the rest lo = reader.ReadByte(); block_size = (hi << 8) | lo; // frame size is 32Kb by default frame_size = 32768; // add the read in bytes to the position pos += 2; } Console.WriteLine("{0} - {1}", block_size, frame_size); // either says there is nothing to decode if (block_size == 0 || frame_size == 0) //if (frame_size == 0) { break; } // let's decompress the sucker decoder.Decompress(input, block_size, output, frame_size); // let's increment the input position by the block size pos += block_size; // reset the position of the input just incase the bit buffer // read in some unused bytes input.Seek(pos, SeekOrigin.Begin); } return(output); }
public static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: UnXNB.exe effectFile.xnb"); } for (int i = 0; i < args.Length; i += 1) { MemoryStream decompressedStream; using (Stream fileIn = File.OpenRead(args[i])) using (BinaryReader reader = new BinaryReader(fileIn)) { if (reader.ReadByte() != 'X' || reader.ReadByte() != 'N' || reader.ReadByte() != 'B' || reader.ReadByte() != 'w') { Console.WriteLine("Not an XNB file!"); continue; } byte version = reader.ReadByte(); if (version != 5 && version != 4) { Console.WriteLine("XNB version too old"); continue; } if ((reader.ReadByte() & 0x80) == 0) { reader.ReadInt32(); // file size reader.ReadByte(); // 7-bit encoded int int strlen = reader.ReadByte(); int skip = reader.ReadByte(); reader.ReadBytes(strlen); reader.ReadBytes(skip); reader.ReadByte(); // ??? reader.ReadInt32(); // ??? int length = reader.ReadInt32(); reader.ReadInt32(); // ??? int offset = reader.ReadInt32(); reader.ReadBytes(offset - 8); // ??? File.WriteAllBytes( Path.GetFileNameWithoutExtension(args[i]) + ".fxb", reader.ReadBytes(length - offset) ); continue; } int compressedSize = reader.ReadInt32(); int decompressedSize = reader.ReadInt32(); int decodedBytes = 0; long startPos = fileIn.Position; long pos = startPos; LzxDecoder decoder = new LzxDecoder(16); decompressedStream = new MemoryStream(decompressedSize); while (pos - startPos < compressedSize) { int hi = reader.ReadByte(); int lo = reader.ReadByte(); int blockSize = (hi << 8) | lo; int frameSize = 0x8000; if (hi == 0xFF) { hi = lo; lo = reader.ReadByte(); frameSize = (hi << 8) | lo; hi = reader.ReadByte(); lo = reader.ReadByte(); blockSize = (hi << 8) | lo; pos += 5; } else { pos += 2; } if (blockSize == 0 || frameSize == 0) { break; } decoder.Decompress( fileIn, blockSize, decompressedStream, frameSize ); pos += blockSize; decodedBytes += frameSize; fileIn.Seek(pos, SeekOrigin.Begin); } if (decompressedStream.Position != decompressedSize) { Console.WriteLine("Decompression failure!"); decompressedStream.Close(); continue; } } // Write to file, cutting out initial XNA crap decompressedStream.Seek(0, SeekOrigin.Begin); using (BinaryReader trim = new BinaryReader(decompressedStream)) { trim.ReadByte(); // 7-bit encoded int trim.ReadString(); // Type info trim.ReadUInt32(); // Version? trim.ReadByte(); // 7-bit encoded int trim.ReadByte(); // 7-bit encoded int int length = trim.ReadInt32(); trim.ReadInt32(); // ??? int offset = trim.ReadInt32(); trim.ReadBytes(offset - 8); // ??? File.WriteAllBytes( Path.GetFileNameWithoutExtension(args[i]) + ".fxb", trim.ReadBytes(length - offset) ); } decompressedStream.Close(); } }