Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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;
        }
Example #8
0
        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);
        }