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',