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_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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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,20 +889,29 @@ void HistogramArea::updateBackBuffer ()
|
||||
int nrOfVGridPartitions = 8; // always show 8 stops (lines at 1,3,7,15,31,63,127)
|
||||
|
||||
// draw vertical gridlines
|
||||
for (int i = 0; i <= nrOfVGridPartitions; i++) {
|
||||
double xpos = padding + 0.5;
|
||||
if (options.histogramDrawMode < 2) {
|
||||
xpos += (pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0;
|
||||
} else {
|
||||
xpos += HistogramScaling::log (255, pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0;
|
||||
if (options.histogramScopeType != 1) {
|
||||
for (int i = 0; i <= nrOfVGridPartitions; i++) {
|
||||
double xpos = padding + 0.5;
|
||||
if (options.histogramDrawMode < 2) {
|
||||
xpos += (pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0;
|
||||
} else {
|
||||
xpos += HistogramScaling::log (255, pow(2.0,i) - 1) * (w - padding * 2.0) / 255.0;
|
||||
}
|
||||
cr->move_to (xpos, 0.);
|
||||
cr->line_to (xpos, h);
|
||||
cr->stroke ();
|
||||
}
|
||||
cr->move_to (xpos, 0.);
|
||||
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();
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -312,6 +312,7 @@ public:
|
||||
bool histogramBar;
|
||||
int histogramHeight;
|
||||
int histogramDrawMode;
|
||||
int histogramScopeType;
|
||||
bool FileBrowserToolbarSingleRow;
|
||||
bool hideTPVScrollbar;
|
||||
int whiteBalanceSpotSize;
|
||||
|
Reference in New Issue
Block a user