From f0e600684f47b1d4f067b756f743b8ec93fc0858 Mon Sep 17 00:00:00 2001 From: "Andon M. Coleman" Date: Mon, 2 Sep 2024 20:07:07 -0400 Subject: [PATCH] Fix birghtness on HDR->SDR snips Remove "Close" option from cluttered context menu --- src/SKIV.cpp | 13 ++++++- src/tabs/viewer.cpp | 36 +++++++++++++++-- src/utility/image.cpp | 89 +++++++++++++++++++++++++++---------------- 3 files changed, 100 insertions(+), 38 deletions(-) diff --git a/src/SKIV.cpp b/src/SKIV.cpp index 28685a5..5fa6f6f 100644 --- a/src/SKIV.cpp +++ b/src/SKIV.cpp @@ -181,6 +181,7 @@ UITab SKIF_Tab_Selected = UITab_Viewer, extern PopupState OpenFileDialog; // Viewer: open file dialog extern PopupState SaveFileDialog; // Viewer: save file dialog extern PopupState ExportSDRDialog; // Viewer: export sdr dialog +extern PopupState ConfigEncoders; // Viewer: configure image encoders // Variables related to the display SKIF is visible on ImVec2 windowPos; @@ -1343,7 +1344,8 @@ wWinMain ( _In_ HINSTANCE hInstance, hotkeyCtrlV = false, // Paste data through the clipboard hotkeyCtrlN = false, // Minimize app hotkeyCtrlS = false, - hotkeyCtrlX = false; + hotkeyCtrlX = false, + hotkeyCtrlB = false; // Encoder Config // Handled in viewer.cpp //hotkeyCtrl1 = (io.KeyCtrl && ImGui::GetKeyData (ImGuiKey_1 )->DownDuration == 0.0f), // Viewer -> Image Scaling: View actual size (1:1 / None) @@ -1592,6 +1594,7 @@ wWinMain ( _In_ HINSTANCE hInstance, hotkeyCtrlN = (io.KeyCtrl && ImGui::GetKeyData (ImGuiKey_N )->DownDuration == 0.0f); // Minimize app hotkeyCtrlS = (io.KeyCtrl && ImGui::GetKeyData (ImGuiKey_S )->DownDuration == 0.0f); // Save Current Image (in same Dynamic Range) hotkeyCtrlX = (io.KeyCtrl && ImGui::GetKeyData (ImGuiKey_X )->DownDuration == 0.0f); // Export Current Image (HDR -> SDR) + hotkeyCtrlB = (io.KeyCtrl && ImGui::GetKeyData (ImGuiKey_E )->DownDuration == 0.0f); // Configure Image Encoders const bool hotkeyCycleScaling = ImGui::IsKeyPressed (ImGuiKey_GamepadL3); const bool hotkeyCycleVisualization = ImGui::IsKeyPressed (ImGuiKey_GamepadR3); @@ -1870,6 +1873,14 @@ wWinMain ( _In_ HINSTANCE hInstance, if (hotkeyCtrlS) SaveFileDialog = PopupState_Open; } + + if (allowShortcutCtrlA && hotkeyCtrlB) + { + if (SKIF_Tab_Selected != UITab_Viewer) + SKIF_Tab_ChangeTo = UITab_Viewer; + + ConfigEncoders = PopupState_Open; + } } allowShortcutCtrlA = true; diff --git a/src/tabs/viewer.cpp b/src/tabs/viewer.cpp index da4594c..7c4d136 100644 --- a/src/tabs/viewer.cpp +++ b/src/tabs/viewer.cpp @@ -429,6 +429,7 @@ PopupState OpenFileDialog = PopupState_Closed; PopupState SaveFileDialog = PopupState_Closed; PopupState ExportSDRDialog = PopupState_Closed; PopupState ContextMenu = PopupState_Closed; +PopupState ConfigEncoders = PopupState_Closed; struct image_s { struct file_s { @@ -1569,9 +1570,11 @@ LoadLibraryTexture (image_s& image) meta.dimension = DirectX::TEX_DIMENSION_TEXTURE2D; void* pixels_buffer = static_cast (temp_img.GetPixels ()); - size_t pixels_buffer_size = temp_img.GetPixelsSize (); +#ifdef _DEBUG + size_t pixels_buffer_size = temp_img.GetPixelsSize (); assert (pixels_buffer_size >= rgb.rowBytes * rgb.height); +#endif memcpy (pixels_buffer, rgb.pixels, rgb.rowBytes * rgb.height); @@ -3716,6 +3719,30 @@ SKIF_UI_Tab_DrawViewer (void) if (ContextMenu == PopupState_Open) ImGui::OpenPopup ("ContextMenu"); + + if (ConfigEncoders == PopupState_Open) + { + ImGui::OpenPopup ("ConfigEncoders"); + ConfigEncoders = PopupState_Opened; + } + + if (ConfigEncoders == PopupState_Opened) + { + if (ImGui::BeginPopup ("ConfigEncoders", ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize)) + { + if (ImGui::Button ("Save")) + { + ImGui::CloseCurrentPopup (); + } + ImGui::EndPopup (); + } + + else + { + ConfigEncoders = PopupState_Closed; + } + } + if (ImGui::BeginPopup ("ContextMenu", ImGuiWindowFlags_NoMove)) { ContextMenu = PopupState_Opened; @@ -3747,13 +3774,15 @@ SKIF_UI_Tab_DrawViewer (void) if (cover.is_hdr && SKIF_ImGui_MenuItemEx2 ("Export to SDR", ICON_FA_FILE_EXPORT, ImGui::GetStyleColorVec4(ImGuiCol_Text), "Ctrl+X")) ExportSDRDialog = PopupState_Open; + //if (SKIF_ImGui_MenuItemEx2 ("Encoder Setup", ICON_FA_GEARS, ImGui::GetStyleColorVec4(ImGuiCol_Text), "Ctrl+B")) + // ConfigEncoders = PopupState_Open; if (//cover.is_hdr && SKIF_ImGui_MenuItemEx2 ("Copy", ICON_FA_CLIPBOARD, ImGui::GetStyleColorVec4(ImGuiCol_Text), "Ctrl+C")) { wantCopyToClipboard = true; } - if (SKIF_ImGui_MenuItemEx2 ("Close", 0, ImGui::GetStyleColorVec4(ImGuiCol_SKIF_Info), "Ctrl+W")) - _SwapOutCover (); + //if (SKIF_ImGui_MenuItemEx2 ("Close", 0, ImGui::GetStyleColorVec4(ImGuiCol_SKIF_Info), "Ctrl+W")) + // _SwapOutCover (); // Image scaling @@ -4146,7 +4175,6 @@ SKIF_UI_Tab_DrawViewer (void) SaveFileDialog = PopupState_Closed; } - if (ExportSDRDialog == PopupState_Open) { ExportSDRDialog = PopupState_Opened; diff --git a/src/utility/image.cpp b/src/utility/image.cpp index 697264f..36512a8 100644 --- a/src/utility/image.cpp +++ b/src/utility/image.cpp @@ -1326,6 +1326,56 @@ SKIV_Image_TonemapToSDR (const DirectX::Image& image, DirectX::ScratchImage& fin } }); + if (XMVectorGetY (maxLum) > std::max (1.0f, (mastering_sdr_nits * 1.00333f) / 80.0f)) + { + needs_tonemapping = true; + } + + const float fLumRange = + XMVectorGetY (maxLum) - XMVectorGetY (minLum); + + auto luminance_freq = std::make_unique (65536); + ZeroMemory (luminance_freq.get (), sizeof (uint32_t) * 65536); + + EvaluateImage ( *scrgb.GetImage (0,0,0), + [&](const XMVECTOR* pixels, size_t width, size_t y) + { + UNREFERENCED_PARAMETER(y); + + for (size_t j = 0; j < width; ++j) + { + XMVECTOR v = *pixels++; + + v = + XMVectorMax (g_XMZero, XMVector3Transform (v, c_from709toXYZ)); + + luminance_freq [ + std::clamp ( (int) + std::roundf ( + (XMVectorGetY (v) - XMVectorGetY (minLum)) / + (fLumRange / 65536.0f) ), + 0, 65535 ) ]++; + } + }); + + double percent = 100.0; + const double img_size = (double)image.width * + (double)image.height; + + for (auto i = 65535; i >= 0; --i) + { + percent -= + 100.0 * ((double)luminance_freq [i] / img_size); + + if (percent <= 99.5) + { + maxLum = + XMVectorReplicate (XMVectorGetY (minLum) + (fLumRange * ((float)i / 65536.0f))); + + break; + } + } + PLOG_INFO << "SKIV_Image_TonemapToSDR ( ): EvaluateImageEnd"; // After tonemapping, re-normalize the image to preserve peak white, @@ -1334,25 +1384,16 @@ SKIV_Image_TonemapToSDR (const DirectX::Image& image, DirectX::ScratchImage& fin // If it's too bright, don't bother trying to tonemap the full range... const float _maxNitsToTonemap = (mastering_max_nits != 0.0f ? mastering_max_nits - : 1000.0f) / 80.0f; + : 1500.0f) / 80.0f; - const float SDR_YInPQ = // Use the user's desktop SDR white level - SKIV_Image_LinearToPQY (mastering_sdr_nits / 80.0f); + const float SDR_YInPQ = + SKIV_Image_LinearToPQY (1.5f); const float maxYInPQ = std::max (SDR_YInPQ, SKIV_Image_LinearToPQY (std::min (_maxNitsToTonemap, XMVectorGetY (maxLum))) ); - if (XMVectorGetY (maxLum) > std::max (1.0f, (mastering_sdr_nits * 1.00333f) / 80.0f)) - { - needs_tonemapping = true; - } - - const XMVECTOR vLumaRescale = - XMVectorReplicate (1.0f/std::max (1.0f, (mastering_sdr_nits * 0.99667f) / 80.0f)); // user's SDR white level - - PLOG_INFO << "SKIV_Image_TonemapToSDR ( ): TransformImageBegin"; TransformImage ( scrgb.GetImages (), scrgb.GetImageCount (), scrgb.GetMetadata (), @@ -1373,12 +1414,8 @@ SKIV_Image_TonemapToSDR (const DirectX::Image& image, DirectX::ScratchImage& fin { XMVECTOR value = inPixels [j]; - value = - XMVectorMultiply (value, vLumaRescale); - if (needs_tonemapping) { -#if 1 XMVECTOR ICtCp = SKIV_Image_Rec709toICtCp (value); @@ -1390,7 +1427,8 @@ SKIV_Image_TonemapToSDR (const DirectX::Image& image, DirectX::ScratchImage& fin if (Y_out + Y_in > 0.0f) { - ICtCp.m128_f32 [0] = std::pow (Y_in, 1.18f); + ICtCp.m128_f32 [0] = + std::pow (Y_in, 1.18f); float I0 = XMVectorGetX (ICtCp); float I1 = 0.0f; @@ -1413,22 +1451,6 @@ SKIV_Image_TonemapToSDR (const DirectX::Image& image, DirectX::ScratchImage& fin value = SKIV_Image_ICtCptoRec709 (ICtCp); -#else - XMVECTOR xyz = - XMVector3Transform (value, c_from709toXYZ); - - float Y_in = std::max (XMVectorGetY (xyz), 0.0f); - float Y_out = 1.0f; - - Y_out = - TonemapHDR (Y_in, maxY, SDR_Y); - - if (Y_out + Y_in > 0.0f) - { - value = - XMVectorMultiply (XMVector3Normalize (value), XMVectorReplicate (Y_out)); - } -#endif maxTonemappedRGB = XMVectorMax (maxTonemappedRGB, XMVectorMax (value, g_XMZero)); @@ -2971,6 +2993,7 @@ SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileNa encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY; encoder->maxQuantizer = AVIF_QUANTIZER_BEST_QUALITY; encoder->codecChoice = AVIF_CODEC_CHOICE_AUTO; + encoder->speed = AVIF_SPEED_FASTEST; addResult = SK_avifEncoderAddImage (encoder, avif_image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE); encodeResult = SK_avifEncoderFinish (encoder, &avifOutput);