From e57c8e0a120775e7bbe45257cfccfff4532005af Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Mon, 29 Mar 2021 15:40:06 -0700 Subject: [PATCH] texconv updated with 709 <-> Display P3 color rotation --- Texconv/texconv.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/Texconv/texconv.cpp b/Texconv/texconv.cpp index eb7cb70..16f6892 100644 --- a/Texconv/texconv.cpp +++ b/Texconv/texconv.cpp @@ -132,6 +132,8 @@ namespace ROTATE_2020_TO_709, ROTATE_P3_TO_HDR10, ROTATE_P3_TO_2020, + ROTATE_709_TO_DISPLAY_P3, + ROTATE_DISPLAY_P3_TO_709, }; static_assert(OPT_MAX <= 64, "dwOptions is a DWORD64 bitfield"); @@ -399,6 +401,8 @@ namespace { L"HDR10to709", ROTATE_HDR10_TO_709 }, { L"P3to2020", ROTATE_P3_TO_2020 }, { L"P3toHDR10", ROTATE_P3_TO_HDR10 }, + { L"709toDisplayP3", ROTATE_709_TO_DISPLAY_P3 }, + { L"DisplayP3to709", ROTATE_DISPLAY_P3_TO_709 }, { nullptr, 0 }, }; @@ -1041,6 +1045,7 @@ namespace 0.f, 0.f, 0.f, 1.f }; + // DCI-P3 https://en.wikipedia.org/wiki/DCI-P3 const XMMATRIX c_fromP3to2020 = { 0.753845f, 0.0457456f, -0.00121055f, 0.f, @@ -1049,6 +1054,23 @@ namespace 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) { 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) ------------------------------------------- if (dwRotateColor) { - if (dwRotateColor == ROTATE_HDR10_TO_709) + if (dwRotateColor == ROTATE_HDR10_TO_709 || dwRotateColor == ROTATE_DISPLAY_P3_TO_709) { std::unique_ptr timage(new (std::nothrow) ScratchImage); if (!timage) @@ -2526,6 +2548,44 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) }, *timage); 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: hr = E_NOTIMPL; break;