Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/dds/DirectDrawSurface.cpp')
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp489
1 files changed, 380 insertions, 109 deletions
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index ede82896554..971658ff482 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributors: Amorilia (amorilia@gamebox.net)
+ * Contributors: Amorilia (amorilia@users.sourceforge.net)
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -69,12 +69,11 @@
#if !defined(MAKEFOURCC)
# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
- ((uint)((unsigned char)(ch0)) | \
- ((uint)((unsigned char)(ch1)) << 8) | \
- ((uint)((unsigned char)(ch2)) << 16) | \
- ((uint)((unsigned char)(ch3)) << 24 ))
+ (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
+ (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
#endif
+static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
@@ -89,6 +88,8 @@ static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y');
static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
+static const uint FOURCC_UVER = MAKEFOURCC('U', 'V', 'E', 'R');
+
// 32 bit RGB formats.
static const uint D3DFMT_R8G8B8 = 20;
static const uint D3DFMT_A8R8G8B8 = 21;
@@ -160,7 +161,10 @@ static const uint DDPF_PALETTEINDEXED4 = 0x00000008U;
static const uint DDPF_PALETTEINDEXED8 = 0x00000020U;
static const uint DDPF_LUMINANCE = 0x00020000U;
static const uint DDPF_ALPHAPREMULT = 0x00008000U;
-static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag.
+
+// Custom NVTT flags.
+static const uint DDPF_NORMAL = 0x80000000U;
+static const uint DDPF_SRGB = 0x40000000U;
// DX10 formats.
enum DXGI_FORMAT
@@ -277,6 +281,20 @@ static const uint DDPF_NORMAL = 0x80000000U; // @@ Custom nv flag.
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+
+ DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+
+ DXGI_FORMAT_BC6H_TYPELESS = 94,
+ DXGI_FORMAT_BC6H_UF16 = 95,
+ DXGI_FORMAT_BC6H_SF16 = 96,
+
+ DXGI_FORMAT_BC7_TYPELESS = 97,
+ DXGI_FORMAT_BC7_UNORM = 98,
+ DXGI_FORMAT_BC7_UNORM_SRGB = 99,
};
enum D3D10_RESOURCE_DIMENSION
@@ -478,6 +496,63 @@ void mem_read(Stream & mem, DDSHeader & header)
}
}
+namespace
+{
+ struct FormatDescriptor
+ {
+ uint format;
+ uint bitcount;
+ uint rmask;
+ uint gmask;
+ uint bmask;
+ uint amask;
+ };
+
+ static const FormatDescriptor s_d3dFormats[] =
+ {
+ { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 },
+ { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM
+ { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM
+ { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM
+ { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 },
+ { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM
+ { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 },
+ { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 },
+ { D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM
+ { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 },
+ { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 },
+ { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2
+ { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM
+ { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 },
+ { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM
+ { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 },
+ { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 },
+
+ { D3DFMT_L8, 8, 8, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM
+ { D3DFMT_L16, 16, 16, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM
+ };
+
+ static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
+
+} // namespace
+
+uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
+{
+ for (int i = 0; i < s_d3dFormatCount; i++)
+ {
+ if (s_d3dFormats[i].bitcount == bitcount &&
+ s_d3dFormats[i].rmask == rmask &&
+ s_d3dFormats[i].gmask == gmask &&
+ s_d3dFormats[i].bmask == bmask &&
+ s_d3dFormats[i].amask == amask)
+ {
+ return s_d3dFormats[i].format;
+ }
+ }
+
+ return 0;
+ }
+
DDSHeader::DDSHeader()
@@ -493,8 +568,8 @@ DDSHeader::DDSHeader()
for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
// Store version information on the reserved header attributes.
- this->reserved[9] = MAKEFOURCC('N', 'V', 'T', 'T');
- this->reserved[10] = (0 << 16) | (9 << 8) | (5); // major.minor.revision
+ this->reserved[9] = FOURCC_NVTT;
+ this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision
this->pf.size = 32;
this->pf.flags = 0;
@@ -532,7 +607,7 @@ void DDSHeader::setHeight(uint h)
void DDSHeader::setDepth(uint d)
{
this->flags |= DDSD_DEPTH;
- this->height = d;
+ this->depth = d;
}
void DDSHeader::setMipmapCount(uint count)
@@ -540,7 +615,7 @@ void DDSHeader::setMipmapCount(uint count)
if (count == 0 || count == 1)
{
this->flags &= ~DDSD_MIPMAPCOUNT;
- this->mipmapcount = 0;
+ this->mipmapcount = 1;
if (this->caps.caps2 == 0) {
this->caps.caps1 = DDSCAPS_TEXTURE;
@@ -561,6 +636,7 @@ void DDSHeader::setMipmapCount(uint count)
void DDSHeader::setTexture2D()
{
this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTexture3D()
@@ -568,6 +644,7 @@ void DDSHeader::setTexture3D()
this->caps.caps2 = DDSCAPS2_VOLUME;
this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+ this->header10.arraySize = 1;
}
void DDSHeader::setTextureCube()
@@ -599,21 +676,32 @@ void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
this->pf.flags = DDPF_FOURCC;
this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
- if (this->pf.fourcc == FOURCC_ATI2)
- {
- this->pf.bitcount = FOURCC_A2XY;
- }
- else
- {
- this->pf.bitcount = 0;
- }
+ this->pf.bitcount = 0;
+ this->pf.rmask = 0;
+ this->pf.gmask = 0;
+ this->pf.bmask = 0;
+ this->pf.amask = 0;
+}
+
+void DDSHeader::setFormatCode(uint32 code)
+{
+ // set fourcc pixel format.
+ this->pf.flags = DDPF_FOURCC;
+ this->pf.fourcc = code;
+ this->pf.bitcount = 0;
this->pf.rmask = 0;
this->pf.gmask = 0;
this->pf.bmask = 0;
this->pf.amask = 0;
}
+void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
+{
+ this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
+}
+
+
void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
{
// Make sure the masks are correct.
@@ -627,10 +715,24 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask
return;
}
- this->pf.flags = DDPF_RGB;
-
- if (amask != 0) {
- this->pf.flags |= DDPF_ALPHAPIXELS;
+ if (rmask != 0 || gmask != 0 || bmask != 0)
+ {
+ if (gmask == 0 && bmask == 0)
+ {
+ this->pf.flags = DDPF_LUMINANCE;
+ }
+ else
+ {
+ this->pf.flags = DDPF_RGB;
+ }
+
+ if (amask != 0) {
+ this->pf.flags |= DDPF_ALPHAPIXELS;
+ }
+ }
+ else if (amask != 0)
+ {
+ this->pf.flags |= DDPF_ALPHA;
}
if (bitcount == 0)
@@ -643,18 +745,16 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask
}
}
+ // D3DX functions do not like this:
+ this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
+ /*if (this->pf.fourcc) {
+ this->pf.flags |= DDPF_FOURCC;
+ }*/
+
if (!(bitcount > 0 && bitcount <= 32)) {
printf("DDS: bad bit count, pixel format not set\n");
return;
}
-
- // Align to 8.
- if (bitcount <= 8) bitcount = 8;
- else if (bitcount <= 16) bitcount = 16;
- else if (bitcount <= 24) bitcount = 24;
- else bitcount = 32;
-
- this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
this->pf.bitcount = bitcount;
this->pf.rmask = rmask;
this->pf.gmask = gmask;
@@ -675,10 +775,108 @@ void DDSHeader::setNormalFlag(bool b)
else this->pf.flags &= ~DDPF_NORMAL;
}
+void DDSHeader::setSrgbFlag(bool b)
+{
+ if (b) this->pf.flags |= DDPF_SRGB;
+ else this->pf.flags &= ~DDPF_SRGB;
+}
+
+void DDSHeader::setHasAlphaFlag(bool b)
+{
+ if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
+ else this->pf.flags &= ~DDPF_ALPHAPIXELS;
+}
+
+void DDSHeader::setUserVersion(int version)
+{
+ this->reserved[7] = FOURCC_UVER;
+ this->reserved[8] = version;
+}
+
+/*
+void DDSHeader::swapBytes()
+{
+ this->fourcc = POSH_LittleU32(this->fourcc);
+ this->size = POSH_LittleU32(this->size);
+ this->flags = POSH_LittleU32(this->flags);
+ this->height = POSH_LittleU32(this->height);
+ this->width = POSH_LittleU32(this->width);
+ this->pitch = POSH_LittleU32(this->pitch);
+ this->depth = POSH_LittleU32(this->depth);
+ this->mipmapcount = POSH_LittleU32(this->mipmapcount);
+
+ for(int i = 0; i < 11; i++) {
+ this->reserved[i] = POSH_LittleU32(this->reserved[i]);
+ }
+
+ this->pf.size = POSH_LittleU32(this->pf.size);
+ this->pf.flags = POSH_LittleU32(this->pf.flags);
+ this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
+ this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
+ this->pf.rmask = POSH_LittleU32(this->pf.rmask);
+ this->pf.gmask = POSH_LittleU32(this->pf.gmask);
+ this->pf.bmask = POSH_LittleU32(this->pf.bmask);
+ this->pf.amask = POSH_LittleU32(this->pf.amask);
+ this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
+ this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
+ this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
+ this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
+ this->notused = POSH_LittleU32(this->notused);
+
+ this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
+ this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
+ this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
+ this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
+ this->header10.reserved = POSH_LittleU32(this->header10.reserved);
+}
+*/
+
bool DDSHeader::hasDX10Header() const
{
- return this->pf.fourcc == FOURCC_DX10; // @@ This is according to AMD
- //return this->pf.flags == 0; // @@ This is according to MS
+ return this->pf.fourcc == FOURCC_DX10;
+}
+
+uint DDSHeader::signature() const
+{
+ return this->reserved[9];
+}
+
+uint DDSHeader::toolVersion() const
+{
+ return this->reserved[10];
+}
+
+uint DDSHeader::userVersion() const
+{
+ if (this->reserved[7] == FOURCC_UVER) {
+ return this->reserved[8];
+ }
+ return 0;
+}
+
+bool DDSHeader::isNormalMap() const
+{
+ return (pf.flags & DDPF_NORMAL) != 0;
+}
+
+bool DDSHeader::isSrgb() const
+{
+ return (pf.flags & DDPF_SRGB) != 0;
+}
+
+bool DDSHeader::hasAlpha() const
+{
+ return (pf.flags & DDPF_ALPHAPIXELS) != 0;
+}
+
+uint DDSHeader::d3d9Format() const
+{
+ if (pf.flags & DDPF_FOURCC) {
+ return pf.fourcc;
+ }
+ else {
+ return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
+ }
}
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
@@ -725,6 +923,16 @@ bool DirectDrawSurface::isSupported() const
{
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;
}
else
{
@@ -743,9 +951,9 @@ bool DirectDrawSurface::isSupported() const
return false;
}
}
- else if (header.pf.flags & DDPF_RGB)
- {
- // All RGB formats are supported now.
+ else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE))
+ {
+ // All RGB and luminance formats are supported now.
}
else
{
@@ -768,6 +976,41 @@ bool DirectDrawSurface::isSupported() const
return true;
}
+bool DirectDrawSurface::hasAlpha() const
+{
+ if (header.hasDX10Header())
+ {
+ /* TODO: Update hasAlpha to handle all DX10 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
+ {
+ // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
uint DirectDrawSurface::mipmapCount() const
{
@@ -794,22 +1037,6 @@ uint DirectDrawSurface::depth() const
else return 1;
}
-bool DirectDrawSurface::hasAlpha() const
-{
- if ((header.pf.flags & DDPF_RGB) && (header.pf.amask == 0))
- {
- return false;
- }
- else if (header.pf.fourcc == FOURCC_DXT1)
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
bool DirectDrawSurface::isTexture1D() const
{
if (header.hasDX10Header())
@@ -853,6 +1080,16 @@ void DirectDrawSurface::setNormalFlag(bool b)
header.setNormalFlag(b);
}
+void DirectDrawSurface::setHasAlphaFlag(bool b)
+{
+ header.setHasAlphaFlag(b);
+}
+
+void DirectDrawSurface::setUserVersion(int version)
+{
+ header.setUserVersion(version);
+}
+
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
{
stream.seek(offset(face, mipmap));
@@ -869,14 +1106,31 @@ void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
img->allocate(w, h);
- if (header.pf.flags & DDPF_RGB)
+ if (hasAlpha())
+ {
+ img->setFormat(Image::Format_ARGB);
+ }
+ else
{
- readLinearImage(img);
+ img->setFormat(Image::Format_RGB);
}
- else if (header.pf.flags & DDPF_FOURCC)
+
+ if (header.hasDX10Header())
{
+ // So far only block formats supported.
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)
@@ -906,17 +1160,6 @@ void DirectDrawSurface::readLinearImage(Image * img)
return;
}
- // 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.
for (uint y = 0; y < h; y++)
{
@@ -926,10 +1169,10 @@ void DirectDrawSurface::readLinearImage(Image * img)
mem_read(stream, (unsigned char *)(&c), byteCount);
Color32 pixel(0, 0, 0, 0xFF);
- pixel.r = PixelFormat::convert(c >> rshift, rsize, 8);
- pixel.g = PixelFormat::convert(c >> gshift, gsize, 8);
- pixel.b = PixelFormat::convert(c >> bshift, bsize, 8);
- pixel.a = PixelFormat::convert(c >> ashift, asize, 8);
+ pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
+ pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
+ pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
+ pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
img->pixel(x, y) = pixel;
}
@@ -939,19 +1182,6 @@ void DirectDrawSurface::readLinearImage(Image * img)
void DirectDrawSurface::readBlockImage(Image * img)
{
- // 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 h = img->height();
@@ -993,20 +1223,33 @@ static Color32 buildNormal(uint8 x, uint8 y)
void DirectDrawSurface::readBlock(ColorBlock * rgba)
{
- 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;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_DXT2 ||
+ else if (fourcc == FOURCC_DXT2 ||
header.pf.fourcc == FOURCC_DXT3)
{
BlockDXT3 block;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_DXT4 ||
+ else if (fourcc == FOURCC_DXT4 ||
header.pf.fourcc == FOURCC_DXT5 ||
header.pf.fourcc == FOURCC_RXGB)
{
@@ -1014,7 +1257,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
mem_read(stream, block);
block.decodeBlock(rgba);
- if (header.pf.fourcc == FOURCC_RXGB)
+ if (fourcc == FOURCC_RXGB)
{
// Swap R & A.
for (int i = 0; i < 16; i++)
@@ -1026,13 +1269,13 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
}
}
}
- else if (header.pf.fourcc == FOURCC_ATI1)
+ else if (fourcc == FOURCC_ATI1)
{
BlockATI1 block;
mem_read(stream, block);
block.decodeBlock(rgba);
}
- else if (header.pf.fourcc == FOURCC_ATI2)
+ else if (fourcc == FOURCC_ATI2)
{
BlockATI2 block;
mem_read(stream, block);
@@ -1042,7 +1285,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
// If normal flag set, convert to normal.
if (header.pf.flags & DDPF_NORMAL)
{
- if (header.pf.fourcc == FOURCC_ATI2)
+ if (fourcc == FOURCC_ATI2)
{
for (int i = 0; i < 16; i++)
{
@@ -1050,7 +1293,7 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba)
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++)
{
@@ -1076,6 +1319,27 @@ uint DirectDrawSurface::blockSize() const
case FOURCC_RXGB:
case FOURCC_ATI2:
return 16;
+ case FOURCC_DX10:
+ switch(header.header10.dxgiFormat)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return 8;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ return 16;
+ };
};
// Not a block image.
@@ -1102,14 +1366,10 @@ uint DirectDrawSurface::mipmapSize(uint mipmap) const
h = (h + 3) / 4;
return blockSize() * w * h;
}
- else if (header.pf.flags & DDPF_RGB)
+ else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE))
{
- // Align pixels to bytes.
- uint byteCount = (header.pf.bitcount + 7) / 8;
-
- // Align pitch to 4 bytes.
- uint pitch = 4 * ((w * byteCount + 3) / 4);
-
+ uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects.
+
return pitch * h * d;
}
else {
@@ -1133,7 +1393,7 @@ uint DirectDrawSurface::faceSize() const
uint DirectDrawSurface::offset(const uint face, const uint mipmap)
{
- uint size = 128; //sizeof(DDSHeader);
+ uint size = 128; // sizeof(DDSHeader);
if (header.hasDX10Header())
{
@@ -1156,7 +1416,6 @@ uint DirectDrawSurface::offset(const uint face, const uint mipmap)
void DirectDrawSurface::printInfo() const
{
- /* printf("FOURCC: %c%c%c%c\n", ((unsigned char *)&header.fourcc)[0], ((unsigned char *)&header.fourcc)[1], ((unsigned char *)&header.fourcc)[2], ((unsigned char *)&header.fourcc)[3]); */
printf("Flags: 0x%.8X\n", header.flags);
if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n");
if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n");
@@ -1175,9 +1434,9 @@ void DirectDrawSurface::printInfo() const
printf("Mipmap count: %d\n", header.mipmapcount);
printf("Pixel Format:\n");
- /* printf("\tSize: %d\n", header.pf.size); */
printf("\tFlags: 0x%.8X\n", header.pf.flags);
if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
+ if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
@@ -1188,23 +1447,30 @@ void DirectDrawSurface::printInfo() const
if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
- printf("\tFourCC: '%c%c%c%c'\n",
- ((header.pf.fourcc >> 0) & 0xFF),
- ((header.pf.fourcc >> 8) & 0xFF),
- ((header.pf.fourcc >> 16) & 0xFF),
- ((header.pf.fourcc >> 24) & 0xFF));
- if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0))
+ if (header.pf.fourcc != 0) {
+ // Display fourcc code even when DDPF_FOURCC flag not set.
+ printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
+ ((header.pf.fourcc >> 0) & 0xFF),
+ ((header.pf.fourcc >> 8) & 0xFF),
+ ((header.pf.fourcc >> 16) & 0xFF),
+ ((header.pf.fourcc >> 24) & 0xFF),
+ header.pf.fourcc);
+ }
+
+ if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
{
- printf("\tSwizzle: '%c%c%c%c'\n",
+ printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
(header.pf.bitcount >> 0) & 0xFF,
(header.pf.bitcount >> 8) & 0xFF,
(header.pf.bitcount >> 16) & 0xFF,
- (header.pf.bitcount >> 24) & 0xFF);
+ (header.pf.bitcount >> 24) & 0xFF,
+ header.pf.bitcount);
}
else
{
printf("\tBit count: %d\n", header.pf.bitcount);
}
+
printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
@@ -1244,7 +1510,7 @@ void DirectDrawSurface::printInfo() const
printf("\tArray size: %u\n", header.header10.arraySize);
}
- if (header.reserved[9] == MAKEFOURCC('N', 'V', 'T', 'T'))
+ if (header.reserved[9] == FOURCC_NVTT)
{
int major = (header.reserved[10] >> 16) & 0xFF;
int minor = (header.reserved[10] >> 8) & 0xFF;
@@ -1253,5 +1519,10 @@ void DirectDrawSurface::printInfo() const
printf("Version:\n");
printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
}
+
+ if (header.reserved[7] == FOURCC_UVER)
+ {
+ printf("User Version: %d\n", header.reserved[8]);
+ }
}