Gimp/app/base/hue-saturation.c
Michael Natterer 163a3f4155 More color correction stuff cleanup:
2002-09-04  Michael Natterer  <mitch@gimp.org>

	More color correction stuff cleanup:

	* app/base/Makefile.am
	* app/base/base-types.h
	* app/base/levels.[ch]: new files containing levels_lut_func(), a
	new "Levels" parameter struct and the "auto levels" stuff.

	* app/base/lut-funcs.[ch]: removed the levels stuff here, added
	lots of g_return_if_fail().

	* app/base/color-balance.[ch]
	* app/base/hue-saturation.[ch]: added init() and reset() functions
	so we don't need to duplicate this code in the tool and the pdb
	wrappers.

	* app/base/curves.[ch]: s/gint/GimpHistogramChannel/g, made
	curves_channel_reset() initialize the curves array.

	* app/tools/gimpcolorbalancetool.[ch]: use the new functions,
	moved the "Range" frame to the top, added a per-range "Reset"
	button, made the global "Reset" button reset all ranges and
	the "Preserve Luminosity" toggle.

	* app/tools/gimpcurvestool.[ch]: don't initialize the curves
	array manually, as curves_channel_reset() does that,
	s/gint/GimpHistogramChannel/g.

	* app/tools/gimphuesaturationtool.c: use the new functions, added
	a per-channel "Reset" button and made the global "Reset" button
	reset all channels, cleaned up the GUI update function.

	* app/tools/gimplevelstool.[ch]: changed to use the new Levels
	parameter struct and it's utility functions. Removed stuff
	which now lives in base/levels.c

	* app/tools/gimpimagemaptool.c: align the "Preview" button
	bottom-left, not bottom-right.

	* tools/pdbgen/pdb/color.pdb: use the new stuff and removed
	uglyness because using the "Levels" struct makes the code more
	straightforward.

	* app/pdb/color_cmds.c: regenerated.
2002-09-04 15:25:15 +00:00

166 lines
4.1 KiB
C

/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpmath/gimpmath.h"
#include "base-types.h"
#include "hue-saturation.h"
#include "pixel-region.h"
void
hue_saturation_init (HueSaturation *hs)
{
GimpHueRange partition;
g_return_if_fail (hs != NULL);
for (partition = GIMP_ALL_HUES; partition <= GIMP_MAGENTA_HUES; partition++)
hue_saturation_partition_reset (hs, partition);
}
void
hue_saturation_partition_reset (HueSaturation *hs,
GimpHueRange partition)
{
g_return_if_fail (hs != NULL);
hs->hue[partition] = 0.0;
hs->lightness[partition] = 0.0;
hs->saturation[partition] = 0.0;
}
void
hue_saturation_calculate_transfers (HueSaturation *hs)
{
gint value;
gint hue;
gint i;
g_return_if_fail (hs != NULL);
/* Calculate transfers */
for (hue = 0; hue < 6; hue++)
for (i = 0; i < 256; i++)
{
value = (hs->hue[0] + hs->hue[hue + 1]) * 255.0 / 360.0;
if ((i + value) < 0)
hs->hue_transfer[hue][i] = 255 + (i + value);
else if ((i + value) > 255)
hs->hue_transfer[hue][i] = i + value - 255;
else
hs->hue_transfer[hue][i] = i + value;
/* Lightness */
value = (hs->lightness[0] + hs->lightness[hue + 1]) * 127.0 / 100.0;
value = CLAMP (value, -255, 255);
if (value < 0)
hs->lightness_transfer[hue][i] = (unsigned char) ((i * (255 + value)) / 255);
else
hs->lightness_transfer[hue][i] = (unsigned char) (i + ((255 - i) * value) / 255);
/* Saturation */
value = (hs->saturation[0] + hs->saturation[hue + 1]) * 255.0 / 100.0;
value = CLAMP (value, -255, 255);
/* This change affects the way saturation is computed. With the
old code (different code for value < 0), increasing the
saturation affected muted colors very much, and bright colors
less. With the new code, it affects muted colors and bright
colors more or less evenly. For enhancing the color in photos,
the new behavior is exactly what you want. It's hard for me
to imagine a case in which the old behavior is better.
*/
hs->saturation_transfer[hue][i] = CLAMP ((i * (255 + value)) / 255, 0, 255);
}
}
void
hue_saturation (PixelRegion *srcPR,
PixelRegion *destPR,
gpointer data)
{
HueSaturation *hs;
guchar *src, *s;
guchar *dest, *d;
gint alpha;
gint w, h;
gint r, g, b;
gint hue;
hs = (HueSaturation *) data;
/* Set the transfer arrays (for speed) */
h = srcPR->h;
src = srcPR->data;
dest = destPR->data;
alpha = (srcPR->bytes == 4) ? TRUE : FALSE;
while (h--)
{
w = srcPR->w;
s = src;
d = dest;
while (w--)
{
r = s[RED_PIX];
g = s[GREEN_PIX];
b = s[BLUE_PIX];
gimp_rgb_to_hls_int (&r, &g, &b);
if (r < 43)
hue = 0;
else if (r < 85)
hue = 1;
else if (r < 128)
hue = 2;
else if (r < 171)
hue = 3;
else if (r < 213)
hue = 4;
else
hue = 5;
r = hs->hue_transfer[hue][r];
g = hs->lightness_transfer[hue][g];
b = hs->saturation_transfer[hue][b];
gimp_hls_to_rgb_int (&r, &g, &b);
d[RED_PIX] = r;
d[GREEN_PIX] = g;
d[BLUE_PIX] = b;
if (alpha)
d[ALPHA_PIX] = s[ALPHA_PIX];
s += srcPR->bytes;
d += destPR->bytes;
}
src += srcPR->rowstride;
dest += destPR->rowstride;
}
}