Skip to content

Instantly share code, notes, and snippets.

@legends2k
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save legends2k/97584e4c576d7b5e0dcf to your computer and use it in GitHub Desktop.

Select an option

Save legends2k/97584e4c576d7b5e0dcf to your computer and use it in GitHub Desktop.
Prints DDS file information
#include <fstream>
#include <iostream>
#include <array>
#include <bitset>
#include <iomanip>
#include <type_traits>
#include <stdexcept>
#include <cstdint>
using DWORD = uint32_t;
using UINT = unsigned int;
#define DDPF_ALPHAPIXELS 0x00000001
#define DDPF_ALPHA 0x00000002
#define DDPF_FOURCC 0x00000004
#define DDPF_RGB 0x00000040
#define DDPF_RGBA 0x00000041
#define DDPF_YUV 0x00000200
#define DDPF_LUMINANCE 0x00020000
#define DDSCAPS2_CUBEMAP 0x200
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x400
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x800
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x1000
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x2000
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x4000
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x8000
#define DDSCAPS2_VOLUME 0x200000
#define DDS_CUBEMAP_ALLFACES (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_POSITIVEY | DDSCAPS2_CUBEMAP_POSITIVEZ | \
DDSCAPS2_CUBEMAP_NEGATIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEY | DDSCAPS2_CUBEMAP_NEGATIVEZ)
enum class D3D10_RESOURCE_DIMENSION : uint8_t {
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
Total
};
enum class DXGI_FORMAT : uint32_t {
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
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,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_FORCE_UINT = 0xffffffffU,
Total = DXGI_FORMAT_B4G4R4A4_UNORM + 2
};
#pragma pack(push)
struct DDS_PIXELFORMAT {
DWORD dwSize;
DWORD dwFlags;
DWORD dwFourCC;
DWORD dwRGBBitCount;
DWORD dwRBitMask;
DWORD dwGBitMask;
DWORD dwBBitMask;
DWORD dwABitMask;
};
struct DDS_HEADER {
DWORD dwSize;
DWORD dwFlags;
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth;
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDS_PIXELFORMAT ddspf;
DWORD dwCaps;
DWORD dwCaps2;
DWORD dwCaps3;
DWORD dwCaps4;
DWORD dwReserved2;
};
struct DDS_HEADER_DXT10 {
DXGI_FORMAT dxgiFormat;
D3D10_RESOURCE_DIMENSION resourceDimension;
UINT miscFlag;
UINT arraySize;
UINT reserved;
};
#pragma pack(pop)
char const *resource_dim_string[] = { "Unknown", "N/A (Buffer)", "1D", "2D", "3D" };
char const *dxgi_format_string[] = {
"UNKNOWN",
"R32G32B32A32_TYPELESS",
"R32G32B32A32_FLOAT",
"R32G32B32A32_UINT",
"R32G32B32A32_SINT",
"R32G32B32_TYPELESS",
"R32G32B32_FLOAT",
"R32G32B32_UINT",
"R32G32B32_SINT",
"R16G16B16A16_TYPELESS",
"R16G16B16A16_FLOAT",
"R16G16B16A16_UNORM",
"R16G16B16A16_UINT",
"R16G16B16A16_SNORM",
"R16G16B16A16_SINT",
"R32G32_TYPELESS",
"R32G32_FLOAT",
"R32G32_UINT",
"R32G32_SINT",
"R32G8X24_TYPELESS",
"D32_FLOAT_S8X24_UINT",
"R32_FLOAT_X8X24_TYPELESS",
"X32_TYPELESS_G8X24_UINT",
"R10G10B10A2_TYPELESS",
"R10G10B10A2_UNORM",
"R10G10B10A2_UINT",
"R11G11B10_FLOAT",
"R8G8B8A8_TYPELESS",
"R8G8B8A8_UNORM",
"R8G8B8A8_UNORM_SRGB",
"R8G8B8A8_UINT",
"R8G8B8A8_SNORM",
"R8G8B8A8_SINT",
"R16G16_TYPELESS",
"R16G16_FLOAT",
"R16G16_UNORM",
"R16G16_UINT",
"R16G16_SNORM",
"R16G16_SINT",
"R32_TYPELESS",
"D32_FLOAT",
"R32_FLOAT",
"R32_UINT",
"R32_SINT",
"R24G8_TYPELESS",
"D24_UNORM_S8_UINT",
"R24_UNORM_X8_TYPELESS",
"X24_TYPELESS_G8_UINT",
"R8G8_TYPELESS",
"R8G8_UNORM",
"R8G8_UINT",
"R8G8_SNORM",
"R8G8_SINT",
"R16_TYPELESS",
"R16_FLOAT",
"D16_UNORM",
"R16_UNORM",
"R16_UINT",
"R16_SNORM",
"R16_SINT",
"R8_TYPELESS",
"R8_UNORM",
"R8_UINT",
"R8_SNORM",
"R8_SINT",
"A8_UNORM",
"R1_UNORM",
"R9G9B9E5_SHAREDEXP",
"R8G8_B8G8_UNORM",
"G8R8_G8B8_UNORM",
"BC1_TYPELESS",
"BC1_UNORM",
"BC1_UNORM_SRGB",
"BC2_TYPELESS",
"BC2_UNORM",
"BC2_UNORM_SRGB",
"BC3_TYPELESS",
"BC3_UNORM",
"BC3_UNORM_SRGB",
"BC4_TYPELESS",
"BC4_UNORM",
"BC4_SNORM",
"BC5_TYPELESS",
"BC5_UNORM",
"BC5_SNORM",
"B5G6R5_UNORM",
"B5G5R5A1_UNORM",
"B8G8R8A8_UNORM",
"B8G8R8X8_UNORM",
"R10G10B10_XR_BIAS_A2_UNORM",
"B8G8R8A8_TYPELESS",
"B8G8R8A8_UNORM_SRGB",
"B8G8R8X8_TYPELESS",
"B8G8R8X8_UNORM_SRGB",
"BC6H_TYPELESS",
"BC6H_UF16",
"BC6H_SF16",
"BC7_TYPELESS",
"BC7_UNORM",
"BC7_UNORM_SRGB",
"AYUV",
"Y410",
"Y416",
"NV12",
"P010",
"P016",
"420_OPAQUE",
"YUY2",
"Y210",
"Y216",
"NV11",
"AI44",
"IA44",
"P8",
"A8P8",
"B4G4R4A4_UNORM",
"FORCE_UINT"
};
char const *str_old_style = "Old-style";
char const *str_compressed = "Compressed";
char const *str_uncompressed = "Uncompressed";
char const *str_cube_map = "Cube Map";
char const *str_vol_tex = "Volume";
char const *str_tex = "Texture";
char const *str_pixels = "pixels";
char const *str_bytes = "bytes";
char const *str_rgb = "RGB";
char const *str_yuv = "YUV";
char const *str_alpha = "Alpha";
char const *str_luminance = "Luminance";
// fields are retained as arrays to be able to find length at compile-time
char const str_field_size[] = "Size: ";
char const str_field_top_level[] = "Top-level Texture: ";
char const str_field_pitch[] = "Stride/Pitch: ";
char const str_field_channels[] = "Channels: ";
char const str_field_fourcc[] = "FourCC: ";
char const str_field_bit_cnt[] = "Bit Count: ";
char const str_field_r_mask[] = "R Mask: ";
char const str_field_g_mask[] = "G Mask: ";
char const str_field_b_mask[] = "B Mask: ";
char const str_field_y_mask[] = "Y Mask: ";
char const str_field_u_mask[] = "U Mask: ";
char const str_field_v_mask[] = "V Mask: ";
char const str_field_alpha_mask[] = "Alpha Mask: ";
char const str_field_luminance_mask[] = "Luminance Mask: ";
char const str_field_dxgi_fmt[] = "DXGI Format: ";
char const str_field_dim[] = "Dimensions: ";
char const str_field_array_cnt[] = "Array Size: ";
char const str_field_mipmaps[] = "Mipmaps: ";
char const str_field_depth[] = "Depth: ";
const uint32_t DDS_ASCII = 0x20534444; // Equivalent to "DDS "
const uint32_t FOURCC_DX10 = 0x30315844; // Equivalent to "DX10" in ASCII
struct DDSHeaders {
DDS_HEADER header;
DDS_HEADER_DXT10 header10;
};
enum class ChannelData : uint8_t {
Alpha = 1 << 0,
YUV = 1 << 1,
RGB = 1 << 2,
Luminance = 1 << 3,
Total = 4
};
// http://stackoverflow.com/a/1448478/183120
// enum class operator
ChannelData operator|(ChannelData a, ChannelData b) {
using UT = typename std::underlying_type<ChannelData>::type;
return static_cast<ChannelData>(static_cast<UT>(a) | static_cast<UT>(b));
}
bool operator&(ChannelData a, ChannelData b) {
using UT = typename std::underlying_type<ChannelData>::type;
return static_cast<UT>(a) & static_cast<UT>(b);
}
void operator|=(ChannelData &a, ChannelData b) {
a = a | b;
}
template <typename T, size_t N>
char const *get_enum_string(T o, char const* (&strings) [N]) {
using UT = typename std::underlying_type<T>::type;
static_assert(N == static_cast<UT>(T::Total), "Update strings to match all enum members!");
auto const i = static_cast<UT>(o);
return strings[i];
}
std::ostream& operator<<(std::ostream &os, ChannelData d) {
bool started = false;
if (d & ChannelData::RGB) {
os << str_rgb;
started = true;
}
if (d & ChannelData::YUV) {
os << (started ? ", " : "") << str_yuv;
started = true;
}
if (d & ChannelData::Alpha) {
os << (started ? ", " : "") << str_alpha;
started = true;
}
if (d & ChannelData::Luminance) {
os << (started ? ", " : "") << str_luminance;
}
return os;
}
std::ostream& operator<<(std::ostream& os, D3D10_RESOURCE_DIMENSION d) {
return os << get_enum_string(d, resource_dim_string);
}
std::ostream& operator<<(std::ostream& os, DXGI_FORMAT f) {
return os << get_enum_string(f, dxgi_format_string);
}
struct DDSFlagInfo {
// 0 - old
// 1 - fourCC (also implies compressed texture)
std::bitset<3> bits;
ChannelData type;
uint32_t bit_count;
std::array<uint32_t, 4> masks;
};
// dummy structs for printing
struct fourcc {
uint32_t f;
explicit fourcc(uint32_t data) : f{data} { }
};
struct mask {
uint32_t m;
explicit mask(uint32_t data) : m{data} { }
};
std::ostream& operator<<(std::ostream &os, fourcc fcc) {
return os << static_cast<char>((fcc.f & 0x000000FF))
<< static_cast<char>((fcc.f & 0x0000FF00) >> 8)
<< static_cast<char>((fcc.f & 0x00FF0000) >> 16)
<< static_cast<char>((fcc.f & 0xFF000000) >> 24);
}
std::ostream& operator<<(std::ostream &os, mask m) {
return os << std::hex << std::showbase << std::setfill('0') << std::internal
<< std::setw(2 + sizeof(uint32_t) * 2u) // two for the base "0x"
<< m.m << std::setfill(' ') << std::noshowbase << std::dec;
}
DDSFlagInfo parse_flags(DDS_HEADER const &header) {
DDSFlagInfo f = { };
if (DDPF_ALPHAPIXELS & header.ddspf.dwFlags) {
f.type |= ChannelData::Alpha;
}
if (DDPF_ALPHA & header.ddspf.dwFlags) {
f.bits[0] = true;
f.type |= ChannelData::Alpha;
}
if (DDPF_FOURCC & header.ddspf.dwFlags) {
f.bits[1] = true;
f.type |= ChannelData::RGB;
}
if (DDPF_RGB & header.ddspf.dwFlags)
f.type |= ChannelData::RGB;
if (DDPF_YUV & header.ddspf.dwFlags) {
f.bits[0] = true;
f.type |= ChannelData::YUV;
}
if (DDPF_LUMINANCE & header.ddspf.dwFlags) {
f.bits[0] = true;
f.type |= ChannelData::Luminance;
}
f.bit_count = header.ddspf.dwRGBBitCount;
f.masks[0] = header.ddspf.dwRBitMask;
f.masks[1] = header.ddspf.dwGBitMask;
f.masks[2] = header.ddspf.dwBBitMask;
f.masks[3] = header.ddspf.dwABitMask;
return f;
}
DDSHeaders read_dds(const std::string &file_path) {
std::ifstream ddsfile{file_path, std::ios::binary | std::ios::in | std::ios::ate };
auto const file_size = ddsfile.tellg();
auto const chunk_size = sizeof(DDS_HEADER) + sizeof(uint32_t);
if (file_size < chunk_size)
throw std::runtime_error(file_path + " isn't a valid DDS file");
ddsfile.seekg(0);
uint32_t magicNo;
if (!(ddsfile.read(reinterpret_cast<char*>(&magicNo), sizeof(magicNo)) && (magicNo == DDS_ASCII)))
throw std::runtime_error(file_path + " isn't a valid DDS file");
DDS_HEADER header = { };
ddsfile.read(reinterpret_cast<char*>(&header), sizeof(DDS_HEADER));
// read the additional DX10 header, if applicable and available
DDS_HEADER_DXT10 ddsDX10Header = { };
if ((header.ddspf.dwFourCC == FOURCC_DX10) && (file_size >= (chunk_size + sizeof(DDS_HEADER_DXT10)))) {
ddsfile.read(reinterpret_cast<char*>(&ddsDX10Header), sizeof(ddsDX10Header));
}
return {header, ddsDX10Header};
}
bool isVolumeTexture(DWORD caps) {
return caps & DDSCAPS2_VOLUME;
}
bool isCubeTexture(DWORD caps) {
return (caps & DDS_CUBEMAP_ALLFACES) || (caps & DDSCAPS2_CUBEMAP);
}
struct field {
int n;
explicit field(size_t align) : n(align) { }
};
std::ostream& operator<<(std::ostream &os, field f) {
return os << std::left << std::setw(f.n);
}
template <typename T>
inline constexpr size_t str_literal_len(const T&) {
return std::extent<T>::value - 1;
}
void print_dds(DDSHeaders const &headers) {
auto const h = headers.header;
auto const f = parse_flags(h);
if (f.bits[0])
std::cout << str_old_style << ' ';
std::cout << (f.bits[1] ? str_compressed : str_uncompressed) << ' ';
if (isCubeTexture(h.dwCaps2))
std::cout << str_cube_map << ' ';
else if (isVolumeTexture(h.dwCaps2))
std::cout << str_vol_tex << ' ';
std::cout << str_tex << '\n';
// use the longest field length as the field width
auto constexpr fw = str_literal_len(str_field_top_level);
std::cout << field(fw) << str_field_size << h.dwWidth << " × " << h.dwHeight << ' ' << str_pixels << '\n'
<< field(fw) << (f.bits[1] ? str_field_top_level : str_field_pitch)
<< h.dwPitchOrLinearSize << ' ' << str_bytes << '\n';
std::cout << field(fw) << str_field_channels << f.type << '\n';
if (f.bits[1])
std::cout << field(fw) << str_field_fourcc << fourcc(h.ddspf.dwFourCC) << '\n';
else {
std::cout << field(fw) << str_field_bit_cnt << f.bit_count << '\n';
// http://stackoverflow.com/q/1532640/183120
// http://stackoverflow.com/a/1449923/183120
// 12 for "Alpha Mask: ", 16 for "Luminance Mask: "
char const *col[][3] = { { str_field_r_mask, str_field_g_mask, str_field_b_mask },
{ str_field_y_mask, str_field_u_mask, str_field_v_mask }};
auto const i = (f.type & ChannelData::RGB) ? 0 : 1;
if ((f.type & ChannelData::RGB) || (f.type & ChannelData::YUV))
std::cout << field(fw) << col[i][0] << mask(f.masks[0]) << '\n'
<< field(fw) << col[i][1] << mask(f.masks[1]) << '\n'
<< field(fw) << col[i][2] << mask(f.masks[2]) << '\n';
if ((f.type & ChannelData::Alpha) || (f.type & ChannelData::Luminance))
std::cout << field(fw) << ((f.type & ChannelData::Alpha) ? str_field_alpha_mask : str_field_luminance_mask)
<< mask(f.masks[3]) << '\n';
std::cout << std::dec;
}
if (h.ddspf.dwFourCC == FOURCC_DX10) {
auto const &h10 = headers.header10;
std::cout << field(fw) << str_field_dxgi_fmt << h10.dxgiFormat << '\n';
std::cout << field(fw) << str_field_dim << h10.resourceDimension << '\n';
std::cout << field(fw) << str_field_array_cnt << h10.arraySize << '\n';
}
std::cout << field(fw) << str_field_mipmaps << h.dwMipMapCount << '\n';
if (isVolumeTexture(h.dwCaps2))
std::cout << field(fw) << str_field_depth << h.dwDepth << ' '<< str_pixels << '\n';
}
int main(int argc, char *argv[]) {
if (argc < 2) {
std::cout << "Usage: ddsnfo FILE\n";
return -1;
}
DDSHeaders head;
try {
head = read_dds(argv[1]);
}
catch (std::runtime_error &e) {
std::cout << "Read failed: " << argv[1];
return -1;
}
print_dds(head);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment