summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-05-25 00:32:39 +0200
committerCarl Hetherington <cth@carlh.net>2021-05-25 21:35:12 +0200
commit71f3520ea315fb65ff151c99aa0b64fc8dccdb1d (patch)
treea09a8200a7ca14cada2e4b72ff40a1adb0b44f32
parentb26f4e4cfa0a3b6df794f3207b420a413c52e773 (diff)
Clamp results correctly when shifting video levels, and account for that in tests.
-rw-r--r--src/lib/image.cc4
-rw-r--r--src/lib/util.h8
-rw-r--r--test/video_level_test.cc12
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<T> v)
extern double db_to_linear (double db);
extern double linear_to_db (double linear);
+
+template <class T>
+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);
}