|
@@ -33,25 +33,106 @@ namespace dds
|
|
using namespace dds::dxinfo;
|
|
using namespace dds::dxinfo;
|
|
|
|
|
|
// Creates a packed uint representation of a FourCC code.
|
|
// Creates a packed uint representation of a FourCC code.
|
|
-static inline uint32_t FourCC(char a, char b, char c, char d)
|
|
|
|
|
|
+#define MakeFourCC(a, b, c, d) ((uint32_t) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)))
|
|
|
|
+
|
|
|
|
+// Translate the old DDS format to our own.
|
|
|
|
+static Format parseDDSFormat(const DDSPixelFormat &fmt)
|
|
{
|
|
{
|
|
- uint32_t fcc = ((uint32_t) a)
|
|
|
|
- | (((uint32_t) b) << 8)
|
|
|
|
- | (((uint32_t) c) << 16)
|
|
|
|
- | (((uint32_t) d) << 24);
|
|
|
|
|
|
+ if ((fmt.flags & DDPF_FOURCC) == 0)
|
|
|
|
+ return FORMAT_UNKNOWN;
|
|
|
|
+
|
|
|
|
+ Format f = FORMAT_UNKNOWN;
|
|
|
|
+
|
|
|
|
+ switch (fmt.fourCC)
|
|
|
|
+ {
|
|
|
|
+ case MakeFourCC('D','X','T','1'):
|
|
|
|
+ f = FORMAT_DXT1;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('D','X','T','3'):
|
|
|
|
+ f = FORMAT_DXT3;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('D','X','T','5'):
|
|
|
|
+ f = FORMAT_DXT5;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('A','T','I','1'):
|
|
|
|
+ case MakeFourCC('B','C','4','U'):
|
|
|
|
+ f = FORMAT_BC4;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('B','C','4','S'):
|
|
|
|
+ f = FORMAT_BC4s;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('A','T','I','2'):
|
|
|
|
+ case MakeFourCC('B','C','5','U'):
|
|
|
|
+ f = FORMAT_BC5;
|
|
|
|
+ break;
|
|
|
|
+ case MakeFourCC('B','C','5','S'):
|
|
|
|
+ f = FORMAT_BC5s;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- return fcc;
|
|
|
|
|
|
+ return f;
|
|
}
|
|
}
|
|
|
|
|
|
-Parser::Image::Image()
|
|
|
|
- : width(0)
|
|
|
|
- , height(0)
|
|
|
|
- , dataSize(0)
|
|
|
|
- , data(0)
|
|
|
|
|
|
+// Translate the new DX10 formats to our own.
|
|
|
|
+static Format parseDX10Format(DXGIFormat fmt)
|
|
{
|
|
{
|
|
|
|
+ Format f = FORMAT_UNKNOWN;
|
|
|
|
+
|
|
|
|
+ switch (fmt)
|
|
|
|
+ {
|
|
|
|
+ case DXGI_FORMAT_BC1_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC1_UNORM:
|
|
|
|
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
|
|
|
|
+ f = FORMAT_DXT1;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC2_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC2_UNORM:
|
|
|
|
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
|
|
|
|
+ f = FORMAT_DXT3;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC3_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC3_UNORM:
|
|
|
|
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
|
|
|
|
+ f = FORMAT_DXT5;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC4_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC4_UNORM:
|
|
|
|
+ f = FORMAT_BC4;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC4_SNORM:
|
|
|
|
+ f = FORMAT_BC4s;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC5_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC5_UNORM:
|
|
|
|
+ f = FORMAT_BC5;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC5_SNORM:
|
|
|
|
+ f = FORMAT_BC5s;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC6H_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC6H_UF16:
|
|
|
|
+ f = FORMAT_BC6H;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC6H_SF16:
|
|
|
|
+ f = FORAMT_BC6Hs;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC7_TYPELESS:
|
|
|
|
+ case DXGI_FORMAT_BC7_UNORM:
|
|
|
|
+ f = FORMAT_BC7;
|
|
|
|
+ break;
|
|
|
|
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
|
|
+ f = FORMAT_BC7srgb;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return f;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Parser::isDDS(const void *data, size_t dataSize)
|
|
|
|
|
|
+bool isDDS(const void *data, size_t dataSize)
|
|
{
|
|
{
|
|
const uint8_t *readData = (const uint8_t *) data;
|
|
const uint8_t *readData = (const uint8_t *) data;
|
|
ptrdiff_t offset = 0;
|
|
ptrdiff_t offset = 0;
|
|
@@ -61,7 +142,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
// All DDS files start with "DDS ".
|
|
// All DDS files start with "DDS ".
|
|
- if((*(uint32_t *) readData) != FourCC('D','D','S',' '))
|
|
|
|
|
|
+ if((*(uint32_t *) readData) != MakeFourCC('D','D','S',' '))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
offset += sizeof(uint32_t);
|
|
offset += sizeof(uint32_t);
|
|
@@ -76,7 +157,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
|
|
offset += sizeof(DDSHeader);
|
|
offset += sizeof(DDSHeader);
|
|
|
|
|
|
// Check for DX10 extension.
|
|
// Check for DX10 extension.
|
|
- if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
|
|
|
|
|
|
+ if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
|
|
{
|
|
{
|
|
// Data must be big enough for both headers plus the magic value.
|
|
// Data must be big enough for both headers plus the magic value.
|
|
if (dataSize < (sizeof(uint32_t) + sizeof(DDSHeader) + sizeof(DDSHeader10)))
|
|
if (dataSize < (sizeof(uint32_t) + sizeof(DDSHeader) + sizeof(DDSHeader10)))
|
|
@@ -86,7 +167,7 @@ bool Parser::isDDS(const void *data, size_t dataSize)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Parser::isCompressedDDS(const void *data, size_t dataSize)
|
|
|
|
|
|
+bool isCompressedDDS(const void *data, size_t dataSize)
|
|
{
|
|
{
|
|
if (!isDDS(data, dataSize))
|
|
if (!isDDS(data, dataSize))
|
|
return false;
|
|
return false;
|
|
@@ -98,7 +179,7 @@ bool Parser::isCompressedDDS(const void *data, size_t dataSize)
|
|
offset += sizeof(DDSHeader);
|
|
offset += sizeof(DDSHeader);
|
|
|
|
|
|
// Check for DX10 extension.
|
|
// Check for DX10 extension.
|
|
- if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
|
|
|
|
|
|
+ if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
|
|
{
|
|
{
|
|
DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
|
|
DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
|
|
return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN;
|
|
return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN;
|
|
@@ -141,7 +222,7 @@ Format Parser::getFormat() const
|
|
return format;
|
|
return format;
|
|
}
|
|
}
|
|
|
|
|
|
-const Parser::Image *Parser::getImageData(size_t miplevel) const
|
|
|
|
|
|
+const Image *Parser::getImageData(size_t miplevel) const
|
|
{
|
|
{
|
|
if (miplevel >= texData.size())
|
|
if (miplevel >= texData.size())
|
|
return 0;
|
|
return 0;
|
|
@@ -149,94 +230,11 @@ const Parser::Image *Parser::getImageData(size_t miplevel) const
|
|
return &texData[miplevel];
|
|
return &texData[miplevel];
|
|
}
|
|
}
|
|
|
|
|
|
-size_t Parser::getNumMipmaps() const
|
|
|
|
|
|
+size_t Parser::getMipmapCount() const
|
|
{
|
|
{
|
|
return texData.size();
|
|
return texData.size();
|
|
}
|
|
}
|
|
|
|
|
|
-Format Parser::parseDDSFormat(const DDSPixelFormat &fmt)
|
|
|
|
-{
|
|
|
|
- if (fmt.flags & DDPF_FOURCC)
|
|
|
|
- {
|
|
|
|
- if (fmt.fourCC == FourCC('D','X','T','1'))
|
|
|
|
- return FORMAT_DXT1;
|
|
|
|
- else if (fmt.fourCC == FourCC('D','X','T','3'))
|
|
|
|
- return FORMAT_DXT3;
|
|
|
|
- else if (fmt.fourCC == FourCC('D','X','T','5'))
|
|
|
|
- return FORMAT_DXT5;
|
|
|
|
- else if (fmt.fourCC == FourCC('A','T','I','1'))
|
|
|
|
- return FORMAT_BC4;
|
|
|
|
- else if (fmt.fourCC == FourCC('A','T','I','2'))
|
|
|
|
- return FORMAT_BC5;
|
|
|
|
- else if (fmt.fourCC == FourCC('B','C','4','U'))
|
|
|
|
- return FORMAT_BC4;
|
|
|
|
- else if (fmt.fourCC == FourCC('B','C','4','S'))
|
|
|
|
- return FORMAT_BC4s;
|
|
|
|
- else if (fmt.fourCC == FourCC('B','C','5','U'))
|
|
|
|
- return FORMAT_BC5;
|
|
|
|
- else if (fmt.fourCC == FourCC('B','C','5','S'))
|
|
|
|
- return FORMAT_BC5s;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return FORMAT_UNKNOWN;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-Format Parser::parseDX10Format(DXGIFormat fmt)
|
|
|
|
-{
|
|
|
|
- Format f = FORMAT_UNKNOWN;
|
|
|
|
-
|
|
|
|
- switch (fmt)
|
|
|
|
- {
|
|
|
|
- case DXGI_FORMAT_BC1_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC1_UNORM:
|
|
|
|
- case DXGI_FORMAT_BC1_UNORM_SRGB:
|
|
|
|
- f = FORMAT_DXT1;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC2_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC2_UNORM:
|
|
|
|
- case DXGI_FORMAT_BC2_UNORM_SRGB:
|
|
|
|
- f = FORMAT_DXT3;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC3_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC3_UNORM:
|
|
|
|
- case DXGI_FORMAT_BC3_UNORM_SRGB:
|
|
|
|
- f = FORMAT_DXT5;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC4_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC4_UNORM:
|
|
|
|
- f = FORMAT_BC4;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC4_SNORM:
|
|
|
|
- f = FORMAT_BC4s;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC5_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC5_UNORM:
|
|
|
|
- f = FORMAT_BC5;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC5_SNORM:
|
|
|
|
- f = FORMAT_BC5s;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC6H_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC6H_UF16:
|
|
|
|
- f = FORMAT_BC6H;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC6H_SF16:
|
|
|
|
- f = FORAMT_BC6Hs;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC7_TYPELESS:
|
|
|
|
- case DXGI_FORMAT_BC7_UNORM:
|
|
|
|
- f = FORMAT_BC7;
|
|
|
|
- break;
|
|
|
|
- case DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
|
|
- f = FORMAT_BC7srgb;
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return f;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
size_t Parser::parseImageSize(Format fmt, int width, int height) const
|
|
size_t Parser::parseImageSize(Format fmt, int width, int height) const
|
|
{
|
|
{
|
|
size_t size = 0;
|
|
size_t size = 0;
|
|
@@ -318,7 +316,7 @@ bool Parser::parseData(const void *data, size_t dataSize)
|
|
|
|
|
|
|
|
|
|
// Check for DX10 extension.
|
|
// Check for DX10 extension.
|
|
- if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == FourCC('D','X','1','0')))
|
|
|
|
|
|
+ if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0')))
|
|
{
|
|
{
|
|
DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
|
|
DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset];
|
|
offset += sizeof(DDSHeader10);
|
|
offset += sizeof(DDSHeader10);
|