File retarget.c of Package arachne

/*
retarget.c
Author: Hayden Walles
Date: 9 September 2007
A command line program that removes a specified number of seams from an image both horizontally and vertically.
*/

/*
    Copyright (C) 2007 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 <stdlib.h>
#include <seamstress.h>
#include "image.h"


void printUsage(void){
  fprintf(stderr,"Usage: retarget [-h] infile [width]x[height] [outfile]\nCarve some seams from an image.  Seams can be removed in both directions (horizontally and vertically) to reach a desired image size.\n\n");
  fprintf(stderr,"  -h         Print this help and exit.\n");
}

int saveResult(char *filename,IMAGE *original,SEAM_UNWEAVER *weaver,int *error){
  IMAGE *image;
  int i,j,oj,oi;
  int result;
  int w,h,x,y;

  *error=MATRIX_E_OK;

  unweaverCurrentSize(weaver,&w,&h);

  image=newImage(w,h,error);
  if(image==NULL)
    return 0;
  for(i=0;i<h;i++){
    for(j=0;j<w;j++){
      x=j;
      y=i;
      unweaverTransformToOriginal(weaver,&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 retarget(SEAM_UNWEAVER *weaver, int xcount,int ycount){
  int i;
  int *seam;
  int error;
  int maxcount=MAX(xcount,ycount);

  seam=malloc(sizeof(int)*(MAX(weaver->common.width,weaver->common.height)));
  if(seam==NULL){
    fprintf(stderr,"retarget: out of memory.\n");
    exit(1);
  }

  for(i=0;i<maxcount;i++){
    if(ycount>0){
      unweaverNextHorizontal(weaver,seam,&error);
      ycount--;
    }
    if(xcount>0){
      unweaverNextVertical(weaver,seam,&error);
      xcount--;
    }
  }

  free(seam);
  return 1;

}



int main(int argc, char **argv){
  char *outname="output.tif",*inname,*mapname="map.tif";
  char scratchname[128];
  int i,j;
  int count;
  IMAGE *in;
  SEAM_UNWEAVER *pic;
  SEAM_MAP *map;
  int error;
  int twidth=-1,theight=-1;
  char *hptr;

  setbuf(stdout,NULL);

  count=0;
  for(i=1;i<argc;i++){
    if(argv[i][0]=='-'){
      if(argv[i][1]=='h'){
	printUsage();
	exit(1);
      }
      else {
	fprintf(stderr,"Unknown option %s\n",argv[i]);
	exit(1);
      }
    }
    else if(count==0){
      inname=argv[i];
      count++;
    }
    else if(count==1){
      if(argv[i][0]=='x')
	theight=strtol(argv[i]+1,NULL,10);
      else if(hptr=strchr(argv[i],'x')){
	twidth=strtol(argv[i],NULL,10);
	theight=strtol(hptr+1,NULL,10);
      }
      else
	twidth = strtol(argv[i],NULL,10);
      count++;
    }
    else if(count==2){
      outname=argv[i];
      count++;
    }
    else {
      fprintf(stderr,"retarget: too many arguments\n");
      exit(1);
    }
  }
  if(count==0){
    fprintf(stderr,"retarget: no input file specified!\n");
    exit(1);
  }
  if(count==1){
    fprintf(stderr,"retarget: no dimensions specified!\n");
    exit(1);
  }

  printf("Input image: %s\nOutput image: %s\n",inname,outname);
  
  printf("Loading image...");
  if((in=loadImage(inname,&error))==NULL){
    fprintf(stderr,"retarget: error loading image\n");
    exit(1);
  }
  printf("done\n");

  if(twidth<0)
    twidth=imageWidth(in);
  if(theight<0)
    theight=imageHeight(in);

  if((twidth>imageWidth(in))||(theight>imageHeight(in))){
    fprintf(stderr,"retarget: cannot enlarge image.\n");
    exit(1);
  }

  if((pic=seamstressNewUnweaver(imageCols(in),imageRows(in),0,0,&error))==NULL){
    fprintf(stderr,"retarget: out of memory\n");
    exit(1);
  }
  for(i=0;i<imageRows(in);i++)
    unweaverSetRowRGB32(pic,i,in->pixels+in->width*i*4);

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

  printf("Retargeting: \n");
  retarget(pic,imageWidth(in)-twidth,imageHeight(in)-theight);
  printf("done.\n");

  printf("Saving result...");
  saveResult(outname,in,pic,&error);
  printf("done\n");

  return 0;
  
   

}
openSUSE Build Service is sponsored by