Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Wrong RGB -> HSL convertion #505

Merged
merged 3 commits into from
Jun 24, 2022
Merged

Conversation

eugene-kulak
Copy link
Contributor

@eugene-kulak eugene-kulak commented Jul 3, 2020

Description

Fixes wrong formula used to convert RGB to HSL color space,
check correct algorithm here (https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/)

References

Tasklist

  • Add test case(s)
  • Ensure all CI builds pass
  • Review and approve

@mloskot
Copy link
Member

mloskot commented Jul 3, 2020

Thanks for the patch.

Could you tell how did you discover the issue, for what input, expected output, a MWE?
In other words, it would be helpful if this PR includes a corresponding test case.

@mloskot mloskot added cat/bug But reports and bug fixes ext/toolbox boost/gil/extension/toolbox/ labels Jul 3, 2020
@eugene-kulak
Copy link
Contributor Author

Hi @mloskot , unfortunately, I don't use boost tests, but here are my GTests:

#define rgb2hsl(r, g, b, h, s, l)                              \
  {                                                            \
    const float abs_error = 0.002;                             \
    using boost::gil::hsl32f_pixel_t;                          \
    using boost::gil::rgb8_pixel_t;                            \
    using boost::gil::hsl_color_space::hue_t;                  \
    using boost::gil::hsl_color_space::lightness_t;            \
    using boost::gil::hsl_color_space::saturation_t;           \
    rgb8_pixel_t rgb(r, g, b);                                 \
    hsl32f_pixel_t hsl;                                        \
                                                               \
    color_convert(rgb, hsl);                                   \
                                                               \
    ASSERT_NEAR(h, get_color(hsl, hue_t()), abs_error);        \
    ASSERT_NEAR(s, get_color(hsl, saturation_t()), abs_error); \
    ASSERT_NEAR(l, get_color(hsl, lightness_t()), abs_error);  \
  }

#define hsl2rgb(h, s, l, r, g, b)                         \
  {                                                       \
    const float abs_error = 1;                            \
    using boost::gil::blue_t;                             \
    using boost::gil::green_t;                            \
    using boost::gil::hsl32f_pixel_t;                     \
    using boost::gil::red_t;                              \
    using boost::gil::rgb8_pixel_t;                       \
    hsl32f_pixel_t hsl(h, s, l);                          \
    rgb8_pixel_t rgb;                                     \
                                                          \
    color_convert(hsl, rgb);                              \
                                                          \
    ASSERT_NEAR(r, get_color(rgb, red_t()), abs_error);   \
    ASSERT_NEAR(g, get_color(rgb, green_t()), abs_error); \
    ASSERT_NEAR(b, get_color(rgb, blue_t()), abs_error);  \
  }

TEST(ColorSpaceTest, RGBToHSL) {
  // black
  rgb2hsl(0, 0, 0, 0, 0, 0);

  // white
  rgb2hsl(255, 255, 255, 0, 0, 1);

  // red
  rgb2hsl(255, 0, 0, 0, 1, 0.5);

  // lime
  rgb2hsl(0, 255, 0, 2 / 6.f, 1, 0.5);

  // blue
  rgb2hsl(0, 0, 255, 4 / 6.f, 1, 0.5);

  // yellow
  rgb2hsl(255, 255, 0, 1 / 6.f, 1, 0.5);

  // cyan
  rgb2hsl(0, 255, 255, 3 / 6.f, 1, 0.5);

  // magenta
  rgb2hsl(255, 0, 255, 5 / 6.f, 1, 0.5);

  // silver
  rgb2hsl(191, 191, 191, 0, 0, 0.75);

  // gray
  rgb2hsl(128, 128, 128, 0, 0, 0.5);

  // maroon
  rgb2hsl(128, 0, 0, 0, 1, 0.25);

  // olive
  rgb2hsl(128, 128, 0, 1 / 6.f, 1, 0.25);

  // green
  rgb2hsl(0, 128, 0, 2 / 6.f, 1, 0.25);

  // purple
  rgb2hsl(128, 0, 128, 5 / 6.f, 1, 0.25);

  // teal
  rgb2hsl(0, 128, 128, 3 / 6.f, 1, 0.25);

  // navy
  rgb2hsl(0, 0, 128, 4 / 6.f, 1, 0.25);
}

TEST(ColorSpaceTest, HSLToRGB) {
  // black
  hsl2rgb(0, 0, 0, 0, 0, 0);

  // white
  hsl2rgb(0, 0, 1, 255, 255, 255);

  // red
  hsl2rgb(0, 1, 0.5, 255, 0, 0);

  // lime
  hsl2rgb(2 / 6.f, 1, 0.5, 0, 255, 0);

  // blue
  hsl2rgb(4 / 6.f, 1, 0.5, 0, 0, 255);

  // purple
  hsl2rgb(5 / 6.f, 1, 0.25, 128, 0, 128);

  // teal
  hsl2rgb(3 / 6.f, 1, 0.25, 0, 128, 128);

  // navy
  hsl2rgb(4 / 6.f, 1, 0.25, 0, 0, 128);
}

@mloskot mloskot self-assigned this Jan 26, 2021
Copy link
Member

@lpranam lpranam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Would be nice to add those tests now we don't use boost test so should be easy. Let us know if you can add or not. @eugene-kulak

@mloskot
Copy link
Member

mloskot commented Jun 24, 2022

@lpranam I think we will have to add the tests on our own
I'm merging this, so this can be followed with porting of the GTest tests - #690

@mloskot mloskot merged commit 5273678 into boostorg:develop Jun 24, 2022
@mloskot mloskot added this to the Boost 1.80 milestone Jun 24, 2022
@mloskot mloskot changed the title Fix wrong RGB -> HSL convertion fix: Wrong RGB -> HSL convertion Jun 24, 2022
mloskot added a commit to mloskot/gil that referenced this pull request Jun 25, 2022
Contributor of PR boostorg#505 posted GTest-based tests in.
This commit ports those tests to Boost.LightweightTest.

Closes boostorg#690
@mloskot mloskot mentioned this pull request Jun 25, 2022
3 tasks
mloskot added a commit that referenced this pull request Jun 25, 2022
Contributor of PR #505 posted GTest-based tests in.
This commit ports those tests to Boost.LightweightTest.

Closes #690
mloskot added a commit that referenced this pull request Jun 27, 2022
* develop:
  docs!: Announce plan to require C++17 after Boost 1.80 (#694)
  feat: Added apply_rasterizer() free function (#695)
  refactor: Ellipse rasterizer according to the comment at (#692)
  refactor: Deprecate apply_operation in favor of variant2::visit for any_image (#656)
  refactor: Replace deprecated libtiff v4.3 typedefs with C99 fixed-size integers (#685)
  fix: Automatic detection of <filesystem> header (#684)
  test: Add tiled TIFF test case to simple_all_formats
  test: Add tests for RGB to HSL (#691)
  refactor: Move RGB to HSL tests to color_convert_rgb.cpp
  refactor: Make with_tolerance reusable across other tests
  chore: Correct include guard
  fix: Add missing #include <array>
  fix: Wrong RGB -> HSL convertion (#505)
@mloskot mloskot mentioned this pull request Jul 5, 2022
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cat/bug But reports and bug fixes ext/toolbox boost/gil/extension/toolbox/
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants