From 6a00eb8db06b75be1f70c05eae4eb51ea64c29cc Mon Sep 17 00:00:00 2001 From: Mira Grudzinska Date: Tue, 28 Jan 2025 12:14:26 +0100 Subject: [PATCH] sw_engine: fix color burn/dodge edge cases Dodge d / (1 - s): - handle d = 0 first to avoid 0/0 when s = 1 - for d != 0 and s = 1, the formula results in d/0 (infinity), which maps to 1 in the 0-1 range (or 255 in the 0-255 range) Burn 1 - (1 - d) / s: - handle d = 1 first to avoid 0/0 when s = 0 - for d != 1 and s = 0, the formula results in 1 - 0/0 -> 1 - inf = -inf Negative infinity in the 0-1 range corresponds to the minimum possible value, which is 0 (255 if we operate in 0-255 range). --- src/renderer/sw_engine/tvgSwCommon.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index a45a996a..53c28049 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -448,9 +448,9 @@ static inline uint32_t opBlendColorDodge(uint32_t s, uint32_t d, TVG_UNUSED uint { // d / (1 - s) s = 0xffffffff - s; - auto c1 = (C1(s) == 0) ? C1(d) : std::min(C1(d) * 255 / C1(s), 255); - auto c2 = (C2(s) == 0) ? C2(d) : std::min(C2(d) * 255 / C2(s), 255); - auto c3 = (C3(s) == 0) ? C3(d) : std::min(C3(d) * 255 / C3(s), 255); + auto c1 = C1(d) == 0 ? 0 : (C1(s) == 0 ? 255 : std::min(C1(d) * 255 / C1(s), 255)); + auto c2 = C2(d) == 0 ? 0 : (C2(s) == 0 ? 255 : std::min(C2(d) * 255 / C2(s), 255)); + auto c3 = C3(d) == 0 ? 0 : (C3(s) == 0 ? 255 : std::min(C3(d) * 255 / C3(s), 255)); return JOIN(255, c1, c2, c3); } @@ -458,9 +458,9 @@ static inline uint32_t opBlendColorBurn(uint32_t s, uint32_t d, TVG_UNUSED uint8 { // 1 - (1 - d) / s auto id = 0xffffffff - d; - auto c1 = (C1(s) == 0) ? C1(d) : 255 - std::min(C1(id) * 255 / C1(s), 255); - auto c2 = (C2(s) == 0) ? C2(d) : 255 - std::min(C2(id) * 255 / C2(s), 255); - auto c3 = (C3(s) == 0) ? C3(d) : 255 - std::min(C3(id) * 255 / C3(s), 255); + auto c1 = C1(d) == 255 ? 255 : (C1(s) == 0 ? 0 : 255 - std::min(C1(id) * 255 / C1(s), 255)); + auto c2 = C2(d) == 255 ? 255 : (C2(s) == 0 ? 0 : 255 - std::min(C2(id) * 255 / C2(s), 255)); + auto c3 = C3(d) == 255 ? 255 : (C3(s) == 0 ? 0 : 255 - std::min(C3(id) * 255 / C3(s), 255)); return JOIN(255, c1, c2, c3); }