IarImage CombineImage(IarImage overlay, IarArchive iarc) { using (var input = new BinMemoryStream(overlay.Data)) { var dir = (List <Entry>)iarc.Dir; int base_index = input.ReadInt32(); if (base_index >= dir.Count) { throw new InvalidFormatException("Invalid base image index"); } int diff_y = input.ReadInt32(); int diff_count = input.ReadInt32(); var overlay_info = overlay.Info; int pixel_size = overlay_info.BPP / 8; var base_image = new IarImage(iarc, dir[base_index]); byte[] output = base_image.Data; if (overlay_info.Height != base_image.Info.Height || overlay_info.Stride != base_image.Info.Stride) { int src_height = (int)Math.Min(overlay_info.Height, base_image.Info.Height); int src_stride = Math.Min(overlay_info.Stride, base_image.Info.Stride); byte[] src = base_image.Data; output = new byte[overlay_info.Height * overlay_info.Stride]; int dst_pos = 0; if (base_image.Info.OffsetY < overlay_info.OffsetY) { dst_pos += (-base_image.Info.OffsetY + overlay_info.OffsetY) * overlay_info.Stride; } if (base_image.Info.OffsetX < overlay_info.OffsetX) { dst_pos += (-base_image.Info.OffsetX + overlay_info.OffsetX) * pixel_size; } for (int y = 0; y < src_height; ++y) { Buffer.BlockCopy(src, y * base_image.Info.Stride, output, dst_pos, src_stride); dst_pos += overlay_info.Stride; } } int dst = diff_y * overlay_info.Stride; for (int i = 0; i < diff_count; ++i) { int chunk_count = input.ReadUInt16(); int x = 0; for (int j = 0; j < chunk_count; ++j) { int skip_count = pixel_size * input.ReadUInt16(); int copy_count = pixel_size * input.ReadUInt16(); x += skip_count; input.Read(output, dst + x, copy_count); x += copy_count; } dst += overlay_info.Stride; } return(new IarImage(overlay_info, output, overlay.Palette)); } }
/// <summary> // Try to parse file containing game meta-information. /// </summary> internal string TryParseMeta(string meta_arc_name) { if (!VFS.FileExists(meta_arc_name)) { return(null); } using (var unpacker = new TocUnpacker(meta_arc_name)) { if (unpacker.Length > 0x1000) { return(null); } var data = unpacker.Unpack(8); if (null == data) { return(null); } using (var content = new BinMemoryStream(data)) { int title_length = content.ReadInt32(); if (title_length <= 0 || title_length > content.Length) { return(null); } var title = content.ReadBytes(title_length); if (title.Length != title_length) { return(null); } return(Encodings.cp932.GetString(title)); } } }
public void UnpackAlpha(int offset) { using (var input = new BinMemoryStream(this.Input, offset, Input.Length - offset)) { if (1 != input.ReadInt32()) { return; } int dst = 3; int ctl = 1 << 1; while (dst < Output.Length) { ctl >>= 1; if (1 == ctl) { ctl = input.ReadUInt8() | 0x100; } if (0 != (ctl & 1)) { int v = input.ReadUInt16(); int x = v & 0x3F; if (x > 0x1F) { x |= -0x40; } int y = (v >> 6) & 7; if (y != 0) { y |= -8; } int count = ((v >> 9) & 0x7F) + 3; int src = dst + (x + y * Width) * 4; if (src < 0 || src >= dst) { return; } for (int i = 0; i < count; ++i) { Output[dst] = Output[src]; src += 4; dst += 4; } } else { Output[dst] = input.ReadUInt8(); dst += 4; } } HasAlpha = true; } }
public override ArcFile TryOpen(ArcView file) { if ((file.View.ReadInt32(0) | file.View.ReadInt32(4) | file.View.ReadInt32(8)) != 0) { return(null); } int key = file.View.ReadInt32(0x10); int count = file.View.ReadInt32(0x14); if (!IsSaneCount(count)) { return(null); } uint index_offset = 0x18; var index = new Dictionary <int, Entry> (count); for (int i = 0; i < count; ++i) { int id = file.View.ReadInt32(index_offset); var entry = new Entry { Offset = file.View.ReadUInt32(index_offset + 4), Size = file.View.ReadUInt32(index_offset + 8), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } index[id] = entry; index_offset += 12; } var names_entry = index[0]; var names = file.View.ReadBytes(names_entry.Offset, names_entry.Size); if (key != 0) { DecryptData(names, key); } using (var input = new BinMemoryStream(names)) { while (input.PeekByte() != -1) { int id = input.ReadInt32(); var name = input.ReadCString(); if (!string.IsNullOrEmpty(name)) { var entry = index[id]; entry.Name = name; entry.Type = FormatCatalog.Instance.GetTypeFromName(name); } } } var dir = index.Values.Where(e => !string.IsNullOrEmpty(e.Name)).ToList(); return(new YkArchive(file, this, dir, key)); }
void LoadBlob(AssetReader reader) { int count = reader.ReadInt32(); int buffer_bytes = reader.ReadInt32(); var node_data = reader.ReadBytes(24 * count); m_data = reader.ReadBytes(buffer_bytes); var parents = new Stack <TypeTree>(); parents.Push(this); using (var buf = new BinMemoryStream(node_data)) { for (int i = 0; i < count; ++i) { int version = buf.ReadInt16(); int depth = buf.ReadUInt8(); TypeTree current; if (0 == depth) { current = this; } else { while (parents.Count > depth) { parents.Pop(); } current = new TypeTree(m_format); parents.Peek().Children.Add(current); parents.Push(current); } current.Version = version; current.IsArray = buf.ReadUInt8() != 0; current.Type = GetString(buf.ReadInt32()); current.Name = GetString(buf.ReadInt32()); current.Size = buf.ReadInt32(); current.Index = buf.ReadUInt32(); current.Flags = buf.ReadInt32(); } } }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "ARC\0")) { return(null); } uint data_offset = file.View.ReadUInt32(8); uint unpacked_size = file.View.ReadUInt32(0xC); uint packed_size = file.View.ReadUInt32(0x10); byte[] unpacked = new byte[unpacked_size]; using (var packed = file.CreateStream(0x14, packed_size)) using (var input = new XoredStream(packed, 0xFF)) { LzssUnpack(input, unpacked); } using (var index = new BinMemoryStream(unpacked)) { var key = index.ReadBytes(256); int count = index.ReadInt32(); if (!IsSaneCount(count)) { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); var name = index.ReadCString(name_length); var entry = FormatCatalog.Instance.Create <GmlEntry> (name); entry.Offset = index.ReadUInt32() + data_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); entry.Header = index.ReadBytes(4); } return(new GmlArchive(file, this, dir, key)); } }
IarImage CombineLayers(IarImage layers, IarArchive iarc) { layers.Info.Stride = (int)layers.Info.Width * 4; layers.Info.BPP = 32; var pixels = new byte[layers.Info.Stride * (int)layers.Info.Height]; var output = new IarImage(layers.Info, pixels); using (var input = new BinMemoryStream(layers.Data)) { int offset_x = 0, offset_y = 0; var dir = (List <Entry>)iarc.Dir; while (input.Position < input.Length) { int cmd = input.ReadUInt8(); switch (cmd) { case 0x21: offset_x += input.ReadInt16(); offset_y += input.ReadInt16(); break; case 0x00: case 0x20: { int index = input.ReadInt32(); if (index < 0 || index >= dir.Count) { throw new InvalidFormatException("Invalid image layer index"); } var layer = new IarImage(iarc, dir[index]); layer.Info.OffsetX -= offset_x; layer.Info.OffsetY -= offset_y; if (0x20 == cmd) { output.ApplyMask(layer); } else { output.Blend(layer); } } break; default: Trace.WriteLine(string.Format("Unknown layer type 0x{0:X2}", cmd), "IAR"); break; } } return(output); } }
public override ArcFile TryOpen(ArcView file) { if (file.MaxOffset <= 12 || file.MaxOffset > uint.MaxValue) { return(null); } uint packed_size = file.View.ReadUInt32(file.MaxOffset - 12) ^ 0xF0F0F0F0; uint unpacked_size = file.View.ReadUInt32(file.MaxOffset - 8) ^ 0xF0F0F0F0; const uint entry_record_size = 0x50; int count = (int)(unpacked_size / entry_record_size); if (unpacked_size % entry_record_size != 0 || packed_size >= file.MaxOffset || !IsSaneCount(count)) { return(null); } var unpacked = new byte[unpacked_size]; using (var packed = file.CreateStream(file.MaxOffset - 12 - packed_size, packed_size)) LzUnpack(packed, unpacked); using (var index = new BinMemoryStream(unpacked)) { var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int flags = index.ReadInt32(); var name = index.ReadCString(0x40); var entry = FormatCatalog.Instance.Create <PmDatEntry> (name); entry.Offset = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.UnpackedSize = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } if (entry.Name.HasAnyOfExtensions("CRGB", "CHAR", "rol", "edg")) { entry.Type = "image"; } entry.IsPacked = (flags & 0xFF0000) != 0; entry.StoredSize = (flags & 0x2000000) != 0; dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
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; } } } }
public override ArcFile TryOpen(ArcView file) { if (!VFS.IsPathEqualsToFileName(file.Name, "AVGDatas.pck")) { return(null); } int seed = Binary.BigEndian(file.View.ReadInt32(file.MaxOffset - 104)); var header = file.View.ReadBytes(file.MaxOffset - 100, 100); var rnd = new RandomGenerator(); rnd.Init(seed); rnd.Decrypt(header, 0, header.Length); uint checksum = (uint)(header[1] | header[2] << 8 | header[0] << 16 | header[3] << 24) ^ 0xDEFD32D3; uint length = BigEndian.ToUInt32(header, 24); if (checksum != length) { return(null); } uint idx_pos = BigEndian.ToUInt32(header, 28); uint idx_size = Binary.BigEndian(file.View.ReadUInt32(idx_pos)); uint index_size; var index = ReadChunk(file, 8, idx_pos + 4, out index_size); if (index_size >= 0x80000000) { index_size &= 0x7FFFFFFF; var unpacked = new byte[idx_size]; LzssUnpack(index, index.Length, unpacked); index = unpacked; } using (var input = new BinMemoryStream(index)) { var dir = new List <Entry>(); int dir_count = 0; while (input.PeekByte() != -1) { input.ReadInt32(); input.ReadInt32(); input.ReadInt32(); int count = Binary.BigEndian(input.ReadInt32()); var dir_name = dir_count.ToString("X4"); for (int i = 0; i < count; ++i) { var name = input.ReadCString(0x28); name = Path.Combine(dir_name, name); var entry = Create <PckEntry> (name); entry.Offset = Binary.BigEndian(input.ReadUInt32()); entry.Size = Binary.BigEndian(input.ReadUInt32()); entry.IsEncrypted = input.ReadInt32() != 0; entry.UnpackedSize = input.ReadUInt32(); entry.IsPacked = entry.Size != entry.UnpackedSize; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } ++dir_count; } return(new ArcFile(file, this, dir)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".g00")) { return(null); } if (file.View.ReadByte(0) != 2) { return(null); } uint width = file.View.ReadUInt16(1); uint height = file.View.ReadUInt16(3); if (0 == width || width > 0x8000 || 0 == height || height > 0x8000) { return(null); } int count = file.View.ReadInt16(5); if (count <= 1 || count > 0x1000) { return(null); } var base_name = Path.GetFileNameWithoutExtension(file.Name); uint index_offset = 9; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = new G00Entry { Name = string.Format("{0}#{1:D3}", base_name, i), X = file.View.ReadInt32(index_offset), Y = file.View.ReadInt32(index_offset + 4), }; dir.Add(entry); index_offset += 0x18; } byte[] bitmap; using (var input = file.CreateStream(index_offset)) bitmap = G00Reader.LzDecompress(input, 2, 1); using (var input = new BinMemoryStream(bitmap)) { if (input.ReadInt32() != count) { return(null); } for (int i = 0; i < count; ++i) { dir[i].Offset = input.ReadUInt32(); dir[i].Size = input.ReadUInt32(); } } dir = dir.Where(e => e.Size != 0).ToList(); if (0 == dir.Count) { return(null); } var info = new ImageMetaData { Width = width, Height = height, BPP = 32 }; return(new G00Archive(file, this, dir, info, bitmap)); }