From d027ad6d792e4fe51b8101a6eaa3575acf40b942 Mon Sep 17 00:00:00 2001 From: "Andon M. Coleman" Date: Wed, 4 Sep 2024 15:38:33 -0400 Subject: [PATCH] Implement encoder configuration (stored in registry for JPEG XL, AVIF and PNG) --- include/utility/registry.h | 54 ++++++++++++++++++++++++++++++++++ src/tabs/viewer.cpp | 60 ++++++++++++++++++++------------------ src/utility/image.cpp | 18 +++++++----- src/utility/registry.cpp | 21 +++++++++++++ 4 files changed, 116 insertions(+), 37 deletions(-) diff --git a/include/utility/registry.h b/include/utility/registry.h index ed8a0d0..e9f1745 100644 --- a/include/utility/registry.h +++ b/include/utility/registry.h @@ -311,6 +311,38 @@ struct SKIF_RegistrySettings { SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\)", LR"(Diagnostics)" ); + KeyValue regKVAVIFQuality = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\AVIF\)", + LR"(Quality)" ); + + KeyValue regKVAVIFSpeed = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\AVIF\)", + LR"(Speed)" ); + + KeyValue regKVAVIFHDRBitDepth = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\AVIF\)", + LR"(HDR BitDepth)" ); + + KeyValue regKVJXLQuality = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\JPEG XL\)", + LR"(Quality)" ); + + KeyValue regKVJXLSpeed = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\JPEG XL\)", + LR"(Speed)" ); + + KeyValue regKVJXLHDRBitDepth = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\JPEG XL\)", + LR"(HDR BitDepth)" ); + + KeyValue regKVJXRQuality = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\JPEG XR\)", + LR"(Quality)" ); + + KeyValue regKVPNGHDRBitDepth = + SKIF_MakeRegKeyI ( LR"(SOFTWARE\Kaldaien\Special K\Viewer\PNG\)", + LR"(HDR BitDepth)" ); + // Wide Strings KeyValue regKVIgnoreUpdate = @@ -429,6 +461,28 @@ struct SKIF_RegistrySettings { std::wstring wsDefaultHDRExt = L".png"; std::wstring wsDefaultSDRExt = L".png"; + // Encoder config + struct { + int hdr_bitdepth = 12; + int quality = 100; + int speed = 10; + int yuv_sampling = 444; + } avif; + + struct { + int quality = 100; + } jxr; + + struct { + int quality = 100; + int speed = 10; + int hdr_bitdepth = 16; + } jxl; + + struct { + int hdr_bitdepth = 16; + } png; + // Windows stuff std::wstring wsAppRegistration; int iNotificationsDuration = 5; // Defaults to 5 seconds in case Windows is not set to something else diff --git a/src/tabs/viewer.cpp b/src/tabs/viewer.cpp index 3d85359..1e20758 100644 --- a/src/tabs/viewer.cpp +++ b/src/tabs/viewer.cpp @@ -3736,52 +3736,54 @@ SKIF_UI_Tab_DrawViewer (void) if (ImGui::BeginTabItem ("AVIF", nullptr, ImGuiTabItemFlags_NoTooltip)) { selection = 0; - //ImGui::TextUnformatted ("AVIF"); - - static int avif_bit_depth = 12; - static int avif_compression_speed = AVIF_SPEED_FASTEST; - static int avif_compression_quality = AVIF_QUALITY_LOSSLESS; - ImGui::SliderInt ("Compression Speed", &avif_compression_speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST); - ImGui::SliderInt ("Compression Quality", &avif_compression_quality, 80, 100); + + if (ImGui::SliderInt ("Compression Speed", &_registry.avif.speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST)) + _registry.regKVAVIFSpeed.putData (_registry.avif.speed); + + if (ImGui::SliderInt ("Compression Quality", &_registry.avif.quality, 80, 100)) + _registry.regKVAVIFQuality.putData (_registry.avif.quality); int avif_bit_select = - avif_bit_depth == 8 ? 0 : - avif_bit_depth == 10 ? 1 : - avif_bit_depth == 12 ? 2 : 2; + _registry.avif.hdr_bitdepth == 8 ? 0 : + _registry.avif.hdr_bitdepth == 10 ? 1 : + _registry.avif.hdr_bitdepth == 12 ? 2 : 2; + bool changed_depth = ImGui::Combo ("Compression Bit Depth", &avif_bit_select, " 8-bpc\0 10-bpc\0 12-bpc\0\0"); - avif_bit_depth = avif_bit_select == 0 ? 8 : - avif_bit_select == 1 ? 10 : - avif_bit_select == 2 ? 12 : 12; + _registry.avif.hdr_bitdepth = avif_bit_select == 0 ? 8 : + avif_bit_select == 1 ? 10 : + avif_bit_select == 2 ? 12 : 12; + + if (changed_depth) + _registry.regKVAVIFHDRBitDepth.putData (_registry.avif.hdr_bitdepth); ImGui::EndTabItem (); } if (ImGui::BeginTabItem ("JPEG XL", nullptr, ImGuiTabItemFlags_NoTooltip)) { selection = 1; - //ImGui::TextUnformatted ("XL"); - static int jxl_compression_speed = 10; - static int jxl_compression_quality = 100; - ImGui::SliderInt ("Compression Speed", &jxl_compression_speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST); - ImGui::SliderInt ("Compression Quality", &jxl_compression_quality, 80, 100); - ImGui::EndTabItem (); - } - if (ImGui::BeginTabItem ("JPEG XR", nullptr, ImGuiTabItemFlags_NoTooltip)) - { - selection = 2; - //ImGui::TextUnformatted ("XR"); - static int jxr_compression_quality = 100; - ImGui::SliderInt ("Compression Quality", &jxr_compression_quality, 80, 100); + if (ImGui::SliderInt ("Compression Speed", &_registry.jxl.speed, AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST)) + _registry.regKVJXLSpeed.putData (_registry.jxl.speed); + + if (ImGui::SliderInt ("Compression Quality", &_registry.jxl.quality, 80, 100)) + _registry.regKVJXLQuality.putData (_registry.jxl.quality); ImGui::EndTabItem (); } + ///if (ImGui::BeginTabItem ("JPEG XR", nullptr, ImGuiTabItemFlags_NoTooltip)) + ///{ + /// selection = 2; + /// //ImGui::TextUnformatted ("XR"); + /// static int jxr_compression_quality = 100; + /// ImGui::SliderInt ("Compression Quality", &jxr_compression_quality, 80, 100); + /// ImGui::EndTabItem (); + ///} if (ImGui::BeginTabItem ("PNG", nullptr, ImGuiTabItemFlags_NoTooltip)) { selection = 3; - //ImGui::TextUnformatted ("PNG"); - static int png_bit_depth = 16; - ImGui::SliderInt ("Bit Depth", &png_bit_depth, 10, 16); + if (ImGui::SliderInt ("HDR Bit Depth", &_registry.png.hdr_bitdepth, 10, 16)) + _registry.regKVJXLQuality.putData (_registry.png.hdr_bitdepth); ImGui::EndTabItem (); } //if (ImGui::BeginTabItem ("Ultra HDR", nullptr, ImGuiTabItemFlags_NoTooltip)) diff --git a/src/utility/image.cpp b/src/utility/image.cpp index be5c4c1..a526fa0 100644 --- a/src/utility/image.cpp +++ b/src/utility/image.cpp @@ -2392,6 +2392,9 @@ SKIV_Image_LoadUltraHDR (DirectX::ScratchImage& image, void* data, int size) HRESULT SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileName) { + SKIF_RegistrySettings& _registry = + SKIF_RegistrySettings::GetInstance (); + using namespace DirectX; const Image* pOutputImage = ℑ @@ -2606,7 +2609,7 @@ SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileNa JxlBasicInfo basic_info = { }; jxlEncoderInitBasicInfo (&basic_info); - const bool bLossless = false; + const bool bLossless = (_registry.jxl.quality == 100); basic_info.xsize = static_cast (image.width); basic_info.ysize = static_cast (image.height); @@ -2640,8 +2643,8 @@ SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileNa jxlEncoderFrameSettingsCreate (jxl_encoder, nullptr); jxlEncoderSetFrameLossless (frame_settings, bLossless ? JXL_TRUE : JXL_FALSE); - jxlEncoderSetFrameDistance (frame_settings, 0.05f);//jxlEncoderDistanceFromQuality (100.0f)); - jxlEncoderFrameSettingsSetOption (frame_settings, JXL_ENC_FRAME_SETTING_EFFORT, 7); + jxlEncoderSetFrameDistance (frame_settings, jxlEncoderDistanceFromQuality ((float)_registry.jxl.quality)); + jxlEncoderFrameSettingsSetOption (frame_settings, JXL_ENC_FRAME_SETTING_EFFORT, _registry.jxl.speed); if ( JXL_ENC_SUCCESS != jxlEncoderAddImageFrame ( frame_settings, &pixel_format, @@ -2748,7 +2751,7 @@ SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileNa if (image.format == DXGI_FORMAT_R16G16B16A16_FLOAT) { - bit_depth = 12; + bit_depth = _registry.avif.hdr_bitdepth; //std::clamp (config.screenshots.avif.scrgb_bit_depth, 8, 12); // 8, 10, 12... nothing else. @@ -2989,16 +2992,15 @@ SKIV_Image_SaveToDisk_HDR (const DirectX::Image& image, const wchar_t* wszFileNa SYSTEM_INFO si = { }; GetSystemInfo (&si); - encoder->quality = 100;//config.screenshots.compression_quality; - encoder->qualityAlpha = 100;//config.screenshots.compression_quality; // N/A? + encoder->quality = _registry.avif.quality; + encoder->qualityAlpha = _registry.avif.quality; // N/A? encoder->timescale = 1; encoder->repetitionCount = AVIF_REPETITION_COUNT_INFINITE; encoder->maxThreads = std::min (64U, std::min ((UINT)si.dwNumberOfProcessors, (UINT)__popcnt64 (si.dwActiveProcessorMask))); - encoder->speed = 7;//config.screenshots.avif.compression_speed; encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY; encoder->maxQuantizer = AVIF_QUANTIZER_BEST_QUALITY; encoder->codecChoice = AVIF_CODEC_CHOICE_AUTO; - encoder->speed = AVIF_SPEED_FASTEST; + encoder->speed = _registry.avif.speed; addResult = SK_avifEncoderAddImage (encoder, avif_image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE); encodeResult = SK_avifEncoderFinish (encoder, &avifOutput); diff --git a/src/utility/registry.cpp b/src/utility/registry.cpp index 1e8b386..4f1cb3e 100644 --- a/src/utility/registry.cpp +++ b/src/utility/registry.cpp @@ -308,6 +308,27 @@ SKIF_RegistrySettings::SKIF_RegistrySettings (void) if (regKVDiagnostics.hasData(&hKey)) iDiagnostics = regKVDiagnostics .getData (&hKey); + + if (regKVAVIFHDRBitDepth.hasData (&hKey)) + avif.hdr_bitdepth = regKVAVIFHDRBitDepth .getData (&hKey); + if (regKVAVIFQuality.hasData (&hKey)) + avif.quality = regKVAVIFQuality .getData (&hKey); + if (regKVAVIFSpeed.hasData (&hKey)) + avif.speed = regKVAVIFSpeed .getData (&hKey); + + if (regKVJXLHDRBitDepth.hasData (&hKey)) + jxl.hdr_bitdepth = regKVJXLHDRBitDepth .getData (&hKey); + if (regKVJXLQuality.hasData (&hKey)) + jxl.quality = regKVJXLQuality .getData (&hKey); + if (regKVJXLSpeed.hasData (&hKey)) + jxl.speed = regKVJXLSpeed .getData (&hKey); + + if (regKVJXRQuality.hasData (&hKey)) + jxr.quality = regKVJXRQuality .getData (&hKey); + + if (regKVPNGHDRBitDepth.hasData (&hKey)) + png.hdr_bitdepth = regKVPNGHDRBitDepth .getData (&hKey); + #if 0 if (! SKIF_Util_GetDragFromMaximized ( )) bMaximizeOnDoubleClick = false; // Force disabled IF the OS prerequisites are not enabled