~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to libs/dimg/filters/auto/equalizefilter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Mangold
  • Date: 2010-04-09 21:30:01 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100409213001-4bfyibrd359rn7o3
Tags: 2:1.2.0-0ubuntu1
* New upstream release (LP: #560576)
* Remove all patches, fixed upstream
  - Remove quilt build-depend

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 *
 
3
 * This file is a part of digiKam project
 
4
 * http://www.digikam.org
 
5
 *
 
6
 * Date        : 2005-24-01
 
7
 * Description : equalize image filter.
 
8
 *
 
9
 * Copyright (C) 2005-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
10
 *
 
11
 * This program is free software; you can redistribute it
 
12
 * and/or modify it under the terms of the GNU General
 
13
 * Public License as published by the Free Software Foundation;
 
14
 * either version 2, or (at your option)
 
15
 * any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * ============================================================ */
 
23
 
 
24
#include "equalizefilter.h"
 
25
 
 
26
// C++ includes
 
27
 
 
28
#include <cstdio>
 
29
#include <cmath>
 
30
 
 
31
// KDE includes
 
32
 
 
33
#include <kdebug.h>
 
34
 
 
35
// Local includes
 
36
 
 
37
#include "dimg.h"
 
38
#include "imagehistogram.h"
 
39
 
 
40
namespace Digikam
 
41
{
 
42
 
 
43
EqualizeFilter::EqualizeFilter(DImg* orgImage, const DImg* refImage, QObject* parent)
 
44
              : DImgThreadedFilter(orgImage, parent, "EqualizeFilter"),
 
45
                m_refImage(*refImage)
 
46
{
 
47
    initFilter();
 
48
}
 
49
 
 
50
EqualizeFilter::~EqualizeFilter()
 
51
{
 
52
}
 
53
 
 
54
void EqualizeFilter::filterImage()
 
55
{
 
56
    equalizeImage();
 
57
    m_destImage = m_orgImage;
 
58
}
 
59
 
 
60
/** Performs an histogram equalization of the image.
 
61
    this method adjusts the brightness of colors across the
 
62
    active image so that the histogram for the value channel
 
63
    is as nearly as possible flat, that is, so that each possible
 
64
    brightness value appears at about the same number of pixels
 
65
    as each other value. Sometimes Equalize works wonderfully at
 
66
    enhancing the contrasts in an image. Other times it gives
 
67
    garbage. It is a very powerful operation, which can either work
 
68
    miracles on an image or destroy it.*/
 
69
void EqualizeFilter::equalizeImage()
 
70
{
 
71
    struct double_packet  high, low, intensity;
 
72
    struct double_packet* map;
 
73
    struct int_packet*    equalize_map;
 
74
    register int          i;
 
75
    int                   progress;
 
76
 
 
77
    if (m_orgImage.sixteenBit() != m_refImage.sixteenBit())
 
78
    {
 
79
        kDebug() << "Ref. image and Org. has different bits depth"; 
 
80
        return;
 
81
    }
 
82
 
 
83
    // Create an histogram of the reference image.
 
84
    ImageHistogram *histogram = new ImageHistogram(m_refImage.bits(), m_refImage.width(),
 
85
                                                   m_refImage.height(), m_refImage.sixteenBit());
 
86
    histogram->calculate();
 
87
 
 
88
    // Memory allocation.
 
89
    map          = new double_packet[histogram->getHistogramSegments()];
 
90
    equalize_map = new int_packet[histogram->getHistogramSegments()];
 
91
 
 
92
    if( !histogram || !map || !equalize_map )
 
93
    {
 
94
       if(histogram)
 
95
           delete histogram;
 
96
 
 
97
       if(map)
 
98
           delete [] map;
 
99
 
 
100
       if(equalize_map)
 
101
           delete [] equalize_map;
 
102
 
 
103
       kWarning() << ("Unable to allocate memory!");
 
104
       return;
 
105
    }
 
106
 
 
107
    // Integrate the histogram to get the equalization map.
 
108
 
 
109
    memset(&intensity, 0, sizeof(struct double_packet));
 
110
    memset(&high,      0, sizeof(struct double_packet));
 
111
    memset(&low,       0, sizeof(struct double_packet));
 
112
 
 
113
    for(i = 0 ; !m_cancel && (i < histogram->getHistogramSegments()) ; ++i)
 
114
    {
 
115
       intensity.red   += histogram->getValue(RedChannel, i);
 
116
       intensity.green += histogram->getValue(GreenChannel, i);
 
117
       intensity.blue  += histogram->getValue(BlueChannel, i);
 
118
       intensity.alpha += histogram->getValue(AlphaChannel, i);
 
119
       map[i]           = intensity;
 
120
    }
 
121
 
 
122
    // Stretch the histogram.
 
123
 
 
124
    low  = map[0];
 
125
    high = map[histogram->getHistogramSegments()-1];
 
126
    memset(equalize_map, 0, histogram->getHistogramSegments()*sizeof(int_packet));
 
127
 
 
128
    // TODO magic number 256
 
129
    for(i = 0 ; !m_cancel && (i < histogram->getHistogramSegments()) ; ++i)
 
130
    {
 
131
       if(high.red != low.red)
 
132
          equalize_map[i].red = (uint)(((256*histogram->getHistogramSegments() -1) *
 
133
                                (map[i].red-low.red))/(high.red-low.red));
 
134
 
 
135
       if(high.green != low.green)
 
136
          equalize_map[i].green = (uint)(((256*histogram->getHistogramSegments() -1) *
 
137
                                  (map[i].green-low.green))/(high.green-low.green));
 
138
 
 
139
       if(high.blue != low.blue)
 
140
          equalize_map[i].blue = (uint)(((256*histogram->getHistogramSegments() -1) *
 
141
                                 (map[i].blue-low.blue))/(high.blue-low.blue));
 
142
 
 
143
       if(high.alpha != low.alpha)
 
144
          equalize_map[i].alpha = (uint)(((256*histogram->getHistogramSegments() -1) *
 
145
                                  (map[i].alpha-low.alpha))/(high.alpha-low.alpha));
 
146
    }
 
147
 
 
148
    delete histogram;
 
149
    delete [] map;
 
150
 
 
151
    uchar* data     = m_orgImage.bits();
 
152
    int w           = m_orgImage.width();
 
153
    int h           = m_orgImage.height();
 
154
    bool sixteenBit = m_orgImage.sixteenBit();
 
155
    int size        = w*h;
 
156
 
 
157
    // Apply results to image.
 
158
    // TODO magic number 257
 
159
    if (!sixteenBit)        // 8 bits image.
 
160
    {
 
161
        uchar  red, green, blue, alpha;
 
162
        uchar* ptr = data;
 
163
 
 
164
        for (i = 0 ; !m_cancel && (i < size) ; ++i)
 
165
        {
 
166
            blue  = ptr[0];
 
167
            green = ptr[1];
 
168
            red   = ptr[2];
 
169
            alpha = ptr[3];
 
170
 
 
171
            if(low.red != high.red)
 
172
                red = (equalize_map[red].red)/257;
 
173
 
 
174
            if(low.green != high.green)
 
175
                green = (equalize_map[green].green)/257;
 
176
 
 
177
            if(low.blue != high.blue)
 
178
                blue = (equalize_map[blue].blue)/257;
 
179
 
 
180
            if(low.alpha != high.alpha)
 
181
                alpha = (equalize_map[alpha].alpha)/257;
 
182
 
 
183
            ptr[0] = blue;
 
184
            ptr[1] = green;
 
185
            ptr[2] = red;
 
186
            ptr[3] = alpha;
 
187
            ptr   += 4;
 
188
 
 
189
            progress = (int)(((double)i * 100.0) / size);
 
190
            if ( progress%5 == 0 )
 
191
                postProgress( progress );
 
192
        }
 
193
    }
 
194
    else               // 16 bits image.
 
195
    {
 
196
        unsigned short  red, green, blue, alpha;
 
197
        unsigned short* ptr = (unsigned short *)data;
 
198
 
 
199
        for (i = 0 ; !m_cancel && (i < size) ; ++i)
 
200
        {
 
201
            blue  = ptr[0];
 
202
            green = ptr[1];
 
203
            red   = ptr[2];
 
204
            alpha = ptr[3];
 
205
 
 
206
            if(low.red != high.red)
 
207
                red = (equalize_map[red].red)/257;
 
208
 
 
209
            if(low.green != high.green)
 
210
                green = (equalize_map[green].green)/257;
 
211
 
 
212
            if(low.blue != high.blue)
 
213
                blue = (equalize_map[blue].blue)/257;
 
214
 
 
215
            if(low.alpha != high.alpha)
 
216
                alpha = (equalize_map[alpha].alpha)/257;
 
217
 
 
218
            ptr[0] = blue;
 
219
            ptr[1] = green;
 
220
            ptr[2] = red;
 
221
            ptr[3] = alpha;
 
222
            ptr   += 4;
 
223
 
 
224
            progress = (int)(((double)i * 100.0) / size);
 
225
            if ( progress%5 == 0 )
 
226
                postProgress( progress );
 
227
        }
 
228
    }
 
229
 
 
230
    delete [] equalize_map;
 
231
}
 
232
 
 
233
}  // namespace Digikam