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

« back to all changes in this revision

Viewing changes to src/Threads/tonemapperThread.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 "tonemapperThread.h"
 
25
#include <QDir>
 
26
#include "../Common/config.h"
 
27
pfs::Frame* resizeFrame(pfs::Frame* inpfsframe, int _xSize);
 
28
void applyGammaFrame( pfs::Frame*, const float);
 
29
pfs::Frame* pfstmo_ashikhmin02 (pfs::Frame*,bool,float,int);
 
30
pfs::Frame* pfstmo_drago03 (pfs::Frame *, float);
 
31
pfs::Frame* pfstmo_fattal02 (pfs::Frame*,float,float,float,float,bool);
 
32
pfs::Frame* pfstmo_durand02 (pfs::Frame*,float,float,float);
 
33
pfs::Frame* pfstmo_pattanaik00 (pfs::Frame*,bool,float,float,float,bool);
 
34
pfs::Frame* pfstmo_reinhard02 (pfs::Frame*,float,float,int,int,int,bool);
 
35
pfs::Frame* pfstmo_reinhard05 (pfs::Frame *,float,float,float);
 
36
pfs::Frame* pfstmo_mantiuk06(pfs::Frame*,float,float,bool);
 
37
 
 
38
// 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.
 
39
int xsize=-1; //-1 means nothing has been computed yet
 
40
// gamma of the pfs:frame written on disk after resize
 
41
float pregamma=-1; //-1 means NOT VALID (size has changed/is changing)
 
42
//pregamma!=-1 means that the pregamma frame has the xsize as width
 
43
QReadWriteLock lock;
 
44
 
 
45
 
 
46
TonemapperThread::TonemapperThread(int xorigsize, const tonemapping_options opts) : QThread(0), originalxsize(xorigsize), settings("Qtpfsgui", "Qtpfsgui"), opts(opts) {
 
47
        colorspaceconversion=false;
 
48
        settings.beginGroup(GROUP_TONEMAPPING);
 
49
        cachepath=settings.value(KEY_TEMP_RESULT_PATH,QDir::currentPath()).toString();
 
50
        settings.endGroup();
 
51
 
 
52
        connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
 
53
        setTerminationEnabled(true);
 
54
        forciblyTerminated=false;
 
55
}
 
56
 
 
57
TonemapperThread::~TonemapperThread() {
 
58
        if (!forciblyTerminated) {
 
59
                wait();
 
60
        }
 
61
}
 
62
 
 
63
void TonemapperThread::fetch(QString filename) {
 
64
        pfs::DOMIO pfsio;
 
65
        workingframe=pfsio.readFrame(cachepath+filename);
 
66
}
 
67
 
 
68
void TonemapperThread::swap(pfs::Frame *frame, QString filename) {
 
69
        //swap frame to hd
 
70
        pfs::DOMIO pfsio;
 
71
        pfsio.writeFrame(frame,cachepath+filename);
 
72
}
 
73
 
 
74
void TonemapperThread::run() {
 
75
        qDebug("TMthread::begin thread, size=%d, gamma=%f",xsize, pregamma);
 
76
        lock.lockForRead();
 
77
        if (opts.xsize==originalxsize && opts.pregamma==1.0f) {
 
78
                //original goes into tone mapping
 
79
                qDebug("TMthread::original goes into tone mapping");
 
80
                fetch("/original.pfs");
 
81
                status=from_tm;
 
82
                colorspaceconversion=true;
 
83
                emit setMaximumSteps(2);
 
84
        } else if (opts.xsize==xsize && opts.pregamma==1.0f) {
 
85
                //resized goes into tone mapping
 
86
                qDebug("TMthread::resized goes into tone mapping");
 
87
                fetch("/after_resize.pfs");
 
88
                status=from_tm;
 
89
                colorspaceconversion=true;
 
90
                emit setMaximumSteps(2);
 
91
        } else if ( (opts.xsize==xsize && opts.pregamma==pregamma) || (opts.xsize==originalxsize && xsize==-1 && opts.pregamma==pregamma) ) {
 
92
                //after_pregamma goes into tone mapping
 
93
                qDebug("TMthread::after_pregamma goes into tone mapping");
 
94
                fetch("/after_pregamma.pfs");
 
95
                status=from_tm;
 
96
                emit setMaximumSteps(2);
 
97
        } else if (opts.xsize==xsize) {
 
98
                //resized goes into pregamma
 
99
                qDebug("TMthread::resized goes into pregamma");
 
100
                fetch("/after_resize.pfs");
 
101
                status=from_pregamma;
 
102
                emit setMaximumSteps(3);
 
103
        } else if (opts.xsize==originalxsize) {
 
104
                //original goes into pregamma
 
105
                qDebug("TMthread::original goes into pregamma");
 
106
                fetch("/original.pfs");
 
107
                status=from_pregamma;
 
108
                emit setMaximumSteps(3);
 
109
        } else {
 
110
                //original goes into resize
 
111
                qDebug("TMthread::original goes into resize");
 
112
                fetch("/original.pfs");
 
113
                status=from_resize;
 
114
                emit setMaximumSteps(4);
 
115
        }
 
116
        emit advanceCurrentProgress();
 
117
        lock.unlock();
 
118
 
 
119
 
 
120
        if (status==from_resize) {
 
121
                assert(opts.xsize!=originalxsize);
 
122
                qDebug("TMthread:: executing resize step");
 
123
                pfs::Frame *resized=resizeFrame(workingframe, opts.xsize);
 
124
                lock.lockForWrite();
 
125
                swap(resized,"/after_resize.pfs");
 
126
                xsize=opts.xsize;
 
127
                pregamma=-1;
 
128
                lock.unlock();
 
129
                delete workingframe;
 
130
                workingframe=resized;
 
131
                status=from_pregamma;
 
132
                emit advanceCurrentProgress();
 
133
        }
 
134
        if (status==from_pregamma) {
 
135
                qDebug("TMthread:: executing pregamma step");
 
136
                applyGammaFrame( workingframe, opts.pregamma );
 
137
                lock.lockForWrite();
 
138
                swap(workingframe,"/after_pregamma.pfs");
 
139
                pregamma=opts.pregamma;
 
140
                if (opts.xsize==originalxsize)
 
141
                        xsize=-1;
 
142
                else
 
143
                        xsize=opts.xsize;
 
144
                lock.unlock();
 
145
                status=from_tm;
 
146
                emit advanceCurrentProgress();
 
147
        }
 
148
        if (status==from_tm) {
 
149
                qDebug("TMthread:: executing tone mapping step");
 
150
                if (colorspaceconversion)
 
151
                        workingframe->convertRGBChannelsToXYZ();
 
152
                pfs::Frame *result=NULL;
 
153
                switch (opts.tmoperator) {
 
154
                case mantiuk:
 
155
                        result=pfstmo_mantiuk06(workingframe,
 
156
                        opts.operator_options.mantiukoptions.contrastfactor,
 
157
                        opts.operator_options.mantiukoptions.saturationfactor,
 
158
                        opts.operator_options.mantiukoptions.contrastequalization);
 
159
                break;
 
160
                case fattal:
 
161
                        //fattal is NOT even reentrant! (problem in PDE solving)
 
162
                        //therefore I need to use a mutex here
 
163
                        lock.lockForWrite();
 
164
                        result=pfstmo_fattal02(workingframe,
 
165
                        opts.operator_options.fattaloptions.alpha,
 
166
                        opts.operator_options.fattaloptions.beta,
 
167
                        opts.operator_options.fattaloptions.color,
 
168
                        opts.operator_options.fattaloptions.noiseredux,
 
169
                        opts.operator_options.fattaloptions.newfattal);
 
170
                        lock.unlock();
 
171
                break;
 
172
                case ashikhmin:
 
173
                        result=pfstmo_ashikhmin02(workingframe,
 
174
                        opts.operator_options.ashikhminoptions.simple,
 
175
                        opts.operator_options.ashikhminoptions.lct,
 
176
                        opts.operator_options.ashikhminoptions.eq2 ? 2 : 4);
 
177
                break;
 
178
                case durand:
 
179
                        //even durand seems to be not reentrant
 
180
                        lock.lockForWrite();
 
181
                        result=pfstmo_durand02(workingframe,
 
182
                        opts.operator_options.durandoptions.spatial,
 
183
                        opts.operator_options.durandoptions.range,
 
184
                        opts.operator_options.durandoptions.base);
 
185
                        lock.unlock();
 
186
                break;
 
187
                case drago:
 
188
                        result=pfstmo_drago03(workingframe, opts.operator_options.dragooptions.bias);
 
189
                break;
 
190
                case pattanaik:
 
191
                        result=pfstmo_pattanaik00(workingframe,
 
192
                        opts.operator_options.pattanaikoptions.local,
 
193
                        opts.operator_options.pattanaikoptions.multiplier,
 
194
                        opts.operator_options.pattanaikoptions.cone,
 
195
                        opts.operator_options.pattanaikoptions.rod,
 
196
                        opts.operator_options.pattanaikoptions.autolum);
 
197
                break;
 
198
                case reinhard02:
 
199
                        result=pfstmo_reinhard02(workingframe,
 
200
                        opts.operator_options.reinhard02options.key,
 
201
                        opts.operator_options.reinhard02options.phi,
 
202
                        opts.operator_options.reinhard02options.range,
 
203
                        opts.operator_options.reinhard02options.lower,
 
204
                        opts.operator_options.reinhard02options.upper,
 
205
                        opts.operator_options.reinhard02options.scales);
 
206
                break;
 
207
                case reinhard05:
 
208
                        result=pfstmo_reinhard05(workingframe,
 
209
                        opts.operator_options.reinhard05options.brightness,
 
210
                        opts.operator_options.reinhard05options.chromaticAdaptation,
 
211
                        opts.operator_options.reinhard05options.lightAdaptation);
 
212
                break;
 
213
                } //switch (opts.tmoperator)
 
214
                emit advanceCurrentProgress();
 
215
                assert(result!=NULL);
 
216
                delete workingframe;
 
217
                const QImage& res=fromLDRPFStoQImage(result);
 
218
                delete result;
 
219
                emit ImageComputed(res,&opts);
 
220
        } //if (status==from_tm)
 
221
//      emit finished();
 
222
}
 
223
 
 
224
void TonemapperThread::terminateRequested() {
 
225
        if (forciblyTerminated)
 
226
                return;
 
227
        lock.lockForWrite();
 
228
        pregamma=-1;
 
229
        xsize=-1;
 
230
        lock.unlock();
 
231
        forciblyTerminated=true;
 
232
        //HACK oddly enough for the other operators we cannot emit finished (it segfaults)
 
233
        if (opts.tmoperator==mantiuk || opts.tmoperator==ashikhmin || opts.tmoperator==pattanaik )
 
234
                emit finished();
 
235
        terminate();
 
236
}
 
237