/* LIBGIMP - The GIMP Library * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include "config.h" #include #include #include "libgimpmath/gimpmath.h" #include "gimpcolortypes.h" #include "gimpcolorspace.h" #include "gimprgb.h" /** * SECTION: gimpcolorspace * @title: GimpColorSpace * @short_description: Utility functions which convert colors between * different color models. * * When programming pixel data manipulation functions you will often * use algorithms operating on a color model different from the one * GIMP uses. This file provides utility functions to convert colors * between different color spaces. **/ #define GIMP_HSL_UNDEFINED -1.0 /* GimpRGB functions */ /** * gimp_rgb_to_hsl: * @rgb: A color value in the RGB colorspace * @hsl: (out caller-allocates): The value converted to HSL * * Convert an RGB color value to a HSL (Hue, Saturation, Lightness) * color value. **/ void gimp_rgb_to_hsl (const GimpRGB *rgb, GimpHSL *hsl) { gdouble max, min, delta; g_return_if_fail (rgb != NULL); g_return_if_fail (hsl != NULL); max = gimp_rgb_max (rgb); min = gimp_rgb_min (rgb); hsl->l = (max + min) / 2.0; if (max == min) { hsl->s = 0.0; hsl->h = GIMP_HSL_UNDEFINED; } else { if (hsl->l <= 0.5) hsl->s = (max - min) / (max + min); else hsl->s = (max - min) / (2.0 - max - min); delta = max - min; if (delta == 0.0) delta = 1.0; if (rgb->r == max) { hsl->h = (rgb->g - rgb->b) / delta; } else if (rgb->g == max) { hsl->h = 2.0 + (rgb->b - rgb->r) / delta; } else { hsl->h = 4.0 + (rgb->r - rgb->g) / delta; } hsl->h /= 6.0; if (hsl->h < 0.0) hsl->h += 1.0; } hsl->a = rgb->a; } static inline gdouble gimp_hsl_value (gdouble n1, gdouble n2, gdouble hue) { gdouble val; if (hue > 6.0) hue -= 6.0; else if (hue < 0.0) hue += 6.0; if (hue < 1.0) val = n1 + (n2 - n1) * hue; else if (hue < 3.0) val = n2; else if (hue < 4.0) val = n1 + (n2 - n1) * (4.0 - hue); else val = n1; return val; } /** * gimp_hsl_to_rgb: * @hsl: A color value in the HSL colorspace * @rgb: (out caller-allocates): The value converted to a value * in the RGB colorspace * * Convert a HSL color value to an RGB color value. **/ void gimp_hsl_to_rgb (const GimpHSL *hsl, GimpRGB *rgb) { g_return_if_fail (hsl != NULL); g_return_if_fail (rgb != NULL); if (hsl->s == 0) { /* achromatic case */ rgb->r = hsl->l; rgb->g = hsl->l; rgb->b = hsl->l; } else { gdouble m1, m2; if (hsl->l <= 0.5) m2 = hsl->l * (1.0 + hsl->s); else m2 = hsl->l + hsl->s - hsl->l * hsl->s; m1 = 2.0 * hsl->l - m2; rgb->r = gimp_hsl_value (m1, m2, hsl->h * 6.0 + 2.0); rgb->g = gimp_hsl_value (m1, m2, hsl->h * 6.0); rgb->b = gimp_hsl_value (m1, m2, hsl->h * 6.0 - 2.0); } rgb->a = hsl->a; }