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

OutputOptions.cpp

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

#include "OutputOptions.h"
#include "GFilter.h"

/* Class used to handle processing of command line parameters passed to
 * kdc2tiff and kdc2jpeg.
 * 
 * Written by:  Chris Studholme
 * Last Update: 6-Dec-2003
 * Copyright:   GPL (http://www.fsf.org/copyleft/gpl.html)
 */


void OutputOptions::SetOutputParameters() {

  image=srcimage;

  // contrast enhancement
  int min=0;
  int max=255;
  if (contrastenhance) {
    // find best min and max
    srcimage->FindBestMinMax(min,max);
    min-=contrastenhance;
    max+=contrastenhance;
    if (min<0) min=0;
    if (max>255) max=255;
    
    if ((min>0)||(max<255)) {
      fprintf(stderr,"Adjusting constrast (%d,%d) -> (0,255).\n",min,max);
      GFilter_ContrastAdjustment* ca = 
      new GFilter_ContrastAdjustment(*image,(min-128)*128,(max+1-128)*128);
      image=ca;
    }
  }

  // white balance
  if (lightwhite) {
    float red=1;
    float blue=1;
    srcimage->FindWhiteBalance(red,blue,min);
    fprintf(stderr,"Light source (%.2f,1.00,%.2f).\n",red,blue);

    // preferred light source
    //    red *= 1.0169;
    //    blue *= 1.003;
    
    // check for sane values
    if (red>1.4) red=1.4;
    if (red<0.7) red=0.7;
    if (blue>1.4) blue=1.4;
    if (blue<0.7) blue=0.7;

    // don't balance images that undergo insane contrast enhancement
    if (max-min<150) {
      float factor = ((float)max-min)/150;
      red = 1 + factor*(red-1);
      blue = 1 + factor*(blue-1);
    }

    if ((red<0.995)||(red>1.005)||(blue<0.995)||(blue>1.005)) {
      fprintf(stderr,"Balancing white (%.2f,1.00,%.2f).\n",red,blue);
      GFilter_WhiteBalance* wb = 
      new GFilter_WhiteBalance(*image,1/red,1/blue);
      image=wb;
    }
  }

  // gamma correction
  if (gammacorrection!=1) {
    fprintf(stderr,"Applying gamma correction of %.2f.\n",gammacorrection);
    GFilter_GammaCorrection* gc = 
      new GFilter_GammaCorrection(*image,gammacorrection);
    image=gc;
  }

  // rotate image
  if (rotate) {
    GFilter_Rotate* rot = new GFilter_Rotate(*image);
    switch (rotate) {
    case 1:
      rot->setClockwiseRotate();
      fprintf(stderr,"Rotating image clockwise.\n");
      break;
    case -1:
      rot->setCounterClockwiseRotate();
      fprintf(stderr,"Rotating image counter-clockwise.\n");
      break;
    default:
      fprintf(stderr,"invalid rotate value (%d)\n", rotate);
    }
    image=rot;
  }

  // default image dimensions
  if ((outputwidth==0)&&(outputheight==0)) {
    outputwidth=image->getPreferredWidth();
    outputheight=image->getPreferredHeight();
  }

  // scale image
  GFilter_Scale* scale = new GFilter_Scale(*image,outputwidth,outputheight);
  if ((outputwidth>0)&&(outputheight>0)) {
    if (!squarepixels)
      scale->setDimensions(outputwidth,outputheight,false);
    else if (nocrop)
      scale->setMaximumDimensions(outputwidth,outputheight);
  }
  image=scale;
  outputwidth=image->getWidth();
  outputheight=image->getHeight();

  fprintf(stderr,"Scaling image to %dx%d%s",outputwidth,outputheight, 
        squarepixels?"":" (non-square pixels)");
  int uncropwidth=scale->getUncropWidth();
  int uncropheight=scale->getUncropHeight();
  if ((uncropwidth!=outputwidth)||(uncropheight!=outputheight))
    fprintf(stderr," cropping from %dx%d",uncropwidth,uncropheight);
  fprintf(stderr,".\n");
}

void OutputOptions::SetOutputFilename() {
  if (outputname==0) {
    outputname = new char[strlen(inputname)+5];
    strcpy(outputname,inputname);
    char* extension = strrchr(outputname,'.');
    if ((extension!=0)&&(extension>strrchr(outputname,'/')))
      strcpy(extension, outputtiff?".tif":".jpg");
    else
      strcat(outputname,outputtiff?".tif":".jpg");
  }
}

void OutputOptions::CalculateScanLine(unsigned char* dest, int y) {
  int w=image->getWidth();
  short r[w],g[w],b[w];
  image->getScanLineHorz(r,g,b,0,y,w,y+1,w);
  for (int x=0; x<w; ++x) {
    dest[x*3+0] = r[x]<-16383 ? 0 : r[x]>16383 ? 255 : 128+r[x]/128;
    dest[x*3+1] = g[x]<-16383 ? 0 : g[x]>16383 ? 255 : 128+g[x]/128;
    dest[x*3+2] = b[x]<-16383 ? 0 : b[x]>16383 ? 255 : 128+b[x]/128;
  }
}


// returns 0 if error
char** OutputOptions::ParseOptions(int& argc, char*argv[]) {
  
  while (argc>0) {
    
    if (argv[0][0]=='-') {
      
      // stdin or stdout
      if (strcmp(argv[0],"-")==0)
      return argv;
      
      // next argument is a filename
      if (strcmp(argv[0],"--")==0) {
      --argc;
      return ++argv;
      }
      
      const char* switches = argv[0]+1;
      while (switches[0]) {
      switch (switches[0]) {
        
        // copyright
      case 'C':
        ++argv;
        if (--argc>0)
          copyright=argv[0];
        else
          return 0;
        break;
        
        // compression scheme
      case 'c':
        ++argv;
        if (--argc>0)
          compresstype=argv[0];
        else
          return 0;
        break;

        // output filename
      case 'o':
        ++argv;
        if (--argc>0) {
          outputname=argv[0];
          overwrite=true;
        }
        else
          return 0;
        break;
        
        // rows per strip
      case 'r':
        ++argv;
        if (--argc>0)
          rowsperstrip=atoi(argv[0]);
        else
          return 0;
        if (rowsperstrip<=0) {
          fprintf(stderr,"invalid rows per strip value (%d)\n",rowsperstrip);
          return 0;
        }
        break;
        
        // don't create progressive jpeg
      case 'P':
        progressive=false;
        break;
        
        // jpeg quality setting
      case 'q':
        ++argv;
        if (--argc>0)
          quality=atoi(argv[0]);
        else 
          return 0;
        if ((quality<0)||(quality>100)) {
          fprintf(stderr,"invalid quality value (%d)\n",quality);
          return 0;
        }
        break;
        
        // width
      case 'w':
        ++argv;
        if (--argc>0)
          outputwidth=atoi(argv[0]);
        else {
          return 0;
        }
        if (outputwidth<=0) {
          fprintf(stderr,"invalid image width (%d)\n",outputwidth);
          return 0;
        }
        break;
        
        // height
      case 'h':
        ++argv;
        if (--argc>0)
          outputheight=atoi(argv[0]);
        else 
          return 0;
        if (outputheight<=0) {
          fprintf(stderr,"invalid image height (%d)\n",outputheight);
          return 0;
        }
        break;
        
        // gamma correction
      case 'g':
        ++argv;
        if (--argc>0)
          gammacorrection=atof(argv[0]);
        else 
          return 0;
        if ((gammacorrection<0.2)||(gammacorrection>5)) {
          fprintf(stderr,"invalid gamma setting (%.1f)\n",gammacorrection);
          return 0;
        }
        break;

        // no grain reduction
      case 'G':
        grainreduction=0;
        break;
        
        // non-square pixels
      case 's':
        squarepixels=false;
        break;
        
        // non-fast de-bayer (highest quality)
      case 'f':
        fastdebayer=false;
        break;
        
        // no contrast enhancement
      case 'e':
        contrastenhance=0;
        break;
        
        // no cropping
      case 'p':
        nocrop=true;
        break;
        
        // don't rotate
      case 'R':
        rotate=0;
        break;

        // colour of light source (white)
      case 'W':
        ++argv;
        if (--argc>0) {
          if (strcasecmp(argv[0],"none")==0)
            lightwhite=0;
          else if (strcasecmp(argv[0],"auto")==0)
            lightwhite=-1;
          else if (strcasecmp(argv[0],"sun")==0)
            lightwhite=-1;
          else if (strcasecmp(argv[0],"shade")==0)
            lightwhite=-1;
          else if (strcasecmp(argv[0],"cloud")==0)
            lightwhite=-1;
          else if (strcasecmp(argv[0],"incandecent")==0)
            lightwhite=-1;
          else if (strcasecmp(argv[0],"flourescent")==0)
            lightwhite=-1;
          else {
            lightwhite=atoi(argv[0]);
            if ((lightwhite<500)||(lightwhite>15000)) {
            fprintf(stderr,"invalid light source temperature, assuming ttl mode\n");
            lightwhite=-1;
            }
          }
        }
        else
          return 0;
        break;
        
      default:
        return 0;
      }
      ++switches;
      }
    }
    
    else if (argv[0][0]=='+') {
      const char* switches = argv[0]+1;
      float tempf;
      while (switches[0]) {
      switch (switches[0]) {
        
        // create progressive jpeg
      case 'P':
        progressive=true;
        break;
        
        // square pixels
      case 's':
        squarepixels=true;
        break;
        
        // fast de-bayer (sacrifice quality)
      case 'f':
        fastdebayer=true;
        break;
        
        // gamma correction
      case 'g':
        ++argv;
        if (--argc>0)
          tempf=atof(argv[0]);
        else 
          return 0;
        if ((tempf<0.2)||(tempf>5)) {
          fprintf(stderr,"invalid gamma setting (%.1f)\n",tempf);
          return 0;
        }
        else
          gammacorrection*=tempf;
        break;

        // grain reduction
      case 'G':
        if (++grainreduction>2)
          grainreduction=2;
        break;
        
        // normal contrast enhancement
      case 'e':
        contrastenhance=2;
        break;

      case 'E':
        ++argv;
        if (--argc>0)
          contrastenhance=atoi(argv[0]);
        else 
          return 0;
        if ((contrastenhance<=0)||(contrastenhance>255)) {
          fprintf(stderr,"invalid contrast enhancement (%d)\n",
                contrastenhance);
          return 0;
        }
        break;
        
        // crop if necessary
      case 'p':
        nocrop=false;
        break;

        // rotate clockwise
      case 'R':
        rotate=1;
        break;

        // rotate counter-clockwise
      case 'B':
        rotate=-1;
        break;

      default:
        return 0;
      }
      ++switches;
      }
    }

    // must be a filename
    else
      return argv;

    ++argv;
    --argc;
  }

  return argv;
}

Generated by  Doxygen 1.6.0   Back to index