1 /* 2 * Copyright 2024, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <HSL.h> 8 9 10 hsl_color 11 hsl_color::from_rgb(const rgb_color& rgb) 12 { 13 hsl_color result; 14 15 float r = rgb.red / 255.0f; 16 float g = rgb.green / 255.0f; 17 float b = rgb.blue / 255.0f; 18 19 float max = max_c(max_c(r, g), b); 20 float min = min_c(min_c(r, g), b); 21 22 result.hue = result.saturation = result.lightness = (max + min) / 2; 23 24 if (max == min) { 25 // grayscale 26 result.hue = result.saturation = 0; 27 } else { 28 float diff = max - min; 29 result.saturation 30 = (result.lightness > 0.5) ? (diff / (2 - max - min)) : (diff / (max + min)); 31 32 if (max == r) 33 result.hue = (g - b) / diff + (g < b ? 6 : 0); 34 else if (max == g) 35 result.hue = (b - r) / diff + 2; 36 else if (max == b) 37 result.hue = (r - g) / diff + 4; 38 39 result.hue /= 6; 40 } 41 42 return result; 43 } 44 45 46 rgb_color 47 hsl_color::to_rgb() const 48 { 49 rgb_color result; 50 result.alpha = 255; 51 52 if (saturation == 0) { 53 // grayscale 54 result.red = result.green = result.blue = uint8(lightness * 255); 55 } else { 56 float q = lightness < 0.5 ? (lightness * (1 + saturation)) 57 : (lightness + saturation - lightness * saturation); 58 float p = 2 * lightness - q; 59 result.red = uint8(hue_to_rgb(p, q, hue + 1./3) * 255); 60 result.green = uint8(hue_to_rgb(p, q, hue) * 255); 61 result.blue = uint8(hue_to_rgb(p, q, hue - 1./3) * 255); 62 } 63 64 return result; 65 } 66 67 68 // reference: https://en.wikipedia.org/wiki/HSL_and_HSV#Color_conversion_formulae 69 // (from_rgb() and to_rgb() are derived from the same) 70 float 71 hsl_color::hue_to_rgb(float p, float q, float t) 72 { 73 if (t < 0) 74 t += 1; 75 if (t > 1) 76 t -= 1; 77 if (t < 1./6) 78 return p + (q - p) * 6 * t; 79 if (t < 1./2) 80 return q; 81 if (t < 2./3) 82 return p + (q - p) * (2./3 - t) * 6; 83 84 return p; 85 } 86