Ejemplo n.º 1
0
        private void previewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var menuItem = sender as ToolStripMenuItem;
            var source   = (menuItem.Owner as ContextMenuStrip).SourceControl as TreeView;

            DatFile df = source?.SelectedNode?.Tag as DatFile;

            tbInfo.Text     = null;
            tbRaw.Text      = null;
            tbAscii.Text    = null;
            pbPreview.Image = null;
            pbPreview.Tag   = null;

            // Select the clicked node
            if (df != null)
            {
                StringBuilder sbInfo  = new StringBuilder();
                StringBuilder sbRaw   = new StringBuilder();
                StringBuilder sbAscii = new StringBuilder();

                string extraInfo          = null;
                string contentDescription = null;

                byte[] actualContent = null;
                byte[] header1       = null;
                byte[] header2       = null;

                if (df.CompressionLevel == CompressionType.Default || df.CompressionLevel == CompressionType.Maximum)
                {
                    // for compressed files, the header is only an unknown dword
                    header1 = _database.GetData(df.FileOffset + 8, 4);
                    var compressed = _database.GetData(df.FileOffset + 12, (int)df.Size1);

                    try
                    {
                        actualContent = Ionic.Zlib.ZlibStream.UncompressBuffer(compressed);

                        // inside the compressed content is the file id (dword), and an unknown dword
                        // of a very low (<256, typically) value.
                        header2       = actualContent.Take(8).ToArray();
                        actualContent = actualContent.Skip(8).ToArray();
                        var compressionRatio = 100 * (decimal)compressed.Length / (decimal)actualContent.Length;
                        contentDescription = $"Content was compressed by {compressionRatio:#} percent.  Viewing decompressed content.";
                    }
                    catch (Exception ex)
                    {
                        byte[] fakeHeader = new byte[2];
                        contentDescription = "Unable to decompress content.  Showing raw content instead.";
                        header1            = new byte[0];
                        actualContent      = compressed;
                    }
                }
                else
                {
                    // for uncompressed files, the header is the file id (dword) and the file size (dword)
                    header1       = _database.GetData(df.FileOffset + 8, 8);
                    actualContent = _database.GetData(df.FileOffset + 16, (int)BitConverter.ToUInt32(header1, 4));
                }

                sbInfo.AppendLine("File ID: " + df.FileId.ToString("X8"));
                sbInfo.AppendLine("Offset: 0x" + df.FileOffset.ToString("X"));
                sbInfo.AppendLine("File Date: " + df.FileDate);
                sbInfo.AppendLine("Version: " + df.Version);
                sbInfo.AppendLine("Compression: " + df.CompressionLevel.ToString());
                sbInfo.AppendLine("File Size: " + df.Size1);
                sbInfo.AppendLine("Dat Space Consumed: " + df.Size2);
                sbInfo.AppendLine("Type: 0x" + df.FileType.ToString("X8"));
                sbInfo.AppendLine("Unknown 1: 0x" + df.Unknown1.ToString("X8"));
                sbInfo.AppendLine("Unknown 2: 0x" + df.Unknown2.ToString("X8"));

                var fileType = DatFile.GetActualFileType(actualContent);

                // raw data tab
                if (!string.IsNullOrWhiteSpace(contentDescription))
                {
                    sbRaw.AppendLine(contentDescription);
                }

                sbRaw.AppendLine().AppendLine($"File Header ({header1.Length} bytes)");
                sbRaw.AppendLine(header1.PrintBytes());

                if (header2 != null)
                {
                    sbRaw.AppendLine().AppendLine($"Compressed Header ({header2.Length} bytes)");
                    sbRaw.AppendLine(header2.PrintBytes());
                }

                sbRaw.AppendLine().AppendLine($"Content ({actualContent.Length} bytes)");
                sbRaw.AppendLine(actualContent.PrintBytes());

                // ascii tab
                sbAscii.AppendLine($"File Header ({header1.Length} bytes)");
                sbAscii.AppendLine(header1.PrintAsciiBytes());

                if (header2 != null)
                {
                    sbAscii.AppendLine().AppendLine($"Compressed Header ({header2.Length} bytes)");
                    sbAscii.AppendLine(header2.PrintAsciiBytes());
                }

                sbAscii.AppendLine().AppendLine($"Content ({actualContent.Length} bytes)");
                sbAscii.Append(actualContent.PrintAsciiBytes());

                switch (fileType)
                {
                case KnownFileType.DXT1:
                case KnownFileType.DXT3:
                case KnownFileType.DXT5:
                {
                    uint height = BitConverter.ToUInt32(actualContent, 0);
                    uint width  = BitConverter.ToUInt32(actualContent, 4);
                    try
                    {
                        var dds = DdsFile.ConvertFromDxt(fileType, actualContent.Skip(16).ToArray(), width, height);
                        pbPreview.Image = DdsFile.DdsToBmp((int)width, (int)height, dds);
                        pbPreview.Tag   = df;

                        sbInfo.AppendLine("Image Content available for preview (use Mouse Wheel to zoom).");
                    }
                    catch (Exception ex)
                    {
                        sbInfo.AppendLine("Image Content Detected but no preview is available.");
                    }
                    break;
                }
                break;
                }

                tbInfo.Text  = sbInfo.ToString();
                tbRaw.Text   = sbRaw.ToString();
                tbAscii.Text = sbAscii.ToString();
            }
        }