public LzxDecoderStream(Stream input, int decompressedSize, int compressedSize) { dec = new LzxDecoder(16); // TODO: Rewrite using block decompression like Lz4DecoderStream Decompress(input, decompressedSize, compressedSize); }
protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { decompressedStream.Dispose(); } dec = null; decompressedStream = null; }
static void DecodeImage(string basename) { var Lzx = new LzxDecoder(16); var Stream = new MemoryStream(File.ReadAllBytes(basename)); var Reader = new BinaryReader(Stream); Stream.Position = 6; var OutStream = DecompressLzx(Stream); Console.WriteLine(OutStream.Length); File.WriteAllBytes(basename + ".u", OutStream.ToArray()); #if true //OutStream.Position = 0x30A; //var Bitmap = DXT5.LoadSwizzled(OutStream, 0x40, 0x80, Swizzled: true); //Bitmap.Save(basename + ".u.png"); OutStream.Position = 0x37; var Reader2 = new BinaryReader(OutStream); var Format = Reader2.ReadInt32(); var Width = Reader2.ReadInt32(); var Height = Reader2.ReadInt32(); var Levels = Reader2.ReadInt32(); for (int Level = 0; Level < Levels; Level++) { OutStream.Position = 0x4B; //var Bitmap = new Bitmap(256, 512); //var Bitmap = new Bitmap(1024, 128); //var Bitmap = new Bitmap(512, 256); //var Bitmap = new Bitmap(1024, 1024); //var Bitmap = new Bitmap(128, 128); var Bitmap = new Bitmap(Width, Height); //var Bitmap = new Bitmap(64, 64); //var BitmapData = OutStream.ReadStructVector<RGBA>((uint)(Bitmap.Width * Bitmap.Height)); //var BitmapData = OutStream.ReadBytes(Bitmap.Width * Bitmap.Height * 4); int Size = Bitmap.Width * Bitmap.Height; for (int n = 0; n < Size; n++) { int x, y; Swizzling.UnswizzledXY(n, Bitmap.Width, 4, out x, out y); var RGBA = OutStream.ReadStruct <RGBA>(); Bitmap.SetPixel(x, y, Color.FromArgb(0xFF, RGBA.R, RGBA.G, RGBA.B)); } //var Bitmap = DXT5.LoadSwizzled(OutStream, 0x40, 0x80, Swizzled: true); //Bitmap.SetChannelsDataLinear(BitmapData, BitmapChannel.Red, BitmapChannel.Green, BitmapChannel.Blue, BitmapChannel.Alpha); //Bitmap.SetChannelsDataLinear(BitmapData, BitmapChannel.Alpha, BitmapChannel.Green, BitmapChannel.Blue, BitmapChannel.Red); Bitmap.Save(basename + ".u." + Level + ".png"); } #endif }
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); }
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; }
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; } } }
public string ExtractFile(string FileName) { var destination = Path.GetTempFileName(); // Do the extraction for (int volumeIndex = 0; volumeIndex < volumes.Count; volumeIndex++) { CabinetVolume volume = volumes.ElementAt(volumeIndex); LzxDecoder lzx = null; Inflater inf = null; if (volume.CabinetFileVolume.typeCompress == CFFOLDER.CFTYPECOMPRESS.TYPE_LZX) { lzx = new LzxDecoder(volume.CabinetFileVolume.typeCompressOption); } if (volume.CabinetFileVolume.typeCompress == CFFOLDER.CFTYPECOMPRESS.TYPE_MSZIP) { inf = new Inflater(true); } List <(CFDATA dataStruct, int dataOffsetCabinet, int beginFolderOffset, int endFolderOffset, int index)> datas = new List <(CFDATA dataStruct, int dataOffsetCabinet, int beginFolderOffset, int endFolderOffset, int index)>(); List <(CabinetVolumeFile file, int startingBlock, int startingBlockOffset, int endingBlock, int endingBlockOffset)> fileBlockMap = new List <(CabinetVolumeFile file, int startingBlock, int startingBlockOffset, int endingBlock, int endingBlockOffset)>(); // Build Data Map using (var cabinetFileStream = File.OpenRead(InputFile)) { var cabinetBinaryReader = new BinaryReader(cabinetFileStream); cabinetFileStream.Seek(volume.CabinetFileVolume.firstDataBlockOffset, SeekOrigin.Begin); int offset = 0; for (int i = 0; i < volume.CabinetFileVolume.dataBlockCount; i++) { CFDATA CabinetData = cabinetBinaryReader.BaseStream.ReadStruct <CFDATA>(); cabinetBinaryReader.BaseStream.Seek(cabinetHeader.DataAdditionalApplicationDataSize, SeekOrigin.Current); datas.Add((CabinetData, (int)cabinetBinaryReader.BaseStream.Position, offset, offset + CabinetData.cbUncomp - 1, i)); cabinetBinaryReader.BaseStream.Seek(CabinetData.cbData, SeekOrigin.Current); offset += CabinetData.cbUncomp; } // Build Block Map foreach (CabinetVolumeFile file in files) { if (file.CabinetFileVolumeFile.iFolder != volumeIndex) { continue; } var FirstBlock = datas.First(x => x.beginFolderOffset <= file.CabinetFileVolumeFile.uoffFolderStart && file.CabinetFileVolumeFile.uoffFolderStart <= x.endFolderOffset); var LastBlock = datas.First(x => x.beginFolderOffset <= (file.CabinetFileVolumeFile.uoffFolderStart + file.CabinetFileVolumeFile.cbFile - 1) && (file.CabinetFileVolumeFile.uoffFolderStart + file.CabinetFileVolumeFile.cbFile - 1) <= x.endFolderOffset); int fileBeginFolderOffset = (int)file.CabinetFileVolumeFile.uoffFolderStart; int fileEndFolderOffset = (int)file.CabinetFileVolumeFile.uoffFolderStart + (int)file.CabinetFileVolumeFile.cbFile - 1; int start = (int)file.CabinetFileVolumeFile.uoffFolderStart - FirstBlock.beginFolderOffset; int end = fileEndFolderOffset - LastBlock.beginFolderOffset; fileBlockMap.Add((file, FirstBlock.index, start, LastBlock.index, end)); } int fcount = 0; for (int i = 0; i < volume.CabinetFileVolume.dataBlockCount; i++) { var CabinetData = datas[i]; cabinetBinaryReader.BaseStream.Seek(CabinetData.dataOffsetCabinet, SeekOrigin.Begin); byte[] uncompressedDataBlock = new byte[CabinetData.dataStruct.cbUncomp]; byte[] compressedDataBlock = null; if (volume.CabinetFileVolume.typeCompress == CFFOLDER.CFTYPECOMPRESS.TYPE_MSZIP) { var magic = cabinetBinaryReader.ReadBytes(2); if (StructuralComparisons.StructuralComparer.Compare(magic, new byte[] { (byte)'C', (byte)'K' }) != 0) { throw new Exception("Bad Cabinet: Invalid Signature for MSZIP block"); } compressedDataBlock = cabinetBinaryReader.ReadBytes(CabinetData.dataStruct.cbData - 2); } else { compressedDataBlock = cabinetBinaryReader.ReadBytes(CabinetData.dataStruct.cbData); } using (var uncompressedDataBlockStream = new MemoryStream(uncompressedDataBlock)) using (var compressedDataBlockStream = new MemoryStream(compressedDataBlock)) { ExpandBlock(uncompressedDataBlockStream, compressedDataBlockStream, volume.CabinetFileVolume.typeCompress, lzx, inf); } foreach (CabinetVolumeFile file in files) { if (file.CabinetFileVolumeFile.iFolder != volumeIndex) { continue; } if (file.FileName.ToLower() != FileName.ToLower()) { continue; } var mapping = fileBlockMap.First(x => x.file.FileName == file.FileName); // This block contains this file if (mapping.startingBlock <= i && i <= mapping.endingBlock) { int start = 0; int end = CabinetData.dataStruct.cbUncomp - 1; bool IsFirstBlock = mapping.startingBlock == i; bool IsLastBlock = mapping.endingBlock == i; if (IsFirstBlock) { start = mapping.startingBlockOffset; } if (IsLastBlock) { end = mapping.endingBlockOffset; fcount++; } int count = end - start + 1; using (var uncompressedDataStream = File.Open(destination, FileMode.OpenOrCreate)) { uncompressedDataStream.Seek(0, SeekOrigin.End); uncompressedDataStream.Write(uncompressedDataBlock, start, count); } } } } } } return(destination); }
public LzxDecompressor(int window) { lzx = new LzxDecoder(window); }
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(); } }