"Fossies" - the Fresh Open Source Software Archive 
Member "pfstools-2.2.0/src/tmo/fattal02/pfstmo_fattal02.cpp" (12 Aug 2021, 8358 Bytes) of package /linux/privat/pfstools-2.2.0.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /**
2 * @file pfstmo_fattal02.cpp
3 * @brief Tone map XYZ channels using Fattal02 model
4 *
5 * Gradient Domain High Dynamic Range Compression
6 * R. Fattal, D. Lischinski, and M. Werman
7 * In ACM Transactions on Graphics, 2002.
8 *
9 *
10 * This file is a part of PFSTMO package.
11 * ----------------------------------------------------------------------
12 * Copyright (C) 2003,2004 Grzegorz Krawczyk
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * ----------------------------------------------------------------------
28 *
29 * @author Grzegorz Krawczyk, <krawczyk@mpi-sb.mpg.de>
30 *
31 * $Id: pfstmo_fattal02.cpp,v 1.10 2012/06/22 12:01:32 rafm Exp $
32 */
33
34 #include <config.h>
35
36 #include <iostream>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <getopt.h>
40 #include <math.h>
41
42 #include <pfs.h>
43
44 #include <algorithm>
45
46 #include "tmo_fattal02.h"
47
48 using namespace std;
49
50 #define PROG_NAME "pfstmo_fattal02"
51
52 /// verbose mode
53 bool verbose = false;
54
55 class QuietException
56 {
57 };
58
59 void printHelp()
60 {
61 fprintf( stderr, PROG_NAME " (" PACKAGE_STRING ") : \n"
62 "\t[--alpha <val>] [--beta <val>] \n"
63 "\t[--gamma <val>] \n"
64 "\t[--saturation <val>] \n"
65 "\t[--noise <val>] \n"
66 "\t[--detail-level <val>] \n"
67 "\t[--black-point <val>] [--white-point <val>] \n"
68 "\t[--multigrid] \n"
69 "\t[--verbose] [--help] \n"
70 "See man page for more information.\n" );
71 }
72
73 void pfstmo_fattal02( int argc, char* argv[] )
74 {
75 pfs::DOMIO pfsio;
76
77 //--- default tone mapping parameters;
78 float opt_alpha = 1.0f;
79 float opt_beta = 0.9f;
80 float opt_gamma = -1.0f; // not set (0.8 for fft solver, 1.0 otherwise)
81 float opt_saturation=0.8f;
82 float opt_noise = -1.0f; // not set
83 int opt_detail_level=-1; // not set (2 for fft solver, 0 otherwise)
84 float opt_black_point=0.1f;
85 float opt_white_point=0.5f;
86
87 // Use multigrid if FFTW lib not available
88 #if !defined(HAVE_FFTW3) || !defined(HAVE_OpenMP)
89 bool opt_fftsolver=false;
90 #else
91 bool opt_fftsolver=true;
92 #endif
93
94 static struct option cmdLineOptions[] = {
95 { "help", no_argument, NULL, 'h' },
96 { "verbose", no_argument, NULL, 'v' },
97 { "multigrid", no_argument, NULL, 'm' },
98 { "alpha", required_argument, NULL, 'a' },
99 { "beta", required_argument, NULL, 'b' },
100 { "gamma", required_argument, NULL, 'g' },
101 { "saturation", required_argument, NULL, 's' },
102 { "noise", required_argument, NULL, 'n' },
103 { "detail-level", required_argument, NULL, 'd' },
104 { "white-point", required_argument, NULL, 'w' },
105 { "black-point", required_argument, NULL, 'l' },
106 { NULL, 0, NULL, 0 }
107 };
108
109 int optionIndex = 0;
110 while( 1 ) {
111 int c = getopt_long (argc, argv, "hvma:b:g:s:n:d:w:k:", cmdLineOptions, &optionIndex);
112 if( c == -1 ) break;
113 switch( c ) {
114 case 'h':
115 printHelp();
116 throw QuietException();
117 case 'v':
118 verbose = true;
119 break;
120 case 'm':
121 opt_fftsolver = false;
122 break;
123 case 'a':
124 opt_alpha = (float)strtod( optarg, NULL );
125 if( opt_alpha<=0.0f )
126 throw pfs::Exception("alpha value out of range, should be >0");
127 break;
128 case 'b':
129 opt_beta = (float)strtod( optarg, NULL );
130 if( opt_beta<=0.0f )
131 throw pfs::Exception("beta value out of range, should be >0");
132 break;
133 case 'g':
134 opt_gamma = (float)strtod( optarg, NULL );
135 if( opt_gamma<=0.0f || opt_gamma>=10.0 )
136 throw pfs::Exception("gamma value out of range, should be >0");
137 break;
138 case 's':
139 opt_saturation = (float)strtod( optarg, NULL );
140 if( opt_saturation<=0.0f || opt_saturation>1.0f )
141 throw pfs::Exception("saturation value out of range, should be 0..1");
142 break;
143 case 'n':
144 opt_noise = (float)strtod( optarg, NULL );
145 if( opt_noise<0.0f )
146 throw pfs::Exception("noise level value out of range, should be >=0");
147 break;
148 case 'd':
149 opt_detail_level = (int) strtod( optarg, NULL );
150 if( opt_detail_level<0 || opt_detail_level>9 )
151 throw pfs::Exception("detail-level value out of range, should be 0..9");
152 break;
153 case 'w':
154 opt_white_point = (float)strtod( optarg, NULL );
155 if( opt_white_point<0.0f || opt_white_point>=50.0f )
156 throw pfs::Exception("white-point value out of range, should be 0..50");
157 break;
158 case 'k':
159 opt_black_point = (float)strtod( optarg, NULL );
160 if( opt_black_point<0.0f || opt_black_point>=50.0f )
161 throw pfs::Exception("black-point value out of range, should be 0..50");
162 break;
163 case '?':
164 throw QuietException();
165 case ':':
166 throw QuietException();
167 }
168 }
169
170 if( opt_fftsolver ) {
171 // Default params for the fftsolver
172 if(opt_detail_level==-1)
173 opt_detail_level=3; // 2 for low res, 3 is better for high res
174 if(opt_gamma==-1.0f)
175 opt_gamma=0.8f;
176 if(opt_noise==-1.0f)
177 opt_noise=0.002f;
178 }
179
180
181 // adjust noise floor if not set by user
182 if( opt_noise<0.0f )
183 opt_noise = opt_alpha*0.01;
184 // set gamma and detail level to default values which produce the
185 // same output as older programme versions using the multi-level pde solver
186 if(opt_detail_level==-1)
187 opt_detail_level=0;
188 if(opt_gamma==-1.0f)
189 opt_gamma=1.0f;
190
191 VERBOSE_STR << "threshold gradient (alpha): " << opt_alpha << endl;
192 VERBOSE_STR << "strengh of modification (beta): " << opt_beta << endl;
193 VERBOSE_STR << "gamma: " << opt_gamma << endl;
194 VERBOSE_STR << "noise floor: " << opt_noise << endl;
195 VERBOSE_STR << "saturation: " << opt_saturation << endl;
196 VERBOSE_STR << "detail level: " << opt_detail_level << endl;
197 VERBOSE_STR << "white point: " << opt_white_point << "%" << endl;
198 VERBOSE_STR << "black point: " << opt_black_point << "%" << endl;
199 VERBOSE_STR << "use fft pde solver: " << opt_fftsolver << endl;
200
201 while( true )
202 {
203 pfs::Frame *frame = pfsio.readFrame( stdin );
204 if( frame == NULL ) break; // No more frames
205
206 pfs::Channel *X, *Y, *Z;
207 frame->getXYZChannels( X, Y, Z );
208 frame->getTags()->setString("LUMINANCE", "RELATIVE");
209 //---
210
211 if( Y==NULL || X==NULL || Z==NULL)
212 throw pfs::Exception( "Missing X, Y, Z channels in the PFS stream" );
213
214 // tone mapping
215 int w = Y->getCols();
216 int h = Y->getRows();
217
218 pfs::Array2DImpl* L = new pfs::Array2DImpl(w,h);
219 tmo_fattal02(w, h, Y->getRawData(), L->getRawData(), opt_alpha, opt_beta,
220 opt_gamma, opt_noise, opt_detail_level,
221 opt_black_point, opt_white_point, opt_fftsolver);
222
223 // in-place color space transform
224 pfs::Array2DImpl *G = new pfs::Array2DImpl( w, h ); // copy for G to preserve Y
225 pfs::Array2D *R = X, *B = Z;
226 pfs::transformColorSpace( pfs::CS_XYZ, X, Y, Z, pfs::CS_RGB, R, G, B );
227
228 // Color correction
229 for( int i=0; i < w*h; i++ )
230 {
231 const float epsilon = 1e-4f;
232 float y = std::max( (*Y)(i), epsilon );
233 float l = std::max( (*L)(i), epsilon );
234 (*R)(i) = powf( std::max((*R)(i)/y,0.f), opt_saturation ) * l;
235 (*G)(i) = powf( std::max((*G)(i)/y,0.f), opt_saturation ) * l;
236 (*B)(i) = powf( std::max((*B)(i)/y,0.f), opt_saturation ) * l;
237 }
238
239
240 pfs::transformColorSpace( pfs::CS_RGB, R, G, B, pfs::CS_XYZ, X, Y, Z );
241
242 delete G;
243 delete L;
244
245 //---
246 pfsio.writeFrame( frame, stdout );
247 pfsio.freeFrame( frame );
248 }
249 }
250
251 int main( int argc, char* argv[] )
252 {
253 try {
254 pfstmo_fattal02( argc, argv );
255 }
256 catch( pfs::Exception ex ) {
257 fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() );
258 return EXIT_FAILURE;
259 }
260 catch( QuietException ex ) {
261 return EXIT_FAILURE;
262 }
263 return EXIT_SUCCESS;
264 }