Fix overflow issue in approx_exp2().
skcms' vector implementation of approx_exp2() used a clever bit-
twiddling trick to generate its results. Unfortunately, the bit trick
fails for large inputs and generates a nonsense result. This is now
fixed with a well-positioned call to min_.
This fix parallels a similar fix in skvm, http://review.skia.org/497283
Change-Id: I9412094e9b4c27a9619781c27726b9e6a00c805e
Reviewed-on: https://skia-review.googlesource.com/c/skcms/+/497452
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/src/Transform_inl.h b/src/Transform_inl.h
index 0dd6404..348a765 100644
--- a/src/Transform_inl.h
+++ b/src/Transform_inl.h
@@ -22,10 +22,12 @@
#if defined(__GNUC__) && !defined(__clang__)
// Once again, GCC is kind of weird, not allowing vector = scalar directly.
static constexpr F F0 = F() + 0.0f,
- F1 = F() + 1.0f;
+ F1 = F() + 1.0f,
+ FInfBits = F() + 0x7f800000; // equals 2139095040, the bit pattern of +Inf
#else
static constexpr F F0 = 0.0f,
- F1 = 1.0f;
+ F1 = 1.0f,
+ FInfBits = 0x7f800000; // equals 2139095040, the bit pattern of +Inf
#endif
// Instead of checking __AVX__ below, we'll check USING_AVX.
@@ -294,7 +296,7 @@
F fbits = (1.0f * (1<<23)) * (x + 121.274057500f
- 1.490129070f*fract
+ 27.728023300f/(4.84252568f - fract));
- I32 bits = cast<I32>(max_(fbits, F0));
+ I32 bits = cast<I32>(min_(max_(fbits, F0), FInfBits));
return bit_pun<F>(bits);
#endif