summaryrefslogtreecommitdiff
path: root/kms++util
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-04-17 15:38:30 +0300
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-04-17 15:38:33 +0300
commit8e0670031ba0cf1563f811963390f529e039447e (patch)
treea50b4ebd345c070ed0cfbe4634961ddc5151148f /kms++util
parent972d642b6dca9eb9108270429d5d54525a26ba5c (diff)
color16: Fix RGB-to-YUV
The calculation was not right, producing bad values. Fix it, and this time actually test the output... Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Diffstat (limited to 'kms++util')
-rw-r--r--kms++util/inc/kms++util/color16.h20
1 files changed, 11 insertions, 9 deletions
diff --git a/kms++util/inc/kms++util/color16.h b/kms++util/inc/kms++util/color16.h
index 6d25c82..ac48785 100644
--- a/kms++util/inc/kms++util/color16.h
+++ b/kms++util/inc/kms++util/color16.h
@@ -1,5 +1,6 @@
#pragma once
+#include <cmath>
#include <cstdint>
#include <algorithm>
@@ -133,23 +134,24 @@ constexpr YUV16 RGB16::to_yuv(RecStandard rec, ColorRange range) const noexcept
const double g_norm = static_cast<double>(g) / max_value;
const double b_norm = static_cast<double>(b) / max_value;
- // Calculate Y
- double y = coeff.kr * r_norm + coeff.kg * g_norm + coeff.kb * b_norm;
+ // Calculate Y (unscaled)
+ double y_unscaled = coeff.kr * r_norm + coeff.kg * g_norm + coeff.kb * b_norm;
- // Scale Y to target range
- y = y * (scaling.y_max - scaling.y_min) + scaling.y_min;
+ // Calculate U and V using unscaled Y
+ double u = (b_norm - y_unscaled) / (2.0 * (1.0 - coeff.kb));
+ double v = (r_norm - y_unscaled) / (2.0 * (1.0 - coeff.kr));
- // Calculate U and V
- double u = (b_norm - y) / (2.0 * (1.0 - coeff.kb));
- double v = (r_norm - y) / (2.0 * (1.0 - coeff.kr));
+ // Scale Y to target range
+ double y = y_unscaled * (scaling.y_max - scaling.y_min) + scaling.y_min;
// Scale U and V to target range
u = u * (scaling.c_max - scaling.c_min) + (scaling.c_max + scaling.c_min) / 2.0;
v = v * (scaling.c_max - scaling.c_min) + (scaling.c_max + scaling.c_min) / 2.0;
// Convert back to 16-bit values
- return YUV16(static_cast<uint16_t>(y * max_value), static_cast<uint16_t>(u * max_value),
- static_cast<uint16_t>(v * max_value));
+ return YUV16(static_cast<uint16_t>(std::round(y * max_value)),
+ static_cast<uint16_t>(std::round(u * max_value)),
+ static_cast<uint16_t>(std::round(v * max_value)));
}
constexpr RGB16 YUV16::to_rgb(RecStandard rec, ColorRange range) const noexcept