~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to plug-ins/common/normalize.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-10-06 13:30:41 UTC
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: james.westby@ubuntu.com-20081006133041-3panbkcanaymfsmp
Tags: upstream-2.6.0
ImportĀ upstreamĀ versionĀ 2.6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GIMP - The GNU Image Manipulation Program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
 
 *
4
 
 * Normalize 1.00 --- image filter plug-in
5
 
 *
6
 
 * Copyright (C) 1997 Adam D. Moss (adam@foxbox.org)
7
 
 * Very largely based on Quartic's "Contrast Autostretch"
8
 
 *
9
 
 * This program is free software; you can redistribute it and/or modify
10
 
 * it under the terms of the GNU General Public License as published by
11
 
 * the Free Software Foundation; either version 2 of the License, or
12
 
 * (at your option) any later version.
13
 
 *
14
 
 * This program is distributed in the hope that it will be useful,
15
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 * GNU General Public License for more details.
18
 
 *
19
 
 * You should have received a copy of the GNU General Public License
20
 
 * along with this program; if not, write to the Free Software
21
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
 
 */
23
 
 
24
 
 
25
 
/* This plugin performs almost the same operation as the 'contrast
26
 
 * autostretch' plugin, except that it won't allow the colour channels
27
 
 * to normalize independently.  This is actually what most people probably
28
 
 * want instead of contrast-autostretch; use c-a only if you wish to remove
29
 
 * an undesirable colour-tint from a source image which is supposed to
30
 
 * contain pure-white and pure-black.
31
 
 */
32
 
 
33
 
#include "config.h"
34
 
 
35
 
#include <stdlib.h>
36
 
 
37
 
#include <libgimp/gimp.h>
38
 
 
39
 
#include "libgimp/stdplugins-intl.h"
40
 
 
41
 
 
42
 
#define PLUG_IN_PROC "plug-in-normalize"
43
 
 
44
 
 
45
 
/* Declare local functions.
46
 
 */
47
 
static void   query             (void);
48
 
static void   run               (const gchar      *name,
49
 
                                 gint              nparams,
50
 
                                 const GimpParam  *param,
51
 
                                 gint             *nreturn_vals,
52
 
                                 GimpParam       **return_vals);
53
 
 
54
 
static void   normalize         (GimpDrawable     *drawable);
55
 
static void   indexed_normalize (gint32            image_ID);
56
 
 
57
 
 
58
 
const GimpPlugInInfo PLUG_IN_INFO =
59
 
{
60
 
  NULL,  /* init_proc  */
61
 
  NULL,  /* quit_proc  */
62
 
  query, /* query_proc */
63
 
  run,   /* run_proc   */
64
 
};
65
 
 
66
 
 
67
 
MAIN ()
68
 
 
69
 
static void
70
 
query (void)
71
 
{
72
 
  static const GimpParamDef args[] =
73
 
  {
74
 
    { GIMP_PDB_INT32,    "run-mode", "Interactive, non-interactive" },
75
 
    { GIMP_PDB_IMAGE,    "image",    "Input image"                  },
76
 
    { GIMP_PDB_DRAWABLE, "drawable", "Input drawable"               }
77
 
  };
78
 
 
79
 
  gimp_install_procedure (PLUG_IN_PROC,
80
 
                          N_("Stretch brightness values to cover the full range"),
81
 
                          "This plugin performs almost the same operation as "
82
 
                          "the 'contrast autostretch' plugin, except that it "
83
 
                          "won't allow the color channels to normalize "
84
 
                          "independently.  This is actually what most people "
85
 
                          "probably want instead of contrast-autostretch; use "
86
 
                          "c-a only if you wish to remove an undesirable "
87
 
                          "color-tint from a source image which is supposed to "
88
 
                          "contain pure-white and pure-black.",
89
 
                          "Adam D. Moss, Federico Mena Quintero",
90
 
                          "Adam D. Moss, Federico Mena Quintero",
91
 
                          "1997",
92
 
                          N_("_Normalize"),
93
 
                          "RGB*, GRAY*, INDEXED*",
94
 
                          GIMP_PLUGIN,
95
 
                          G_N_ELEMENTS (args), 0,
96
 
                          args, NULL);
97
 
 
98
 
  gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Colors/Auto");
99
 
}
100
 
 
101
 
static void
102
 
run (const gchar      *name,
103
 
     gint              nparams,
104
 
     const GimpParam  *param,
105
 
     gint             *nreturn_vals,
106
 
     GimpParam       **return_vals)
107
 
{
108
 
  static GimpParam   values[1];
109
 
  GimpDrawable      *drawable;
110
 
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
111
 
  GimpRunMode        run_mode;
112
 
  gint32             image_ID;
113
 
 
114
 
  INIT_I18N ();
115
 
 
116
 
  run_mode = param[0].data.d_int32;
117
 
 
118
 
  /*  Get the specified drawable  */
119
 
  drawable = gimp_drawable_get (param[2].data.d_drawable);
120
 
  image_ID = param[1].data.d_image;
121
 
 
122
 
  /*  Make sure that the drawable is gray or RGB color  */
123
 
  if (gimp_drawable_is_rgb (drawable->drawable_id) ||
124
 
      gimp_drawable_is_gray (drawable->drawable_id))
125
 
    {
126
 
      gimp_progress_init (_("Normalizing"));
127
 
      gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1));
128
 
 
129
 
      normalize (drawable);
130
 
 
131
 
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
132
 
        gimp_displays_flush ();
133
 
    }
134
 
  else if (gimp_drawable_is_indexed (drawable->drawable_id))
135
 
    {
136
 
      indexed_normalize (image_ID);
137
 
 
138
 
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
139
 
        gimp_displays_flush ();
140
 
    }
141
 
  else
142
 
    {
143
 
      status = GIMP_PDB_EXECUTION_ERROR;
144
 
    }
145
 
 
146
 
  *nreturn_vals = 1;
147
 
  *return_vals  = values;
148
 
 
149
 
  values[0].type          = GIMP_PDB_STATUS;
150
 
  values[0].data.d_status = status;
151
 
 
152
 
  gimp_drawable_detach (drawable);
153
 
}
154
 
 
155
 
 
156
 
static void
157
 
indexed_normalize (gint32 image_ID)  /* a.d.m. */
158
 
{
159
 
  guchar *cmap;
160
 
  gint ncols,i;
161
 
  gint hi=0,lo=255;
162
 
 
163
 
  cmap = gimp_image_get_colormap (image_ID, &ncols);
164
 
 
165
 
  if (cmap==NULL)
166
 
    {
167
 
      g_printerr ("normalize: cmap was NULL!  Quitting...\n");
168
 
      return;
169
 
    }
170
 
 
171
 
  for (i=0;i<ncols;i++)
172
 
    {
173
 
      if (cmap[i*3 +0] > hi) hi=cmap[i*3 +0];
174
 
      if (cmap[i*3 +1] > hi) hi=cmap[i*3 +1];
175
 
      if (cmap[i*3 +2] > hi) hi=cmap[i*3 +2];
176
 
      if (cmap[i*3 +0] < lo) lo=cmap[i*3 +0];
177
 
      if (cmap[i*3 +1] < lo) lo=cmap[i*3 +1];
178
 
      if (cmap[i*3 +2] < lo) lo=cmap[i*3 +2];
179
 
    }
180
 
 
181
 
  if (hi!=lo)
182
 
    for (i=0;i<ncols;i++)
183
 
      {
184
 
        cmap[i*3 +0] = (255 * (cmap[i*3 +0] - lo)) / (hi-lo);
185
 
        cmap[i*3 +1] = (255 * (cmap[i*3 +1] - lo)) / (hi-lo);
186
 
        cmap[i*3 +2] = (255 * (cmap[i*3 +2] - lo)) / (hi-lo);
187
 
      }
188
 
 
189
 
  gimp_image_set_colormap (image_ID, cmap, ncols);
190
 
}
191
 
 
192
 
typedef struct
193
 
{
194
 
  guchar  lut[256];
195
 
  gdouble min;
196
 
  gdouble max;
197
 
  gint alpha;
198
 
  gboolean has_alpha;
199
 
} NormalizeParam_t;
200
 
 
201
 
static void
202
 
find_min_max (const guchar *src,
203
 
              gint          bpp,
204
 
              gpointer      data)
205
 
{
206
 
  NormalizeParam_t *param = (NormalizeParam_t*) data;
207
 
  gint              b;
208
 
 
209
 
  for (b = 0; b < param->alpha; b++)
210
 
    {
211
 
      if (!param->has_alpha || src[param->alpha])
212
 
        {
213
 
          if (src[b] < param->min)
214
 
            param->min = src[b];
215
 
          if (src[b] > param->max)
216
 
            param->max = src[b];
217
 
        }
218
 
    }
219
 
}
220
 
 
221
 
static void
222
 
normalize_func (const guchar *src,
223
 
                guchar       *dest,
224
 
                gint          bpp,
225
 
                gpointer      data)
226
 
{
227
 
  NormalizeParam_t *param = (NormalizeParam_t*) data;
228
 
  gint              b;
229
 
 
230
 
  for (b = 0; b < param->alpha; b++)
231
 
    dest[b] = param->lut[src[b]];
232
 
 
233
 
  if (param->has_alpha)
234
 
    dest[param->alpha] = src[param->alpha];
235
 
}
236
 
 
237
 
static void
238
 
normalize (GimpDrawable *drawable)
239
 
{
240
 
  NormalizeParam_t param;
241
 
  gint x;
242
 
  guchar  range;
243
 
 
244
 
  param.min = 255;
245
 
  param.max = 0;
246
 
  param.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
247
 
  param.alpha = (param.has_alpha) ? drawable->bpp - 1 : drawable->bpp;
248
 
 
249
 
  gimp_rgn_iterate1 (drawable, 0 /* unused */, find_min_max, &param);
250
 
 
251
 
  /* Calculate LUT */
252
 
 
253
 
  range = param.max - param.min;
254
 
 
255
 
  if (range != 0)
256
 
    for (x = param.min; x <= param.max; x++)
257
 
      param.lut[x] = 255 * (x - param.min) / range;
258
 
  else
259
 
    param.lut[(gint)param.min] = param.min;
260
 
 
261
 
  gimp_rgn_iterate2 (drawable, 0 /* unused */, normalize_func, &param);
262
 
}