Portable PixMap reader/writers for texconv (#180)

This commit is contained in:
Chuck Walbourn
2020-06-04 20:07:21 -07:00
committed by GitHub
parent 09fc5fe957
commit 0539287324
10 changed files with 1232 additions and 497 deletions

View File

@@ -53,389 +53,420 @@ using namespace DirectX;
using namespace DirectX::PackedVector;
using Microsoft::WRL::ComPtr;
enum OPTIONS
namespace
{
OPT_RECURSIVE = 1,
OPT_FILELIST,
OPT_WIDTH,
OPT_HEIGHT,
OPT_MIPLEVELS,
OPT_FORMAT,
OPT_FILTER,
OPT_SRGBI,
OPT_SRGBO,
OPT_SRGB,
OPT_PREFIX,
OPT_SUFFIX,
OPT_OUTPUTDIR,
OPT_TOLOWER,
OPT_OVERWRITE,
OPT_FILETYPE,
OPT_HFLIP,
OPT_VFLIP,
OPT_DDS_DWORD_ALIGN,
OPT_DDS_BAD_DXTN_TAILS,
OPT_USE_DX10,
OPT_USE_DX9,
OPT_TGA20,
OPT_WIC_QUALITY,
OPT_WIC_LOSSLESS,
OPT_WIC_MULTIFRAME,
OPT_NOLOGO,
OPT_TIMING,
OPT_SEPALPHA,
OPT_NO_WIC,
OPT_TYPELESS_UNORM,
OPT_TYPELESS_FLOAT,
OPT_PREMUL_ALPHA,
OPT_DEMUL_ALPHA,
OPT_EXPAND_LUMINANCE,
OPT_TA_WRAP,
OPT_TA_MIRROR,
OPT_FORCE_SINGLEPROC,
OPT_GPU,
OPT_NOGPU,
OPT_FEATURE_LEVEL,
OPT_FIT_POWEROF2,
OPT_ALPHA_THRESHOLD,
OPT_ALPHA_WEIGHT,
OPT_NORMAL_MAP,
OPT_NORMAL_MAP_AMPLITUDE,
OPT_BC_COMPRESS,
OPT_COLORKEY,
OPT_TONEMAP,
OPT_X2_BIAS,
OPT_PRESERVE_ALPHA_COVERAGE,
OPT_INVERT_Y,
OPT_ROTATE_COLOR,
OPT_PAPER_WHITE_NITS,
OPT_BCNONMULT4FIX,
OPT_MAX
};
enum OPTIONS
{
OPT_RECURSIVE = 1,
OPT_FILELIST,
OPT_WIDTH,
OPT_HEIGHT,
OPT_MIPLEVELS,
OPT_FORMAT,
OPT_FILTER,
OPT_SRGBI,
OPT_SRGBO,
OPT_SRGB,
OPT_PREFIX,
OPT_SUFFIX,
OPT_OUTPUTDIR,
OPT_TOLOWER,
OPT_OVERWRITE,
OPT_FILETYPE,
OPT_HFLIP,
OPT_VFLIP,
OPT_DDS_DWORD_ALIGN,
OPT_DDS_BAD_DXTN_TAILS,
OPT_USE_DX10,
OPT_USE_DX9,
OPT_TGA20,
OPT_WIC_QUALITY,
OPT_WIC_LOSSLESS,
OPT_WIC_MULTIFRAME,
OPT_NOLOGO,
OPT_TIMING,
OPT_SEPALPHA,
OPT_NO_WIC,
OPT_TYPELESS_UNORM,
OPT_TYPELESS_FLOAT,
OPT_PREMUL_ALPHA,
OPT_DEMUL_ALPHA,
OPT_EXPAND_LUMINANCE,
OPT_TA_WRAP,
OPT_TA_MIRROR,
OPT_FORCE_SINGLEPROC,
OPT_GPU,
OPT_NOGPU,
OPT_FEATURE_LEVEL,
OPT_FIT_POWEROF2,
OPT_ALPHA_THRESHOLD,
OPT_ALPHA_WEIGHT,
OPT_NORMAL_MAP,
OPT_NORMAL_MAP_AMPLITUDE,
OPT_BC_COMPRESS,
OPT_COLORKEY,
OPT_TONEMAP,
OPT_X2_BIAS,
OPT_PRESERVE_ALPHA_COVERAGE,
OPT_INVERT_Y,
OPT_ROTATE_COLOR,
OPT_PAPER_WHITE_NITS,
OPT_BCNONMULT4FIX,
OPT_MAX
};
enum
{
ROTATE_709_TO_HDR10 = 1,
ROTATE_HDR10_TO_709,
ROTATE_709_TO_2020,
ROTATE_2020_TO_709,
ROTATE_P3_TO_HDR10,
ROTATE_P3_TO_2020,
};
enum
{
ROTATE_709_TO_HDR10 = 1,
ROTATE_HDR10_TO_709,
ROTATE_709_TO_2020,
ROTATE_2020_TO_709,
ROTATE_P3_TO_HDR10,
ROTATE_P3_TO_2020,
};
static_assert(OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield");
static_assert(OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield");
struct SConversion
{
wchar_t szSrc[MAX_PATH];
wchar_t szDest[MAX_PATH];
};
struct SConversion
{
wchar_t szSrc[MAX_PATH];
wchar_t szDest[MAX_PATH];
};
struct SValue
{
LPCWSTR pName;
DWORD dwValue;
};
struct SValue
{
LPCWSTR pName;
DWORD dwValue;
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
const SValue g_pOptions[] =
{
{ L"r", OPT_RECURSIVE },
{ L"flist", OPT_FILELIST },
{ L"w", OPT_WIDTH },
{ L"h", OPT_HEIGHT },
{ L"m", OPT_MIPLEVELS },
{ L"f", OPT_FORMAT },
{ L"if", OPT_FILTER },
{ L"srgbi", OPT_SRGBI },
{ L"srgbo", OPT_SRGBO },
{ L"srgb", OPT_SRGB },
{ L"px", OPT_PREFIX },
{ L"sx", OPT_SUFFIX },
{ L"o", OPT_OUTPUTDIR },
{ L"l", OPT_TOLOWER },
{ L"y", OPT_OVERWRITE },
{ L"ft", OPT_FILETYPE },
{ L"hflip", OPT_HFLIP },
{ L"vflip", OPT_VFLIP },
{ L"dword", OPT_DDS_DWORD_ALIGN },
{ L"badtails", OPT_DDS_BAD_DXTN_TAILS },
{ L"dx10", OPT_USE_DX10 },
{ L"dx9", OPT_USE_DX9 },
{ L"tga20", OPT_TGA20 },
{ L"wicq", OPT_WIC_QUALITY },
{ L"wiclossless", OPT_WIC_LOSSLESS },
{ L"wicmulti", OPT_WIC_MULTIFRAME },
{ L"nologo", OPT_NOLOGO },
{ L"timing", OPT_TIMING },
{ L"sepalpha", OPT_SEPALPHA },
{ L"keepcoverage", OPT_PRESERVE_ALPHA_COVERAGE },
{ L"nowic", OPT_NO_WIC },
{ L"tu", OPT_TYPELESS_UNORM },
{ L"tf", OPT_TYPELESS_FLOAT },
{ L"pmalpha", OPT_PREMUL_ALPHA },
{ L"alpha", OPT_DEMUL_ALPHA },
{ L"xlum", OPT_EXPAND_LUMINANCE },
{ L"wrap", OPT_TA_WRAP },
{ L"mirror", OPT_TA_MIRROR },
{ L"singleproc", OPT_FORCE_SINGLEPROC },
{ L"gpu", OPT_GPU },
{ L"nogpu", OPT_NOGPU },
{ L"fl", OPT_FEATURE_LEVEL },
{ L"pow2", OPT_FIT_POWEROF2 },
{ L"at", OPT_ALPHA_THRESHOLD },
{ L"aw", OPT_ALPHA_WEIGHT },
{ L"nmap", OPT_NORMAL_MAP },
{ L"nmapamp", OPT_NORMAL_MAP_AMPLITUDE },
{ L"bc", OPT_BC_COMPRESS },
{ L"c", OPT_COLORKEY },
{ L"tonemap", OPT_TONEMAP },
{ L"x2bias", OPT_X2_BIAS },
{ L"inverty", OPT_INVERT_Y },
{ L"rotatecolor", OPT_ROTATE_COLOR },
{ L"nits", OPT_PAPER_WHITE_NITS },
{ L"fixbc4x4", OPT_BCNONMULT4FIX},
{ nullptr, 0 }
};
const SValue g_pOptions[] =
{
{ L"r", OPT_RECURSIVE },
{ L"flist", OPT_FILELIST },
{ L"w", OPT_WIDTH },
{ L"h", OPT_HEIGHT },
{ L"m", OPT_MIPLEVELS },
{ L"f", OPT_FORMAT },
{ L"if", OPT_FILTER },
{ L"srgbi", OPT_SRGBI },
{ L"srgbo", OPT_SRGBO },
{ L"srgb", OPT_SRGB },
{ L"px", OPT_PREFIX },
{ L"sx", OPT_SUFFIX },
{ L"o", OPT_OUTPUTDIR },
{ L"l", OPT_TOLOWER },
{ L"y", OPT_OVERWRITE },
{ L"ft", OPT_FILETYPE },
{ L"hflip", OPT_HFLIP },
{ L"vflip", OPT_VFLIP },
{ L"dword", OPT_DDS_DWORD_ALIGN },
{ L"badtails", OPT_DDS_BAD_DXTN_TAILS },
{ L"dx10", OPT_USE_DX10 },
{ L"dx9", OPT_USE_DX9 },
{ L"tga20", OPT_TGA20 },
{ L"wicq", OPT_WIC_QUALITY },
{ L"wiclossless", OPT_WIC_LOSSLESS },
{ L"wicmulti", OPT_WIC_MULTIFRAME },
{ L"nologo", OPT_NOLOGO },
{ L"timing", OPT_TIMING },
{ L"sepalpha", OPT_SEPALPHA },
{ L"keepcoverage", OPT_PRESERVE_ALPHA_COVERAGE },
{ L"nowic", OPT_NO_WIC },
{ L"tu", OPT_TYPELESS_UNORM },
{ L"tf", OPT_TYPELESS_FLOAT },
{ L"pmalpha", OPT_PREMUL_ALPHA },
{ L"alpha", OPT_DEMUL_ALPHA },
{ L"xlum", OPT_EXPAND_LUMINANCE },
{ L"wrap", OPT_TA_WRAP },
{ L"mirror", OPT_TA_MIRROR },
{ L"singleproc", OPT_FORCE_SINGLEPROC },
{ L"gpu", OPT_GPU },
{ L"nogpu", OPT_NOGPU },
{ L"fl", OPT_FEATURE_LEVEL },
{ L"pow2", OPT_FIT_POWEROF2 },
{ L"at", OPT_ALPHA_THRESHOLD },
{ L"aw", OPT_ALPHA_WEIGHT },
{ L"nmap", OPT_NORMAL_MAP },
{ L"nmapamp", OPT_NORMAL_MAP_AMPLITUDE },
{ L"bc", OPT_BC_COMPRESS },
{ L"c", OPT_COLORKEY },
{ L"tonemap", OPT_TONEMAP },
{ L"x2bias", OPT_X2_BIAS },
{ L"inverty", OPT_INVERT_Y },
{ L"rotatecolor", OPT_ROTATE_COLOR },
{ L"nits", OPT_PAPER_WHITE_NITS },
{ L"fixbc4x4", OPT_BCNONMULT4FIX},
{ nullptr, 0 }
};
#define DEFFMT(fmt) { L## #fmt, DXGI_FORMAT_ ## fmt }
const SValue g_pFormats[] =
{
// List does not include _TYPELESS or depth/stencil formats
DEFFMT(R32G32B32A32_FLOAT),
DEFFMT(R32G32B32A32_UINT),
DEFFMT(R32G32B32A32_SINT),
DEFFMT(R32G32B32_FLOAT),
DEFFMT(R32G32B32_UINT),
DEFFMT(R32G32B32_SINT),
DEFFMT(R16G16B16A16_FLOAT),
DEFFMT(R16G16B16A16_UNORM),
DEFFMT(R16G16B16A16_UINT),
DEFFMT(R16G16B16A16_SNORM),
DEFFMT(R16G16B16A16_SINT),
DEFFMT(R32G32_FLOAT),
DEFFMT(R32G32_UINT),
DEFFMT(R32G32_SINT),
DEFFMT(R10G10B10A2_UNORM),
DEFFMT(R10G10B10A2_UINT),
DEFFMT(R11G11B10_FLOAT),
DEFFMT(R8G8B8A8_UNORM),
DEFFMT(R8G8B8A8_UNORM_SRGB),
DEFFMT(R8G8B8A8_UINT),
DEFFMT(R8G8B8A8_SNORM),
DEFFMT(R8G8B8A8_SINT),
DEFFMT(R16G16_FLOAT),
DEFFMT(R16G16_UNORM),
DEFFMT(R16G16_UINT),
DEFFMT(R16G16_SNORM),
DEFFMT(R16G16_SINT),
DEFFMT(R32_FLOAT),
DEFFMT(R32_UINT),
DEFFMT(R32_SINT),
DEFFMT(R8G8_UNORM),
DEFFMT(R8G8_UINT),
DEFFMT(R8G8_SNORM),
DEFFMT(R8G8_SINT),
DEFFMT(R16_FLOAT),
DEFFMT(R16_UNORM),
DEFFMT(R16_UINT),
DEFFMT(R16_SNORM),
DEFFMT(R16_SINT),
DEFFMT(R8_UNORM),
DEFFMT(R8_UINT),
DEFFMT(R8_SNORM),
DEFFMT(R8_SINT),
DEFFMT(A8_UNORM),
DEFFMT(R9G9B9E5_SHAREDEXP),
DEFFMT(R8G8_B8G8_UNORM),
DEFFMT(G8R8_G8B8_UNORM),
DEFFMT(BC1_UNORM),
DEFFMT(BC1_UNORM_SRGB),
DEFFMT(BC2_UNORM),
DEFFMT(BC2_UNORM_SRGB),
DEFFMT(BC3_UNORM),
DEFFMT(BC3_UNORM_SRGB),
DEFFMT(BC4_UNORM),
DEFFMT(BC4_SNORM),
DEFFMT(BC5_UNORM),
DEFFMT(BC5_SNORM),
DEFFMT(B5G6R5_UNORM),
DEFFMT(B5G5R5A1_UNORM),
const SValue g_pFormats[] =
{
// List does not include _TYPELESS or depth/stencil formats
DEFFMT(R32G32B32A32_FLOAT),
DEFFMT(R32G32B32A32_UINT),
DEFFMT(R32G32B32A32_SINT),
DEFFMT(R32G32B32_FLOAT),
DEFFMT(R32G32B32_UINT),
DEFFMT(R32G32B32_SINT),
DEFFMT(R16G16B16A16_FLOAT),
DEFFMT(R16G16B16A16_UNORM),
DEFFMT(R16G16B16A16_UINT),
DEFFMT(R16G16B16A16_SNORM),
DEFFMT(R16G16B16A16_SINT),
DEFFMT(R32G32_FLOAT),
DEFFMT(R32G32_UINT),
DEFFMT(R32G32_SINT),
DEFFMT(R10G10B10A2_UNORM),
DEFFMT(R10G10B10A2_UINT),
DEFFMT(R11G11B10_FLOAT),
DEFFMT(R8G8B8A8_UNORM),
DEFFMT(R8G8B8A8_UNORM_SRGB),
DEFFMT(R8G8B8A8_UINT),
DEFFMT(R8G8B8A8_SNORM),
DEFFMT(R8G8B8A8_SINT),
DEFFMT(R16G16_FLOAT),
DEFFMT(R16G16_UNORM),
DEFFMT(R16G16_UINT),
DEFFMT(R16G16_SNORM),
DEFFMT(R16G16_SINT),
DEFFMT(R32_FLOAT),
DEFFMT(R32_UINT),
DEFFMT(R32_SINT),
DEFFMT(R8G8_UNORM),
DEFFMT(R8G8_UINT),
DEFFMT(R8G8_SNORM),
DEFFMT(R8G8_SINT),
DEFFMT(R16_FLOAT),
DEFFMT(R16_UNORM),
DEFFMT(R16_UINT),
DEFFMT(R16_SNORM),
DEFFMT(R16_SINT),
DEFFMT(R8_UNORM),
DEFFMT(R8_UINT),
DEFFMT(R8_SNORM),
DEFFMT(R8_SINT),
DEFFMT(A8_UNORM),
DEFFMT(R9G9B9E5_SHAREDEXP),
DEFFMT(R8G8_B8G8_UNORM),
DEFFMT(G8R8_G8B8_UNORM),
DEFFMT(BC1_UNORM),
DEFFMT(BC1_UNORM_SRGB),
DEFFMT(BC2_UNORM),
DEFFMT(BC2_UNORM_SRGB),
DEFFMT(BC3_UNORM),
DEFFMT(BC3_UNORM_SRGB),
DEFFMT(BC4_UNORM),
DEFFMT(BC4_SNORM),
DEFFMT(BC5_UNORM),
DEFFMT(BC5_SNORM),
DEFFMT(B5G6R5_UNORM),
DEFFMT(B5G5R5A1_UNORM),
// DXGI 1.1 formats
DEFFMT(B8G8R8A8_UNORM),
DEFFMT(B8G8R8X8_UNORM),
DEFFMT(R10G10B10_XR_BIAS_A2_UNORM),
DEFFMT(B8G8R8A8_UNORM_SRGB),
DEFFMT(B8G8R8X8_UNORM_SRGB),
DEFFMT(BC6H_UF16),
DEFFMT(BC6H_SF16),
DEFFMT(BC7_UNORM),
DEFFMT(BC7_UNORM_SRGB),
// DXGI 1.1 formats
DEFFMT(B8G8R8A8_UNORM),
DEFFMT(B8G8R8X8_UNORM),
DEFFMT(R10G10B10_XR_BIAS_A2_UNORM),
DEFFMT(B8G8R8A8_UNORM_SRGB),
DEFFMT(B8G8R8X8_UNORM_SRGB),
DEFFMT(BC6H_UF16),
DEFFMT(BC6H_SF16),
DEFFMT(BC7_UNORM),
DEFFMT(BC7_UNORM_SRGB),
// DXGI 1.2 formats
DEFFMT(AYUV),
DEFFMT(Y410),
DEFFMT(Y416),
DEFFMT(YUY2),
DEFFMT(Y210),
DEFFMT(Y216),
// No support for legacy paletted video formats (AI44, IA44, P8, A8P8)
DEFFMT(B4G4R4A4_UNORM),
// DXGI 1.2 formats
DEFFMT(AYUV),
DEFFMT(Y410),
DEFFMT(Y416),
DEFFMT(YUY2),
DEFFMT(Y210),
DEFFMT(Y216),
// No support for legacy paletted video formats (AI44, IA44, P8, A8P8)
DEFFMT(B4G4R4A4_UNORM),
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
const SValue g_pFormatAliases[] =
{
{ L"DXT1", DXGI_FORMAT_BC1_UNORM },
{ L"DXT2", DXGI_FORMAT_BC2_UNORM },
{ L"DXT3", DXGI_FORMAT_BC2_UNORM },
{ L"DXT4", DXGI_FORMAT_BC3_UNORM },
{ L"DXT5", DXGI_FORMAT_BC3_UNORM },
const SValue g_pFormatAliases[] =
{
{ L"DXT1", DXGI_FORMAT_BC1_UNORM },
{ L"DXT2", DXGI_FORMAT_BC2_UNORM },
{ L"DXT3", DXGI_FORMAT_BC2_UNORM },
{ L"DXT4", DXGI_FORMAT_BC3_UNORM },
{ L"DXT5", DXGI_FORMAT_BC3_UNORM },
{ L"RGBA", DXGI_FORMAT_R8G8B8A8_UNORM },
{ L"BGRA", DXGI_FORMAT_B8G8R8A8_UNORM },
{ L"RGBA", DXGI_FORMAT_R8G8B8A8_UNORM },
{ L"BGRA", DXGI_FORMAT_B8G8R8A8_UNORM },
{ L"FP16", DXGI_FORMAT_R16G16B16A16_FLOAT },
{ L"FP32", DXGI_FORMAT_R32G32B32A32_FLOAT },
{ L"FP16", DXGI_FORMAT_R16G16B16A16_FLOAT },
{ L"FP32", DXGI_FORMAT_R32G32B32A32_FLOAT },
{ L"BPTC", DXGI_FORMAT_BC7_UNORM },
{ L"BPTC_FLOAT", DXGI_FORMAT_BC6H_UF16 },
{ L"BPTC", DXGI_FORMAT_BC7_UNORM },
{ L"BPTC_FLOAT", DXGI_FORMAT_BC6H_UF16 },
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
const SValue g_pReadOnlyFormats[] =
{
DEFFMT(R32G32B32A32_TYPELESS),
DEFFMT(R32G32B32_TYPELESS),
DEFFMT(R16G16B16A16_TYPELESS),
DEFFMT(R32G32_TYPELESS),
DEFFMT(R32G8X24_TYPELESS),
DEFFMT(D32_FLOAT_S8X24_UINT),
DEFFMT(R32_FLOAT_X8X24_TYPELESS),
DEFFMT(X32_TYPELESS_G8X24_UINT),
DEFFMT(R10G10B10A2_TYPELESS),
DEFFMT(R8G8B8A8_TYPELESS),
DEFFMT(R16G16_TYPELESS),
DEFFMT(R32_TYPELESS),
DEFFMT(D32_FLOAT),
DEFFMT(R24G8_TYPELESS),
DEFFMT(D24_UNORM_S8_UINT),
DEFFMT(R24_UNORM_X8_TYPELESS),
DEFFMT(X24_TYPELESS_G8_UINT),
DEFFMT(R8G8_TYPELESS),
DEFFMT(R16_TYPELESS),
DEFFMT(R8_TYPELESS),
DEFFMT(BC1_TYPELESS),
DEFFMT(BC2_TYPELESS),
DEFFMT(BC3_TYPELESS),
DEFFMT(BC4_TYPELESS),
DEFFMT(BC5_TYPELESS),
const SValue g_pReadOnlyFormats[] =
{
DEFFMT(R32G32B32A32_TYPELESS),
DEFFMT(R32G32B32_TYPELESS),
DEFFMT(R16G16B16A16_TYPELESS),
DEFFMT(R32G32_TYPELESS),
DEFFMT(R32G8X24_TYPELESS),
DEFFMT(D32_FLOAT_S8X24_UINT),
DEFFMT(R32_FLOAT_X8X24_TYPELESS),
DEFFMT(X32_TYPELESS_G8X24_UINT),
DEFFMT(R10G10B10A2_TYPELESS),
DEFFMT(R8G8B8A8_TYPELESS),
DEFFMT(R16G16_TYPELESS),
DEFFMT(R32_TYPELESS),
DEFFMT(D32_FLOAT),
DEFFMT(R24G8_TYPELESS),
DEFFMT(D24_UNORM_S8_UINT),
DEFFMT(R24_UNORM_X8_TYPELESS),
DEFFMT(X24_TYPELESS_G8_UINT),
DEFFMT(R8G8_TYPELESS),
DEFFMT(R16_TYPELESS),
DEFFMT(R8_TYPELESS),
DEFFMT(BC1_TYPELESS),
DEFFMT(BC2_TYPELESS),
DEFFMT(BC3_TYPELESS),
DEFFMT(BC4_TYPELESS),
DEFFMT(BC5_TYPELESS),
// DXGI 1.1 formats
DEFFMT(B8G8R8A8_TYPELESS),
DEFFMT(B8G8R8X8_TYPELESS),
DEFFMT(BC6H_TYPELESS),
DEFFMT(BC7_TYPELESS),
// DXGI 1.1 formats
DEFFMT(B8G8R8A8_TYPELESS),
DEFFMT(B8G8R8X8_TYPELESS),
DEFFMT(BC6H_TYPELESS),
DEFFMT(BC7_TYPELESS),
// DXGI 1.2 formats
DEFFMT(NV12),
DEFFMT(P010),
DEFFMT(P016),
DEFFMT(420_OPAQUE),
DEFFMT(NV11),
// DXGI 1.2 formats
DEFFMT(NV12),
DEFFMT(P010),
DEFFMT(P016),
DEFFMT(420_OPAQUE),
DEFFMT(NV11),
// DXGI 1.3 formats
{ L"P208", DXGI_FORMAT(130) },
{ L"V208", DXGI_FORMAT(131) },
{ L"V408", DXGI_FORMAT(132) },
// DXGI 1.3 formats
{ L"P208", DXGI_FORMAT(130) },
{ L"V208", DXGI_FORMAT(131) },
{ L"V408", DXGI_FORMAT(132) },
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
{ nullptr, DXGI_FORMAT_UNKNOWN }
};
const SValue g_pFilters[] =
{
{ L"POINT", TEX_FILTER_POINT },
{ L"LINEAR", TEX_FILTER_LINEAR },
{ L"CUBIC", TEX_FILTER_CUBIC },
{ L"FANT", TEX_FILTER_FANT },
{ L"BOX", TEX_FILTER_BOX },
{ L"TRIANGLE", TEX_FILTER_TRIANGLE },
{ L"POINT_DITHER", TEX_FILTER_POINT | TEX_FILTER_DITHER },
{ L"LINEAR_DITHER", TEX_FILTER_LINEAR | TEX_FILTER_DITHER },
{ L"CUBIC_DITHER", TEX_FILTER_CUBIC | TEX_FILTER_DITHER },
{ L"FANT_DITHER", TEX_FILTER_FANT | TEX_FILTER_DITHER },
{ L"BOX_DITHER", TEX_FILTER_BOX | TEX_FILTER_DITHER },
{ L"TRIANGLE_DITHER", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER },
{ L"POINT_DITHER_DIFFUSION", TEX_FILTER_POINT | TEX_FILTER_DITHER_DIFFUSION },
{ L"LINEAR_DITHER_DIFFUSION", TEX_FILTER_LINEAR | TEX_FILTER_DITHER_DIFFUSION },
{ L"CUBIC_DITHER_DIFFUSION", TEX_FILTER_CUBIC | TEX_FILTER_DITHER_DIFFUSION },
{ L"FANT_DITHER_DIFFUSION", TEX_FILTER_FANT | TEX_FILTER_DITHER_DIFFUSION },
{ L"BOX_DITHER_DIFFUSION", TEX_FILTER_BOX | TEX_FILTER_DITHER_DIFFUSION },
{ L"TRIANGLE_DITHER_DIFFUSION", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER_DIFFUSION },
{ nullptr, TEX_FILTER_DEFAULT }
};
const SValue g_pFilters[] =
{
{ L"POINT", TEX_FILTER_POINT },
{ L"LINEAR", TEX_FILTER_LINEAR },
{ L"CUBIC", TEX_FILTER_CUBIC },
{ L"FANT", TEX_FILTER_FANT },
{ L"BOX", TEX_FILTER_BOX },
{ L"TRIANGLE", TEX_FILTER_TRIANGLE },
{ L"POINT_DITHER", TEX_FILTER_POINT | TEX_FILTER_DITHER },
{ L"LINEAR_DITHER", TEX_FILTER_LINEAR | TEX_FILTER_DITHER },
{ L"CUBIC_DITHER", TEX_FILTER_CUBIC | TEX_FILTER_DITHER },
{ L"FANT_DITHER", TEX_FILTER_FANT | TEX_FILTER_DITHER },
{ L"BOX_DITHER", TEX_FILTER_BOX | TEX_FILTER_DITHER },
{ L"TRIANGLE_DITHER", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER },
{ L"POINT_DITHER_DIFFUSION", TEX_FILTER_POINT | TEX_FILTER_DITHER_DIFFUSION },
{ L"LINEAR_DITHER_DIFFUSION", TEX_FILTER_LINEAR | TEX_FILTER_DITHER_DIFFUSION },
{ L"CUBIC_DITHER_DIFFUSION", TEX_FILTER_CUBIC | TEX_FILTER_DITHER_DIFFUSION },
{ L"FANT_DITHER_DIFFUSION", TEX_FILTER_FANT | TEX_FILTER_DITHER_DIFFUSION },
{ L"BOX_DITHER_DIFFUSION", TEX_FILTER_BOX | TEX_FILTER_DITHER_DIFFUSION },
{ L"TRIANGLE_DITHER_DIFFUSION", TEX_FILTER_TRIANGLE | TEX_FILTER_DITHER_DIFFUSION },
{ nullptr, TEX_FILTER_DEFAULT }
};
const SValue g_pRotateColor[] =
{
{ L"709to2020", ROTATE_709_TO_2020 },
{ L"2020to709", ROTATE_2020_TO_709 },
{ L"709toHDR10", ROTATE_709_TO_HDR10 },
{ L"HDR10to709", ROTATE_HDR10_TO_709 },
{ L"P3to2020", ROTATE_P3_TO_2020 },
{ L"P3toHDR10", ROTATE_P3_TO_HDR10 },
{ nullptr, 0 },
};
const SValue g_pRotateColor[] =
{
{ L"709to2020", ROTATE_709_TO_2020 },
{ L"2020to709", ROTATE_2020_TO_709 },
{ L"709toHDR10", ROTATE_709_TO_HDR10 },
{ L"HDR10to709", ROTATE_HDR10_TO_709 },
{ L"P3to2020", ROTATE_P3_TO_2020 },
{ L"P3toHDR10", ROTATE_P3_TO_HDR10 },
{ nullptr, 0 },
};
#define CODEC_DDS 0xFFFF0001
#define CODEC_TGA 0xFFFF0002
#define CODEC_HDP 0xFFFF0003
#define CODEC_JXR 0xFFFF0004
#define CODEC_HDR 0xFFFF0005
#define CODEC_PPM 0xFFFF0006
#define CODEC_PFM 0xFFFF0007
#ifdef USE_OPENEXR
#define CODEC_EXR 0xFFFF0006
#define CODEC_EXR 0xFFFF0008
#endif
const SValue g_pSaveFileTypes[] = // valid formats to write to
{
{ L"BMP", WIC_CODEC_BMP },
{ L"JPG", WIC_CODEC_JPEG },
{ L"JPEG", WIC_CODEC_JPEG },
{ L"PNG", WIC_CODEC_PNG },
{ L"DDS", CODEC_DDS },
{ L"TGA", CODEC_TGA },
{ L"HDR", CODEC_HDR },
{ L"TIF", WIC_CODEC_TIFF },
{ L"TIFF", WIC_CODEC_TIFF },
{ L"WDP", WIC_CODEC_WMP },
{ L"HDP", CODEC_HDP },
{ L"JXR", CODEC_JXR },
#ifdef USE_OPENEXR
{ L"EXR", CODEC_EXR },
#endif
{ nullptr, CODEC_DDS }
};
const SValue g_pSaveFileTypes[] = // valid formats to write to
{
{ L"BMP", WIC_CODEC_BMP },
{ L"JPG", WIC_CODEC_JPEG },
{ L"JPEG", WIC_CODEC_JPEG },
{ L"PNG", WIC_CODEC_PNG },
{ L"DDS", CODEC_DDS },
{ L"TGA", CODEC_TGA },
{ L"HDR", CODEC_HDR },
{ L"TIF", WIC_CODEC_TIFF },
{ L"TIFF", WIC_CODEC_TIFF },
{ L"WDP", WIC_CODEC_WMP },
{ L"HDP", CODEC_HDP },
{ L"JXR", CODEC_JXR },
{ L"PPM", CODEC_PPM },
{ L"PFM", CODEC_PFM },
#ifdef USE_OPENEXR
{ L"EXR", CODEC_EXR },
#endif
{ nullptr, CODEC_DDS }
};
const SValue g_pFeatureLevels[] = // valid feature levels for -fl for maximimum size
{
{ L"9.1", 2048 },
{ L"9.2", 2048 },
{ L"9.3", 4096 },
{ L"10.0", 8192 },
{ L"10.1", 8192 },
{ L"11.0", 16384 },
{ L"11.1", 16384 },
{ L"12.0", 16384 },
{ L"12.1", 16384 },
{ nullptr, 0 },
};
const SValue g_pFeatureLevels[] = // valid feature levels for -fl for maximimum size
{
{ L"9.1", 2048 },
{ L"9.2", 2048 },
{ L"9.3", 4096 },
{ L"10.0", 8192 },
{ L"10.1", 8192 },
{ L"11.0", 16384 },
{ L"11.1", 16384 },
{ L"12.0", 16384 },
{ L"12.1", 16384 },
{ nullptr, 0 },
};
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
HRESULT __cdecl LoadFromBMPEx(
_In_z_ const wchar_t* szFile,
_In_ WIC_FLAGS flags,
_Out_opt_ TexMetadata* metadata,
_Out_ ScratchImage& image) noexcept;
HRESULT __cdecl LoadFromPortablePixMap(
_In_z_ const wchar_t* szFile,
_Out_opt_ TexMetadata* metadata,
_Out_ ScratchImage& image) noexcept;
HRESULT __cdecl SaveToPortablePixMap(
_In_ const Image& image,
_In_z_ const wchar_t* szFile) noexcept;
HRESULT __cdecl LoadFromPortablePixMapHDR(
_In_z_ const wchar_t* szFile,
_Out_opt_ TexMetadata* metadata,
_Out_ ScratchImage& image) noexcept;
HRESULT __cdecl SaveToPortablePixMapHDR(
_In_ const Image& image,
_In_z_ const wchar_t* szFile) noexcept;
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -445,13 +476,9 @@ const SValue g_pFeatureLevels[] = // valid feature levels for -fl for maximimu
namespace
{
inline HANDLE safe_handle(HANDLE h) { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
struct handle_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>;
struct find_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
struct find_closer { void operator()(HANDLE h) noexcept { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
using ScopedFindHandle = std::unique_ptr<void, find_closer>;
@@ -984,127 +1011,6 @@ namespace
float normalizedLinear = pow(std::max(pow(abs(ST2084), 1.0f / 78.84375f) - 0.8359375f, 0.0f) / (18.8515625f - 18.6875f * pow(abs(ST2084), 1.0f / 78.84375f)), 1.0f / 0.1593017578f);
return normalizedLinear;
}
HRESULT ReadData(_In_z_ const wchar_t* szFile, std::unique_ptr<uint8_t[]>& blob, size_t& bmpSize)
{
blob.reset();
ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
if (!hFile)
{
return HRESULT_FROM_WIN32(GetLastError());
}
// Get the file size
FILE_STANDARD_INFO fileInfo;
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
{
return HRESULT_FROM_WIN32(GetLastError());
}
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough)
if (fileInfo.EndOfFile.HighPart > 0)
{
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
}
// Zero-sized files assumed to be invalid
if (fileInfo.EndOfFile.LowPart < 1)
{
return E_FAIL;
}
// Read file
blob.reset(new (std::nothrow) uint8_t[fileInfo.EndOfFile.LowPart]);
if (!blob)
{
return E_OUTOFMEMORY;
}
DWORD bytesRead = 0;
if (!ReadFile(hFile.get(), blob.get(), fileInfo.EndOfFile.LowPart, &bytesRead, nullptr))
{
return HRESULT_FROM_WIN32(GetLastError());
}
if (bytesRead != fileInfo.EndOfFile.LowPart)
{
return E_FAIL;
}
bmpSize = fileInfo.EndOfFile.LowPart;
return S_OK;
}
HRESULT LoadFromExtendedBMPMemory(_In_reads_bytes_(size) const void* pSource, _In_ size_t size, _Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image)
{
// This loads from non-standard BMP files that are not supported by WIC
image.Release();
if (size < (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)))
return E_FAIL;
// Valid BMP files always start with 'BM' at the top
auto filehdr = reinterpret_cast<const BITMAPFILEHEADER*>(pSource);
if (filehdr->bfType != 0x4D42)
return E_FAIL;
if (size < filehdr->bfOffBits)
return E_FAIL;
auto header = reinterpret_cast<const BITMAPINFOHEADER*>(reinterpret_cast<const uint8_t*>(pSource) + sizeof(BITMAPFILEHEADER));
if (header->biSize != sizeof(BITMAPINFOHEADER))
return E_FAIL;
if (header->biWidth < 1 || header->biHeight < 1 || header->biPlanes != 1 || header->biBitCount != 16)
{
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
switch (header->biCompression)
{
case 0x31545844: // FourCC "DXT1"
format = DXGI_FORMAT_BC1_UNORM;
break;
case 0x33545844: // FourCC "DXT3"
format = DXGI_FORMAT_BC2_UNORM;
break;
case 0x35545844: // FourCC "DXT5"
format = DXGI_FORMAT_BC3_UNORM;
break;
default:
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
HRESULT hr = image.Initialize2D(format, size_t(header->biWidth), size_t(header->biHeight), 1, 1);
if (FAILED(hr))
return hr;
if (header->biSizeImage != image.GetPixelsSize())
return E_UNEXPECTED;
size_t remaining = size - filehdr->bfOffBits;
if (!remaining)
return E_FAIL;
if (remaining < image.GetPixelsSize())
return E_UNEXPECTED;
auto pixels = reinterpret_cast<const uint8_t*>(pSource) + filehdr->bfOffBits;
memcpy(image.GetPixels(), pixels, image.GetPixelsSize());
if (metadata)
{
*metadata = image.GetMetadata();
}
return S_OK;
}
}
//--------------------------------------------------------------------------------------
@@ -1803,20 +1709,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
else if (_wcsicmp(ext, L".bmp") == 0)
{
std::unique_ptr<uint8_t[]> bmpData;
size_t bmpSize;
hr = ReadData(pConv->szSrc, bmpData, bmpSize);
if (SUCCEEDED(hr))
{
hr = LoadFromWICMemory(bmpData.get(), bmpSize, WIC_FLAGS_NONE | dwFilter, &info, *image);
if (FAILED(hr))
{
if (SUCCEEDED(LoadFromExtendedBMPMemory(bmpData.get(), bmpSize, &info, *image)))
{
hr = S_OK;
}
}
}
hr = LoadFromBMPEx(pConv->szSrc, WIC_FLAGS_NONE | dwFilter, &info, *image);
if (FAILED(hr))
{
wprintf(L" FAILED (%x)\n", static_cast<unsigned int>(hr));
@@ -1841,6 +1734,24 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
continue;
}
}
else if (_wcsicmp(ext, L".ppm") == 0)
{
hr = LoadFromPortablePixMap(pConv->szSrc, &info, *image);
if (FAILED(hr))
{
wprintf(L" FAILED (%x)\n", static_cast<unsigned int>(hr));
continue;
}
}
else if (_wcsicmp(ext, L".pfm") == 0)
{
hr = LoadFromPortablePixMapHDR(pConv->szSrc, &info, *image);
if (FAILED(hr))
{
wprintf(L" FAILED (%x)\n", static_cast<unsigned int>(hr));
continue;
}
}
#ifdef USE_OPENEXR
else if (_wcsicmp(ext, L".exr") == 0)
{
@@ -3146,6 +3057,14 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
hr = SaveToHDRFile(img[0], pConv->szDest);
break;
case CODEC_PPM:
hr = SaveToPortablePixMap(img[0], pConv->szDest);
break;
case CODEC_PFM:
hr = SaveToPortablePixMapHDR(img[0], pConv->szDest);
break;
#ifdef USE_OPENEXR
case CODEC_EXR:
hr = SaveToEXRFile(img[0], pConv->szDest);