Skip to content

Commit

Permalink
Viewer info line: compute HSV from linear RGB
Browse files Browse the repository at this point in the history
Fixes #286
  • Loading branch information
devernay committed Jun 8, 2018
1 parent 8df0bb2 commit 9d43b4b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
## Version 2.3.13

- Fix default value for file premult in ReadSVG (should be premultiplied).
- HSV values in the viewer info lines are now computed from linear RGB #286.


## Version 2.3.12
Expand Down
17 changes: 14 additions & 3 deletions Engine/Lut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1612,9 +1612,13 @@ LutManager::VLogLut()
return LutManager::m_instance.getLut("V-Log", from_func_VLog, to_func_VLog);
}

// r,g,b values are from 0 to 1
// r,g,b values are linear values from 0 to 1
// h = [0,OFXS_HUE_CIRCLE], s = [0,1], v = [0,1]
// if s == 0, then h = 0 (undefined)
// Reference:
// "Color gamut transform pairs", Alvy Ray Smith, Proceeding SIGGRAPH '78
// https://doi.org/10.1145/800248.807361
// http://www.icst.pku.edu.cn/F/course/ImageProcessing/2018/resource/Color78.pdf
void
rgb_to_hsv( float r,
float g,
Expand All @@ -1623,8 +1627,8 @@ rgb_to_hsv( float r,
float *s,
float *v )
{
float min = std::min(std::min(r, g), b);
float max = std::max(std::max(r, g), b);
float min = (std::min)((std::min)(r, g), b);
float max = (std::max)((std::max)(r, g), b);

*v = max; // v

Expand Down Expand Up @@ -1655,6 +1659,13 @@ rgb_to_hsv( float r,
}
}

// r,g,b values are linear values from 0 to 1
// h = [0,OFXS_HUE_CIRCLE], s = [0,1], v = [0,1]
// if s == 0, then h = 0 (undefined)
// Reference:
// "Color gamut transform pairs", Alvy Ray Smith, Proceeding SIGGRAPH '78
// https://doi.org/10.1145/800248.807361
// http://www.icst.pku.edu.cn/F/course/ImageProcessing/2018/resource/Color78.pdf
void
hsv_to_rgb(float h,
float s,
Expand Down
18 changes: 15 additions & 3 deletions Gui/InfoViewerWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,9 @@ InfoViewerWidget::setColor(float r,
rgbaValues->setText(values);
rgbaValues->update();
float h, s, v, l;
// Nuke's HSV display is based on sRGB, an L is Rec.709.
// see http://forums.thefoundry.co.uk/phpBB2/viewtopic.php?t=2283
// Nuke's HSV display is based on sRGB until Nuke 8, an L is Rec.709.
// see https://community.foundry.com/discuss/topic/100271
// This was changed in Nuke 9 to use linear values.
double srgb_r = Color::to_func_srgb(r);
double srgb_g = Color::to_func_srgb(g);
double srgb_b = Color::to_func_srgb(b);
Expand All @@ -339,7 +340,18 @@ InfoViewerWidget::setColor(float r,
color->update();

const QFont &hsvFont = hvl_lastOption->font();
Color::rgb_to_hsv(srgb_r, srgb_g, srgb_b, &h, &s, &v);
// Nuke 5-8 version used sRGB colors to compute HSV
//Color::rgb_to_hsv(srgb_r, srgb_g, srgb_b, &h, &s, &v);

// However, as Alvin Ray Smith said in his paper,
// "We shall assume that an RGB monitor is a linear device"
// We thus use linear values (same as Nuke 9 and later).
// Fixes https://github.com/NatronGitHub/Natron/issues/286
// Reference:
// "Color gamut transform pairs", Alvy Ray Smith, Proceeding SIGGRAPH '78
// https://doi.org/10.1145/800248.807361
// http://www.icst.pku.edu.cn/F/course/ImageProcessing/2018/resource/Color78.pdf
Color::rgb_to_hsv(r, g, b, &h, &s, &v);
l = 0.2125 * r + 0.7154 * g + 0.0721 * b; // L according to Rec.709

QString lS = _colorValid ? QString::number(l, 'f', 5) : QString::fromUtf8("?");
Expand Down
2 changes: 1 addition & 1 deletion libs/OpenFX

0 comments on commit 9d43b4b

Please sign in to comment.