public static TxpEntry FromFile(string filename, string foldername) { if (!File.Exists(filename)) { return(new TxpEntry()); } using (XmlTextReader reader = new XmlTextReader(filename)) { reader.WhitespaceHandling = WhitespaceHandling.All; XmlSerializer serializer = new XmlSerializer(typeof(TxpEntry)); TxpEntry entry = (TxpEntry)serializer.Deserialize(reader); Console.WriteLine("Reading {0}...", entry.FilePath); var path = entry.FilePath; if (!String.IsNullOrWhiteSpace(foldername)) { path = Path.Combine(foldername, path); } if (entry.Raw) { using (BinaryReader bmp = new BinaryReader(File.Open(path, FileMode.Open))) { entry.TextureRawData = bmp.ReadBytes((int)bmp.BaseStream.Length); } } else { // Import image file var origbmp = Bitmap.FromFile(path); var bmpPixelFormat = PixelFormat.Format32bppRgb; // TODO: Do more work to figure out what the real output pixel format should be here var bmp = new Bitmap(origbmp.Width, origbmp.Height, bmpPixelFormat); using (Graphics gr = Graphics.FromImage(bmp)) { gr.DrawImage(origbmp, new Rectangle(0, 0, bmp.Width, bmp.Height)); } entry.Format = (uint)SceGxmTextureFormat.U8U8U8U8_ARGB; entry.Type = 0; // SceGxmTextureType.Linear entry.Width = (ushort)bmp.Width; entry.Height = (ushort)bmp.Height; var bmpdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); int numbytes = bmpdata.Stride * bmp.Height; IntPtr ptr = bmpdata.Scan0; entry.TextureRawData = new byte[numbytes]; Marshal.Copy(ptr, entry.TextureRawData, 0, numbytes); } entry.TextureSize = (uint)entry.TextureRawData.Length; var filenameData = Encoding.GetEncoding(932).GetBytes(entry.InternalFilePath); entry.FilenameHash = Crc32.Calculate(filenameData, filenameData.Length); return(entry); } }
public static Txp Read(byte[] data, string inputPath, string outputPath, bool isRawExtract = false) { Txp file = new Txp(); using (MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid TXP file."); } file.Version = reader.ReadInt32(); file.NumberOfTextures = reader.ReadInt32(); file.HashSectionOffset = reader.ReadUInt32(); // File info for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); TxpEntry entry = TxpEntry.Read(reader); entry.FileIndexA = file._entries.Count; file._entries.Add(entry); } // Filename hashes reader.BaseStream.Seek(file.HashSectionOffset, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].FilenameHash = reader.ReadUInt32(); int idx = reader.ReadInt32(); if (idx < file._entries.Count) { file._entries[idx].FileIndexB = i; } else { Console.WriteLine("ERROR(?): Found hash entry without a matching file entry"); } } // Image data for (int i = 0; i < file.NumberOfTextures; i++) { // Palette data if (file._entries[i].PaletteOffset != 0) { reader.BaseStream.Seek(file._entries[i].PaletteOffset, SeekOrigin.Begin); file._entries[i].PaletteData = new uint[0x100]; for (int x = 0; x < 0x100; x++) { file._entries[i].PaletteData[x] = reader.ReadUInt32(); } } reader.BaseStream.Seek(file._entries[i].TextureOffset, SeekOrigin.Begin); file._entries[i].TextureRawData = new byte[file._entries[i].TextureSize]; reader.Read(file._entries[i].TextureRawData, 0, (int)file._entries[i].TextureSize); } for (int i = 0; i < file.NumberOfTextures; i++) { Console.WriteLine("Converting {0}...", file._entries[i].InternalFilePath); file._entries[i].ToFile(outputPath, isRawExtract); } } return(file); }