/* -*- mode: c++; c-basic-offset: 3 -*-
 *
 * PANDORE (PANTHEON Project)
 *
 * GREYC IMAGE
 * 6 Boulevard Maréchal Juin
 * F-14050 Caen Cedex France
 *
 * This file is free software. You can use it, distribute it
 * and/or modify it. However, the entire risk to the quality
 * and performance of this program is with you.
 *
 * Please email any bugs, comments, and/or additions to this file to:
 * pandore@greyc.ensicaen.fr
 * http://www.greyc.ensicaen.fr/EquipeImage/Pandore/
 */

/**
 * @author Jean-Baptiste Hoock - 2005-07-28 
 */

/**
 * @file quartdetour.cpp
 *
 * Rotation  of an image counterclockwise n*90 degrees.
 *
 * tourner une image d'un certain nombre quart de tours
 */


#include <pandore.h>
using namespace pandore;
//created for curvelet (fct and fict) 

//image3d isn't implemented

template <typename T>
Errc QuartDeTour(Img2d<T> &ims, Img2d<T> &imd, Short nb_quart_tour) {
   Long i,j; //variables of loop
   Long hauteur=imd.Height();
   Long largeur=imd.Width();

   //we come back into the interval [|0;3|]
   nb_quart_tour%=4;
   if (nb_quart_tour<0) nb_quart_tour+=4;

   if (nb_quart_tour==0)
      imd=ims;
   else {
      if (nb_quart_tour==3) {
	 for(i=0; i<largeur; i++)
	    for(j=0;j<hauteur; j++)
	       imd[j][i]=ims[largeur-i-1][j];
      } else {
	 if (nb_quart_tour==2) {
	    for(i=0; i<largeur; i++)
	       for(j=0;j<hauteur; j++)
		  imd[j][i]=ims[hauteur-j-1][largeur-i-1];
	 } else {
	    for(i=0; i<largeur; i++)
	       for(j=0;j<hauteur; j++)
		  imd[j][i]=ims[i][hauteur-j-1];
	 }
      }
   }
   
   return SUCCESS;  
} 


#ifdef MAIN 
/* 
 * Modify only the following constants, and the operator switches. 
 */ 
#define USAGE "USAGE : %s nb_quart_tour [-m mask] [im_in|-] [im_out|-]" 
#define PARC 1 // Number of parameters 
#define FINC 1 // Number of input images 
#define FOUTC 1 // Number of output images 
#define MASK 0 // Level of masking 
int main(int argc,char* argv[]) {
   Errc result;
   Pobject* mask;
   Pobject* objin[FINC+1];
   Pobject* objs[FINC+1];
   Pobject* objout[FOUTC+1];
   Pobject* objd[FOUTC+1];
   char *parv[PARC+1];
 
   ReadArgs(argc,argv,PARC,FINC,FOUTC,&mask, objin,objs,objout,objd,parv,USAGE,MASK); 

   switch(objs[0]->Type()){ 
   case Po_Img2duc: { 
      Img2duc* const ims=(Img2duc*)objs[0];
      if ((((Short)atoi(parv[0]))%2)==0)
	 objd[0]=new Img2duc(ims->Height(),ims->Width()); 
      else
	 objd[0]=new Img2duc(ims->Width(),ims->Height()); 
      Img2duc* const imd=(Img2duc*)objd[0]; 
      result=QuartDeTour(*ims,*imd,(Short)atoi(parv[0]));
   } 
      break; 
   case Po_Img2dsl: { 
      Img2dsl* const ims=(Img2dsl*)objs[0]; 
      if(((Short)(atoi(parv[0]))%2)==0)
	 objd[0]=new Img2dsl(ims->Height(),ims->Width()); 
      else objd[0]=new Img2dsl(ims->Width(),ims->Height()); 
      Img2dsl* const imd=(Img2dsl*)objd[0]; 
      result=QuartDeTour(*ims,*imd,(Short)atoi(parv[0]));  
      break; 
   }
   case Po_Img2dsf: { 
      Img2dsf* const ims=(Img2dsf*)objs[0]; 
      if(((Short)(atoi(parv[0]))%2)==0)
	 objd[0]=new Img2dsf(ims->Height(),ims->Width()); 
      else objd[0]=new Img2dsf(ims->Width(),ims->Height()); 
      Img2dsf* const imd=(Img2dsf*)objd[0]; 
      result=QuartDeTour(*ims,*imd,(Short)atoi(parv[0]));
      break; 
   } 
   default: PrintErrorFormat(objin,FINC); 
      result=FAILURE; 
   } 
   WriteArgs(argc,argv,PARC,FINC,FOUTC,&mask,objin,objs,objout,objd,MASK);
   Exit(result); 
   return 0; 
}

#endif
