From 71f3520ea315fb65ff151c99aa0b64fc8dccdb1d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 25 May 2021 00:32:39 +0200 Subject: [PATCH] Clamp results correctly when shifting video levels, and account for that in tests. --- src/lib/image.cc | 4 ++-- src/lib/util.h | 8 ++++++++ test/video_level_test.cc | 12 +++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/lib/image.cc b/src/lib/image.cc index 4859ebe14..eff53a2aa 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -1433,7 +1433,7 @@ Image::video_range_to_full_range () 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 = clamp(lrintf((*q - 16) * factor), 0L, 255L); ++q; } p += stride()[0]; @@ -1450,7 +1450,7 @@ Image::video_range_to_full_range () 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 = clamp(lrintf((*q - 256) * factor), 0L, 4095L); ++q; } } diff --git a/src/lib/util.h b/src/lib/util.h index fa0d9fdf2..013eabe12 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -150,4 +150,12 @@ list_to_vector (std::list v) extern double db_to_linear (double db); extern double linear_to_db (double linear); + +template +T clamp (T val, T minimum, T maximum) +{ + return std::max(std::min(val, maximum), minimum); +} + + #endif diff --git a/test/video_level_test.cc b/test/video_level_test.cc index c7e255394..c974c938d 100644 --- a/test/video_level_test.cc +++ b/test/video_level_test.cc @@ -344,8 +344,11 @@ image_FoV (string name) content->video->set_range (VideoRange::VIDEO); auto range = pixel_range (film, content); - BOOST_CHECK_EQUAL (range.first, 11); - BOOST_CHECK_EQUAL (range.second, 250); + /* We are taking some full-range content and saying it should be read as video range, after which its + * pixels will still be full range. + */ + BOOST_CHECK_EQUAL (range.first, 0); + BOOST_CHECK_EQUAL (range.second, 255); return film; } @@ -451,7 +454,10 @@ BOOST_AUTO_TEST_CASE (image_F_to_dcp) BOOST_AUTO_TEST_CASE (image_FoV_to_dcp) { auto range = dcp_range (image_FoV("image_FoV_to_dcp")); - check_int_close (range, {430, 4012}, 2); + /* The nearly-full-range of the input has become even more full, and clipped. + * XXX: I'm not sure why this doesn't quite hit 4095. + */ + check_int_close (range, {0, 4095}, 16); } -- 2.30.2