/* -*- c-basic-offset: 3; mode: c++ -*-
 *
 * 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 Régis Clouard - 1997-07-23
 */

#include <pandore.h>
using namespace pandore;

/**
 * @file penergyvalue.cpp
 * Calculates the total energy of the image.
 * Energy = the square of the sum of the pixels.
 */



Double PEnergyValue( const Img1duc &ims ) {
   Img1duc::ValueType *ps=ims.Vector();
   const Img1duc::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img1dsl &ims ) {
   Img1dsl::ValueType *ps=ims.Vector();
   const Img1dsl::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img1dsf &ims ) {
   Img1dsf::ValueType *ps=ims.Vector();
   const Img1dsf::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img2duc &ims ) {
   Img2duc::ValueType *ps=ims.Vector();
   const Img2duc::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img2dsl &ims ) {
   Img2dsl::ValueType *ps=ims.Vector();
   const Img2dsl::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img2dsf &ims ) {
   Img2dsf::ValueType *ps=ims.Vector();
   const Img2dsf::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img3duc &ims ) {
   Img3duc::ValueType *ps=ims.Vector();
   const Img3duc::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img3dsl &ims ) {
   Img3dsl::ValueType *ps=ims.Vector();
   const Img3dsl::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Img3dsf &ims ) {
   Img3dsf::ValueType *ps=ims.Vector();
   const Img3dsf::ValueType *pf=ims.Vector()+ims.VectorSize();
   Double som=0.0;
   
   for ( ; ps<pf; ps++ ) {
      som += (double)*ps * *ps;
   }
   
   return som / ims.VectorSize();
}

Double PEnergyValue( const Graph2d &grs ) {
   int i;
   double som =0;  
   Ulong nb=0;

   for (i=0;i<grs.Size();i++)
      if ((grs[i]) && (grs[i]->value)){
	 som+=(double)grs[i]->value * grs[i]->value ;
	 nb++;
      }
   return som/nb;
}

Double PEnergyValue( const Graph3d &grs ) {
   int i;
   double som =0;  
   Ulong nb=0;

   for (i=0;i<grs.Size();i++)
      if ((grs[i]) && (grs[i]->value)){
	 som+=(double)grs[i]->value * grs[i]->value ;
	 nb++;
      }
   return som/nb;
}


#ifdef MAIN
#define USAGE	"usage: %s [im_in|-]"
#define PARC	0
#define FINC	1
#define FOUTC	0
#define MASK	0

int main( int argc, char *argv[] ) {
   Errc result;              // The result code of the execution.
   Pobject* mask;            // The region map.
   Pobject* objin[FINC+1];   // The input objects;
   Pobject* objs[FINC+1];    // The source objects masked.
   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_Img1duc) {
      Img1duc* const ims=(Img1duc*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img1dsl) {
      Img1dsl* const ims=(Img1dsl*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img1dsf) {
      Img1dsf* const ims=(Img1dsf*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img2duc) {
      Img2duc* const ims=(Img2duc*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img2dsl) {
      Img2dsl* const ims=(Img2dsl*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img2dsf) {
      Img2dsf* const ims=(Img2dsf*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img3duc) {
      Img3duc* const ims=(Img3duc*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img3dsl) {
      Img3dsl* const ims=(Img3dsl*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Img3dsf) {
      Img3dsf* const ims=(Img3dsf*)objs[0];
      
      result= PEnergyValue(*ims);
      goto end;
   }
   if (objs[0]->Type() == Po_Graph2d) {
      Graph2d* const grs=(Graph2d*)objs[0];
      
      result= PEnergyValue(*grs);
      goto end;
   }
   if (objs[0]->Type() == Po_Graph3d) {
      Graph3d* const grs=(Graph3d*)objs[0];
      
      result= PEnergyValue(*grs);
      goto end;
   }
  {
     PrintErrorFormat(objin,FINC);
     result = FAILURE;
  }	

end:
  if (result)
	WriteArgs(argc,argv,PARC,FINC,FOUTC,&mask,objin,objs,objout,objd,MASK);
  Exit(result);
  return 0;
}
#endif
