代码之家  ›  专栏  ›  技术社区  ›  Justin Meiners

确定与endian相关的问题

  •  3
  • Justin Meiners  · 技术社区  · 16 年前

    我最近了解了endianness,但仍然难以识别问题区域。

    下面是一段代码,它使用从二进制文件(DXT纹理)加载的数据。我不确定endianness是否会在这种情况下导致问题,例如宽度、高度和十六进制比较。我需要改变什么?为什么?

    DxtHeader* header = (DxtHeader*)data;
    width = header->width;
    height = header->height;
    
    uint pixelFormat = header->pixelFormat.fourCC;
    if (pixelFormat == 0x31545844){
        ...
    } else if (pixelFormat == 0x33545844){
        ...
    } else if (pixelFormat == 0x35545844){
        ...
    }
    
    2 回复  |  直到 11 年前
        1
  •  1
  •   Oliver Charlesworth    16 年前

    一般来说,只有当数据通过某个物理接口(例如,通过网络或文件)传输时,endianness才重要,因为它可能来自具有不同本机endianness的平台。如果你试图用指针投射来做“聪明”的事情,也会发生这种情况,例如 int a = 0xABCD; char b = *(char *)&a; .

    从您的示例中不清楚原始数据来自何处,但我假设它是从某个文件或某个地方读取的。实际上,处理无端性转换的最佳位置是尽可能靠近接口,因此在您的例子中,是读取文件并填充结构的例程。通常情况下,这可以用预处理器αIFIFS来解决,例如C(我知道这是C++问题,但我相信你能找到一个适当的等价物):

    #ifdef (LITTLE_ENDIAN)
    #define FILE_TO_NATIVE_16(x)  ((((x) & 0xFF) << 8) | ((x) >> 8))
    #else
    #define FILE_TO_NATIVE_16(x)  (x)
    #endif
    

    等等。

    如果隔离到接口例程的转换,其余代码就变成了endian不可知论者。

        2
  •  1
  •   dash-tom-bang    16 年前

    最好首先保存适合目标平台的数据。也就是说,创建数据文件时,endian会交换所有字段。

    撇开这一点不谈,我认为您的DXT加载程序应该自动处理这一问题,因为目前DXT通常是在Windows机器上构建的,而Windows机器是小endian。