Exemplo n.º 1
0
        public static byte[] Compress(byte[] decompressed, uint width, uint height, PegFormat format)
        {
            uint compressedSize = 0;

            Flags flags = 0;

            if (format == PegFormat.DXT1)
            {
                compressedSize = (uint)(decompressed.Length / 8);
                flags         |= Flags.DXT1;
            }
            else if (format == PegFormat.DXT3)
            {
                compressedSize = (uint)(decompressed.Length / 4);
                flags         |= Flags.DXT3;
            }
            else if (format == PegFormat.DXT5)
            {
                compressedSize = (uint)(decompressed.Length / 4);
                flags         |= Flags.DXT5;
            }

            flags |= Flags.ColourMetricUniform | Flags.ColourIterativeClusterFit;
            byte[] compressed = new byte[compressedSize];


            NativeMethods.CompressImage(decompressed, width, height, compressed, (int)flags);

            return(compressed);
        }
Exemplo n.º 2
0
 public static Bitmap RawDataToBitmap(byte[] rawData, PegFormat format, ushort width, ushort height)
 {
     if (format == PegFormat.PC_DXT1)
     {
         var decompressBuffer = Squish.Decompress(rawData, width, height, Squish.Flags.DXT1);
         return(MakeBitmapFromDXT(width, height, decompressBuffer, true));
     }
     else if (format == PegFormat.PC_DXT3)
     {
         var decompressBuffer = Squish.Decompress(rawData, width, height, Squish.Flags.DXT3);
         return(MakeBitmapFromDXT(width, height, decompressBuffer, true));
     }
     else if (format == PegFormat.PC_DXT5)
     {
         var decompressBuffer = Squish.Decompress(rawData, width, height, Squish.Flags.DXT5);
         return(MakeBitmapFromDXT(width, height, decompressBuffer, true));
     }
     else if (format == PegFormat.PC_8888)
     {
         return(MakeBitmapFromPc8888(width, height, rawData));
     }
     else
     {
         throw new Exception($"Unsupported PEG data format detected! {format.ToString()} is not yet supported.");
     }
 }
Exemplo n.º 3
0
        public static byte[] ByteSwap(byte[] data, PegFormat format)
        {
            byte[] output = new byte[data.Length];
            switch (format)
            {
            case PegFormat.DXT1:
                for (int i = 0; i < data.Length; i += 8)
                {
                    output[i]     = data[i + 1];
                    output[i + 1] = data[i];
                    output[i + 2] = data[i + 3];
                    output[i + 3] = data[i + 2];
                    output[i + 4] = data[i + 4];
                    output[i + 5] = data[i + 5];
                    output[i + 6] = data[i + 6];
                    output[i + 7] = data[i + 7];
                }
                break;

            case PegFormat.A8R8G8B8:
                for (int i = 0; i < data.Length; i += 4)
                {
                    output[i]     = data[i + 3];
                    output[i + 1] = data[i + 2];
                    output[i + 2] = data[i + 1];
                    output[i + 3] = data[i];
                }
                break;

            default:
                throw new Exception("Unhandled format: " + format.ToString());
            }

            return(output);
        }
Exemplo n.º 4
0
 public void Read(BinaryReader header)
 {
     data              = header.ReadUInt32();
     width             = header.ReadUInt16();
     height            = header.ReadUInt16();
     bitmap_format     = (PegFormat)header.ReadUInt16();
     source_width      = header.ReadUInt16();
     anim_tiles_width  = header.ReadUInt16();
     anim_tiles_height = header.ReadUInt16();
     num_frames        = header.ReadUInt16();
     flags             = header.ReadUInt16();
     filename          = header.ReadUInt32();
     source_height     = header.ReadUInt16();
     fps        = header.ReadByte();
     mip_levels = header.ReadByte();
     frame_size = header.ReadUInt32();
     next       = header.ReadUInt32();
     previous   = header.ReadUInt32();
     cache0     = header.ReadUInt32();
     cache1     = header.ReadUInt32();
 }
Exemplo n.º 5
0
        public static byte[] Decompress(byte[] compressed, uint width, uint height, PegFormat format)
        {
            byte[] decompressed = new byte[width * height * 4];
            Flags  flags        = 0;

            if (format == PegFormat.DXT1)
            {
                flags |= Flags.DXT1;
            }
            else if (format == PegFormat.DXT3)
            {
                flags |= Flags.DXT3;
            }
            else if (format == PegFormat.DXT5)
            {
                flags |= Flags.DXT5;
            }

            NativeMethods.DecompressImage(decompressed, width, height, compressed, (int)flags);

            return(decompressed);
        }
Exemplo n.º 6
0
        public static void ParseFrames(XmlNode framesNode, PegEntry entry)
        {
            foreach (XmlNode frameNode in framesNode.ChildNodes)
            {
                switch (frameNode.Name)
                {
                case "Frame":
                    PegFrame frame = new PegFrame();
                    foreach (XmlNode node in frameNode.ChildNodes)
                    {
                        switch (node.Name)
                        {
                        case "Width":
                            ushort.TryParse(node.InnerText, out frame.Width);
                            break;

                        case "Height":
                            ushort.TryParse(node.InnerText, out frame.Height);
                            break;

                        case "Format":
                            PegFormat format = (PegFormat)Enum.Parse(typeof(PegFormat), node.InnerText, true);
                            frame.Format = (ushort)format;
                            break;

                        case "Unknown0A":
                            ushort.TryParse(node.InnerText, out frame.Unknown0A);
                            break;

                        case "Unknown0C":
                            uint.TryParse(node.InnerText, out frame.Unknown0C);
                            break;

                        case "Unknown12":
                            uint.TryParse(node.InnerText, out frame.Unknown12);
                            break;

                        case "Unknown16":
                            uint.TryParse(node.InnerText, out frame.Unknown16);
                            break;

                        case "UnknownFlags1A":
                            ushort.TryParse(node.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out frame.UnknownFlags1A);
                            break;

                        case "Size":
                            uint.TryParse(node.InnerText, out frame.Size);
                            break;

                        case "Unknown20":
                            uint.TryParse(node.InnerText, out frame.Unknown20);
                            break;

                        case "Unknown24":
                            uint.TryParse(node.InnerText, out frame.Unknown24);
                            break;

                        case "Unknown28":
                            uint.TryParse(node.InnerText, out frame.Unknown28);
                            break;

                        case "Unknown2C":
                            uint.TryParse(node.InnerText, out frame.Unknown2C);
                            break;
                            //default:
                            //throw new Exception(String.Format("Encountered unknown XML element: {0}", node.Name));
                        }
                    }
                    entry.Frames.Add(frame);
                    break;

                default:
                    throw new Exception(String.Format("Encountered unknown XML element: {0}", frameNode.Name));
                }
            }
        }
Exemplo n.º 7
0
        public static void Repack(string descFilePath)
        {
            Console.WriteLine("Repacking {0}:", descFilePath);
            if (!File.Exists(descFilePath))
            {
                Console.WriteLine("peg_desc file does not exist: {0}", descFilePath);
                return;
            }

            string extension = Path.GetExtension(descFilePath);

            if (!(extension == ".peg_desc"))
            {
                Console.WriteLine("File is not a peg_desc file: {0}", descFilePath);
                return;
            }

            string descFolder = Path.GetDirectoryName(descFilePath);

            Console.Write("Loading Peg Description... ");
            PegFile pegFile = XmlParser.ParseFile(descFilePath);

            if (pegFile == null)
            {
                Console.WriteLine("An error occurred while loading the peg_desc file.");
                return;
            }
            Console.WriteLine("done.");

            Console.WriteLine("Loading texture data, performing colour space conversions and compressing data:");
            Dictionary <PegFrame, byte[]> rawFrameData = new Dictionary <PegFrame, byte[]>();

            uint   totalSize   = 0;
            ushort totalFrames = 0;

            foreach (PegEntry entry in pegFile.Entries)
            {
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    PegFrame frame = entry.Frames[i];
                    Console.Write(" - {0} (frame {1})... ", entry.Name, i);
                    frame.Frames = (ushort)((i == 0) ? entry.Frames.Count : 1);
                    frame.Offset = totalSize;
                    PegFormat format  = (PegFormat)frame.Format;
                    byte[]    rawData = null;

                    string rawFilePath = Path.Combine(descFolder, String.Format("{0}_{1}.raw", entry.Name, i));
                    string filePath    = Path.Combine(descFolder, String.Format("{0}_{1}.png", entry.Name, i));

                    if (File.Exists(rawFilePath))
                    {
                        Console.Write("loading from {0}... ", rawFilePath);
                        FileStream rawFileStream = new FileStream(rawFilePath, FileMode.Open, FileAccess.Read, FileShare.None);
                        rawData = new byte[rawFileStream.Length];
                        rawFileStream.Read(rawData, 0, rawData.Length);
                        rawFileStream.Close();
                        Console.WriteLine("done.");
                    }
                    else
                    {
                        Console.Write("importing from {0}... ", filePath);
                        if (!File.Exists(filePath))
                        {
                            Console.WriteLine("Unable to find file: {0}", filePath);
                            Console.WriteLine("Make sure all your texture files are in the correct location and correctly named.");
                            return;
                        }

                        Bitmap srcBitmap = new Bitmap(filePath);
                        switch (format)
                        {
                        case PegFormat.DXT1:
                        case PegFormat.DXT3:
                        case PegFormat.DXT5:
                            rawData = GetRawA8R8G8B8DataFromBitmap(srcBitmap);
                            ImageFormats.SwapRedAndBlue((uint)srcBitmap.Width, (uint)srcBitmap.Height, ref rawData);
                            rawData = ImageFormats.Compress(rawData, (uint)srcBitmap.Width, (uint)srcBitmap.Height, format);
                            break;

                        case PegFormat.A8R8G8B8:
                            rawData = GetRawA8R8G8B8DataFromBitmap(srcBitmap);
                            break;

                        case PegFormat.R5G6B5:
                            Bitmap outBitmap = new Bitmap(srcBitmap.Width, srcBitmap.Height, PixelFormat.Format16bppRgb565);
                            srcBitmap.SetResolution(96, 96);
                            Graphics g = Graphics.FromImage(outBitmap);
                            g.CompositingMode    = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                            g.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                            g.DrawImage(srcBitmap, 0, 0, srcBitmap.Width, srcBitmap.Height);
                            g.Dispose();
                            Rectangle  lockArea   = new Rectangle(0, 0, outBitmap.Width, outBitmap.Height);
                            BitmapData bitmapData = outBitmap.LockBits(lockArea, ImageLockMode.ReadOnly, outBitmap.PixelFormat);
                            rawData = new byte[srcBitmap.Width * srcBitmap.Height * 2];
                            Marshal.Copy(bitmapData.Scan0, rawData, 0, rawData.Length);
                            outBitmap.UnlockBits(bitmapData);
                            outBitmap.Dispose();
                            break;

                        default:
                            throw new Exception("Unhandled format: " + format.ToString());
                        }

                        srcBitmap.Dispose();
                        Console.WriteLine("done.");
                    }
                    frame.Size = (uint)rawData.Length;
                    totalSize += frame.Size;
                    if (totalSize % 16 != 0)
                    {
                        uint difference = (uint)(Math.Ceiling((float)totalSize / 16f) * 16) - totalSize;
                        totalSize += difference;
                    }
                    totalFrames++;
                    entry.Frames[i] = frame;
                    rawFrameData.Add(frame, rawData);
                }
            }
            pegFile.DataFileSize = totalSize;
            Console.WriteLine("Finished loading texture data.");

            Console.Write("Writing peg_pc and g_peg_pc files...");
            string pegFilePath     = Path.ChangeExtension(descFilePath, "peg_pc");
            string pegDataFilePath = Path.ChangeExtension(descFilePath, "g_peg_pc");

            FileStream pegFileStream     = new FileStream(pegFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
            FileStream pegDataFileStream = new FileStream(pegDataFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            pegFileStream.WriteU32(0x564B4547);       // GEKV
            pegFileStream.WriteU16(10);               // Version
            pegFileStream.WriteU16(pegFile.Unknown06);
            pegFileStream.WriteU32(pegFile.FileSize); // Length - we come back and fill this in later
            pegFileStream.WriteU32(pegFile.DataFileSize);
            pegFileStream.WriteU16((ushort)pegFile.Entries.Count);
            pegFileStream.WriteU16(pegFile.Unknown12);
            pegFileStream.WriteU16(totalFrames);
            pegFileStream.WriteU16(pegFile.Unknown16);

            // Write entries
            pegFileStream.Seek(0x18, SeekOrigin.Begin);
            foreach (PegEntry entry in pegFile.Entries)
            {
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    PegFrame frame     = entry.Frames[i];
                    byte[]   frameData = StructureToByteArray(frame);
                    pegFileStream.Write(frameData, 0, frameData.Length);
                }
            }

            // Write names
            pegFileStream.Seek(0x18 + (0x30 * totalFrames), SeekOrigin.Begin);
            foreach (PegEntry entry in pegFile.Entries)
            {
                pegFileStream.WriteASCIIZ(entry.Name);
            }
            pegFileStream.Seek(0x08, SeekOrigin.Begin);
            pegFileStream.WriteU32((uint)pegFileStream.Length);
            pegFileStream.Flush();
            pegFileStream.Close();

            pegDataFileStream.SetLength(pegFile.DataFileSize);

            foreach (PegEntry entry in pegFile.Entries)
            {
                foreach (PegFrame frame in entry.Frames)
                {
                    pegDataFileStream.Seek(frame.Offset, SeekOrigin.Begin);
                    pegDataFileStream.Write(rawFrameData[frame], 0, (int)frame.Size);
                }
            }
            pegDataFileStream.Flush();
            pegDataFileStream.Close();

            Console.WriteLine("done.");

            Console.WriteLine();
            Console.WriteLine("Finished repacking.");
        }
Exemplo n.º 8
0
        public static void UnpackImages(PegFile pegFile, string path, Stream pegDataFileStream)
        {
            foreach (PegEntry entry in pegFile.Entries)
            {
                Console.WriteLine("Extracting {0} ({1} frame{2}):", entry.Name, entry.Frames.Count, (entry.Frames.Count == 1 ? "" : "s"));
                for (int i = 0; i < entry.Frames.Count; i++)
                {
                    string filePath    = Path.Combine(path, String.Format("{0}_{1}.png", entry.Name, i));
                    string rawFilePath = Path.Combine(path, String.Format("{0}_{1}.raw", entry.Name, i));
                    Console.Write(" - Extracting {0}... ", filePath);

                    PegFrame frame = entry.Frames[i];
                    pegDataFileStream.Seek(frame.Offset, SeekOrigin.Begin);
                    byte[] rawData = new byte[frame.Size];
                    pegDataFileStream.Read(rawData, 0, (int)frame.Size);

                    PegFormat format = (PegFormat)frame.Format;

                    FileStream rawFileStream = new FileStream(rawFilePath, FileMode.Create, FileAccess.Write, FileShare.None);
                    rawFileStream.Write(rawData, 0, rawData.Length);
                    rawFileStream.Flush();
                    rawFileStream.Close();

                    Bitmap bitmap = null;

                    switch (format)
                    {
                    case PegFormat.A8R8G8B8:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        bitmap = ImageFormats.MakeBitmapFromA8R8G8B8(frame.Width, frame.Height, rawData);
                        break;

                    case PegFormat.R5G6B5:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        bitmap = ImageFormats.MakeBitmapFromR5G6B5(frame.Width, frame.Height, rawData);
                        break;

                    case PegFormat.DXT1:
                        if (pegFile.BigEndian)
                        {
                            rawData = ImageFormats.ByteSwap(rawData, format);
                        }
                        byte[] decompressedDXT1 = ImageFormats.Decompress(rawData, frame.Width, frame.Height, format);
                        bitmap = ImageFormats.MakeBitmapFromDXT(frame.Width, frame.Height, decompressedDXT1, false);
                        break;

                    case PegFormat.DXT3:
                    case PegFormat.DXT5:
                        byte[] decompressed = ImageFormats.Decompress(rawData, frame.Width, frame.Height, format);
                        bitmap = ImageFormats.MakeBitmapFromDXT(frame.Width, frame.Height, decompressed, true);
                        break;

                    default:
                        throw new Exception("Unhandled format: " + format.ToString());
                    }

                    bitmap.Save(filePath, ImageFormat.Png);
                    bitmap.Dispose();

                    Console.WriteLine("done.");
                }
            }
        }
Exemplo n.º 9
0
        public static void WritePegDescription(PegFile pegFile, string pegDescFilePath)
        {
            XmlTextWriter writer = new XmlTextWriter(pegDescFilePath, Encoding.UTF8);

            writer.Formatting  = Formatting.Indented;
            writer.IndentChar  = '\t';
            writer.Indentation = 1;

            writer.WriteStartDocument();
            writer.WriteStartElement("PegDescription");

            // Header data
            writer.WriteElementString("BigEndian", pegFile.BigEndian.ToString());
            writer.WriteElementString("Magic", "GEKV");
            writer.WriteElementString("Version", "10");
            writer.WriteElementString("Unknown06", pegFile.Unknown06.ToString());
            writer.WriteElementString("FileSize", pegFile.FileSize.ToString());
            writer.WriteElementString("DataFileSize", pegFile.DataFileSize.ToString());
            writer.WriteElementString("EntryCount", pegFile.Entries.Count.ToString());
            writer.WriteElementString("Unknown12", pegFile.Unknown12.ToString());
            int frameCount = 0;

            foreach (PegEntry entry in pegFile.Entries)
            {
                frameCount += entry.Frames.Count;
            }
            writer.WriteElementString("FrameCount", frameCount.ToString());
            writer.WriteElementString("Unknown16", pegFile.Unknown16.ToString());

            writer.WriteStartElement("Entries");

            foreach (PegEntry entry in pegFile.Entries)
            {
                writer.WriteStartElement("Entry");
                writer.WriteElementString("Name", entry.Name);
                writer.WriteStartElement("Frames");
                foreach (PegFrame frame in entry.Frames)
                {
                    writer.WriteStartElement("Frame");
                    writer.WriteElementString("Offset", frame.Offset.ToString());
                    writer.WriteElementString("Width", frame.Width.ToString());
                    writer.WriteElementString("Height", frame.Height.ToString());
                    PegFormat frameFormat = (PegFormat)frame.Format;
                    writer.WriteElementString("Format", frameFormat.ToString());
                    writer.WriteElementString("Unknown0A", frame.Unknown0A.ToString());
                    writer.WriteElementString("Unknown0C", frame.Unknown0C.ToString());
                    writer.WriteElementString("Frames", frame.Frames.ToString());
                    writer.WriteElementString("Unknown12", frame.Unknown12.ToString());
                    writer.WriteElementString("Unknown16", frame.Unknown16.ToString());
                    writer.WriteElementString("UnknownFlags1A", frame.UnknownFlags1A.ToString("X4"));
                    writer.WriteElementString("Size", frame.Size.ToString());
                    writer.WriteElementString("Unknown20", frame.Unknown20.ToString());
                    writer.WriteElementString("Unknown24", frame.Unknown24.ToString());
                    writer.WriteElementString("Unknown28", frame.Unknown28.ToString());
                    writer.WriteElementString("Unknown2C", frame.Unknown2C.ToString());
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Close();
        }