texconv updated with 709 <-> Display P3 color rotation

This commit is contained in:
Chuck Walbourn 2021-03-29 15:40:06 -07:00
parent eda513ceba
commit e57c8e0a12

View File

@ -132,6 +132,8 @@ namespace
ROTATE_2020_TO_709, ROTATE_2020_TO_709,
ROTATE_P3_TO_HDR10, ROTATE_P3_TO_HDR10,
ROTATE_P3_TO_2020, ROTATE_P3_TO_2020,
ROTATE_709_TO_DISPLAY_P3,
ROTATE_DISPLAY_P3_TO_709,
}; };
static_assert(OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield"); static_assert(OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield");
@ -399,6 +401,8 @@ namespace
{ L"HDR10to709", ROTATE_HDR10_TO_709 }, { L"HDR10to709", ROTATE_HDR10_TO_709 },
{ L"P3to2020", ROTATE_P3_TO_2020 }, { L"P3to2020", ROTATE_P3_TO_2020 },
{ L"P3toHDR10", ROTATE_P3_TO_HDR10 }, { L"P3toHDR10", ROTATE_P3_TO_HDR10 },
{ L"709toDisplayP3", ROTATE_709_TO_DISPLAY_P3 },
{ L"DisplayP3to709", ROTATE_DISPLAY_P3_TO_709 },
{ nullptr, 0 }, { nullptr, 0 },
}; };
@ -1041,6 +1045,7 @@ namespace
0.f, 0.f, 0.f, 1.f 0.f, 0.f, 0.f, 1.f
}; };
// DCI-P3 https://en.wikipedia.org/wiki/DCI-P3
const XMMATRIX c_fromP3to2020 = const XMMATRIX c_fromP3to2020 =
{ {
0.753845f, 0.0457456f, -0.00121055f, 0.f, 0.753845f, 0.0457456f, -0.00121055f, 0.f,
@ -1049,6 +1054,23 @@ namespace
0.f, 0.f, 0.f, 1.f 0.f, 0.f, 0.f, 1.f
}; };
// Display P3 (P3D65)
const XMMATRIX c_from709toDisplayP3 =
{
0.822461969f, 0.033194199f, 0.017082631f, 0.f,
0.1775380f, 0.9668058f, 0.0723974f, 0.f,
0.0000000f, 0.0000000f, 0.9105199f, 0.f,
0.f, 0.f, 0.f, 1.f
};
const XMMATRIX c_fromDisplayP3to709 =
{
1.224940176f, -0.042056955f, -0.019637555f, 0.f,
-0.224940176f, 1.042056955f, -0.078636046f, 0.f,
0.0000000f, 0.0000000f, 1.098273600f, 0.f,
0.f, 0.f, 0.f, 1.f
};
inline float LinearToST2084(float normalizedLinearValue) inline float LinearToST2084(float normalizedLinearValue)
{ {
float ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), 0.1593017578f)), 78.84375f); float ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), 0.1593017578f)), 78.84375f);
@ -2325,7 +2347,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
// --- Color rotation (if requested) ------------------------------------------- // --- Color rotation (if requested) -------------------------------------------
if (dwRotateColor) if (dwRotateColor)
{ {
if (dwRotateColor == ROTATE_HDR10_TO_709) if (dwRotateColor == ROTATE_HDR10_TO_709 || dwRotateColor == ROTATE_DISPLAY_P3_TO_709)
{ {
std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage); std::unique_ptr<ScratchImage> timage(new (std::nothrow) ScratchImage);
if (!timage) if (!timage)
@ -2526,6 +2548,44 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}, *timage); }, *timage);
break; break;
case ROTATE_709_TO_DISPLAY_P3:
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t w, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < w; ++j)
{
XMVECTOR value = inPixels[j];
XMVECTOR nvalue = XMVector3Transform(value, c_from709toDisplayP3);
value = XMVectorSelect(value, nvalue, g_XMSelect1110);
outPixels[j] = value;
}
}, *timage);
break;
case ROTATE_DISPLAY_P3_TO_709:
hr = TransformImage(image->GetImages(), image->GetImageCount(), image->GetMetadata(),
[&](XMVECTOR* outPixels, const XMVECTOR* inPixels, size_t w, size_t y)
{
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < w; ++j)
{
XMVECTOR value = inPixels[j];
XMVECTOR nvalue = XMVector3Transform(value, c_fromDisplayP3to709);
value = XMVectorSelect(value, nvalue, g_XMSelect1110);
outPixels[j] = value;
}
}, *timage);
break;
default: default:
hr = E_NOTIMPL; hr = E_NOTIMPL;
break; break;