void UnpackV2() { Format = PixelFormats.Bgra32; int tile_count = m_input.ReadInt32(); var tiles = new List <Tile> (tile_count); for (int i = 0; i < tile_count; ++i) { var tile = new Tile(); tile.X = m_input.ReadInt32(); tile.Y = m_input.ReadInt32(); tiles.Add(tile); m_input.Seek(0x10, SeekOrigin.Current); } using (var input = new BinMemoryStream(LzDecompress(m_input, 2, 1))) { if (input.ReadInt32() != tile_count) { throw new InvalidFormatException(); } int dst_stride = m_width * 4; m_output = new byte[m_height * dst_stride]; for (int i = 0; i < tile_count; ++i) { tiles[i].Offset = input.ReadUInt32(); tiles[i].Length = input.ReadInt32(); } var tile = tiles.First(t => t.Length != 0); input.Position = tile.Offset; int tile_type = input.ReadUInt16(); int count = input.ReadUInt16(); if (tile_type != 1) { throw new InvalidFormatException(); } input.Seek(0x70, SeekOrigin.Current); for (int i = 0; i < count; ++i) { int tile_x = input.ReadUInt16(); int tile_y = input.ReadUInt16(); input.ReadInt16(); int tile_width = input.ReadUInt16(); int tile_height = input.ReadUInt16(); input.Seek(0x52, SeekOrigin.Current); tile_x += tile.X; tile_y += tile.Y; if (tile_x + tile_width > m_width || tile_y + tile_height > m_height) { throw new InvalidFormatException(); } int dst = tile_y * dst_stride + tile_x * 4; int tile_stride = tile_width * 4; for (int row = 0; row < tile_height; ++row) { input.Read(m_output, dst, tile_stride); dst += dst_stride; } } } }