예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }