gpt4 book ai didi

c# - 如何确保 DirectDraw 表面具有正确的文件格式?

转载 作者:行者123 更新时间:2023-11-30 15:53:36 29 4
gpt4 key购买 nike

我需要做一个简单的检查 dds 文件的格式是否有效。我只需要对 dds 文件进行一般检查,所以我不需要检查它是否是 dxt1、dxt5、dx10 等。例如,如果我有一个 png 图像并且我将扩展名重命名为 .dds dds 格式当然会是错误的,然后我需要告诉用户他正在尝试使用格式错误的 dds 文件。但是,如果我有一个确实具有正确文件格式的 dds,我将不需要做任何进一步的调查,因为我不关心它是什么类型的 dds 文件(此时)。所以我只需要阅读 dds 文件中所有 dds 文件都保持不变的部分。我想我可以通过某种方式读取 dds header 和魔数(Magic Number)。我必须对 png 文件进行相同的验证,并且我正在读取 png 标题,如下所示:

    var png = new byte[] { 0x89, 0x50, 0x4e, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }
using (FileStream fs = new FileStream(fileToCheck, FileMode.Open, FileAccess.Read))
{
if (fs.Length > buffer.Length)
{
fs.Read(buffer, 0, buffer.Length);
fs.Position = (int)fs.Length - endBuffer.Length;
fs.Read(bufferEnd, 0, endBuffer.Length);
}

fs.Close();
}
for (int i = 0; i < png.Length; i++)
{
if (buffer[i] != png[i])
return false;
}

return true;

我正在寻找是否有类似的方法来检查 dds 文件的格式。我对此很陌生,我遇到的问题是知道 dds 文件中的哪些字节对于所有 dds 文件始终相同(以便我可以检查这些字节以查看 dds 格式是否有效)以及我如何可以通过简单的方式实现代码来检查dds格式。任何帮助将不胜感激。

编辑:所以感谢@NaCl,我已经回答了问题的第一部分。我现在知道 dds 文件中的哪些部分是必需的,但我不知道如何在 dds 文件中找到它。我用十六进制编辑器打开了很多 dds 文件,但我不太擅长逆向工程,所以我不明白我需要检查的字节在哪里,这进一步让我不知道如何实现代码在指定的位置搜索字节(我可以用 png 文件来做,因为我发现了更多关于该文件的文档),因为我不知道去哪个位置。

如果有人能指出正确的方向或以其他方式帮助我,我将不胜感激。谢谢。

最佳答案

对于具有 header 的文件要做的第一件事是检查其魔数(Magic Number)(如果文档中给出了任何魔数(Magic Number)),以防DDS file。 ,魔数(Magic Number)是0x44445220,等于“纯文本”中的“DDS”

之后,只需处理规范即可。所有内容(魔数(Magic Number)除外)都以小端格式存储,因此在处理字节时要小心,据微软称,definition DDS header 的结构是 (C++):

typedef struct {
DWORD dwSize; /* Always equal to 124 */
DWORD dwFlags;
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth;
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDS_PIXELFORMAT ddspf;
DWORD dwCaps;
DWORD dwCaps2;
DWORD dwCaps3;
DWORD dwCaps4;
DWORD dwReserved2;
} DDS_HEADER;

基于此,我为任何“通用”DDS 文件提供了以下代码:

public static bool IsValidDDS(string path)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
if (!File.Exists(path)) // Check for existence.
return false;

uint magicNumber = 0; byte[] headerLength = new byte[sizeof(byte)];
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
byte[] magic = new byte[sizeof(uint)];

// I'm still pretty used to C and fread, so here you go :^)
if (fs.Read(magic, 0, sizeof(uint)) != sizeof(uint))
return false; // Not even a valid file.

if (fs.Read(headerLength, 0, sizeof(byte)) != sizeof(byte))
return false; // Not enough bytes, even if the first 4 bytes were checked.

// Convert to a big endian integer.
magicNumber = (uint)((magic[0] << 24) | (magic[1] << 16) | (magic[2] << 8) | magic[3]);
}
return (headerLength[0] == 0x7C) && (magicNumber == 0x44445320);
}

上面的代码只检查输入文件的前 5 个字节(作为参数 path 传递),它们总是和我看到的一样,应该等于:

0x44 0x44 0x53 0x20 0x7C 0x00 0x00 0x00 (8 bytes)

上面的代码是用这个存储库中的 .dds 文件测试的:https://github.com/toji/webgl-texture-utils/tree/master/sample/img ,并且这两个文件具有完全相同的 header :

iamnacl:~/workspace $ cd dds-test/
iamnacl:~/workspace/dds-test $ dotnet run ../test-dxt1.dds
The file is a valid DDS file? True
iamnacl:~/workspace/dds-test $ dotnet run ../test-dxt5.dds
The file is a valid DDS file? True
iamnacl:~/workspace/dds-test $

您可以优化上面的代码以执行对 ulong 大小的 fs.Read 的单个调用,并根据此值检查整个事情:0x444453207C000000

希望这有帮助:)

关于c# - 如何确保 DirectDraw 表面具有正确的文件格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51974508/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com