Commit 70c1ecfd authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann

added GimpHSV type and functions and gimp_rgb_composite functions

2001-01-14  Sven Neumann  <sven@gimp.org>

	* libgimp/gimpcolor.[ch]: added GimpHSV type and functions and
	gimp_rgb_composite functions

	* libgimp/gimpcolorbutton.c: indentation

	* libgimp/gimpcolorspace.[ch]: added GimpRGB <-> GimpHSV conversion
	routines

	* libgimp/gimpwidgets.[ch]: removed gimp_color_update_uchar function

	* plug-ins/Lighting/lighting_main.[ch]
	* plug-ins/Lighting/lighting_preview.c
	* plug-ins/Lighting/lighting_shade.c
	* plug-ins/MapObject/mapobject_image.c
	* plug-ins/MapObject/mapobject_main.[ch]
	* plug-ins/MapObject/mapobject_shade.c
	* plug-ins/common/mapcolor.c
	* plug-ins/common/nova.c
	* plug-ins/common/papertile.c
	* plug-ins/common/sinus.c
	* plug-ins/ifscompose/ifscompose.c
	* plug-ins/script-fu/script-fu-scripts.c: use GimpRGB and GimpHSV
parent f504187d
2001-01-14 Sven Neumann <sven@gimp.org>
* libgimp/gimpcolor.[ch]: added GimpHSV type and functions and
gimp_rgb_composite functions
* libgimp/gimpcolorbutton.c: indentation
* libgimp/gimpcolorspace.[ch]: added GimpRGB <-> GimpHSV conversion
routines
* libgimp/gimpwidgets.[ch]: removed gimp_color_update_uchar function
* plug-ins/Lighting/lighting_main.[ch]
* plug-ins/Lighting/lighting_preview.c
* plug-ins/Lighting/lighting_shade.c
* plug-ins/MapObject/mapobject_image.c
* plug-ins/MapObject/mapobject_main.[ch]
* plug-ins/MapObject/mapobject_shade.c
* plug-ins/common/mapcolor.c
* plug-ins/common/nova.c
* plug-ins/common/papertile.c
* plug-ins/common/sinus.c
* plug-ins/ifscompose/ifscompose.c
* plug-ins/script-fu/script-fu-scripts.c: use GimpRGB and GimpHSV
2001-01-14 Michael Natterer <mitch@gimp.org>
* app/channel.[ch]
......
......@@ -46,6 +46,15 @@ gimp_rgb_set (GimpRGB *rgb,
rgb->b = b;
}
void
gimp_rgb_set_alpha (GimpRGB *rgb,
gdouble a)
{
g_return_if_fail (rgb != NULL);
rgb->a = a;
}
void
gimp_rgb_set_uchar (GimpRGB *rgb,
guchar r,
......@@ -143,6 +152,7 @@ gimp_rgb_clamp (GimpRGB *rgb)
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
......@@ -173,6 +183,41 @@ gimp_rgb_intensity (const GimpRGB *rgb)
INTENSITY_BLUE * rgb->b);
}
void
gimp_rgb_composite (GimpRGB *color1,
const GimpRGB *color2,
GimpRGBCompositeMode mode)
{
gdouble factor;
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 */
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 */
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 */
void
......@@ -269,55 +314,52 @@ gimp_rgba_distance (const GimpRGB *rgba1,
fabs (rgba1->b - rgba2->b) + fabs (rgba1->a - rgba2->a));
}
/* These two are probably not needed */
gdouble
gimp_rgba_max (const GimpRGB *rgba)
{
g_return_val_if_fail (rgba != NULL, 0.0);
return MAX (rgba->r, MAX (rgba->g, MAX (rgba->b, rgba->a)));
}
/* HSV functions */
gdouble
gimp_rgba_min (const GimpRGB *rgba)
void
gimp_hsv_set (GimpHSV *hsv,
gdouble h,
gdouble s,
gdouble v)
{
g_return_val_if_fail (rgba != NULL, 0.0);
g_return_if_fail (hsv != NULL);
return MIN (rgba->r, MIN (rgba->g, MIN (rgba->b, rgba->a)));
hsv->h = h;
hsv->s = s;
hsv->v = v;
}
void
gimp_rgba_clamp (GimpRGB *rgba)
gimp_hsv_clamp (GimpHSV *hsv)
{
g_return_if_fail (rgba != NULL);
g_return_if_fail (hsv != NULL);
rgba->r = CLAMP (rgba->r, 0.0, 1.0);
rgba->g = CLAMP (rgba->g, 0.0, 1.0);
rgba->b = CLAMP (rgba->b, 0.0, 1.0);
rgba->a = CLAMP (rgba->a, 0.0, 1.0);
if (hsv->h < 0.0)
hsv->h = GIMP_HSV_UNDEFINED;
hsv->h -= (gint) hsv->h;
hsv->s = CLAMP (hsv->s, 0.0, 1.0);
hsv->v = CLAMP (hsv->v, 0.0, 1.0);
hsv->a = CLAMP (hsv->a, 0.0, 1.0);
}
void
gimp_rgba_gamma (GimpRGB *rgba,
gdouble gamma)
gimp_hsva_set (GimpHSV *hsva,
gdouble h,
gdouble s,
gdouble v,
gdouble a)
{
gdouble ig;
g_return_if_fail (rgba != NULL);
if (gamma != 0.0)
ig = 1.0 / gamma;
else
(ig = 0.0);
g_return_if_fail (hsva != NULL);
rgba->r = pow (rgba->r, ig);
rgba->g = pow (rgba->g, ig);
rgba->b = pow (rgba->b, ig);
rgba->a = pow (rgba->a, ig);
hsva->h = h;
hsva->s = s;
hsva->v = v;
hsva->a = a;
}
/* These functions will become the default one day */
gboolean
......@@ -348,3 +390,30 @@ gimp_palette_get_foreground_rgb (GimpRGB *rgb)
return FALSE;
}
gboolean
gimp_palette_set_background_rgb (const GimpRGB *rgb)
{
guchar r, g, b;
g_return_val_if_fail (rgb != NULL, FALSE);
gimp_rgb_get_uchar (rgb, &r, &g, &b);
return gimp_palette_set_background (r, g, b);
}
gboolean
gimp_palette_get_background_rgb (GimpRGB *rgb)
{
guchar r, g, b;
g_return_val_if_fail (rgb != NULL, FALSE);
if (gimp_palette_get_background (&r, &g, &b))
{
gimp_rgb_set_uchar (rgb, r, g, b);
return TRUE;
}
return FALSE;
}
......@@ -36,11 +36,27 @@ struct _GimpRGB
gdouble r, g, b, a;
};
typedef struct _GimpHSV GimpHSV;
struct _GimpHSV
{
gdouble h, s, v, a;
};
typedef enum
{
GIMP_RGB_COMPOSITE_NONE = 0,
GIMP_RGB_COMPOSITE_NORMAL,
GIMP_RGB_COMPOSITE_BEHIND
} GimpRGBCompositeMode;
void gimp_rgb_set (GimpRGB *rgb,
gdouble r,
gdouble g,
gdouble b);
void gimp_rgb_set_alpha (GimpRGB *rgb,
gdouble a);
void gimp_rgb_set_uchar (GimpRGB *rgb,
guchar r,
guchar g,
......@@ -65,6 +81,9 @@ void gimp_rgb_gamma (GimpRGB *rgb,
gdouble gamma);
gdouble gimp_rgb_intensity (const GimpRGB *rgb);
void gimp_rgb_composite (GimpRGB *color1,
const GimpRGB *color2,
GimpRGBCompositeMode mode);
void gimp_rgba_set (GimpRGB *rgba,
gdouble r,
......@@ -90,17 +109,25 @@ void gimp_rgba_multiply (GimpRGB *rgba,
gdouble factor);
gdouble gimp_rgba_distance (const GimpRGB *rgba1,
const GimpRGB *rgba2);
gdouble gimp_rgba_max (const GimpRGB *rgba);
gdouble gimp_rgba_min (const GimpRGB *rgba);
void gimp_rgba_clamp (GimpRGB *rgba);
void gimp_rgba_gamma (GimpRGB *rgba,
gdouble gamma);
void gimp_hsv_set (GimpHSV *hsv,
gdouble h,
gdouble s,
gdouble v);
void gimp_hsv_clamp (GimpHSV *hsv);
void gimp_hsva_set (GimpHSV *hsva,
gdouble h,
gdouble s,
gdouble v,
gdouble a);
/* These will become the default one day */
/* These will become the default one day */
gboolean gimp_palette_set_foreground_rgb (const GimpRGB *rgb);
gboolean gimp_palette_get_foreground_rgb (GimpRGB *rgb);
gboolean gimp_palette_set_background_rgb (const GimpRGB *rgb);
gboolean gimp_palette_get_background_rgb (GimpRGB *rgb);
#ifdef __cplusplus
......
......@@ -46,31 +46,31 @@ struct _GimpColorButton
};
static void gimp_color_button_destroy (GtkObject *object);
static void gimp_color_button_clicked (GtkButton *button);
static void gimp_color_button_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void gimp_color_button_dialog_ok (GtkWidget *widget,
gpointer data);
static void gimp_color_button_dialog_cancel (GtkWidget *widget,
gpointer data);
static void gimp_color_button_use_fg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static void gimp_color_button_use_bg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static gint gimp_color_button_menu_popup (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gchar * gimp_color_button_menu_translate (const gchar *path,
gpointer func_data);
static void gimp_color_button_color_changed (GtkObject *object,
gpointer data);
static void gimp_color_button_destroy (GtkObject *object);
static void gimp_color_button_clicked (GtkButton *button);
static void gimp_color_button_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void gimp_color_button_dialog_ok (GtkWidget *widget,
gpointer data);
static void gimp_color_button_dialog_cancel (GtkWidget *widget,
gpointer data);
static void gimp_color_button_use_fg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static void gimp_color_button_use_bg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static gint gimp_color_button_menu_popup (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gchar * gimp_color_button_menu_translate (const gchar *path,
gpointer func_data);
static void gimp_color_button_color_changed (GtkObject *object,
gpointer data);
static GtkItemFactoryEntry menu_items[] =
......
......@@ -33,125 +33,118 @@
void
gimp_rgb_to_hsv (GimpRGB *rgb,
gdouble *hue,
gdouble *saturation,
gdouble *value)
GimpHSV *hsv)
{
gdouble max, min, delta;
g_return_if_fail (rgb != NULL);
g_return_if_fail (hue != NULL);
g_return_if_fail (saturation != NULL);
g_return_if_fail (value != NULL);
g_return_if_fail (hsv != NULL);
max = gimp_rgb_max (rgb);
min = gimp_rgb_min (rgb);
*value = max;
if (max != 0.0)
{
*saturation = (max - min) / max;
}
else
{
*saturation = 0.0;
}
hsv->v = max;
if (*saturation == 0.0)
{
*hue = GIMP_HSV_UNDEFINED;
}
else
if (max != 0.0)
{
delta = max - min;
hsv->s = delta / max;
if (rgb->r == max)
{
*hue = (rgb->g - rgb->b) / delta;
hsv->h = (rgb->g - rgb->b) / delta;
}
else if (rgb->g == max)
{
*hue = 2.0 + (rgb->b - rgb->r) / delta;
hsv->h = 2.0 + (rgb->b - rgb->r) / delta;
}
else if (rgb->b == max)
{
*hue = 4.0 + (rgb->r - rgb->g) / delta;
hsv->h = 4.0 + (rgb->r - rgb->g) / delta;
}
*hue = *hue * 60.0;
hsv->h /= 6.0;
if (*hue < 0.0)
*hue = *hue + 360;
if (hsv->h < 0.0)
hsv->h += 1.0;
else if (hsv->h > 1.0)
hsv->h -= 1.0;
}
else
{
hsv->s = 0.0;
hsv->h = GIMP_HSV_UNDEFINED;
}
hsv->a = rgb->a;
}
void
gimp_hsv_to_rgb (gdouble hue,
gdouble saturation,
gdouble value,
gimp_hsv_to_rgb (GimpHSV *hsv,
GimpRGB *rgb)
{
gint i;
gdouble f, w, q, t;
g_return_if_fail (rgb != NULL);
g_return_if_fail (hsv != NULL);
if (saturation == 0.0)
if (hsv->s == 0.0 || hsv->h == GIMP_HSV_UNDEFINED)
{
if (hue == GIMP_HSV_UNDEFINED)
{
rgb->r = value;
rgb->g = value;
rgb->b = value;
}
rgb->r = hsv->v;
rgb->g = hsv->v;
rgb->b = hsv->v;
}
else
{
if (hue == 360.0)
hue = 0.0;
if (hsv->h == 1.0)
hsv->h = 0.0;
hue = hue / 60.0;
hsv->h *= 6.0;
i = (gint) hue;
f = hue - i;
w = value * (1.0 - saturation);
q = value * (1.0 - (saturation * f));
t = value * (1.0 - (saturation * (1.0 - f)));
i = (gint) hsv->h;
f = hsv->h - i;
w = hsv->v * (1.0 - hsv->s);
q = hsv->v * (1.0 - (hsv->s * f));
t = hsv->v * (1.0 - (hsv->s * (1.0 - f)));
switch (i)
{
case 0:
rgb->r = value;
rgb->r = hsv->v;
rgb->g = t;
rgb->b = w;
break;
case 1:
rgb->r = q;
rgb->g = value;
rgb->g = hsv->v;
rgb->b = w;
break;
case 2:
rgb->r = w;
rgb->g = value;
rgb->g = hsv->v;
rgb->b = t;
break;
case 3:
rgb->r = w;
rgb->g = q;
rgb->b = value;
rgb->b = hsv->v;
break;
case 4:
rgb->r = t;
rgb->g = w;
rgb->b = value;
rgb->b = hsv->v;
break;
case 5:
rgb->r = value;
rgb->r = hsv->v;
rgb->g = w;
rgb->b = q;
break;
}
}
rgb->a = hsv->a;
}
void
......
......@@ -36,18 +36,16 @@ extern "C" {
#define GIMP_HSL_UNDEFINED -1.0
void gimp_rgb_to_hsv (GimpRGB *rgb,
gdouble *hue,
gdouble *saturation,
gdouble *value);
GimpHSV *hsv);
void gimp_rgb_to_hsl (GimpRGB *rgb,
gdouble *hue,
gdouble *saturation,
gdouble *lightness);
void gimp_hsv_to_rgb (gdouble hue,
gdouble saturation,
gdouble value,
void gimp_hsv_to_rgb (GimpHSV *hsv,
GimpRGB *rgb);
void gimp_hsl_to_rgb (gdouble hue,
gdouble saturation,
gdouble lightness,
......
......@@ -27,8 +27,6 @@
#include "gimptypes.h"
#include "gimpuitypes.h"
#include "gimpcolorarea.h"
#include "gimpcolorbutton.h"
#include "gimpchainbutton.h"
#include "gimphelpui.h"
#include "gimppixmap.h"
......@@ -1339,50 +1337,6 @@ gimp_unit_menu_update (GtkWidget *widget,
}
}
/**
* gimp_color_update:
* @widget: A pointer to a #GimpColorArea or #GimpColorButton.
* @data: A pointer to an array of #guchar that will be set to the new color.
*
* This function will go away.
**/
void
gimp_color_update_uchar (GtkWidget *widget,
gpointer data)
{
GimpRGB color;
gboolean alpha;
guchar *dest;
g_return_if_fail (widget != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_COLOR_AREA (widget) ||
GIMP_IS_COLOR_BUTTON (widget));
if (GIMP_IS_COLOR_AREA (widget))
{
gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &color);
alpha = gimp_color_area_has_alpha (GIMP_COLOR_AREA (widget));
}
else if (GIMP_IS_COLOR_BUTTON (widget))
{
gimp_color_button_get_color (GIMP_COLOR_BUTTON (widget), &color);
alpha = gimp_color_button_has_alpha (GIMP_COLOR_BUTTON (widget));
}
else
return;
dest = (guchar *) data;
*dest++ = color.r * 255.999;
*dest++ = color.g * 255.999;
*dest++ = color.b * 255.999;
if (alpha)
*dest++ = color.a * 255.999;
}
/*
* Helper Functions
......
......@@ -227,8 +227,6 @@ void gimp_double_adjustment_update (GtkAdjustment *adjustment,
void gimp_unit_menu_update (GtkWidget *widget,
gpointer data);
void gimp_color_update_uchar (GtkWidget *widget,
gpointer data);
/*
* Helper Functions
......
......@@ -46,31 +46,31 @@ struct _GimpColorButton
};
static void gimp_color_button_destroy (GtkObject *object);
static void gimp_color_button_clicked (GtkButton *button);
static void gimp_color_button_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void gimp_color_button_dialog_ok (GtkWidget *widget,
gpointer data);
static void gimp_color_button_dialog_cancel (GtkWidget *widget,
gpointer data);
static void gimp_color_button_use_fg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static void gimp_color_button_use_bg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static gint gimp_color_button_menu_popup (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gchar * gimp_color_button_menu_translate (const gchar *path,
gpointer func_data);
static void gimp_color_button_color_changed (GtkObject *object,
gpointer data);
static void gimp_color_button_destroy (GtkObject *object);
static void gimp_color_button_clicked (GtkButton *button);
static void gimp_color_button_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void gimp_color_button_dialog_ok (GtkWidget *widget,
gpointer data);
static void gimp_color_button_dialog_cancel (GtkWidget *widget,
gpointer data);
static void gimp_color_button_use_fg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static void gimp_color_button_use_bg (gpointer callback_data,
guint callback_action,
GtkWidget *widget);
static gint gimp_color_button_menu_popup (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gchar * gimp_color_button_menu_translate (const gchar *path,
gpointer func_data);
static void gimp_color_button_color_changed (GtkObject *object,
gpointer data);
static GtkItemFactoryEntry menu_items[] =
......
......@@ -27,8 +27,6 @@
#include "gimptypes.h"
#include "gimpuitypes.h"
#include "gimpcolorarea.h"
#include "gimpcolorbutton.h"
#include "gimpchainbutton.h"
#include "gimphelpui.h"
#include "gimppixmap.h"
......@@ -1339,50 +1337,6 @@ gimp_unit_menu_update (GtkWidget *widget,
}
}
/**
* gimp_color_update:
* @widget: A pointer to a #GimpColorArea or #GimpColorButton.
* @data: A pointer to an array of #guchar that will be set to the new color.
*
* This function will go away.
**/
void
gimp_color_update_uchar (GtkWidget *widget,
gpointer data)
{
GimpRGB color;
gboolean alpha;
guchar *dest;
g_return_if_fail (widget != NULL);
g_return_if_fail (data != NULL);
g_return_if_fail (GIMP_IS_COLOR_AREA (widget) ||
GIMP_IS_COLOR_BUTTON (widget));
if (GIMP_IS_COLOR_AREA (widget))
{
gimp_color_area_get_color (GIMP_COLOR_AREA (widget), &color);
alpha = gimp_color_area_has_alpha (GIMP_COLOR_AREA (widget));
}
else if (GIMP_IS_COLOR_BUTTON (widget))
{
gimp_color_button_get_color (GIMP_COLOR_BUTTON (widget), &color);
alpha = gimp_color_button_has_alpha (GIMP_COLOR_BUTTON (widget));
}
else
return;
dest = (guchar *) data;
*dest++ = color.r * 255.999;
*dest++ = color.g * 255.999;
*dest++ = color.b * 255.999;
if (alpha)
*dest++ = color.a * 255.999;
}
/*
* Helper Functions
......
......@@ -227,8 +227,6 @@ void gimp_double_adjustment_update (GtkAdjustment *adjustment,
void gimp_unit_menu_update (GtkWidget *widget,
gpointer data);