From 9aaa70c5b671aed730a1e24ab9d1b79aaaab66ee Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Sat, 31 Jan 2026 23:35:40 +0100 Subject: [PATCH] jfjoch_viewer: Improve HDR mode --- viewer/JFJochViewerWindow.cpp | 3 +++ viewer/image_viewer/JFJochImage.cpp | 27 +++++++++++++++++-- viewer/image_viewer/JFJochImage.h | 2 ++ viewer/toolbar/JFJochViewerToolbarDisplay.cpp | 15 ++++++++--- viewer/toolbar/JFJochViewerToolbarDisplay.h | 4 ++- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/viewer/JFJochViewerWindow.cpp b/viewer/JFJochViewerWindow.cpp index d9405ff6..134959e2 100644 --- a/viewer/JFJochViewerWindow.cpp +++ b/viewer/JFJochViewerWindow.cpp @@ -159,6 +159,9 @@ JFJochViewerWindow::JFJochViewerWindow(QWidget *parent, bool dbus, const QString connect(toolBarDisplay, &JFJochViewerToolbarDisplay::setAutoForeground, viewer, &JFJochDiffractionImage::setAutoForeground); + connect(toolBarDisplay, &JFJochViewerToolbarDisplay::setHDRMode, viewer, + &JFJochImage::setHDRMode); + connect(toolBarDisplay, &JFJochViewerToolbarDisplay::colorMapChanged, viewer, &JFJochDiffractionImage::setColorMap); diff --git a/viewer/image_viewer/JFJochImage.cpp b/viewer/image_viewer/JFJochImage.cpp index dadc20e6..5723d4b9 100644 --- a/viewer/image_viewer/JFJochImage.cpp +++ b/viewer/image_viewer/JFJochImage.cpp @@ -600,7 +600,9 @@ void JFJochImage::GeneratePixmap() { const auto &lut_data = color_scale.LUTData(); const int64_t lutSize = lut_data.size(); const float lutScale = static_cast(lutSize - 1); - const float invRange = (maxv > minv) ? (1.0f / (maxv - minv)) * lutScale : 0.0f; + const float range = maxv - minv; + const float invRange = (range > 0) ? (lutScale / range) : 0.0f; + const float invRangeLog = (range > 0) ? (lutScale / std::log1p(range)) : 0.0f; rgb gap_color = color_scale.Apply(ColorScaleSpecial::Gap); for (int y = 0; y < H; ++y) { @@ -619,7 +621,22 @@ void JFJochImage::GeneratePixmap() { c = std::signbit(fp) ? bad_color : sat_color; } } else { - auto idx = static_cast((fp - minv) * invRange + 0.5f); + float f; + const float fp_minv = fp - minv; + + if (hdr_mode) { + if (fp_minv <= 0.0f) + f = 0.0f; + else if (fp_minv >= range) + f = lutSize; + else + f = std::log1p(fp_minv) * invRangeLog; + } else + f = fp_minv * invRange; + + if (f < 0.0f) f = 0.0f; + + auto idx = static_cast(f + 0.5f); if (idx <= 0) idx = 0; else if (idx >= lutSize) idx = lutSize - 1; c = lut_data[idx]; @@ -849,3 +866,9 @@ void JFJochImage::adjustForeground(bool input) { } void JFJochImage::beforeOverlayCleared() {} + +void JFJochImage::setHDRMode(bool input) { + hdr_mode = input; + GeneratePixmap(); + Redraw(); +} diff --git a/viewer/image_viewer/JFJochImage.h b/viewer/image_viewer/JFJochImage.h index 2c0a5e9e..62568e1b 100644 --- a/viewer/image_viewer/JFJochImage.h +++ b/viewer/image_viewer/JFJochImage.h @@ -36,6 +36,7 @@ protected: bool auto_bg = false; bool auto_fg = false; + bool hdr_mode = false; double scale_factor = 1.0; @@ -108,6 +109,7 @@ public slots: void fitToView(); void adjustForeground(bool input); + void setHDRMode(bool input); public: explicit JFJochImage(QWidget *parent = nullptr); }; diff --git a/viewer/toolbar/JFJochViewerToolbarDisplay.cpp b/viewer/toolbar/JFJochViewerToolbarDisplay.cpp index 60ce9430..f9cee39b 100644 --- a/viewer/toolbar/JFJochViewerToolbarDisplay.cpp +++ b/viewer/toolbar/JFJochViewerToolbarDisplay.cpp @@ -21,6 +21,11 @@ JFJochViewerToolbarDisplay::JFJochViewerToolbarDisplay(QWidget *parent) auto_foreground_button->setChecked(false); addWidget(auto_foreground_button); + hdr_mode_button = new QPushButton("HDR"); + hdr_mode_button->setCheckable(true); + hdr_mode_button->setChecked(false); + addWidget(hdr_mode_button); + addWidget(new QLabel("  Color map  ")); // Initialize QComboBox with the options @@ -41,7 +46,7 @@ JFJochViewerToolbarDisplay::JFJochViewerToolbarDisplay(QWidget *parent) connect(color_map_select, QOverload::of(&QComboBox::currentIndexChanged), this, &JFJochViewerToolbarDisplay::colorComboBoxSet); connect(auto_foreground_button, &QPushButton::clicked, this, &JFJochViewerToolbarDisplay::autoForegroundButtonPressed); - + connect(hdr_mode_button, &QPushButton::clicked, this, &JFJochViewerToolbarDisplay::HDRModeButtonPressed); auto *stretch = new QWidget(this); stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); addWidget(stretch); @@ -60,7 +65,6 @@ void JFJochViewerToolbarDisplay::colorComboBoxSet(int val) { emit colorMapChanged(val); } - void JFJochViewerToolbarDisplay::autoForegroundButtonPressed() { emit setAutoForeground(auto_foreground_button->isChecked()); } @@ -70,15 +74,18 @@ void JFJochViewerToolbarDisplay::updateAutoForeground(bool val) { auto_foreground_button->setChecked(val); } +void JFJochViewerToolbarDisplay::HDRModeButtonPressed() { + emit setHDRMode(hdr_mode_button->isChecked()); +} + void JFJochViewerToolbarDisplay::imageLoaded(std::shared_ptr image) { if (image) { auto valid = image->ValidMinMax(); - if (valid.has_value()) + if (valid.has_value() && valid->second > 1) foreground_slider->setMax(valid->second); else foreground_slider->setMax(MAX_SLIDER_NO_IMAGE); } else { foreground_slider->setMax(MAX_SLIDER_NO_IMAGE); } - } diff --git a/viewer/toolbar/JFJochViewerToolbarDisplay.h b/viewer/toolbar/JFJochViewerToolbarDisplay.h index 86f0f511..e39f7623 100644 --- a/viewer/toolbar/JFJochViewerToolbarDisplay.h +++ b/viewer/toolbar/JFJochViewerToolbarDisplay.h @@ -17,7 +17,7 @@ class JFJochViewerToolbarDisplay : public QToolBar { SliderPlusBox *foreground_slider; QPushButton *auto_foreground_button; - + QPushButton *hdr_mode_button; QComboBox *color_map_select; public: JFJochViewerToolbarDisplay(QWidget *parent = nullptr); @@ -26,6 +26,7 @@ signals: void setForeground(float val); void colorMapChanged(int val); void setAutoForeground(bool val); + void setHDRMode(bool val); public slots: void updateForeground(float val); @@ -35,6 +36,7 @@ private slots: void foregroundSet(double val); void colorComboBoxSet(int val); void autoForegroundButtonPressed(); + void HDRModeButtonPressed(); };