Skip to content

Commit

Permalink
DDS: alpha/luminance format fixes, add & enable more tests (#3581)
Browse files Browse the repository at this point in the history
* DDS: fixes for A8, L8, A8L8 formats

While developing #3573 at one time I had them working properly, but then
while fixing the address sanitizer failure for 3-channel formats I
botched them again. Note to self: never again do a "yeah I'll add tests
later", since if I had all of them running all the time this would
not have happened. 🤦

* DDS: extend test coverage for more formats & channel size cases

With more test images recently added (#3459),
start using them for DDS tests. This covers now:
- Alpha, Luminance and Alpha+Luminance formats,
- RGB formats with rarer channel sizes (rgb10 a2, r3g3b2),
- Several "broken" DDS file cases
- Removed usage of sample-DXT1 since it is well covered by others.
  • Loading branch information
aras-p authored Oct 5, 2022
1 parent caf15b6 commit 4ee3535
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 20 deletions.
47 changes: 35 additions & 12 deletions src/dds.imageio/ddsinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,17 +453,29 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
m_nchans = GetChannelCount(m_compression,
m_dds.fmt.flags & DDS_PF_NORMAL);
} else {
m_nchans = ((m_dds.fmt.flags & (DDS_PF_LUMINANCE | DDS_PF_ALPHAONLY))
? 1
: 3)
+ ((m_dds.fmt.flags & DDS_PF_ALPHA) ? 1 : 0);
// also calculate bytes per pixel and the bit shifts
m_Bpp = (m_dds.fmt.bpp + 7) >> 3;
if (!(m_dds.fmt.flags & DDS_PF_LUMINANCE)) {
for (int i = 0; i < 4; ++i)
calc_shifts(m_dds.fmt.masks[i], m_BitCounts[i],
m_RightShifts[i]);
for (int i = 0; i < 4; ++i)
calc_shifts(m_dds.fmt.masks[i], m_BitCounts[i], m_RightShifts[i]);
m_nchans = 3;
if (m_dds.fmt.flags & DDS_PF_LUMINANCE) {
// we treat luminance as one channel;
// move next channel (possible alpha) info
// after it
m_nchans = 1;
m_dds.fmt.masks[1] = m_dds.fmt.masks[3];
m_BitCounts[1] = m_BitCounts[3];
m_RightShifts[1] = m_RightShifts[3];
} else if (m_dds.fmt.flags & DDS_PF_ALPHAONLY) {
// alpha-only image; move alpha info
// into the first slot
m_nchans = 1;
m_dds.fmt.masks[0] = m_dds.fmt.masks[3];
m_BitCounts[0] = m_BitCounts[3];
m_RightShifts[0] = m_RightShifts[3];
}
if (m_dds.fmt.flags & DDS_PF_ALPHA)
m_nchans++;
}

// fix depth, pitch and mipmaps for later use, if needed
Expand Down Expand Up @@ -747,10 +759,21 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
}
}
} else {
// uncompressed image

// HACK: shortcut for luminance
if (m_dds.fmt.flags & DDS_PF_LUMINANCE) {
// uncompressed image:
// check if we can just directly copy pixels without any processing
bool direct = false;
if (m_spec.nchannels == m_Bpp) {
direct = true;
for (int ch = 0; ch < m_spec.nchannels; ++ch) {
if ((m_dds.fmt.masks[ch] != (0xFFu << (ch * 8)))
|| (m_RightShifts[ch] != uint32_t(ch * 8))
|| (m_BitCounts[ch] != 8u)) {
direct = false;
break;
}
}
}
if (direct) {
return ioread(dst, w * m_Bpp, h);
}

Expand Down
87 changes: 81 additions & 6 deletions testsuite/dds/ref/out.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
Reading ../oiio-images/dds/sample-DXT1.dds
../oiio-images/dds/sample-DXT1.dds : 123 x 456, 4 channel, uint8 dds
SHA-1: 95586C955325224DC81FF9F4600D7C2B424D12EF
channel list: R, G, B, A
compression: "DXT1"
textureformat: "Plain Texture"
Reading ../oiio-images/dds/dds_bc1.dds
../oiio-images/dds/dds_bc1.dds : 16 x 8, 4 channel, uint8 dds
SHA-1: A2DD1B9BF07149F6E32B177BE5A1D85A7A3C6BCF
Expand Down Expand Up @@ -124,3 +118,84 @@ Reading ../oiio-images/dds/dds_rgba8_mips.dds
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 32
Reading ../oiio-images/dds/dds_a8.dds
../oiio-images/dds/dds_a8.dds : 24 x 20, 1 channel, uint8 dds
SHA-1: 497ACCA96FAAC89AE74BDE8CA7B69B37CA9C5F20
channel list: Y
textureformat: "Plain Texture"
oiio:BitsPerSample: 8
Reading ../oiio-images/dds/dds_abgr8.dds
../oiio-images/dds/dds_abgr8.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: B84A369C1CB71B102DA57D04635B7F42116F9B16
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 32
Reading ../oiio-images/dds/dds_bc3nm.dds
../oiio-images/dds/dds_bc3nm.dds : 24 x 20, 3 channel, uint8 dds
SHA-1: 04C252DA402FBF35E7D39605231356CBCA6AF006
channel list: R, G, B
compression: "DXT5"
textureformat: "Plain Texture"
Reading ../oiio-images/dds/dds_bc3rxgb.dds
../oiio-images/dds/dds_bc3rxgb.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: 460EAC801AA68743CC3D3FC01E9BF067CD9CB67F
channel list: R, G, B, A
compression: "DXT5"
textureformat: "Plain Texture"
Reading ../oiio-images/dds/dds_bc3ycocg.dds
../oiio-images/dds/dds_bc3ycocg.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: 485B74D1E9BEF25D8CA06880A6CAD260430CBE30
channel list: R, G, B, A
compression: "DXT5"
textureformat: "Plain Texture"
Reading ../oiio-images/dds/dds_l8.dds
../oiio-images/dds/dds_l8.dds : 24 x 20, 1 channel, uint8 dds
SHA-1: 2E40B849905A3F67F22F86188540DD21DB3C29C5
channel list: Y
textureformat: "Plain Texture"
oiio:BitsPerSample: 8
Reading ../oiio-images/dds/dds_l8a8.dds
../oiio-images/dds/dds_l8a8.dds : 24 x 20, 2 channel, uint8 dds
SHA-1: D6B33AA4813B6D181399AF0E9658D173BD505E2D
channel list: Y, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 16
Reading ../oiio-images/dds/dds_rgb10a2.dds
../oiio-images/dds/dds_rgb10a2.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: D7599C62CA35D7C4478341471A54526CB546CF0C
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 32
Reading ../oiio-images/dds/dds_rgb332.dds
../oiio-images/dds/dds_rgb332.dds : 24 x 20, 3 channel, uint8 dds
SHA-1: 777DB8FC8240CA6FADF6B58870B07D83EEA84372
channel list: R, G, B
textureformat: "Plain Texture"
oiio:BitsPerSample: 8
Reading ../oiio-images/dds/dds_rgb5a1.dds
../oiio-images/dds/dds_rgb5a1.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: C6EE5529AB29827FFF4AD941D7714EF30F3DAA75
channel list: R, G, B, A
textureformat: "Plain Texture"
oiio:BitsPerSample: 16
Reading ../oiio-images/dds/broken/dds_bc3_just_header.dds
../oiio-images/dds/broken/dds_bc3_just_header.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
channel list: R, G, B, A
compression: "DXT5"
textureformat: "Plain Texture"
oiiotool ERROR: read : "../oiio-images/dds/broken/dds_bc3_no_full_header.dds": Read error: hit end of file
Full command line was:
> oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc3_no_full_header.dds
Reading ../oiio-images/dds/broken/dds_bc7_just_header.dds
../oiio-images/dds/broken/dds_bc7_just_header.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
channel list: R, G, B, A
compression: "BC7"
textureformat: "Plain Texture"
Reading ../oiio-images/dds/broken/dds_bc7_not_enough_data.dds
../oiio-images/dds/broken/dds_bc7_not_enough_data.dds : 24 x 20, 4 channel, uint8 dds
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
channel list: R, G, B, A
compression: "BC7"
textureformat: "Plain Texture"
24 changes: 22 additions & 2 deletions testsuite/dds/run.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env python

failureok = 1
redirect = ' >> out.txt 2>&1 '
files = [
"sample-DXT1.dds",
"dds_bc1.dds",
"dds_bc1_mips.dds",
"dds_bc2.dds",
Expand All @@ -20,6 +21,25 @@
"dds_rgb8.dds",
"dds_rgba4.dds",
"dds_rgba8.dds",
"dds_rgba8_mips.dds" ]
"dds_rgba8_mips.dds",
"dds_a8.dds",
"dds_abgr8.dds",
"dds_bc3nm.dds",
"dds_bc3rxgb.dds",
"dds_bc3ycocg.dds",
"dds_l8.dds",
"dds_l8a8.dds",
"dds_rgb10a2.dds",
"dds_rgb332.dds",
"dds_rgb5a1.dds",
# In some CI matrix cases a PtexReader
# also attempts to read this, and outputs
# a "PtexReader error: read failed (EOF)"
# failure error.
#"broken/dds_8bytes.dds",
"broken/dds_bc3_just_header.dds",
"broken/dds_bc3_no_full_header.dds",
"broken/dds_bc7_just_header.dds",
"broken/dds_bc7_not_enough_data.dds" ]
for f in files:
command += info_command (OIIO_TESTSUITE_IMAGEDIR + "/" + f)

0 comments on commit 4ee3535

Please sign in to comment.