diff options
| author | Carl Hetherington <cth@carlh.net> | 2020-11-08 22:34:18 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2020-11-16 01:40:36 +0100 |
| commit | e64a1a9aae0200d14feed49a4c6cf537bf5708a4 (patch) | |
| tree | b1b01bb8e6f1872309eb246434120de3b769e9e5 /src/lib/image.cc | |
| parent | f5608308b17c72b3ee459c805663e0103de1d2a4 (diff) | |
Obey requests to change the video range of RGB content.
Video that comes in with RGB pixels will not have its video level
ranges changed by libswscale (it only does this for YUV and greyscale).
Here we add code to do it ourselves for RGB content coming in
via image files (e.g. PNG/DPX etc). Part of #1851.
Diffstat (limited to 'src/lib/image.cc')
| -rw-r--r-- | src/lib/image.cc | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/lib/image.cc b/src/lib/image.cc index 03f1bf6dc..891715a46 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -1319,3 +1319,46 @@ Image::as_png () const return dcp::ArrayData (state.data, state.size); } + + +void +Image::video_range_to_full_range () +{ + switch (_pixel_format) { + case AV_PIX_FMT_RGB24: + { + float const factor = 256.0 / 219.0; + uint8_t* p = data()[0]; + int const lines = sample_size(0).height; + for (int y = 0; y < lines; ++y) { + uint8_t* q = p; + for (int x = 0; x < line_size()[0]; ++x) { + *q = int((*q - 16) * factor); + ++q; + } + p += stride()[0]; + } + break; + } + case AV_PIX_FMT_GBRP12LE: + { + float const factor = 4096.0 / 3504.0; + for (int c = 0; c < 3; ++c) { + uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]); + int const lines = sample_size(c).height; + for (int y = 0; y < lines; ++y) { + uint16_t* q = p; + int const line_size_pixels = line_size()[c] / 2; + for (int x = 0; x < line_size_pixels; ++x) { + *q = int((*q - 256) * factor); + ++q; + } + } + } + break; + } + default: + throw PixelFormatError ("video_range_to_full_range()", _pixel_format); + } +} + |
