Implement RGB parade

This commit is contained in:
Lawrence Lee 2020-09-26 11:54:05 -07:00
parent 6e7185081a
commit 1a5456dbd1
7 changed files with 428 additions and 17 deletions

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="histogram-type-parade-off-small.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:export-filename="/tmp/template.png"
id="SVGRoot"
version="1.1"
viewBox="0 0 16 16"
height="16"
width="16">
<sodipodi:namedview
inkscape:document-rotation="0"
inkscape:snap-bbox-midpoints="false"
inkscape:snap-grids="true"
inkscape:object-nodes="false"
inkscape:snap-others="false"
inkscape:bbox-nodes="true"
inkscape:snap-bbox="true"
inkscape:pagecheckerboard="false"
inkscape:grid-bbox="true"
inkscape:window-maximized="1"
inkscape:window-y="0"
inkscape:window-x="0"
inkscape:window-height="1041"
inkscape:window-width="1920"
showgrid="true"
inkscape:current-layer="layer1"
inkscape:document-units="px"
inkscape:cy="8.6629402"
inkscape:cx="7.579725"
inkscape:zoom="70.762127"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
borderopacity="1.0"
bordercolor="#666768"
pagecolor="#E0E1E2"
id="base">
<inkscape:grid
dotted="false"
empspacing="7"
originy="1"
originx="1"
id="grid1374"
type="xygrid" />
</sodipodi:namedview>
<defs
id="defs815" />
<metadata
id="metadata818">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Lawrence Lee</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:rights>
<dc:description>RawTherapee icon.</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-8)"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
y="12"
x="4"
height="8"
width="8"
id="rect896"
style="opacity:0.3;fill:#2a7fff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(0,8)"
d="M 9.3339844 6.1777344 C 8.678894 6.4640849 8 7 8 7 C 8 7 7.3211062 7.5359114 6.6660156 7.8222656 L 6.6660156 9.671875 C 7.127212 9.8671333 7.5894845 10 8 10 C 8.4105155 10 8.872788 9.8671333 9.3339844 9.671875 L 9.3339844 6.1777344 z "
style="fill:#00ff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path894" />
<rect
y="11.5"
x="3.5"
height="9"
width="9.000001"
id="rect849"
style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999998;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(0,8)"
d="M 10 6 C 9.8023972 6 9.5703097 6.0744328 9.3339844 6.1777344 L 9.3339844 9.671875 C 10.673091 9.1049331 12 8 12 8 L 12 7 C 12 7 10.745355 6 10 6 z "
style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path835" />
<path
transform="translate(0,8)"
d="M 4 7 L 4 8 C 4 8 5.3269093 9.1049331 6.6660156 9.671875 L 6.6660156 7.8222656 C 6.4296902 7.9255686 6.1976033 8 6 8 C 5.2546434 8 4 7 4 7 z "
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path837" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
viewBox="0 0 16 16"
version="1.1"
id="SVGRoot"
inkscape:export-filename="/tmp/template.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="histogram-type-parade-small.svg">
<sodipodi:namedview
id="base"
pagecolor="#E0E1E2"
bordercolor="#666768"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="26.672054"
inkscape:cx="6.4865394"
inkscape:cy="9.5260087"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1041"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:grid-bbox="true"
inkscape:pagecheckerboard="false"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:snap-others="false"
inkscape:object-nodes="false"
inkscape:snap-grids="true"
inkscape:snap-bbox-midpoints="false"
inkscape:document-rotation="0">
<inkscape:grid
type="xygrid"
id="grid1374"
originx="1"
originy="1"
empspacing="7"
dotted="false" />
</sodipodi:namedview>
<defs
id="defs815" />
<metadata
id="metadata818">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Lawrence Lee</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:rights>
<dc:description>RawTherapee icon.</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1"
transform="translate(0,-8)">
<rect
style="opacity:0.3;fill:#2a7fff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect896"
width="12"
height="12"
x="2"
y="10" />
<path
transform="translate(0,8)"
d="M 11 4.0234375 C 10.691576 4.0252479 10.345351 4.1582074 10 4.3535156 L 10 11.367188 C 12.008913 10.233429 14 8.0234375 14 8.0234375 L 14 6 C 14 6 12.197351 4.0164165 11 4.0234375 z "
style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path894" />
<rect
style="opacity:1;fill:none;fill-opacity:0.3;stroke:#000000;stroke-width:0.999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect849"
width="13"
height="13.000001"
x="1.5"
y="9.5" />
<path
transform="translate(0,8)"
d="M 2 6 L 2 8.0234375 C 2 8.0234375 3.9910868 10.233429 6 11.367188 L 6 7.6972656 C 5.6537675 7.8922018 5.3071207 8.0252714 5 8.0234375 C 3.7936541 8.0162345 2 6 2 6 z "
style="fill:#fd0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path834" />
<path
transform="translate(0,8)"
d="M 10 4.3535156 C 8.9719096 4.9349372 7.9511719 6.0839844 7.9511719 6.0839844 C 7.9511719 6.0839844 6.9807951 7.1450573 6 7.6972656 L 6 11.367188 C 6.6915471 11.757472 7.3844485 12.023438 8 12.023438 C 8.6155516 12.023438 9.3084528 11.757472 10 11.367188 L 10 4.3535156 z "
style="fill:#00ff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path844" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -252,6 +252,7 @@ HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram.
HISTOGRAM_TOOLTIP_TYPE;Toggle visibility of the scope selection buttons.
HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM;Histogram
HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW;Raw Histogram
HISTOGRAM_TOOLTIP_TYPE_PARADE;RGB Parade
HISTOGRAM_TOOLTIP_TYPE_WAVEFORM;Waveform
HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC;Hue-Chroma Vectorscope
HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS;Hue-Saturation Vectorscope

View File

@ -2301,6 +2301,7 @@ bool EditorPanel::updateVectorscopeHS(void) const
bool EditorPanel::updateWaveform(void) const
{
return histogram_scope_type == ScopeType::WAVEFORM
|| histogram_scope_type == ScopeType::PARADE
|| histogram_scope_type == ScopeType::NONE;
}
@ -2327,6 +2328,7 @@ void EditorPanel::scopeTypeChanged(ScopeType new_type)
case ScopeType::VECTORSCOPE_HS:
histogram_observable->requestUpdateVectorscopeHS();
break;
case ScopeType::PARADE:
case ScopeType::WAVEFORM:
histogram_observable->requestUpdateWaveform();
break;

View File

@ -86,6 +86,7 @@ HistogramPanel::HistogramPanel () :
case ScopeType::VECTORSCOPE_HS:
histogramRGBArea = nullptr;
break;
case ScopeType::PARADE:
case ScopeType::WAVEFORM:
histogramRGBArea = histogramRGBAreaVert.get();
break;
@ -129,17 +130,20 @@ HistogramPanel::HistogramPanel () :
histImage.reset(new RTImage("histogram-type-histogram-small.png"));
histRawImage.reset(new RTImage("histogram-bayer-on-small.png"));
paradeImage.reset(new RTImage("histogram-type-parade-small.png"));
waveImage.reset(new RTImage("histogram-type-waveform-small.png"));
vectHcImage.reset(new RTImage("histogram-type-vectorscope-hc-small.png"));
vectHsImage.reset(new RTImage("histogram-type-vectorscope-hs-small.png"));
histImageOn.reset(new RTImage("histogram-type-histogram-small.png"));
histRawImageOn.reset(new RTImage("histogram-bayer-on-small.png"));
paradeImageOn.reset(new RTImage("histogram-type-parade-small.png"));
waveImageOn.reset(new RTImage("histogram-type-waveform-small.png"));
vectHcImageOn.reset(new RTImage("histogram-type-vectorscope-hc-small.png"));
vectHsImageOn.reset(new RTImage("histogram-type-vectorscope-hs-small.png"));
histImageOff.reset(new RTImage("histogram-type-histogram-off-small.png"));
histRawImageOff.reset(new RTImage("histogram-bayer-off-small.png"));
paradeImageOff.reset(new RTImage("histogram-type-parade-off-small.png"));
waveImageOff.reset(new RTImage("histogram-type-waveform-off-small.png"));
vectHcImageOff.reset(new RTImage("histogram-type-vectorscope-hc-off-small.png"));
vectHsImageOff.reset(new RTImage("histogram-type-vectorscope-hs-off-small.png"));
@ -156,11 +160,13 @@ HistogramPanel::HistogramPanel () :
Gtk::RadioButtonGroup scopeTypeGroup;
scopeHistBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeHistRawBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeParadeBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeWaveBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeVectHcBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeVectHsBtn = Gtk::manage(new Gtk::RadioButton(scopeTypeGroup));
scopeHistBtn->set_mode(false);
scopeHistRawBtn->set_mode(false);
scopeParadeBtn->set_mode(false);
scopeWaveBtn->set_mode(false);
scopeVectHcBtn->set_mode(false);
scopeVectHsBtn->set_mode(false);
@ -185,6 +191,8 @@ HistogramPanel::HistogramPanel () :
scopeHistBtn->set_can_focus(false);
scopeHistRawBtn->set_name("histButton");
scopeHistRawBtn->set_can_focus(false);
scopeParadeBtn->set_name("histButton");
scopeParadeBtn->set_can_focus(false);
scopeWaveBtn->set_name("histButton");
scopeWaveBtn->set_can_focus(false);
scopeVectHcBtn->set_name("histButton");
@ -202,6 +210,7 @@ HistogramPanel::HistogramPanel () :
showBAR->set_relief (Gtk::RELIEF_NONE);
scopeHistBtn->set_relief (Gtk::RELIEF_NONE);
scopeHistRawBtn->set_relief (Gtk::RELIEF_NONE);
scopeParadeBtn->set_relief (Gtk::RELIEF_NONE);
scopeWaveBtn->set_relief (Gtk::RELIEF_NONE);
scopeVectHcBtn->set_relief (Gtk::RELIEF_NONE);
scopeVectHsBtn->set_relief (Gtk::RELIEF_NONE);
@ -216,6 +225,7 @@ HistogramPanel::HistogramPanel () :
showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR"));
scopeHistBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM"));
scopeHistRawBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_HISTOGRAM_RAW"));
scopeParadeBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_PARADE"));
scopeWaveBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_WAVEFORM"));
scopeVectHcBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HC"));
scopeVectHsBtn->set_tooltip_text(M("HISTOGRAM_TOOLTIP_TYPE_VECTORSCOPE_HS"));
@ -249,6 +259,7 @@ HistogramPanel::HistogramPanel () :
showMode->set_image(*mode2Image);
scopeHistBtn->set_image(*histImageOff);
scopeHistRawBtn->set_image(*histRawImageOff);
scopeParadeBtn->set_image(*paradeImageOff);
scopeWaveBtn->set_image(*waveImageOff);
scopeVectHcBtn->set_image(*vectHcImageOff);
scopeVectHsBtn->set_image(*vectHsImageOff);
@ -261,6 +272,10 @@ HistogramPanel::HistogramPanel () :
scopeHistRawBtn->set_active();
scopeHistRawBtn->set_image(*histRawImageOn);
break;
case ScopeType::PARADE:
scopeParadeBtn->set_active();
scopeParadeBtn->set_image(*paradeImageOn);
break;
case ScopeType::WAVEFORM:
scopeWaveBtn->set_active();
scopeWaveBtn->set_image(*waveImageOn);
@ -279,6 +294,8 @@ HistogramPanel::HistogramPanel () :
showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g);
type_changed();
updateHistAreaOptions();
updateHistRGBAreaOptions();
setExpandAlignProperties(showRed , false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
setExpandAlignProperties(showGreen, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
@ -299,6 +316,7 @@ HistogramPanel::HistogramPanel () :
showBAR->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::bar_toggled), showBAR );
scopeHistBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeHistBtn));
scopeHistRawBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeHistRawBtn));
scopeParadeBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeParadeBtn));
scopeWaveBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeWaveBtn));
scopeVectHcBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeVectHcBtn));
scopeVectHsBtn->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &HistogramPanel::type_selected), scopeVectHsBtn));
@ -314,6 +332,7 @@ HistogramPanel::HistogramPanel () :
scopeButtons->add(*scopeHistBtn);
scopeButtons->add(*scopeHistRawBtn);
scopeButtons->add(*scopeParadeBtn);
scopeButtons->add(*scopeWaveBtn);
scopeButtons->add(*scopeVectHsBtn);
scopeButtons->add(*scopeVectHcBtn);
@ -462,6 +481,8 @@ void HistogramPanel::type_selected(Gtk::RadioButton* button)
new_type = ScopeType::HISTOGRAM;
} else if (button == scopeHistRawBtn) {
new_type = ScopeType::HISTOGRAM_RAW;
} else if (button == scopeParadeBtn) {
new_type = ScopeType::PARADE;
} else if (button == scopeWaveBtn) {
new_type = ScopeType::WAVEFORM;
} else if (button == scopeVectHcBtn) {
@ -481,6 +502,9 @@ void HistogramPanel::type_selected(Gtk::RadioButton* button)
case ScopeType::HISTOGRAM_RAW:
scopeHistRawBtn->set_image(*histRawImageOff);
break;
case ScopeType::PARADE:
scopeParadeBtn->set_image(*paradeImageOff);
break;
case ScopeType::WAVEFORM:
scopeWaveBtn->set_image(*waveImageOff);
break;
@ -501,6 +525,9 @@ void HistogramPanel::type_selected(Gtk::RadioButton* button)
case ScopeType::HISTOGRAM_RAW:
scopeHistRawBtn->set_image(*histRawImageOn);
break;
case ScopeType::PARADE:
scopeParadeBtn->set_image(*paradeImageOn);
break;
case ScopeType::WAVEFORM:
scopeWaveBtn->set_image(*waveImageOn);
break;
@ -551,6 +578,7 @@ void HistogramPanel::type_changed()
scopeType->set_image(*histRawImage);
histogramRGBArea = nullptr;
break;
case ScopeType::PARADE:
case ScopeType::WAVEFORM:
showRed->set_sensitive();
showGreen->set_sensitive();
@ -558,7 +586,11 @@ void HistogramPanel::type_changed()
showValue->set_sensitive();
showChro->set_sensitive(false);
showMode->set_sensitive(false);
scopeType->set_image(*waveImage);
if (options.histogramScopeType == ScopeType::PARADE) {
scopeType->set_image(*paradeImage);
} else {
scopeType->set_image(*waveImage);
}
histogramRGBArea = histogramRGBAreaVert.get();
break;
case ScopeType::VECTORSCOPE_HC:
@ -803,7 +835,11 @@ void HistogramRGBArea::setShow(bool show)
void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustring &profile, const Glib::ustring &profileW)
{
if (!get_realized () || !showMode || !(options.histogramScopeType == ScopeType::HISTOGRAM || options.histogramScopeType == ScopeType::WAVEFORM)) {
if (!get_realized () || !showMode || !(
options.histogramScopeType == ScopeType::HISTOGRAM
|| options.histogramScopeType == ScopeType::PARADE
|| options.histogramScopeType == ScopeType::WAVEFORM
)) {
return;
}
@ -852,6 +888,7 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin
if(
(needLuma || needChroma)
&& (options.histogramScopeType == ScopeType::HISTOGRAM
|| options.histogramScopeType == ScopeType::PARADE
|| options.histogramScopeType == ScopeType::WAVEFORM)
) {
float Lab_L, Lab_a, Lab_b;
@ -1009,7 +1046,7 @@ void HistogramRGBAreaHori::get_preferred_width_for_height_vfunc (int height, int
void HistogramRGBAreaVert::drawBar(Cairo::RefPtr<Cairo::Context> cc, double value, double max_value, int winw, int winh, double scale)
{
double pos;
if (options.histogramDrawMode < 2 || options.histogramScopeType == ScopeType::WAVEFORM) {
if (options.histogramDrawMode < 2 || options.histogramScopeType == ScopeType::PARADE || options.histogramScopeType == ScopeType::WAVEFORM) {
pos = padding + value * (winh - padding * 2.0 - 1) / max_value + 0.5 * scale;
} else {
pos = padding + HistogramScaling::log (max_value, value) * (winh - padding * 2.0) / max_value + 0.5 * scale;
@ -1054,7 +1091,7 @@ HistogramArea::HistogramArea (DrawModeListener *fml) :
vect_hc_buffer_dirty(true), vect_hs_buffer_dirty(true),
waveform_scale(0),
rwave(0, 0), gwave(0, 0),bwave(0, 0), lwave(0, 0),
wave_buffer_dirty(true),
parade_buffer_dirty(true), wave_buffer_dirty(true),
valid(false), drawMode(options.histogramDrawMode), myDrawModeListener(fml),
scopeType(options.histogramScopeType),
oldwidth(-1), oldheight(-1),
@ -1178,13 +1215,14 @@ void HistogramArea::update(
ghistRaw = histGreenRaw;
bhistRaw = histBlueRaw;
break;
case ScopeType::PARADE:
case ScopeType::WAVEFORM:
waveform_scale = waveformScale;
rwave = waveformRed;
gwave = waveformGreen;
bwave = waveformBlue;
lwave = waveformLuma;
wave_buffer_dirty = true;
parade_buffer_dirty = wave_buffer_dirty = true;
break;
case ScopeType::VECTORSCOPE_HS:
vectorscope_scale = vectorscopeScale;
@ -1285,7 +1323,7 @@ void HistogramArea::updateBackBuffer ()
}
// draw horizontal gridlines
if (options.histogramScopeType == ScopeType::WAVEFORM) {
if (options.histogramScopeType == ScopeType::PARADE || options.histogramScopeType == ScopeType::WAVEFORM) {
for (int i = 0; i <= nrOfVGridPartitions; i++) {
const double ypos = h - padding - (pow(2.0,i) - 1) * (h - 2 * padding - 1) / 255.0;
cr->move_to(0, ypos);
@ -1419,6 +1457,8 @@ void HistogramArea::updateBackBuffer ()
drawMarks(cr, bhchanged, realhistheight, w, ui, oi);
}
} else if (scopeType == ScopeType::PARADE && rwave.getWidth() > 0) {
drawParade(cr, w, h);
} else if (scopeType == ScopeType::WAVEFORM && rwave.getWidth() > 0) {
drawWaveform(cr, w, h);
} else if (scopeType == ScopeType::VECTORSCOPE_HC || scopeType == ScopeType::VECTORSCOPE_HS) {
@ -1505,6 +1545,101 @@ void HistogramArea::drawMarks(Cairo::RefPtr<Cairo::Context> &cr,
cr->fill();
}
void HistogramArea::drawParade(Cairo::RefPtr<Cairo::Context> &cr, int w, int h)
{
// Arbitrary scale factor divided by current scale.
const float scale = trace_brightness * 32.f * 255.f / waveform_scale;
const int wave_width = rwave.getWidth();
const int wave_height = rwave.getHeight();
// See Cairo documentation on stride.
const int cairo_stride = Cairo::ImageSurface::format_stride_for_width(Cairo::FORMAT_ARGB32, rwave.getWidth());
if (parade_buffer_dirty) {
const auto buffer_size = static_cast<std::vector<unsigned char>::size_type>(wave_height) * cairo_stride;
parade_buffer_r.assign(buffer_size, 0);
parade_buffer_g.assign(buffer_size, 0);
parade_buffer_b.assign(buffer_size, 0);
wave_buffer_luma.assign(buffer_size, 0);
assert(parade_buffer_r.size() % 4 == 0);
assert(parade_buffer_g.size() % 4 == 0);
assert(parade_buffer_b.size() % 4 == 0);
assert(wave_buffer_luma.size() % 4 == 0);
for (int val = 0; val < wave_height; val++) {
const int* const r_row = rwave[val];
const int* const g_row = gwave[val];
const int* const b_row = bwave[val];
std::uint32_t* const buffer_r_row = reinterpret_cast<uint32_t*>(parade_buffer_r.data() + (255 - val) * cairo_stride);
std::uint32_t* const buffer_g_row = reinterpret_cast<uint32_t*>(parade_buffer_g.data() + (255 - val) * cairo_stride);
std::uint32_t* const buffer_b_row = reinterpret_cast<uint32_t*>(parade_buffer_b.data() + (255 - val) * cairo_stride);
for (int col = 0; col < wave_width; col++) {
const unsigned char r = std::min<float>(scale * r_row[col], 0xff);
const unsigned char g = std::min<float>(scale * g_row[col], 0xff);
const unsigned char b = std::min<float>(scale * b_row[col], 0xff);
if (r == 0) {
buffer_r_row[col] = 0;
} else {
buffer_r_row[col] = (r << 16) | (r << 24);
}
if (g == 0) {
buffer_g_row[col] = 0;
} else {
buffer_g_row[col] = (g << 8) | (g << 24);
}
if (b == 0) {
buffer_b_row[col] = 0;
} else {
const unsigned char green = b / 2; // Make blue easier to see.
buffer_b_row[col] = b | (green << 8) | (b << 24);
}
}
}
for (int val = 0; val < wave_height; val++) {
const int* const l_row = lwave[val];
std::uint32_t* const buffer_row =
reinterpret_cast<uint32_t*>(wave_buffer_luma.data() + (255 - val) * cairo_stride);
for (int col = 0; col < wave_width; col++) {
const unsigned char l = std::min<float>(scale * l_row[col], 0xff);
buffer_row[col] = l | (l << 8) | (l << 16) | (l << 24);
}
}
parade_buffer_dirty = false;
}
std::vector<unsigned char*> buffers;
if (needLuma) {
buffers.push_back(wave_buffer_luma.data());
}
if (needRed) {
buffers.push_back(parade_buffer_r.data());
}
if (needGreen) {
buffers.push_back(parade_buffer_g.data());
}
if (needBlue) {
buffers.push_back(parade_buffer_b.data());
}
auto orig_matrix = cr->get_matrix();
const double display_wave_width = static_cast<double>(w) / buffers.size();
for (int i = 0; i < buffers.size(); i++) {
Cairo::RefPtr<Cairo::ImageSurface> surface;
cr->translate(i * display_wave_width, padding);
cr->scale(display_wave_width / wave_width, (h - 2 * padding) / wave_height);
surface = Cairo::ImageSurface::create(
buffers[i], Cairo::FORMAT_ARGB32, wave_width, wave_height, cairo_stride);
cr->set_source(surface, 0, 0);
cr->set_operator(Cairo::OPERATOR_OVER);
cr->paint();
surface->finish();
cr->set_matrix(orig_matrix);
}
}
void HistogramArea::drawVectorscope(Cairo::RefPtr<Cairo::Context> &cr, int w, int h)
{
if (scopeType != ScopeType::VECTORSCOPE_HC && scopeType != ScopeType::VECTORSCOPE_HS) {
@ -1726,15 +1861,13 @@ void HistogramArea::drawWaveform(Cairo::RefPtr<Cairo::Context> &cr, int w, int h
}
}
if (needLuma) {
for (int val = 0; val < wave_height; val++) {
const int* const l_row = lwave[val];
std::uint32_t* const buffer_row =
reinterpret_cast<uint32_t*>(wave_buffer_luma.data() + (255 - val) * cairo_stride);
for (int col = 0; col < wave_width; col++) {
const unsigned char l = std::min<float>(scale * l_row[col], 0xff);
buffer_row[col] = l | (l << 8) | (l << 16) | (l << 24);
}
for (int val = 0; val < wave_height; val++) {
const int* const l_row = lwave[val];
std::uint32_t* const buffer_row =
reinterpret_cast<uint32_t*>(wave_buffer_luma.data() + (255 - val) * cairo_stride);
for (int col = 0; col < wave_width; col++) {
const unsigned char l = std::min<float>(scale * l_row[col], 0xff);
buffer_row[col] = l | (l << 8) | (l << 16) | (l << 24);
}
}
@ -1834,7 +1967,8 @@ bool HistogramArea::on_motion_notify_event (GdkEventMotion* event)
setDirty(true);
queue_draw ();
} else if (
scopeType == ScopeType::WAVEFORM
scopeType == ScopeType::PARADE
|| scopeType == ScopeType::WAVEFORM
|| scopeType == ScopeType::VECTORSCOPE_HC
|| scopeType == ScopeType::VECTORSCOPE_HS
) { // Adjust brightness.
@ -1844,7 +1978,7 @@ bool HistogramArea::on_motion_notify_event (GdkEventMotion* event)
double dx = (event->x - movingPosition) / get_width();
float new_brightness = LIM<float>(trace_brightness * pow(RANGE, dx), MIN_BRIGHT, MAX_BRIGHT);
if (new_brightness != trace_brightness) {
wave_buffer_dirty = vect_hc_buffer_dirty = vect_hs_buffer_dirty = true;
parade_buffer_dirty = wave_buffer_dirty = vect_hc_buffer_dirty = vect_hs_buffer_dirty = true;
trace_brightness = new_brightness;
setDirty(true);
queue_draw();

View File

@ -166,6 +166,10 @@ protected:
bool vect_hc_buffer_dirty, vect_hs_buffer_dirty;
int waveform_scale;
array2D<int> rwave, gwave, bwave, lwave;
std::vector<unsigned char> parade_buffer_r;
std::vector<unsigned char> parade_buffer_g;
std::vector<unsigned char> parade_buffer_b;
bool parade_buffer_dirty;
std::vector<unsigned char> wave_buffer;
std::vector<unsigned char> wave_buffer_luma;
bool wave_buffer_dirty;
@ -227,6 +231,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 drawParade(Cairo::RefPtr<Cairo::Context> &cr, int hsize, int vsize);
void drawVectorscope(Cairo::RefPtr<Cairo::Context> &cr, int hsize, int vsize);
void drawWaveform(Cairo::RefPtr<Cairo::Context> &cr, int hsize, int vsize);
Gtk::SizeRequestMode get_request_mode_vfunc () const override;
@ -268,6 +273,7 @@ protected:
Gtk::RadioButton* scopeHistBtn;
Gtk::RadioButton* scopeHistRawBtn;
Gtk::RadioButton* scopeParadeBtn;
Gtk::RadioButton* scopeWaveBtn;
Gtk::RadioButton* scopeVectHcBtn;
Gtk::RadioButton* scopeVectHsBtn;
@ -288,17 +294,20 @@ protected:
std::unique_ptr<Gtk::Image> histImage;
std::unique_ptr<Gtk::Image> histRawImage;
std::unique_ptr<Gtk::Image> paradeImage;
std::unique_ptr<Gtk::Image> waveImage;
std::unique_ptr<Gtk::Image> vectHcImage;
std::unique_ptr<Gtk::Image> vectHsImage;
std::unique_ptr<Gtk::Image> histImageOn;
std::unique_ptr<Gtk::Image> histRawImageOn;
std::unique_ptr<Gtk::Image> paradeImageOn;
std::unique_ptr<Gtk::Image> waveImageOn;
std::unique_ptr<Gtk::Image> vectHcImageOn;
std::unique_ptr<Gtk::Image> vectHsImageOn;
std::unique_ptr<Gtk::Image> histImageOff;
std::unique_ptr<Gtk::Image> histRawImageOff;
std::unique_ptr<Gtk::Image> paradeImageOff;
std::unique_ptr<Gtk::Image> waveImageOff;
std::unique_ptr<Gtk::Image> vectHcImageOff;
std::unique_ptr<Gtk::Image> vectHsImageOff;

View File

@ -179,6 +179,7 @@ public:
NONE = -1,
HISTOGRAM,
HISTOGRAM_RAW,
PARADE,
VECTORSCOPE_HC,
VECTORSCOPE_HS,
WAVEFORM