Skip to content

Commit

Permalink
add luminance() operation
Browse files Browse the repository at this point in the history
  • Loading branch information
igagis committed Nov 6, 2024
1 parent e351dd0 commit cf6be68
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/rasterimage/operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,30 @@ constexpr r4::vector4<value_type> unpremultiply_alpha(const r4::vector4<value_ty
};
}

/**
* @brief Calculate luminance of a pixel.
* @param px - pixel value to calculate luminance from.
*/
template <typename value_type, size_t num_channels>
constexpr value_type luminance(const r4::vector<value_type, num_channels>& px)
{
if constexpr (num_channels == 1 || num_channels == 2) {
return px.r();
} else {
static_assert(num_channels >= 3, "logic error");

// Luminance is calculated using formula L = 0.2126 * R + 0.7152 * G + 0.0722 * B

constexpr auto red_coeff = 0.2126;
constexpr auto green_coeff = 0.7152;
constexpr auto blue_coeff = 0.0722;

return rasterimage::multiply(px.r(), value<value_type>(float(red_coeff))) +
rasterimage::multiply(px.g(), value<value_type>(float(green_coeff))) +
rasterimage::multiply(px.b(), value<value_type>(float(blue_coeff)));
}
}

/**
* @brief Convert pixel of integral color value type to floating point one.
* @param px - pixel to convert.
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/src/operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,29 @@ const tst::set set("operations", [](tst::suite& suite) {
tst::check_eq(rasterimage::get_alpha(rgb), 1.0f, SL);
tst::check_eq(rasterimage::get_alpha(rgba), 0.4f, SL);
});

suite.add("luminance__float", []() {
r4::vector<float, 1> a = {0.1f};
r4::vector2<float> ga = {0.1f, 0.2f};
r4::vector3<float> rgb = {0.1f, 0.2f, 0.3f};
r4::vector4<float> rgba = {0.1f, 0.2f, 0.3f, 0.4f};

tst::check_eq(rasterimage::luminance(a), 0.1f, SL);
tst::check_eq(rasterimage::luminance(ga), 0.1f, SL);
tst::check_eq(rasterimage::luminance(rgb), 0.18596f, SL);
tst::check_eq(rasterimage::luminance(rgba), 0.18596f, SL);
});

suite.add("luminance__uint8_t", []() {
r4::vector<uint8_t, 1> a = {0x13};
r4::vector2<uint8_t> ga = {0x13, 0x14};
r4::vector3<uint8_t> rgb = {0x13, 0x44, 0xfe};
r4::vector4<uint8_t> rgba = {0x13, 0x44, 0xfe, 0xab};

tst::check_eq(rasterimage::luminance(a), uint8_t(0x13), SL);
tst::check_eq(rasterimage::luminance(ga), uint8_t(0x13), SL);
tst::check_eq(rasterimage::luminance(rgb), uint8_t(69), SL);
tst::check_eq(rasterimage::luminance(rgba), uint8_t(69), SL);
});
});
} // namespace

0 comments on commit cf6be68

Please sign in to comment.