~ubuntu-branches/ubuntu/natty/qtpfsgui/natty

« back to all changes in this revision

Viewing changes to src/Threads/tonemapper_thread.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2008-01-06 04:39:36 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080106043936-a9u9g7yih3w16ru5
Tags: 1.9.0-1
* New upstream release.
* Replace “COPYING” with “LICENSE” in the NOT_NEEDED variable of
  debian/rules, following upstream's renaming.
* Update debian/links accordingly.
* Delete the matching TODO item since there's no longer needed to have a
  patched (with HTML tags) license file to get a correct display in the
  “License agreement” tab.
* Update the gcc4.3 patch (drop the hunk touching src/Libpfs/pfs.cpp):
   - 20_gcc4.3_includes.
* Add a link from /usr/share/qtpfsgui/html to the HTML documentation
  under /usr/share/doc/qtpfsgui/html since the former is used at runtime
  to display the manual.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * This file is a part of Qtpfsgui package.
3
 
 * ---------------------------------------------------------------------- 
4
 
 * Copyright (C) 2006,2007 Giuseppe Rota
5
 
 * 
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 * ---------------------------------------------------------------------- 
20
 
 *
21
 
 * @author Giuseppe Rota <grota@users.sourceforge.net>
22
 
 */
23
 
 
24
 
#include "tonemapper_thread.h"
25
 
#include <QProgressBar>
26
 
pfs::Frame* resizeFrame(pfs::Frame* inpfsframe, int _xSize);
27
 
void applyGammaFrame( pfs::Frame*, const float);
28
 
pfs::Frame* pfstmo_ashikhmin02 (pfs::Frame*,bool,float,int);
29
 
pfs::Frame* pfstmo_drago03 (pfs::Frame *, float);
30
 
pfs::Frame* pfstmo_fattal02 (pfs::Frame*,float,float,float,float,bool);
31
 
pfs::Frame* pfstmo_durand02 (pfs::Frame*,float,float,float);
32
 
pfs::Frame* pfstmo_pattanaik00 (pfs::Frame*,bool,float,float,float,bool);
33
 
pfs::Frame* pfstmo_reinhard02 (pfs::Frame*,float,float,int,int,int,bool);
34
 
pfs::Frame* pfstmo_reinhard04 (pfs::Frame *,float,float,float);
35
 
pfs::Frame* pfstmo_mantiuk06(pfs::Frame*,float,float,bool);
36
 
 
37
 
// width of the pfs:frame written on disk during resize operation, cannot be the 100% size: originalxsize, because i don't resize to 100% and write to disk.
38
 
int xsize=-1; //-1 means nothing has been computed yet
39
 
// gamma of the pfs:frame written on disk after resize
40
 
float pregamma=-1; //-1 means NOT VALID (size has changed/is changing)
41
 
//pregamma!=-1 means that the pregamma frame has the xsize as width
42
 
QReadWriteLock lock;
43
 
 
44
 
 
45
 
TonemapperThread::TonemapperThread(int xorigsize, QString cachepath, QProgressBar* b) : QThread(0), bar(b), originalxsize(xorigsize), cachepath(cachepath){
46
 
        colorspaceconversion=false;
47
 
}
48
 
 
49
 
TonemapperThread::~TonemapperThread() {
50
 
        wait();
51
 
//      qDebug("~TonemapperThread()");
52
 
}
53
 
 
54
 
void TonemapperThread::fetch(QString filename) {
55
 
        pfs::DOMIO pfsio;
56
 
        workingframe=pfsio.readFrame(cachepath+filename);
57
 
}
58
 
 
59
 
void TonemapperThread::swap(pfs::Frame *frame, QString filename) {
60
 
        //swap frame to hd
61
 
        pfs::DOMIO pfsio;
62
 
        pfsio.writeFrame(frame,cachepath+filename);
63
 
}
64
 
 
65
 
void TonemapperThread::run() {
66
 
//      dumpOpts();
67
 
//      qDebug("::::::begin thread, size=%d, gamma=%f",xsize, pregamma);
68
 
        lock.lockForRead();
69
 
        if (opt.xsize==originalxsize && opt.pregamma==1.0f) {
70
 
                //original goes into tone mapping
71
 
                qDebug("::::::original goes into tone mapping");
72
 
                fetch("/original.pfs");
73
 
                status=from_tm;
74
 
                colorspaceconversion=true;
75
 
                emit setMaximumSteps(2);
76
 
        } else if (opt.xsize==xsize && opt.pregamma==1.0f) {
77
 
                //resized goes into tone mapping
78
 
                qDebug("::::::resized goes into tone mapping");
79
 
                fetch("/after_resize.pfs");
80
 
                status=from_tm;
81
 
                colorspaceconversion=true;
82
 
                emit setMaximumSteps(2);
83
 
        } else if ( (opt.xsize==xsize && opt.pregamma==pregamma) || (opt.xsize==originalxsize && xsize==-1 && opt.pregamma==pregamma) ) {
84
 
                //after_pregamma goes into tone mapping
85
 
                qDebug("::::::after_pregamma goes into tone mapping");
86
 
                fetch("/after_pregamma.pfs");
87
 
                status=from_tm;
88
 
                emit setMaximumSteps(2);
89
 
        } else if (opt.xsize==xsize) {
90
 
                //resized goes into pregamma
91
 
                qDebug("::::::resized goes into pregamma");
92
 
                fetch("/after_resize.pfs");
93
 
                status=from_pregamma;
94
 
                emit setMaximumSteps(3);
95
 
        } else if (opt.xsize==originalxsize) {
96
 
                //original goes into pregamma
97
 
                qDebug("::::::original goes into pregamma");
98
 
                fetch("/original.pfs");
99
 
                status=from_pregamma;
100
 
                emit setMaximumSteps(3);
101
 
        } else {
102
 
                //original goes into resize
103
 
                qDebug("::::::original goes into resize");
104
 
                fetch("/original.pfs");
105
 
                status=from_resize;
106
 
                emit setMaximumSteps(4);
107
 
        }
108
 
        emit setCurrentProgress(1);
109
 
        lock.unlock();
110
 
 
111
 
 
112
 
        if (status==from_resize) {
113
 
                assert(opt.xsize!=originalxsize);
114
 
                qDebug("executing resize step");
115
 
                pfs::Frame *resized=resizeFrame(workingframe, opt.xsize);
116
 
                lock.lockForWrite();
117
 
                swap(resized,"/after_resize.pfs");
118
 
                xsize=opt.xsize;
119
 
                pregamma=-1;
120
 
                lock.unlock();
121
 
                delete workingframe;
122
 
                workingframe=resized;
123
 
                status=from_pregamma;
124
 
                if (bar) emit setCurrentProgress(bar->value()+1);
125
 
        }
126
 
        if (status==from_pregamma) {
127
 
                qDebug("executing pregamma step");
128
 
                applyGammaFrame( workingframe, opt.pregamma );
129
 
                lock.lockForWrite();
130
 
                swap(workingframe,"/after_pregamma.pfs");
131
 
                pregamma=opt.pregamma;
132
 
                if (opt.xsize==originalxsize)
133
 
                        xsize=-1;
134
 
                else
135
 
                        xsize=opt.xsize;
136
 
                lock.unlock();
137
 
                status=from_tm;
138
 
                if (bar) emit setCurrentProgress(bar->value()+1);
139
 
        }
140
 
        if (status==from_tm) {
141
 
                qDebug("executing tone mapping step");
142
 
                if (colorspaceconversion)
143
 
                        workingframe->convertRGBChannelsToXYZ();
144
 
                pfs::Frame *result=NULL;
145
 
                switch (opt.tmoperator) {
146
 
                case mantiuk:
147
 
                        result=pfstmo_mantiuk06(workingframe,
148
 
                        opt.operator_options.mantiukoptions.contrastfactor,
149
 
                        opt.operator_options.mantiukoptions.saturationfactor,
150
 
                        opt.operator_options.mantiukoptions.contrastequalization);
151
 
                break;
152
 
                case fattal:
153
 
                        //fattal is NOT even reentrant! (problem in PDE solving)
154
 
                        //therefore I need to use a mutex here
155
 
                        lock.lockForWrite();
156
 
                        result=pfstmo_fattal02(workingframe,
157
 
                        opt.operator_options.fattaloptions.alpha,
158
 
                        opt.operator_options.fattaloptions.beta,
159
 
                        opt.operator_options.fattaloptions.color,
160
 
                        opt.operator_options.fattaloptions.noiseredux,
161
 
                        opt.operator_options.fattaloptions.newfattal);
162
 
                        lock.unlock();
163
 
                break;
164
 
                case ashikhmin:
165
 
                        result=pfstmo_ashikhmin02(workingframe,
166
 
                        opt.operator_options.ashikhminoptions.simple,
167
 
                        opt.operator_options.ashikhminoptions.lct,
168
 
                        opt.operator_options.ashikhminoptions.eq2 ? 2 : 4);
169
 
                break;
170
 
                case durand:
171
 
                        //even durand seems to be not reentrant
172
 
                        lock.lockForWrite();
173
 
                        result=pfstmo_durand02(workingframe,
174
 
                        opt.operator_options.durandoptions.spatial,
175
 
                        opt.operator_options.durandoptions.range,
176
 
                        opt.operator_options.durandoptions.base);
177
 
                        lock.unlock();
178
 
                break;
179
 
                case drago:
180
 
                        result=pfstmo_drago03(workingframe, opt.operator_options.dragooptions.bias);
181
 
                break;
182
 
                case pattanaik:
183
 
                        result=pfstmo_pattanaik00(workingframe,
184
 
                        opt.operator_options.pattanaikoptions.local,
185
 
                        opt.operator_options.pattanaikoptions.multiplier,
186
 
                        opt.operator_options.pattanaikoptions.cone,
187
 
                        opt.operator_options.pattanaikoptions.rod,
188
 
                        opt.operator_options.pattanaikoptions.autolum);
189
 
                break;
190
 
                case reinhard02:
191
 
                        result=pfstmo_reinhard02(workingframe,
192
 
                        opt.operator_options.reinhard02options.key,
193
 
                        opt.operator_options.reinhard02options.phi,
194
 
                        opt.operator_options.reinhard02options.range,
195
 
                        opt.operator_options.reinhard02options.lower,
196
 
                        opt.operator_options.reinhard02options.upper,
197
 
                        opt.operator_options.reinhard02options.scales);
198
 
                break;
199
 
                case reinhard04:
200
 
                        result=pfstmo_reinhard04(workingframe,
201
 
                        opt.operator_options.reinhard04options.brightness,
202
 
                        opt.operator_options.reinhard04options.chromaticAdaptation,
203
 
                        opt.operator_options.reinhard04options.lightAdaptation);
204
 
                break;
205
 
                }
206
 
        if (bar) emit setCurrentProgress(bar->value()+1);
207
 
        assert(result!=NULL);
208
 
        delete workingframe;
209
 
        const QImage& res=fromLDRPFStoQImage(result);
210
 
        delete result;
211
 
        emit ImageComputed(res,&opt);
212
 
        if (bar) emit removeProgressBar(bar);
213
 
        }
214
 
}
215
 
 
216
 
#if 0
217
 
void TonemapperThread::dumpOpts() {
218
 
        qDebug("dump: opt.xsize=%d",opt.xsize);
219
 
        qDebug("dump: opt.pregamma=%f",opt.pregamma);
220
 
        switch (opt.tmoperator) {
221
 
        case fattal:
222
 
                qDebug("dump: fattal");
223
 
                qDebug("dump: opt.alpha=%f",opt.operator_options.fattaloptions.alpha);
224
 
                qDebug("dump: opt.beta=%f",opt.operator_options.fattaloptions.beta);
225
 
                qDebug("dump: opt.color=%f",opt.operator_options.fattaloptions.color);
226
 
        break;
227
 
        case ashikhmin:
228
 
                qDebug("dump: ashikhmin");
229
 
                qDebug(opt.operator_options.ashikhminoptions.simple? "dump: opt.simple=true" : "dump: opt.simple=false");
230
 
                qDebug("dump: opt.lct=%f",opt.operator_options.ashikhminoptions.lct);
231
 
                qDebug("dump: opt.eq=%d",
232
 
 opt.operator_options.ashikhminoptions.eq2 ? 2 : 4);
233
 
        break;
234
 
        case durand:
235
 
                qDebug("dump: durand");
236
 
                qDebug("dump: opt.spatial=%f",opt.operator_options.durandoptions.spatial);
237
 
                qDebug("dump: opt.range=%f",opt.operator_options.durandoptions.range);
238
 
                qDebug("dump: opt.base=%f",opt.operator_options.durandoptions.base);
239
 
        break;
240
 
        case drago:
241
 
                qDebug("dump: drago");
242
 
                qDebug("dump: opt.bias=%f",opt.operator_options.dragooptions.bias);
243
 
        break;
244
 
        case pattanaik:
245
 
                qDebug("dump: pattanaik");
246
 
                qDebug(opt.operator_options.pattanaikoptions.local?"dump: opt.local=true":"dump: opt.local=false");
247
 
                qDebug(opt.operator_options.pattanaikoptions.autolum?"dump: opt.autolum=true":"dump: opt.autolum=false");
248
 
                qDebug("dump: opt.multiplier=%f",opt.operator_options.pattanaikoptions.multiplier);
249
 
                qDebug("dump: opt.cone=%f",opt.operator_options.pattanaikoptions.cone);
250
 
                qDebug("dump: opt.rod=%f",opt.operator_options.pattanaikoptions.rod);
251
 
        break;
252
 
        case reinhard02:
253
 
                qDebug("dump: reinhard02");
254
 
                qDebug(opt.operator_options.reinhard02options.scales?"dump: opt.scales=true":"dump: opt.scales=false");
255
 
                qDebug("dump: opt.key=%f",opt.operator_options.reinhard02options.key);
256
 
                qDebug("dump: opt.phi=%f",opt.operator_options.reinhard02options.phi);
257
 
                qDebug("dump: opt.range=%d",opt.operator_options.reinhard02options.range);
258
 
                qDebug("dump: opt.lower=%d",opt.operator_options.reinhard02options.lower);
259
 
                qDebug("dump: opt.upper=%d",opt.operator_options.reinhard02options.upper);
260
 
        break;
261
 
        case reinhard04:
262
 
                qDebug("dump: reinhard04");
263
 
                qDebug("dump: opt.brightness=%f",opt.operator_options.reinhard04options.brightness);
264
 
                qDebug("dump: opt.saturation=%f",opt.operator_options.reinhard04options.saturation);
265
 
        break;
266
 
        }
267
 
}
268
 
#endif
269
 
 
270
 
void TonemapperThread::ComputeImage(const tonemapping_options opt) {
271
 
        this->opt=opt;
272
 
        if (!isRunning()) {
273
 
#ifdef _WIN32
274
 
                start();
275
 
#else
276
 
                start(HighestPriority);
277
 
#endif
278
 
        }
279
 
}