/** * @brief Contrast mapping TMO * * From: * * Rafal Mantiuk, Karol Myszkowski, Hans-Peter Seidel. * A Perceptual Framework for Contrast Processing of High Dynamic Range Images * In: ACM Transactions on Applied Perception 3 (3), pp. 286-308, 2006 * http://www.mpi-inf.mpg.de/~mantiuk/contrast_domain/ * * This file is a part of PFSTMO package. * ---------------------------------------------------------------------- * Copyright (C) 2007 Grzegorz Krawczyk * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ---------------------------------------------------------------------- * * @author Radoslaw Mantiuk, * * $Id: pfstmo_mantiuk06.cpp,v 1.5 2007/06/16 19:23:08 rafm Exp $ */ #include #include #include #include #include #include #include #include #include #include "contrast_domain.h" #define PROG_NAME "pfstmo_mantiuk06" class QuietException { }; using namespace std; void printHelp() { fprintf( stderr, PROG_NAME " (" PACKAGE_STRING ") : \n" "\t[--factor ] [--saturation ] [--equalize-contrast]\n" "\t[--help] \n" "See man page for more information.\n" ); } bool verbose = false; void progress_report( int progress ) { if( verbose ) { fprintf( stderr, "\rcompleted %d%%", progress ); if( progress == 100 ) fprintf( stderr, "\n" ); } } void tmo_mantiuk06(int argc, char * argv[]) { //--- default tone mapping parameters; float scaleFactor = 0.3f; float saturationFactor = 0.8f; bool cont_map = false, cont_eq = false; //--- process command line args static struct option cmdLineOptions[] = { { "help", no_argument, NULL, 'h' }, { "verbose", no_argument, NULL, 'v' }, { "factor", required_argument, NULL, 'f' }, { "saturation", required_argument, NULL, 's' }, { "equalize-contrast", no_argument, NULL, 'e' }, { NULL, 0, NULL, 0 } }; int optionIndex = 0; while( 1 ) { int c = getopt_long (argc, argv, "vhf:s:e", cmdLineOptions, &optionIndex); if( c == -1 ) break; switch( c ) { case 'h': printHelp(); throw QuietException(); case 'v': verbose = true; break; case 'e': scaleFactor = 0; cont_eq = true; break; case 's': saturationFactor = (float)strtod( optarg, NULL ); if( saturationFactor < 0.0f || saturationFactor > 1.0f ) throw pfs::Exception("incorrect saturation factor, accepted range is (0..1)"); break; case 'f': cont_map = true; scaleFactor = (float)strtod( optarg, NULL ); if( scaleFactor < 0.0f || scaleFactor > 1.0f ) throw pfs::Exception("incorrect contrast scale factor, accepted range is (0..1)"); break; case '?': throw QuietException(); case ':': throw QuietException(); } } if( cont_eq && cont_map ) throw pfs::Exception( "the 'factor' parameter cannot be used in combination with contrast equalization" ); if( scaleFactor == 0 ) { VERBOSE_STR << "algorithm: contrast equalization" << endl; } else { VERBOSE_STR << "algorithm: contrast mapping" << endl; VERBOSE_STR << "contrast scale factor = " << scaleFactor << endl; } VERBOSE_STR << "saturation factor = " << saturationFactor << endl; pfs::DOMIO pfsio; pfs::Frame *frame = pfsio.readFrame( stdin ); if( frame == NULL ) { return; } pfs::Channel *inX, *inY, *inZ; frame->getXYZChannels(inX, inY, inZ); int cols = frame->getWidth(); int rows = frame->getHeight(); pfs::Array2DImpl R( cols, rows ); pfs::transformColorSpace( pfs::CS_XYZ, inX, inY, inZ, pfs::CS_RGB, inX, &R, inZ ); tmo_mantiuk06_contmap( cols, rows, inX->getRawData(), R.getRawData(), inZ->getRawData(), inY->getRawData(), scaleFactor, saturationFactor, progress_report ); pfs::transformColorSpace( pfs::CS_RGB, inX, inY, inZ, pfs::CS_XYZ, inX, inY, inZ ); frame->getTags()->setString("LUMINANCE", "RELATIVE"); pfsio.writeFrame( frame, stdout ); pfsio.freeFrame(frame); } int main( int argc, char* argv[] ) { try { tmo_mantiuk06( argc, argv ); } catch( pfs::Exception ex ) { fprintf( stderr, PROG_NAME " error: %s\n", ex.getMessage() ); return EXIT_FAILURE; } catch( QuietException ex ) { return EXIT_FAILURE; } return EXIT_SUCCESS; }