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

« back to all changes in this revision

Viewing changes to app/base/gimphistogram.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
 
 * gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@earthlink.net>
 
4
 * gimphistogram module Copyright (C) 1999 Jay Cox <jaycox@gimp.org>
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
20
20
 
21
21
#include "config.h"
22
22
 
23
 
#ifdef ENABLE_MP
24
 
#include <pthread.h>
25
 
#endif
 
23
#include <string.h>
26
24
 
27
25
#include <glib-object.h>
28
26
 
30
28
 
31
29
#include "base-types.h"
32
30
 
33
 
#include "config/gimpbaseconfig.h"
34
 
 
35
31
#include "gimphistogram.h"
36
32
#include "pixel-processor.h"
37
33
#include "pixel-region.h"
38
34
 
39
35
 
 
36
#ifdef ENABLE_MP
 
37
#define NUM_SLOTS  GIMP_MAX_NUM_THREADS
 
38
#else
 
39
#define NUM_SLOTS  1
 
40
#endif
 
41
 
 
42
 
40
43
struct _GimpHistogram
41
44
{
42
 
  gint               bins;
43
 
  gdouble          **values;
44
 
  gint               n_channels;
45
 
 
 
45
  gint           n_channels;
46
46
#ifdef ENABLE_MP
47
 
  pthread_mutex_t    mutex;
48
 
  gint               num_slots;
49
 
  gdouble         ***tmp_values;
50
 
  gchar             *tmp_slots;
 
47
  GStaticMutex   mutex;
 
48
  gchar          slots[NUM_SLOTS];
51
49
#endif
 
50
  gdouble       *values[NUM_SLOTS];
52
51
};
53
52
 
54
53
 
55
54
/*  local function prototypes  */
56
55
 
57
 
static void   gimp_histogram_alloc_values         (GimpHistogram *histogram,
58
 
                                                   gint           bytes);
59
 
static void   gimp_histogram_free_values          (GimpHistogram *histogram);
60
 
static void   gimp_histogram_calculate_sub_region (GimpHistogram *histogram,
61
 
                                                   PixelRegion   *region,
62
 
                                                   PixelRegion   *mask);
 
56
static void  gimp_histogram_alloc_values         (GimpHistogram *histogram,
 
57
                                                  gint           bytes);
 
58
static void  gimp_histogram_free_values          (GimpHistogram *histogram);
 
59
static void  gimp_histogram_calculate_sub_region (GimpHistogram *histogram,
 
60
                                                  PixelRegion   *region,
 
61
                                                  PixelRegion   *mask);
63
62
 
64
63
 
65
64
/*  public functions  */
66
65
 
67
66
GimpHistogram *
68
 
gimp_histogram_new (GimpBaseConfig *config)
 
67
gimp_histogram_new (void)
69
68
{
70
 
  GimpHistogram *histogram;
71
 
 
72
 
  g_return_val_if_fail (GIMP_IS_BASE_CONFIG (config), NULL);
73
 
 
74
 
  histogram = g_new0 (GimpHistogram, 1);
75
 
 
76
 
  histogram->bins       = 0;
77
 
  histogram->values     = NULL;
78
 
  histogram->n_channels = 0;
 
69
  GimpHistogram *histogram = g_new0 (GimpHistogram, 1);
79
70
 
80
71
#ifdef ENABLE_MP
81
 
  pthread_mutex_init (&histogram->mutex, NULL);
82
 
 
83
 
  histogram->num_slots  = config->num_processors;
84
 
  histogram->tmp_slots  = g_new0 (gchar,      histogram->num_slots);
85
 
  histogram->tmp_values = g_new0 (gdouble **, histogram->num_slots);
86
 
#endif /* ENABLE_MP */
 
72
  g_static_mutex_init (&histogram->mutex);
 
73
#endif
87
74
 
88
75
  return histogram;
89
76
}
93
80
{
94
81
  g_return_if_fail (histogram != NULL);
95
82
 
96
 
#ifdef ENABLE_MP
97
 
  pthread_mutex_destroy (&histogram->mutex);
98
 
 
99
 
  g_free (histogram->tmp_values);
100
 
  g_free (histogram->tmp_slots);
101
 
#endif
102
 
 
103
83
  gimp_histogram_free_values (histogram);
104
84
  g_free (histogram);
105
85
}
106
86
 
107
87
void
108
88
gimp_histogram_calculate (GimpHistogram *histogram,
109
 
                          PixelRegion   *region,
110
 
                          PixelRegion   *mask)
 
89
                          PixelRegion   *region,
 
90
                          PixelRegion   *mask)
111
91
{
112
 
  gint i, j;
 
92
  gint i;
113
93
 
114
94
  g_return_if_fail (histogram != NULL);
115
95
 
121
101
 
122
102
  gimp_histogram_alloc_values (histogram, region->bytes);
123
103
 
124
 
#ifdef ENABLE_MP
125
 
  for (i = 0; i < histogram->num_slots; i++)
126
 
    {
127
 
      histogram->tmp_values[i] = g_new0 (gdouble *, histogram->n_channels);
128
 
      histogram->tmp_slots[i]  = 0;
129
 
 
130
 
      for (j = 0; j < histogram->n_channels; j++)
131
 
        {
132
 
          gint k;
133
 
 
134
 
          histogram->tmp_values[i][j] = g_new0 (gdouble, 256);
135
 
 
136
 
          for (k = 0; k < 256; k++)
137
 
            histogram->tmp_values[i][j][k] = 0.0;
138
 
        }
139
 
    }
140
 
#endif
141
 
 
142
 
  for (i = 0; i < histogram->n_channels; i++)
143
 
    for (j = 0; j < 256; j++)
144
 
      histogram->values[i][j] = 0.0;
145
 
 
146
 
  pixel_regions_process_parallel ((p_func) gimp_histogram_calculate_sub_region,
 
104
  for (i = 0; i < NUM_SLOTS; i++)
 
105
    if (histogram->values[i])
 
106
      memset (histogram->values[i],
 
107
              0, histogram->n_channels * 256 * sizeof (gdouble));
 
108
 
 
109
  pixel_regions_process_parallel ((PixelProcessorFunc)
 
110
                                  gimp_histogram_calculate_sub_region,
147
111
                                  histogram, 2, region, mask);
148
112
 
149
113
#ifdef ENABLE_MP
150
 
  /* add up all the tmp buffers and free their memmory */
151
 
  for (i = 0; i < histogram->num_slots; i++)
152
 
    {
153
 
      for (j = 0; j < histogram->n_channels; j++)
154
 
        {
155
 
          gint k;
156
 
 
157
 
          for (k = 0; k < 256; k++)
158
 
            histogram->values[j][k] += histogram->tmp_values[i][j][k];
159
 
 
160
 
          g_free (histogram->tmp_values[i][j]);
161
 
        }
162
 
 
163
 
      g_free (histogram->tmp_values[i]);
164
 
    }
 
114
  /* add up all slots */
 
115
  for (i = 1; i < NUM_SLOTS; i++)
 
116
    if (histogram->values[i])
 
117
      {
 
118
        gint j;
 
119
 
 
120
        for (j = 0; j < histogram->n_channels * 256; j++)
 
121
          histogram->values[0][j] += histogram->values[i][j];
 
122
      }
165
123
#endif
166
124
}
167
125
 
 
126
 
 
127
#define HISTOGRAM_VALUE(c,i) (histogram->values[0][(c) * 256 + (i)])
 
128
 
 
129
 
168
130
gdouble
169
131
gimp_histogram_get_maximum (GimpHistogram        *histogram,
170
 
                            GimpHistogramChannel  channel)
 
132
                            GimpHistogramChannel  channel)
171
133
{
172
134
  gdouble max = 0.0;
173
135
  gint    x;
178
140
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
179
141
    channel = 1;
180
142
 
181
 
  if (! histogram->values ||
 
143
  if (! histogram->values[0] ||
182
144
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
183
145
    return 0.0;
184
146
 
185
147
  if (channel == GIMP_HISTOGRAM_RGB)
186
148
    for (x = 0; x < 256; x++)
187
149
      {
188
 
        max = MAX (max, histogram->values[GIMP_HISTOGRAM_RED][x]);
189
 
        max = MAX (max, histogram->values[GIMP_HISTOGRAM_GREEN][x]);
190
 
        max = MAX (max, histogram->values[GIMP_HISTOGRAM_BLUE][x]);
 
150
        max = MAX (max, HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   x));
 
151
        max = MAX (max, HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, x));
 
152
        max = MAX (max, HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  x));
191
153
      }
192
154
  else
193
155
    for (x = 0; x < 256; x++)
194
 
      if (histogram->values[channel][x] > max)
195
 
        max = histogram->values[channel][x];
 
156
      {
 
157
        max = MAX (max, HISTOGRAM_VALUE (channel, x));
 
158
      }
196
159
 
197
160
  return max;
198
161
}
199
162
 
200
163
gdouble
201
164
gimp_histogram_get_value (GimpHistogram        *histogram,
202
 
                          GimpHistogramChannel  channel,
203
 
                          gint                  bin)
 
165
                          GimpHistogramChannel  channel,
 
166
                          gint                  bin)
204
167
{
205
168
  g_return_val_if_fail (histogram != NULL, 0.0);
206
169
 
208
171
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
209
172
    channel = 1;
210
173
 
211
 
  if (! histogram->values ||
 
174
  if (! histogram->values[0] ||
212
175
      bin < 0 || bin >= 256 ||
213
176
      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
214
177
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
216
179
 
217
180
  if (channel == GIMP_HISTOGRAM_RGB)
218
181
    {
219
 
      gdouble min = histogram->values[GIMP_HISTOGRAM_RED][bin];
220
 
 
221
 
      min = MIN (min, histogram->values[GIMP_HISTOGRAM_GREEN][bin]);
222
 
 
223
 
      return MIN (min, histogram->values[GIMP_HISTOGRAM_BLUE][bin]);
 
182
      gdouble min = HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED, bin);
 
183
 
 
184
      min = MIN (min, HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, bin));
 
185
 
 
186
      return MIN (min, HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE, bin));
224
187
    }
225
188
  else
226
 
    return histogram->values[channel][bin];
 
189
    {
 
190
      return HISTOGRAM_VALUE (channel, bin);
 
191
    }
227
192
}
228
193
 
229
194
gdouble
230
195
gimp_histogram_get_channel (GimpHistogram        *histogram,
231
 
                            GimpHistogramChannel  channel,
232
 
                            gint                  bin)
 
196
                            GimpHistogramChannel  channel,
 
197
                            gint                  bin)
233
198
{
234
199
  g_return_val_if_fail (histogram != NULL, 0.0);
235
200
 
236
201
  if (histogram->n_channels > 3)
237
 
    return gimp_histogram_get_value (histogram, channel + 1, bin);
238
 
  else
239
 
    return gimp_histogram_get_value (histogram, channel,     bin);
 
202
    channel++;
 
203
 
 
204
  return gimp_histogram_get_value (histogram, channel, bin);
240
205
}
241
206
 
242
207
gint
250
215
gdouble
251
216
gimp_histogram_get_count (GimpHistogram        *histogram,
252
217
                          GimpHistogramChannel  channel,
253
 
                          gint                  start,
254
 
                          gint                  end)
 
218
                          gint                  start,
 
219
                          gint                  end)
255
220
{
256
221
  gint    i;
257
222
  gdouble count = 0.0;
265
230
  if (channel == GIMP_HISTOGRAM_RGB)
266
231
    return (gimp_histogram_get_count (histogram,
267
232
                                      GIMP_HISTOGRAM_RED, start, end)   +
268
 
            gimp_histogram_get_count (histogram,
 
233
            gimp_histogram_get_count (histogram,
269
234
                                      GIMP_HISTOGRAM_GREEN, start, end) +
270
 
            gimp_histogram_get_count (histogram,
 
235
            gimp_histogram_get_count (histogram,
271
236
                                      GIMP_HISTOGRAM_BLUE, start, end));
272
237
 
273
 
  if (! histogram->values ||
 
238
  if (! histogram->values[0] ||
274
239
      start > end ||
275
240
      channel >= histogram->n_channels)
276
241
    return 0.0;
279
244
  end   = CLAMP (end, 0, 255);
280
245
 
281
246
  for (i = start; i <= end; i++)
282
 
    count += histogram->values[channel][i];
 
247
    count += HISTOGRAM_VALUE (channel, i);
283
248
 
284
249
  return count;
285
250
}
286
251
 
287
252
gdouble
288
253
gimp_histogram_get_mean (GimpHistogram        *histogram,
289
 
                         GimpHistogramChannel  channel,
290
 
                         gint                  start,
291
 
                         gint                  end)
 
254
                         GimpHistogramChannel  channel,
 
255
                         gint                  start,
 
256
                         gint                  end)
292
257
{
293
258
  gint    i;
294
259
  gdouble mean = 0.0;
300
265
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
301
266
    channel = 1;
302
267
 
303
 
  if (! histogram->values ||
 
268
  if (! histogram->values[0] ||
304
269
      start > end ||
305
270
      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
306
271
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
312
277
  if (channel == GIMP_HISTOGRAM_RGB)
313
278
    {
314
279
      for (i = start; i <= end; i++)
315
 
        mean += (i * histogram->values[GIMP_HISTOGRAM_RED][i]   +
316
 
                 i * histogram->values[GIMP_HISTOGRAM_GREEN][i] +
317
 
                 i * histogram->values[GIMP_HISTOGRAM_BLUE][i]);
 
280
        mean += (i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
 
281
                 i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
 
282
                 i * HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
318
283
    }
319
284
  else
320
285
    {
321
286
      for (i = start; i <= end; i++)
322
 
        mean += i * histogram->values[channel][i];
 
287
        mean += i * HISTOGRAM_VALUE (channel, i);
323
288
    }
324
289
 
325
290
  count = gimp_histogram_get_count (histogram, channel, start, end);
332
297
 
333
298
gint
334
299
gimp_histogram_get_median (GimpHistogram         *histogram,
335
 
                           GimpHistogramChannel   channel,
336
 
                           gint                   start,
337
 
                           gint                   end)
 
300
                           GimpHistogramChannel   channel,
 
301
                           gint                   start,
 
302
                           gint                   end)
338
303
{
339
304
  gint    i;
340
305
  gdouble sum = 0.0;
346
311
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
347
312
    channel = 1;
348
313
 
349
 
  if (! histogram->values ||
 
314
  if (! histogram->values[0] ||
350
315
      start > end ||
351
316
      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
352
317
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
360
325
  if (channel == GIMP_HISTOGRAM_RGB)
361
326
    for (i = start; i <= end; i++)
362
327
      {
363
 
        sum += (histogram->values[GIMP_HISTOGRAM_RED][i]   +
364
 
                histogram->values[GIMP_HISTOGRAM_GREEN][i] +
365
 
                histogram->values[GIMP_HISTOGRAM_BLUE][i]);
 
328
        sum += (HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
 
329
                HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
 
330
                HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
366
331
 
367
 
        if (sum * 2 > count)
368
 
          return i;
 
332
        if (sum * 2 > count)
 
333
          return i;
369
334
      }
370
335
  else
371
336
    for (i = start; i <= end; i++)
372
337
      {
373
 
        sum += histogram->values[channel][i];
 
338
        sum += HISTOGRAM_VALUE (channel, i);
374
339
 
375
 
        if (sum * 2 > count)
376
 
          return i;
 
340
        if (sum * 2 > count)
 
341
          return i;
377
342
      }
378
343
 
379
344
  return -1;
380
345
}
381
346
 
 
347
/*
 
348
 * adapted from GNU ocrad 0.14 : page_image_io.cc : otsu_th
 
349
 *
 
350
 *  N. Otsu, "A threshold selection method from gray-level histograms,"
 
351
 *  IEEE Trans. Systems, Man, and Cybernetics, vol. 9, no. 1, pp. 62-66, 1979.
 
352
 */
 
353
gdouble
 
354
gimp_histogram_get_threshold (GimpHistogram        *histogram,
 
355
                              GimpHistogramChannel  channel,
 
356
                              gint                  start,
 
357
                              gint                  end)
 
358
{
 
359
  gint     i;
 
360
  gint     maxval;
 
361
  gdouble *hist      = NULL;
 
362
  gdouble *chist     = NULL;
 
363
  gdouble *cmom      = NULL;
 
364
  gdouble  hist_max  = 0.0;
 
365
  gdouble  chist_max = 0.0;
 
366
  gdouble  cmom_max  = 0.0;
 
367
  gdouble  bvar_max  = 0.0;
 
368
  gint     threshold = 127;
 
369
 
 
370
  g_return_val_if_fail (histogram != NULL, -1);
 
371
 
 
372
  /*  the gray alpha channel is in slot 1  */
 
373
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
 
374
    channel = 1;
 
375
 
 
376
  if (! histogram->values[0] ||
 
377
      start > end ||
 
378
      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
 
379
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
 
380
    return 0;
 
381
 
 
382
  start = CLAMP (start, 0, 255);
 
383
  end = CLAMP (end, 0, 255);
 
384
 
 
385
  maxval = end - start;
 
386
 
 
387
  hist  = g_newa (gdouble, maxval + 1);
 
388
  chist = g_newa (gdouble, maxval + 1);
 
389
  cmom  = g_newa (gdouble, maxval + 1);
 
390
 
 
391
  if (channel == GIMP_HISTOGRAM_RGB)
 
392
    {
 
393
      for (i = start; i <= end; i++)
 
394
        hist[i - start] = (HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
 
395
                           HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
 
396
                           HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
 
397
    }
 
398
  else
 
399
    {
 
400
      for (i = start; i <= end; i++)
 
401
        hist[i - start] = HISTOGRAM_VALUE (channel, i);
 
402
    }
 
403
 
 
404
  hist_max = hist[0];
 
405
  chist[0] = hist[0];
 
406
  cmom[0] = 0;
 
407
 
 
408
  for (i = 1; i <= maxval; i++)
 
409
    {
 
410
      if (hist[i] > hist_max)
 
411
        hist_max = hist[i];
 
412
 
 
413
      chist[i] = chist[i-1] + hist[i];
 
414
      cmom[i] = cmom[i-1] + i * hist[i];
 
415
    }
 
416
 
 
417
  chist_max = chist[maxval];
 
418
  cmom_max = cmom[maxval];
 
419
  bvar_max = 0;
 
420
 
 
421
  for (i = 0; i < maxval; ++i)
 
422
    if (chist[i] > 0 && chist[i] < chist_max)
 
423
      {
 
424
        gdouble bvar;
 
425
 
 
426
        bvar = (gdouble) cmom[i] / chist[i];
 
427
        bvar -= (cmom_max - cmom[i]) / (chist_max - chist[i]);
 
428
        bvar *= bvar;
 
429
        bvar *= chist[i];
 
430
        bvar *= chist_max - chist[i];
 
431
 
 
432
        if (bvar > bvar_max)
 
433
          {
 
434
            bvar_max = bvar;
 
435
            threshold = start + i;
 
436
          }
 
437
      }
 
438
 
 
439
  return threshold;
 
440
}
 
441
 
382
442
gdouble
383
443
gimp_histogram_get_std_dev (GimpHistogram        *histogram,
384
 
                            GimpHistogramChannel  channel,
385
 
                            gint                  start,
386
 
                            gint                  end)
 
444
                            GimpHistogramChannel  channel,
 
445
                            gint                  start,
 
446
                            gint                  end)
387
447
{
388
448
  gint    i;
389
449
  gdouble dev = 0.0;
396
456
  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
397
457
    channel = 1;
398
458
 
399
 
  if (! histogram->values ||
 
459
  if (! histogram->values[0] ||
400
460
      start > end ||
401
461
      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
402
462
      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
409
469
    count = 1.0;
410
470
 
411
471
  for (i = start; i <= end; i++)
412
 
    dev += gimp_histogram_get_value (histogram, channel, i) *
413
 
      (i - mean) * (i - mean);
 
472
    dev += gimp_histogram_get_value (histogram, channel, i) * SQR (i - mean);
414
473
 
415
474
  return sqrt (dev / count);
416
475
}
422
481
gimp_histogram_alloc_values (GimpHistogram *histogram,
423
482
                             gint           bytes)
424
483
{
425
 
  gint i;
426
 
 
427
484
  if (bytes + 1 != histogram->n_channels)
428
485
    {
429
486
      gimp_histogram_free_values (histogram);
430
487
 
431
488
      histogram->n_channels = bytes + 1;
432
 
      histogram->values     = g_new0 (gdouble *, histogram->n_channels);
433
489
 
434
 
      for (i = 0; i < histogram->n_channels; i++)
435
 
        histogram->values[i] = g_new (gdouble, 256);
 
490
      histogram->values[0] = g_new (gdouble, histogram->n_channels * 256);
436
491
    }
437
492
}
438
493
 
441
496
{
442
497
  gint i;
443
498
 
444
 
  if (histogram->values)
445
 
    {
446
 
      for (i = 0; i < histogram->n_channels; i++)
 
499
  for (i = 0; i < NUM_SLOTS; i++)
 
500
    if (histogram->values[i])
 
501
      {
447
502
        g_free (histogram->values[i]);
448
 
 
449
 
      g_free (histogram->values);
450
 
 
451
 
      histogram->values     = NULL;
452
 
      histogram->n_channels = 0;
453
 
    }
 
503
        histogram->values[i] = NULL;
 
504
      }
 
505
 
 
506
  histogram->n_channels = 0;
454
507
}
455
508
 
456
509
static void
457
510
gimp_histogram_calculate_sub_region (GimpHistogram *histogram,
458
 
                                     PixelRegion   *region,
459
 
                                     PixelRegion   *mask)
 
511
                                     PixelRegion   *region,
 
512
                                     PixelRegion   *mask)
460
513
{
461
514
  const guchar *src, *msrc;
462
515
  const guchar *m, *s;
463
 
  gdouble **values;
464
 
  gint h, w, max;
 
516
  gdouble      *values;
 
517
  gint          h, w, max;
465
518
 
466
519
#ifdef ENABLE_MP
467
520
  gint slot = 0;
468
521
 
469
522
  /* find an unused temporary slot to put our results in and lock it */
470
 
  pthread_mutex_lock (&histogram->mutex);
 
523
  g_static_mutex_lock (&histogram->mutex);
471
524
 
472
 
  while (histogram->tmp_slots[slot])
 
525
  while (histogram->slots[slot])
473
526
    slot++;
474
527
 
475
 
  values = histogram->tmp_values[slot];
476
 
  histogram->tmp_slots[slot] = 1;
477
 
 
478
 
  pthread_mutex_unlock (&histogram->mutex);
 
528
  values = histogram->values[slot];
 
529
  histogram->slots[slot] = 1;
 
530
 
 
531
  g_static_mutex_unlock (&histogram->mutex);
 
532
 
 
533
  if (! values)
 
534
    {
 
535
      histogram->values[slot] = g_new0 (gdouble, histogram->n_channels * 256);
 
536
      values = histogram->values[slot];
 
537
    }
479
538
 
480
539
#else
481
 
  values = histogram->values;
 
540
  values = histogram->values[0];
482
541
#endif
483
542
 
 
543
#define VALUE(c,i) (values[(c) * 256 + (i)])
 
544
 
484
545
  h = region->h;
485
546
  w = region->w;
486
547
 
491
552
      src  = region->data;
492
553
      msrc = mask->data;
493
554
 
494
 
      while (h--)
495
 
        {
496
 
          s = src;
497
 
          m = msrc;
498
 
          w = region->w;
499
 
 
500
 
          switch (region->bytes)
501
 
            {
502
 
            case 1:
503
 
              while (w--)
504
 
                {
505
 
                  masked = m[0] / 255.0;
506
 
                  values[0][s[0]] += masked;
507
 
                  s += 1;
508
 
                  m += 1;
509
 
                }
510
 
              break;
511
 
 
512
 
            case 2:
513
 
              while (w--)
514
 
                {
515
 
                  masked = m[0] / 255.0;
516
 
                  values[0][s[0]] += masked;
517
 
                  values[1][s[1]] += masked;
518
 
                  s += 2;
519
 
                  m += 1;
520
 
                }
521
 
              break;
522
 
 
523
 
            case 3: /* calculate separate value values */
524
 
              while (w--)
525
 
                {
526
 
                  masked = m[0] / 255.0;
527
 
                  values[1][s[0]] += masked;
528
 
                  values[2][s[1]] += masked;
529
 
                  values[3][s[2]] += masked;
530
 
                  max = (s[0] > s[1]) ? s[0] : s[1];
531
 
 
532
 
                  if (s[2] > max)
533
 
                    values[0][s[2]] += masked;
534
 
                  else
535
 
                    values[0][max] += masked;
536
 
 
537
 
                  s += 3;
538
 
                  m += 1;
539
 
                }
540
 
              break;
541
 
 
542
 
            case 4: /* calculate separate value values */
543
 
              while (w--)
544
 
                {
545
 
                  masked = m[0] / 255.0;
546
 
                  values[1][s[0]] += masked;
547
 
                  values[2][s[1]] += masked;
548
 
                  values[3][s[2]] += masked;
549
 
                  values[4][s[3]] += masked;
550
 
                  max = (s[0] > s[1]) ? s[0] : s[1];
551
 
 
552
 
                  if (s[2] > max)
553
 
                    values[0][s[2]] += masked;
554
 
                  else
555
 
                    values[0][max] += masked;
556
 
 
557
 
                  s += 4;
558
 
                  m += 1;
559
 
                }
560
 
              break;
561
 
            }
562
 
 
563
 
          src  += region->rowstride;
564
 
          msrc += mask->rowstride;
565
 
        }
 
555
      switch (region->bytes)
 
556
        {
 
557
        case 1:
 
558
          while (h--)
 
559
            {
 
560
              s = src;
 
561
              m = msrc;
 
562
              w = region->w;
 
563
 
 
564
              while (w--)
 
565
                {
 
566
                  masked = m[0] / 255.0;
 
567
 
 
568
                  VALUE (0, s[0]) += masked;
 
569
 
 
570
                  s += 1;
 
571
                  m += 1;
 
572
                }
 
573
 
 
574
              src  += region->rowstride;
 
575
              msrc += mask->rowstride;
 
576
            }
 
577
          break;
 
578
 
 
579
        case 2:
 
580
          while (h--)
 
581
            {
 
582
              s = src;
 
583
              m = msrc;
 
584
              w = region->w;
 
585
 
 
586
              while (w--)
 
587
                {
 
588
                  masked = m[0] / 255.0;
 
589
 
 
590
                  VALUE (0, s[0]) += masked;
 
591
                  VALUE (1, s[1]) += masked;
 
592
 
 
593
                  s += 2;
 
594
                  m += 1;
 
595
                }
 
596
 
 
597
              src  += region->rowstride;
 
598
              msrc += mask->rowstride;
 
599
            }
 
600
          break;
 
601
 
 
602
        case 3: /* calculate separate value values */
 
603
          while (h--)
 
604
            {
 
605
              s = src;
 
606
              m = msrc;
 
607
              w = region->w;
 
608
 
 
609
              while (w--)
 
610
                {
 
611
                  masked = m[0] / 255.0;
 
612
 
 
613
                  VALUE (1, s[0]) += masked;
 
614
                  VALUE (2, s[1]) += masked;
 
615
                  VALUE (3, s[2]) += masked;
 
616
 
 
617
                  max = (s[0] > s[1]) ? s[0] : s[1];
 
618
 
 
619
                  if (s[2] > max)
 
620
                    VALUE (0, s[2]) += masked;
 
621
                  else
 
622
                    VALUE (0, max) += masked;
 
623
 
 
624
                  s += 3;
 
625
                  m += 1;
 
626
                }
 
627
 
 
628
              src  += region->rowstride;
 
629
              msrc += mask->rowstride;
 
630
            }
 
631
          break;
 
632
 
 
633
        case 4: /* calculate separate value values */
 
634
          while (h--)
 
635
            {
 
636
              s = src;
 
637
              m = msrc;
 
638
              w = region->w;
 
639
 
 
640
              while (w--)
 
641
                {
 
642
                  masked = m[0] / 255.0;
 
643
 
 
644
                  VALUE (1, s[0]) += masked;
 
645
                  VALUE (2, s[1]) += masked;
 
646
                  VALUE (3, s[2]) += masked;
 
647
                  VALUE (4, s[3]) += masked;
 
648
 
 
649
                  max = (s[0] > s[1]) ? s[0] : s[1];
 
650
 
 
651
                  if (s[2] > max)
 
652
                   VALUE (0, s[2]) += masked;
 
653
                  else
 
654
                    VALUE (0, max) += masked;
 
655
 
 
656
                  s += 4;
 
657
                  m += 1;
 
658
                }
 
659
 
 
660
              src  += region->rowstride;
 
661
              msrc += mask->rowstride;
 
662
            }
 
663
          break;
 
664
        }
566
665
    }
567
666
  else /* no mask */
568
667
    {
569
668
      src = region->data;
570
669
 
571
 
      while (h--)
572
 
        {
573
 
          s = src;
574
 
          w = region->w;
575
 
 
576
 
          switch(region->bytes)
577
 
            {
578
 
            case 1:
579
 
              while (w--)
580
 
                {
581
 
                  values[0][s[0]] += 1.0;
582
 
                  s += 1;
583
 
                }
584
 
              break;
585
 
 
586
 
            case 2:
587
 
              while (w--)
588
 
                {
589
 
                  values[0][s[0]] += 1.0;
590
 
                  values[1][s[1]] += 1.0;
591
 
                  s += 2;
592
 
                }
593
 
              break;
594
 
 
595
 
            case 3: /* calculate separate value values */
596
 
              while (w--)
597
 
                {
598
 
                  values[1][s[0]] += 1.0;
599
 
                  values[2][s[1]] += 1.0;
600
 
                  values[3][s[2]] += 1.0;
601
 
                  max = (s[0] > s[1]) ? s[0] : s[1];
602
 
 
603
 
                  if (s[2] > max)
604
 
                    values[0][s[2]] += 1.0;
605
 
                  else
606
 
                    values[0][max] += 1.0;
607
 
 
608
 
                  s += 3;
609
 
                }
610
 
              break;
611
 
 
612
 
            case 4: /* calculate separate value values */
613
 
              while (w--)
614
 
                {
615
 
                  values[1][s[0]] += 1.0;
616
 
                  values[2][s[1]] += 1.0;
617
 
                  values[3][s[2]] += 1.0;
618
 
                  values[4][s[3]] += 1.0;
619
 
                  max = (s[0] > s[1]) ? s[0] : s[1];
620
 
 
621
 
                  if (s[2] > max)
622
 
                    values[0][s[2]] += 1.0;
623
 
                  else
624
 
                    values[0][max] += 1.0;
625
 
 
626
 
                  s += 4;
627
 
                }
628
 
              break;
629
 
            }
630
 
 
631
 
          src += region->rowstride;
632
 
        }
 
670
      switch (region->bytes)
 
671
        {
 
672
        case 1:
 
673
          while (h--)
 
674
            {
 
675
              s = src;
 
676
              w = region->w;
 
677
 
 
678
              while (w--)
 
679
                {
 
680
                  VALUE (0, s[0]) += 1.0;
 
681
 
 
682
                  s += 1;
 
683
                }
 
684
 
 
685
              src += region->rowstride;
 
686
            }
 
687
          break;
 
688
 
 
689
        case 2:
 
690
          while (h--)
 
691
            {
 
692
              s = src;
 
693
              w = region->w;
 
694
 
 
695
              while (w--)
 
696
                {
 
697
                  VALUE (0, s[0]) += 1.0;
 
698
                  VALUE (1, s[1]) += 1.0;
 
699
 
 
700
                  s += 2;
 
701
                }
 
702
 
 
703
              src += region->rowstride;
 
704
            }
 
705
          break;
 
706
 
 
707
        case 3: /* calculate separate value values */
 
708
          while (h--)
 
709
            {
 
710
              s = src;
 
711
              w = region->w;
 
712
 
 
713
              while (w--)
 
714
                {
 
715
                  VALUE (1, s[0]) += 1.0;
 
716
                  VALUE (2, s[1]) += 1.0;
 
717
                  VALUE (3, s[2]) += 1.0;
 
718
 
 
719
                  max = (s[0] > s[1]) ? s[0] : s[1];
 
720
 
 
721
                  if (s[2] > max)
 
722
                    VALUE (0, s[2]) += 1.0;
 
723
                  else
 
724
                    VALUE (0, max) += 1.0;
 
725
 
 
726
                  s += 3;
 
727
                }
 
728
 
 
729
              src += region->rowstride;
 
730
            }
 
731
          break;
 
732
 
 
733
        case 4: /* calculate separate value values */
 
734
          while (h--)
 
735
            {
 
736
              s = src;
 
737
              w = region->w;
 
738
 
 
739
              while (w--)
 
740
                {
 
741
                  VALUE (1, s[0]) += 1.0;
 
742
                  VALUE (2, s[1]) += 1.0;
 
743
                  VALUE (3, s[2]) += 1.0;
 
744
                  VALUE (4, s[3]) += 1.0;
 
745
 
 
746
                  max = (s[0] > s[1]) ? s[0] : s[1];
 
747
 
 
748
                  if (s[2] > max)
 
749
                    VALUE (0, s[2]) += 1.0;
 
750
                  else
 
751
                    VALUE (0, max) += 1.0;
 
752
 
 
753
                  s += 4;
 
754
                }
 
755
 
 
756
              src += region->rowstride;
 
757
            }
 
758
          break;
 
759
        }
633
760
    }
634
761
 
635
762
#ifdef ENABLE_MP
636
763
  /* unlock this slot */
637
 
  /* we shouldn't have to use mutex locks here */
638
 
  pthread_mutex_lock (&histogram->mutex);
639
 
  histogram->tmp_slots[slot] = 0;
640
 
  pthread_mutex_unlock (&histogram->mutex);
 
764
  g_static_mutex_lock (&histogram->mutex);
 
765
 
 
766
  histogram->slots[slot] = 0;
 
767
 
 
768
  g_static_mutex_unlock (&histogram->mutex);
641
769
#endif
642
770
}