summaryrefslogtreecommitdiffstats
path: root/libgimpcolor/gimprgb.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:30:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:30:19 +0000
commit5c1676dfe6d2f3c837a5e074117b45613fd29a72 (patch)
treecbffb45144febf451e54061db2b21395faf94bfe /libgimpcolor/gimprgb.c
parentInitial commit. (diff)
downloadgimp-upstream.tar.xz
gimp-upstream.zip
Adding upstream version 2.10.34.upstream/2.10.34upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libgimpcolor/gimprgb.c')
-rw-r--r--libgimpcolor/gimprgb.c846
1 files changed, 846 insertions, 0 deletions
diff --git a/libgimpcolor/gimprgb.c b/libgimpcolor/gimprgb.c
new file mode 100644
index 0000000..b9ab4be
--- /dev/null
+++ b/libgimpcolor/gimprgb.c
@@ -0,0 +1,846 @@
+/* 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
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <babl/babl.h>
+#include <glib-object.h>
+
+#define GIMP_DISABLE_DEPRECATION_WARNINGS /* for GIMP_RGB_INTENSITY() */
+#include "libgimpmath/gimpmath.h"
+
+#include "gimpcolortypes.h"
+
+#undef GIMP_DISABLE_DEPRECATED /* for GIMP_RGB_INTENSITY() */
+#include "gimprgb.h"
+
+
+/**
+ * SECTION: gimprgb
+ * @title: GimpRGB
+ * @short_description: Definitions and Functions relating to RGB colors.
+ *
+ * Definitions and Functions relating to RGB colors.
+ **/
+
+
+/*
+ * GIMP_TYPE_RGB
+ */
+
+static GimpRGB * gimp_rgb_copy (const GimpRGB *rgb);
+
+
+GType
+gimp_rgb_get_type (void)
+{
+ static GType rgb_type = 0;
+
+ if (!rgb_type)
+ rgb_type = g_boxed_type_register_static ("GimpRGB",
+ (GBoxedCopyFunc) gimp_rgb_copy,
+ (GBoxedFreeFunc) g_free);
+
+ return rgb_type;
+}
+
+void
+gimp_value_get_rgb (const GValue *value,
+ GimpRGB *rgb)
+{
+ g_return_if_fail (GIMP_VALUE_HOLDS_RGB (value));
+ g_return_if_fail (rgb != NULL);
+
+ if (value->data[0].v_pointer)
+ *rgb = *((GimpRGB *) value->data[0].v_pointer);
+ else
+ gimp_rgba_set (rgb, 0.0, 0.0, 0.0, 1.0);
+}
+
+void
+gimp_value_set_rgb (GValue *value,
+ const GimpRGB *rgb)
+{
+ g_return_if_fail (GIMP_VALUE_HOLDS_RGB (value));
+ g_return_if_fail (rgb != NULL);
+
+ g_value_set_boxed (value, rgb);
+}
+
+static GimpRGB *
+gimp_rgb_copy (const GimpRGB *rgb)
+{
+ return g_memdup (rgb, sizeof (GimpRGB));
+}
+
+
+/* RGB functions */
+
+/**
+ * gimp_rgb_set:
+ * @rgb: a #GimpRGB struct
+ * @red: the red component
+ * @green: the green component
+ * @blue: the blue component
+ *
+ * Sets the red, green and blue components of @rgb and leaves the
+ * alpha component unchanged. The color values should be between 0.0
+ * and 1.0 but there is no check to enforce this and the values are
+ * set exactly as they are passed in.
+ **/
+void
+gimp_rgb_set (GimpRGB *rgb,
+ gdouble r,
+ gdouble g,
+ gdouble b)
+{
+ g_return_if_fail (rgb != NULL);
+
+ rgb->r = r;
+ rgb->g = g;
+ rgb->b = b;
+}
+
+/**
+ * gimp_rgb_set_alpha:
+ * @rgb: a #GimpRGB struct
+ * @alpha: the alpha component
+ *
+ * Sets the alpha component of @rgb and leaves the RGB components unchanged.
+ **/
+void
+gimp_rgb_set_alpha (GimpRGB *rgb,
+ gdouble a)
+{
+ g_return_if_fail (rgb != NULL);
+
+ rgb->a = a;
+}
+
+/**
+ * gimp_rgb_set_pixel:
+ * @rgb: a #GimpRGB struct
+ * @format: a Babl format
+ * @pixel: pointer to the source pixel
+ *
+ * Sets the red, green and blue components of @rgb from the color
+ * stored in @pixel. The pixel format of @pixel is determined by
+ * @format.
+ *
+ * Since: 2.10
+ **/
+void
+gimp_rgb_set_pixel (GimpRGB *rgb,
+ const Babl *format,
+ gconstpointer pixel)
+{
+ g_return_if_fail (rgb != NULL);
+ g_return_if_fail (format != NULL);
+ g_return_if_fail (pixel != NULL);
+
+ babl_process (babl_fish (format,
+ babl_format ("R'G'B' double")),
+ pixel, rgb, 1);
+}
+
+/**
+ * gimp_rgb_get_pixel:
+ * @rgb: a #GimpRGB struct
+ * @format: a Babl format
+ * @pixel: pointer to the destination pixel
+ *
+ * Writes the red, green, blue and alpha components of @rgb to the
+ * color stored in @pixel. The pixel format of @pixel is determined by
+ * @format.
+ *
+ * Since: 2.10
+ **/
+void
+gimp_rgb_get_pixel (const GimpRGB *rgb,
+ const Babl *format,
+ gpointer pixel)
+{
+ g_return_if_fail (rgb != NULL);
+ g_return_if_fail (format != NULL);
+ g_return_if_fail (pixel != NULL);
+
+ babl_process (babl_fish (babl_format ("R'G'B' double"),
+ format),
+ rgb, pixel, 1);
+}
+
+/**
+ * gimp_rgb_set_uchar:
+ * @rgb: a #GimpRGB struct
+ * @red: the red component
+ * @green: the green component
+ * @blue: the blue component
+ *
+ * Sets the red, green and blue components of @rgb from 8bit values
+ * (0 to 255) and leaves the alpha component unchanged.
+ **/
+void
+gimp_rgb_set_uchar (GimpRGB *rgb,
+ guchar r,
+ guchar g,
+ guchar b)
+{
+ g_return_if_fail (rgb != NULL);
+
+ rgb->r = (gdouble) r / 255.0;
+ rgb->g = (gdouble) g / 255.0;
+ rgb->b = (gdouble) b / 255.0;
+}
+
+void
+gimp_rgb_get_uchar (const GimpRGB *rgb,
+ guchar *r,
+ guchar *g,
+ guchar *b)
+{
+ g_return_if_fail (rgb != NULL);
+
+ if (r) *r = ROUND (CLAMP (rgb->r, 0.0, 1.0) * 255.0);
+ if (g) *g = ROUND (CLAMP (rgb->g, 0.0, 1.0) * 255.0);
+ if (b) *b = ROUND (CLAMP (rgb->b, 0.0, 1.0) * 255.0);
+}
+
+void
+gimp_rgb_add (GimpRGB *rgb1,
+ const GimpRGB *rgb2)
+{
+ g_return_if_fail (rgb1 != NULL);
+ g_return_if_fail (rgb2 != NULL);
+
+ rgb1->r += rgb2->r;
+ rgb1->g += rgb2->g;
+ rgb1->b += rgb2->b;
+}
+
+void
+gimp_rgb_subtract (GimpRGB *rgb1,
+ const GimpRGB *rgb2)
+{
+ g_return_if_fail (rgb1 != NULL);
+ g_return_if_fail (rgb2 != NULL);
+
+ rgb1->r -= rgb2->r;
+ rgb1->g -= rgb2->g;
+ rgb1->b -= rgb2->b;
+}
+
+void
+gimp_rgb_multiply (GimpRGB *rgb,
+ gdouble factor)
+{
+ g_return_if_fail (rgb != NULL);
+
+ rgb->r *= factor;
+ rgb->g *= factor;
+ rgb->b *= factor;
+}
+
+gdouble
+gimp_rgb_distance (const GimpRGB *rgb1,
+ const GimpRGB *rgb2)
+{
+ g_return_val_if_fail (rgb1 != NULL, 0.0);
+ g_return_val_if_fail (rgb2 != NULL, 0.0);
+
+ return (fabs (rgb1->r - rgb2->r) +
+ fabs (rgb1->g - rgb2->g) +
+ fabs (rgb1->b - rgb2->b));
+}
+
+gdouble
+gimp_rgb_max (const GimpRGB *rgb)
+{
+ g_return_val_if_fail (rgb != NULL, 0.0);
+
+ if (rgb->r > rgb->g)
+ return (rgb->r > rgb->b) ? rgb->r : rgb->b;
+ else
+ return (rgb->g > rgb->b) ? rgb->g : rgb->b;
+}
+
+gdouble
+gimp_rgb_min (const GimpRGB *rgb)
+{
+ g_return_val_if_fail (rgb != NULL, 0.0);
+
+ if (rgb->r < rgb->g)
+ return (rgb->r < rgb->b) ? rgb->r : rgb->b;
+ else
+ return (rgb->g < rgb->b) ? rgb->g : rgb->b;
+}
+
+void
+gimp_rgb_clamp (GimpRGB *rgb)
+{
+ g_return_if_fail (rgb != NULL);
+
+ rgb->r = CLAMP (rgb->r, 0.0, 1.0);
+ rgb->g = CLAMP (rgb->g, 0.0, 1.0);
+ rgb->b = CLAMP (rgb->b, 0.0, 1.0);
+ rgb->a = CLAMP (rgb->a, 0.0, 1.0);
+}
+
+void
+gimp_rgb_gamma (GimpRGB *rgb,
+ gdouble gamma)
+{
+ gdouble ig;
+
+ g_return_if_fail (rgb != NULL);
+
+ if (gamma != 0.0)
+ ig = 1.0 / gamma;
+ else
+ ig = 0.0;
+
+ rgb->r = pow (rgb->r, ig);
+ rgb->g = pow (rgb->g, ig);
+ rgb->b = pow (rgb->b, ig);
+}
+
+/**
+ * gimp_rgb_luminance:
+ * @rgb: a #GimpRGB struct
+ *
+ * Return value: the luminous intensity of the range from 0.0 to 1.0.
+ *
+ * Since: 2.4
+ **/
+gdouble
+gimp_rgb_luminance (const GimpRGB *rgb)
+{
+ gdouble luminance;
+
+ g_return_val_if_fail (rgb != NULL, 0.0);
+
+ luminance = GIMP_RGB_LUMINANCE (rgb->r, rgb->g, rgb->b);
+
+ return CLAMP (luminance, 0.0, 1.0);
+}
+
+/**
+ * gimp_rgb_luminance_uchar:
+ * @rgb: a #GimpRGB struct
+ *
+ * Return value: the luminous intensity in the range from 0 to 255.
+ *
+ * Since: 2.4
+ **/
+guchar
+gimp_rgb_luminance_uchar (const GimpRGB *rgb)
+{
+ g_return_val_if_fail (rgb != NULL, 0);
+
+ return ROUND (gimp_rgb_luminance (rgb) * 255.0);
+}
+
+/**
+ * gimp_rgb_intensity:
+ * @rgb: a #GimpRGB struct
+ *
+ * This function is deprecated! Use gimp_rgb_luminance() instead.
+ *
+ * Return value: the intensity in the range from 0.0 to 1.0.
+ **/
+gdouble
+gimp_rgb_intensity (const GimpRGB *rgb)
+{
+ gdouble intensity;
+
+ g_return_val_if_fail (rgb != NULL, 0.0);
+
+ intensity = GIMP_RGB_INTENSITY (rgb->r, rgb->g, rgb->b);
+
+ return CLAMP (intensity, 0.0, 1.0);
+}
+
+/**
+ * gimp_rgb_intensity_uchar:
+ * @rgb: a #GimpRGB struct
+ *
+ * This function is deprecated! Use gimp_rgb_luminance_uchar() instead.
+ *
+ * Return value: the intensity in the range from 0 to 255.
+ **/
+guchar
+gimp_rgb_intensity_uchar (const GimpRGB *rgb)
+{
+ g_return_val_if_fail (rgb != NULL, 0);
+
+ return ROUND (gimp_rgb_intensity (rgb) * 255.0);
+}
+
+void
+gimp_rgb_composite (GimpRGB *color1,
+ const GimpRGB *color2,
+ GimpRGBCompositeMode mode)
+{
+ g_return_if_fail (color1 != NULL);
+ g_return_if_fail (color2 != NULL);
+
+ switch (mode)
+ {
+ case GIMP_RGB_COMPOSITE_NONE:
+ break;
+
+ case GIMP_RGB_COMPOSITE_NORMAL:
+ /* put color2 on top of color1 */
+ if (color2->a == 1.0)
+ {
+ *color1 = *color2;
+ }
+ else
+ {
+ gdouble factor = color1->a * (1.0 - color2->a);
+
+ color1->r = color1->r * factor + color2->r * color2->a;
+ color1->g = color1->g * factor + color2->g * color2->a;
+ color1->b = color1->b * factor + color2->b * color2->a;
+ color1->a = factor + color2->a;
+ }
+ break;
+
+ case GIMP_RGB_COMPOSITE_BEHIND:
+ /* put color2 below color1 */
+ if (color1->a < 1.0)
+ {
+ gdouble factor = color2->a * (1.0 - color1->a);
+
+ color1->r = color2->r * factor + color1->r * color1->a;
+ color1->g = color2->g * factor + color1->g * color1->a;
+ color1->b = color2->b * factor + color1->b * color1->a;
+ color1->a = factor + color1->a;
+ }
+ break;
+ }
+}
+
+/* RGBA functions */
+
+/**
+ * gimp_rgba_set_pixel:
+ * @rgba: a #GimpRGB struct
+ * @format: a Babl format
+ * @pixel: pointer to the source pixel
+ *
+ * Sets the red, green, blue and alpha components of @rgba from the
+ * color stored in @pixel. The pixel format of @pixel is determined
+ * by @format.
+ *
+ * Since: 2.10
+ **/
+void
+gimp_rgba_set_pixel (GimpRGB *rgba,
+ const Babl *format,
+ gconstpointer pixel)
+{
+ g_return_if_fail (rgba != NULL);
+ g_return_if_fail (format != NULL);
+ g_return_if_fail (pixel != NULL);
+
+ babl_process (babl_fish (format,
+ babl_format ("R'G'B'A double")),
+ pixel, rgba, 1);
+}
+
+/**
+ * gimp_rgba_get_pixel:
+ * @rgba: a #GimpRGB struct
+ * @format: a Babl format
+ * @pixel: pointer to the destination pixel
+ *
+ * Writes the red, green, blue and alpha components of @rgba to the
+ * color stored in @pixel. The pixel format of @pixel is determined by
+ * @format.
+ *
+ * Since: 2.10
+ **/
+void
+gimp_rgba_get_pixel (const GimpRGB *rgba,
+ const Babl *format,
+ gpointer pixel)
+{
+ g_return_if_fail (rgba != NULL);
+ g_return_if_fail (format != NULL);
+ g_return_if_fail (pixel != NULL);
+
+ babl_process (babl_fish (babl_format ("R'G'B'A double"),
+ format),
+ rgba, pixel, 1);
+}
+
+/**
+ * gimp_rgba_set:
+ * @rgba: a #GimpRGB struct
+ * @red: the red component
+ * @green: the green component
+ * @blue: the blue component
+ * @alpha: the alpha component
+ *
+ * Sets the red, green, blue and alpha components of @rgb. The values
+ * should be between 0.0 and 1.0 but there is no check to enforce this
+ * and the values are set exactly as they are passed in.
+ **/
+void
+gimp_rgba_set (GimpRGB *rgba,
+ gdouble r,
+ gdouble g,
+ gdouble b,
+ gdouble a)
+{
+ g_return_if_fail (rgba != NULL);
+
+ rgba->r = r;
+ rgba->g = g;
+ rgba->b = b;
+ rgba->a = a;
+}
+
+/**
+ * gimp_rgba_set_uchar:
+ * @rgba: a #GimpRGB struct
+ * @red: the red component
+ * @green: the green component
+ * @blue: the blue component
+ * @alpha: the alpha component
+ *
+ * Sets the red, green, blue and alpha components of @rgb from 8bit
+ * values (0 to 255).
+ **/
+void
+gimp_rgba_set_uchar (GimpRGB *rgba,
+ guchar r,
+ guchar g,
+ guchar b,
+ guchar a)
+{
+ g_return_if_fail (rgba != NULL);
+
+ rgba->r = (gdouble) r / 255.0;
+ rgba->g = (gdouble) g / 255.0;
+ rgba->b = (gdouble) b / 255.0;
+ rgba->a = (gdouble) a / 255.0;
+}
+
+void
+gimp_rgba_get_uchar (const GimpRGB *rgba,
+ guchar *r,
+ guchar *g,
+ guchar *b,
+ guchar *a)
+{
+ g_return_if_fail (rgba != NULL);
+
+ if (r) *r = ROUND (CLAMP (rgba->r, 0.0, 1.0) * 255.0);
+ if (g) *g = ROUND (CLAMP (rgba->g, 0.0, 1.0) * 255.0);
+ if (b) *b = ROUND (CLAMP (rgba->b, 0.0, 1.0) * 255.0);
+ if (a) *a = ROUND (CLAMP (rgba->a, 0.0, 1.0) * 255.0);
+}
+
+void
+gimp_rgba_add (GimpRGB *rgba1,
+ const GimpRGB *rgba2)
+{
+ g_return_if_fail (rgba1 != NULL);
+ g_return_if_fail (rgba2 != NULL);
+
+ rgba1->r += rgba2->r;
+ rgba1->g += rgba2->g;
+ rgba1->b += rgba2->b;
+ rgba1->a += rgba2->a;
+}
+
+void
+gimp_rgba_subtract (GimpRGB *rgba1,
+ const GimpRGB *rgba2)
+{
+ g_return_if_fail (rgba1 != NULL);
+ g_return_if_fail (rgba2 != NULL);
+
+ rgba1->r -= rgba2->r;
+ rgba1->g -= rgba2->g;
+ rgba1->b -= rgba2->b;
+ rgba1->a -= rgba2->a;
+}
+
+void
+gimp_rgba_multiply (GimpRGB *rgba,
+ gdouble factor)
+{
+ g_return_if_fail (rgba != NULL);
+
+ rgba->r *= factor;
+ rgba->g *= factor;
+ rgba->b *= factor;
+ rgba->a *= factor;
+}
+
+gdouble
+gimp_rgba_distance (const GimpRGB *rgba1,
+ const GimpRGB *rgba2)
+{
+ g_return_val_if_fail (rgba1 != NULL, 0.0);
+ g_return_val_if_fail (rgba2 != NULL, 0.0);
+
+ return (fabs (rgba1->r - rgba2->r) +
+ fabs (rgba1->g - rgba2->g) +
+ fabs (rgba1->b - rgba2->b) +
+ fabs (rgba1->a - rgba2->a));
+}
+
+
+/*
+ * GIMP_TYPE_PARAM_RGB
+ */
+
+#define GIMP_PARAM_SPEC_RGB(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_RGB, GimpParamSpecRGB))
+
+typedef struct _GimpParamSpecRGB GimpParamSpecRGB;
+
+struct _GimpParamSpecRGB
+{
+ GParamSpecBoxed parent_instance;
+
+ gboolean has_alpha;
+ gboolean validate; /* change this to enable [0.0...1.0] */
+ GimpRGB default_value;
+};
+
+static void gimp_param_rgb_class_init (GParamSpecClass *class);
+static void gimp_param_rgb_init (GParamSpec *pspec);
+static void gimp_param_rgb_set_default (GParamSpec *pspec,
+ GValue *value);
+static gboolean gimp_param_rgb_validate (GParamSpec *pspec,
+ GValue *value);
+static gint gimp_param_rgb_values_cmp (GParamSpec *pspec,
+ const GValue *value1,
+ const GValue *value2);
+
+/**
+ * gimp_param_rgb_get_type:
+ *
+ * Reveals the object type
+ *
+ * Returns: the #GType for a GimpParamRGB object
+ *
+ * Since: 2.4
+ **/
+GType
+gimp_param_rgb_get_type (void)
+{
+ static GType spec_type = 0;
+
+ if (! spec_type)
+ {
+ const GTypeInfo type_info =
+ {
+ sizeof (GParamSpecClass),
+ NULL, NULL,
+ (GClassInitFunc) gimp_param_rgb_class_init,
+ NULL, NULL,
+ sizeof (GimpParamSpecRGB),
+ 0,
+ (GInstanceInitFunc) gimp_param_rgb_init
+ };
+
+ spec_type = g_type_register_static (G_TYPE_PARAM_BOXED,
+ "GimpParamRGB",
+ &type_info, 0);
+ }
+
+ return spec_type;
+}
+
+static void
+gimp_param_rgb_class_init (GParamSpecClass *class)
+{
+ class->value_type = GIMP_TYPE_RGB;
+ class->value_set_default = gimp_param_rgb_set_default;
+ class->value_validate = gimp_param_rgb_validate;
+ class->values_cmp = gimp_param_rgb_values_cmp;
+}
+
+static void
+gimp_param_rgb_init (GParamSpec *pspec)
+{
+ GimpParamSpecRGB *cspec = GIMP_PARAM_SPEC_RGB (pspec);
+
+ gimp_rgba_set (&cspec->default_value, 0.0, 0.0, 0.0, 1.0);
+}
+
+static void
+gimp_param_rgb_set_default (GParamSpec *pspec,
+ GValue *value)
+{
+ GimpParamSpecRGB *cspec = GIMP_PARAM_SPEC_RGB (pspec);
+
+ g_value_set_static_boxed (value, &cspec->default_value);
+}
+
+static gboolean
+gimp_param_rgb_validate (GParamSpec *pspec,
+ GValue *value)
+{
+ GimpParamSpecRGB *rgb_spec = GIMP_PARAM_SPEC_RGB (pspec);
+ GimpRGB *rgb = value->data[0].v_pointer;
+
+ if (rgb_spec->validate && rgb)
+ {
+ GimpRGB oval = *rgb;
+
+ gimp_rgb_clamp (rgb);
+
+ return (oval.r != rgb->r ||
+ oval.g != rgb->g ||
+ oval.b != rgb->b ||
+ (rgb_spec->has_alpha && oval.a != rgb->a));
+ }
+
+ return FALSE;
+}
+
+static gint
+gimp_param_rgb_values_cmp (GParamSpec *pspec,
+ const GValue *value1,
+ const GValue *value2)
+{
+ GimpRGB *rgb1 = value1->data[0].v_pointer;
+ GimpRGB *rgb2 = value2->data[0].v_pointer;
+
+ /* try to return at least *something*, it's useless anyway... */
+
+ if (! rgb1)
+ {
+ return rgb2 != NULL ? -1 : 0;
+ }
+ else if (! rgb2)
+ {
+ return rgb1 != NULL;
+ }
+ else
+ {
+ guint32 int1 = 0;
+ guint32 int2 = 0;
+
+ if (GIMP_PARAM_SPEC_RGB (pspec)->has_alpha)
+ {
+ gimp_rgba_get_uchar (rgb1,
+ ((guchar *) &int1) + 0,
+ ((guchar *) &int1) + 1,
+ ((guchar *) &int1) + 2,
+ ((guchar *) &int1) + 3);
+ gimp_rgba_get_uchar (rgb2,
+ ((guchar *) &int2) + 0,
+ ((guchar *) &int2) + 1,
+ ((guchar *) &int2) + 2,
+ ((guchar *) &int2) + 3);
+ }
+ else
+ {
+ gimp_rgb_get_uchar (rgb1,
+ ((guchar *) &int1) + 0,
+ ((guchar *) &int1) + 1,
+ ((guchar *) &int1) + 2);
+ gimp_rgb_get_uchar (rgb2,
+ ((guchar *) &int2) + 0,
+ ((guchar *) &int2) + 1,
+ ((guchar *) &int2) + 2);
+ }
+
+ return int1 - int2;
+ }
+}
+
+/**
+ * gimp_param_spec_rgb:
+ * @name: Canonical name of the param
+ * @nick: Nickname of the param
+ * @blurb: Brief description of param.
+ * @has_alpha: %TRUE if the alpha channel has relevance.
+ * @default_value: Value to use if none is assigned.
+ * @flags: a combination of #GParamFlags
+ *
+ * Creates a param spec to hold an #GimpRGB value.
+ * See g_param_spec_internal() for more information.
+ *
+ * Returns: a newly allocated #GParamSpec instance
+ *
+ * Since: 2.4
+ **/
+GParamSpec *
+gimp_param_spec_rgb (const gchar *name,
+ const gchar *nick,
+ const gchar *blurb,
+ gboolean has_alpha,
+ const GimpRGB *default_value,
+ GParamFlags flags)
+{
+ GimpParamSpecRGB *cspec;
+
+ cspec = g_param_spec_internal (GIMP_TYPE_PARAM_RGB,
+ name, nick, blurb, flags);
+
+ cspec->has_alpha = has_alpha;
+
+ if (default_value)
+ cspec->default_value = *default_value;
+ else
+ gimp_rgba_set (&cspec->default_value, 0.0, 0.0, 0.0, 1.0);
+
+ return G_PARAM_SPEC (cspec);
+}
+
+/**
+ * gimp_param_spec_rgb_get_default:
+ * @pspec: a #GimpParamSpecRGB.
+ * @default_value: return location for @pspec's default value
+ *
+ * Returns the @pspec's default color value.
+ *
+ * Since: 2.10.14
+ **/
+void
+gimp_param_spec_rgb_get_default (GParamSpec *pspec,
+ GimpRGB *default_value)
+{
+ g_return_if_fail (GIMP_IS_PARAM_SPEC_RGB (pspec));
+ g_return_if_fail (default_value != NULL);
+
+ *default_value = GIMP_PARAM_SPEC_RGB (pspec)->default_value;
+}
+
+/**
+ * gimp_param_spec_rgb_has_alpha:
+ * @pspec: a #GParamSpec to hold an #GimpRGB value.
+ *
+ * Returns: %TRUE if the alpha channel is relevant.
+ *
+ * Since: 2.4
+ **/
+gboolean
+gimp_param_spec_rgb_has_alpha (GParamSpec *pspec)
+{
+ g_return_val_if_fail (GIMP_IS_PARAM_SPEC_RGB (pspec), FALSE);
+
+ return GIMP_PARAM_SPEC_RGB (pspec)->has_alpha;
+}