Skip to content

Commit b8ce666

Browse files
authored
Support DDS on big-endian systems (#563)
1 parent b1d33f2 commit b8ce666

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

Source/astcenc_vecmathlib_none_4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// ----------------------------------------------------------------------------
3-
// Copyright 2019-2024 Arm Limited
3+
// Copyright 2019-2025 Arm Limited
44
//
55
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
66
// use this file except in compliance with the License. You may obtain a copy

Source/astcenccli_image_load_store.cpp

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// ----------------------------------------------------------------------------
3-
// Copyright 2011-2023 Arm Limited
3+
// Copyright 2011-2025 Arm Limited
44
//
55
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
66
// use this file except in compliance with the License. You may obtain a copy
@@ -1746,6 +1746,21 @@ struct dds_header_dx10
17461746
#define DDS_MAGIC 0x20534444
17471747
#define DX10_MAGIC 0x30315844
17481748

1749+
1750+
#if defined(ASTCENC_BIG_ENDIAN)
1751+
/**
1752+
* @brief Reverse the bytes in a uint32_t value.
1753+
*/
1754+
static uint32_t reverse_bytes_u32(
1755+
uint32_t val
1756+
) {
1757+
return ((val >> 24) & 0x000000FF) |
1758+
((val >> 8) & 0x0000FF00) |
1759+
((val << 8) & 0x00FF0000) |
1760+
((val << 24) & 0xFF000000);
1761+
}
1762+
#endif
1763+
17491764
/**
17501765
* @brief Load an uncompressed DDS image using the local custom loader.
17511766
*
@@ -1769,23 +1784,52 @@ static astcenc_image* load_dds_uncompressed_image(
17691784
return nullptr;
17701785
}
17711786

1772-
uint8_t magic[4];
1787+
// Read and check the DDS magic number
1788+
uint32_t magic;
1789+
size_t magic_bytes_read = fread(&magic, 1, sizeof(uint32_t), f);
1790+
if (magic_bytes_read != 4)
1791+
{
1792+
printf("Failed to read magic number from file %s\n", filename);
1793+
fclose(f);
1794+
return nullptr;
1795+
}
17731796

1797+
#if defined(ASTCENC_BIG_ENDIAN)
1798+
magic = reverse_bytes_u32(magic);
1799+
#endif
1800+
1801+
if (magic != DDS_MAGIC)
1802+
{
1803+
printf("File %s has incorrect magic number\n", filename);
1804+
fclose(f);
1805+
return nullptr;
1806+
}
1807+
1808+
// Validate that we can read the DDS header
17741809
dds_header hdr;
1775-
size_t magic_bytes_read = fread(magic, 1, 4, f);
17761810
size_t header_bytes_read = fread(&hdr, 1, sizeof(hdr), f);
1777-
if (magic_bytes_read != 4 || header_bytes_read != sizeof(hdr))
1811+
if (header_bytes_read != sizeof(hdr))
17781812
{
1779-
printf("Failed to read header of DDS file %s\n", filename);
1813+
printf("Failed to read header from file %s\n", filename);
17801814
fclose(f);
17811815
return nullptr;
17821816
}
17831817

1784-
uint32_t magicx = magic[0] | (magic[1] << 8) | (magic[2] << 16) | (magic[3] << 24);
1818+
#if defined(ASTCENC_BIG_ENDIAN)
1819+
// DDS header fields all 32-bit words
1820+
uint32_t* words = reinterpret_cast<uint32_t*>(&hdr);
1821+
size_t word_count = sizeof(hdr) / sizeof(uint32_t);
1822+
1823+
// Reverse all of them
1824+
for (size_t i = 0; i < word_count; i++)
1825+
{
1826+
words[i] = reverse_bytes_u32(words[i]);
1827+
}
1828+
#endif
17851829

1786-
if (magicx != DDS_MAGIC || hdr.size != 124)
1830+
if (hdr.size != 124)
17871831
{
1788-
printf("File %s does not have a valid DDS header\n", filename);
1832+
printf("File %s has incorrect header\n", filename);
17891833
fclose(f);
17901834
return nullptr;
17911835
}

0 commit comments

Comments
 (0)