/* -*- 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 col2curv.cpp
 *
 * Col2Curv builds the curvelet image at a given scale and a given angle
 *
 * Col2Curv construit l'image de curvelet a une echelle et un angle donnes
 * a partir de la collection.
 */

#include <pandore.h>
using namespace pandore;

/*
 * In the collection curvelet, curvelets are in an array of 3D images 
 * (see fict). But, curvelets are 2D images. In order to visualize an image of 
 * curvelet, this operator reproduces the image at a given scale and
 * a given angle (num_angle).
 * The result is in imd.
 */
Errc Col2Curv(const Collection& curvelet, Img2dsf& imd,  Long scale, Long num_angle) {
   Long i,j; //variables of loop

   Collection** les_curvelets;
   les_curvelets=curvelet.GETPARRAY("curvelets",Collection);
   Img2dsf** curvdata_tmp=les_curvelets[scale-1]->GETPARRAY("curvangles",Img2dsf);
  
   for(i=0; i<imd.Width(); i++)
      for(j=0; j<imd.Height(); j++)
	 imd[j][i]=(*(curvdata_tmp[num_angle-1]))[j][i];
  
   return SUCCESS;  
} 

#ifdef MAIN 
/* 
 * Modify only the following constants, and the operator switches. 
 */ 
#define USAGE "USAGE : %s scale num_angle [-m mask] [col_in|-] [im_out|-]" 
#define PARC 2 // 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; // The result code of the execution. 
   Pobject* mask; // The mask. 
   Pobject* objin[FINC+1]; // The input objects; 
   Pobject* objs[FINC+1]; // The source objects masked by the mask. 
   Pobject* objout[FOUTC+1]; // The output object. 
   Pobject* objd[FOUTC+1]; // The result object of the execution. 
   char *parv[PARC+1]; // The input parameters. 
   
   ReadArgs(argc,argv,PARC,FINC,FOUTC,&mask, objin,objs,objout,objd,parv,USAGE,MASK); 
   
   if ( objs[0]->Type() == Po_Collection ) {
      Collection* const curvelet=(Collection*)objs[0];  
      
      //recovery of size of curvelets in order to allocate imd
      Long nbscales;
      Img1dsl* nbangles;
      Img2dsl** curv_size;
      
      Long height_curv;
      Long width_curv;
      
      Long scale=atol(parv[0]);
      Long num_angle=atol(parv[1]);
      
      //recovery of data
      nbscales=curvelet->GETVALUE("nbscales",Long);
      nbangles=(Img1dsl*)(curvelet->GETPOBJECT("nbangles",Img1dsl));
      curv_size=curvelet->GETPARRAY("curv_size",Img2dsl);
      
      //verification of parameters
      if((scale<1)||(scale>nbscales)) {
	 std::cout<<"ERROR: bad scale"<<std::endl;
	 std::cout<<"give a scale between 1 and "<<nbscales<<std::endl;
	 return FAILURE;
      }
      
      if((num_angle<1)||(num_angle>(*nbangles)[scale-1])) {
	 std::cout<<"ERROR: bad angle"<<std::endl;
	 std::cout<<"give a numero of angle between 1 and "<<(*nbangles)[scale-1];
	 std::cout<<" at the scale "<<scale<<std::endl;
	 return FAILURE;
      }
      
      //recovery of size of the curvelet
      height_curv=(*(curv_size[scale-1]))[num_angle-1][0];
      width_curv=(*(curv_size[scale-1]))[num_angle-1][1];
      
      objd[0]=new Img2dsf(height_curv,width_curv);
      Img2dsf* const imd=(Img2dsf*)objd[0];
      
      result=Col2Curv(*curvelet,*imd,scale,num_angle);  
   } else {
      PrintErrorFormat(objin,FINC);
      result = FAILURE;
   }	
   
   WriteArgs(argc,argv,PARC,FINC,FOUTC,&mask,objin,objs,objout,objd,MASK);
   Exit(result); 
   return 0; 
}

#endif

