mirror of https://github.com/GNOME/gimp.git
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:
parent
884f6a8bd7
commit
0196e83f8d
24
ChangeLog
24
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -39,8 +39,6 @@ typedef struct _ColorNotebook ColorNotebook;
|
|||
|
||||
typedef struct _GDisplay GDisplay;
|
||||
|
||||
typedef struct _GimpHistogram GimpHistogram;
|
||||
|
||||
typedef struct _GimpImageNewValues GimpImageNewValues;
|
||||
|
||||
typedef struct _GimpProgress GimpProgress;
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 (®ion, 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, ®ion, &mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_histogram_calculate (histogram, ®ion, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
gdouble
|
||||
gimp_histogram_get_maximum (GimpHistogram *histogram,
|
||||
GimpHistogramChannel channel)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 (®ion, 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, ®ion, &mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_histogram_calculate (histogram, ®ion, NULL);
|
||||
}
|
||||
}
|
|
@ -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__ */
|
|
@ -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
|
||||
|
|
|
@ -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 (®ion, 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, ®ion, &mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_histogram_calculate (histogram, ®ion, 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);
|
||||
}
|
|
@ -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__ */
|
426
app/lut_funcs.c
426
app/lut_funcs.c
|
@ -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;
|
||||
}
|
|
@ -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__ */
|
|
@ -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"
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "gimphistogramview.h"
|
||||
#include "base/gimphistogram.h"
|
||||
|
||||
#include "gimphistogram.h"
|
||||
#include "gimphistogramview.h"
|
||||
|
||||
|
||||
#define WAITING 0
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue