36
36
void writeRGBEfile (pfs::Frame* inputpfsframe, const char* outfilename);
37
37
void writeEXRfile (pfs::Frame* inputpfsframe, const char* outfilename);
39
#if defined(__FreeBSD__) || defined(WIN32)
40
40
#define error(Z) { fprintf(stderr,Z); exit(1); }
43
43
#define error(Z) error(1,0,Z);
46
///string is a QString with a %1 in it
47
#define VERBOSEPRINT( string, argument ) \
49
fprintf(stdout, qPrintable(tr( string "\n" ).arg( argument )) ); \
47
53
static struct option cmdLineOptions[] = {
48
54
{ "verbose", no_argument, NULL, 'v' },
63
69
CommandLineInterfaceManager::CommandLineInterfaceManager(const int argc, char **argv) : argc(argc), argv(argv) {
64
70
hdrCreationManager=NULL;
65
71
align_mode=NO_ALIGN;
66
qtpfsgui_options=new qtpfsgui_opts();
67
QtPfsGuiOptions::loadOptions(qtpfsgui_options);
72
qtpfsgui_options=QtpfsguiOptions::getInstance();
68
73
connect(this,SIGNAL(startParsing()),this,SLOT(parseArgs()),Qt::QueuedConnection);
69
74
emit startParsing();
289
294
for (int index = optind; index < argc; index++) {
290
295
inputFiles << QString(argv[index]);
291
qDebug("Input file %s", argv[index]);
296
VERBOSEPRINT("Input file %1" , argv[index]);
294
299
if (!ev.isEmpty() && ev.count()!=inputFiles.count())
295
300
error(qPrintable(tr("Error: The number of EV values specified is different from the number of input files.")));
297
302
//now validate operation mode.
298
if (inputFiles.size()!=0 && loadHdrFilename.isEmpty())
303
if (inputFiles.size()!=0 && loadHdrFilename.isEmpty()) {
299
304
operation_mode=CREATE_HDR_MODE;
300
else if (!loadHdrFilename.isEmpty() && inputFiles.size()==0 )
305
VERBOSEPRINT("Running in HDR-creation mode. %1" , "");
306
} else if (!loadHdrFilename.isEmpty() && inputFiles.size()==0 ) {
301
307
operation_mode=LOAD_HDR_MODE;
308
VERBOSEPRINT("Running in Load-HDR mode. %1" , "");
303
310
printHelp(argv[0]);
304
311
error("Wrong combination of parameters.");
307
314
if (operation_mode==CREATE_HDR_MODE) {
308
QSettings settings("Qtpfsgui", "Qtpfsgui");
309
QString temppath = settings.value(KEY_TEMP_RESULT_PATH, QDir::currentPath()).toString();
310
int numthreads=settings.value(KEY_NUM_BATCH_THREADS,1).toInt();
311
QStringList rawopts=settings.value(KEY_EXTERNAL_DCRAW_OPTIONS,"-T").toStringList();
312
hdrCreationManager = new HdrCreationManager(numthreads, temppath, rawopts);
316
VERBOSEPRINT("Temporary directory: %1",qtpfsgui_options->tempfilespath);
317
VERBOSEPRINT("Dcraw parameters: %1",qtpfsgui_options->dcraw_options.join(" ") );
318
VERBOSEPRINT("Using %1 threads.", qtpfsgui_options->num_threads);
320
hdrCreationManager = new HdrCreationManager(qtpfsgui_options->num_threads, qtpfsgui_options->tempfilespath, qtpfsgui_options->dcraw_options);
313
321
connect(hdrCreationManager,SIGNAL(finishedLoadingInputFiles(QStringList)),this, SLOT(finishedLoadingInputFiles(QStringList)));
314
322
connect(hdrCreationManager,SIGNAL(errorWhileLoading(QString)),this, SLOT(errorWhileLoading(QString)));
315
323
connect(hdrCreationManager, SIGNAL(finishedAligning()), this, SLOT(createHDR()));
318
326
hdrCreationManager->loadInputFiles();
321
LoadHdrThread *loadthread = new LoadHdrThread(loadHdrFilename, "", qtpfsgui_options);
329
LoadHdrThread *loadthread = new LoadHdrThread(loadHdrFilename, "");
322
330
connect(loadthread, SIGNAL(finished()), loadthread, SLOT(deleteLater()));
323
331
connect(loadthread, SIGNAL(hdr_ready(pfs::Frame*,QString)), this, SLOT(loadFinished(pfs::Frame*,QString)));
324
332
connect(loadthread, SIGNAL(load_failed(QString)), this, SLOT(errorWhileLoading(QString)));
325
333
loadthread->start();
334
VERBOSEPRINT("Loading file %1.",loadHdrFilename);
329
void CommandLineInterfaceManager::loadFinished(pfs::Frame* hdr, QString /*fname*/) {
338
void CommandLineInterfaceManager::loadFinished(pfs::Frame* hdr, QString fname) {
339
VERBOSEPRINT("Successfully loaded file %1.",fname);
334
344
void CommandLineInterfaceManager::finishedLoadingInputFiles(QStringList filesLackingExif) {
335
345
if (filesLackingExif.size()!=0) {
337
347
for(int i=0; i<ev.size(); i++)
338
348
hdrCreationManager->setEV(ev.at(i),i);
349
VERBOSEPRINT("EV values have been assigned. %1","");
340
351
error(qPrintable(tr("Error: Exif data missing in images and EV values not specifed on the commandline, bailing out.")));
342
353
hdrCreationManager->checkEVvalues();
355
366
void CommandLineInterfaceManager::ais_failed(QProcess::ProcessError) {
356
errorWhileLoading("Failed executing align_image_stack");
367
errorWhileLoading(tr("Failed executing align_image_stack"));
359
370
void CommandLineInterfaceManager::createHDR() {
360
371
hdrCreationManager->removeTempFiles();
372
VERBOSEPRINT("Creating (in memory) the HDR. %1","");
361
373
HDR=hdrCreationManager->createHdr(false,1);
365
377
void CommandLineInterfaceManager::saveHDR() {
366
378
if (!saveHdrFilename.isEmpty()) {
379
VERBOSEPRINT("Saving to file %1.",saveHdrFilename);
367
380
QFileInfo qfi(saveHdrFilename);
368
381
if (qfi.suffix().toUpper()=="EXR") {
369
382
writeEXRfile(HDR,qfi.filePath().toUtf8().constData());
381
394
pfsio.writeFrame(HDR,qfi.filePath());
382
395
HDR->convertXYZChannelsToRGB();
384
error("Error, please specify a supported HDR file formats.");
397
error("Error, please specify a supported HDR file format.");
400
VERBOSEPRINT("NOT Saving HDR image to file. %1","");
391
406
void CommandLineInterfaceManager::startTonemap() {
392
407
if (!saveLdrFilename.isEmpty()) {
408
VERBOSEPRINT("Tonemapping requested, saving to file %1.",saveLdrFilename);
393
409
//now check if user wants to resize (create thread with either -2 or true original size as first argument in ctor, see options.cpp).
394
410
int origxsize= (tmopts->xsize==-2) ? -2 : HDR->getWidth();
395
411
TonemapperThread *thread = new TonemapperThread(origxsize, *tmopts);
396
412
connect(thread, SIGNAL(ImageComputed(const QImage&,tonemapping_options*)), this, SLOT(tonemapTerminated(const QImage&,tonemapping_options*)));
414
pfsio.writeFrame(HDR, qtpfsgui_options->tempfilespath+"/original.pfs");
415
pfsio.freeFrame(HDR);
418
VERBOSEPRINT("Tonemapping NOT requested. %1","");
398
419
emit finishedParsing();
402
423
void CommandLineInterfaceManager::tonemapTerminated(const QImage& newimage,tonemapping_options*) {
424
QFile::remove(qtpfsgui_options->tempfilespath+"/original.pfs");
425
QFile::remove(qtpfsgui_options->tempfilespath+"/after_resize.pfs");
426
QFile::remove(qtpfsgui_options->tempfilespath+"/after_pregamma.pfs");
403
427
QFileInfo qfi(saveLdrFilename);
404
428
if (!newimage.save(saveLdrFilename, qfi.suffix().toAscii().constData(), 100)) {
405
429
error(qPrintable(tr("ERROR: Cannot save to file: %1").arg(saveLdrFilename)));
407
431
TMOptionsOperations operations(tmopts);
408
ExifOperations::writeExifData(saveLdrFilename.toStdString(),operations.getExifComment().toStdString());
432
//ExifOperations methods want a std::string, we need to use the QFile::encodeName(QString).constData() trick to cope with utf8 characters.
433
ExifOperations::writeExifData(QFile::encodeName(saveLdrFilename).constData(),operations.getExifComment().toStdString());
410
435
emit finishedParsing();
439
464
-e --ev EV1,EV2,... Specify numerical EV values (as many as INPUTFILES).\n \
440
465
-c --config HDR creation config. Possible values: \n\
441
466
weight=triangular|gaussian|plateau:response_curve=from_file|linear|gamma|log|robertson:model=robertson|debevec:curve_filename=your_file_here.m \n\
442
(Default is triangular,linear,debevec) \n\
467
(Default is weight=triangular:response_curve=linear:model=debevec) \n\
443
468
-l --load HDR_FILE Load an HDR instead of creating a new one. \n \
444
-s --save HDR_FILE Save to a HDR file format. \n \
445
-g --gamma VALUE Gamma value to use during tone mapping. \n \
446
-r --resize VALUE Width want to resize your HDR to (resized before gamma and tone mapping) \n \
447
-t --tmo Tone mapping operator. Possible values: \n\
469
-s --save HDR_FILE Save to a HDR file format. (default: don't save) \n \
470
-g --gamma VALUE Gamma value to use during tone mapping. (default: 1) \n \
471
-r --resize VALUE Width you want to resize your HDR to (resized before gamma and tone mapping) \n \
472
-t --tmo Tone mapping operator. Legal values are: \n\
448
473
ashikhmin|drago|durand|fattal|pattanaik|reinhard02|reinhard05|mantiuk\n \
449
474
(Default is mantiuk)\n \
450
-p --tmoptions Tone mapping operator options. Possible values: \n\
475
-p --tmoptions Tone mapping operator options. Legal values are: \n\
451
476
alpha=VALUE:beta=VALUE:color=VALUE:noise=VALUE:new=true|false (for fattal)\n\
452
477
contrast=VALUE:saturation=VALUE:equalization=true|false (for mantiuk)\n\
453
478
localcontrast=VALUE:eq=2|4:simple=true|false (for ashikhmin)\n\
456
481
local=true|false:autolum=true|false:cone=VALUE:rod=VALUE:multiplier=VALUE (for pattanaik)\n\
457
482
scales=true|false:key=VALUE:phi=VALUE:num=VALUE:low=VALUE:high=VALUE (for reinhard02)\n\
458
483
brightness=VALUE:chroma=VALUE:lightness=VALUE (for reinhard05)\n\
459
(Default is contrast=0.3:equalization=false:saturation=1.8)\n \
484
(default is contrast=0.3:equalization=false:saturation=1.8, see also -o)\n \
460
485
-o --output LDR_FILE File name you want to save your tone mapped LDR to.\n \
486
(No tonemapping is performed unless -o is specified).\n \
462
You must either load an existing HDR file (via the -l option) or specify INPUTFILES to create a new one.\n").arg(progname).arg(progname);
488
You must either load an existing HDR file (via the -l option) or specify INPUTFILES to create a new HDR.\n").arg(progname).arg(progname);
463
489
fprintf(stderr,qPrintable(help));