diff --git a/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h b/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h
index f9f2861d71802348c2271affd15efa568e83f48f..2bed2ed5a1705ed4735aba4550c0f71f5d920490 100644
--- a/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h
+++ b/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h
@@ -18,7 +18,7 @@
 #ifndef __otbMultiChannelRAndBAndNIRVegetationIndexImageFilter_h
 #define __otbMultiChannelRAndBAndNIRVegetationIndexImageFilter_h
 
-#include "itkInPlaceImageFilter.h"
+#include "itkUnaryFunctorImageFilter.h"
 #include "itkImageRegionIteratorWithIndex.h"
 #include "otbVegetationIndex.h"
 
@@ -26,72 +26,39 @@ namespace otb
 {
 
 /** \class MultiChannelRAndBAndNIRVegetationIndexImageFilter
- * \brief Implements mutli channel R and B and NIR vegetation index operation, pixel-wise generic vegetation index operation on one vector image.
+ * \brief Implements mutli channel R and B and NIR pixel-wise generic vegetation index operation on one vector image.
  *
  * This class is parameterized over the type of the input image and
  * the type of the output image.  It is also parameterized by the
  * operation to be applied, using a Functor style.
  *
+ * \sa UnaryFunctorImageFilter
+ *
  */
 template <class TInputImage, class TOutputImage,
-class TFunction = Functor::ARVI<        typename TInputImage::InternalPixelType,
-typename TInputImage::InternalPixelType,
-typename TInputImage::InternalPixelType,
-typename TOutputImage::PixelType>  >
-class ITK_EXPORT MultiChannelRAndBAndNIRVegetationIndexImageFilter : public itk::InPlaceImageFilter<TInputImage,TOutputImage>
+	  class TFunction = Functor::ARVI< typename TInputImage::InternalPixelType,
+					   typename TInputImage::InternalPixelType,
+					   typename TInputImage::InternalPixelType,
+					   typename TOutputImage::PixelType>  >
+class ITK_EXPORT MultiChannelRAndBAndNIRVegetationIndexImageFilter 
+  : public itk::UnaryFunctorImageFilter<TInputImage,TOutputImage,TFunction>
 {
 public:
   /** Standard class typedefs. */
-  typedef MultiChannelRAndBAndNIRVegetationIndexImageFilter  Self;
-  typedef itk::InPlaceImageFilter<TInputImage,TOutputImage>  Superclass;
-  typedef itk::SmartPointer<Self>   Pointer;
-  typedef itk::SmartPointer<const Self>  ConstPointer;
+  typedef MultiChannelRAndBAndNIRVegetationIndexImageFilter                Self;
+  typedef itk::UnaryFunctorImageFilter<TInputImage,TOutputImage,TFunction> Superclass;
+  typedef itk::SmartPointer<Self>                                          Pointer;
+  typedef itk::SmartPointer<const Self>                                    ConstPointer;
 
   /** Method for creation through the object factory. */
   itkNewMacro(Self);
 
   /** Run-time type information (and related methods). */
-  itkTypeMacro(MultiChannelRAndBAndNIRVegetationIndexImageFilter, InPlaceImageFilter);
+  itkTypeMacro(MultiChannelRAndBAndNIRVegetationIndexImageFilter, UnaryFunctorImageFilter);
 
   /** Some typedefs. */
   typedef TFunction   FunctorType;
-  typedef TInputImage InputImageType;
-  typedef typename    InputImageType::ConstPointer    InputImagePointer;
-  typedef typename    InputImageType::RegionType InputImageRegionType;
-  typedef typename    InputImageType::PixelType  InputImagePixelType;
-  typedef TOutputImage OutputImageType;
-  typedef typename     OutputImageType::Pointer    OutputImagePointer;
-  typedef typename     OutputImageType::RegionType OutputImageRegionType;
-  typedef typename     OutputImageType::PixelType  OutputImagePixelType;
-
-  /** Get the functor object.  The functor is returned by reference.
-   * (Functors do not have to derive from itk::LightObject, so they do
-   * not necessarily have a reference count. So we cannot return a
-   * SmartPointer.) */
-  FunctorType& GetFunctor()
-  {
-    return m_Functor;
-  };
-  const FunctorType& GetFunctor() const
-  {
-    return m_Functor;
-  };
-
-  /** Set the functor object.  This replaces the current Functor with a
-   * copy of the specified Functor. This allows the user to specify a
-   * functor that has ivars set differently than the default functor.
-   * This method requires an operator!=() be defined on the functor
-   * (or the compiler's default implementation of operator!=() being
-   * appropriate). */
-  void SetFunctor(const FunctorType& functor)
-  {
-    if (m_Functor != functor)
-    {
-      m_Functor = functor;
-      this->Modified();
-    }
-  }
-
+  
   /** Set/Get the red channel index. Value must be in [1...[ */
   itkSetMacro(RedIndex,unsigned int);
   itkGetMacro(RedIndex,unsigned int);
@@ -103,33 +70,29 @@ public:
   itkGetMacro(NIRIndex,unsigned int);
 
 protected:
-  MultiChannelRAndBAndNIRVegetationIndexImageFilter();
+  /// Constructor
+  MultiChannelRAndBAndNIRVegetationIndexImageFilter(): m_RedIndex(3),m_BlueIndex(1),m_NIRIndex(4) {};
+  /// Destructor
   virtual ~MultiChannelRAndBAndNIRVegetationIndexImageFilter() {};
-
-  /** MultiChannelRAndBAndNIRVegetationIndexImageFilter can produce an image which is a different
-   * resolution than its input image.  As such, MultiChannelRAndBAndNIRVegetationIndexImageFilter
-   * needs to provide an implementation for
-   * GenerateOutputInformation() in order to inform the pipeline
-   * execution model.  The original documentation of this method is
-   * below.
-   *
-   * \sa ProcessObject::GenerateOutputInformaton()  */
-  virtual void GenerateOutputInformation();
-
-  /** MultiChannelRAndBAndNIRVegetationIndexImageFilter can be implemented as a multithreaded filter.
-   * Therefore, this implementation provides a ThreadedGenerateData() routine
-   * which is called for each processing thread. The output image data is
-   * allocated automatically by the superclass prior to calling
-   * ThreadedGenerateData().  ThreadedGenerateData can only write to the
-   * portion of the output image specified by the parameter
-   * "outputRegionForThread"
-   *
-   * \sa ImageToImageFilter::ThreadedGenerateData(),
-   *     ImageToImageFilter::GenerateData()  */
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            int threadId );
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+  /// Before generating data, set functor parameters
+  virtual void BeforeThreadedGenerateData()
+  {
+    if(m_RedIndex < 1 || m_BlueIndex < 1 || m_NIRIndex < 1)
+      {
+      itkExceptionMacro(<<"Channel indices must belong to range [1, ...[");
+      }
+    this->GetFunctor().SetRedIndex(m_RedIndex);
+    this->GetFunctor().SetBlueIndex(m_BlueIndex);
+    this->GetFunctor().SetNIRIndex(m_NIRIndex);
+  }
+  /// PrintSelf
+  void PrintSelf(std::ostream& os, itk::Indent indent) const
+  {
+    this->Superclass::PrintSelf(os,indent);
+    os << indent << "Red  index: "<<m_RedIndex<<std::endl;
+    os << indent << "Blue index: "<<m_BlueIndex<<std::endl;
+    os << indent << "NIR  index: "<<m_NIRIndex<<std::endl;
+  }
 
 private:
   MultiChannelRAndBAndNIRVegetationIndexImageFilter(const Self&); //purposely not implemented
@@ -141,13 +104,8 @@ private:
   unsigned int m_BlueIndex;
   /** NIR channel index */
   unsigned int m_NIRIndex;
-  FunctorType m_Functor;
 };
 
 } // end namespace otb
 
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.txx"
-#endif
-
 #endif
diff --git a/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.txx b/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.txx
deleted file mode 100644
index 845266542904daa1e470b43e71072bdbe8e7b4bf..0000000000000000000000000000000000000000
--- a/Code/Radiometry/otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.txx
+++ /dev/null
@@ -1,197 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef __otbMultiChannelRAndBAndNIRVegetationIndexImageFilter_txx
-#define __otbMultiChannelRAndBAndNIRVegetationIndexImageFilter_txx
-
-#include "otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkProgressReporter.h"
-
-namespace otb
-{
-
-/**
- * Constructor
- */
-template <class TInputImage, class TOutputImage, class TFunction  >
-MultiChannelRAndBAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::MultiChannelRAndBAndNIRVegetationIndexImageFilter()
-{
-  this->SetNumberOfRequiredInputs( 1 );
-  this->InPlaceOff();
-}
-
-/**
- * MultiChannelRAndBAndNIRVegetationIndexImageFilter can produce an image which is a different resolution
- * than its input image.  As such, MultiChannelRAndBAndNIRVegetationIndexImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model.  The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton()
- */
-template <class TInputImage, class TOutputImage, class TFunction>
-void
-MultiChannelRAndBAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::GenerateOutputInformation()
-{
-  // do not call the superclass' implementation of this method since
-  // this filter allows the input the output to be of different dimensions
-
-  // get pointers to the input and output
-  typename Superclass::OutputImagePointer      outputPtr = this->GetOutput();
-  typename Superclass::InputImageConstPointer  inputPtr  = this->GetInput();
-
-  if ( !outputPtr || !inputPtr)
-  {
-    return;
-  }
-
-  // Set the output image largest possible region.  Use a RegionCopier
-  // so that the input and output images can be different dimensions.
-  OutputImageRegionType outputLargestPossibleRegion;
-  this->CallCopyInputRegionToOutputRegion(outputLargestPossibleRegion,
-                                          inputPtr->GetLargestPossibleRegion());
-  outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
-
-  // Set the output spacing and origin
-  const itk::ImageBase<Superclass::InputImageDimension> *phyData;
-
-  phyData
-  = dynamic_cast<const itk::ImageBase<Superclass::InputImageDimension>*>(this->GetInput());
-
-  if (phyData)
-  {
-    // Copy what we can from the image from spacing and origin of the input
-    // This logic needs to be augmented with logic that select which
-    // dimensions to copy
-    unsigned int i, j;
-    const typename InputImageType::SpacingType&
-    inputSpacing = inputPtr->GetSpacing();
-    const typename InputImageType::PointType&
-    inputOrigin = inputPtr->GetOrigin();
-    const typename InputImageType::DirectionType&
-    inputDirection = inputPtr->GetDirection();
-
-    typename OutputImageType::SpacingType outputSpacing;
-    typename OutputImageType::PointType outputOrigin;
-    typename OutputImageType::DirectionType outputDirection;
-
-    // copy the input to the output and fill the rest of the
-    // output with zeros.
-    for (i=0; i < Superclass::InputImageDimension; ++i)
-    {
-      outputSpacing[i] = inputSpacing[i];
-      outputOrigin[i] = inputOrigin[i];
-      for (j=0; j < Superclass::OutputImageDimension; j++)
-      {
-        if (j < Superclass::InputImageDimension)
-        {
-          outputDirection[j][i] = inputDirection[j][i];
-        }
-        else
-        {
-          outputDirection[j][i] = 0.0;
-        }
-      }
-    }
-    for (; i < Superclass::OutputImageDimension; ++i)
-    {
-      outputSpacing[i] = 1.0;
-      outputOrigin[i] = 0.0;
-      for (j=0; j < Superclass::OutputImageDimension; j++)
-      {
-        if (j == i)
-        {
-          outputDirection[j][i] = 1.0;
-        }
-        else
-        {
-          outputDirection[j][i] = 0.0;
-        }
-      }
-    }
-
-    // set the spacing and origin
-    outputPtr->SetSpacing( outputSpacing );
-    outputPtr->SetOrigin( outputOrigin );
-    outputPtr->SetDirection( outputDirection );
-    outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info
-      inputPtr->GetNumberOfComponentsPerPixel());
-  }
-  else
-  {
-    // pointer could not be cast back down
-    itkExceptionMacro(<< "otb::MultiChannelRAndBAndNIRVegetationIndexImageFilter::GenerateOutputInformation "
-                      << "cannot cast input to "
-                      << typeid(itk::ImageBase<Superclass::InputImageDimension>*).name() );
-  }
-}
-
-
-/**
- * ThreadedGenerateData Performs the pixel-wise addition
- */
-template <class TInputImage, class TOutputImage, class TFunction  >
-void
-MultiChannelRAndBAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
-                        int threadId)
-{
-  InputImagePointer  inputPtr = this->GetInput();
-  OutputImagePointer outputPtr = this->GetOutput(0);
-
-  // Define the portion of the input to walk for this thread, using
-  // the CallCopyOutputRegionToInputRegion method allows for the input
-  // and output images to be different dimensions
-  InputImageRegionType inputRegionForThread;
-  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-
-  // Define the iterators
-  itk::ImageRegionConstIterator<TInputImage>  inputIt(inputPtr, inputRegionForThread);
-  itk::ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
-
-  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-
-  inputIt.GoToBegin();
-  outputIt.GoToBegin();
-
-  while ( !inputIt.IsAtEnd() )
-  {
-    outputIt.Set( m_Functor( inputIt.Get()[m_RedIndex-1],inputIt.Get()[m_BlueIndex-1], inputIt.Get()[m_NIRIndex-1] ) );
-    ++inputIt;
-    ++outputIt;
-    progress.CompletedPixel();  // potential exception thrown here
-  }
-}
-
-template <class TInputImage, class TOutputImage, class TFunction  >
-void
-MultiChannelRAndBAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  this->Superclass::PrintSelf(os,indent);
-  os << indent << "Red index: "<<m_RedIndex<<std::endl;
-  os << indent << "Blue index: "<<m_BlueIndex<<std::endl;
-  os << indent << "NIR index: "<<m_NIRIndex<<std::endl;
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.h b/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.h
index 0bdee3acbeee1bea2a20e7705c615ef825f65e87..a95d32261d59201b9d6b4382fa6f5ba03310f53a 100644
--- a/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.h
+++ b/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.h
@@ -18,7 +18,7 @@
 #ifndef __otbMultiChannelRAndNIRVegetationIndexImageFilter_h
 #define __otbMultiChannelRAndNIRVegetationIndexImageFilter_h
 
-#include "itkInPlaceImageFilter.h"
+#include "itkUnaryFunctorImageFilter.h"
 #include "itkImageRegionIteratorWithIndex.h"
 #include "otbVegetationIndex.h"
 
@@ -26,71 +26,37 @@ namespace otb
 {
 
 /** \class MultiChannelRAndNIRVegetationIndexImageFilter
- * \brief Implements mutli channel R and NIR vegetation index operation, pixel-wise generic vegetation index operation on one vector image.
+ * \brief Implements mutli channel R and NIR  pixel-wise generic vegetation index operation on one vector image.
  *
  * This class is parameterized over the type of the input image and
  * the type of the output image.  It is also parameterized by the
  * operation to be applied, using a Functor style.
- *
+ * 
+ * \sa UnaryFunctorImageFilter
  */
 template <class TInputImage, class TOutputImage,
-class TFunction = Functor::NDVI<        typename TInputImage::InternalPixelType,
-typename TInputImage::InternalPixelType,
-typename TOutputImage::PixelType>  >
-class ITK_EXPORT MultiChannelRAndNIRVegetationIndexImageFilter : public itk::InPlaceImageFilter<TInputImage,TOutputImage>
+	  class TFunction = Functor::NDVI< typename TInputImage::InternalPixelType,
+					   typename TInputImage::InternalPixelType,
+					   typename TOutputImage::PixelType>  >
+class ITK_EXPORT MultiChannelRAndNIRVegetationIndexImageFilter 
+  : public itk::UnaryFunctorImageFilter<TInputImage,TOutputImage, TFunction>
 {
 public:
   /** Standard class typedefs. */
-  typedef MultiChannelRAndNIRVegetationIndexImageFilter  Self;
-  typedef itk::InPlaceImageFilter<TInputImage,TOutputImage>  Superclass;
-  typedef itk::SmartPointer<Self>   Pointer;
-  typedef itk::SmartPointer<const Self>  ConstPointer;
+  typedef MultiChannelRAndNIRVegetationIndexImageFilter                     Self;
+  typedef itk::UnaryFunctorImageFilter<TInputImage,TOutputImage, TFunction> Superclass;
+  typedef itk::SmartPointer<Self>                                           Pointer;
+  typedef itk::SmartPointer<const Self>                                     ConstPointer;
 
   /** Method for creation through the object factory. */
   itkNewMacro(Self);
 
   /** Run-time type information (and related methods). */
-  itkTypeMacro(MultiChannelRAndNIRVegetationIndexImageFilter, InPlaceImageFilter);
+  itkTypeMacro(MultiChannelRAndNIRVegetationIndexImageFilter, UnaryFunctorImageFilter);
 
   /** Some typedefs. */
   typedef TFunction   FunctorType;
-  typedef TInputImage InputImageType;
-  typedef typename    InputImageType::ConstPointer    InputImagePointer;
-  typedef typename    InputImageType::RegionType InputImageRegionType;
-  typedef typename    InputImageType::PixelType  InputImagePixelType;
-  typedef TOutputImage OutputImageType;
-  typedef typename     OutputImageType::Pointer    OutputImagePointer;
-  typedef typename     OutputImageType::RegionType OutputImageRegionType;
-  typedef typename     OutputImageType::PixelType  OutputImagePixelType;
-
-  /** Get the functor object.  The functor is returned by reference.
-   * (Functors do not have to derive from itk::LightObject, so they do
-   * not necessarily have a reference count. So we cannot return a
-   * SmartPointer.) */
-  FunctorType& GetFunctor()
-  {
-    return m_Functor;
-  };
-  const FunctorType& GetFunctor() const
-  {
-    return m_Functor;
-  };
-
-  /** Set the functor object.  This replaces the current Functor with a
-   * copy of the specified Functor. This allows the user to specify a
-   * functor that has ivars set differently than the default functor.
-   * This method requires an operator!=() be defined on the functor
-   * (or the compiler's default implementation of operator!=() being
-   * appropriate). */
-  void SetFunctor(const FunctorType& functor)
-  {
-    if (m_Functor != functor)
-    {
-      m_Functor = functor;
-      this->Modified();
-    }
-  }
-
+ 
   /** Set/Get the red channel index. Value must be in [1...[ */
   itkSetMacro(RedIndex,unsigned int);
   itkGetMacro(RedIndex,unsigned int);
@@ -99,49 +65,35 @@ public:
   itkGetMacro(NIRIndex,unsigned int);
 
 protected:
-  MultiChannelRAndNIRVegetationIndexImageFilter();
+  /// Constructor
+  MultiChannelRAndNIRVegetationIndexImageFilter(): m_RedIndex(3), m_NIRIndex(4) {};
+  /// Destructor
   virtual ~MultiChannelRAndNIRVegetationIndexImageFilter() {};
-
-  /** MultiChannelRAndNIRVegetationIndexImageFilter can produce an image which is a different
-   * resolution than its input image.  As such, MultiChannelRAndNIRVegetationIndexImageFilter
-   * needs to provide an implementation for
-   * GenerateOutputInformation() in order to inform the pipeline
-   * execution model.  The original documentation of this method is
-   * below.
-   *
-   * \sa ProcessObject::GenerateOutputInformaton()  */
-  virtual void GenerateOutputInformation();
-
-  /** MultiChannelRAndNIRVegetationIndexImageFilter can be implemented as a multithreaded filter.
-   * Therefore, this implementation provides a ThreadedGenerateData() routine
-   * which is called for each processing thread. The output image data is
-   * allocated automatically by the superclass prior to calling
-   * ThreadedGenerateData().  ThreadedGenerateData can only write to the
-   * portion of the output image specified by the parameter
-   * "outputRegionForThread"
-   *
-   * \sa ImageToImageFilter::ThreadedGenerateData(),
-   *     ImageToImageFilter::GenerateData()  */
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            int threadId );
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
+  /// Before generating data, set functor parameters
+  virtual void BeforeThreadedGenerateData()
+  {
+    if(m_RedIndex < 1 || m_NIRIndex < 1)
+      {
+      itkExceptionMacro(<<"Channel indices must belong to range [1, ...[");
+      }
+    this->GetFunctor().SetRedIndex(m_RedIndex);
+    this->GetFunctor().SetNIRIndex(m_NIRIndex);
+  }
+  /// PrintSelf Method
+  void PrintSelf(std::ostream& os, itk::Indent indent) const
+  {
+    this->Superclass::PrintSelf(os,indent);
+    os << indent << "Red index: "<<m_RedIndex<<std::endl;
+    os << indent << "NIR index: "<<m_NIRIndex<<std::endl;
+  }
 private:
   MultiChannelRAndNIRVegetationIndexImageFilter(const Self&); //purposely not implemented
   void operator=(const Self&); //purposely not implemented
-
   /** Red channel index */
   unsigned int m_RedIndex;
   /** NIR channel index */
   unsigned int m_NIRIndex;
-  FunctorType m_Functor;
 };
-
 } // end namespace otb
 
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbMultiChannelRAndNIRVegetationIndexImageFilter.txx"
-#endif
-
 #endif
diff --git a/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.txx b/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.txx
deleted file mode 100644
index 8d0695b5d7d6b2aed25e125b4ea53d27a1ea53bb..0000000000000000000000000000000000000000
--- a/Code/Radiometry/otbMultiChannelRAndNIRVegetationIndexImageFilter.txx
+++ /dev/null
@@ -1,197 +0,0 @@
-/*=========================================================================
-
-  Program:   ORFEO Toolbox
-  Language:  C++
-  Date:      $Date$
-  Version:   $Revision$
-
-
-  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
-  See OTBCopyright.txt for details.
-
-
-     This software is distributed WITHOUT ANY WARRANTY; without even
-     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-     PURPOSE.  See the above copyright notices for more information.
-
-=========================================================================*/
-#ifndef __otbMultiChannelRAndNIRVegetationIndexImageFilter_txx
-#define __otbMultiChannelRAndNIRVegetationIndexImageFilter_txx
-
-#include "otbMultiChannelRAndNIRVegetationIndexImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkProgressReporter.h"
-
-namespace otb
-{
-
-/**
- * Constructor
- */
-template <class TInputImage, class TOutputImage, class TFunction  >
-MultiChannelRAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::MultiChannelRAndNIRVegetationIndexImageFilter()
-{
-  this->SetNumberOfRequiredInputs( 1 );
-  this->InPlaceOff();
-}
-
-/**
- * MultiChannelRAndNIRVegetationIndexImageFilter can produce an image which is a different resolution
- * than its input image.  As such, MultiChannelRAndNIRVegetationIndexImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model.  The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton()
- */
-template <class TInputImage, class TOutputImage, class TFunction>
-void
-MultiChannelRAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::GenerateOutputInformation()
-{
-  // do not call the superclass' implementation of this method since
-  // this filter allows the input the output to be of different dimensions
-
-  // get pointers to the input and output
-  typename Superclass::OutputImagePointer      outputPtr = this->GetOutput();
-  typename Superclass::InputImageConstPointer  inputPtr  = this->GetInput();
-
-  if ( !outputPtr || !inputPtr)
-  {
-    return;
-  }
-
-  // Set the output image largest possible region.  Use a RegionCopier
-  // so that the input and output images can be different dimensions.
-  OutputImageRegionType outputLargestPossibleRegion;
-  this->CallCopyInputRegionToOutputRegion(outputLargestPossibleRegion,
-                                          inputPtr->GetLargestPossibleRegion());
-  outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
-
-  // Set the output spacing and origin
-  const itk::ImageBase<Superclass::InputImageDimension> *phyData;
-
-  phyData
-  = dynamic_cast<const itk::ImageBase<Superclass::InputImageDimension>*>(this->GetInput());
-
-  if (phyData)
-  {
-    // Copy what we can from the image from spacing and origin of the input
-    // This logic needs to be augmented with logic that select which
-    // dimensions to copy
-    unsigned int i, j;
-    const typename InputImageType::SpacingType&
-    inputSpacing = inputPtr->GetSpacing();
-    const typename InputImageType::PointType&
-    inputOrigin = inputPtr->GetOrigin();
-    const typename InputImageType::DirectionType&
-    inputDirection = inputPtr->GetDirection();
-
-    typename OutputImageType::SpacingType outputSpacing;
-    typename OutputImageType::PointType outputOrigin;
-    typename OutputImageType::DirectionType outputDirection;
-
-    // copy the input to the output and fill the rest of the
-    // output with zeros.
-    for (i=0; i < Superclass::InputImageDimension; ++i)
-    {
-      outputSpacing[i] = inputSpacing[i];
-      outputOrigin[i] = inputOrigin[i];
-      for (j=0; j < Superclass::OutputImageDimension; j++)
-      {
-        if (j < Superclass::InputImageDimension)
-        {
-          outputDirection[j][i] = inputDirection[j][i];
-        }
-        else
-        {
-          outputDirection[j][i] = 0.0;
-        }
-      }
-    }
-    for (; i < Superclass::OutputImageDimension; ++i)
-    {
-      outputSpacing[i] = 1.0;
-      outputOrigin[i] = 0.0;
-      for (j=0; j < Superclass::OutputImageDimension; j++)
-      {
-        if (j == i)
-        {
-          outputDirection[j][i] = 1.0;
-        }
-        else
-        {
-          outputDirection[j][i] = 0.0;
-        }
-      }
-    }
-
-    // set the spacing and origin
-    outputPtr->SetSpacing( outputSpacing );
-    outputPtr->SetOrigin( outputOrigin );
-    outputPtr->SetDirection( outputDirection );
-    outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info
-      inputPtr->GetNumberOfComponentsPerPixel());
-  }
-  else
-  {
-    // pointer could not be cast back down
-    itkExceptionMacro(<< "otb::MultiChannelRAndNIRVegetationIndexImageFilter::GenerateOutputInformation "
-                      << "cannot cast input to "
-                      << typeid(itk::ImageBase<Superclass::InputImageDimension>*).name() );
-  }
-}
-
-
-/**
- * ThreadedGenerateData Performs the pixel-wise addition
- */
-template <class TInputImage, class TOutputImage, class TFunction  >
-void
-MultiChannelRAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
-                        int threadId)
-{
-  InputImagePointer  inputPtr = this->GetInput();
-  OutputImagePointer outputPtr = this->GetOutput(0);
-
-  // Define the portion of the input to walk for this thread, using
-  // the CallCopyOutputRegionToInputRegion method allows for the input
-  // and output images to be different dimensions
-  InputImageRegionType inputRegionForThread;
-  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-
-  // Define the iterators
-  itk::ImageRegionConstIterator<TInputImage>  inputIt(inputPtr, inputRegionForThread);
-  itk::ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
-
-  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-
-  inputIt.GoToBegin();
-  outputIt.GoToBegin();
-
-  while ( !inputIt.IsAtEnd() )
-  {
-//    outputIt.Set( m_Functor( inputIt.Get() ) );
-    outputIt.Set( m_Functor( inputIt.Get()[m_RedIndex-1], inputIt.Get()[m_NIRIndex-1] ) );
-    ++inputIt;
-    ++outputIt;
-    progress.CompletedPixel();  // potential exception thrown here
-  }
-}
-
-template <class TInputImage, class TOutputImage, class TFunction  >
-void
-MultiChannelRAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  this->Superclass::PrintSelf(os,indent);
-  os << indent << "Red index: "<<m_RedIndex<<std::endl;
-  os << indent << "NIR index: "<<m_NIRIndex<<std::endl;
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Code/Radiometry/otbVegetationIndex.h b/Code/Radiometry/otbVegetationIndex.h
index ba2763e05680eac2a46fa74939c6a604112faee5..06ae70dde6eb0ab8ca4e2b2dd155b19c721ea780 100644
--- a/Code/Radiometry/otbVegetationIndex.h
+++ b/Code/Radiometry/otbVegetationIndex.h
@@ -19,11 +19,148 @@
 #define __otbVegetationIndex_h
 
 #include "otbMath.h"
+#include "itkVariableLengthVector.h"
 
 namespace otb
 {
 namespace Functor
 {
+/** Base class for R And NIR based Index
+*  Implement operators for UnaryFunctorImageFilter templated with a
+*  VectorImage and BinaryFunctorImageFilter templated with single
+*  images.
+*  Subclasses should NOT overload operators, they must  re-implement 
+*  the Evaluate() method.
+*/
+template<class TInput1, class TInput2, class TOutput>
+class RAndNIRIndexBase
+{
+public:
+  /// Vector pixel type used to support both vector images and multiple
+  /// input images
+  typedef itk::VariableLengthVector<TInput1> InputVectorType;
+  
+  // Operator on vector pixel type
+  inline TOutput operator()(const InputVectorType & inputVector)
+  {
+    return this->Evaluate(inputVector[m_RedIndex-1],static_cast<TInput2>(inputVector[m_NIRIndex-1])); 
+  }
+
+  // Binary operator
+  inline TOutput operator()(const TInput1 &r, const TInput2 &nir) 
+  {
+    return this->Evaluate(r,nir);
+  };
+  /// Constructor
+  RAndNIRIndexBase() : m_RedIndex(3), m_NIRIndex(4) {};
+  /// Desctructor
+  ~RAndNIRIndexBase() {};
+  
+  /// Set Red Index
+  void SetRedIndex(unsigned int channel)
+  {
+    m_RedIndex = channel;
+  }
+  /// Get Red Index
+  unsigned int GetRedIndex()
+  {
+    return m_RedIndex;
+  }
+  /// Set NIR Index
+  void SetNIRIndex(unsigned int channel)
+  {
+    m_NIRIndex = channel;
+  }
+  /// Get NIR Index
+  unsigned int GetNIRIndex()
+  {
+    return m_NIRIndex;
+  }
+protected:
+  // This method must be reimplemented in subclasses to actually
+  // compute the index value
+  virtual TOutput Evaluate(const TInput1 & r, const TInput2 & nir) const = 0;
+
+private:
+  unsigned int m_RedIndex;
+  unsigned int m_NIRIndex;
+};
+
+/** base class for R, B And NIR based Index
+*  Implement operators for UnaryFunctorImageFilter templated with a
+*  VectorImage and BinaryFunctorImageFilter templated with single
+*  images.
+*  Subclasses should NOT overload operators, they must  re-implement 
+*  the Evaluate() method.
+*/
+template<class TInput1, class TInput2, class TInput3, class TOutput>
+class RBAndNIRIndexBase
+{
+public:
+  /// Vector pixel type used to support both vector images and multiple
+  /// input images
+  typedef itk::VariableLengthVector<TInput1> InputVectorType;
+  
+  // Operator on vector pixel type
+  inline TOutput operator()(const InputVectorType & inputVector)
+  {
+    return this->Evaluate(inputVector[m_RedIndex-1],static_cast<TInput2>(inputVector[m_BlueIndex-1]), static_cast<TInput3>(inputVector[m_NIRIndex-1])); 
+  }
+
+  // Binary operator
+  inline TOutput operator()(const TInput1 &r, const TInput2 &b, const TInput2 &nir) 
+  {
+    return this->Evaluate(r,b,nir);
+  };
+  /// Constructor
+  RBAndNIRIndexBase() : m_RedIndex(3), m_BlueIndex(1), m_NIRIndex(4) {};
+  /// Desctructor
+  ~RBAndNIRIndexBase() {};
+  
+  /// Set Red Index
+  void SetRedIndex(unsigned int channel)
+  {
+    m_RedIndex = channel;
+  }
+  /// Get Red Index
+  unsigned int GetRedIndex()
+  {
+    return m_RedIndex;
+  }
+  /// Set Blue Index
+  void SetBlueIndex(unsigned int channel)
+  {
+    m_BlueIndex = channel;
+  }
+  /// Get Blue Index
+  unsigned int GetBlueIndex()
+  {
+    return m_BlueIndex;
+  }
+
+  /// Set NIR Index
+  void SetNIRIndex(unsigned int channel)
+  {
+    m_NIRIndex = channel;
+  }
+  /// Get NIR Index
+  unsigned int GetNIRIndex()
+  {
+    return m_NIRIndex;
+  }
+protected:
+  // This method must be reimplemented in subclasses to actually
+  // compute the index value
+  virtual TOutput Evaluate(const TInput1 & r, const TInput2& b, const TInput3 & nir) const = 0;
+
+private:
+  unsigned int m_RedIndex;
+  unsigned int m_BlueIndex;
+  unsigned int m_NIRIndex;
+};
+
+
+
 /** \class NDVI
  *  \brief This functor calculate the NormalizeD Vegetation Index (NDVI)
  *
@@ -32,19 +169,23 @@ namespace Functor
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TOutput>
-class NDVI
+class NDVI : public RAndNIRIndexBase<TInput1,TInput2,TOutput>
 {
 public:
+  /// Constructor
   NDVI() {};
+  /// Desctructor
   ~NDVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
+  // Operator on r and nir single pixel values
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
   {
     double dr = static_cast<double>(r);
     double dnir = static_cast<double>(nir);
     if ( (nir + r) == 0 )
-    {
+      {
       return static_cast<TOutput>(0.);
-    }
+      }
 
     return ( static_cast<TOutput>((dnir-dr)/(dnir+dr)));
   }
@@ -58,19 +199,20 @@ public:
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TOutput>
-class RVI
+class RVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
 {
 public:
   RVI() {};
   ~RVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
   {
     double dr = static_cast<double>(r);
     double dnir = static_cast<double>(nir);
     if ( r == 0 )
-    {
+      {
       return static_cast<TOutput>(0.);
-    }
+      }
     return ( static_cast<TOutput>(dnir/dr));
   }
 };
@@ -82,17 +224,11 @@ public:
  *  \ingroup Functor2
  */
 template <class TInput1, class TInput2, class TOutput>
-class PVI
+class PVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
 {
 public:
   PVI() {};
   ~PVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
-  {
-    double dnir = static_cast<double>(nir);
-    double dr = static_cast<double>(r);
-    return ( static_cast<TOutput>(  (dnir - m_A*dr - m_B)*m_Coeff) );
-  }
   /** Set/Get A and B parameters */
   void SetA(const double A)
   {
@@ -111,7 +247,14 @@ public:
   {
     return (  m_B );
   }
-
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
+  {
+    double dnir = static_cast<double>(nir);
+    double dr = static_cast<double>(r);
+    return ( static_cast<TOutput>(  (dnir - m_A*dr - m_B)*m_Coeff) );
+  }
+ 
 private:
 
   /** A and B parameters */
@@ -131,22 +274,12 @@ private:
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TOutput>
-class SAVI
+class SAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
 {
 public:
   SAVI() : m_L(0.5) {};
   ~SAVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
-  {
-    double dnir = static_cast<double>(nir);
-    double dr = static_cast<double>(r);
-    double denominator = dnir + dr + m_L;
-    if ( denominator == 0. )
-    {
-      return static_cast<TOutput>(0.);
-    }
-    return ( static_cast<TOutput>(  ((dnir-dr)*(1+m_L))/denominator ) );
-  }
+
   /** Set/Get L correction */
   void SetL(const double L)
   {
@@ -157,6 +290,19 @@ public:
     return (  m_L );
   }
 
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
+  {
+    double dnir = static_cast<double>(nir);
+    double dr = static_cast<double>(r);
+    double denominator = dnir + dr + m_L;
+    if ( denominator == 0. )
+      {
+      return static_cast<TOutput>(0.);
+      }
+    return ( static_cast<TOutput>(  ((dnir-dr)*(1+m_L))/denominator ) );
+  }
+
 private:
 
   /** L correction */
@@ -171,22 +317,12 @@ private:
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TOutput>
-class TSAVI
+class TSAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
 {
 public:
   TSAVI() : m_X(0.08) {};
   ~TSAVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
-  {
-    double dnir = static_cast<double>(nir);
-    double dr = static_cast<double>(r);
-    double denominator = m_A*dnir + dr + m_X*(1.+m_A*m_A);
-    if ( denominator == 0. )
-    {
-      return static_cast<TOutput>(0.);
-    }
-    return ( static_cast<TOutput>(  (m_A*(dnir - m_A*dr - m_B))/denominator ) );
-  }
+  
   /** Set/Get A and B parameters */
   void SetA(const double A)
   {
@@ -214,6 +350,19 @@ public:
     return (m_X);
   }
 
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
+  {
+    double dnir = static_cast<double>(nir);
+    double dr = static_cast<double>(r);
+    double denominator = m_A*dnir + dr + m_X*(1.+m_A*m_A);
+    if ( denominator == 0. )
+      {
+      return static_cast<TOutput>(0.);
+      }
+    return ( static_cast<TOutput>(  (m_A*(dnir - m_A*dr - m_B))/denominator ) );
+  }
+  
 private:
 
   /** A and B parameters */
@@ -232,20 +381,22 @@ private:
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TOutput>
-class MSAVI
+class MSAVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput>
 {
 public:
   MSAVI() {};
   ~MSAVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &nir)
+
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const
   {
     double dnir = static_cast<double>(nir);
     double dr = static_cast<double>(r);
     double sqrt_value = (2*dnir+1)*(2*dnir+1) - 8*(dnir-dr);
     if ( sqrt_value < 0. )
-    {
+      {
       return static_cast<TOutput>(0.);
-    }
+      }
     return ( static_cast<TOutput>(  (2*dnir + 1 - vcl_sqrt(sqrt_value))/2. ) );
   }
 
@@ -256,17 +407,29 @@ public:
  *
  *  This vegetation index use three inputs channels
  *
- *  [Yoram J. Kaufman and Didier Tanr�, 1992]
+ *  [Yoram J. Kaufman and Didier Tanre, 1992]
  *
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TInput3, class TOutput>
-class ARVI
+class ARVI : public RBAndNIRIndexBase<TInput1,TInput2,TInput3,TOutput>
 {
 public:
   ARVI() : m_Gamma(0.5) {};
   ~ARVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &b, const TInput3 &nir)
+
+  /** Set/Get Gamma parameter */
+  void SetGamma(const double gamma)
+  {
+    m_Gamma = gamma;
+  }
+  double GetGamma(void)const
+  {
+    return (m_Gamma);
+  }
+
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const
   {
     double dr = static_cast<double>(r);
     double db = static_cast<double>(b);
@@ -274,20 +437,11 @@ public:
     double RHOrb = dr - m_Gamma*(db - dr);
     double denominator = dnir + RHOrb;
     if ( denominator == 0. )
-    {
+      {
       return static_cast<TOutput>(0.);
-    }
+      }
     return ( static_cast<TOutput>(  (dnir - RHOrb)/denominator ) );
   }
-  /** Set/Get Gamma parameter */
-  void SetGamma(const double gamma)
-  {
-    m_Gamma = gamma;
-  }
-  double GetGamma(void)const
-  {
-    return (m_Gamma);
-  }
 
 private:
 
@@ -305,25 +459,12 @@ private:
  *  \ingroup Functor
  */
 template <class TInput1, class TInput2, class TInput3, class TOutput>
-class EVI
+class EVI : public RBAndNIRIndexBase<TInput1,TInput2,TInput3,TOutput>
 {
 public:
   EVI() : m_G(2.5), m_C1(6.0), m_C2(7.5), m_L(1.0) {};
   ~EVI() {};
-  inline TOutput operator()(const TInput1 &r, const TInput2 &b, const TInput3 &nir)
-  {
-    double dr = static_cast<double>(r);
-    double db = static_cast<double>(b);
-    double dnir = static_cast<double>(nir);
-    double denominator = dnir + m_C1*dr - m_C2*db + m_L;
-    if ( denominator == 0. )
-    {
-      return static_cast<TOutput>(0.);
-    }
-    return ( static_cast<TOutput>( m_G * (dnir - dr)/denominator ) );
-//return ( static_cast<TOutput>( dnir ) );
-  }
-  /** Set/Get G parameter */
+/** Set/Get G parameter */
   void SetG(const double g)
   {
     m_G = g;
@@ -359,7 +500,20 @@ public:
   {
     return (m_L);
   }
-
+protected:
+  inline TOutput Evaluate(const TInput1 &r, const TInput2 &b, const TInput3 &nir) const
+  {
+    double dr = static_cast<double>(r);
+    double db = static_cast<double>(b);
+    double dnir = static_cast<double>(nir);
+    double denominator = dnir + m_C1*dr - m_C2*db + m_L;
+    if ( denominator == 0. )
+      {
+      return static_cast<TOutput>(0.);
+      }
+    return ( static_cast<TOutput>( m_G * (dnir - dr)/denominator ) );
+  }
+  
 private:
 
   /** Gain factor */
diff --git a/Code/SpatialReasoning/otbPolygonListToRCC8GraphFilter.txx b/Code/SpatialReasoning/otbPolygonListToRCC8GraphFilter.txx
index df6876db6fdd863837cad3d2ce62c92d97d89ecc..45d96e97bef2f9596ef24d34e6f97a72b3224002 100644
--- a/Code/SpatialReasoning/otbPolygonListToRCC8GraphFilter.txx
+++ b/Code/SpatialReasoning/otbPolygonListToRCC8GraphFilter.txx
@@ -341,7 +341,18 @@ PolygonListToRCC8GraphFilter<TPolygonList, TOutputGraph>
           {
             // Add the edge to the graph.
             otbMsgDevMacro(<<"Adding edge: "<<vIt1.GetIndex()<<" -> "<<vIt2.GetIndex()<<": "<<value);
-            m_EdgesPerThread[threadId][EdgePairType(vIt1.GetIndex(),vIt2.GetIndex())]=value;
+	    if(value==OTB_RCC8_NTPPI)
+	      {
+	      m_EdgesPerThread[threadId][EdgePairType(vIt2.GetIndex(),vIt1.GetIndex())]=OTB_RCC8_NTPP;
+	      }
+	    else if(value == OTB_RCC8_TPPI)
+	      {
+	      m_EdgesPerThread[threadId][EdgePairType(vIt2.GetIndex(),vIt1.GetIndex())]=OTB_RCC8_TPP;
+	      }
+	    else
+	      {
+	      m_EdgesPerThread[threadId][EdgePairType(vIt1.GetIndex(),vIt2.GetIndex())]=value;
+	      }
             if (m_UseInverted)
             {
               m_EdgesPerThread[threadId][EdgePairType(vIt2.GetIndex(),vIt1.GetIndex())]=invert[value];