Skip to content

Commit 4ee3535

Browse files
authored
DDS: alpha/luminance format fixes, add & enable more tests (#3581)
* 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.
1 parent caf15b6 commit 4ee3535

File tree

3 files changed

+138
-20
lines changed

3 files changed

+138
-20
lines changed

src/dds.imageio/ddsinput.cpp

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -453,17 +453,29 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
453453
m_nchans = GetChannelCount(m_compression,
454454
m_dds.fmt.flags & DDS_PF_NORMAL);
455455
} else {
456-
m_nchans = ((m_dds.fmt.flags & (DDS_PF_LUMINANCE | DDS_PF_ALPHAONLY))
457-
? 1
458-
: 3)
459-
+ ((m_dds.fmt.flags & DDS_PF_ALPHA) ? 1 : 0);
460456
// also calculate bytes per pixel and the bit shifts
461457
m_Bpp = (m_dds.fmt.bpp + 7) >> 3;
462-
if (!(m_dds.fmt.flags & DDS_PF_LUMINANCE)) {
463-
for (int i = 0; i < 4; ++i)
464-
calc_shifts(m_dds.fmt.masks[i], m_BitCounts[i],
465-
m_RightShifts[i]);
458+
for (int i = 0; i < 4; ++i)
459+
calc_shifts(m_dds.fmt.masks[i], m_BitCounts[i], m_RightShifts[i]);
460+
m_nchans = 3;
461+
if (m_dds.fmt.flags & DDS_PF_LUMINANCE) {
462+
// we treat luminance as one channel;
463+
// move next channel (possible alpha) info
464+
// after it
465+
m_nchans = 1;
466+
m_dds.fmt.masks[1] = m_dds.fmt.masks[3];
467+
m_BitCounts[1] = m_BitCounts[3];
468+
m_RightShifts[1] = m_RightShifts[3];
469+
} else if (m_dds.fmt.flags & DDS_PF_ALPHAONLY) {
470+
// alpha-only image; move alpha info
471+
// into the first slot
472+
m_nchans = 1;
473+
m_dds.fmt.masks[0] = m_dds.fmt.masks[3];
474+
m_BitCounts[0] = m_BitCounts[3];
475+
m_RightShifts[0] = m_RightShifts[3];
466476
}
477+
if (m_dds.fmt.flags & DDS_PF_ALPHA)
478+
m_nchans++;
467479
}
468480

469481
// fix depth, pitch and mipmaps for later use, if needed
@@ -747,10 +759,21 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
747759
}
748760
}
749761
} else {
750-
// uncompressed image
751-
752-
// HACK: shortcut for luminance
753-
if (m_dds.fmt.flags & DDS_PF_LUMINANCE) {
762+
// uncompressed image:
763+
// check if we can just directly copy pixels without any processing
764+
bool direct = false;
765+
if (m_spec.nchannels == m_Bpp) {
766+
direct = true;
767+
for (int ch = 0; ch < m_spec.nchannels; ++ch) {
768+
if ((m_dds.fmt.masks[ch] != (0xFFu << (ch * 8)))
769+
|| (m_RightShifts[ch] != uint32_t(ch * 8))
770+
|| (m_BitCounts[ch] != 8u)) {
771+
direct = false;
772+
break;
773+
}
774+
}
775+
}
776+
if (direct) {
754777
return ioread(dst, w * m_Bpp, h);
755778
}
756779

testsuite/dds/ref/out.txt

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
Reading ../oiio-images/dds/sample-DXT1.dds
2-
../oiio-images/dds/sample-DXT1.dds : 123 x 456, 4 channel, uint8 dds
3-
SHA-1: 95586C955325224DC81FF9F4600D7C2B424D12EF
4-
channel list: R, G, B, A
5-
compression: "DXT1"
6-
textureformat: "Plain Texture"
71
Reading ../oiio-images/dds/dds_bc1.dds
82
../oiio-images/dds/dds_bc1.dds : 16 x 8, 4 channel, uint8 dds
93
SHA-1: A2DD1B9BF07149F6E32B177BE5A1D85A7A3C6BCF
@@ -124,3 +118,84 @@ Reading ../oiio-images/dds/dds_rgba8_mips.dds
124118
channel list: R, G, B, A
125119
textureformat: "Plain Texture"
126120
oiio:BitsPerSample: 32
121+
Reading ../oiio-images/dds/dds_a8.dds
122+
../oiio-images/dds/dds_a8.dds : 24 x 20, 1 channel, uint8 dds
123+
SHA-1: 497ACCA96FAAC89AE74BDE8CA7B69B37CA9C5F20
124+
channel list: Y
125+
textureformat: "Plain Texture"
126+
oiio:BitsPerSample: 8
127+
Reading ../oiio-images/dds/dds_abgr8.dds
128+
../oiio-images/dds/dds_abgr8.dds : 24 x 20, 4 channel, uint8 dds
129+
SHA-1: B84A369C1CB71B102DA57D04635B7F42116F9B16
130+
channel list: R, G, B, A
131+
textureformat: "Plain Texture"
132+
oiio:BitsPerSample: 32
133+
Reading ../oiio-images/dds/dds_bc3nm.dds
134+
../oiio-images/dds/dds_bc3nm.dds : 24 x 20, 3 channel, uint8 dds
135+
SHA-1: 04C252DA402FBF35E7D39605231356CBCA6AF006
136+
channel list: R, G, B
137+
compression: "DXT5"
138+
textureformat: "Plain Texture"
139+
Reading ../oiio-images/dds/dds_bc3rxgb.dds
140+
../oiio-images/dds/dds_bc3rxgb.dds : 24 x 20, 4 channel, uint8 dds
141+
SHA-1: 460EAC801AA68743CC3D3FC01E9BF067CD9CB67F
142+
channel list: R, G, B, A
143+
compression: "DXT5"
144+
textureformat: "Plain Texture"
145+
Reading ../oiio-images/dds/dds_bc3ycocg.dds
146+
../oiio-images/dds/dds_bc3ycocg.dds : 24 x 20, 4 channel, uint8 dds
147+
SHA-1: 485B74D1E9BEF25D8CA06880A6CAD260430CBE30
148+
channel list: R, G, B, A
149+
compression: "DXT5"
150+
textureformat: "Plain Texture"
151+
Reading ../oiio-images/dds/dds_l8.dds
152+
../oiio-images/dds/dds_l8.dds : 24 x 20, 1 channel, uint8 dds
153+
SHA-1: 2E40B849905A3F67F22F86188540DD21DB3C29C5
154+
channel list: Y
155+
textureformat: "Plain Texture"
156+
oiio:BitsPerSample: 8
157+
Reading ../oiio-images/dds/dds_l8a8.dds
158+
../oiio-images/dds/dds_l8a8.dds : 24 x 20, 2 channel, uint8 dds
159+
SHA-1: D6B33AA4813B6D181399AF0E9658D173BD505E2D
160+
channel list: Y, A
161+
textureformat: "Plain Texture"
162+
oiio:BitsPerSample: 16
163+
Reading ../oiio-images/dds/dds_rgb10a2.dds
164+
../oiio-images/dds/dds_rgb10a2.dds : 24 x 20, 4 channel, uint8 dds
165+
SHA-1: D7599C62CA35D7C4478341471A54526CB546CF0C
166+
channel list: R, G, B, A
167+
textureformat: "Plain Texture"
168+
oiio:BitsPerSample: 32
169+
Reading ../oiio-images/dds/dds_rgb332.dds
170+
../oiio-images/dds/dds_rgb332.dds : 24 x 20, 3 channel, uint8 dds
171+
SHA-1: 777DB8FC8240CA6FADF6B58870B07D83EEA84372
172+
channel list: R, G, B
173+
textureformat: "Plain Texture"
174+
oiio:BitsPerSample: 8
175+
Reading ../oiio-images/dds/dds_rgb5a1.dds
176+
../oiio-images/dds/dds_rgb5a1.dds : 24 x 20, 4 channel, uint8 dds
177+
SHA-1: C6EE5529AB29827FFF4AD941D7714EF30F3DAA75
178+
channel list: R, G, B, A
179+
textureformat: "Plain Texture"
180+
oiio:BitsPerSample: 16
181+
Reading ../oiio-images/dds/broken/dds_bc3_just_header.dds
182+
../oiio-images/dds/broken/dds_bc3_just_header.dds : 24 x 20, 4 channel, uint8 dds
183+
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
184+
channel list: R, G, B, A
185+
compression: "DXT5"
186+
textureformat: "Plain Texture"
187+
oiiotool ERROR: read : "../oiio-images/dds/broken/dds_bc3_no_full_header.dds": Read error: hit end of file
188+
Full command line was:
189+
> oiiotool --info -v -a --hash ../oiio-images/dds/broken/dds_bc3_no_full_header.dds
190+
Reading ../oiio-images/dds/broken/dds_bc7_just_header.dds
191+
../oiio-images/dds/broken/dds_bc7_just_header.dds : 24 x 20, 4 channel, uint8 dds
192+
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
193+
channel list: R, G, B, A
194+
compression: "BC7"
195+
textureformat: "Plain Texture"
196+
Reading ../oiio-images/dds/broken/dds_bc7_not_enough_data.dds
197+
../oiio-images/dds/broken/dds_bc7_not_enough_data.dds : 24 x 20, 4 channel, uint8 dds
198+
SHA-1: 7070E1838A7C0595287731B65FB8062C365E7BED
199+
channel list: R, G, B, A
200+
compression: "BC7"
201+
textureformat: "Plain Texture"

testsuite/dds/run.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#!/usr/bin/env python
22

3+
failureok = 1
4+
redirect = ' >> out.txt 2>&1 '
35
files = [
4-
"sample-DXT1.dds",
56
"dds_bc1.dds",
67
"dds_bc1_mips.dds",
78
"dds_bc2.dds",
@@ -20,6 +21,25 @@
2021
"dds_rgb8.dds",
2122
"dds_rgba4.dds",
2223
"dds_rgba8.dds",
23-
"dds_rgba8_mips.dds" ]
24+
"dds_rgba8_mips.dds",
25+
"dds_a8.dds",
26+
"dds_abgr8.dds",
27+
"dds_bc3nm.dds",
28+
"dds_bc3rxgb.dds",
29+
"dds_bc3ycocg.dds",
30+
"dds_l8.dds",
31+
"dds_l8a8.dds",
32+
"dds_rgb10a2.dds",
33+
"dds_rgb332.dds",
34+
"dds_rgb5a1.dds",
35+
# In some CI matrix cases a PtexReader
36+
# also attempts to read this, and outputs
37+
# a "PtexReader error: read failed (EOF)"
38+
# failure error.
39+
#"broken/dds_8bytes.dds",
40+
"broken/dds_bc3_just_header.dds",
41+
"broken/dds_bc3_no_full_header.dds",
42+
"broken/dds_bc7_just_header.dds",
43+
"broken/dds_bc7_not_enough_data.dds" ]
2444
for f in files:
2545
command += info_command (OIIO_TESTSUITE_IMAGEDIR + "/" + f)

0 commit comments

Comments
 (0)