public static Ctpk Create(string inputPath, string outputPath) { if (!Directory.Exists(inputPath)) { return(null); } Ctpk file = new Ctpk(); // Look for all xml definition files in the folder var files = Directory.GetFiles(inputPath, "*.xml", SearchOption.AllDirectories); foreach (var xmlFilename in files) { CTPKEntry entry = CTPKEntry.FromFile(xmlFilename, inputPath); file._entries.Add(entry); } for (int i = 0; i < file._entries.Count; i++) { file._entries[i].BitmapSizeOffset = (uint)((file._entries.Count + 1) * 8 + i); } using (BinaryWriter writer = new BinaryWriter(File.Open(outputPath, FileMode.Create))) { file.Write(writer); } Console.WriteLine("Finished! Saved to {0}", outputPath); return(file); }
public static CTPKEntry Read(BinaryReader reader) { CTPKEntry entry = new CTPKEntry(); var pathOffset = reader.ReadInt32(); entry.TextureSize = reader.ReadUInt32(); entry.TextureOffset = reader.ReadUInt32(); entry.Format = reader.ReadUInt32(); entry.Width = reader.ReadUInt16(); entry.Height = reader.ReadUInt16(); entry.MipLevel = reader.ReadByte(); entry.Type = reader.ReadByte(); entry.Unknown = reader.ReadUInt16(); entry.BitmapSizeOffset = reader.ReadUInt32(); entry.FileTime = reader.ReadUInt32(); #region Read path string var curOffset = reader.BaseStream.Position; reader.BaseStream.Seek(pathOffset, SeekOrigin.Begin); List <byte> temp = new List <byte>(); byte c = 0; while ((c = reader.ReadByte()) != 0) { temp.Add(c); } entry.InternalFilePath = Encoding.GetEncoding(932).GetString(temp.ToArray()); // 932 = Shift-JIS reader.BaseStream.Seek(curOffset, SeekOrigin.Begin); #endregion switch ((TextureFormat)entry.Format) { case TextureFormat.A4: case TextureFormat.A8: case TextureFormat.La4: case TextureFormat.Rgb5551: case TextureFormat.Rgba4: case TextureFormat.Rgba8: case TextureFormat.Etc1A4: entry.HasAlpha = true; break; default: entry.HasAlpha = false; break; } return(entry); }
public static CTPKEntry FromFile(string filename, string foldername) { if (!File.Exists(filename)) { return(new CTPKEntry()); } using (XmlTextReader reader = new XmlTextReader(filename)) { reader.WhitespaceHandling = WhitespaceHandling.All; XmlSerializer serializer = new XmlSerializer(typeof(CTPKEntry)); CTPKEntry entry = (CTPKEntry)serializer.Deserialize(reader); Console.WriteLine("Reading {0}...", entry.FilePath); // Import image file entry._textureData = new Texture(); var path = entry.FilePath; if (!String.IsNullOrWhiteSpace(foldername)) { path = Path.Combine(foldername, path); } var origbmp = Bitmap.FromFile(path); var pixelSize = 3; var bmpPixelFormat = PixelFormat.Format24bppRgb; entry.Format = (int)TextureFormat.Rgb8; entry.HasAlpha = true; if (entry.HasAlpha) { bmpPixelFormat = PixelFormat.Format32bppArgb; entry.Format = (int)TextureFormat.Rgba8; pixelSize = 4; } 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.Width = (ushort)bmp.Width; entry.Height = (ushort)bmp.Height; var scramble = new Texture().GetScrambledTextureData(bmp); var dataSize = bmp.Width * bmp.Height * pixelSize; entry.TextureRawData = new byte[dataSize]; entry.TextureSize = (uint)dataSize; Array.Copy(scramble, entry.TextureRawData, dataSize); entry.FileTime = (uint)File.GetLastWriteTime(path).Ticks; // This is right exactly? Not sure, don't think it matters either var filenameData = Encoding.GetEncoding(932).GetBytes(entry.InternalFilePath); entry.FilenameHash = Crc32.Calculate(filenameData, filenameData.Length); return(entry); } }
public static Ctpk Read(byte[] data, string inputPath, string outputPath, bool isRawExtract = false) { Ctpk file = new Ctpk(); using (MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid CTPK file."); } file.Version = reader.ReadUInt16(); file.NumberOfTextures = reader.ReadUInt16(); file.TextureSectionOffset = reader.ReadUInt32(); file.TextureSectionSize = reader.ReadUInt32(); file.HashSectionOffset = reader.ReadUInt32(); file.TextureInfoSection = reader.ReadUInt32(); // Section 1 + 3 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); CTPKEntry entry = CTPKEntry.Read(reader); entry.FileIndexA = file._entries.Count; file._entries.Add(entry); } // Section 2 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info = reader.ReadUInt32(); } // Section 4 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"); } } // Section 5 reader.BaseStream.Seek(file.TextureInfoSection, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info2 = reader.ReadUInt32(); } // Section 6 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(file.TextureSectionOffset + 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); }
public static CTPKEntry FromFile(string filename, string foldername) { if (!File.Exists(filename)) { return(new CTPKEntry()); } using (XmlTextReader reader = new XmlTextReader(filename)) { reader.WhitespaceHandling = WhitespaceHandling.All; XmlSerializer serializer = new XmlSerializer(typeof(CTPKEntry)); CTPKEntry entry = (CTPKEntry)serializer.Deserialize(reader); Console.WriteLine("Reading {0}...", entry.FilePath); var path = entry.FilePath; if (!String.IsNullOrWhiteSpace(foldername)) { path = Path.Combine(foldername, path); } /* * var pixelSize = 3; * var bmpPixelFormat = PixelFormat.Format24bppRgb; * entry.Format = (int)TextureFormat.Rgb8; * * entry.HasAlpha = true; * if (entry.HasAlpha) * { * bmpPixelFormat = PixelFormat.Format32bppArgb; * entry.Format = (int)TextureFormat.Rgba8; * pixelSize = 4; * } * * 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.Width = (ushort)bmp.Width; * entry.Height = (ushort)bmp.Height; * * var scramble = new Texture().GetScrambledTextureData(bmp); * var dataSize = bmp.Width * bmp.Height * pixelSize; * * entry.TextureRawData = new byte[dataSize]; * entry.TextureSize = (uint)dataSize; * Array.Copy(scramble, entry.TextureRawData, dataSize); */ 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 entry._textureData = new Texture(); var origbmp = Bitmap.FromFile(path); var bmpPixelFormat = PixelFormat.Format24bppRgb; if (entry.Format != (uint)TextureFormat.Rgba8 && entry.Format != (uint)TextureFormat.Rgb8 && entry.Format != (uint)TextureFormat.Rgb565 && entry.Format != (uint)TextureFormat.Rgba4 && entry.Format != (uint)TextureFormat.La8 && entry.Format != (uint)TextureFormat.Hilo8 && entry.Format != (uint)TextureFormat.L8 && entry.Format != (uint)TextureFormat.A8 && entry.Format != (uint)TextureFormat.Etc1 && entry.Format != (uint)TextureFormat.Etc1A4) { // Set everything that isn't one of the normal formats to Rgba8 entry.Format = (uint)TextureFormat.Rgba8; bmpPixelFormat = PixelFormat.Format32bppArgb; entry.HasAlpha = true; } else if (entry.Format == (uint)TextureFormat.Rgba8 || entry.Format == (uint)TextureFormat.Rgba4 || entry.Format == (uint)TextureFormat.La8 || entry.Format == (uint)TextureFormat.A8) { bmpPixelFormat = PixelFormat.Format32bppArgb; entry.HasAlpha = true; } else if (entry.Format == (uint)TextureFormat.Etc1A4) { bmpPixelFormat = PixelFormat.Format32bppArgb; entry.HasAlpha = true; } else { bmpPixelFormat = PixelFormat.Format24bppRgb; entry.HasAlpha = false; } 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.Width = (ushort)bmp.Width; entry.Height = (ushort)bmp.Height; entry.TextureRawData = Texture.FromBitmap(bmp, (TextureFormat)entry.Format, true); } entry.TextureSize = (uint)entry.TextureRawData.Length; entry.FileTime = (uint)File.GetLastWriteTime(path).Ticks; // This is right exactly? Not sure, don't think it matters either var filenameData = Encoding.GetEncoding(932).GetBytes(entry.InternalFilePath); entry.FilenameHash = Crc32.Calculate(filenameData, filenameData.Length); return(entry); } }
public static Ctpk Create(string inputPath, string outputPath, string _patchPath) { if (!Directory.Exists(inputPath)) { return(null); } string _goodInPath = makePathGood(inputPath); string _goodPatchPath = _patchPath != null?makePathGood(_patchPath) : null; Ctpk file = new Ctpk(); // Look for all xml definition files in the folder string[] _xmlFiles = Directory.GetFiles(_goodInPath, "*.xml", SearchOption.AllDirectories); string[] _xmlOverrides = new string[_xmlFiles.Length]; string[] _pngFiles = new string[_xmlFiles.Length]; Array.Clear(_pngFiles, 0, _pngFiles.Length); Array.Clear(_xmlOverrides, 0, _xmlOverrides.Length); if (_goodPatchPath != null) { string[] patchFiles = Directory.GetFiles(_goodPatchPath, "*", SearchOption.AllDirectories); // Merge patchFiles into files for (int j = 0; j < patchFiles.Length; ++j) { string _choppedName = Path.GetFileNameWithoutExtension(patchFiles[j]); int i; for (i = 0; i < _xmlFiles.Length; ++i) { if (Path.GetFileNameWithoutExtension(_xmlFiles[i]) == _choppedName) { if (Path.GetExtension(patchFiles[j]) == ".xml") { _xmlOverrides[i] = patchFiles[j]; } else { _pngFiles[i] = patchFiles[j]; } break; } } if (i == _xmlFiles.Length) { Console.WriteLine("Base path is " + _goodInPath); for (i = 0; i < _xmlFiles.Length; ++i) { Console.WriteLine(String.Format("{0} ({1})", _xmlFiles[i], Path.GetFileNameWithoutExtension(_xmlFiles[i]))); } throw new Exception(String.Format("Could not find replacement for {0} ({3}) from {1} to put in {2}", patchFiles[j], _goodPatchPath, _goodInPath, _choppedName)); } } } for (int i = 0; i < _xmlFiles.Length; ++i) { CTPKEntry entry; if (_xmlOverrides[i] != null) { entry = CTPKEntry.FromFile(_xmlOverrides[i], _goodInPath, _pngFiles[i]); if (entry == null) { entry = CTPKEntry.FromFile(_xmlFiles[i], _goodInPath, _pngFiles[i]); } } else { entry = CTPKEntry.FromFile(_xmlFiles[i], _goodInPath, _pngFiles[i]); } if (entry == null) { throw new Exception("failed to create ctpkentry"); } file._entries.Add(entry); } for (int i = 0; i < file._entries.Count; i++) { file._entries[i].BitmapSizeOffset = (uint)((file._entries.Count + 1) * 8 + i); } using (BinaryWriter writer = new BinaryWriter(File.Open(outputPath, FileMode.Create))) { file.Write(writer); } Console.WriteLine("Finished! Saved to {0}", outputPath); return(file); }
public static CTPKEntry Read(BinaryReader reader) { CTPKEntry entry = new CTPKEntry(); var pathOffset = reader.ReadInt32(); entry.TextureSize = reader.ReadUInt32(); entry.TextureOffset = reader.ReadUInt32(); entry.Format = reader.ReadUInt32(); entry.Width = reader.ReadUInt16(); entry.Height = reader.ReadUInt16(); entry.MipLevel = reader.ReadByte(); entry.Type = reader.ReadByte(); entry.Unknown = reader.ReadUInt16(); entry.BitmapSizeOffset = reader.ReadUInt32(); entry.FileTime = reader.ReadUInt32(); #region Read path string var curOffset = reader.BaseStream.Position; reader.BaseStream.Seek(pathOffset, SeekOrigin.Begin); List<byte> temp = new List<byte>(); byte c; while ((c = reader.ReadByte()) != 0) { temp.Add(c); } entry.InternalFilePath = Encoding.GetEncoding(932).GetString(temp.ToArray()); // 932 = Shift-JIS reader.BaseStream.Seek(curOffset, SeekOrigin.Begin); #endregion switch ((TextureFormat)entry.Format) { case TextureFormat.A4: case TextureFormat.A8: case TextureFormat.La4: case TextureFormat.Rgb5551: case TextureFormat.Rgba4: case TextureFormat.Rgba8: case TextureFormat.Etc1A4: entry.HasAlpha = true; break; default: entry.HasAlpha = false; break; } return entry; }
public static Ctpk Read(byte[] data, string filename) { Ctpk file = new Ctpk(); using (MemoryStream dataStream = new MemoryStream(data)) using (BinaryReader reader = new BinaryReader(dataStream)) { if (reader.ReadUInt32() != Magic) { Console.WriteLine("ERROR: Not a valid CTPK file."); } file.Version = reader.ReadUInt16(); file.NumberOfTextures = reader.ReadUInt16(); file.TextureSectionOffset = reader.ReadUInt32(); file.TextureSectionSize = reader.ReadUInt32(); file.HashSectionOffset = reader.ReadUInt32(); file.TextureInfoSection = reader.ReadUInt32(); // Section 1 + 3 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(0x20 * (i + 1), SeekOrigin.Begin); CTPKEntry entry = CTPKEntry.Read(reader); file._entries.Add(entry); } // Section 2 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info = reader.ReadUInt32(); } // Section 4 for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].FilenameHash = reader.ReadUInt32(); } // Section 5 reader.BaseStream.Seek(file.TextureInfoSection, SeekOrigin.Begin); for (int i = 0; i < file.NumberOfTextures; i++) { file._entries[i].Info2 = reader.ReadUInt32(); } // Section 6 for (int i = 0; i < file.NumberOfTextures; i++) { reader.BaseStream.Seek(file.TextureSectionOffset + 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); } string basePath = Path.GetDirectoryName(filename); string baseFilename = Path.GetFileNameWithoutExtension(filename); if (!String.IsNullOrWhiteSpace(basePath)) { baseFilename = Path.Combine(basePath, baseFilename); } for (int i = 0; i < file.NumberOfTextures; i++) { Console.WriteLine("Converting {0}...", file._entries[i].InternalFilePath); file._entries[i].ToFile(baseFilename); } } return(file); }