Skip to content

Commit 3c3e867

Browse files
committed
[Math] Fix Nan from powf() domain error.
This change prevents calling powf(x,y) with negative x. The SIMD versions using ssePower() already seem to be resistent to negative pixel values, but the scalar version was not. This would cause a SIGFPE on apps that have floating point exceptions enabled. FIXES: #2066 Signed-off-by: Bram Stolk <b.stolk@gmail.com>
1 parent 4dd0273 commit 3c3e867

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

src/OpenColorIO/ops/gamma/GammaOpCPU.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
#include "SSE.h"
1414

1515

16+
// powf() throws a domain error if the base is negative and the exponent non-integer.
17+
// This is a safer call to powf() that avoids a negative base.
18+
#define POW_NON_NEG(B, E) \
19+
std::pow((B) < 0.0f ? 0.0f : (B), (E))
20+
1621
namespace OCIO_NAMESPACE
1722
{
1823

@@ -540,10 +545,10 @@ void GammaMoncurveOpCPUFwd::apply(const void * inImg, void * outImg, long numPix
540545
{
541546
const float pixel[4] = { in[0], in[1], in[2], in[3] };
542547

543-
const float data[4] = { std::pow(pixel[0] * red[0] + red[1], red[2]),
544-
std::pow(pixel[1] * grn[0] + grn[1], grn[2]),
545-
std::pow(pixel[2] * blu[0] + blu[1], blu[2]),
546-
std::pow(pixel[3] * alp[0] + alp[1], alp[2]) };
548+
const float data[4] = { POW_NON_NEG(pixel[0] * red[0] + red[1], red[2]),
549+
POW_NON_NEG(pixel[1] * grn[0] + grn[1], grn[2]),
550+
POW_NON_NEG(pixel[2] * blu[0] + blu[1], blu[2]),
551+
POW_NON_NEG(pixel[3] * alp[0] + alp[1], alp[2]) };
547552

548553
out[0] = pixel[0]<=red[3] ? pixel[0] * red[4] : data[0];
549554
out[1] = pixel[1]<=grn[3] ? pixel[1] * grn[4] : data[1];
@@ -629,10 +634,10 @@ void GammaMoncurveOpCPURev::apply(const void * inImg, void * outImg, long numPix
629634
{
630635
const float pixel[4] = { in[0], in[1], in[2], in[3] };
631636

632-
const float data[4] = { std::pow(pixel[0], red[0]) * red[1] - red[2],
633-
std::pow(pixel[1], grn[0]) * grn[1] - grn[2],
634-
std::pow(pixel[2], blu[0]) * blu[1] - blu[2],
635-
std::pow(pixel[3], alp[0]) * alp[1] - alp[2] };
637+
const float data[4] = { POW_NON_NEG(pixel[0], red[0]) * red[1] - red[2],
638+
POW_NON_NEG(pixel[1], grn[0]) * grn[1] - grn[2],
639+
POW_NON_NEG(pixel[2], blu[0]) * blu[1] - blu[2],
640+
POW_NON_NEG(pixel[3], alp[0]) * alp[1] - alp[2] };
636641

637642
out[0] = pixel[0]<=red[3] ? pixel[0] * red[4] : data[0];
638643
out[1] = pixel[1]<=grn[3] ? pixel[1] * grn[4] : data[1];

0 commit comments

Comments
 (0)