diff --git a/app/operations/layer-modes-legacy/gimpcolor-legacy.c b/app/operations/layer-modes-legacy/gimpcolor-legacy.c new file mode 100644 index 0000000000..1fff7e5442 --- /dev/null +++ b/app/operations/layer-modes-legacy/gimpcolor-legacy.c @@ -0,0 +1,255 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpcolor-legacy.c + * Copyright (C) 2024 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" + +#include "../operations-types.h" + +#include "gimpcolor-legacy.h" + + +#define GIMP_HSL_UNDEFINED -1.0 + + +void +gimp_rgb_to_hsv_legacy (gdouble *rgb, + gdouble *hsv) +{ + gdouble max, min, delta; + + g_return_if_fail (rgb != NULL); + g_return_if_fail (hsv != NULL); + + max = MAX (rgb[0], MAX (rgb[1], rgb[2])); + min = MIN (rgb[0], MIN (rgb[1], rgb[2])); + + hsv[2] = max; + delta = max - min; + + if (delta > 0.0001) + { + hsv[1] = delta / max; + + if (rgb[0] == max) + { + hsv[0] = (rgb[1] - rgb[2]) / delta; + if (hsv[0] < 0.0) + hsv[0] += 6.0; + } + else if (rgb[1] == max) + { + hsv[0] = 2.0 + (rgb[2] - rgb[0]) / delta; + } + else + { + hsv[0] = 4.0 + (rgb[0] - rgb[1]) / delta; + } + + hsv[0] /= 6.0; + } + else + { + hsv[1] = 0.0; + hsv[0] = 0.0; + } + + hsv[3] = rgb[3]; +} + +void +gimp_hsv_to_rgb_legacy (gdouble *hsv, + gdouble *rgb) +{ + gint i; + gdouble f, w, q, t; + + gdouble hue; + + g_return_if_fail (rgb != NULL); + g_return_if_fail (hsv != NULL); + + if (hsv[1] == 0.0) + { + rgb[0] = hsv[2]; + rgb[1] = hsv[2]; + rgb[2] = hsv[2]; + } + else + { + hue = hsv[0]; + + if (hue == 1.0) + hue = 0.0; + + hue *= 6.0; + + i = (gint) hue; + f = hue - i; + w = hsv[2] * (1.0 - hsv[1]); + q = hsv[2] * (1.0 - (hsv[1] * f)); + t = hsv[2] * (1.0 - (hsv[1] * (1.0 - f))); + + switch (i) + { + case 0: + rgb[0] = hsv[2]; + rgb[1] = t; + rgb[2] = w; + break; + case 1: + rgb[0] = q; + rgb[1] = hsv[2]; + rgb[2] = w; + break; + case 2: + rgb[0] = w; + rgb[1] = hsv[2]; + rgb[2] = t; + break; + case 3: + rgb[0] = w; + rgb[1] = q; + rgb[2] = hsv[2]; + break; + case 4: + rgb[0] = t; + rgb[1] = w; + rgb[2] = hsv[2]; + break; + case 5: + rgb[0] = hsv[2]; + rgb[1] = w; + rgb[2] = q; + break; + } + } + + rgb[3] = hsv[3]; +} + +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; +} + +void +gimp_rgb_to_hsl_legacy (gdouble *rgb, + gdouble *hsl) +{ + gdouble max, min, delta; + + g_return_if_fail (rgb != NULL); + g_return_if_fail (hsl != NULL); + + max = MAX (rgb[0], MAX (rgb[1], rgb[2])); + min = MIN (rgb[0], MIN (rgb[1], rgb[2])); + + hsl[2] = (max + min) / 2.0; + + if (max == min) + { + hsl[1] = 0.0; + hsl[0] = GIMP_HSL_UNDEFINED; + } + else + { + if (hsl[2] <= 0.5) + hsl[1] = (max - min) / (max + min); + else + hsl[1] = (max - min) / (2.0 - max - min); + + delta = max - min; + + if (delta == 0.0) + delta = 1.0; + + if (rgb[0] == max) + { + hsl[0] = (rgb[1] - rgb[2]) / delta; + } + else if (rgb[1] == max) + { + hsl[0] = 2.0 + (rgb[2] - rgb[0]) / delta; + } + else + { + hsl[0] = 4.0 + (rgb[0] - rgb[1]) / delta; + } + + hsl[0] /= 6.0; + + if (hsl[0] < 0.0) + hsl[0] += 1.0; + } + + hsl[3] = rgb[3]; +} + +void +gimp_hsl_to_rgb_legacy (gdouble *hsl, + gdouble *rgb) +{ + g_return_if_fail (hsl != NULL); + g_return_if_fail (rgb != NULL); + + if (hsl[1] == 0) + { + /* achromatic case */ + rgb[0] = hsl[2]; + rgb[1] = hsl[2]; + rgb[2] = hsl[2]; + } + else + { + gdouble m1, m2; + + if (hsl[2] <= 0.5) + m2 = hsl[2] * (1.0 + hsl[1]); + else + m2 = hsl[2] + hsl[1] - hsl[2] * hsl[1]; + + m1 = 2.0 * hsl[2] - m2; + + rgb[0] = gimp_hsl_value (m1, m2, hsl[0] * 6.0 + 2.0); + rgb[1] = gimp_hsl_value (m1, m2, hsl[0] * 6.0); + rgb[2] = gimp_hsl_value (m1, m2, hsl[0] * 6.0 - 2.0); + } + + rgb[3] = hsl[3]; +} diff --git a/app/operations/layer-modes-legacy/gimpcolor-legacy.h b/app/operations/layer-modes-legacy/gimpcolor-legacy.h new file mode 100644 index 0000000000..64f15cddae --- /dev/null +++ b/app/operations/layer-modes-legacy/gimpcolor-legacy.h @@ -0,0 +1,36 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpcolor-legacy.h + * Copyright (C) 2024 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __GIMP_COLOR_LEGACY_H__ +#define __GIMP_COLOR_LEGACY_H__ + + +void gimp_rgb_to_hsv_legacy (gdouble *rgb, + gdouble *hsv); +void gimp_hsv_to_rgb_legacy (gdouble *hsv, + gdouble *rgb); + +void gimp_rgb_to_hsl_legacy (gdouble *rgb, + gdouble *hsl); +void gimp_hsl_to_rgb_legacy (gdouble *hsl, + gdouble *rgb); + + +#endif /* __GIMP_COLOR_LEGACY_H__ */ diff --git a/app/operations/layer-modes-legacy/meson.build b/app/operations/layer-modes-legacy/meson.build index 7fa8409fbc..58a0dd3bb6 100644 --- a/app/operations/layer-modes-legacy/meson.build +++ b/app/operations/layer-modes-legacy/meson.build @@ -1,4 +1,5 @@ libapplayermodeslegacy_sources = [ + 'gimpcolor-legacy.c', 'gimpoperationadditionlegacy.c', 'gimpoperationburnlegacy.c', 'gimpoperationdarkenonlylegacy.c',