app/gimphistogram.[ch] removed.

2001-05-23  Michael Natterer  <mitch@gimp.org>

	* app/gimphistogram.[ch]
	* app/lut_funcs.[ch]: removed.

	* app/base/gimphistogram.[ch]
	* app/base/lut-funcs.[ch]
	* app/core/gimpdrawable-histogram.[ch]: added, cleanup.

	* app/Makefile.am
	* app/appenums.h
	* app/apptypes.h
	* app/base/Makefile.am
	* app/base/base-types.h
	* app/core/Makefile.am
	* app/core/gimpchannel.c
	* app/core/gimpdrawable-equalize.c
	* app/core/gimpdrawable-invert.c
	* app/pdb/color_cmds.c
	* app/widgets/gimphistogramview.c
	* tools/pdbgen/Makefile.am
	* tools/pdbgen/enums.pl
	* tools/pdbgen/pdb/color.pdb: changed accordingly.
This commit is contained in:
Michael Natterer 2001-05-22 23:05:35 +00:00 committed by Michael Natterer
parent 884f6a8bd7
commit 0196e83f8d
26 changed files with 549 additions and 1398 deletions

View File

@ -1,3 +1,27 @@
2001-05-23 Michael Natterer <mitch@gimp.org>
* app/gimphistogram.[ch]
* app/lut_funcs.[ch]: removed.
* app/base/gimphistogram.[ch]
* app/base/lut-funcs.[ch]
* app/core/gimpdrawable-histogram.[ch]: added, cleanup.
* app/Makefile.am
* app/appenums.h
* app/apptypes.h
* app/base/Makefile.am
* app/base/base-types.h
* app/core/Makefile.am
* app/core/gimpchannel.c
* app/core/gimpdrawable-equalize.c
* app/core/gimpdrawable-invert.c
* app/pdb/color_cmds.c
* app/widgets/gimphistogramview.c
* tools/pdbgen/Makefile.am
* tools/pdbgen/enums.pl
* tools/pdbgen/pdb/color.pdb: changed accordingly.
2001-05-22 Michael Natterer <mitch@gimp.org>
* app/Makefile.am

View File

@ -89,8 +89,6 @@ gimp_SOURCES = \
datafiles.h \
floating_sel.c \
floating_sel.h \
gimphistogram.c \
gimphistogram.h \
gimppreviewcache.h \
gimppreviewcache.c \
parasitelist.c \
@ -138,8 +136,6 @@ gimp_SOURCES = \
image_new.h \
libgimp_glue.c \
libgimp_glue.h \
lut_funcs.c \
lut_funcs.h \
main.c \
path.c \
path.h \

View File

@ -119,14 +119,5 @@ typedef enum /*< skip >*/
CURSOR_MODE_CROSSHAIR
} CursorMode;
typedef enum /*< skip >*/
{
GIMP_HISTOGRAM_VALUE = 0,
GIMP_HISTOGRAM_RED = 1,
GIMP_HISTOGRAM_GREEN = 2,
GIMP_HISTOGRAM_BLUE = 3,
GIMP_HISTOGRAM_ALPHA = 4
} GimpHistogramChannel;
#endif /* __APPENUMS_H__ */

View File

@ -39,8 +39,6 @@ typedef struct _ColorNotebook ColorNotebook;
typedef struct _GDisplay GDisplay;
typedef struct _GimpHistogram GimpHistogram;
typedef struct _GimpImageNewValues GimpImageNewValues;
typedef struct _GimpProgress GimpProgress;

View File

@ -12,8 +12,12 @@ libappbase_la_SOURCES = \
boundary.h \
brush-scale.c \
brush-scale.h \
gimphistogram.c \
gimphistogram.h \
gimplut.c \
gimplut.h \
lut-funcs.c \
lut-funcs.h \
pixel-processor.c \
pixel-processor.h \
pixel-region.c \

View File

@ -78,6 +78,16 @@ typedef enum
NEAREST_NEIGHBOR_INTERPOLATION
} InterpolationType;
typedef enum
{
VALUE_LUT,
RED_LUT,
GREEN_LUT,
BLUE_LUT,
ALPHA_LUT,
GRAY_LUT = 0 /*< skip >*/
} ChannelLutType;
/* Transparency representation */
typedef enum /*< skip >*/
{
@ -96,11 +106,21 @@ typedef enum /*< skip >*/
LARGE_CHECKS = 2
} GimpCheckSize;
typedef enum /*< skip >*/
{
GIMP_HISTOGRAM_VALUE = 0,
GIMP_HISTOGRAM_RED = 1,
GIMP_HISTOGRAM_GREEN = 2,
GIMP_HISTOGRAM_BLUE = 3,
GIMP_HISTOGRAM_ALPHA = 4
} GimpHistogramChannel;
/* types */
typedef struct _BoundSeg BoundSeg;
typedef struct _GimpHistogram GimpHistogram;
typedef struct _GimpLut GimpLut;
typedef struct _PixelRegionIterator PixelRegionIterator;

View File

@ -24,20 +24,15 @@
#include <pthread.h>
#endif /* ENABLE_MP */
#include <gtk/gtk.h>
#include <glib.h>
#include "libgimpmath/gimpmath.h"
#include "core/core-types.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "base-types.h"
#include "gimphistogram.h"
#include "gimprc.h"
#include "pixel-processor.h"
#include "pixel-region.h"
struct _GimpHistogram
@ -347,40 +342,6 @@ gimp_histogram_calculate (GimpHistogram *histogram,
#endif
}
void
gimp_histogram_calculate_drawable (GimpHistogram *histogram,
GimpDrawable *drawable)
{
PixelRegion region;
PixelRegion mask;
gint x1, y1, x2, y2;
gint off_x, off_y;
gboolean no_mask;
no_mask = (gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&region, gimp_drawable_data (drawable), x1, y1,
(x2 - x1), (y2 - y1), FALSE);
if (!no_mask)
{
GimpChannel *sel_mask;
GimpImage *gimage;
gimage = gimp_drawable_gimage (drawable);
sel_mask = gimp_image_get_mask (gimage);
gimp_drawable_offsets (drawable, &off_x, &off_y);
pixel_region_init (&mask, gimp_drawable_data (GIMP_DRAWABLE (sel_mask)),
x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
gimp_histogram_calculate (histogram, &region, &mask);
}
else
{
gimp_histogram_calculate (histogram, &region, NULL);
}
}
gdouble
gimp_histogram_get_maximum (GimpHistogram *histogram,
GimpHistogramChannel channel)

View File

@ -24,11 +24,11 @@
GimpHistogram * gimp_histogram_new (void);
void gimp_histogram_free (GimpHistogram *histogram);
void gimp_histogram_calculate (GimpHistogram *historgam,
PixelRegion *region,
PixelRegion *mask);
void gimp_histogram_calculate_drawable (GimpHistogram *histogram,
GimpDrawable *drawable);
gdouble gimp_histogram_get_maximum (GimpHistogram *histogram,
GimpHistogramChannel channel);
gdouble gimp_histogram_get_count (GimpHistogram *histogram,

View File

@ -24,27 +24,29 @@
#include "libgimpmath/gimpmath.h"
#include "core/core-types.h"
#include "base/gimplut.h"
#include "base-types.h"
#include "gimphistogram.h"
#include "gimplut.h"
#include "lut-funcs.h"
/* ---------- Brightness/Contrast -----------*/
typedef struct B_C_struct
{
double brightness;
double contrast;
gdouble brightness;
gdouble contrast;
} B_C_struct;
static float
brightness_contrast_lut_func(B_C_struct *data,
int nchannels, int channel, float value)
static gfloat
brightness_contrast_lut_func (B_C_struct *data,
gint nchannels,
gint channel,
gfloat value)
{
float nvalue;
double power;
gfloat nvalue;
gdouble power;
/* return the original value for the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
@ -58,273 +60,344 @@ brightness_contrast_lut_func(B_C_struct *data,
/* apply contrast */
if (data->contrast < 0.0)
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + data->contrast));
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + data->contrast));
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
else
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
power = (data->contrast == 1.0) ? 127 : 1.0 / (1.0 - data->contrast);
nvalue = 0.5 * pow (2.0 * nvalue, power);
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
power = (data->contrast == 1.0) ? 127 : 1.0 / (1.0 - data->contrast);
nvalue = 0.5 * pow (2.0 * nvalue, power);
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
return value;
}
void
brightness_contrast_lut_setup(GimpLut *lut, double brightness, double contrast,
int nchannels)
{
B_C_struct data;
data.brightness = brightness;
data.contrast = contrast;
gimp_lut_setup(lut, (GimpLutFunc) brightness_contrast_lut_func,
(void *) &data, nchannels);
}
GimpLut *
brightness_contrast_lut_new(double brightness, double contrast,
int nchannels)
brightness_contrast_lut_new (gdouble brightness,
gdouble contrast,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
brightness_contrast_lut_setup(lut, brightness, contrast, nchannels);
lut = gimp_lut_new ();
brightness_contrast_lut_setup (lut, brightness, contrast, n_channels);
return lut;
}
void
brightness_contrast_lut_setup (GimpLut *lut,
gdouble brightness,
gdouble contrast,
gint n_channels)
{
B_C_struct data;
data.brightness = brightness;
data.contrast = contrast;
gimp_lut_setup (lut, (GimpLutFunc) brightness_contrast_lut_func,
(gpointer) &data, n_channels);
}
/* ---------------- invert ------------------ */
static float
invert_lut_func(void *unused,
int nchannels, int channel, float value)
static gfloat
invert_lut_func (gpointer unused,
gint n_channels,
gint channel,
gfloat value)
{
/* don't invert the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
if ((n_channels == 2 || n_channels == 4) && channel == n_channels -1)
return value;
return 1.0 - value;
}
void
invert_lut_setup(GimpLut *lut, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) invert_lut_func,
NULL , nchannels);
}
GimpLut *
invert_lut_new(int nchannels)
invert_lut_new (gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
invert_lut_setup(lut, nchannels);
lut = gimp_lut_new ();
invert_lut_setup (lut, n_channels);
return lut;
}
void
invert_lut_setup (GimpLut *lut,
gint n_channels)
{
gimp_lut_setup_exact (lut, (GimpLutFunc) invert_lut_func,
NULL , n_channels);
}
/* ---------------- add (or subract)------------------ */
static float
add_lut_func(double *ammount,
int nchannels, int channel, float value)
static gfloat
add_lut_func (gdouble *amount,
gint n_channels,
gint channel,
gfloat value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
if ((n_channels == 2 || n_channels == 4) && channel == n_channels -1)
return value;
return (value + *ammount);
}
void
add_lut_setup(GimpLut *lut, double ammount, int nchannels)
{
gimp_lut_setup(lut, (GimpLutFunc) add_lut_func,
(void *) &ammount , nchannels);
return (value + *amount);
}
GimpLut *
add_lut_new(double ammount, int nchannels)
add_lut_new (gdouble amount,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
add_lut_setup(lut, ammount, nchannels);
lut = gimp_lut_new ();
add_lut_setup (lut, amount, n_channels);
return lut;
}
void
add_lut_setup (GimpLut *lut,
gdouble amount,
gint n_channels)
{
gimp_lut_setup (lut, (GimpLutFunc) add_lut_func,
(gpointer) &amount, n_channels);
}
/* ---------------- intersect (MIN (pixel, value)) ------------------ */
static float
intersect_lut_func(double *min,
int nchannels, int channel, float value)
static gfloat
intersect_lut_func (gdouble *min,
gint n_channels,
gint channel,
gfloat value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
if ((n_channels == 2 || n_channels == 4) && channel == n_channels -1)
return value;
return MIN (value, *min);
}
void
intersect_lut_setup(GimpLut *lut, double value, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) intersect_lut_func,
(void *) &value , nchannels);
}
GimpLut *
intersect_lut_new(double value, int nchannels)
intersect_lut_new (gdouble value,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
intersect_lut_setup(lut, value, nchannels);
lut = gimp_lut_new ();
intersect_lut_setup (lut, value, n_channels);
return lut;
}
void
intersect_lut_setup (GimpLut *lut,
gdouble value,
gint n_channels)
{
gimp_lut_setup_exact (lut, (GimpLutFunc) intersect_lut_func,
(gpointer) &value , n_channels);
}
/* ---------------- Threshold ------------------ */
static float
threshold_lut_func(double *min,
int nchannels, int channel, float value)
static gfloat
threshold_lut_func (gdouble *min,
gint n_channels,
gint channel,
gfloat value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
if ((n_channels == 2 || n_channels == 4) && channel == n_channels -1)
return value;
if (value < *min)
return 0.0;
return 1.0;
}
void
threshold_lut_setup(GimpLut *lut, double value, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) threshold_lut_func,
(void *) &value , nchannels);
}
GimpLut *
threshold_lut_new(double value, int nchannels)
threshold_lut_new (gdouble value,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
threshold_lut_setup(lut, value, nchannels);
lut = gimp_lut_new ();
threshold_lut_setup (lut, value, n_channels);
return lut;
}
void
threshold_lut_setup (GimpLut *lut,
gdouble value,
gint n_channels)
{
gimp_lut_setup_exact (lut, (GimpLutFunc) threshold_lut_func,
(gpointer) &value , n_channels);
}
/* ------------- levels ------------ */
typedef struct
{
double *gamma;
gdouble *gamma;
int *low_input;
int *high_input;
gint *low_input;
gint *high_input;
int *low_output;
int *high_output;
gint *low_output;
gint *high_output;
} levels_struct;
static float
levels_lut_func(levels_struct *data,
int nchannels, int channel, float value)
static gfloat
levels_lut_func (levels_struct *data,
gint n_channels,
gint channel,
gfloat value)
{
double inten;
int j;
gdouble inten;
gint j;
if (nchannels == 1)
if (n_channels == 1)
j = 0;
else
j = channel + 1;
inten = value;
/* For color images this runs through the loop with j = channel +1
the first time and j = 0 the second time */
/* For bw images this runs through the loop with j = 0 the first and
only time */
* the first time and j = 0 the second time
*
* For bw images this runs through the loop with j = 0 the first and
* only time
*/
for (; j >= 0; j -= (channel + 1))
{
/* don't apply the overall curve to the alpha channel */
if (j == 0 && (nchannels == 2 || nchannels == 4)
&& channel == nchannels -1)
return inten;
{
/* don't apply the overall curve to the alpha channel */
if (j == 0 && (n_channels == 2 || n_channels == 4)
&& channel == n_channels -1)
return inten;
/* determine input intensity */
if (data->high_input[j] != data->low_input[j])
inten = (double) (255.0*inten - data->low_input[j]) /
(double) (data->high_input[j] - data->low_input[j]);
else
inten = (double) (255.0*inten - data->low_input[j]);
/* determine input intensity */
if (data->high_input[j] != data->low_input[j])
inten = ((gdouble) (255.0 * inten - data->low_input[j]) /
(gdouble) (data->high_input[j] - data->low_input[j]));
else
inten = (gdouble) (255.0 * inten - data->low_input[j]);
if (data->gamma[j] != 0.0)
{
if (inten >= 0.0)
inten = pow ( inten, (1.0 / data->gamma[j]));
else
inten = -pow (-inten, (1.0 / data->gamma[j]));
}
if (data->gamma[j] != 0.0)
{
if (inten >= 0.0)
inten = pow ( inten, (1.0 / data->gamma[j]));
else
inten = -pow (-inten, (1.0 / data->gamma[j]));
}
/* determine the output intensity */
if (data->high_output[j] >= data->low_output[j])
inten = (double) (inten * (data->high_output[j] - data->low_output[j]) +
data->low_output[j]);
else if (data->high_output[j] < data->low_output[j])
inten = (double) (data->low_output[j] - inten *
(data->low_output[j] - data->high_output[j]));
/* determine the output intensity */
if (data->high_output[j] >= data->low_output[j])
inten = (gdouble) (inten * (data->high_output[j] - data->low_output[j]) +
data->low_output[j]);
else if (data->high_output[j] < data->low_output[j])
inten = (gdouble) (data->low_output[j] - inten *
(data->low_output[j] - data->high_output[j]));
inten /= 255.0;
}
inten /= 255.0;
}
return inten;
}
void
levels_lut_setup(GimpLut *lut, double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels)
{
levels_struct data;
data.gamma = gamma;
data.low_input = low_input;
data.high_input = high_input;
data.low_output = low_output;
data.high_output = high_output;
gimp_lut_setup(lut, (GimpLutFunc) levels_lut_func,
(void *) &data, nchannels);
}
GimpLut *
levels_lut_new(double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels)
levels_lut_new (gdouble *gamma,
gint *low_input,
gint *high_input,
gint *low_output,
gint *high_output,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
levels_lut_setup(lut, gamma, low_input, high_input,
low_output, high_output, nchannels);
lut = gimp_lut_new ();
levels_lut_setup (lut, gamma, low_input, high_input,
low_output, high_output, n_channels);
return lut;
}
void
levels_lut_setup (GimpLut *lut,
gdouble *gamma,
gint *low_input,
gint *high_input,
gint *low_output,
gint *high_output,
gint n_channels)
{
levels_struct data;
data.gamma = gamma;
data.low_input = low_input;
data.high_input = high_input;
data.low_output = low_output;
data.high_output = high_output;
gimp_lut_setup (lut, (GimpLutFunc) levels_lut_func,
(gpointer) &data, n_channels);
}
/* --------------- posterize ---------------- */
static float
posterize_lut_func(int *ilevels,
int nchannels, int channel, float value)
static gfloat
posterize_lut_func (gint *ilevels,
gint n_channels,
gint channel,
gfloat value)
{
int levels;
gint levels;
/* don't posterize the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
if ((n_channels == 2 || n_channels == 4) && channel == n_channels -1)
return value;
if (*ilevels < 2)
@ -332,79 +405,109 @@ posterize_lut_func(int *ilevels,
else
levels = *ilevels;
value = RINT(value * (levels - 1.0)) / (levels - 1.0);
value = RINT (value * (levels - 1.0)) / (levels - 1.0);
return value;
}
void
posterize_lut_setup(GimpLut *lut, int levels, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) posterize_lut_func,
(void *) &levels , nchannels);
}
GimpLut *
posterize_lut_new(int levels, int nchannels)
posterize_lut_new (gint levels,
gint n_channels)
{
GimpLut *lut;
lut = gimp_lut_new();
posterize_lut_setup(lut, levels, nchannels);
lut = gimp_lut_new ();
posterize_lut_setup (lut, levels, n_channels);
return lut;
}
void
posterize_lut_setup (GimpLut *lut,
gint levels,
gint n_channels)
{
gimp_lut_setup_exact (lut, (GimpLutFunc) posterize_lut_func,
(gpointer) &levels , n_channels);
}
/* --------------- equalize ------------- */
struct hist_lut_struct
typedef struct
{
GimpHistogram *histogram;
int part[5][257];
};
gint part[5][257];
} hist_lut_struct;
static float
equalize_lut_func(struct hist_lut_struct *hlut,
int nchannels, int channel, float value)
static gfloat
equalize_lut_func (hist_lut_struct *hlut,
gint n_channels,
gint channel,
gfloat value)
{
int i = 0, j;
j = (int)(value * 255.0 + 0.5);
gint i = 0;
gint j;
j = (gint) (value * 255.0 + 0.5);
while (hlut->part[channel][i + 1] <= j)
i++;
return i / 255.0;
}
void
eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes)
GimpLut *
eq_histogram_lut_new (GimpHistogram *histogram,
gint n_channels)
{
int i, k, j;
struct hist_lut_struct hlut;
double pixels_per_value;
double desired;
double sum, dif;
GimpLut *lut;
lut = gimp_lut_new ();
eq_histogram_lut_setup (lut, histogram, n_channels);
return lut;
}
void
eq_histogram_lut_setup (GimpLut *lut,
GimpHistogram *hist,
gint n_channels)
{
gint i, k, j;
hist_lut_struct hlut;
gdouble pixels_per_value;
gdouble desired;
gdouble sum, dif;
/* Find partition points */
pixels_per_value = gimp_histogram_get_count(hist, 0, 255) / 256.0;
pixels_per_value = gimp_histogram_get_count (hist, 0, 255) / 256.0;
for (k = 0; k < bytes; k++)
for (k = 0; k < n_channels; k++)
{
/* First and last points in partition */
hlut.part[k][0] = 0;
hlut.part[k][256] = 256;
/* Find intermediate points */
j = 0;
sum = gimp_histogram_get_channel(hist, k, 0) +
gimp_histogram_get_channel(hist, k, 1);
j = 0;
sum = (gimp_histogram_get_channel (hist, k, 0) +
gimp_histogram_get_channel (hist, k, 1));
for (i = 1; i < 256; i++)
{
desired = i * pixels_per_value;
while (sum <= desired)
{
j++;
sum += gimp_histogram_get_channel(hist, k, j + 1);
}
{
j++;
sum += gimp_histogram_get_channel (hist, k, j + 1);
}
/* Nearest sum */
dif = sum - gimp_histogram_get_channel(hist, k, j);
dif = sum - gimp_histogram_get_channel (hist, k, j);
if ((sum - desired) > (dif / 2.0))
hlut.part[k][i] = j;
else
@ -412,15 +515,6 @@ eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes)
}
}
gimp_lut_setup(lut, (GimpLutFunc) equalize_lut_func,
(void *) &hlut, bytes);
}
GimpLut *
eq_histogram_lut_new(GimpHistogram *h, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
eq_histogram_lut_setup(lut, h, nchannels);
return lut;
gimp_lut_setup (lut, (GimpLutFunc) equalize_lut_func,
(gpointer) &hlut, n_channels);
}

View File

@ -20,51 +20,69 @@
#define __LUT_FUNCS_H__
typedef enum
{
VALUE_LUT,
RED_LUT,
GREEN_LUT,
BLUE_LUT,
ALPHA_LUT,
GRAY_LUT = 0 /*< skip >*/
} ChannelLutType;
/* brightness contrast */
void brightness_contrast_lut_setup (GimpLut *lut,
double brightness, double contrast,
int nchannels);
GimpLut *brightness_contrast_lut_new (double brightness, double contrast,
int nchannels);
GimpLut * brightness_contrast_lut_new (gdouble brightness,
gdouble contrast,
gint n_channels);
void brightness_contrast_lut_setup (GimpLut *lut,
gdouble brightness,
gdouble contrast,
gint n_channels);
/* invert */
void invert_lut_setup (GimpLut *lut, int nchannels);
GimpLut *invert_lut_new (int nchannels);
GimpLut * invert_lut_new (gint n_channels);
void invert_lut_setup (GimpLut *lut,
gint n_channels);
/* add (or subtract) */
void add_lut_setup (GimpLut *lut, double ammount, int nchannels);
GimpLut *add_lut_new (double ammount, int nchannels);
GimpLut * add_lut_new (gdouble amount,
gint n_channels);
void add_lut_setup (GimpLut *lut,
gdouble amount,
gint n_channels);
/* intersect (MIN (pixel, value)) */
void intersect_lut_setup (GimpLut *lut, double value, int nchannels);
GimpLut *intersect_lut_new (double value, int nchannels);
GimpLut * intersect_lut_new (gdouble value,
gint n_channels);
void intersect_lut_setup (GimpLut *lut,
gdouble value,
gint n_channels);
/* threshold */
void threshold_lut_setup (GimpLut *lut, double value, int nchannels);
GimpLut *threshold_lut_new (double value, int nchannels);
GimpLut * threshold_lut_new (gdouble value,
gint n_channels);
void threshold_lut_setup (GimpLut *lut,
gdouble value,
gint n_channels);
/* levels */
void levels_lut_setup (GimpLut *lut, double *gamma,
int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels);
GimpLut *levels_lut_new (double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels);
GimpLut * levels_lut_new (gdouble *gamma,
gint *low_input,
gint *high_input,
gint *low_output,
gint *high_output,
gint n_channels);
void levels_lut_setup (GimpLut *lut,
gdouble *gamma,
gint *low_input,
gint *high_input,
gint *low_output,
gint *high_output,
gint n_channels);
/* posterize */
void posterize_lut_setup (GimpLut *lut, int levels, int nchannels);
GimpLut *posterize_lut_new (int levels, int nchannels);
GimpLut * posterize_lut_new (gint levels,
gint n_channels);
void posterize_lut_setup (GimpLut *lut,
gint levels,
gint n_channels);
/* equalize histogram */
void eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes);
GimpLut *eq_histogram_lut_new (GimpHistogram *h, int nchannels);
GimpLut * eq_histogram_lut_new (GimpHistogram *histogram,
gint n_channels);
void eq_histogram_lut_setup (GimpLut *lut,
GimpHistogram *histogram,
gint n_channels);
#endif /* __LUT_FUNCS_H__ */

View File

@ -29,6 +29,8 @@ libappcore_la_SOURCES = \
gimpdrawable-desaturate.h \
gimpdrawable-equalize.c \
gimpdrawable-equalize.h \
gimpdrawable-histogram.c \
gimpdrawable-histogram.h \
gimpdrawable-invert.c \
gimpdrawable-invert.h \
gimpdrawable-offset.c \

View File

@ -30,6 +30,7 @@
#include "base/boundary.h"
#include "base/gimplut.h"
#include "base/lut-funcs.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -44,7 +45,6 @@
#include "gimpchannel.h"
#include "gimplayer.h"
#include "parasitelist.h"
#include "lut_funcs.h"
#include "undo.h"
#include "libgimp/gimpintl.h"

View File

@ -30,6 +30,7 @@
#include "base/boundary.h"
#include "base/gimplut.h"
#include "base/lut-funcs.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "base/temp-buf.h"
@ -44,7 +45,6 @@
#include "gimpchannel.h"
#include "gimplayer.h"
#include "parasitelist.h"
#include "lut_funcs.h"
#include "undo.h"
#include "libgimp/gimpintl.h"

View File

@ -22,16 +22,18 @@
#include "core-types.h"
#include "base/gimphistogram.h"
#include "base/gimplut.h"
#include "base/lut-funcs.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "drawable.h"
#include "gimpdrawable.h"
#include "gimpdrawable-equalize.h"
#include "gimpdrawable-histogram.h"
#include "gimpimage.h"
#include "lut_funcs.h"
#include "gimphistogram.h"
#include "drawable.h"
void
@ -56,7 +58,7 @@ gimp_drawable_equalize (GimpDrawable *drawable,
alpha = has_alpha ? (bytes - 1) : bytes;
hist = gimp_histogram_new ();
gimp_histogram_calculate_drawable (hist, drawable);
gimp_drawable_calculate_histogram (drawable, hist);
/* Build equalization LUT */
lut = eq_histogram_lut_new (hist, bytes);

View File

@ -0,0 +1,71 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
*
* 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 <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
#include "core/core-types.h"
#include "base/gimphistogram.h"
#include "base/pixel-region.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
void
gimp_drawable_calculate_histogram (GimpDrawable *drawable,
GimpHistogram *histogram)
{
PixelRegion region;
PixelRegion mask;
gint x1, y1, x2, y2;
gint off_x, off_y;
gboolean no_mask;
g_return_if_fail (drawable != NULL);
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (histogram != NULL);
no_mask = (gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&region, gimp_drawable_data (drawable), x1, y1,
(x2 - x1), (y2 - y1), FALSE);
if (! no_mask)
{
GimpChannel *sel_mask;
GimpImage *gimage;
gimage = gimp_drawable_gimage (drawable);
sel_mask = gimp_image_get_mask (gimage);
gimp_drawable_offsets (drawable, &off_x, &off_y);
pixel_region_init (&mask, gimp_drawable_data (GIMP_DRAWABLE (sel_mask)),
x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
gimp_histogram_calculate (histogram, &region, &mask);
}
else
{
gimp_histogram_calculate (histogram, &region, NULL);
}
}

View File

@ -0,0 +1,29 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
*
* 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.
*/
#ifndef __GIMP_DRAWABLE_HISTOGRAM_H__
#define __GIMP_DRAWABLE_HISTOGRAM_H__
void gimp_drawable_calculate_histogram (GimpDrawable *drawable,
GimpHistogram *histogram);
#endif /* __GIMP_HISTOGRAM_H__ */

View File

@ -23,13 +23,14 @@
#include "core-types.h"
#include "base/gimplut.h"
#include "base/lut-funcs.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "drawable.h"
#include "gimpdrawable.h"
#include "gimpdrawable-invert.h"
#include "lut_funcs.h"
#include "drawable.h"
void

View File

@ -1,506 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
*
* 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"
#ifdef ENABLE_MP
#include <pthread.h>
#endif /* ENABLE_MP */
#include <gtk/gtk.h>
#include "libgimpmath/gimpmath.h"
#include "core/core-types.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "gimphistogram.h"
#include "gimprc.h"
struct _GimpHistogram
{
gint bins;
gdouble **values;
gint n_channels;
#ifdef ENABLE_MP
pthread_mutex_t mutex;
gint nthreads;
gdouble ***tmp_values;
gchar *tmp_slots;
#endif /* ENABLE_MP */
};
GimpHistogram *
gimp_histogram_new (void)
{
GimpHistogram *histogram;
histogram = g_new0 (GimpHistogram, 1);
histogram->bins = 0;
histogram->values = NULL;
histogram->n_channels = 0;
#ifdef ENABLE_MP
histogram->nthreads = 0;
histogram->tmp_values = NULL;
histogram->tmp_slots = NULL;
#endif /* ENABLE_MP */
return histogram;
}
void
gimp_histogram_free (GimpHistogram *histogram)
{
gint i;
if (histogram->values)
{
for (i = 0; i < histogram->n_channels; i++)
g_free (histogram->values[i]);
g_free (histogram->values);
}
g_free (histogram);
}
static void
gimp_histogram_calculate_sub_region (GimpHistogram *histogram,
PixelRegion *region,
PixelRegion *mask)
{
const guchar *src, *msrc;
const guchar *m, *s;
gdouble **values;
gint h, w, max;
#ifdef ENABLE_MP
gint slot = 0;
/* find an unused temporary slot to put our results in and lock it */
pthread_mutex_lock (&histogram->mutex);
{
while (histogram->tmp_slots[slot])
slot++;
values = histogram->tmp_values[slot];
histogram->tmp_slots[slot] = 1;
}
pthread_mutex_unlock (&histogram->mutex);
#else /* !ENABLE_MP */
values = histogram->values;
#endif
h = region->h;
w = region->w;
if (mask)
{
gdouble masked;
src = region->data;
msrc = mask->data;
while (h--)
{
s = src;
m = msrc;
w = region->w;
switch(region->bytes)
{
case 1:
while (w--)
{
masked = m[0] / 255.0;
values[0][s[0]] += masked;
s += 1;
m += 1;
}
break;
case 2:
while (w--)
{
masked = m[0] / 255.0;
values[0][s[0]] += masked;
values[1][s[1]] += masked;
s += 2;
m += 1;
}
break;
case 3: /* calculate seperate value values */
while (w--)
{
masked = m[0] / 255.0;
values[1][s[0]] += masked;
values[2][s[1]] += masked;
values[3][s[2]] += masked;
max = (s[0] > s[1]) ? s[0] : s[1];
if (s[2] > max)
values[0][s[2]] += masked;
else
values[0][max] += masked;
s += 3;
m += 1;
}
break;
case 4: /* calculate seperate value values */
while (w--)
{
masked = m[0] / 255.0;
values[1][s[0]] += masked;
values[2][s[1]] += masked;
values[3][s[2]] += masked;
values[4][s[3]] += masked;
max = (s[0] > s[1]) ? s[0] : s[1];
if (s[2] > max)
values[0][s[2]] += masked;
else
values[0][max] += masked;
s += 3;
m += 1;
}
break;
}
src += region->rowstride;
msrc += mask->rowstride;
}
}
else /* no mask */
{
src = region->data;
while (h--)
{
s = src;
w = region->w;
switch(region->bytes)
{
case 1:
while (w--)
{
values[0][s[0]] += 1.0;
s += 1;
}
break;
case 2:
while (w--)
{
values[0][s[0]] += 1.0;
values[1][s[1]] += 1.0;
s += 2;
}
break;
case 3: /* calculate seperate value values */
while (w--)
{
values[1][s[0]] += 1.0;
values[2][s[1]] += 1.0;
values[3][s[2]] += 1.0;
max = (s[0] > s[1]) ? s[0] : s[1];
if (s[2] > max)
values[0][s[2]] += 1.0;
else
values[0][max] += 1.0;
s += 3;
}
break;
case 4: /* calculate seperate value values */
while (w--)
{
values[1][s[0]] += 1.0;
values[2][s[1]] += 1.0;
values[3][s[2]] += 1.0;
values[4][s[3]] += 1.0;
max = (s[0] > s[1]) ? s[0] : s[1];
if (s[2] > max)
values[0][s[2]] += 1.0;
else
values[0][max] += 1.0;
s += 4;
}
break;
}
src += region->rowstride;
}
}
#ifdef ENABLE_MP
/* unlock this slot */
/* we shouldn't have to use mutex locks here */
pthread_mutex_lock (&histogram->mutex);
histogram->tmp_slots[slot] = 0;
pthread_mutex_unlock (&histogram->mutex);
#endif
}
static void
gimp_histogram_alloc (GimpHistogram *histogram,
gint bytes)
{
gint i;
if (bytes + 1 != histogram->n_channels)
{
if (histogram->values)
{
for (i = 0; i < histogram->n_channels; i++)
g_free (histogram->values[i]);
g_free (histogram->values);
}
histogram->n_channels = bytes + 1;
histogram->values = g_new0 (gdouble *, histogram->n_channels);
for (i = 0; i < histogram->n_channels; i++)
histogram->values[i] = g_new (double, 256);
}
}
void
gimp_histogram_calculate (GimpHistogram *histogram,
PixelRegion *region,
PixelRegion *mask)
{
gint i, j;
#ifdef ENABLE_MP
gint k;
#endif
gimp_histogram_alloc (histogram, region->bytes);
#ifdef ENABLE_MP
pthread_mutex_init (&histogram->mutex, NULL);
histogram->tmp_slots = g_new0 (gchar, num_processors);
histogram->tmp_values = g_new0 (gdouble **, num_processors);
for (i = 0; i < num_processors; i++)
{
histogram->tmp_values[i] = g_new0 (double *, histogram->n_channels);
histogram->tmp_slots[i] = 0;
for (j = 0; j < histogram->n_channels; j++)
{
histogram->tmp_values[i][j] = g_new0 (gdouble, 256);
for (k = 0; k < 256; k++)
histogram->tmp_values[i][j][k] = 0.0;
}
}
#endif
for (i = 0; i < histogram->n_channels; i++)
for (j = 0; j < 256; j++)
histogram->values[i][j] = 0.0;
pixel_regions_process_parallel ((p_func)gimp_histogram_calculate_sub_region,
histogram, 2, region, mask);
#ifdef ENABLE_MP
/* add up all the tmp buffers and free their memmory */
for (i = 0; i < num_processors; i++)
{
for (j = 0; j < histogram->n_channels; j++)
{
for (k = 0; k < 256; k++)
histogram->values[j][k] += histogram->tmp_values[i][j][k];
g_free (histogram->tmp_values[i][j]);
}
g_free (histogram->tmp_values[i]);
}
g_free (histogram->tmp_values);
g_free (histogram->tmp_slots);
#endif
}
void
gimp_histogram_calculate_drawable (GimpHistogram *histogram,
GimpDrawable *drawable)
{
PixelRegion region;
PixelRegion mask;
gint x1, y1, x2, y2;
gint off_x, off_y;
gboolean no_mask;
no_mask = (gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&region, gimp_drawable_data (drawable), x1, y1,
(x2 - x1), (y2 - y1), FALSE);
if (!no_mask)
{
GimpChannel *sel_mask;
GimpImage *gimage;
gimage = gimp_drawable_gimage (drawable);
sel_mask = gimp_image_get_mask (gimage);
gimp_drawable_offsets (drawable, &off_x, &off_y);
pixel_region_init (&mask, gimp_drawable_data (GIMP_DRAWABLE (sel_mask)),
x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
gimp_histogram_calculate (histogram, &region, &mask);
}
else
{
gimp_histogram_calculate (histogram, &region, NULL);
}
}
gdouble
gimp_histogram_get_maximum (GimpHistogram *histogram,
GimpHistogramChannel channel)
{
gdouble max = 0.0;
gint x;
for (x = 0; x < 256; x++)
if (histogram->values[channel][x] > max)
max = histogram->values[channel][x];
return max;
}
gdouble
gimp_histogram_get_value (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint bin)
{
if (channel < histogram->n_channels && bin >= 0 && bin < 256)
return histogram->values[channel][bin];
return 0.0;
}
gdouble
gimp_histogram_get_channel (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint bin)
{
if (histogram->n_channels > 3)
return gimp_histogram_get_value (histogram, channel + 1, bin);
else
return gimp_histogram_get_value (histogram, channel , bin);
}
gint
gimp_histogram_nchannels (GimpHistogram *histogram)
{
return histogram->n_channels - 1;
}
gdouble
gimp_histogram_get_count (GimpHistogram *histogram,
gint start,
gint end)
{
gint i;
gdouble count = 0.0;
for (i = start; i <= end; i++)
count += histogram->values[0][i];
return count;
}
gdouble
gimp_histogram_get_mean (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end)
{
gint i;
gdouble mean = 0.0;
gdouble count;
for (i = start; i <= end; i++)
mean += i * histogram->values[channel][i];
count = gimp_histogram_get_count (histogram, start, end);
if (count > 0.0)
return mean / count;
return mean;
}
gint
gimp_histogram_get_median (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end)
{
gint i;
gdouble sum = 0.0;
gdouble count;
count = gimp_histogram_get_count (histogram, start, end);
for (i = start; i <= end; i++)
{
sum += histogram->values[channel][i];
if (sum * 2 > count)
return i;
}
return -1;
}
gdouble
gimp_histogram_get_std_dev (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end)
{
gint i;
gdouble dev = 0.0;
gdouble count;
gdouble mean;
mean = gimp_histogram_get_mean (histogram, channel, start, end);
count = gimp_histogram_get_count (histogram, start, end);
if (count == 0.0)
count = 1.0;
for (i = start; i <= end; i++)
dev += gimp_histogram_get_value (histogram, channel, i) *
(i - mean) * (i - mean);
return sqrt (dev / count);
}

View File

@ -1,58 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
*
* 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.
*/
#ifndef __GIMP_HISTOGRAM_H__
#define __GIMP_HISTOGRAM_H__
GimpHistogram * gimp_histogram_new (void);
void gimp_histogram_free (GimpHistogram *histogram);
void gimp_histogram_calculate (GimpHistogram *historgam,
PixelRegion *region,
PixelRegion *mask);
void gimp_histogram_calculate_drawable (GimpHistogram *histogram,
GimpDrawable *drawable);
gdouble gimp_histogram_get_maximum (GimpHistogram *histogram,
GimpHistogramChannel channel);
gdouble gimp_histogram_get_count (GimpHistogram *histogram,
gint start,
gint end);
gdouble gimp_histogram_get_mean (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end);
gint gimp_histogram_get_median (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end);
gdouble gimp_histogram_get_std_dev (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint start,
gint end);
gdouble gimp_histogram_get_value (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint bin);
gdouble gimp_histogram_get_channel (GimpHistogram *histogram,
GimpHistogramChannel channel,
gint bin);
gint gimp_histogram_nchannels (GimpHistogram *histogram);
#endif /* __GIMP_HISTOGRAM_H__ */

View File

@ -1,426 +0,0 @@
/* 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 <stdio.h>
#include <glib.h>
#include "libgimpmath/gimpmath.h"
#include "core/core-types.h"
#include "base/gimplut.h"
#include "gimphistogram.h"
/* ---------- Brightness/Contrast -----------*/
typedef struct B_C_struct
{
double brightness;
double contrast;
} B_C_struct;
static float
brightness_contrast_lut_func(B_C_struct *data,
int nchannels, int channel, float value)
{
float nvalue;
double power;
/* return the original value for the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
/* apply brightness */
if (data->brightness < 0.0)
value = value * (1.0 + data->brightness);
else
value = value + ((1.0 - value) * data->brightness);
/* apply contrast */
if (data->contrast < 0.0)
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + data->contrast));
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
else
{
if (value > 0.5)
nvalue = 1.0 - value;
else
nvalue = value;
if (nvalue < 0.0)
nvalue = 0.0;
power = (data->contrast == 1.0) ? 127 : 1.0 / (1.0 - data->contrast);
nvalue = 0.5 * pow (2.0 * nvalue, power);
if (value > 0.5)
value = 1.0 - nvalue;
else
value = nvalue;
}
return value;
}
void
brightness_contrast_lut_setup(GimpLut *lut, double brightness, double contrast,
int nchannels)
{
B_C_struct data;
data.brightness = brightness;
data.contrast = contrast;
gimp_lut_setup(lut, (GimpLutFunc) brightness_contrast_lut_func,
(void *) &data, nchannels);
}
GimpLut *
brightness_contrast_lut_new(double brightness, double contrast,
int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
brightness_contrast_lut_setup(lut, brightness, contrast, nchannels);
return lut;
}
/* ---------------- invert ------------------ */
static float
invert_lut_func(void *unused,
int nchannels, int channel, float value)
{
/* don't invert the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
return 1.0 - value;
}
void
invert_lut_setup(GimpLut *lut, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) invert_lut_func,
NULL , nchannels);
}
GimpLut *
invert_lut_new(int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
invert_lut_setup(lut, nchannels);
return lut;
}
/* ---------------- add (or subract)------------------ */
static float
add_lut_func(double *ammount,
int nchannels, int channel, float value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
return (value + *ammount);
}
void
add_lut_setup(GimpLut *lut, double ammount, int nchannels)
{
gimp_lut_setup(lut, (GimpLutFunc) add_lut_func,
(void *) &ammount , nchannels);
}
GimpLut *
add_lut_new(double ammount, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
add_lut_setup(lut, ammount, nchannels);
return lut;
}
/* ---------------- intersect (MIN (pixel, value)) ------------------ */
static float
intersect_lut_func(double *min,
int nchannels, int channel, float value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
return MIN (value, *min);
}
void
intersect_lut_setup(GimpLut *lut, double value, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) intersect_lut_func,
(void *) &value , nchannels);
}
GimpLut *
intersect_lut_new(double value, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
intersect_lut_setup(lut, value, nchannels);
return lut;
}
/* ---------------- Threshold ------------------ */
static float
threshold_lut_func(double *min,
int nchannels, int channel, float value)
{
/* don't change the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
if (value < *min)
return 0.0;
return 1.0;
}
void
threshold_lut_setup(GimpLut *lut, double value, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) threshold_lut_func,
(void *) &value , nchannels);
}
GimpLut *
threshold_lut_new(double value, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
threshold_lut_setup(lut, value, nchannels);
return lut;
}
/* ------------- levels ------------ */
typedef struct
{
double *gamma;
int *low_input;
int *high_input;
int *low_output;
int *high_output;
} levels_struct;
static float
levels_lut_func(levels_struct *data,
int nchannels, int channel, float value)
{
double inten;
int j;
if (nchannels == 1)
j = 0;
else
j = channel + 1;
inten = value;
/* For color images this runs through the loop with j = channel +1
the first time and j = 0 the second time */
/* For bw images this runs through the loop with j = 0 the first and
only time */
for (; j >= 0; j -= (channel + 1))
{
/* don't apply the overall curve to the alpha channel */
if (j == 0 && (nchannels == 2 || nchannels == 4)
&& channel == nchannels -1)
return inten;
/* determine input intensity */
if (data->high_input[j] != data->low_input[j])
inten = (double) (255.0*inten - data->low_input[j]) /
(double) (data->high_input[j] - data->low_input[j]);
else
inten = (double) (255.0*inten - data->low_input[j]);
if (data->gamma[j] != 0.0)
{
if (inten >= 0.0)
inten = pow ( inten, (1.0 / data->gamma[j]));
else
inten = -pow (-inten, (1.0 / data->gamma[j]));
}
/* determine the output intensity */
if (data->high_output[j] >= data->low_output[j])
inten = (double) (inten * (data->high_output[j] - data->low_output[j]) +
data->low_output[j]);
else if (data->high_output[j] < data->low_output[j])
inten = (double) (data->low_output[j] - inten *
(data->low_output[j] - data->high_output[j]));
inten /= 255.0;
}
return inten;
}
void
levels_lut_setup(GimpLut *lut, double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels)
{
levels_struct data;
data.gamma = gamma;
data.low_input = low_input;
data.high_input = high_input;
data.low_output = low_output;
data.high_output = high_output;
gimp_lut_setup(lut, (GimpLutFunc) levels_lut_func,
(void *) &data, nchannels);
}
GimpLut *
levels_lut_new(double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
levels_lut_setup(lut, gamma, low_input, high_input,
low_output, high_output, nchannels);
return lut;
}
/* --------------- posterize ---------------- */
static float
posterize_lut_func(int *ilevels,
int nchannels, int channel, float value)
{
int levels;
/* don't posterize the alpha channel */
if ((nchannels == 2 || nchannels == 4) && channel == nchannels -1)
return value;
if (*ilevels < 2)
levels = 2;
else
levels = *ilevels;
value = RINT(value * (levels - 1.0)) / (levels - 1.0);
return value;
}
void
posterize_lut_setup(GimpLut *lut, int levels, int nchannels)
{
gimp_lut_setup_exact(lut, (GimpLutFunc) posterize_lut_func,
(void *) &levels , nchannels);
}
GimpLut *
posterize_lut_new(int levels, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
posterize_lut_setup(lut, levels, nchannels);
return lut;
}
/* --------------- equalize ------------- */
struct hist_lut_struct
{
GimpHistogram *histogram;
int part[5][257];
};
static float
equalize_lut_func(struct hist_lut_struct *hlut,
int nchannels, int channel, float value)
{
int i = 0, j;
j = (int)(value * 255.0 + 0.5);
while (hlut->part[channel][i + 1] <= j)
i++;
return i / 255.0;
}
void
eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes)
{
int i, k, j;
struct hist_lut_struct hlut;
double pixels_per_value;
double desired;
double sum, dif;
/* Find partition points */
pixels_per_value = gimp_histogram_get_count(hist, 0, 255) / 256.0;
for (k = 0; k < bytes; k++)
{
/* First and last points in partition */
hlut.part[k][0] = 0;
hlut.part[k][256] = 256;
/* Find intermediate points */
j = 0;
sum = gimp_histogram_get_channel(hist, k, 0) +
gimp_histogram_get_channel(hist, k, 1);
for (i = 1; i < 256; i++)
{
desired = i * pixels_per_value;
while (sum <= desired)
{
j++;
sum += gimp_histogram_get_channel(hist, k, j + 1);
}
/* Nearest sum */
dif = sum - gimp_histogram_get_channel(hist, k, j);
if ((sum - desired) > (dif / 2.0))
hlut.part[k][i] = j;
else
hlut.part[k][i] = j + 1;
}
}
gimp_lut_setup(lut, (GimpLutFunc) equalize_lut_func,
(void *) &hlut, bytes);
}
GimpLut *
eq_histogram_lut_new(GimpHistogram *h, int nchannels)
{
GimpLut *lut;
lut = gimp_lut_new();
eq_histogram_lut_setup(lut, h, nchannels);
return lut;
}

View File

@ -1,70 +0,0 @@
/* 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.
*/
#ifndef __LUT_FUNCS_H__
#define __LUT_FUNCS_H__
typedef enum
{
VALUE_LUT,
RED_LUT,
GREEN_LUT,
BLUE_LUT,
ALPHA_LUT,
GRAY_LUT = 0 /*< skip >*/
} ChannelLutType;
/* brightness contrast */
void brightness_contrast_lut_setup (GimpLut *lut,
double brightness, double contrast,
int nchannels);
GimpLut *brightness_contrast_lut_new (double brightness, double contrast,
int nchannels);
/* invert */
void invert_lut_setup (GimpLut *lut, int nchannels);
GimpLut *invert_lut_new (int nchannels);
/* add (or subtract) */
void add_lut_setup (GimpLut *lut, double ammount, int nchannels);
GimpLut *add_lut_new (double ammount, int nchannels);
/* intersect (MIN (pixel, value)) */
void intersect_lut_setup (GimpLut *lut, double value, int nchannels);
GimpLut *intersect_lut_new (double value, int nchannels);
/* threshold */
void threshold_lut_setup (GimpLut *lut, double value, int nchannels);
GimpLut *threshold_lut_new (double value, int nchannels);
/* levels */
void levels_lut_setup (GimpLut *lut, double *gamma,
int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels);
GimpLut *levels_lut_new (double *gamma, int *low_input, int *high_input,
int *low_output, int *high_output, int nchannels);
/* posterize */
void posterize_lut_setup (GimpLut *lut, int levels, int nchannels);
GimpLut *posterize_lut_new (int levels, int nchannels);
/* equalize histogram */
void eq_histogram_lut_setup (GimpLut *lut, GimpHistogram *hist, int bytes);
GimpLut *eq_histogram_lut_new (GimpHistogram *h, int nchannels);
#endif /* __LUT_FUNCS_H__ */

View File

@ -29,7 +29,10 @@
#include "tools/tools-types.h"
#include "procedural_db.h"
#include "base/base-types.h"
#include "base/gimphistogram.h"
#include "base/gimplut.h"
#include "base/lut-funcs.h"
#include "base/pixel-processor.h"
#include "base/pixel-region.h"
#include "core/gimpdrawable-desaturate.h"
@ -38,8 +41,6 @@
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "drawable.h"
#include "gimphistogram.h"
#include "lut_funcs.h"
#include "tools/color_balance.h"
#include "tools/curves.h"
#include "tools/histogram_tool.h"

View File

@ -24,9 +24,9 @@
#include "widgets-types.h"
#include "gimphistogramview.h"
#include "base/gimphistogram.h"
#include "gimphistogram.h"
#include "gimphistogramview.h"
#define WAITING 0

View File

@ -52,7 +52,6 @@ enum_headers = \
../../app/appenums.h \
../../app/appenv.h \
../../app/errors.h \
../../app/lut_funcs.h \
../../app/paint-funcs/paint-funcs.h \
../../app/base/base-types.h \
../../app/core/core-types.h \

View File

@ -238,16 +238,6 @@ package Gimp::CodeGen::enums;
STACK_TRACE_QUERY => '1',
STACK_TRACE_ALWAYS => '2' }
},
ChannelLutType =>
{ contig => 1,
header => 'lut_funcs.h',
symbols => [ qw(VALUE_LUT RED_LUT GREEN_LUT BLUE_LUT ALPHA_LUT) ],
mapping => { VALUE_LUT => '0',
RED_LUT => '1',
GREEN_LUT => '2',
BLUE_LUT => '3',
ALPHA_LUT => '4' }
},
LayerModeEffects =>
{ contig => 1,
header => 'base/base-types.h',
@ -294,6 +284,16 @@ package Gimp::CodeGen::enums;
CUBIC_INTERPOLATION => '1',
NEAREST_NEIGHBOR_INTERPOLATION => '2' }
},
ChannelLutType =>
{ contig => 1,
header => 'base/base-types.h',
symbols => [ qw(VALUE_LUT RED_LUT GREEN_LUT BLUE_LUT ALPHA_LUT) ],
mapping => { VALUE_LUT => '0',
RED_LUT => '1',
GREEN_LUT => '2',
BLUE_LUT => '3',
ALPHA_LUT => '4' }
},
GimpImageBaseType =>
{ contig => 1,
header => 'core/core-types.h',

View File

@ -762,8 +762,8 @@ CODE
}
@headers = qw("widgets/gimphistogramview.h" "core/gimpimage.h"
"core/gimpdrawable.h" "gimphistogram.h" "base/gimplut.h"
"lut_funcs.h" "base/pixel-region.h" "base/pixel-processor.h"
"core/gimpdrawable.h" "base/gimphistogram.h" "base/gimplut.h"
"base/lut-funcs.h" "base/pixel-region.h" "base/pixel-processor.h"
"tools/tools-types.h");
@procs = qw(brightness_contrast levels posterize desaturate equalize invert