Skip to content

Commit

Permalink
ColorW type for extended sRGB
Browse files Browse the repository at this point in the history
  • Loading branch information
dancazarin committed Feb 13, 2025
1 parent 77cf680 commit e929a08
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
21 changes: 17 additions & 4 deletions include/brisk/graphics/Color.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ using ColorF = ColorOf<float, ColorGamma::Default>;
/** @brief A standard 8-bit sRGB color type. */
using Color = ColorOf<uint8_t, ColorGamma::sRGB>;

/** @brief An extended-range 16-bit sRGB color type with 13-bit precision. */
using ColorW = ColorOf<int16_t, ColorGamma::sRGB>;

namespace Internal {

template <typename T>
constexpr int colorScale() {
if constexpr (std::is_floating_point_v<T>)
return 1;
else if constexpr (std::is_unsigned_v<T>)
return std::numeric_limits<T>::max();
else if constexpr (std::is_same_v<T, int16_t>)
return 8192; // 16-bit Extended range sRGB
}
} // namespace Internal

/**
* @brief Converts a 32-bit RGBA color to a `Color` instance.
*
Expand All @@ -103,11 +119,8 @@ struct ColorOf {

/**
* @brief Maximum value for color components, based on the type `T`.
*
* If `T` is a floating-point type, the maximum is 1.0. If `T` is an integer type, the maximum is
* determined by the limits of that type (e.g., 255 for `uint8_t`).
*/
constexpr static inline int maximum = std::is_floating_point_v<T> ? 1 : std::numeric_limits<T>::max();
constexpr static inline int maximum = Internal::colorScale<T>();

/**
* @brief Returns the color space of the current color based on the gamma setting.
Expand Down
30 changes: 30 additions & 0 deletions src/graphics/Color_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,36 @@
#include <brisk/core/Reflection.hpp>

namespace Brisk {

TEST_CASE("colorGamma") {
CHECK_THAT(Internal::srgbGammaToLinear(0.f), Catch::Matchers::WithinAbs(0.f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(0.5f), Catch::Matchers::WithinAbs(0.21404f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(1.f), Catch::Matchers::WithinAbs(1.f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(2.f), Catch::Matchers::WithinAbs(4.9538f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(-0.5f), Catch::Matchers::WithinAbs(-0.21404f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(-1.f), Catch::Matchers::WithinAbs(-1.f, 0.001f));
CHECK_THAT(Internal::srgbGammaToLinear(-2.f), Catch::Matchers::WithinAbs(-4.9538f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(0.f), Catch::Matchers::WithinAbs(0.f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(0.5f), Catch::Matchers::WithinAbs(0.73536f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(1.f), Catch::Matchers::WithinAbs(1.f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(2.f), Catch::Matchers::WithinAbs(1.3532f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(-0.5f), Catch::Matchers::WithinAbs(-0.73536f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(-1.f), Catch::Matchers::WithinAbs(-1.f, 0.001f));
CHECK_THAT(Internal::srgbLinearToGamma(-2.f), Catch::Matchers::WithinAbs(-1.3532f, 0.001f));
}

TEST_CASE("ColorW") {
bool linearColor = true;
std::swap(linearColor, Brisk::linearColor);
SCOPE_EXIT {
std::swap(linearColor, Brisk::linearColor);
};

CHECK(ColorW(Color(255, 128, 0)).v == ColorW(8192, 4112, 0, 8192).v);
CHECK_THAT(ColorF(ColorW(32767, -32767, 32767, 8192)).v,
Catch::Matchers::SIMDWithinMatcher(ColorF(25.312836, -25.312836, 25.312836, 1.f).v, 0.001));
}

TEST_CASE("rgbToColor") {
CHECK(rgbToColor(0xAABBCC) == Color{ 0xAA, 0xBB, 0xCC, 0xFF });

Expand Down

0 comments on commit e929a08

Please sign in to comment.