From 2c986d353333d2604f0c3f1fcef262cc763c0001 Mon Sep 17 00:00:00 2001 From: FlareFlo Date: Tue, 19 Nov 2024 04:41:58 +0100 Subject: [PATCH] Clamp NaN to white when converting to integer (#2381) --- src/color.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/color.rs b/src/color.rs index 1027611858..b3745d9b83 100644 --- a/src/color.rs +++ b/src/color.rs @@ -436,17 +436,24 @@ impl FromPrimitive for T { // Note that in to-integer-conversion we are performing rounding but NumCast::from is implemented // as truncate towards zero. We emulate rounding by adding a bias. +// All other special values are clamped inbetween 0.0 and 1.0 (infinities and subnormals) +// NaN however always maps to NaN therefore we have to force it towards some value. +// 1.0 (white) was picked as firefox and chrome choose to map NaN to that. +#[inline] +fn normalize_float(float: f32, max: f32) -> f32 { + let clamped = if !(float < 1.0) { 1.0 } else { float.max(0.0) }; + (clamped * max).round() +} + impl FromPrimitive for u8 { fn from_primitive(float: f32) -> Self { - let inner = (float.clamp(0.0, 1.0) * u8::MAX as f32).round(); - NumCast::from(inner).unwrap() + NumCast::from(normalize_float(float, u8::MAX as f32)).unwrap() } } impl FromPrimitive for u16 { fn from_primitive(float: f32) -> Self { - let inner = (float.clamp(0.0, 1.0) * u16::MAX as f32).round(); - NumCast::from(inner).unwrap() + NumCast::from(normalize_float(float, u16::MAX as f32)).unwrap() } }