Skip to content

Commit

Permalink
Add functions to check if scalars, colors and spectra are finite
Browse files Browse the repository at this point in the history
  • Loading branch information
dictoon committed Jan 17, 2017
1 parent 9ad3764 commit d907c26
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 68 deletions.
16 changes: 16 additions & 0 deletions src/appleseed/foundation/image/color.h
Expand Up @@ -31,6 +31,7 @@
#define APPLESEED_FOUNDATION_IMAGE_COLOR_H

// appleseed.foundation headers.
#include "foundation/math/fp.h"
#include "foundation/math/scalar.h"
#include "foundation/platform/types.h"
#include "foundation/utility/poison.h"
Expand Down Expand Up @@ -164,6 +165,9 @@ template <typename T, size_t N> T average_value(const Color<T, N>& c);
// Return true if a color contains at least one NaN value.
template <typename T, size_t N> bool has_nan(const Color<T, N>& c);

// Return true if all components of a color are finite (not NaN, not infinite).
template <typename T, size_t N> bool is_finite(const Color<T, N>& c);


//
// RGB color class of arbitrary type.
Expand Down Expand Up @@ -813,6 +817,18 @@ inline bool has_nan(const Color<T, N>& c)
return false;
}

template <typename T, size_t N>
inline bool is_finite(const Color<T, N>& c)
{
for (size_t i = 0; i < N; ++i)
{
if (!FP<T>::is_finite(c[i]))
return false;
}

return true;
}


//
// RGB color implementation.
Expand Down
16 changes: 16 additions & 0 deletions src/appleseed/foundation/image/regularspectrum.h
Expand Up @@ -31,6 +31,7 @@
#define APPLESEED_FOUNDATION_IMAGE_REGULARSPECTRUM_H

// appleseed.foundation headers.
#include "foundation/math/fp.h"
#include "foundation/math/scalar.h"
#include "foundation/platform/compiler.h"
#ifdef APPLESEED_USE_SSE
Expand Down Expand Up @@ -159,6 +160,9 @@ template <typename T, size_t N> T average_value(const RegularSpectrum<T, N>& s);
// Return true if a spectrum contains at least one NaN value.
template <typename T, size_t N> bool has_nan(const RegularSpectrum<T, N>& s);

// Return true if all components of a spectrum are finite (not NaN, not infinite).
template <typename T, size_t N> bool is_finite(const RegularSpectrum<T, N>& s);


//
// Full specializations for spectra of type float and double.
Expand Down Expand Up @@ -867,6 +871,18 @@ inline bool has_nan(const RegularSpectrum<T, N>& s)
return false;
}

template <typename T, size_t N>
inline bool is_finite(const RegularSpectrum<T, N>& s)
{
for (size_t i = 0; i < N; ++i)
{
if (!FP<T>::is_finite(s[i]))
return false;
}

return true;
}

} // namespace foundation

#endif // !APPLESEED_FOUNDATION_IMAGE_REGULARSPECTRUM_H
152 changes: 84 additions & 68 deletions src/appleseed/foundation/math/fp.h
Expand Up @@ -127,6 +127,9 @@ struct FP<float>
// Return true if x equals quiet NaN.
static bool is_qnan(float x);

// Return true if x is neither NaN nor infinite.
static bool is_finite(float x);

// Construct a 32-bit floating-point value given a sign, an exponent and a mantissa.
static float construct(
const uint32 sign,
Expand Down Expand Up @@ -204,6 +207,9 @@ struct FP<double>
// Return true if x equals quiet NaN.
static bool is_qnan(double x);

// Return true if x is neither NaN nor infinite.
static bool is_finite(double x);

// Construct a 64-bit floating-point value given a sign, an exponent and a mantissa.
static double construct(
const uint64 sign,
Expand All @@ -229,6 +235,51 @@ T shift(const T x, const typename TypeConv<T>::Int n);
// FP<float> class implementation.
//

inline float FP<float>::pos_zero()
{
return binary_cast<float>(PosZero);
}

inline float FP<float>::neg_zero()
{
return binary_cast<float>(NegZero);
}

inline float FP<float>::pos_min()
{
return binary_cast<float>(PosMin);
}

inline float FP<float>::neg_min()
{
return binary_cast<float>(NegMin);
}

inline float FP<float>::pos_inf()
{
return binary_cast<float>(PosInf);
}

inline float FP<float>::neg_inf()
{
return binary_cast<float>(NegInf);
}

inline float FP<float>::snan()
{
return binary_cast<float>(SNaN);
}

inline float FP<float>::qnan()
{
return binary_cast<float>(QNaN);
}

inline float FP<float>::indefinite()
{
return binary_cast<float>(QNaN);
}

inline uint32 FP<float>::sign(float x)
{
return (binary_cast<uint32>(x) & 0x80000000L) >> 31;
Expand Down Expand Up @@ -299,6 +350,11 @@ inline bool FP<float>::is_qnan(float x)
return sign(x) == 1 && is_nan(x);
}

inline bool FP<float>::is_finite(float x)
{
return !is_inf(x) && !is_nan(x);
}

inline float FP<float>::construct(
const uint32 sign,
const uint32 exponent,
Expand All @@ -316,56 +372,56 @@ inline float FP<float>::construct(
return binary_cast<float>(value);
}

inline float FP<float>::pos_zero()

//
// FP<double> class implementation.
//

inline double FP<double>::pos_zero()
{
return binary_cast<float>(PosZero);
return binary_cast<double>(PosZero);
}

inline float FP<float>::neg_zero()
inline double FP<double>::neg_zero()
{
return binary_cast<float>(NegZero);
return binary_cast<double>(NegZero);
}

inline float FP<float>::pos_min()
inline double FP<double>::pos_min()
{
return binary_cast<float>(PosMin);
return binary_cast<double>(PosMin);
}

inline float FP<float>::neg_min()
inline double FP<double>::neg_min()
{
return binary_cast<float>(NegMin);
return binary_cast<double>(NegMin);
}

inline float FP<float>::pos_inf()
inline double FP<double>::pos_inf()
{
return binary_cast<float>(PosInf);
return binary_cast<double>(PosInf);
}

inline float FP<float>::neg_inf()
inline double FP<double>::neg_inf()
{
return binary_cast<float>(NegInf);
return binary_cast<double>(NegInf);
}

inline float FP<float>::snan()
inline double FP<double>::snan()
{
return binary_cast<float>(SNaN);
return binary_cast<double>(SNaN);
}

inline float FP<float>::qnan()
inline double FP<double>::qnan()
{
return binary_cast<float>(QNaN);
return binary_cast<double>(QNaN);
}

inline float FP<float>::indefinite()
inline double FP<double>::indefinite()
{
return binary_cast<float>(QNaN);
return binary_cast<double>(QNaN);
}


//
// FP<double> class implementation.
//

inline uint64 FP<double>::sign(double x)
{
return (binary_cast<uint64>(x) & 0x8000000000000000LL) >> 63;
Expand Down Expand Up @@ -436,6 +492,11 @@ inline bool FP<double>::is_qnan(double x)
return sign(x) == 1 && is_nan(x);
}

inline bool FP<double>::is_finite(double x)
{
return !is_inf(x) && !is_nan(x);
}

inline double FP<double>::construct(
const uint64 sign,
const uint64 exponent,
Expand All @@ -453,51 +514,6 @@ inline double FP<double>::construct(
return binary_cast<double>(value);
}

inline double FP<double>::pos_zero()
{
return binary_cast<double>(PosZero);
}

inline double FP<double>::neg_zero()
{
return binary_cast<double>(NegZero);
}

inline double FP<double>::pos_min()
{
return binary_cast<double>(PosMin);
}

inline double FP<double>::neg_min()
{
return binary_cast<double>(NegMin);
}

inline double FP<double>::pos_inf()
{
return binary_cast<double>(PosInf);
}

inline double FP<double>::neg_inf()
{
return binary_cast<double>(NegInf);
}

inline double FP<double>::snan()
{
return binary_cast<double>(SNaN);
}

inline double FP<double>::qnan()
{
return binary_cast<double>(QNaN);
}

inline double FP<double>::indefinite()
{
return binary_cast<double>(QNaN);
}


//
// shift() function implementation.
Expand Down
16 changes: 16 additions & 0 deletions src/appleseed/renderer/utility/dynamicspectrum.h
Expand Up @@ -33,6 +33,7 @@
#include "foundation/image/color.h"
#include "foundation/image/colorspace.h"
#include "foundation/image/regularspectrum.h"
#include "foundation/math/fp.h"
#include "foundation/math/scalar.h"
#include "foundation/platform/compiler.h"
#include "foundation/platform/types.h"
Expand Down Expand Up @@ -225,6 +226,9 @@ template <typename T, size_t N> T average_value(const renderer::DynamicSpectrum<
// Return true if a spectrum contains at least one NaN value.
template <typename T, size_t N> bool has_nan(const renderer::DynamicSpectrum<T, N>& s);

// Return true if all components of a spectrum are finite (not NaN, not infinite).
template <typename T, size_t N> bool is_finite(const renderer::DynamicSpectrum<T, N>& s);

// Return the square root of a spectrum.
template <typename T, size_t N> renderer::DynamicSpectrum<T, N> sqrt(const renderer::DynamicSpectrum<T, N>& s);

Expand Down Expand Up @@ -1441,6 +1445,18 @@ inline bool has_nan(const renderer::DynamicSpectrum<T, N>& s)
return false;
}

template <typename T, size_t N>
inline bool is_finite(const renderer::DynamicSpectrum<T, N>& s)
{
for (size_t i = 0, e = s.size(); i < e; ++i)
{
if (!FP<T>::is_finite(s[i]))
return false;
}

return true;
}

template <typename T, size_t N>
inline renderer::DynamicSpectrum<T, N> sqrt(const renderer::DynamicSpectrum<T, N>& s)
{
Expand Down

0 comments on commit d907c26

Please sign in to comment.