public static Node[] GetNodes(byte[] bytes, string parent_file, AldFileEntry parent) { List <Node> list = new List <Node>(); using (var ms1 = new MemoryStream(bytes)) using (var brfile = new BinaryReader(ms1)) while (brfile.BaseStream.Position < brfile.BaseStream.Length) { long tag_start_offset = brfile.BaseStream.Position; var tag = (new Tag()).ReadTag(brfile); if (tag.TagName == "LIBL" && tag.TagLength > 16) { var dataBytes = tag.TagData; using (var ms = new MemoryStream(dataBytes)) using (var brtag = new BinaryReader(ms)) { int fileCount = brtag.ReadInt32(); //9 int dataLength = 0; string fileName = "alt_image.ajp"; for (int fileNumber = 0; fileNumber < fileCount; fileNumber++) { HexView.Debugger(dataBytes.Slice(brtag.BaseStream.Position, brtag.BaseStream.Position + 50)); uint fileNameLength = brtag.ReadUInt32(); //8 if (fileNameLength > 255) { continue; } var fileNameBytes = brtag.ReadBytes((int)fileNameLength); brtag.BaseStream.Position = ((brtag.BaseStream.Position - 1) | 3) + 1; fileName = shiftJis.GetString(fileNameBytes); if (parent_file != null) { fileName = Path.GetFileNameWithoutExtension(parent_file) + $"_image{fileNumber.ToString().PadLeft(1 + (int)System.Math.Log(fileCount, 10), '0')}"; } int type = brtag.ReadInt32(); dataLength = brtag.ReadInt32(); long libl_img_off = brtag.BaseStream.Position + tag_start_offset + 8; // 8 is (tag + size) HexView.Debugger(dataBytes.Slice(libl_img_off, libl_img_off + 20)); if (type == (int)DataType.FLAG_CG) { int unknown1 = brtag.ReadInt32(); // XXX: special case: CG usually (not always!) has extra int32 int maybe_head; if (unknown1 == 0x00544E51 || unknown1 == 0x00504A41) // QNT or AJP { maybe_head = unknown1; } else { maybe_head = brtag.ReadInt32(); } byte[] imageBytes = null; brtag.BaseStream.Position -= 4; if (maybe_head == 0x00544E51) //QNT needs the tag { libl_img_off -= 4; imageBytes = brtag.ReadBytes(dataLength); fileName += ".qnt"; } else if (maybe_head == 0x00504A41) //AJP needs the tag { libl_img_off -= 4; imageBytes = brtag.ReadBytes(dataLength); fileName += ".ajp"; } else // unknown image //imageBytes = brtag.ReadBytes(dataLength); { brtag.BaseStream.Position += dataLength; fileName += ".dat"; } if (imageBytes != null) { list.Add(new Node() { Bytes = imageBytes, FileName = fileName, Offset = libl_img_off, Parent = parent }); } } else { brtag.BaseStream.Position += dataLength; } brtag.BaseStream.Position = ((brtag.BaseStream.Position - 1) | 3) + 1 - 4; } // for } } // LIBL else if (tag.TagName == "TALT" && tag.TagLength > 16) { var dataBytes = tag.TagData; using (var ms = new MemoryStream(dataBytes)) using (var brtag = new BinaryReader(ms)) { int fileCount = brtag.ReadInt32(); //9 int dataLength = 0; string fileName = "alt_image.ajp"; for (int fileNumber = 0; fileNumber < fileCount; fileNumber++) { if (parent_file != null) { fileName = Path.GetFileNameWithoutExtension(parent_file) + $"_alt_image{fileNumber.ToString().PadLeft(System.Math.Max(0, (int)System.Math.Log(10, fileCount)) + 1, '0')}"; } dataLength = brtag.ReadInt32(); //9 //brtag.BaseStream.Position += dataLength; brtag.BaseStream.Position = ((brtag.BaseStream.Position - 1) | 3) + 1; int maybe_head = brtag.ReadInt32(); // long libl_img_off = brtag.BaseStream.Position + tag_start_offset + 8; HexView.Debugger(bytes.Slice(libl_img_off, libl_img_off + 20)); byte[] imageBytes = null; brtag.BaseStream.Position -= 4; if (maybe_head == 0x00544E51) //QNT needs the tag { libl_img_off -= 4; imageBytes = brtag.ReadBytes(dataLength); fileName += ".qnt"; } if (maybe_head == 0x00504A41) //AJP needs the tag { libl_img_off -= 4; imageBytes = brtag.ReadBytes(dataLength); fileName += ".ajp"; } else // unknown image //imageBytes = brtag.ReadBytes(dataLength); { brtag.BaseStream.Position += dataLength; fileName += ".dat"; } if (imageBytes != null) { list.Add(new Node() { Bytes = imageBytes, FileName = fileName, Offset = libl_img_off, Parent = parent }); } brtag.BaseStream.Position = ((brtag.BaseStream.Position - 1) | 3) + 1 - 4; } // for } } // TALT }// EndOfStream return(list.ToArray()); }