1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
4 * This library is free software: you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <https://www.gnu.org/licenses/>.
21 #include <babl/babl.h>
22 #include <glib-object.h>
24 #include "libgimpmath/gimpmath.h"
26 #include "gimpcolortypes.h"
33 * @short_description: Definitions and Functions relating to RGB colors.
35 * Definitions and Functions relating to RGB colors.
43 static GimpRGB
* gimp_rgb_copy (const GimpRGB
*rgb
);
47 gimp_rgb_get_type (void)
49 static GType rgb_type
= 0;
52 rgb_type
= g_boxed_type_register_static ("GimpRGB",
53 (GBoxedCopyFunc
) gimp_rgb_copy
,
54 (GBoxedFreeFunc
) g_free
);
60 gimp_value_get_rgb (const GValue
*value
,
63 g_return_if_fail (GIMP_VALUE_HOLDS_RGB (value
));
64 g_return_if_fail (rgb
!= NULL
);
66 if (value
->data
[0].v_pointer
)
67 *rgb
= *((GimpRGB
*) value
->data
[0].v_pointer
);
69 gimp_rgba_set (rgb
, 0.0, 0.0, 0.0, 1.0);
73 gimp_value_set_rgb (GValue
*value
,
76 g_return_if_fail (GIMP_VALUE_HOLDS_RGB (value
));
77 g_return_if_fail (rgb
!= NULL
);
79 g_value_set_boxed (value
, rgb
);
83 gimp_rgb_copy (const GimpRGB
*rgb
)
85 return g_memdup (rgb
, sizeof (GimpRGB
));
93 * @rgb: a #GimpRGB struct
94 * @red: the red component
95 * @green: the green component
96 * @blue: the blue component
98 * Sets the red, green and blue components of @rgb and leaves the
99 * alpha component unchanged. The color values should be between 0.0
100 * and 1.0 but there is no check to enforce this and the values are
101 * set exactly as they are passed in.
104 gimp_rgb_set (GimpRGB
*rgb
,
109 g_return_if_fail (rgb
!= NULL
);
117 * gimp_rgb_set_alpha:
118 * @rgb: a #GimpRGB struct
119 * @alpha: the alpha component
121 * Sets the alpha component of @rgb and leaves the RGB components unchanged.
124 gimp_rgb_set_alpha (GimpRGB
*rgb
,
127 g_return_if_fail (rgb
!= NULL
);
133 * gimp_rgb_set_pixel:
134 * @rgb: a #GimpRGB struct
135 * @format: a Babl format
136 * @pixel: pointer to the source pixel
138 * Sets the red, green and blue components of @rgb from the color
139 * stored in @pixel. The pixel format of @pixel is determined by
145 gimp_rgb_set_pixel (GimpRGB
*rgb
,
149 g_return_if_fail (rgb
!= NULL
);
150 g_return_if_fail (format
!= NULL
);
151 g_return_if_fail (pixel
!= NULL
);
153 babl_process (babl_fish (format
,
154 babl_format ("R'G'B' double")),
159 * gimp_rgb_get_pixel:
160 * @rgb: a #GimpRGB struct
161 * @format: a Babl format
162 * @pixel: pointer to the destination pixel
164 * Writes the red, green, blue and alpha components of @rgb to the
165 * color stored in @pixel. The pixel format of @pixel is determined by
171 gimp_rgb_get_pixel (const GimpRGB
*rgb
,
175 g_return_if_fail (rgb
!= NULL
);
176 g_return_if_fail (format
!= NULL
);
177 g_return_if_fail (pixel
!= NULL
);
179 babl_process (babl_fish (babl_format ("R'G'B' double"),
185 * gimp_rgb_set_uchar:
186 * @rgb: a #GimpRGB struct
187 * @red: the red component
188 * @green: the green component
189 * @blue: the blue component
191 * Sets the red, green and blue components of @rgb from 8bit values
192 * (0 to 255) and leaves the alpha component unchanged.
195 gimp_rgb_set_uchar (GimpRGB
*rgb
,
200 g_return_if_fail (rgb
!= NULL
);
202 rgb
->r
= (gdouble
) r
/ 255.0;
203 rgb
->g
= (gdouble
) g
/ 255.0;
204 rgb
->b
= (gdouble
) b
/ 255.0;
208 gimp_rgb_get_uchar (const GimpRGB
*rgb
,
213 g_return_if_fail (rgb
!= NULL
);
215 if (r
) *r
= ROUND (CLAMP (rgb
->r
, 0.0, 1.0) * 255.0);
216 if (g
) *g
= ROUND (CLAMP (rgb
->g
, 0.0, 1.0) * 255.0);
217 if (b
) *b
= ROUND (CLAMP (rgb
->b
, 0.0, 1.0) * 255.0);
221 gimp_rgb_add (GimpRGB
*rgb1
,
224 g_return_if_fail (rgb1
!= NULL
);
225 g_return_if_fail (rgb2
!= NULL
);
233 gimp_rgb_subtract (GimpRGB
*rgb1
,
236 g_return_if_fail (rgb1
!= NULL
);
237 g_return_if_fail (rgb2
!= NULL
);
245 gimp_rgb_multiply (GimpRGB
*rgb
,
248 g_return_if_fail (rgb
!= NULL
);
256 gimp_rgb_distance (const GimpRGB
*rgb1
,
259 g_return_val_if_fail (rgb1
!= NULL
, 0.0);
260 g_return_val_if_fail (rgb2
!= NULL
, 0.0);
262 return (fabs (rgb1
->r
- rgb2
->r
) +
263 fabs (rgb1
->g
- rgb2
->g
) +
264 fabs (rgb1
->b
- rgb2
->b
));
268 gimp_rgb_max (const GimpRGB
*rgb
)
270 g_return_val_if_fail (rgb
!= NULL
, 0.0);
273 return (rgb
->r
> rgb
->b
) ? rgb
->r
: rgb
->b
;
275 return (rgb
->g
> rgb
->b
) ? rgb
->g
: rgb
->b
;
279 gimp_rgb_min (const GimpRGB
*rgb
)
281 g_return_val_if_fail (rgb
!= NULL
, 0.0);
284 return (rgb
->r
< rgb
->b
) ? rgb
->r
: rgb
->b
;
286 return (rgb
->g
< rgb
->b
) ? rgb
->g
: rgb
->b
;
290 gimp_rgb_clamp (GimpRGB
*rgb
)
292 g_return_if_fail (rgb
!= NULL
);
294 rgb
->r
= CLAMP (rgb
->r
, 0.0, 1.0);
295 rgb
->g
= CLAMP (rgb
->g
, 0.0, 1.0);
296 rgb
->b
= CLAMP (rgb
->b
, 0.0, 1.0);
297 rgb
->a
= CLAMP (rgb
->a
, 0.0, 1.0);
301 gimp_rgb_gamma (GimpRGB
*rgb
,
306 g_return_if_fail (rgb
!= NULL
);
313 rgb
->r
= pow (rgb
->r
, ig
);
314 rgb
->g
= pow (rgb
->g
, ig
);
315 rgb
->b
= pow (rgb
->b
, ig
);
319 * gimp_rgb_luminance:
320 * @rgb: a #GimpRGB struct
322 * Return value: the luminous intensity of the range from 0.0 to 1.0.
327 gimp_rgb_luminance (const GimpRGB
*rgb
)
331 g_return_val_if_fail (rgb
!= NULL
, 0.0);
333 luminance
= GIMP_RGB_LUMINANCE (rgb
->r
, rgb
->g
, rgb
->b
);
335 return CLAMP (luminance
, 0.0, 1.0);
339 * gimp_rgb_luminance_uchar:
340 * @rgb: a #GimpRGB struct
342 * Return value: the luminous intensity in the range from 0 to 255.
347 gimp_rgb_luminance_uchar (const GimpRGB
*rgb
)
349 g_return_val_if_fail (rgb
!= NULL
, 0);
351 return ROUND (gimp_rgb_luminance (rgb
) * 255.0);
355 gimp_rgb_composite (GimpRGB
*color1
,
356 const GimpRGB
*color2
,
357 GimpRGBCompositeMode mode
)
359 g_return_if_fail (color1
!= NULL
);
360 g_return_if_fail (color2
!= NULL
);
364 case GIMP_RGB_COMPOSITE_NONE
:
367 case GIMP_RGB_COMPOSITE_NORMAL
:
368 /* put color2 on top of color1 */
369 if (color2
->a
== 1.0)
375 gdouble factor
= color1
->a
* (1.0 - color2
->a
);
377 color1
->r
= color1
->r
* factor
+ color2
->r
* color2
->a
;
378 color1
->g
= color1
->g
* factor
+ color2
->g
* color2
->a
;
379 color1
->b
= color1
->b
* factor
+ color2
->b
* color2
->a
;
380 color1
->a
= factor
+ color2
->a
;
384 case GIMP_RGB_COMPOSITE_BEHIND
:
385 /* put color2 below color1 */
388 gdouble factor
= color2
->a
* (1.0 - color1
->a
);
390 color1
->r
= color2
->r
* factor
+ color1
->r
* color1
->a
;
391 color1
->g
= color2
->g
* factor
+ color1
->g
* color1
->a
;
392 color1
->b
= color2
->b
* factor
+ color1
->b
* color1
->a
;
393 color1
->a
= factor
+ color1
->a
;
402 * gimp_rgba_set_pixel:
403 * @rgba: a #GimpRGB struct
404 * @format: a Babl format
405 * @pixel: pointer to the source pixel
407 * Sets the red, green, blue and alpha components of @rgba from the
408 * color stored in @pixel. The pixel format of @pixel is determined
414 gimp_rgba_set_pixel (GimpRGB
*rgba
,
418 g_return_if_fail (rgba
!= NULL
);
419 g_return_if_fail (format
!= NULL
);
420 g_return_if_fail (pixel
!= NULL
);
422 babl_process (babl_fish (format
,
423 babl_format ("R'G'B'A double")),
428 * gimp_rgba_get_pixel:
429 * @rgba: a #GimpRGB struct
430 * @format: a Babl format
431 * @pixel: pointer to the destination pixel
433 * Writes the red, green, blue and alpha components of @rgba to the
434 * color stored in @pixel. The pixel format of @pixel is determined by
440 gimp_rgba_get_pixel (const GimpRGB
*rgba
,
444 g_return_if_fail (rgba
!= NULL
);
445 g_return_if_fail (format
!= NULL
);
446 g_return_if_fail (pixel
!= NULL
);
448 babl_process (babl_fish (babl_format ("R'G'B'A double"),
455 * @rgba: a #GimpRGB struct
456 * @red: the red component
457 * @green: the green component
458 * @blue: the blue component
459 * @alpha: the alpha component
461 * Sets the red, green, blue and alpha components of @rgb. The values
462 * should be between 0.0 and 1.0 but there is no check to enforce this
463 * and the values are set exactly as they are passed in.
466 gimp_rgba_set (GimpRGB
*rgba
,
472 g_return_if_fail (rgba
!= NULL
);
481 * gimp_rgba_set_uchar:
482 * @rgba: a #GimpRGB struct
483 * @red: the red component
484 * @green: the green component
485 * @blue: the blue component
486 * @alpha: the alpha component
488 * Sets the red, green, blue and alpha components of @rgb from 8bit
492 gimp_rgba_set_uchar (GimpRGB
*rgba
,
498 g_return_if_fail (rgba
!= NULL
);
500 rgba
->r
= (gdouble
) r
/ 255.0;
501 rgba
->g
= (gdouble
) g
/ 255.0;
502 rgba
->b
= (gdouble
) b
/ 255.0;
503 rgba
->a
= (gdouble
) a
/ 255.0;
507 gimp_rgba_get_uchar (const GimpRGB
*rgba
,
513 g_return_if_fail (rgba
!= NULL
);
515 if (r
) *r
= ROUND (CLAMP (rgba
->r
, 0.0, 1.0) * 255.0);
516 if (g
) *g
= ROUND (CLAMP (rgba
->g
, 0.0, 1.0) * 255.0);
517 if (b
) *b
= ROUND (CLAMP (rgba
->b
, 0.0, 1.0) * 255.0);
518 if (a
) *a
= ROUND (CLAMP (rgba
->a
, 0.0, 1.0) * 255.0);
522 gimp_rgba_add (GimpRGB
*rgba1
,
523 const GimpRGB
*rgba2
)
525 g_return_if_fail (rgba1
!= NULL
);
526 g_return_if_fail (rgba2
!= NULL
);
528 rgba1
->r
+= rgba2
->r
;
529 rgba1
->g
+= rgba2
->g
;
530 rgba1
->b
+= rgba2
->b
;
531 rgba1
->a
+= rgba2
->a
;
535 gimp_rgba_subtract (GimpRGB
*rgba1
,
536 const GimpRGB
*rgba2
)
538 g_return_if_fail (rgba1
!= NULL
);
539 g_return_if_fail (rgba2
!= NULL
);
541 rgba1
->r
-= rgba2
->r
;
542 rgba1
->g
-= rgba2
->g
;
543 rgba1
->b
-= rgba2
->b
;
544 rgba1
->a
-= rgba2
->a
;
548 gimp_rgba_multiply (GimpRGB
*rgba
,
551 g_return_if_fail (rgba
!= NULL
);
560 gimp_rgba_distance (const GimpRGB
*rgba1
,
561 const GimpRGB
*rgba2
)
563 g_return_val_if_fail (rgba1
!= NULL
, 0.0);
564 g_return_val_if_fail (rgba2
!= NULL
, 0.0);
566 return (fabs (rgba1
->r
- rgba2
->r
) +
567 fabs (rgba1
->g
- rgba2
->g
) +
568 fabs (rgba1
->b
- rgba2
->b
) +
569 fabs (rgba1
->a
- rgba2
->a
));
574 * GIMP_TYPE_PARAM_RGB
577 #define GIMP_PARAM_SPEC_RGB(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_RGB, GimpParamSpecRGB))
579 typedef struct _GimpParamSpecRGB GimpParamSpecRGB
;
581 struct _GimpParamSpecRGB
583 GParamSpecBoxed parent_instance
;
586 gboolean validate
; /* change this to enable [0.0...1.0] */
587 GimpRGB default_value
;
590 static void gimp_param_rgb_class_init (GParamSpecClass
*class);
591 static void gimp_param_rgb_init (GParamSpec
*pspec
);
592 static void gimp_param_rgb_set_default (GParamSpec
*pspec
,
594 static gboolean
gimp_param_rgb_validate (GParamSpec
*pspec
,
596 static gint
gimp_param_rgb_values_cmp (GParamSpec
*pspec
,
597 const GValue
*value1
,
598 const GValue
*value2
);
601 * gimp_param_rgb_get_type:
603 * Reveals the object type
605 * Returns: the #GType for a GimpParamRGB object
610 gimp_param_rgb_get_type (void)
612 static GType spec_type
= 0;
616 const GTypeInfo type_info
=
618 sizeof (GParamSpecClass
),
620 (GClassInitFunc
) gimp_param_rgb_class_init
,
622 sizeof (GimpParamSpecRGB
),
624 (GInstanceInitFunc
) gimp_param_rgb_init
627 spec_type
= g_type_register_static (G_TYPE_PARAM_BOXED
,
636 gimp_param_rgb_class_init (GParamSpecClass
*class)
638 class->value_type
= GIMP_TYPE_RGB
;
639 class->value_set_default
= gimp_param_rgb_set_default
;
640 class->value_validate
= gimp_param_rgb_validate
;
641 class->values_cmp
= gimp_param_rgb_values_cmp
;
645 gimp_param_rgb_init (GParamSpec
*pspec
)
647 GimpParamSpecRGB
*cspec
= GIMP_PARAM_SPEC_RGB (pspec
);
649 gimp_rgba_set (&cspec
->default_value
, 0.0, 0.0, 0.0, 1.0);
653 gimp_param_rgb_set_default (GParamSpec
*pspec
,
656 GimpParamSpecRGB
*cspec
= GIMP_PARAM_SPEC_RGB (pspec
);
658 g_value_set_static_boxed (value
, &cspec
->default_value
);
662 gimp_param_rgb_validate (GParamSpec
*pspec
,
665 GimpParamSpecRGB
*rgb_spec
= GIMP_PARAM_SPEC_RGB (pspec
);
666 GimpRGB
*rgb
= value
->data
[0].v_pointer
;
668 if (rgb_spec
->validate
&& rgb
)
672 gimp_rgb_clamp (rgb
);
674 return (oval
.r
!= rgb
->r
||
677 (rgb_spec
->has_alpha
&& oval
.a
!= rgb
->a
));
684 gimp_param_rgb_values_cmp (GParamSpec
*pspec
,
685 const GValue
*value1
,
686 const GValue
*value2
)
688 GimpRGB
*rgb1
= value1
->data
[0].v_pointer
;
689 GimpRGB
*rgb2
= value2
->data
[0].v_pointer
;
691 /* try to return at least *something*, it's useless anyway... */
695 return rgb2
!= NULL
? -1 : 0;
706 if (GIMP_PARAM_SPEC_RGB (pspec
)->has_alpha
)
708 gimp_rgba_get_uchar (rgb1
,
709 ((guchar
*) &int1
) + 0,
710 ((guchar
*) &int1
) + 1,
711 ((guchar
*) &int1
) + 2,
712 ((guchar
*) &int1
) + 3);
713 gimp_rgba_get_uchar (rgb2
,
714 ((guchar
*) &int2
) + 0,
715 ((guchar
*) &int2
) + 1,
716 ((guchar
*) &int2
) + 2,
717 ((guchar
*) &int2
) + 3);
721 gimp_rgb_get_uchar (rgb1
,
722 ((guchar
*) &int1
) + 0,
723 ((guchar
*) &int1
) + 1,
724 ((guchar
*) &int1
) + 2);
725 gimp_rgb_get_uchar (rgb2
,
726 ((guchar
*) &int2
) + 0,
727 ((guchar
*) &int2
) + 1,
728 ((guchar
*) &int2
) + 2);
736 * gimp_param_spec_rgb:
737 * @name: Canonical name of the param
738 * @nick: Nickname of the param
739 * @blurb: Brief description of param.
740 * @has_alpha: %TRUE if the alpha channel has relevance.
741 * @default_value: Value to use if none is assigned.
742 * @flags: a combination of #GParamFlags
744 * Creates a param spec to hold an #GimpRGB value.
745 * See g_param_spec_internal() for more information.
747 * Returns: a newly allocated #GParamSpec instance
752 gimp_param_spec_rgb (const gchar
*name
,
756 const GimpRGB
*default_value
,
759 GimpParamSpecRGB
*cspec
;
761 cspec
= g_param_spec_internal (GIMP_TYPE_PARAM_RGB
,
762 name
, nick
, blurb
, flags
);
764 cspec
->has_alpha
= has_alpha
;
767 cspec
->default_value
= *default_value
;
769 return G_PARAM_SPEC (cspec
);
773 * gimp_param_spec_rgb_has_alpha:
774 * @pspec: a #GParamSpec to hold an #GimpRGB value.
776 * Returns: %TRUE if the alpha channel is relevant.
781 gimp_param_spec_rgb_has_alpha (GParamSpec
*pspec
)
783 g_return_val_if_fail (GIMP_IS_PARAM_SPEC_RGB (pspec
), FALSE
);
785 return GIMP_PARAM_SPEC_RGB (pspec
)->has_alpha
;