~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

Viewing changes to modules/cdisplay_highcontrast.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1999 Manish Singh <yosh@gimp.org>
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <string.h>
 
22
 
 
23
#include <gtk/gtk.h>
 
24
 
 
25
#include "libgimpbase/gimpbase.h"
 
26
#include "libgimpmath/gimpmath.h"
 
27
#include "libgimpmodule/gimpmodule.h"
 
28
#include "libgimpwidgets/gimpwidgets.h"
 
29
 
 
30
#include "libgimp/libgimp-intl.h"
 
31
 
 
32
 
 
33
#define DEFAULT_CONTRAST 1.0
 
34
 
 
35
 
 
36
#define CDISPLAY_TYPE_CONTRAST            (cdisplay_contrast_type)
 
37
#define CDISPLAY_CONTRAST(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CDISPLAY_TYPE_CONTRAST, CdisplayContrast))
 
38
#define CDISPLAY_CONTRAST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CDISPLAY_TYPE_CONTRAST, CdisplayContrastClass))
 
39
#define CDISPLAY_IS_CONTRAST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CDISPLAY_TYPE_CONTRAST))
 
40
#define CDISPLAY_IS_CONTRAST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_CONTRAST))
 
41
 
 
42
 
 
43
typedef struct _CdisplayContrast      CdisplayContrast;
 
44
typedef struct _CdisplayContrastClass CdisplayContrastClass;
 
45
 
 
46
struct _CdisplayContrast
 
47
{
 
48
  GimpColorDisplay  parent_instance;
 
49
 
 
50
  gdouble           contrast;
 
51
  guchar            lookup[256];
 
52
 
 
53
  GtkWidget        *hbox;
 
54
  GtkObject        *adjustment;
 
55
};
 
56
 
 
57
struct _CdisplayContrastClass
 
58
{
 
59
  GimpColorDisplayClass  parent_instance;
 
60
};
 
61
 
 
62
 
 
63
enum
 
64
{
 
65
  PROP_0,
 
66
  PROP_CONTRAST
 
67
};
 
68
 
 
69
 
 
70
static GType   cdisplay_contrast_get_type     (GTypeModule        *module);
 
71
static void    cdisplay_contrast_class_init   (CdisplayContrastClass *klass);
 
72
 
 
73
static void    cdisplay_contrast_dispose      (GObject            *object);
 
74
static void    cdisplay_contrast_set_property (GObject            *object,
 
75
                                               guint               property_id,
 
76
                                               const GValue       *value,
 
77
                                               GParamSpec         *pspec);
 
78
static void    cdisplay_contrast_get_property (GObject            *object,
 
79
                                               guint               property_id,
 
80
                                               GValue             *value,
 
81
                                               GParamSpec         *pspec);
 
82
 
 
83
static GimpColorDisplay * cdisplay_contrast_clone  (GimpColorDisplay *display);
 
84
static void    cdisplay_contrast_convert           (GimpColorDisplay *display,
 
85
                                                    guchar           *buf,
 
86
                                                    gint              w,
 
87
                                                    gint              h,
 
88
                                                    gint              bpp,
 
89
                                                    gint              bpl);
 
90
static void    cdisplay_contrast_load_state        (GimpColorDisplay *display,
 
91
                                                    GimpParasite     *state);
 
92
static GimpParasite * cdisplay_contrast_save_state (GimpColorDisplay *display);
 
93
static GtkWidget    * cdisplay_contrast_configure  (GimpColorDisplay *display);
 
94
static void    cdisplay_contrast_configure_reset   (GimpColorDisplay *display);
 
95
 
 
96
static void    cdisplay_contrast_set_contrast      (CdisplayContrast *contrast,
 
97
                                                    gdouble           value);
 
98
static void    cdisplay_contrast_adj_callback      (GtkAdjustment    *adj,
 
99
                                                    CdisplayContrast *contrast);
 
100
 
 
101
 
 
102
static const GimpModuleInfo cdisplay_contrast_info =
 
103
{
 
104
  GIMP_MODULE_ABI_VERSION,
 
105
  N_("High Contrast color display filter"),
 
106
  "Jay Cox <jaycox@earthlink.net>",
 
107
  "v0.2",
 
108
  "(c) 2000, released under the GPL",
 
109
  "October 14, 2000"
 
110
};
 
111
 
 
112
static GType                  cdisplay_contrast_type = 0;
 
113
static GimpColorDisplayClass *parent_class        = NULL;
 
114
 
 
115
 
 
116
G_MODULE_EXPORT const GimpModuleInfo *
 
117
gimp_module_query (GTypeModule *module)
 
118
{
 
119
  return &cdisplay_contrast_info;
 
120
}
 
121
 
 
122
G_MODULE_EXPORT gboolean
 
123
gimp_module_register (GTypeModule *module)
 
124
{
 
125
  cdisplay_contrast_get_type (module);
 
126
 
 
127
  return TRUE;
 
128
}
 
129
 
 
130
static GType
 
131
cdisplay_contrast_get_type (GTypeModule *module)
 
132
{
 
133
  if (! cdisplay_contrast_type)
 
134
    {
 
135
      static const GTypeInfo display_info =
 
136
      {
 
137
        sizeof (CdisplayContrastClass),
 
138
        (GBaseInitFunc) NULL,
 
139
        (GBaseFinalizeFunc) NULL,
 
140
        (GClassInitFunc) cdisplay_contrast_class_init,
 
141
        NULL,           /* class_finalize */
 
142
        NULL,           /* class_data     */
 
143
        sizeof (CdisplayContrast),
 
144
        0,              /* n_preallocs    */
 
145
        NULL            /* instance_init  */
 
146
      };
 
147
 
 
148
      cdisplay_contrast_type =
 
149
        g_type_module_register_type (module,
 
150
                                     GIMP_TYPE_COLOR_DISPLAY,
 
151
                                     "CdisplayContrast",
 
152
                                     &display_info, 0);
 
153
    }
 
154
 
 
155
  return cdisplay_contrast_type;
 
156
}
 
157
 
 
158
static void
 
159
cdisplay_contrast_class_init (CdisplayContrastClass *klass)
 
160
{
 
161
  GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
 
162
  GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
163
 
 
164
  parent_class = g_type_class_peek_parent (klass);
 
165
 
 
166
  object_class->dispose          = cdisplay_contrast_dispose;
 
167
  object_class->get_property     = cdisplay_contrast_get_property;
 
168
  object_class->set_property     = cdisplay_contrast_set_property;
 
169
 
 
170
  g_object_class_install_property (object_class, PROP_CONTRAST,
 
171
                                   g_param_spec_double ("contrast", NULL, NULL,
 
172
                                                        0.01, 10.0,
 
173
                                                        DEFAULT_CONTRAST,
 
174
                                                        G_PARAM_READWRITE |
 
175
                                                        G_PARAM_CONSTRUCT |
 
176
                                                        GIMP_MODULE_PARAM_SERIALIZE));
 
177
 
 
178
  display_class->name            = _("Contrast");
 
179
  display_class->help_id         = "gimp-colordisplay-contrast";
 
180
  display_class->clone           = cdisplay_contrast_clone;
 
181
  display_class->convert         = cdisplay_contrast_convert;
 
182
  display_class->load_state      = cdisplay_contrast_load_state;
 
183
  display_class->save_state      = cdisplay_contrast_save_state;
 
184
  display_class->configure       = cdisplay_contrast_configure;
 
185
  display_class->configure_reset = cdisplay_contrast_configure_reset;
 
186
}
 
187
 
 
188
static void
 
189
cdisplay_contrast_dispose (GObject *object)
 
190
{
 
191
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (object);
 
192
 
 
193
  if (contrast->hbox)
 
194
    gtk_widget_destroy (contrast->hbox);
 
195
 
 
196
  G_OBJECT_CLASS (parent_class)->dispose (object);
 
197
}
 
198
 
 
199
static void
 
200
cdisplay_contrast_get_property (GObject    *object,
 
201
                                guint       property_id,
 
202
                                GValue     *value,
 
203
                                GParamSpec *pspec)
 
204
{
 
205
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (object);
 
206
 
 
207
  switch (property_id)
 
208
    {
 
209
    case PROP_CONTRAST:
 
210
      g_value_set_double (value, contrast->contrast);
 
211
      break;
 
212
    default:
 
213
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
214
      break;
 
215
    }
 
216
}
 
217
 
 
218
static void
 
219
cdisplay_contrast_set_property (GObject      *object,
 
220
                                guint         property_id,
 
221
                                const GValue *value,
 
222
                                GParamSpec   *pspec)
 
223
{
 
224
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (object);
 
225
 
 
226
  switch (property_id)
 
227
    {
 
228
    case PROP_CONTRAST:
 
229
      cdisplay_contrast_set_contrast (contrast, g_value_get_double (value));
 
230
      break;
 
231
    default:
 
232
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
233
      break;
 
234
    }
 
235
}
 
236
 
 
237
static GimpColorDisplay *
 
238
cdisplay_contrast_clone (GimpColorDisplay *display)
 
239
{
 
240
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
 
241
  CdisplayContrast *copy;
 
242
 
 
243
  copy = CDISPLAY_CONTRAST (gimp_color_display_new (G_TYPE_FROM_INSTANCE (contrast)));
 
244
 
 
245
  copy->contrast = contrast->contrast;
 
246
 
 
247
  memcpy (copy->lookup, contrast->lookup, sizeof (guchar) * 256);
 
248
 
 
249
  return GIMP_COLOR_DISPLAY (copy);
 
250
}
 
251
 
 
252
static void
 
253
cdisplay_contrast_convert (GimpColorDisplay *display,
 
254
                           guchar           *buf,
 
255
                           gint              width,
 
256
                           gint              height,
 
257
                           gint              bpp,
 
258
                           gint              bpl)
 
259
{
 
260
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
 
261
  gint              i, j     = height;
 
262
 
 
263
  /* You will not be using the entire buffer most of the time.
 
264
   * Hence, the simplistic code for this is as follows:
 
265
   *
 
266
   * for (j = 0; j < height; j++)
 
267
   *   {
 
268
   *     for (i = 0; i < width * bpp; i++)
 
269
   *       buf[i] = lookup[buf[i]];
 
270
   *     buf += bpl;
 
271
   *   }
 
272
   */
 
273
 
 
274
  width *= bpp;
 
275
  bpl -= width;
 
276
 
 
277
  while (j--)
 
278
    {
 
279
      i = width;
 
280
      while (i--)
 
281
        {
 
282
          *buf = contrast->lookup[*buf];
 
283
          buf++;
 
284
        }
 
285
      buf += bpl;
 
286
    }
 
287
}
 
288
 
 
289
static void
 
290
cdisplay_contrast_load_state (GimpColorDisplay *display,
 
291
                              GimpParasite     *state)
 
292
{
 
293
  gdouble value;
 
294
 
 
295
#if G_BYTE_ORDER == G_BIG_ENDIAN
 
296
  memcpy (&value, gimp_parasite_data (state), sizeof (gdouble));
 
297
#else
 
298
  {
 
299
    guint32        buf[2];
 
300
    const guint32 *data;
 
301
 
 
302
    data = gimp_parasite_data (state);
 
303
 
 
304
    buf[0] = g_ntohl (data[1]);
 
305
    buf[1] = g_ntohl (data[0]);
 
306
 
 
307
    memcpy (&value, buf, sizeof (gdouble));
 
308
  }
 
309
#endif
 
310
 
 
311
  cdisplay_contrast_set_contrast (CDISPLAY_CONTRAST (display), value);
 
312
}
 
313
 
 
314
static GimpParasite *
 
315
cdisplay_contrast_save_state (GimpColorDisplay *display)
 
316
{
 
317
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
 
318
  guint32           buf[2];
 
319
 
 
320
  memcpy (buf, &contrast->contrast, sizeof (double));
 
321
 
 
322
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 
323
  {
 
324
    guint32 tmp;
 
325
 
 
326
    tmp    = g_htonl (buf[0]);
 
327
    buf[0] = g_htonl (buf[1]);
 
328
    buf[1] = tmp;
 
329
  }
 
330
#endif
 
331
 
 
332
  return gimp_parasite_new ("Display/Contrast", GIMP_PARASITE_PERSISTENT,
 
333
                            sizeof (double), &buf);
 
334
}
 
335
 
 
336
static GtkWidget *
 
337
cdisplay_contrast_configure (GimpColorDisplay *display)
 
338
{
 
339
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
 
340
  GtkWidget        *label;
 
341
  GtkWidget        *spinbutton;
 
342
 
 
343
  if (contrast->hbox)
 
344
    gtk_widget_destroy (contrast->hbox);
 
345
 
 
346
  contrast->hbox = gtk_hbox_new (FALSE, 6);
 
347
 
 
348
  g_signal_connect (contrast->hbox, "destroy",
 
349
                    G_CALLBACK (gtk_widget_destroyed),
 
350
                    &contrast->hbox);
 
351
 
 
352
  label = gtk_label_new_with_mnemonic (_("Contrast C_ycles:"));
 
353
  gtk_box_pack_start (GTK_BOX (contrast->hbox), label, FALSE, FALSE, 0);
 
354
  gtk_widget_show (label);
 
355
 
 
356
  spinbutton = gimp_spin_button_new (&contrast->adjustment,
 
357
                                     contrast->contrast,
 
358
                                     0.01, 10.0, 0.01, 0.1, 0.0,
 
359
                                     0.1, 3);
 
360
  gtk_box_pack_start (GTK_BOX (contrast->hbox), spinbutton, FALSE, FALSE, 0);
 
361
  gtk_widget_show (spinbutton);
 
362
 
 
363
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);
 
364
 
 
365
  g_signal_connect (contrast->adjustment, "value_changed",
 
366
                    G_CALLBACK (cdisplay_contrast_adj_callback),
 
367
                    contrast);
 
368
 
 
369
  return contrast->hbox;
 
370
}
 
371
 
 
372
static void
 
373
cdisplay_contrast_configure_reset (GimpColorDisplay *display)
 
374
{
 
375
  CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
 
376
 
 
377
  if (contrast->adjustment)
 
378
    gtk_adjustment_set_value (GTK_ADJUSTMENT (contrast->adjustment),
 
379
                              DEFAULT_CONTRAST);
 
380
}
 
381
 
 
382
static void
 
383
cdisplay_contrast_set_contrast (CdisplayContrast *contrast,
 
384
                                gdouble           value)
 
385
{
 
386
  if (value <= 0.0)
 
387
    value = 1.0;
 
388
 
 
389
  if (value != contrast->contrast)
 
390
    {
 
391
      gint i;
 
392
 
 
393
      contrast->contrast = value;
 
394
 
 
395
      for (i = 0; i < 256; i++)
 
396
        {
 
397
          contrast->lookup[i] = (guchar) (gint)
 
398
            (255 * .5 * (1 + sin (value * 2 * G_PI * i / 255.0)));
 
399
        }
 
400
 
 
401
      g_object_notify (G_OBJECT (contrast), "contrast");
 
402
      gimp_color_display_changed (GIMP_COLOR_DISPLAY (contrast));
 
403
    }
 
404
}
 
405
 
 
406
static void
 
407
cdisplay_contrast_adj_callback (GtkAdjustment    *adj,
 
408
                                CdisplayContrast *contrast)
 
409
{
 
410
  cdisplay_contrast_set_contrast (contrast, adj->value);
 
411
}