File removeseams.c of Package arachne

/*
removeseams.c
Author: Hayden Walles
Date: 9 September 2007
A driver for a command line program that removes a specified number of seams from an image.
*/

/*
    Copyright (C) 2007, 2008 Hayden Walles

    This file is part of Arachne.

    Arachne 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.

    Arachne 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
*/

#include <stdio.h>
#include <seamstress.h>
#include "image.h"


void printUsage(void){
  fprintf(stderr,"Usage: removeseams [-h] [-c count] [-r] [-d D] infile [outfile]\nCarve some seams from an image.  Seams will be removed in only one direction (horizontally or vertically).\n\n");
  fprintf(stderr,"  -r         Use dynamic energy\n");
  fprintf(stderr,"  -dx       Remove vertical (x is v) or horizontal (x is h) seams.\n");
  fprintf(stderr,"  -c count   Specifies the number of seams to remove.\n");
  fprintf(stderr,"  -h         Print this help and exit.\n");
}


int saveResult(char *filename,IMAGE *original,SEAM_UNPICKER *pic,int *error){
  IMAGE *image;
  int i,j,x,y;
  int result;
  int nw,nh;
  
  *error=MATRIX_E_OK;

  unpickerCurrentSize(pic,&nw,&nh);
  
    image=newImage(nw,nh,error);

    
    if(image==NULL)
      return 0;

    for(i=0;i<imageHeight(image);i++){
      for(j=0;j<imageWidth(image);j++){
	x=j;
	y=i;
	unpickerTransformToOriginal(pic,&x,&y);
	setPixel(image,i,j,getRed(original,y,x),getGreen(original,y,x),getBlue(original,y,x));
      }
    }
  
  result=saveImage(filename,image,error);
  deleteImage(image);
  
  return result;
  
}



int main(int argc, char **argv){
  char *outname="output.tif",*inname;
  char scratchname[128];
  int i,j;
  int count;
  IMAGE *in;
  SEAM_UNPICKER *pic;
  SEAM_MAP *map;
  int error;
  int cutcount=50;
  int dynenergy=0;
  int direction=0;
  int *seam;

  setbuf(stdout,NULL);

  count=0;
  for(i=1;i<argc;i++){
    if(argv[i][0]=='-'){
      if(argv[i][1]=='c'){
	if(argv[i][2]==0){
	  if(i+1>=argc){
	    fprintf(stderr,"-c requires argument\n");
	    exit(1);
	  }
	  cutcount=strtol(argv[i+1],NULL,10);
	  i++;
	}
	else {
	  cutcount=strtol(argv[i]+2,NULL,10);
	}
      }
      else if(argv[i][1]=='r'){
	dynenergy=1;
      }
      else if(argv[i][1]=='d'){
	if(argv[i][2]=='v')
	  direction=0;
	else if(argv[i][2]=='h')
	  direction=1;
	else{
	  fprintf(stderr,"removeseams: Invalid direction %s.  Try -dv or -dh.\n",argv[i]);
	  exit(1);
	}
      }
      else if(argv[i][1]=='h'){
	printUsage();
	exit(0);
      }
      else {
	fprintf(stderr,"removeseams: Unknown option %s\n",argv[i]);
	exit(1);
      }
    }
    else if(count==0){
      inname=argv[i];
      count++;
    }
    else if(count==1){
      outname=argv[i];
      count++;
    }
    else {
      fprintf(stderr,"removeseams: Too many arguments\n");
      exit(1);
    }
  }
  if(count==0){
    fprintf(stderr,"removeseams: No input file specified!\n");
    exit(1);
  }
  
  printf("Input image: %s\nOutput image: %s\n",inname,outname);
  if(direction==0)
    printf("Removing vertical seams.\n");
  else
    printf("Removing horizontal seams\n");
  if(dynenergy)
    printf("Using dynamic energy\n");

  printf("Loading image...");
  if((in=loadImage(inname,&error))==NULL){
    fprintf(stderr,"removeseams: Error loading image\n");
    exit(1);
  }
  printf("done\n");

  if((direction==0)&&(cutcount>=imageWidth(in))||
     (direction==1)&&(cutcount>=imageHeight(in))){
    fprintf(stderr,"removeseams: Cannot remove more seams than are in the image.\n");
    exit(1);
  }

  
  if((pic=seamstressNewUnpicker(imageCols(in),imageRows(in),direction,0,dynenergy,&error))==NULL){
    fprintf(stderr,"removeseams: Out of memory\n");
    exit(1);
  }
  for(i=0;i<imageRows(in);i++)
    unpickerSetRowRGB32(pic,i,in->pixels+in->width*i*4);

 
  printf("Computing energy...");
  unpickerComputeEnergy(pic,NULL,NULL,NULL,&error);
  printf("done\n");

  if(direction==0)
    seam = malloc(sizeof(int)*imageHeight(in));
  else
    seam = malloc(sizeof(int)*imageWidth(in));
  
  if(seam==NULL){
    fprintf(stderr,"removeseams: out of memory\n");
    exit(1);
  }

  printf("Removing seams %d seams:\n",cutcount);
  for(i=0;i<cutcount;i++){
    if(!unpickerNextSeam(pic,seam,0,&error)){
      fprintf(stderr,"removeseams: error computing seams\n");
      exit(1);
    }
  }


  printf("Saving result...");
  
  if(!saveResult(outname,in,pic,&error)){
    fprintf(stderr,"removeseams: error saving image\n");
    exit(1);
  }
  printf("done\n");

  return 0;
  
   

}
openSUSE Build Service is sponsored by