Logo Search packages:      
Sourcecode: pfstools version File versions  Download package

main.cpp

/**
 * @brief 
 * 
 * This file is a part of PFSTOOLS package.
 * ---------------------------------------------------------------------- 
 * Copyright (C) 2003,2004 Rafal Mantiuk and 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 Rafal Mantiuk, <mantiuk@mpi-sb.mpg.de>
 *
 * $Id: main.cpp,v 1.8 2007/11/20 11:44:12 rafm Exp $
 */

#include <config.h>

#include "main.h"

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#include <qtoolbar.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <qtoolbutton.h>
#include <qstatusbar.h>
#include <qtooltip.h>
#include <qcursor.h>
#include <qfiledialog.h>
#include <qclipboard.h>

#include <pfs.h>

#include "pfsview_widget.h"
#include "luminancerange_widget.h"

#define PROGNAME "pfsview"

QApplication *qApp;

PFSViewMainWin::PFSViewMainWin(  float window_min, float window_max ):
  QMainWindow( 0, "pfsMainWindow")
{
  currentFrame = frameList.end();
  
    pfsView = new PFSViewWidget( this, "pfsView" );
  
  setCentralWidget( pfsView );

  QToolBar *toolBar = new QToolBar( this );
//  toolBar->setHorizontalStretchable( true );

  QToolButton *previousFrameBt = new QToolButton( LeftArrow, toolBar );
  previousFrameBt->setMinimumWidth( 15 );
  connect( previousFrameBt, SIGNAL(clicked()), this, SLOT(gotoPreviousFrame()) );
  QToolTip::add( previousFrameBt, "Goto previous frame" );
  QToolButton *nextFrameBt = new QToolButton( RightArrow, toolBar );
  nextFrameBt->setMinimumWidth( 15 );
  connect( nextFrameBt, SIGNAL(clicked()), this, SLOT(gotoNextFrame()) );
  QToolTip::add( nextFrameBt, "Goto next frame" );

  QLabel *channelSelLabel = new QLabel( "&Channel", toolBar );
  channelSelection = new QComboBox( toolBar, "Channels" );
  channelSelLabel->setBuddy( channelSelection );
  connect( channelSelection, SIGNAL( activated( int ) ),
    this, SLOT( setChannelSelection(int) ) );
  
  toolBar->addSeparator();

  QLabel *mappingMethodLabel = new QLabel( "&Mapping", toolBar );
  mappingMethodLabel->setAlignment( AlignRight | AlignVCenter | 
                            ExpandTabs | ShowPrefix );
  mappingMethodCB = new QComboBox( toolBar );
  mappingMethodLabel->setBuddy( mappingMethodCB );
  mappingMethodCB->insertItem( "Linear" );
  mappingMethodCB->insertItem( "Gamma 1.4" );
  mappingMethodCB->insertItem( "Gamma 1.8" );
  mappingMethodCB->insertItem( "Gamma 2.2" );
  mappingMethodCB->insertItem( "Gamma 2.6" );
  mappingMethodCB->insertItem( "Logarithmic" );
  mappingMethodCB->setCurrentItem( 3 );
  connect( mappingMethodCB, SIGNAL( activated( int ) ),
    this, SLOT( setLumMappingMethod(int) ) );

  QToolBar *toolBarLR = new QToolBar( this );
  
  lumRange = new LuminanceRangeWidget( toolBarLR );
  connect( lumRange, SIGNAL( updateRangeWindow() ), this,
    SLOT( updateRangeWindow() ) );

  statusBar = new QStatusBar( this );
  pointerPosAndVal = new QLabel( statusBar );
  statusBar->addWidget( pointerPosAndVal );
  QFont fixedFont = QFont::defaultFont();
  fixedFont.setFixedPitch( true );
  pointerPosAndVal->setFont( fixedFont );
  zoomValue = new QLabel( statusBar );
  statusBar->addWidget( zoomValue );

  connect( pfsView, SIGNAL(updatePointerValue()),
             this, SLOT(updatePointerValue()) );


  QMenuBar *menuBar = new QMenuBar( this );
  QPopupMenu *frameMenu = new QPopupMenu( menuBar );
  menuBar->insertItem( "&Frame", frameMenu );
  frameMenu->insertItem( "&Next frame", this, SLOT(gotoNextFrame()), Key_PageDown ); 
  frameMenu->insertItem( "&Previous frame", this, SLOT(gotoPreviousFrame()), Key_PageUp ); 
  frameMenu->insertSeparator();
  frameMenu->insertItem( "&Save image...", this, SLOT(saveImage()), Key_S ); 
  frameMenu->insertItem( "&Copy image to clipboard", this, SLOT(copyImage()), CTRL + Key_C ); 
  frameMenu->insertSeparator();
  frameMenu->insertItem( "&Quit", qApp, SLOT(quit()), Key_Q ); 

  viewMenu = new QPopupMenu( menuBar );
  menuBar->insertItem( "&View", viewMenu );
  viewMenu->insertItem( "Increase exposure", lumRange, 
                  SLOT(increaseExposure()), Key_Minus ); 
  viewMenu->insertItem( "Decrease exposure", lumRange, 
                  SLOT(decreaseExposure()), Key_Equal );
  viewMenu->insertItem( "Extend dynamic range", lumRange, 
                  SLOT(extendRange()), Key_BracketRight ); 
  viewMenu->insertItem( "Shrink dynamic range", lumRange, 
                  SLOT(shrinkRange()), Key_BracketLeft );
  viewMenu->insertItem( "Fit to dynamic range", lumRange, 
                  SLOT(fitToDynamicRange()), Key_Backslash );
  viewMenu->insertItem( "Low dynamic range", lumRange, 
                  SLOT(lowDynamicRange()), ALT + Key_L );

  viewMenu->insertSeparator();

  QPopupMenu *mappingMenu = new QPopupMenu( menuBar );
  viewMenu->insertItem( "&Mapping method", mappingMenu );
  int menuItem;
  menuItem = mappingMenu->insertItem( "&Linear", this, SLOT(setLumMappingMethod(int)), Key_L );
  mappingMenu->setItemParameter( menuItem, 0 );
  menuItem = mappingMenu->insertItem( "Gamma &1.4", this, SLOT(setLumMappingMethod(int)), Key_1 );
  mappingMenu->setItemParameter( menuItem, 1 );
  menuItem = mappingMenu->insertItem( "Gamma 1.&8", this, SLOT(setLumMappingMethod(int)), Key_2 );
  mappingMenu->setItemParameter( menuItem, 2 );
  menuItem = mappingMenu->insertItem( "Gamma 2.&2", this, SLOT(setLumMappingMethod(int)), Key_3 );
  mappingMenu->setItemParameter( menuItem, 3 );
  menuItem = mappingMenu->insertItem( "Gamma 2.&4", this, SLOT(setLumMappingMethod(int)), Key_4 );
  mappingMenu->setItemParameter( menuItem, 4 );
  menuItem = mappingMenu->insertItem( "Lo&garithmic", this, SLOT(setLumMappingMethod(int)), Key_O );
  mappingMenu->setItemParameter( menuItem, 5 );
  
  infnanMenu = new QPopupMenu( menuBar );
  viewMenu->insertItem( "NaN and &Inf values", infnanMenu );
  infNaNMI[0] = infnanMenu->insertItem( "&Hide", pfsView, SLOT(setInfNaNTreatment(int)) );
  infnanMenu->setItemParameter( infNaNMI[0], 0 );
  infnanMenu->connectItem( infNaNMI[0], this, SLOT(setInfNaNTreatment(int)) );
  infNaNMI[1] = infnanMenu->insertItem( "Mark with &red color", pfsView, SLOT(setInfNaNTreatment(int)) );
  infnanMenu->setItemParameter( infNaNMI[1], 1 );
  infnanMenu->connectItem( infNaNMI[1], this, SLOT(setInfNaNTreatment(int)) );
  infnanMenu->setItemChecked( infNaNMI[1], true );

  negativeMenu = new QPopupMenu( menuBar );
  viewMenu->insertItem( "&Negative values", negativeMenu );
  negativeMI[0] = negativeMenu->insertItem( "&Black", pfsView, SLOT(setNegativeTreatment(int)), ALT + Key_B );
  negativeMenu->setItemParameter( negativeMI[0], NEGATIVE_BLACK );
  negativeMenu->setItemChecked( negativeMI[0], true );
  negativeMenu->connectItem( negativeMI[0], this, SLOT(setNegativeTreatment(int)) );
  negativeMI[1] = negativeMenu->insertItem( "Mark with &red color", pfsView,
    SLOT(setNegativeTreatment(int)), ALT + Key_R );
  negativeMenu->setItemParameter( negativeMI[1], NEGATIVE_MARK_AS_RED );
  negativeMenu->connectItem( negativeMI[1], this, SLOT(setNegativeTreatment(int)) );
  negativeMI[2] = negativeMenu->insertItem( "Use &green color scale", pfsView,
    SLOT(setNegativeTreatment(int)), ALT + Key_G );
  negativeMenu->setItemParameter( negativeMI[2], NEGATIVE_GREEN_SCALE );
  negativeMenu->connectItem( negativeMI[2], this, SLOT(setNegativeTreatment(int)) );
  negativeMI[3] = negativeMenu->insertItem( "Use &absolute values", pfsView,
    SLOT(setNegativeTreatment(int)), ALT + Key_A );
  negativeMenu->setItemParameter( negativeMI[3], NEGATIVE_ABSOLUTE );
  negativeMenu->connectItem( negativeMI[3], this, SLOT(setNegativeTreatment(int)) );

  viewMenu->insertSeparator();  
    
  colorClipMenu = new QPopupMenu( menuBar );
  viewMenu->insertItem( "&Color clipping", colorClipMenu );

  clippingMethodMI[CLIP_SIMPLE] = colorClipMenu->insertItem( "&Simple clipping", pfsView, SLOT(setRGBClippingMethod(int)), CTRL + Key_H );
  colorClipMenu->setItemParameter( clippingMethodMI[CLIP_SIMPLE], CLIP_SIMPLE );
  colorClipMenu->setItemChecked( clippingMethodMI[CLIP_SIMPLE], true );
  colorClipMenu->connectItem( clippingMethodMI[CLIP_SIMPLE], this, SLOT(changeClippingMethod(int)) );
  clippingMethodMI[CLIP_COLORCODED] = colorClipMenu->insertItem( "&Color-coded clipping", pfsView, SLOT(setRGBClippingMethod(int)), CTRL + Key_J );
  colorClipMenu->setItemParameter( clippingMethodMI[CLIP_COLORCODED], CLIP_COLORCODED );
  colorClipMenu->setItemChecked( clippingMethodMI[CLIP_COLORCODED], false );  
  colorClipMenu->connectItem( clippingMethodMI[CLIP_COLORCODED], this, SLOT(changeClippingMethod(int)) );
  clippingMethodMI[CLIP_KEEP_BRI_HUE] = colorClipMenu->insertItem( "&Keep brightness and hue", pfsView, SLOT(setRGBClippingMethod(int)), CTRL + Key_K );
  colorClipMenu->setItemParameter( clippingMethodMI[CLIP_KEEP_BRI_HUE], CLIP_KEEP_BRI_HUE );
  colorClipMenu->setItemChecked( clippingMethodMI[CLIP_KEEP_BRI_HUE], false );  
  colorClipMenu->connectItem( clippingMethodMI[CLIP_KEEP_BRI_HUE], this, SLOT(changeClippingMethod(int)) );

  
  colorCoordMenu = new QPopupMenu( menuBar );
  viewMenu->insertItem( "Color coo&rdinates", colorCoordMenu );
  menuItem = colorCoordMenu->insertItem( "&RGB", this, SLOT(setColorCoord(int)) );
  colorCoordMenu->setItemParameter( menuItem, 0 );
  menuItem = colorCoordMenu->insertItem( "&XYZ", this, SLOT(setColorCoord(int)) );
  colorCoordMenu->setItemParameter( menuItem, 1 );
  menuItem = colorCoordMenu->insertItem( "Y&u'v'", this, SLOT(setColorCoord(int)) );
  colorCoordMenu->setItemParameter( menuItem, 2 );
  menuItem = colorCoordMenu->insertItem( "Yx&y", this, SLOT(setColorCoord(int)) );
  colorCoordMenu->setItemParameter( menuItem, 3 );

  viewMenu->insertSeparator();
  int itemID;
  itemID = viewMenu->insertItem( "&Zoom in", pfsView, 
                  SLOT(zoomIn()), Key_Period );
  viewMenu->connectItem( itemID, this, SLOT(updateZoomValue()) );
  itemID = viewMenu->insertItem( "Zoom &out", pfsView, 
                  SLOT(zoomOut()), Key_Comma ); 
  viewMenu->connectItem( itemID, this, SLOT(updateZoomValue()) );
  itemID = viewMenu->insertItem( "Zoom &1:1", pfsView, 
                  SLOT(zoomOriginal()), Key_N ); 
  viewMenu->connectItem( itemID, this, SLOT(updateZoomValue()) );
  viewMenu->insertItem( "&Fit window to content", this, 
                  SLOT(updateViewSize()), Key_C ); 

  QPopupMenu *helpMenu = new QPopupMenu( menuBar );
  menuBar->insertItem( "&Help", helpMenu );
  helpMenu->insertItem( "&About", this, 
                  SLOT(showAboutdialog()) );

  setColorCoord( CC_RGB );
  
/*  
  viewMenu->insertItem( "Keep-lightness clipping", pfsView, 
                  SLOT(setRGBClippingMethod()) );
  viewMenu->insertItem( "Keep-saturation clipping", pfsView, 
                  SLOT(setRGBClippingMethod()) );
*/

  //Window should not be larger than desktop
  // TODO: how to find desktop size - gnome taksbars
//  setMaximumSize( QApplication::desktop()->width(), QApplication::desktop()->height() );

  try {
    
    if( !readNextFrame() ) 
      throw PFSViewException();

    lumRange->setRangeWindowMinMax( window_min, window_max );  
    
  } catch( pfs::Exception ex ) {
    QMessageBox::critical( this, "pfsview error", ex.getMessage() );
    throw PFSViewException();
  }
  
}


void PFSViewMainWin::changeClippingMethod( int clippingMethod )
{
  for( int i = 0; i < CLIP_COUNT; i++ )
    viewMenu->setItemChecked( clippingMethodMI[i], clippingMethod == i );

  statusBar->message( viewMenu->text(clippingMethodMI[clippingMethod]), 1000 );  
}

void PFSViewMainWin::setInfNaNTreatment( int method )
{
  infnanMenu->setItemChecked( infNaNMI[0], method == 0 );
  infnanMenu->setItemChecked( infNaNMI[1], method == 1 );
}

void PFSViewMainWin::setNegativeTreatment( int method )
{
  for( int i = 0; i < NEGATIVE_COUNT; i++ )
    negativeMenu->setItemChecked( negativeMI[i], method == i );
}

void PFSViewMainWin::setLumMappingMethod( int method )
{
  mappingMethodCB->setCurrentItem( method );
  pfsView->setLumMappingMethod( method );
}

struct ColorSpaceLabel
{
  const char *comboBoxLabel;
  const char *c1, *c2, *c3;
};

static const ColorSpaceLabel scLabels[] = {
  { "Color XYZ", "X", "Y", "Z" }    
};

int scLabelsCount = sizeof( scLabels ) / sizeof( ColorSpaceLabel );

void PFSViewMainWin::updatePointerValue()
{
  const PointerValue &pv = pfsView->getPointerValue();

  if( pv.valid ) {
    char pointerValueStr[256];
    const PointerValue &pv = pfsView->getPointerValue();
    sprintf( pointerValueStr, "(x,y)=(%4d,%4d) ", pv.x, pv.y );
    QString label( pointerValueStr );

    int channelSel = channelSelection->currentItem();
    if( pv.valuesUsed == 3 ) { // Color
      assert( channelSel < scLabelsCount );

      pfs::Array2DImpl X(1,1), Y(1,1), Z(1,1);
      X(0) = pv.value[0];
      Y(0) = pv.value[1];
      Z(0) = pv.value[2];

      char *l1, *l2, *l3;
      switch( colorCoord ) {
      case CC_RGB:
        l1 = "R"; l2 = "G"; l3 = "B";
        pfs::transformColorSpace( pfs::CS_XYZ, &X, &Y, &Z, pfs::CS_RGB, &X, &Y, &Z );
        break;
      case CC_XYZ:
        l1 = "X"; l2 = "Y"; l3 = "Z";
        break;
      case CC_Yupvp:
        pfs::transformColorSpace( pfs::CS_XYZ, &X, &Y, &Z, pfs::CS_YUV, &X, &Y, &Z );
        l1 = "Y"; l2 = "u'"; l3 = "v'";
        break;
      case CC_Yxy:
        pfs::transformColorSpace( pfs::CS_XYZ, &X, &Y, &Z, pfs::CS_Yxy, &X, &Y, &Z );
        l1 = "Y"; l2 = "x"; l3 = "y";
        break;
      };
      
      sprintf( pointerValueStr, "%s=%07.4g %s=%07.4g %s=%07.4g",
        l1, X(0),
        l2, Y(0),
        l3, Z(0)
        );
      label += pointerValueStr;
      lumRange->showValuePointer( log10(pv.value[1]) );
      
    } else {                    // Single channel
      const QString &name = channelSelection->text( channelSel );
      sprintf( pointerValueStr, "%s=%07.4g", (const char*)name, pv.value[0] );
      label += pointerValueStr;
      lumRange->showValuePointer( log10(pv.value[0]) );
    }    
    
    pointerPosAndVal->setText( label );
  } else {
    pointerPosAndVal->setText( "(?,?)" );
    lumRange->hideValuePointer();
  }
  
  
}

void PFSViewMainWin::setColorCoord( int method )
{
  colorCoord = (ColorCoord)method;
  updatePointerValue();
  for( int i = 0; i < CC_COUNT; i++ )
    colorCoordMenu->setItemChecked( colorCoordMenu->idAt(i), method == i );
}


void PFSViewMainWin::updateZoomValue()
{
  char strBuf[20];
  sprintf( strBuf, "%d%%", (int)(pfsView->getZoom()*100) );
  zoomValue->setText( strBuf );
}



void PFSViewMainWin::updateViewSize()
{
  adjustSize();
}

void PFSViewMainWin::updateRangeWindow()
{
  pfsView->setRangeWindow( pow( 10, lumRange->getRangeWindowMin() ), pow( 10, lumRange->getRangeWindowMax() ) );
}

void PFSViewMainWin::updateChannelSelection()
{
  channelSelection->clear();

  const char *visibleChannel = pfsView->getVisibleChannel();
  
  if( pfsView->hasColorChannels() ) {  
    channelSelection->insertItem( "Color XYZ" );
    if( !strcmp( visibleChannel, "Color" ) )
      channelSelection->setCurrentItem( 0 );
  }  

  /*  channelSelection->insertItem( "Color RGB" );
  channelSelection->insertItem( "Color XYZ" );
  channelSelection->insertItem( "Color L*ab" );
  channelSelection->insertItem( "Luminance Y" );*/
  
  QArray<const char*> channelNames = pfsView->getChannels();
  for( int c = 0; c < channelNames.size(); c++ ) {
    channelSelection->insertItem( channelNames[c] );
    if( !strcmp( channelNames[c], visibleChannel ) )
      channelSelection->setCurrentItem( channelSelection->count()-1 );
  }
  

}

void PFSViewMainWin::setChannelSelection( int selectedChannel )
{
  // If channel combo box has not been initialized yet
  if( selectedChannel >= channelSelection->count() ) 
    return;
  
  const QString &name = channelSelection->text( selectedChannel );
  if( pfsView->hasColorChannels() && selectedChannel < scLabelsCount ) {
    pfsView->setVisibleChannel( NULL ); // Color
  } else {
    pfsView->setVisibleChannel( name );
  }
  updateMenuEnable( );
  lumRange->setHistogramImage(pfsView->getPrimaryChannel());

  updatePointerValue();
  
}

void PFSViewMainWin::updateMenuEnable( )
{
  bool color = pfsView->getVisibleChannel() == COLOR_CHANNELS;

  negativeMenu->setItemEnabled( negativeMI[NEGATIVE_GREEN_SCALE], !color );
  negativeMenu->setItemEnabled( negativeMI[NEGATIVE_ABSOLUTE], !color );  
}


void PFSViewMainWin::showAboutdialog()
{
   QMessageBox::information( this, "pfsview",
     "pfsview " PACKAGE_VERSION "\n"
     "Copyright (C) 2005 Rafal Mantiuk\n\n"
     "See the manual page (man pfsview) and\n"
     "the web page (http://pfstools.sourceforge.net/)\n"
     "for more information"
     );
   
}

// ======================= Loading next frame ==========================

/**
 * GUI action -> goto next frame
 * handle error and eof of frame
 */
void PFSViewMainWin::gotoNextFrame()
{
  try {
    if( !readNextFrame() ) {
      statusBar->message( "No more frames", 1000 );
    }
  }
  catch( pfs::Exception ex )
    {
      // Display message and keep the old frame
      QMessageBox::critical( this, "pfsview error", ex.getMessage() );
      qApp->quit();
    }
}

void PFSViewMainWin::gotoPreviousFrame()
{
  currentFrame++;
  if( currentFrame == frameList.end() ) {
    currentFrame--;
    statusBar->message( "No more frames in buffer (buffer holds max 5 frames)", 1000 );
    return;
  }

  setFrame( *currentFrame );
}

void PFSViewMainWin::setFrame( pfs::Frame *frame )
{
  QApplication::setOverrideCursor( Qt::waitCursor );

  
  pfsView->setFrame( frame );

  lumRange->setHistogramImage(pfsView->getPrimaryChannel());
    
  updateRangeWindow();
  updateChannelSelection();
  updateZoomValue();

  // Set the window caption to the name of the frame, if it is given
  const char *fileName = frame->getTags()->getString( "FILE_NAME" );
  const char *luminanceTag = frame->getTags()->getString( "LUMINANCE" );
  QString qLuminance( "" );
  if( luminanceTag!=NULL )
    qLuminance=QString(" (") + QString(luminanceTag) + QString(")");
  if( fileName == NULL )
    setCaption( QString( "pfsview" ) );
  else {
    QString qFileName( fileName );
    if( qFileName.length() > 30 )
      setCaption( QString( "pfsview: ... " ) + QString( fileName ).right( 30 ) + qLuminance);
    else
      setCaption( QString( "pfsview: " ) + QString( fileName ) + qLuminance);
  }
  updateMenuEnable( );

  QApplication::restoreOverrideCursor();  
}

/**
 * Load next frame from the stream.
 * @return false if there are no more frames
 */
bool PFSViewMainWin::readNextFrame()
{
  if( currentFrame != frameList.begin() )
  {
    currentFrame--;
    setFrame( *currentFrame );
    return true;
  }
  
  pfs::DOMIO pfsCtx;
  pfs::Frame *newFrame;
  newFrame = pfsCtx.readFrame( stdin );
  if( newFrame == NULL ) return false; // No more frames
  
  if( frameList.size() == MAX_FRAMES_IN_MEMORY ) {
    // Remove one frame from the back
    pfsCtx.freeFrame( frameList.back() );
    frameList.pop_back();
  }
  frameList.push_front( newFrame );
  currentFrame = frameList.begin();
  
  setFrame( newFrame );  
  
  return true;
}

// ======================= Saving image ================================

void PFSViewMainWin::saveImage()
{
  QString fileName = QFileDialog::getSaveFileName( "pfsview_screenshot.png", "Images (*.png)", this );
  if ( !fileName.isNull() ) {                 // got a file name
    QImage *image = pfsView->getDisplayedImage();
    //QImage::imageFormat( fileName )
    if( !image->save( fileName, "PNG", -1 ) )
    {
      QMessageBox::warning( this, "Saving image problem", "Cannot save image " + fileName );
    }
  }
}

void PFSViewMainWin::copyImage()
{
  QClipboard *cb = QApplication::clipboard();

  const QImage *image = pfsView->getDisplayedImage();
  cb->setImage( *image, QClipboard::Clipboard );
  statusBar->message( "Image copied to clipboard", 2000 );
}


// ======================= main and command line =======================

void printUsage()
{
    fprintf( stderr,
      "Usage: " PROGNAME " [options]\n"
      "\n"
      "Displays high-dynamic range image in pfs format. The image is read from the "
      "standard output.\n"
      "\n"
      "options:\n"
      "\t--help                        : prints this message\n"
      "\t--window_min log_lum          : lower bound of hdr display window, given as "
      "a log10 of luminance.\n"
      "\t--window_min log_lum          : the same as above, but the upper bound\n"
      );
}

static void errorCheck( bool condition, char *string )
{
    if( !condition ) {
      fprintf( stderr, PROGNAME " error: %s\n", string );
      abort();
    }
}

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    qApp = &app;

    float window_min = 0, window_max = 2;

    for( int i=1 ; i<argc ; i++ )
    {
      if( !strcmp( argv[i], "--help") ) {
        printUsage();
        return 0;
      }
      else if( !strcmp( argv[i], "--window_min") ) {
        i++;
        errorCheck( i < argc, "expected parameter after --window_min" );
        char *checkPtr;
        window_min = (float)strtod( argv[i], &checkPtr );
        errorCheck( checkPtr != NULL && checkPtr[0] == 0 &&
          window_min < 100 && window_min > -100,
          "--window_min expects floating point value between -100 and 100" );  
      }
      else if( !strcmp( argv[i], "--window_max") ) {
        i++;
        errorCheck( i < argc, "expected parameter after --window_max" );
        char *checkPtr;
        window_max = (float)strtod( argv[i], &checkPtr );
        errorCheck( checkPtr != NULL && checkPtr[0] == 0 &&
          window_max < 100 && window_max > -100,
          "--window_max expects floating point value between -100 and 100" );
      } else {
        fprintf( stderr, PROGNAME " error: not recognized parameter '%s'\n", argv[i] );
        printUsage();
        return -1;
      }
    }

    errorCheck( window_min < window_max, "window_min must be less than window_max" );


    try {
      
      PFSViewMainWin pfsViewMW( window_min, window_max );
      app.setMainWidget(&pfsViewMW);    
      pfsViewMW.show();
      pfsViewMW.adjustSize();
      
      return app.exec();
      
    }
    catch( PFSViewException ex )
    {
      QMessageBox::critical( NULL, "pfsview error", "Can not open the first PFS frame. Quitting." );
      return -1;
    }
    
    
}


Generated by  Doxygen 1.6.0   Back to index