Add initial implementation of waveform
This commit is contained in:
@@ -249,6 +249,7 @@ HISTOGRAM_TOOLTIP_L;Show/Hide CIELab luminance histogram.
|
|||||||
HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram.
|
HISTOGRAM_TOOLTIP_MODE;Toggle between linear, log-linear and log-log scaling of the histogram.
|
||||||
HISTOGRAM_TOOLTIP_R;Show/Hide red histogram.
|
HISTOGRAM_TOOLTIP_R;Show/Hide red histogram.
|
||||||
HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram.
|
HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram.
|
||||||
|
HISTOGRAM_TOOLTIP_TYPE;Toggle between histogram and waveform.
|
||||||
HISTORY_CHANGED;Changed
|
HISTORY_CHANGED;Changed
|
||||||
HISTORY_CUSTOMCURVE;Custom curve
|
HISTORY_CUSTOMCURVE;Custom curve
|
||||||
HISTORY_FROMCLIPBOARD;From clipboard
|
HISTORY_FROMCLIPBOARD;From clipboard
|
||||||
|
@@ -129,6 +129,8 @@ ImProcCoordinator::ImProcCoordinator() :
|
|||||||
|
|
||||||
histLRETI(256),
|
histLRETI(256),
|
||||||
|
|
||||||
|
waveformWidth(0),
|
||||||
|
|
||||||
CAMBrightCurveJ(), CAMBrightCurveQ(),
|
CAMBrightCurveJ(), CAMBrightCurveQ(),
|
||||||
|
|
||||||
rCurve(),
|
rCurve(),
|
||||||
@@ -1639,7 +1641,30 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
|||||||
|
|
||||||
if (hListener) {
|
if (hListener) {
|
||||||
updateLRGBHistograms();
|
updateLRGBHistograms();
|
||||||
hListener->histogramChanged(histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma, histLRETI);
|
updateWaveforms();
|
||||||
|
hListener->histogramChanged(
|
||||||
|
histRed,
|
||||||
|
histGreen,
|
||||||
|
histBlue,
|
||||||
|
histLuma,
|
||||||
|
histToneCurve,
|
||||||
|
histLCurve,
|
||||||
|
histCCurve,
|
||||||
|
/*histCLurve,
|
||||||
|
* histLLCurve,*/
|
||||||
|
histLCAM,
|
||||||
|
histCCAM,
|
||||||
|
histRedRaw,
|
||||||
|
histGreenRaw,
|
||||||
|
histBlueRaw,
|
||||||
|
histChroma,
|
||||||
|
histLRETI,
|
||||||
|
waveformScale,
|
||||||
|
waveformWidth,
|
||||||
|
waveformRed.get(),
|
||||||
|
waveformGreen.get(),
|
||||||
|
waveformBlue.get()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1801,6 +1826,43 @@ void ImProcCoordinator::updateLRGBHistograms()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImProcCoordinator::updateWaveforms()
|
||||||
|
{
|
||||||
|
if (!workimg) {
|
||||||
|
waveformWidth = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waveformWidth != workimg->getWidth()) {
|
||||||
|
// Resize waveform arrays.
|
||||||
|
waveformWidth = workimg->getWidth();
|
||||||
|
waveformRed.reset(new int[waveformWidth][256]);
|
||||||
|
waveformGreen.reset(new int[waveformWidth][256]);
|
||||||
|
waveformBlue.reset(new int[waveformWidth][256]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int (*red)[256] = waveformRed.get();
|
||||||
|
int (*green)[256] = waveformGreen.get();
|
||||||
|
int (*blue)[256] = waveformBlue.get();
|
||||||
|
|
||||||
|
// Start with zero.
|
||||||
|
const int waveformSize = 256 * waveformWidth;
|
||||||
|
memset(waveformRed.get(), 0, waveformSize * sizeof(red[0][0]));
|
||||||
|
memset(waveformGreen.get(), 0, waveformSize * sizeof(green[0][0]));
|
||||||
|
memset(waveformBlue.get(), 0, waveformSize * sizeof(blue[0][0]));
|
||||||
|
|
||||||
|
const int img_height = workimg->getHeight();
|
||||||
|
for (int col = 0; col < waveformWidth; col++) {
|
||||||
|
for (int row = 0; row < img_height; row++) {
|
||||||
|
red[col][workimg->r(row, col)]++;
|
||||||
|
green[col][workimg->g(row, col)]++;
|
||||||
|
blue[col][workimg->b(row, col)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
waveformScale = img_height;
|
||||||
|
}
|
||||||
|
|
||||||
bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, double tempBias)
|
bool ImProcCoordinator::getAutoWB(double& temp, double& green, double equal, double tempBias)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -126,6 +126,12 @@ protected:
|
|||||||
LUTu histBlue, histBlueRaw;
|
LUTu histBlue, histBlueRaw;
|
||||||
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve;
|
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve;
|
||||||
LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI;
|
LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma, histLRETI;
|
||||||
|
/// Waveform's intensity. Same as height of reference image.
|
||||||
|
int waveformScale;
|
||||||
|
int waveformWidth;
|
||||||
|
std::unique_ptr<int[][256]> waveformRed, waveformRedRaw;
|
||||||
|
std::unique_ptr<int[][256]> waveformGreen, waveformGreenRaw;
|
||||||
|
std::unique_ptr<int[][256]> waveformBlue, waveformBlueRaw;
|
||||||
|
|
||||||
LUTf CAMBrightCurveJ, CAMBrightCurveQ;
|
LUTf CAMBrightCurveJ, CAMBrightCurveQ;
|
||||||
|
|
||||||
@@ -195,6 +201,7 @@ protected:
|
|||||||
|
|
||||||
void reallocAll();
|
void reallocAll();
|
||||||
void updateLRGBHistograms();
|
void updateLRGBHistograms();
|
||||||
|
void updateWaveforms();
|
||||||
void setScale(int prevscale);
|
void setScale(int prevscale);
|
||||||
void updatePreviewImage (int todo, bool panningRelatedChange);
|
void updatePreviewImage (int todo, bool panningRelatedChange);
|
||||||
|
|
||||||
|
@@ -327,7 +327,12 @@ public:
|
|||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw,
|
const LUTu& histBlueRaw,
|
||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histLRETI
|
const LUTu& histLRETI,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
) = 0;
|
) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -2245,11 +2245,16 @@ void EditorPanel::histogramChanged(
|
|||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw,
|
const LUTu& histBlueRaw,
|
||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histLRETI
|
const LUTu& histLRETI,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (histogramPanel) {
|
if (histogramPanel) {
|
||||||
histogramPanel->histogramChanged(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw);
|
histogramPanel->histogramChanged(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, waveformScale, waveformWidth, waveformRed, waveformGreen, waveformBlue);
|
||||||
}
|
}
|
||||||
|
|
||||||
tpc->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
tpc->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve, histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma, histLRETI);
|
||||||
|
@@ -126,7 +126,12 @@ public:
|
|||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw,
|
const LUTu& histBlueRaw,
|
||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histLRETI
|
const LUTu& histLRETI,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
|
@@ -85,6 +85,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showChro = Gtk::manage (new Gtk::ToggleButton ());
|
showChro = Gtk::manage (new Gtk::ToggleButton ());
|
||||||
showRAW = Gtk::manage (new Gtk::ToggleButton ());
|
showRAW = Gtk::manage (new Gtk::ToggleButton ());
|
||||||
showMode = Gtk::manage (new Gtk::Button ());
|
showMode = Gtk::manage (new Gtk::Button ());
|
||||||
|
scopeType = Gtk::manage (new Gtk::Button ());
|
||||||
showBAR = Gtk::manage (new Gtk::ToggleButton ());
|
showBAR = Gtk::manage (new Gtk::ToggleButton ());
|
||||||
|
|
||||||
showRed->set_name("histButton");
|
showRed->set_name("histButton");
|
||||||
@@ -101,6 +102,8 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showRAW->set_can_focus(false);
|
showRAW->set_can_focus(false);
|
||||||
showMode->set_name("histButton");
|
showMode->set_name("histButton");
|
||||||
showMode->set_can_focus(false);
|
showMode->set_can_focus(false);
|
||||||
|
scopeType->set_name("histButton");
|
||||||
|
scopeType->set_can_focus(false);
|
||||||
showBAR->set_name("histButton");
|
showBAR->set_name("histButton");
|
||||||
showBAR->set_can_focus(false);
|
showBAR->set_can_focus(false);
|
||||||
|
|
||||||
@@ -111,6 +114,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showChro->set_relief (Gtk::RELIEF_NONE);
|
showChro->set_relief (Gtk::RELIEF_NONE);
|
||||||
showRAW->set_relief (Gtk::RELIEF_NONE);
|
showRAW->set_relief (Gtk::RELIEF_NONE);
|
||||||
showMode->set_relief (Gtk::RELIEF_NONE);
|
showMode->set_relief (Gtk::RELIEF_NONE);
|
||||||
|
scopeType->set_relief (Gtk::RELIEF_NONE);
|
||||||
showBAR->set_relief (Gtk::RELIEF_NONE);
|
showBAR->set_relief (Gtk::RELIEF_NONE);
|
||||||
|
|
||||||
showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R"));
|
showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R"));
|
||||||
@@ -120,6 +124,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showChro->set_tooltip_text (M("HISTOGRAM_TOOLTIP_CHRO"));
|
showChro->set_tooltip_text (M("HISTOGRAM_TOOLTIP_CHRO"));
|
||||||
showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW"));
|
showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW"));
|
||||||
showMode->set_tooltip_text (M("HISTOGRAM_TOOLTIP_MODE"));
|
showMode->set_tooltip_text (M("HISTOGRAM_TOOLTIP_MODE"));
|
||||||
|
scopeType->set_tooltip_text (M("HISTOGRAM_TOOLTIP_TYPE"));
|
||||||
showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR"));
|
showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR"));
|
||||||
|
|
||||||
buttonGrid = Gtk::manage (new Gtk::Grid ());
|
buttonGrid = Gtk::manage (new Gtk::Grid ());
|
||||||
@@ -145,9 +150,15 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showMode->set_image(*mode1Image);
|
showMode->set_image(*mode1Image);
|
||||||
else
|
else
|
||||||
showMode->set_image(*mode2Image);
|
showMode->set_image(*mode2Image);
|
||||||
|
if (options.histogramScopeType == 0) {
|
||||||
|
// TODO: scopeType->set_image(*histImage);
|
||||||
|
} else {
|
||||||
|
// TODO: scopeType->set_image(*waveImage);
|
||||||
|
}
|
||||||
showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g);
|
showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g);
|
||||||
|
|
||||||
raw_toggled(); // Make sure the luma/chroma toggles are enabled or disabled
|
raw_toggled(); // Make sure the luma/chroma toggles are enabled or disabled
|
||||||
|
type_changed();
|
||||||
|
|
||||||
setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
@@ -156,6 +167,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
setExpandAlignProperties(showChro , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showChro , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
setExpandAlignProperties(showRAW , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showRAW , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
setExpandAlignProperties(showMode , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showMode , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
|
setExpandAlignProperties(scopeType, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
setExpandAlignProperties(showBAR , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
setExpandAlignProperties(showBAR , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||||
|
|
||||||
showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::red_toggled), showRed );
|
showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::red_toggled), showRed );
|
||||||
@@ -165,6 +177,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
showChro->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::chro_toggled), showChro );
|
showChro->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::chro_toggled), showChro );
|
||||||
showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::raw_toggled), showRAW );
|
showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::raw_toggled), showRAW );
|
||||||
showMode->signal_released().connect( sigc::mem_fun(*this, &HistogramPanel::mode_released), showMode );
|
showMode->signal_released().connect( sigc::mem_fun(*this, &HistogramPanel::mode_released), showMode );
|
||||||
|
scopeType->signal_pressed().connect( sigc::mem_fun(*this, &HistogramPanel::type_pressed), scopeType );
|
||||||
showBAR->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::bar_toggled), showBAR );
|
showBAR->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::bar_toggled), showBAR );
|
||||||
|
|
||||||
buttonGrid->add (*showRed);
|
buttonGrid->add (*showRed);
|
||||||
@@ -174,6 +187,7 @@ HistogramPanel::HistogramPanel ()
|
|||||||
buttonGrid->add (*showChro);
|
buttonGrid->add (*showChro);
|
||||||
buttonGrid->add (*showRAW);
|
buttonGrid->add (*showRAW);
|
||||||
buttonGrid->add (*showMode);
|
buttonGrid->add (*showMode);
|
||||||
|
buttonGrid->add (*scopeType);
|
||||||
buttonGrid->add (*showBAR);
|
buttonGrid->add (*showBAR);
|
||||||
|
|
||||||
// Put the button vbox next to the window's border to be less disturbing
|
// Put the button vbox next to the window's border to be less disturbing
|
||||||
@@ -266,8 +280,8 @@ void HistogramPanel::raw_toggled ()
|
|||||||
showChro->set_sensitive(false);
|
showChro->set_sensitive(false);
|
||||||
} else {
|
} else {
|
||||||
showRAW->set_image(*rawImage_g);
|
showRAW->set_image(*rawImage_g);
|
||||||
showValue->set_sensitive(true);
|
showValue->set_sensitive(options.histogramScopeType != 1);
|
||||||
showChro->set_sensitive(true);
|
showChro->set_sensitive(options.histogramScopeType != 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
rgbv_toggled();
|
rgbv_toggled();
|
||||||
@@ -285,6 +299,34 @@ void HistogramPanel::mode_released ()
|
|||||||
rgbv_toggled();
|
rgbv_toggled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistogramPanel::type_pressed()
|
||||||
|
{
|
||||||
|
constexpr int TYPE_COUNT = 2; // Histogram and waveform.
|
||||||
|
options.histogramScopeType = (options.histogramScopeType + 1) % TYPE_COUNT;
|
||||||
|
if (options.histogramScopeType == 0) {
|
||||||
|
// TODO: showMode->set_image(*histImage);
|
||||||
|
} else {
|
||||||
|
// TODO: showMode->set_image(*waveImage);
|
||||||
|
}
|
||||||
|
type_changed();
|
||||||
|
rgbv_toggled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistogramPanel::type_changed()
|
||||||
|
{
|
||||||
|
if (options.histogramScopeType == 0) {
|
||||||
|
showValue->set_sensitive(!showRAW->get_active());
|
||||||
|
showChro->set_sensitive(!showRAW->get_active());
|
||||||
|
showRAW->set_sensitive();
|
||||||
|
showMode->set_sensitive();
|
||||||
|
} else {
|
||||||
|
showValue->set_sensitive(false);
|
||||||
|
showChro->set_sensitive(false);
|
||||||
|
showRAW->set_sensitive(false);
|
||||||
|
showMode->set_sensitive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistogramPanel::bar_toggled ()
|
void HistogramPanel::bar_toggled ()
|
||||||
{
|
{
|
||||||
showBAR->set_image(showBAR->get_active() ? *barImage : *barImage_g);
|
showBAR->set_image(showBAR->get_active() ? *barImage : *barImage_g);
|
||||||
@@ -294,7 +336,7 @@ void HistogramPanel::bar_toggled ()
|
|||||||
void HistogramPanel::rgbv_toggled ()
|
void HistogramPanel::rgbv_toggled ()
|
||||||
{
|
{
|
||||||
// Update Display
|
// Update Display
|
||||||
histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showChro->get_active(), showRAW->get_active(), options.histogramDrawMode);
|
histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showChro->get_active(), showRAW->get_active(), options.histogramDrawMode, options.histogramScopeType);
|
||||||
histogramArea->queue_draw ();
|
histogramArea->queue_draw ();
|
||||||
|
|
||||||
histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showChro->get_active(), showRAW->get_active(), showBAR->get_active());
|
histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showChro->get_active(), showRAW->get_active(), showBAR->get_active());
|
||||||
@@ -443,7 +485,7 @@ bool HistogramRGBArea::getShow()
|
|||||||
|
|
||||||
void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW)
|
void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW)
|
||||||
{
|
{
|
||||||
if (!get_realized () || !showMode || rawMode) {
|
if (!get_realized () || !showMode || rawMode || options.histogramScopeType == 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +697,9 @@ void HistogramRGBArea::factorChanged (double newFactor)
|
|||||||
//
|
//
|
||||||
// HistogramArea
|
// HistogramArea
|
||||||
HistogramArea::HistogramArea (DrawModeListener *fml) :
|
HistogramArea::HistogramArea (DrawModeListener *fml) :
|
||||||
|
waveform_width(0),
|
||||||
valid(false), drawMode(options.histogramDrawMode), myDrawModeListener(fml),
|
valid(false), drawMode(options.histogramDrawMode), myDrawModeListener(fml),
|
||||||
|
scopeType(options.histogramScopeType),
|
||||||
oldwidth(-1), oldheight(-1),
|
oldwidth(-1), oldheight(-1),
|
||||||
needRed(options.histogramRed), needGreen(options.histogramGreen), needBlue(options.histogramBlue),
|
needRed(options.histogramRed), needGreen(options.histogramGreen), needBlue(options.histogramBlue),
|
||||||
needLuma(options.histogramLuma), needChroma(options.histogramChroma), rawMode(options.histogramRAW),
|
needLuma(options.histogramLuma), needChroma(options.histogramChroma), rawMode(options.histogramRAW),
|
||||||
@@ -720,7 +764,7 @@ void HistogramArea::get_preferred_width_for_height_vfunc (int height, int &minim
|
|||||||
get_preferred_width_vfunc (minimum_width, natural_width);
|
get_preferred_width_vfunc (minimum_width, natural_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode)
|
void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode, int type)
|
||||||
{
|
{
|
||||||
|
|
||||||
options.histogramRed = needRed = r;
|
options.histogramRed = needRed = r;
|
||||||
@@ -730,6 +774,7 @@ void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool
|
|||||||
options.histogramChroma = needChroma = c;
|
options.histogramChroma = needChroma = c;
|
||||||
options.histogramRAW = rawMode = raw;
|
options.histogramRAW = rawMode = raw;
|
||||||
options.histogramDrawMode = drawMode = mode;
|
options.histogramDrawMode = drawMode = mode;
|
||||||
|
options.histogramScopeType = scopeType = type;
|
||||||
|
|
||||||
updateBackBuffer ();
|
updateBackBuffer ();
|
||||||
}
|
}
|
||||||
@@ -742,7 +787,12 @@ void HistogramArea::update(
|
|||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histRedRaw,
|
const LUTu& histRedRaw,
|
||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw
|
const LUTu& histBlueRaw,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (histRed) {
|
if (histRed) {
|
||||||
@@ -754,6 +804,19 @@ void HistogramArea::update(
|
|||||||
rhistRaw = histRedRaw;
|
rhistRaw = histRedRaw;
|
||||||
ghistRaw = histGreenRaw;
|
ghistRaw = histGreenRaw;
|
||||||
bhistRaw = histBlueRaw;
|
bhistRaw = histBlueRaw;
|
||||||
|
waveform_scale = waveformScale;
|
||||||
|
if (waveform_width != waveformWidth) {
|
||||||
|
waveform_width = waveformWidth;
|
||||||
|
rwave.reset(new int[waveformWidth][256]);
|
||||||
|
gwave.reset(new int[waveformWidth][256]);
|
||||||
|
bwave.reset(new int[waveformWidth][256]);
|
||||||
|
}
|
||||||
|
int (* const rw)[256] = rwave.get();
|
||||||
|
int (* const gw)[256] = gwave.get();
|
||||||
|
int (* const bw)[256] = bwave.get();
|
||||||
|
memcpy(rw, waveformRed, 256 * waveformWidth * sizeof(rw[0][0]));
|
||||||
|
memcpy(gw, waveformGreen, 256 * waveformWidth * sizeof(gw[0][0]));
|
||||||
|
memcpy(bw, waveformBlue, 256 * waveformWidth * sizeof(bw[0][0]));
|
||||||
valid = true;
|
valid = true;
|
||||||
} else {
|
} else {
|
||||||
valid = false;
|
valid = false;
|
||||||
@@ -826,6 +889,7 @@ void HistogramArea::updateBackBuffer ()
|
|||||||
int nrOfVGridPartitions = 8; // always show 8 stops (lines at 1,3,7,15,31,63,127)
|
int nrOfVGridPartitions = 8; // always show 8 stops (lines at 1,3,7,15,31,63,127)
|
||||||
|
|
||||||
// draw vertical gridlines
|
// draw vertical gridlines
|
||||||
|
if (options.histogramScopeType != 1) {
|
||||||
for (int i = 0; i <= nrOfVGridPartitions; i++) {
|
for (int i = 0; i <= nrOfVGridPartitions; i++) {
|
||||||
double xpos = padding + 0.5;
|
double xpos = padding + 0.5;
|
||||||
if (options.histogramDrawMode < 2) {
|
if (options.histogramDrawMode < 2) {
|
||||||
@@ -837,9 +901,17 @@ void HistogramArea::updateBackBuffer ()
|
|||||||
cr->line_to (xpos, h);
|
cr->line_to (xpos, h);
|
||||||
cr->stroke ();
|
cr->stroke ();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// draw horizontal gridlines
|
// draw horizontal gridlines
|
||||||
if (options.histogramDrawMode == 0) {
|
if (options.histogramScopeType == 1) {
|
||||||
|
for (int i = 0; i <= nrOfVGridPartitions; i++) {
|
||||||
|
const double ypos = h - 1 - (pow(2.0,i) - 1) * (h - 1) / 255.0;
|
||||||
|
cr->move_to(padding, ypos);
|
||||||
|
cr->line_to(w - padding, ypos);
|
||||||
|
cr->stroke();
|
||||||
|
}
|
||||||
|
} else if (options.histogramDrawMode == 0) {
|
||||||
for (int i = 1; i < nrOfHGridPartitions; i++) {
|
for (int i = 1; i < nrOfHGridPartitions; i++) {
|
||||||
cr->move_to (padding, i * (double)h / nrOfHGridPartitions + 0.5);
|
cr->move_to (padding, i * (double)h / nrOfHGridPartitions + 0.5);
|
||||||
cr->line_to (w - padding, i * (double)h / nrOfHGridPartitions + 0.5);
|
cr->line_to (w - padding, i * (double)h / nrOfHGridPartitions + 0.5);
|
||||||
@@ -855,7 +927,7 @@ void HistogramArea::updateBackBuffer ()
|
|||||||
|
|
||||||
cr->unset_dash();
|
cr->unset_dash();
|
||||||
|
|
||||||
if (valid) {
|
if (valid && scopeType == 0) {
|
||||||
// For RAW mode use the other hists
|
// For RAW mode use the other hists
|
||||||
LUTu& rh = rawMode ? rhistRaw : rhist;
|
LUTu& rh = rawMode ? rhistRaw : rhist;
|
||||||
LUTu& gh = rawMode ? ghistRaw : ghist;
|
LUTu& gh = rawMode ? ghistRaw : ghist;
|
||||||
@@ -962,6 +1034,8 @@ void HistogramArea::updateBackBuffer ()
|
|||||||
drawMarks(cr, bhchanged, realhistheight, w, ui, oi);
|
drawMarks(cr, bhchanged, realhistheight, w, ui, oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (scopeType == 1 && waveform_width > 0) {
|
||||||
|
drawWaveform(cr, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the frame's border
|
// Draw the frame's border
|
||||||
@@ -1026,6 +1100,48 @@ void HistogramArea::drawMarks(Cairo::RefPtr<Cairo::Context> &cr,
|
|||||||
cr->fill();
|
cr->fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistogramArea::drawWaveform(Cairo::RefPtr<Cairo::Context> &cr, int w, int h)
|
||||||
|
{
|
||||||
|
// Arbitrary scale factor divided by current scale.
|
||||||
|
const float scale = 32.f * 255.f / waveform_scale;
|
||||||
|
|
||||||
|
// See Cairo documentation on stride.
|
||||||
|
const int cairo_stride = Cairo::ImageSurface::format_stride_for_width(Cairo::FORMAT_ARGB32, waveform_width);
|
||||||
|
std::unique_ptr<unsigned char[]> buffer(new unsigned char[256 * cairo_stride]);
|
||||||
|
|
||||||
|
// Clear waveform.
|
||||||
|
memset(buffer.get(), 0, 256 * cairo_stride);
|
||||||
|
|
||||||
|
// TODO: Optimize.
|
||||||
|
for (int col = 0; col < waveform_width; col++) {
|
||||||
|
for (int val = 0; val < 256; val++) {
|
||||||
|
const float r = needRed ? scale * rwave[col][255 - val] : 0.f;
|
||||||
|
const float g = needGreen ? scale * gwave[col][255 - val] : 0.f;
|
||||||
|
const float b = needBlue ? scale * bwave[col][255 - val] : 0.f;
|
||||||
|
const float value = (r > g && r > b) ? r : ((g > b) ? g : b);
|
||||||
|
if (value <= 0) {
|
||||||
|
buffer[val * cairo_stride + col * 4 + 3] = 0;
|
||||||
|
} else {
|
||||||
|
buffer[val * cairo_stride + col * 4 + 3] = value;
|
||||||
|
buffer[val * cairo_stride + col * 4 + 2] = r;
|
||||||
|
buffer[val * cairo_stride + col * 4 + 1] = g;
|
||||||
|
buffer[val * cairo_stride + col * 4] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cairo::RefPtr<Cairo::ImageSurface> surface = Cairo::ImageSurface::create(
|
||||||
|
buffer.get(), Cairo::FORMAT_ARGB32, waveform_width, 256, cairo_stride);
|
||||||
|
auto orig_matrix = cr->get_matrix();
|
||||||
|
cr->translate(padding, 0);
|
||||||
|
cr->scale(static_cast<double>(w - 2 * padding) / waveform_width, h / 256.0);
|
||||||
|
cr->set_source(surface, 0, 0);
|
||||||
|
cr->set_operator(Cairo::OPERATOR_OVER);
|
||||||
|
cr->paint();
|
||||||
|
surface->finish();
|
||||||
|
cr->set_matrix(orig_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
|
bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1070,6 +1186,10 @@ bool HistogramArea::on_button_release_event (GdkEventButton* event)
|
|||||||
|
|
||||||
bool HistogramArea::on_motion_notify_event (GdkEventMotion* event)
|
bool HistogramArea::on_motion_notify_event (GdkEventMotion* event)
|
||||||
{
|
{
|
||||||
|
if (drawMode == 0 || scopeType == 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isPressed)
|
if (isPressed)
|
||||||
{
|
{
|
||||||
double mod = 1 + (event->x - movingPosition) / get_width();
|
double mod = 1 + (event->x - movingPosition) / get_width();
|
||||||
|
@@ -130,10 +130,14 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
LUTu rhist, ghist, bhist, lhist, chist;
|
LUTu rhist, ghist, bhist, lhist, chist;
|
||||||
LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused?
|
LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused?
|
||||||
|
int waveform_scale;
|
||||||
|
int waveform_width;
|
||||||
|
std::unique_ptr<int[][256]> rwave, gwave, bwave;
|
||||||
|
|
||||||
bool valid;
|
bool valid;
|
||||||
int drawMode;
|
int drawMode;
|
||||||
DrawModeListener *myDrawModeListener;
|
DrawModeListener *myDrawModeListener;
|
||||||
|
int scopeType;
|
||||||
int oldwidth, oldheight;
|
int oldwidth, oldheight;
|
||||||
|
|
||||||
bool needRed, needGreen, needBlue, needLuma, needChroma;
|
bool needRed, needGreen, needBlue, needLuma, needChroma;
|
||||||
@@ -158,9 +162,14 @@ public:
|
|||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histRedRaw,
|
const LUTu& histRedRaw,
|
||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw
|
const LUTu& histBlueRaw,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
);
|
);
|
||||||
void updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode);
|
void updateOptions (bool r, bool g, bool b, bool l, bool c, bool raw, int mode, int type);
|
||||||
void on_realize() override;
|
void on_realize() override;
|
||||||
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
|
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
|
||||||
bool on_button_press_event (GdkEventButton* event) override;
|
bool on_button_press_event (GdkEventButton* event) override;
|
||||||
@@ -171,6 +180,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void drawCurve(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int vsize);
|
void drawCurve(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int vsize);
|
||||||
void drawMarks(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi);
|
void drawMarks(Cairo::RefPtr<Cairo::Context> &cr, const LUTu & data, double scale, int hsize, int & ui, int & oi);
|
||||||
|
void drawWaveform(Cairo::RefPtr<Cairo::Context> &cr, int hsize, int vsize);
|
||||||
Gtk::SizeRequestMode get_request_mode_vfunc () const override;
|
Gtk::SizeRequestMode get_request_mode_vfunc () const override;
|
||||||
void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override;
|
void get_preferred_height_vfunc (int& minimum_height, int& natural_height) const override;
|
||||||
void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override;
|
void get_preferred_width_vfunc (int &minimum_width, int &natural_width) const override;
|
||||||
@@ -195,6 +205,7 @@ protected:
|
|||||||
Gtk::ToggleButton* showBAR;
|
Gtk::ToggleButton* showBAR;
|
||||||
Gtk::ToggleButton* showChro;
|
Gtk::ToggleButton* showChro;
|
||||||
Gtk::Button* showMode;
|
Gtk::Button* showMode;
|
||||||
|
Gtk::Button* scopeType;
|
||||||
|
|
||||||
Gtk::Image *redImage;
|
Gtk::Image *redImage;
|
||||||
Gtk::Image *greenImage;
|
Gtk::Image *greenImage;
|
||||||
@@ -232,9 +243,15 @@ public:
|
|||||||
const LUTu& histChroma,
|
const LUTu& histChroma,
|
||||||
const LUTu& histRedRaw,
|
const LUTu& histRedRaw,
|
||||||
const LUTu& histGreenRaw,
|
const LUTu& histGreenRaw,
|
||||||
const LUTu& histBlueRaw)
|
const LUTu& histBlueRaw,
|
||||||
|
int waveformScale,
|
||||||
|
int waveformWidth,
|
||||||
|
const int waveformRed[][256],
|
||||||
|
const int waveformGreen[][256],
|
||||||
|
const int waveformBlue[][256]
|
||||||
|
)
|
||||||
{
|
{
|
||||||
histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw);
|
histogramArea->update(histRed, histGreen, histBlue, histLuma, histChroma, histRedRaw, histGreenRaw, histBlueRaw, waveformScale, waveformWidth, waveformRed, waveformGreen, waveformBlue);
|
||||||
}
|
}
|
||||||
// pointermotionlistener interface
|
// pointermotionlistener interface
|
||||||
void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) override;
|
void pointerMoved (bool validPos, const Glib::ustring &profile, const Glib::ustring &profileW, int x, int y, int r, int g, int b, bool isRaw = false) override;
|
||||||
@@ -251,6 +268,8 @@ public:
|
|||||||
void chro_toggled ();
|
void chro_toggled ();
|
||||||
void bar_toggled ();
|
void bar_toggled ();
|
||||||
void mode_released ();
|
void mode_released ();
|
||||||
|
void type_pressed ();
|
||||||
|
void type_changed ();
|
||||||
void rgbv_toggled ();
|
void rgbv_toggled ();
|
||||||
void resized (Gtk::Allocation& req);
|
void resized (Gtk::Allocation& req);
|
||||||
|
|
||||||
|
@@ -450,6 +450,7 @@ void Options::setDefaults()
|
|||||||
histogramBar = true;
|
histogramBar = true;
|
||||||
histogramHeight = 200;
|
histogramHeight = 200;
|
||||||
histogramDrawMode = 0;
|
histogramDrawMode = 0;
|
||||||
|
histogramScopeType = 0;
|
||||||
curvebboxpos = 1;
|
curvebboxpos = 1;
|
||||||
complexity = 1;
|
complexity = 1;
|
||||||
prevdemo = PD_Sidecar;
|
prevdemo = PD_Sidecar;
|
||||||
@@ -1426,6 +1427,10 @@ void Options::readFromFile(Glib::ustring fname)
|
|||||||
histogramDrawMode = keyFile.get_integer("GUI", "HistogramDrawMode");
|
histogramDrawMode = keyFile.get_integer("GUI", "HistogramDrawMode");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyFile.has_key("GUI", "HistogramScopeType")) {
|
||||||
|
histogramScopeType = keyFile.get_integer("GUI", "HistogramScopeType");
|
||||||
|
}
|
||||||
|
|
||||||
if (keyFile.has_key("GUI", "NavigatorRGBUnit")) {
|
if (keyFile.has_key("GUI", "NavigatorRGBUnit")) {
|
||||||
navRGBUnit = (NavigatorUnit)keyFile.get_integer("GUI", "NavigatorRGBUnit");
|
navRGBUnit = (NavigatorUnit)keyFile.get_integer("GUI", "NavigatorRGBUnit");
|
||||||
}
|
}
|
||||||
@@ -2233,6 +2238,7 @@ void Options::saveToFile(Glib::ustring fname)
|
|||||||
keyFile.set_boolean("GUI", "HistogramBar", histogramBar);
|
keyFile.set_boolean("GUI", "HistogramBar", histogramBar);
|
||||||
keyFile.set_integer("GUI", "HistogramHeight", histogramHeight);
|
keyFile.set_integer("GUI", "HistogramHeight", histogramHeight);
|
||||||
keyFile.set_integer("GUI", "HistogramDrawMode", histogramDrawMode);
|
keyFile.set_integer("GUI", "HistogramDrawMode", histogramDrawMode);
|
||||||
|
keyFile.set_integer("GUI", "HistogramScopeType", histogramScopeType);
|
||||||
keyFile.set_integer("GUI", "NavigatorRGBUnit", (int)navRGBUnit);
|
keyFile.set_integer("GUI", "NavigatorRGBUnit", (int)navRGBUnit);
|
||||||
keyFile.set_integer("GUI", "NavigatorHSVUnit", (int)navHSVUnit);
|
keyFile.set_integer("GUI", "NavigatorHSVUnit", (int)navHSVUnit);
|
||||||
keyFile.set_boolean("GUI", "ShowFilmStripToolBar", showFilmStripToolBar);
|
keyFile.set_boolean("GUI", "ShowFilmStripToolBar", showFilmStripToolBar);
|
||||||
|
@@ -312,6 +312,7 @@ public:
|
|||||||
bool histogramBar;
|
bool histogramBar;
|
||||||
int histogramHeight;
|
int histogramHeight;
|
||||||
int histogramDrawMode;
|
int histogramDrawMode;
|
||||||
|
int histogramScopeType;
|
||||||
bool FileBrowserToolbarSingleRow;
|
bool FileBrowserToolbarSingleRow;
|
||||||
bool hideTPVScrollbar;
|
bool hideTPVScrollbar;
|
||||||
int whiteBalanceSpotSize;
|
int whiteBalanceSpotSize;
|
||||||
|
Reference in New Issue
Block a user