Decompress DDS10 files. Only BC# supported so far.
This commit is contained in:
parent
bb5b02df0e
commit
3161fca9d9
@ -800,6 +800,15 @@ bool DirectDrawSurface::isSupported() const
|
|||||||
|
|
||||||
if (header.hasDX10Header())
|
if (header.hasDX10Header())
|
||||||
{
|
{
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -844,6 +853,40 @@ bool DirectDrawSurface::isSupported() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DirectDrawSurface::hasAlpha() const
|
||||||
|
{
|
||||||
|
if (header.hasDX10Header())
|
||||||
|
{
|
||||||
|
// @@ TODO: Update with all formats.
|
||||||
|
return
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
|
||||||
|
header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (header.pf.flags & DDPF_RGB)
|
||||||
|
{
|
||||||
|
return header.pf.amask != 0;
|
||||||
|
}
|
||||||
|
else if (header.pf.flags & DDPF_FOURCC)
|
||||||
|
{
|
||||||
|
if (header.pf.fourcc == FOURCC_RXGB ||
|
||||||
|
header.pf.fourcc == FOURCC_ATI1 ||
|
||||||
|
header.pf.fourcc == FOURCC_ATI2 ||
|
||||||
|
header.pf.flags & DDPF_NORMAL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint DirectDrawSurface::mipmapCount() const
|
uint DirectDrawSurface::mipmapCount() const
|
||||||
{
|
{
|
||||||
@ -939,15 +982,32 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
img->allocate(w, h);
|
img->allocate(w, h);
|
||||||
|
|
||||||
if (header.pf.flags & DDPF_RGB)
|
if (hasAlpha())
|
||||||
{
|
{
|
||||||
readLinearImage(img);
|
img->setFormat(Image::Format_ARGB);
|
||||||
}
|
}
|
||||||
else if (header.pf.flags & DDPF_FOURCC)
|
else
|
||||||
{
|
{
|
||||||
|
img->setFormat(Image::Format_RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.hasDX10Header())
|
||||||
|
{
|
||||||
|
// So far only block formats supported.
|
||||||
readBlockImage(img);
|
readBlockImage(img);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (header.pf.flags & DDPF_RGB)
|
||||||
|
{
|
||||||
|
readLinearImage(img);
|
||||||
|
}
|
||||||
|
else if (header.pf.flags & DDPF_FOURCC)
|
||||||
|
{
|
||||||
|
readBlockImage(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirectDrawSurface::readLinearImage(Image * img)
|
void DirectDrawSurface::readLinearImage(Image * img)
|
||||||
@ -972,17 +1032,6 @@ void DirectDrawSurface::readLinearImage(Image * img)
|
|||||||
|
|
||||||
uint byteCount = (header.pf.bitcount + 7) / 8;
|
uint byteCount = (header.pf.bitcount + 7) / 8;
|
||||||
|
|
||||||
// set image format: RGB or ARGB
|
|
||||||
// alpha channel exists if and only if the alpha mask is non-zero
|
|
||||||
if (header.pf.amask == 0)
|
|
||||||
{
|
|
||||||
img->setFormat(Image::Format_RGB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
img->setFormat(Image::Format_ARGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read linear RGB images.
|
// Read linear RGB images.
|
||||||
for (uint y = 0; y < h; y++)
|
for (uint y = 0; y < h; y++)
|
||||||
{
|
{
|
||||||
@ -1007,19 +1056,6 @@ void DirectDrawSurface::readBlockImage(Image * img)
|
|||||||
nvDebugCheck(stream != NULL);
|
nvDebugCheck(stream != NULL);
|
||||||
nvDebugCheck(img != NULL);
|
nvDebugCheck(img != NULL);
|
||||||
|
|
||||||
// set image format: RGB or ARGB
|
|
||||||
if (header.pf.fourcc == FOURCC_RXGB ||
|
|
||||||
header.pf.fourcc == FOURCC_ATI1 ||
|
|
||||||
header.pf.fourcc == FOURCC_ATI2 ||
|
|
||||||
header.pf.flags & DDPF_NORMAL)
|
|
||||||
{
|
|
||||||
img->setFormat(Image::Format_RGB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
img->setFormat(Image::Format_ARGB);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint w = img->width();
|
const uint w = img->width();
|
||||||
const uint h = img->height();
|
const uint h = img->height();
|
||||||
|
|
||||||
@ -1064,20 +1100,33 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
|
|||||||
nvDebugCheck(stream != NULL);
|
nvDebugCheck(stream != NULL);
|
||||||
nvDebugCheck(rgba != NULL);
|
nvDebugCheck(rgba != NULL);
|
||||||
|
|
||||||
if (header.pf.fourcc == FOURCC_DXT1)
|
uint fourcc = header.pf.fourcc;
|
||||||
|
|
||||||
|
// Map DX10 block formats to fourcc codes.
|
||||||
|
if (header.hasDX10Header())
|
||||||
|
{
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
|
||||||
|
if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fourcc == FOURCC_DXT1)
|
||||||
{
|
{
|
||||||
BlockDXT1 block;
|
BlockDXT1 block;
|
||||||
*stream << block;
|
*stream << block;
|
||||||
block.decodeBlock(rgba);
|
block.decodeBlock(rgba);
|
||||||
}
|
}
|
||||||
else if (header.pf.fourcc == FOURCC_DXT2 ||
|
else if (fourcc == FOURCC_DXT2 ||
|
||||||
header.pf.fourcc == FOURCC_DXT3)
|
header.pf.fourcc == FOURCC_DXT3)
|
||||||
{
|
{
|
||||||
BlockDXT3 block;
|
BlockDXT3 block;
|
||||||
*stream << block;
|
*stream << block;
|
||||||
block.decodeBlock(rgba);
|
block.decodeBlock(rgba);
|
||||||
}
|
}
|
||||||
else if (header.pf.fourcc == FOURCC_DXT4 ||
|
else if (fourcc == FOURCC_DXT4 ||
|
||||||
header.pf.fourcc == FOURCC_DXT5 ||
|
header.pf.fourcc == FOURCC_DXT5 ||
|
||||||
header.pf.fourcc == FOURCC_RXGB)
|
header.pf.fourcc == FOURCC_RXGB)
|
||||||
{
|
{
|
||||||
@ -1085,7 +1134,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
|
|||||||
*stream << block;
|
*stream << block;
|
||||||
block.decodeBlock(rgba);
|
block.decodeBlock(rgba);
|
||||||
|
|
||||||
if (header.pf.fourcc == FOURCC_RXGB)
|
if (fourcc == FOURCC_RXGB)
|
||||||
{
|
{
|
||||||
// Swap R & A.
|
// Swap R & A.
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
@ -1097,13 +1146,13 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (header.pf.fourcc == FOURCC_ATI1)
|
else if (fourcc == FOURCC_ATI1)
|
||||||
{
|
{
|
||||||
BlockATI1 block;
|
BlockATI1 block;
|
||||||
*stream << block;
|
*stream << block;
|
||||||
block.decodeBlock(rgba);
|
block.decodeBlock(rgba);
|
||||||
}
|
}
|
||||||
else if (header.pf.fourcc == FOURCC_ATI2)
|
else if (fourcc == FOURCC_ATI2)
|
||||||
{
|
{
|
||||||
BlockATI2 block;
|
BlockATI2 block;
|
||||||
*stream << block;
|
*stream << block;
|
||||||
@ -1113,7 +1162,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
|
|||||||
// If normal flag set, convert to normal.
|
// If normal flag set, convert to normal.
|
||||||
if (header.pf.flags & DDPF_NORMAL)
|
if (header.pf.flags & DDPF_NORMAL)
|
||||||
{
|
{
|
||||||
if (header.pf.fourcc == FOURCC_ATI2)
|
if (fourcc == FOURCC_ATI2)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
@ -1121,7 +1170,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
|
|||||||
c = buildNormal(c.r, c.g);
|
c = buildNormal(c.r, c.g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (header.pf.fourcc == FOURCC_DXT5)
|
else if (fourcc == FOURCC_DXT5)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +114,8 @@ namespace nv
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
bool isSupported() const;
|
bool isSupported() const;
|
||||||
|
|
||||||
|
bool hasAlpha() const;
|
||||||
|
|
||||||
uint mipmapCount() const;
|
uint mipmapCount() const;
|
||||||
uint width() const;
|
uint width() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user