Add initial implementation of waveform

This commit is contained in:
Lawrence Lee
2020-07-21 22:45:10 -07:00
parent a18f17a476
commit 4cbd622569
10 changed files with 257 additions and 26 deletions

View File

@@ -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_R;Show/Hide red histogram.
HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram.
HISTOGRAM_TOOLTIP_TYPE;Toggle between histogram and waveform.
HISTORY_CHANGED;Changed
HISTORY_CUSTOMCURVE;Custom curve
HISTORY_FROMCLIPBOARD;From clipboard

View File

@@ -129,6 +129,8 @@ ImProcCoordinator::ImProcCoordinator() :
histLRETI(256),
waveformWidth(0),
CAMBrightCurveJ(), CAMBrightCurveQ(),
rCurve(),
@@ -1639,7 +1641,30 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
if (hListener) {
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)
{

View File

@@ -126,6 +126,12 @@ protected:
LUTu histBlue, histBlueRaw;
LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve;
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;
@@ -195,6 +201,7 @@ protected:
void reallocAll();
void updateLRGBHistograms();
void updateWaveforms();
void setScale(int prevscale);
void updatePreviewImage (int todo, bool panningRelatedChange);

View File

@@ -327,7 +327,12 @@ public:
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
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;
};

View File

@@ -2245,11 +2245,16 @@ void EditorPanel::histogramChanged(
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
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) {
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);

View File

@@ -126,7 +126,12 @@ public:
const LUTu& histGreenRaw,
const LUTu& histBlueRaw,
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;
// event handlers

View File

@@ -85,6 +85,7 @@ HistogramPanel::HistogramPanel ()
showChro = Gtk::manage (new Gtk::ToggleButton ());
showRAW = Gtk::manage (new Gtk::ToggleButton ());
showMode = Gtk::manage (new Gtk::Button ());
scopeType = Gtk::manage (new Gtk::Button ());
showBAR = Gtk::manage (new Gtk::ToggleButton ());
showRed->set_name("histButton");
@@ -101,6 +102,8 @@ HistogramPanel::HistogramPanel ()
showRAW->set_can_focus(false);
showMode->set_name("histButton");
showMode->set_can_focus(false);
scopeType->set_name("histButton");
scopeType->set_can_focus(false);
showBAR->set_name("histButton");
showBAR->set_can_focus(false);
@@ -111,6 +114,7 @@ HistogramPanel::HistogramPanel ()
showChro->set_relief (Gtk::RELIEF_NONE);
showRAW->set_relief (Gtk::RELIEF_NONE);
showMode->set_relief (Gtk::RELIEF_NONE);
scopeType->set_relief (Gtk::RELIEF_NONE);
showBAR->set_relief (Gtk::RELIEF_NONE);
showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R"));
@@ -120,6 +124,7 @@ HistogramPanel::HistogramPanel ()
showChro->set_tooltip_text (M("HISTOGRAM_TOOLTIP_CHRO"));
showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW"));
showMode->set_tooltip_text (M("HISTOGRAM_TOOLTIP_MODE"));
scopeType->set_tooltip_text (M("HISTOGRAM_TOOLTIP_TYPE"));
showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR"));
buttonGrid = Gtk::manage (new Gtk::Grid ());
@@ -145,9 +150,15 @@ HistogramPanel::HistogramPanel ()
showMode->set_image(*mode1Image);
else
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);
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(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(showRAW , 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);
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 );
showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::raw_toggled), showRAW );
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 );
buttonGrid->add (*showRed);
@@ -174,6 +187,7 @@ HistogramPanel::HistogramPanel ()
buttonGrid->add (*showChro);
buttonGrid->add (*showRAW);
buttonGrid->add (*showMode);
buttonGrid->add (*scopeType);
buttonGrid->add (*showBAR);
// 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);
} else {
showRAW->set_image(*rawImage_g);
showValue->set_sensitive(true);
showChro->set_sensitive(true);
showValue->set_sensitive(options.histogramScopeType != 1);
showChro->set_sensitive(options.histogramScopeType != 1);
}
rgbv_toggled();
@@ -285,6 +299,34 @@ void HistogramPanel::mode_released ()
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 ()
{
showBAR->set_image(showBAR->get_active() ? *barImage : *barImage_g);
@@ -294,7 +336,7 @@ void HistogramPanel::bar_toggled ()
void HistogramPanel::rgbv_toggled ()
{
// 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 ();
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)
{
if (!get_realized () || !showMode || rawMode) {
if (!get_realized () || !showMode || rawMode || options.histogramScopeType == 1) {
return;
}
@@ -655,7 +697,9 @@ void HistogramRGBArea::factorChanged (double newFactor)
//
// HistogramArea
HistogramArea::HistogramArea (DrawModeListener *fml) :
waveform_width(0),
valid(false), drawMode(options.histogramDrawMode), myDrawModeListener(fml),
scopeType(options.histogramScopeType),
oldwidth(-1), oldheight(-1),
needRed(options.histogramRed), needGreen(options.histogramGreen), needBlue(options.histogramBlue),
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);
}
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;
@@ -730,6 +774,7 @@ void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool c, bool
options.histogramChroma = needChroma = c;
options.histogramRAW = rawMode = raw;
options.histogramDrawMode = drawMode = mode;
options.histogramScopeType = scopeType = type;
updateBackBuffer ();
}
@@ -742,7 +787,12 @@ void HistogramArea::update(
const LUTu& histChroma,
const LUTu& histRedRaw,
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) {
@@ -754,6 +804,19 @@ void HistogramArea::update(
rhistRaw = histRedRaw;
ghistRaw = histGreenRaw;
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;
} else {
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)
// draw vertical gridlines
if (options.histogramScopeType != 1) {
for (int i = 0; i <= nrOfVGridPartitions; i++) {
double xpos = padding + 0.5;
if (options.histogramDrawMode < 2) {
@@ -837,9 +901,17 @@ void HistogramArea::updateBackBuffer ()
cr->line_to (xpos, h);
cr->stroke ();
}
}
// 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++) {
cr->move_to (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();
if (valid) {
if (valid && scopeType == 0) {
// For RAW mode use the other hists
LUTu& rh = rawMode ? rhistRaw : rhist;
LUTu& gh = rawMode ? ghistRaw : ghist;
@@ -962,6 +1034,8 @@ void HistogramArea::updateBackBuffer ()
drawMarks(cr, bhchanged, realhistheight, w, ui, oi);
}
} else if (scopeType == 1 && waveform_width > 0) {
drawWaveform(cr, w, h);
}
// Draw the frame's border
@@ -1026,6 +1100,48 @@ void HistogramArea::drawMarks(Cairo::RefPtr<Cairo::Context> &cr,
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)
{
@@ -1070,6 +1186,10 @@ bool HistogramArea::on_button_release_event (GdkEventButton* event)
bool HistogramArea::on_motion_notify_event (GdkEventMotion* event)
{
if (drawMode == 0 || scopeType == 1) {
return false;
}
if (isPressed)
{
double mod = 1 + (event->x - movingPosition) / get_width();

View File

@@ -130,10 +130,14 @@ private:
protected:
LUTu rhist, ghist, bhist, lhist, chist;
LUTu rhistRaw, ghistRaw, bhistRaw, lhistRaw; //lhistRaw is unused?
int waveform_scale;
int waveform_width;
std::unique_ptr<int[][256]> rwave, gwave, bwave;
bool valid;
int drawMode;
DrawModeListener *myDrawModeListener;
int scopeType;
int oldwidth, oldheight;
bool needRed, needGreen, needBlue, needLuma, needChroma;
@@ -158,9 +162,14 @@ public:
const LUTu& histChroma,
const LUTu& histRedRaw,
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;
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
bool on_button_press_event (GdkEventButton* event) override;
@@ -171,6 +180,7 @@ public:
private:
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 drawWaveform(Cairo::RefPtr<Cairo::Context> &cr, int hsize, int vsize);
Gtk::SizeRequestMode get_request_mode_vfunc () 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;
@@ -195,6 +205,7 @@ protected:
Gtk::ToggleButton* showBAR;
Gtk::ToggleButton* showChro;
Gtk::Button* showMode;
Gtk::Button* scopeType;
Gtk::Image *redImage;
Gtk::Image *greenImage;
@@ -232,9 +243,15 @@ public:
const LUTu& histChroma,
const LUTu& histRedRaw,
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
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 bar_toggled ();
void mode_released ();
void type_pressed ();
void type_changed ();
void rgbv_toggled ();
void resized (Gtk::Allocation& req);

View File

@@ -450,6 +450,7 @@ void Options::setDefaults()
histogramBar = true;
histogramHeight = 200;
histogramDrawMode = 0;
histogramScopeType = 0;
curvebboxpos = 1;
complexity = 1;
prevdemo = PD_Sidecar;
@@ -1426,6 +1427,10 @@ void Options::readFromFile(Glib::ustring fname)
histogramDrawMode = keyFile.get_integer("GUI", "HistogramDrawMode");
}
if (keyFile.has_key("GUI", "HistogramScopeType")) {
histogramScopeType = keyFile.get_integer("GUI", "HistogramScopeType");
}
if (keyFile.has_key("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_integer("GUI", "HistogramHeight", histogramHeight);
keyFile.set_integer("GUI", "HistogramDrawMode", histogramDrawMode);
keyFile.set_integer("GUI", "HistogramScopeType", histogramScopeType);
keyFile.set_integer("GUI", "NavigatorRGBUnit", (int)navRGBUnit);
keyFile.set_integer("GUI", "NavigatorHSVUnit", (int)navHSVUnit);
keyFile.set_boolean("GUI", "ShowFilmStripToolBar", showFilmStripToolBar);

View File

@@ -312,6 +312,7 @@ public:
bool histogramBar;
int histogramHeight;
int histogramDrawMode;
int histogramScopeType;
bool FileBrowserToolbarSingleRow;
bool hideTPVScrollbar;
int whiteBalanceSpotSize;