65
68
#if !defined(MAKEFOURCC)
66
69
# define MAKEFOURCC(ch0, ch1, ch2, ch3) \
67
((uint)((unsigned char)(ch0)) | \
68
((uint)((unsigned char)(ch1)) << 8) | \
69
((uint)((unsigned char)(ch2)) << 16) | \
70
((uint)((unsigned char)(ch3)) << 24 ))
70
(uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
71
(uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
74
static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
73
75
static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
74
76
static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
75
77
static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
272
279
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
273
280
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
274
281
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
283
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
284
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
285
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
286
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
287
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
289
DXGI_FORMAT_BC6H_TYPELESS = 94,
290
DXGI_FORMAT_BC6H_UF16 = 95,
291
DXGI_FORMAT_BC6H_SF16 = 96,
293
DXGI_FORMAT_BC7_TYPELESS = 97,
294
DXGI_FORMAT_BC7_UNORM = 98,
295
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
277
298
enum D3D10_RESOURCE_DIMENSION
499
struct FormatDescriptor
509
static const FormatDescriptor s_d3dFormats[] =
511
{ D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 },
512
{ D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM
513
{ D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM
514
{ D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM
515
{ D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 },
516
{ D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM
517
{ D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 },
518
{ D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 },
519
{ D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM
520
{ D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 },
521
{ D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 },
522
{ D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2
523
{ D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM
524
{ D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 },
525
{ D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM
526
{ D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 },
527
{ D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 },
529
{ D3DFMT_L8, 8, 8, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM
530
{ D3DFMT_L16, 16, 16, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM
533
static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
537
uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
539
for (int i = 0; i < s_d3dFormatCount; i++)
541
if (s_d3dFormats[i].bitcount == bitcount &&
542
s_d3dFormats[i].rmask == rmask &&
543
s_d3dFormats[i].gmask == gmask &&
544
s_d3dFormats[i].bmask == bmask &&
545
s_d3dFormats[i].amask == amask)
547
return s_d3dFormats[i].format;
478
556
DDSHeader::DDSHeader()
594
674
this->pf.flags = DDPF_FOURCC;
595
675
this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
597
if (this->pf.fourcc == FOURCC_ATI2)
599
this->pf.bitcount = FOURCC_A2XY;
603
this->pf.bitcount = 0;
677
this->pf.bitcount = 0;
684
void DDSHeader::setFormatCode(uint32 code)
686
// set fourcc pixel format.
687
this->pf.flags = DDPF_FOURCC;
688
this->pf.fourcc = code;
690
this->pf.bitcount = 0;
606
691
this->pf.rmask = 0;
607
692
this->pf.gmask = 0;
608
693
this->pf.bmask = 0;
609
694
this->pf.amask = 0;
697
void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
699
this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
612
703
void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
614
705
// Make sure the masks are correct.
615
if ((rmask & gmask) || \
706
if ((rmask & gmask) ||
620
711
(bmask & amask)) {
621
712
printf("DDS: bad RGBA masks, pixel format not set\n");
625
this->pf.flags = DDPF_RGB;
716
if (rmask != 0 || gmask != 0 || bmask != 0)
718
if (gmask == 0 && bmask == 0)
720
this->pf.flags = DDPF_LUMINANCE;
724
this->pf.flags = DDPF_RGB;
628
this->pf.flags |= DDPF_ALPHAPIXELS;
728
this->pf.flags |= DDPF_ALPHAPIXELS;
733
this->pf.flags |= DDPF_ALPHA;
631
736
if (bitcount == 0)
746
// D3DX functions do not like this:
747
this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
748
/*if (this->pf.fourcc) {
749
this->pf.flags |= DDPF_FOURCC;
641
752
if (!(bitcount > 0 && bitcount <= 32)) {
642
753
printf("DDS: bad bit count, pixel format not set\n");
647
if (bitcount <= 8) bitcount = 8;
648
else if (bitcount <= 16) bitcount = 16;
649
else if (bitcount <= 24) bitcount = 24;
652
this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
653
756
this->pf.bitcount = bitcount;
654
757
this->pf.rmask = rmask;
655
758
this->pf.gmask = gmask;
670
773
else this->pf.flags &= ~DDPF_NORMAL;
776
void DDSHeader::setSrgbFlag(bool b)
778
if (b) this->pf.flags |= DDPF_SRGB;
779
else this->pf.flags &= ~DDPF_SRGB;
782
void DDSHeader::setHasAlphaFlag(bool b)
784
if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
785
else this->pf.flags &= ~DDPF_ALPHAPIXELS;
788
void DDSHeader::setUserVersion(int version)
790
this->reserved[7] = FOURCC_UVER;
791
this->reserved[8] = version;
795
void DDSHeader::swapBytes()
797
this->fourcc = POSH_LittleU32(this->fourcc);
798
this->size = POSH_LittleU32(this->size);
799
this->flags = POSH_LittleU32(this->flags);
800
this->height = POSH_LittleU32(this->height);
801
this->width = POSH_LittleU32(this->width);
802
this->pitch = POSH_LittleU32(this->pitch);
803
this->depth = POSH_LittleU32(this->depth);
804
this->mipmapcount = POSH_LittleU32(this->mipmapcount);
806
for (int i = 0; i < 11; i++) {
807
this->reserved[i] = POSH_LittleU32(this->reserved[i]);
810
this->pf.size = POSH_LittleU32(this->pf.size);
811
this->pf.flags = POSH_LittleU32(this->pf.flags);
812
this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
813
this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
814
this->pf.rmask = POSH_LittleU32(this->pf.rmask);
815
this->pf.gmask = POSH_LittleU32(this->pf.gmask);
816
this->pf.bmask = POSH_LittleU32(this->pf.bmask);
817
this->pf.amask = POSH_LittleU32(this->pf.amask);
818
this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
819
this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
820
this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
821
this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
822
this->notused = POSH_LittleU32(this->notused);
824
this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
825
this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
826
this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
827
this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
828
this->header10.reserved = POSH_LittleU32(this->header10.reserved);
673
832
bool DDSHeader::hasDX10Header() const
675
return this->pf.fourcc == FOURCC_DX10; // @@ This is according to AMD
676
//return this->pf.flags == 0; // @@ This is according to MS
834
return this->pf.fourcc == FOURCC_DX10;
837
uint DDSHeader::signature() const
839
return this->reserved[9];
842
uint DDSHeader::toolVersion() const
844
return this->reserved[10];
847
uint DDSHeader::userVersion() const
849
if (this->reserved[7] == FOURCC_UVER) {
850
return this->reserved[8];
855
bool DDSHeader::isNormalMap() const
857
return (pf.flags & DDPF_NORMAL) != 0;
860
bool DDSHeader::isSrgb() const
862
return (pf.flags & DDPF_SRGB) != 0;
865
bool DDSHeader::hasAlpha() const
867
return (pf.flags & DDPF_ALPHAPIXELS) != 0;
870
uint DDSHeader::d3d9Format() const
872
if (pf.flags & DDPF_FOURCC) {
876
return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
679
880
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
977
bool DirectDrawSurface::hasAlpha() const
979
if (header.hasDX10Header())
981
/* TODO: Update hasAlpha to handle all DX10 formats. */
983
header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
984
header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
985
header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
989
if (header.pf.flags & DDPF_RGB)
991
return header.pf.amask != 0;
993
else if (header.pf.flags & DDPF_FOURCC)
995
if (header.pf.fourcc == FOURCC_RXGB ||
996
header.pf.fourcc == FOURCC_ATI1 ||
997
header.pf.fourcc == FOURCC_ATI2 ||
998
header.pf.flags & DDPF_NORMAL)
1004
// @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
767
1013
uint DirectDrawSurface::mipmapCount() const
921
1167
mem_read(stream, (unsigned char *)(&c), byteCount);
923
1169
Color32 pixel(0, 0, 0, 0xFF);
924
pixel.r = PixelFormat::convert(c >> rshift, rsize, 8);
925
pixel.g = PixelFormat::convert(c >> gshift, gsize, 8);
926
pixel.b = PixelFormat::convert(c >> bshift, bsize, 8);
927
pixel.a = PixelFormat::convert(c >> ashift, asize, 8);
1170
pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
1171
pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
1172
pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
1173
pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
929
1175
img->pixel(x, y) = pixel;
989
1222
void DirectDrawSurface::readBlock(ColorBlock * rgba)
991
if (header.pf.fourcc == FOURCC_DXT1)
1224
uint fourcc = header.pf.fourcc;
1226
// Map DX10 block formats to fourcc codes.
1227
if (header.hasDX10Header())
1229
if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
1230
if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
1231
if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
1232
if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
1233
if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
1237
if (fourcc == FOURCC_DXT1)
993
1239
BlockDXT1 block;
994
1240
mem_read(stream, block);
995
1241
block.decodeBlock(rgba);
997
else if (header.pf.fourcc == FOURCC_DXT2 ||
1243
else if (fourcc == FOURCC_DXT2 ||
998
1244
header.pf.fourcc == FOURCC_DXT3)
1000
1246
BlockDXT3 block;
1001
1247
mem_read(stream, block);
1002
1248
block.decodeBlock(rgba);
1004
else if (header.pf.fourcc == FOURCC_DXT4 ||
1250
else if (fourcc == FOURCC_DXT4 ||
1005
1251
header.pf.fourcc == FOURCC_DXT5 ||
1006
1252
header.pf.fourcc == FOURCC_RXGB)
1071
1317
case FOURCC_RXGB:
1072
1318
case FOURCC_ATI2:
1321
switch(header.header10.dxgiFormat)
1323
case DXGI_FORMAT_BC1_TYPELESS:
1324
case DXGI_FORMAT_BC1_UNORM:
1325
case DXGI_FORMAT_BC1_UNORM_SRGB:
1326
case DXGI_FORMAT_BC4_TYPELESS:
1327
case DXGI_FORMAT_BC4_UNORM:
1328
case DXGI_FORMAT_BC4_SNORM:
1330
case DXGI_FORMAT_BC2_TYPELESS:
1331
case DXGI_FORMAT_BC2_UNORM:
1332
case DXGI_FORMAT_BC2_UNORM_SRGB:
1333
case DXGI_FORMAT_BC3_TYPELESS:
1334
case DXGI_FORMAT_BC3_UNORM:
1335
case DXGI_FORMAT_BC3_UNORM_SRGB:
1336
case DXGI_FORMAT_BC5_TYPELESS:
1337
case DXGI_FORMAT_BC5_UNORM:
1338
case DXGI_FORMAT_BC5_SNORM:
1076
1343
// Not a block image.
1162
1424
if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n");
1163
1425
if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n");
1165
printf("Height: %d\n", header.height);
1166
printf("Width: %d\n", header.width);
1167
printf("Depth: %d\n", header.depth);
1168
if (header.flags & DDSD_PITCH) printf("Pitch: %d\n", header.pitch);
1169
else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %d\n", header.pitch);
1170
printf("Mipmap count: %d\n", header.mipmapcount);
1427
printf("Height: %u\n", header.height);
1428
printf("Width: %u\n", header.width);
1429
printf("Depth: %u\n", header.depth);
1430
if (header.flags & DDSD_PITCH) printf("Pitch: %u\n", header.pitch);
1431
else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %u\n", header.pitch);
1432
printf("Mipmap count: %u\n", header.mipmapcount);
1172
1434
printf("Pixel Format:\n");
1173
/* printf("\tSize: %d\n", header.pf.size); */
1174
1435
printf("\tFlags: 0x%.8X\n", header.pf.flags);
1175
1436
if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
1437
if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
1176
1438
if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
1177
1439
if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
1178
1440
if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
1183
1445
if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
1184
1446
if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
1186
printf("\tFourCC: '%c%c%c%c'\n",
1187
((header.pf.fourcc >> 0) & 0xFF),
1188
((header.pf.fourcc >> 8) & 0xFF),
1189
((header.pf.fourcc >> 16) & 0xFF),
1190
((header.pf.fourcc >> 24) & 0xFF));
1191
if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0))
1448
if (header.pf.fourcc != 0) {
1449
// Display fourcc code even when DDPF_FOURCC flag not set.
1450
printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
1451
((header.pf.fourcc >> 0) & 0xFF),
1452
((header.pf.fourcc >> 8) & 0xFF),
1453
((header.pf.fourcc >> 16) & 0xFF),
1454
((header.pf.fourcc >> 24) & 0xFF),
1458
if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
1193
printf("\tSwizzle: '%c%c%c%c'\n",
1460
printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n",
1194
1461
(header.pf.bitcount >> 0) & 0xFF,
1195
1462
(header.pf.bitcount >> 8) & 0xFF,
1196
1463
(header.pf.bitcount >> 16) & 0xFF,
1197
(header.pf.bitcount >> 24) & 0xFF);
1464
(header.pf.bitcount >> 24) & 0xFF,
1465
header.pf.bitcount);
1201
printf("\tBit count: %d\n", header.pf.bitcount);
1469
printf("\tBit count: %u\n", header.pf.bitcount);
1203
1472
printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
1204
1473
printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
1205
1474
printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);