Decompress DDS10 files. Only BC# supported so far.

This commit is contained in:
castano 2008-07-30 02:28:09 +00:00
parent bb5b02df0e
commit 3161fca9d9
2 changed files with 87 additions and 36 deletions

View File

@ -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
{ {
@ -940,6 +983,22 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
img->allocate(w, h); img->allocate(w, h);
if (hasAlpha())
{
img->setFormat(Image::Format_ARGB);
}
else
{
img->setFormat(Image::Format_RGB);
}
if (header.hasDX10Header())
{
// So far only block formats supported.
readBlockImage(img);
}
else
{
if (header.pf.flags & DDPF_RGB) if (header.pf.flags & DDPF_RGB)
{ {
readLinearImage(img); readLinearImage(img);
@ -948,6 +1007,7 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
{ {
readBlockImage(img); 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++)
{ {

View File

@ -115,6 +115,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;
uint height() const; uint height() const;