diff --git a/Code/BasicFilters/otbMeanShiftImageFilter.txx b/Code/BasicFilters/otbMeanShiftImageFilter.txx
index 9d8614950eadd46135dcd357fe596d61b9ca16f1..1bd3aa742e13f6f475fc51356f41dfe62fdeaef8 100644
--- a/Code/BasicFilters/otbMeanShiftImageFilter.txx
+++ b/Code/BasicFilters/otbMeanShiftImageFilter.txx
@@ -192,7 +192,7 @@ MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput, TBufferConverter
 template <class TInputImage, class TOutputImage, class TLabeledOutput, class TBufferConverter>
 void
 MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput, TBufferConverter>
-::ThreadedGenerateData(const RegionType& outputRegionForThread, int threadId)
+::ThreadedGenerateData(const RegionType& outputRegionForThread, int itkNotUsed(threadId))
 {
   // Input and output pointers
   typename InputImageType::ConstPointer inputPtr  = this->GetInput();
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx b/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3d4bd8d9e92b175790fb5236b101caa10bd7bf1e
--- /dev/null
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.cxx
@@ -0,0 +1,103 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#include "otbStreamingShrinkImageFilter.h"
+
+namespace otb
+{
+
+unsigned int
+StreamingShrinkImageRegionSplitter
+::GetNumberOfSplits(const RegionType& region, unsigned int requestedNumber)
+{
+  unsigned int theoricalNbPixelPerTile = region.GetNumberOfPixels() / requestedNumber;
+  unsigned int theoricalTileDimension = static_cast<unsigned int> (vcl_sqrt(static_cast<double>(theoricalNbPixelPerTile)) );
+
+  // Take the previous multiple of m_TileSizeAlignment (eventually generate more splits than requested)
+  m_TileDimension = theoricalTileDimension / m_TileSizeAlignment * m_TileSizeAlignment;
+
+  // Minimal tile size is m_TileSizeAlignment * m_TileSizeAlignment
+  if (m_TileDimension < m_TileSizeAlignment)
+    {
+    otbMsgDevMacro(<< "Using the minimal tile size : " << m_TileSizeAlignment << " * " << m_TileSizeAlignment);
+    m_TileDimension = m_TileSizeAlignment;
+    }
+
+  // Use the computed tile size, and generate (m_TileDimension * 1) tiles
+  const SizeType&  regionSize = region.GetSize();
+  m_SplitsPerDimension[0] = (regionSize[0] + m_TileDimension - 1) / m_TileDimension;
+  m_SplitsPerDimension[1] = regionSize[1] / m_TileSizeAlignment;
+
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < ImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  otbMsgDevMacro(<< "Tile dimension : " << m_TileDimension)
+  otbMsgDevMacro(<< "Number of splits per dimension : " << m_SplitsPerDimension[0] << " " <<  m_SplitsPerDimension[1])
+
+  return numPieces;
+}
+
+StreamingShrinkImageRegionSplitter::RegionType
+StreamingShrinkImageRegionSplitter
+::GetSplit(unsigned int i, unsigned int numberOfPieces, const RegionType& region)
+{
+  RegionType splitRegion;
+  IndexType  splitIndex;
+
+  // Compute the actual number of splits
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < ImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  if (i >= numPieces)
+    {
+    itkExceptionMacro("Requested split number " << i << " but region contains only " << numPieces << " splits");
+    }
+
+  // Compute the split index in the streaming grid
+  splitIndex[1] = i / m_SplitsPerDimension[0];
+  splitIndex[0] = i % m_SplitsPerDimension[0];
+
+  // Transform the split index to the actual coordinates
+  splitRegion.SetIndex(0, region.GetIndex(0) + m_TileDimension * splitIndex[0]);
+  splitRegion.SetIndex(1, region.GetIndex(1) + m_TileSizeAlignment * splitIndex[1]);
+
+  splitRegion.SetSize(0, m_TileDimension);
+  splitRegion.SetSize(1, 1);
+
+  // Handle the borders
+  splitRegion.Crop(region);
+
+  return splitRegion;
+}
+
+void
+StreamingShrinkImageRegionSplitter
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "SplitsPerDimension : " << m_SplitsPerDimension << std::endl;
+  os << indent << "TileDimension      : " << m_TileDimension << std::endl;
+  os << indent << "TileSizeAlignment  : " << m_TileSizeAlignment << std::endl;
+}
+
+} // End namespace otb
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.h b/Code/BasicFilters/otbStreamingShrinkImageFilter.h
index c077557e021e7e242895479b509ad395c5efa305..b6b3e9eabc91da4b5c32fc56b3e5d7b8f29e407b 100644
--- a/Code/BasicFilters/otbStreamingShrinkImageFilter.h
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.h
@@ -25,11 +25,134 @@
 #include "otbPersistentImageFilter.h"
 #include "otbPersistentFilterStreamingDecorator.h"
 
-#include "itkTimeProbe.h"
+#include "otbStreamingManager.h"
 
 namespace otb
 {
 
+class ITK_EXPORT StreamingShrinkImageRegionSplitter : public itk::ImageRegionSplitter<2>
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingShrinkImageRegionSplitter        Self;
+  typedef itk::ImageRegionSplitter<2>               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(StreamingShrinkImageRegionSplitter, itk::Object);
+
+  /** Dimension of the image available at compile time. */
+  itkStaticConstMacro(ImageDimension, unsigned int, 2);
+
+  /** Dimension of the image available at run time. */
+  static unsigned int GetImageDimension()
+  {
+    return ImageDimension;
+  }
+
+  /** Index typedef support. An index is used to access pixel values. */
+  typedef itk::Index<ImageDimension>         IndexType;
+  typedef IndexType::IndexValueType IndexValueType;
+
+  /** Size typedef support. A size is used to define region bounds. */
+  typedef itk::Size<ImageDimension>        SizeType;
+  typedef SizeType::SizeValueType SizeValueType;
+
+  /** Region typedef support.   */
+  typedef itk::ImageRegion<ImageDimension> RegionType;
+
+  /** How many pieces can the specified region be split? A given region
+   *  cannot always be divided into the requested number of pieces.  For
+   *  instance, if the numberOfPieces exceeds the number of pixels along
+   *  a certain dimensions, then some splits will not be possible.
+   */
+  virtual unsigned int GetNumberOfSplits(const RegionType& region,
+                                         unsigned int requestedNumber);
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" specified should be less than or equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i, unsigned int numberOfPieces,
+                              const RegionType& region);
+
+  itkGetMacro(TileSizeAlignment, unsigned int);
+  itkSetMacro(TileSizeAlignment, unsigned int);
+
+  itkGetMacro(TileDimension, unsigned int);
+
+  itkSetMacro(ShrinkFactor, unsigned int);
+  itkGetMacro(ShrinkFactor, unsigned int);
+
+protected:
+  StreamingShrinkImageRegionSplitter() : m_SplitsPerDimension(0U), m_ShrinkFactor(10) {}
+  virtual ~StreamingShrinkImageRegionSplitter() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  StreamingShrinkImageRegionSplitter(const StreamingShrinkImageRegionSplitter &); //purposely not implemented
+  void operator =(const StreamingShrinkImageRegionSplitter&); //purposely not implemented
+
+  itk::FixedArray<unsigned int, ImageDimension> m_SplitsPerDimension;
+  unsigned int m_TileDimension;
+  unsigned int m_TileSizeAlignment;
+  unsigned int m_ShrinkFactor;
+};
+
+
+template <class TInputImage>
+class ITK_EXPORT StreamingShrinkStreamingManager : public StreamingManager<TInputImage>
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingShrinkStreamingManager Self;
+  typedef StreamingManager<TInputImage>   Superclass;
+  typedef itk::SmartPointer<Self>         Pointer;
+  typedef itk::SmartPointer<const Self>   ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Runtime information support. */
+  itkTypeMacro(StreamingShrinkStreamingManager, StreamingManager);
+
+  typedef TInputImage                            ImageType;
+  typedef typename ImageType::Pointer            ImagePointerType;
+  typedef typename ImageType::RegionType         RegionType;
+  typedef typename RegionType::IndexType         IndexType;
+  typedef typename RegionType::SizeType          SizeType;
+  typedef typename ImageType::InternalPixelType  PixelType;
+
+  itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension);
+
+  /** Actually computes the stream divisions, according to the specified streaming mode,
+   * eventually using the input parameter to estimate memory consumption */
+  virtual void PrepareStreaming(itk::DataObject * input, const RegionType &region);
+
+  void SetShrinkFactor(unsigned int val)
+  {
+    m_ShrinkFactor = val;
+  }
+
+  unsigned int GetShrinkFactor() const
+  {
+    return m_ShrinkFactor;
+  }
+
+protected:
+  StreamingShrinkStreamingManager();
+  virtual ~StreamingShrinkStreamingManager();
+
+private:
+  StreamingShrinkStreamingManager(const StreamingShrinkStreamingManager &); //purposely not implemented
+  void operator =(const StreamingShrinkStreamingManager&); //purposely not implemented
+
+  unsigned int m_ShrinkFactor;
+};
+
 
 /** \class PersistentShrinkImageFilter
  * \brief
@@ -116,9 +239,6 @@ private:
 
   /** The shrink factor */
   unsigned int m_ShrinkFactor;
-
-  itk::TimeProbe m_Chrono;
-
 }; // end of class PersistentStatisticsVectorImageFilter
 
 
@@ -156,10 +276,14 @@ public:
   typedef TOutputImage                                OutputImageType;
   typedef typename Superclass::FilterType             PersistentFilterType;
 
+  typedef StreamingShrinkStreamingManager<InputImageType>       StreamingShrinkStreamingManagerType;
+  typedef typename StreamingShrinkStreamingManagerType::Pointer StreamingShrinkStreamingManagerPointerType;
+
   void SetInput(InputImageType * input)
   {
     this->GetFilter()->SetInput(input);
   }
+
   const InputImageType * GetInput()
   {
     return this->GetFilter()->GetInput();
@@ -173,15 +297,29 @@ public:
   otbSetObjectMemberMacro(Filter, ShrinkFactor, unsigned int);
   otbGetObjectMemberMacro(Filter, ShrinkFactor, unsigned int);
 
+  virtual void Update(void)
+  {
+    m_StreamingManager->SetShrinkFactor( this->GetFilter()->GetShrinkFactor() );
+    Superclass::Update();
+  }
+
 protected:
   /** Constructor */
-  StreamingShrinkImageFilter() {}
+  StreamingShrinkImageFilter()
+  {
+    // Use a specific StreamingManager implementation
+    m_StreamingManager = StreamingShrinkStreamingManagerType::New();
+    this->GetStreamer()->SetStreamingManager( m_StreamingManager );
+  }
+
   /** Destructor */
   virtual ~StreamingShrinkImageFilter() {}
 
 private:
   StreamingShrinkImageFilter(const Self &); //purposely not implemented
   void operator =(const Self&); //purposely not implemented
+
+  StreamingShrinkStreamingManagerPointerType m_StreamingManager;
 };
 
 } // End namespace otb
diff --git a/Code/BasicFilters/otbStreamingShrinkImageFilter.txx b/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
index 4c7a810c1bf1d2ea5026ed9822ccd697cae73ca0..cd045e31f27cf8c625ed7bb97dda07de7a163956 100644
--- a/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
+++ b/Code/BasicFilters/otbStreamingShrinkImageFilter.txx
@@ -26,6 +26,34 @@
 namespace otb
 {
 
+template <class TImage>
+StreamingShrinkStreamingManager<TImage>::StreamingShrinkStreamingManager()
+{
+}
+
+template <class TImage>
+StreamingShrinkStreamingManager<TImage>::~StreamingShrinkStreamingManager()
+{
+}
+
+template <class TImage>
+void
+StreamingShrinkStreamingManager<TImage>::PrepareStreaming( itk::DataObject * input, const RegionType &region )
+{
+  typedef otb::StreamingShrinkImageRegionSplitter TileSplitterType;
+  TileSplitterType::Pointer splitter = TileSplitterType::New();
+  splitter->SetTileSizeAlignment(m_ShrinkFactor);
+  this->m_Splitter = splitter;
+
+  unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+  this->m_ComputedNumberOfSplits = this->m_Splitter->GetNumberOfSplits(region, nbDivisions);
+  otbMsgDevMacro(<< "Number of split : " << this->m_ComputedNumberOfSplits)
+
+  // Save the region to generate the splits later
+  this->m_Region = region;
+}
+
+
 /** Constructor */
 template <class TInputImage, class TOutputImage>
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
@@ -79,31 +107,22 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
   // Nothing that needs to be allocated for the remaining outputs
 }
 
+
 template<class TInputImage, class TOutputImage>
 void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::Reset()
 {
-  // Reinit the chrono
-  m_Chrono = itk::TimeProbe();
-
-  // get pointers to the input and output
+  // Get pointers to the input and output
   InputImageType* inputPtr = const_cast<InputImageType*>(this->GetInput());
   inputPtr->UpdateOutputInformation();
 
   m_ShrinkedOutput = OutputImageType::New();
 
-  // we need to compute the output spacing, the output image size, and the
-  // output image start index
   const typename InputImageType::SpacingType&
                                            inputSpacing = inputPtr->GetSpacing();
   const typename InputImageType::SizeType& inputSize
     = inputPtr->GetLargestPossibleRegion().GetSize();
-  const typename InputImageType::IndexType& inputStartIndex
-    = inputPtr->GetLargestPossibleRegion().GetIndex();
-  
-  otbMsgDebugMacro(<< "Input index " << inputStartIndex);
-  otbMsgDebugMacro(<< "Input size: " << inputSize);
 
   typename OutputImageType::SpacingType shrinkedOutputSpacing;
   typename OutputImageType::RegionType  shrinkedOutputLargestPossibleRegion;
@@ -113,9 +132,7 @@ PersistentShrinkImageFilter<TInputImage, TOutputImage>
   for (unsigned int i = 0; i < OutputImageType::ImageDimension; ++i)
     {
     shrinkedOutputSpacing[i] = inputSpacing[i] * static_cast<double>(m_ShrinkFactor);
-    //shrinkedOutputSize[i] = static_cast<int>(static_cast<double>(inputSize[i]) / static_cast<double>(m_ShrinkFactor));
     shrinkedOutputSize[i] = inputSize[i] / m_ShrinkFactor;
-    //outputStartIndex[i] = inputStartIndex[i];
     shrinkedOutputStartIndex[i] = 0;
     }
 
@@ -134,7 +151,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::Synthetize()
 {
-  otbMsgDevMacro( "Shrink time : " << m_Chrono.GetTotal() )
 }
 
 template<class TInputImage, class TOutputImage>
@@ -142,7 +158,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::BeforeThreadedGenerateData()
 {
-  m_Chrono.Start();
 }
 
 template<class TInputImage, class TOutputImage>
@@ -175,7 +190,6 @@ void
 PersistentShrinkImageFilter<TInputImage, TOutputImage>
 ::AfterThreadedGenerateData()
 {
-  m_Chrono.Stop();
 }
 
 template <class TImage, class TOutputImage>
diff --git a/Code/Common/otbFilterWatcherBase.cxx b/Code/Common/otbFilterWatcherBase.cxx
index 2e47d89fc3ba3fc19c98f3368af84b29b705ac8d..742eb90d370ac5ece85d2ae495e7a9e3a5bf48ca 100644
--- a/Code/Common/otbFilterWatcherBase.cxx
+++ b/Code/Common/otbFilterWatcherBase.cxx
@@ -46,11 +46,11 @@ FilterWatcherBase
 
   // Assign the callbacks
   m_StartFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::StartFilter);
+                                            &FilterWatcherBase::StartFilterCallback);
   m_EndFilterCommand->SetCallbackFunction(this,
-                                          &FilterWatcherBase::EndFilter);
+                                          &FilterWatcherBase::EndFilterCallback);
   m_ProgressFilterCommand->SetCallbackFunction(this,
-                                               &FilterWatcherBase::ShowProgress);
+                                               &FilterWatcherBase::ShowProgressCallback);
 
   // Add the commands as observers
   m_StartTag = m_Process->AddObserver(itk::StartEvent(),
@@ -90,11 +90,11 @@ FilterWatcherBase
 
     // Assign the callbacks
     m_StartFilterCommand->SetCallbackFunction(this,
-                                              &FilterWatcherBase::StartFilter);
+                                              &FilterWatcherBase::StartFilterCallback);
     m_EndFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::EndFilter);
+                                            &FilterWatcherBase::EndFilterCallback);
     m_ProgressFilterCommand->SetCallbackFunction(this,
-                                                 &FilterWatcherBase::ShowProgress);
+                                                 &FilterWatcherBase::ShowProgressCallback);
 
     // Add the commands as observers
     m_StartTag = m_Process->AddObserver(itk::StartEvent(), m_StartFilterCommand);
@@ -132,11 +132,11 @@ FilterWatcherBase
 
     // Assign the callbacks
     m_StartFilterCommand->SetCallbackFunction(this,
-                                              &FilterWatcherBase::StartFilter);
+                                              &FilterWatcherBase::StartFilterCallback);
     m_EndFilterCommand->SetCallbackFunction(this,
-                                            &FilterWatcherBase::EndFilter);
+                                            &FilterWatcherBase::EndFilterCallback);
     m_ProgressFilterCommand->SetCallbackFunction(this,
-                                                 &FilterWatcherBase::ShowProgress);
+                                                 &FilterWatcherBase::ShowProgressCallback);
 
     // Add the commands as observers
     m_StartTag = m_Process->AddObserver(itk::StartEvent(), m_StartFilterCommand);
diff --git a/Code/Common/otbFilterWatcherBase.h b/Code/Common/otbFilterWatcherBase.h
index 9e64c176323186f99f421e1e8bc31933df6fbf41..ef739e490c713ab76d91a39705275a4fbd4711ae 100644
--- a/Code/Common/otbFilterWatcherBase.h
+++ b/Code/Common/otbFilterWatcherBase.h
@@ -85,6 +85,24 @@ public:
 
 protected:
 
+  /** Callback method to show the ProgressEvent */
+  virtual void ShowProgressCallback()
+  {
+    this->ShowProgress();
+  }
+
+  /** Callback method to show the StartEvent */
+  virtual void StartFilterCallback()
+  {
+    this->StartFilter();
+  }
+
+  /** Callback method to show the EndEvent */
+  virtual void EndFilterCallback()
+  {
+    this->EndFilter();
+  }
+
   /** Callback method to show the ProgressEvent */
   virtual void ShowProgress() = 0;
 
diff --git a/Code/Common/otbImageRegionSquareTileSplitter.h b/Code/Common/otbImageRegionSquareTileSplitter.h
new file mode 100644
index 0000000000000000000000000000000000000000..10dd5b71e45436d6640a2e1f401d2a46d0ca59ed
--- /dev/null
+++ b/Code/Common/otbImageRegionSquareTileSplitter.h
@@ -0,0 +1,146 @@
+/*=========================================================================
+
+  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 __otbImageRegionSquareTileSplitter_h
+#define __otbImageRegionSquareTileSplitter_h
+
+#include "itkObject.h"
+#include "itkRegion.h"
+#include "itkImageRegion.h"
+#include "itkImageRegionSplitter.h"
+#include "itkObjectFactory.h"
+#include "itkIndex.h"
+#include "itkSize.h"
+
+namespace otb
+{
+
+/** \class ImageRegionSquareTileSplitter
+   * \brief Divide a region into several pieces.
+   *
+   * ImageRegionSquareTileSplitter divides an ImageRegion into smaller regions.
+   * ImageRegionSquareTileSplitter is used by the StreamingImageFilter to divide a
+   * requested output region into a series of smaller requests of the
+   * pipeline.  This object has two basic methods: GetNumberOfSplits()
+   * and GetSplit().
+   *
+   * GetNumberOfSplits() is used to determine how may subregions a given
+   * region can be divided.  You call GetNumberOfSplits with an argument
+   * that is the number of subregions you want.  If the image region can
+   * support that number of subregions, that number is returned.
+   * Otherwise, the maximum number of splits a region can support will
+   * be returned.  For example, if a region splitter class only divides
+   * a region into horizontal slabs, then the maximum number of splits
+   * will be the number of rows in the region.
+   *
+   * GetSplit() returns the ith of N subregions (as an ImageRegion object).
+   *
+   * This ImageRegionSquareTileSplitter class divides a region along the outermost
+   * dimension. If the outermost dimension has size 1 (i.e. a volume
+   * with a single slice), the ImageRegionSquareTileSplitter will divide the
+   * region along the next outermost dimension. If that dimension has size 1,
+   * the process continues with the next outermost dimension.
+   *
+   * Regions obtained by the ImageRegionSquareTileSplitter are aligned on a grid
+   * with width of 256. Divisions can occur only at line defined as k*256.
+   *
+   * Other ImageRegionSquareTileSplitter subclasses could divide an image into
+   * more uniform shaped regions instead of slabs.
+   *
+   * \sa ImageRegionMultidimensionalSplitter
+   *
+   * \ingroup ITKSystemObjects
+   * \ingroup DataProcessing
+ */
+
+template <unsigned int VImageDimension>
+class ITK_EXPORT ImageRegionSquareTileSplitter : public itk::ImageRegionSplitter<VImageDimension>
+{
+public:
+  /** Standard class typedefs. */
+  typedef ImageRegionSquareTileSplitter                Self;
+  typedef itk::ImageRegionSplitter<VImageDimension> 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(ImageRegionSquareTileSplitter, itk::Object);
+
+  /** Dimension of the image available at compile time. */
+  itkStaticConstMacro(ImageDimension, unsigned int, VImageDimension);
+
+  /** Dimension of the image available at run time. */
+  static unsigned int GetImageDimension()
+  {
+    return VImageDimension;
+  }
+
+  /** Index typedef support. An index is used to access pixel values. */
+  typedef itk::Index<VImageDimension>        IndexType;
+  typedef typename IndexType::IndexValueType IndexValueType;
+
+  /** Size typedef support. A size is used to define region bounds. */
+  typedef itk::Size<VImageDimension>       SizeType;
+  typedef typename SizeType::SizeValueType SizeValueType;
+
+  /** Region typedef support.   */
+  typedef itk::ImageRegion<VImageDimension> RegionType;
+
+  /** How many pieces can the specified region be split? A given region
+   *  cannot always be divided into the requested number of pieces.  For
+   *  instance, if the numberOfPieces exceeds the number of pixels along
+   *  a certain dimensions, then some splits will not be possible.
+   */
+  virtual unsigned int GetNumberOfSplits(const RegionType& region,
+                                         unsigned int requestedNumber);
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" specified should be less than or equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i, unsigned int numberOfPieces,
+                              const RegionType& region);
+
+  itkGetMacro(TileSizeAlignment, unsigned int);
+  itkSetMacro(TileSizeAlignment, unsigned int);
+
+  itkGetMacro(TileDimension, unsigned int);
+
+protected:
+  ImageRegionSquareTileSplitter() : m_SplitsPerDimension(0U), m_TileDimension(0), m_TileSizeAlignment(16) {}
+  virtual ~ImageRegionSquareTileSplitter() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  ImageRegionSquareTileSplitter(const ImageRegionSquareTileSplitter &); //purposely not implemented
+  void operator =(const ImageRegionSquareTileSplitter&); //purposely not implemented
+
+  itk::FixedArray<unsigned int, VImageDimension> m_SplitsPerDimension;
+  unsigned int m_TileDimension;
+  unsigned int m_TileSizeAlignment;
+};
+
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+# include "otbImageRegionSquareTileSplitter.txx"
+#endif
+
+#endif
diff --git a/Code/Common/otbImageRegionSquareTileSplitter.txx b/Code/Common/otbImageRegionSquareTileSplitter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..6870b8dd034b2cef25ba00ab21b28721a2aa40bd
--- /dev/null
+++ b/Code/Common/otbImageRegionSquareTileSplitter.txx
@@ -0,0 +1,120 @@
+/*=========================================================================
+
+  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 __otbImageRegionSquareTileSplitter_txx
+#define __otbImageRegionSquareTileSplitter_txx
+
+#include "otbImageRegionSquareTileSplitter.h"
+#include "otbMath.h"
+#include "otbMacro.h"
+
+namespace otb
+{
+
+template <unsigned int VImageDimension>
+unsigned int
+ImageRegionSquareTileSplitter<VImageDimension>
+::GetNumberOfSplits(const RegionType& region, unsigned int requestedNumber)
+{
+  unsigned int theoricalNbPixelPerTile = region.GetNumberOfPixels() / requestedNumber;
+  unsigned int theoricalTileDimension = static_cast<unsigned int> (vcl_sqrt(static_cast<double>(theoricalNbPixelPerTile)) );
+
+  // Take the previous multiple of m_TileSizeAlignment (eventually generate more splits than requested)
+  m_TileDimension = theoricalTileDimension / m_TileSizeAlignment * m_TileSizeAlignment;
+
+  // Minimal tile size is m_TileSizeAlignment * m_TileSizeAlignment
+  if (m_TileDimension < m_TileSizeAlignment)
+    {
+    otbMsgDevMacro(<< "Warning: clamping tile size to " << m_TileSizeAlignment << " * " << m_TileSizeAlignment);
+    m_TileDimension = m_TileSizeAlignment;
+    }
+
+  unsigned int numPieces = 1;
+  const SizeType&  regionSize = region.GetSize();
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    m_SplitsPerDimension[j] = (regionSize[j] + m_TileDimension - 1) / m_TileDimension;
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  otbMsgDevMacro(<< "Tile dimension : " << m_TileDimension)
+  otbMsgDevMacro(<< "Number of splits per dimension : " << m_SplitsPerDimension[0] << " " <<  m_SplitsPerDimension[1])
+
+  return numPieces;
+}
+
+template <unsigned int VImageDimension>
+itk::ImageRegion<VImageDimension>
+ImageRegionSquareTileSplitter<VImageDimension>
+::GetSplit(unsigned int i, unsigned int itkNotUsed(numberOfPieces), const RegionType& region)
+{
+  RegionType splitRegion;
+  IndexType  splitIndex;
+
+  // Compute the actual number of splits
+  unsigned int numPieces = 1;
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    numPieces *= m_SplitsPerDimension[j];
+    }
+
+  // Sanity check
+  if (i >= numPieces)
+    {
+    itkExceptionMacro("Asked for split number " << i << " but region contains only " << numPieces << " splits");
+    }
+
+  // Compute the split index in the streaming grid
+  unsigned int remaining = i;
+  for (unsigned int j = VImageDimension - 1; j > 0; --j)
+    {
+    splitIndex[j] = remaining / m_SplitsPerDimension[VImageDimension - 1 - j];
+    remaining = remaining % m_SplitsPerDimension[VImageDimension - 1 - j];
+    }
+  splitIndex[0] = remaining;
+
+  // Transform the split index to the actual coordinates
+  for (unsigned int j = 0; j < VImageDimension; ++j)
+    {
+    splitRegion.SetIndex(j, region.GetIndex(j) + m_TileDimension * splitIndex[j]);
+    splitRegion.SetSize(j, m_TileDimension);
+    }
+
+  // Handle the borders
+  splitRegion.Crop(region);
+
+  return splitRegion;
+}
+
+/**
+ *
+ */
+template <unsigned int VImageDimension>
+void
+ImageRegionSquareTileSplitter<VImageDimension>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+  os << indent << "SplitsPerDimension : " << m_SplitsPerDimension << std::endl;
+  os << indent << "TileDimension      : " << m_TileDimension << std::endl;
+  os << indent << "TileSizeAlignment  : " << m_TileSizeAlignment << std::endl;
+
+}
+
+} // end namespace itk
+
+#endif
diff --git a/Code/Common/otbPersistentImageFilter.h b/Code/Common/otbPersistentImageFilter.h
index ccea263130c7e5727c5757df6b5802dc8fc1a4b1..87d78f2202c5f16572dae4d689f5bc005c0e4ce6 100644
--- a/Code/Common/otbPersistentImageFilter.h
+++ b/Code/Common/otbPersistentImageFilter.h
@@ -66,7 +66,7 @@ public:
 
 protected:
   /** Constructor */
-  PersistentImageFilter() {};
+  PersistentImageFilter() {}
   /** Destructor */
   virtual ~PersistentImageFilter() {}
   /**PrintSelf method */
diff --git a/Code/Common/otbPipelineMemoryPrintCalculator.cxx b/Code/Common/otbPipelineMemoryPrintCalculator.cxx
index 397ba8b1126fbb30d860dccc6d5d8967c3cf5e6c..b8dff8c995087bc77f8d936ed71e8a3c18ad58d7 100644
--- a/Code/Common/otbPipelineMemoryPrintCalculator.cxx
+++ b/Code/Common/otbPipelineMemoryPrintCalculator.cxx
@@ -61,7 +61,7 @@ void
 PipelineMemoryPrintCalculator
 ::Compute()
 {
-  // Clear the visisted process objects set
+  // Clear the visited process objects set
   m_VisitedProcessObjects.clear();
 
   // Dry run of pipeline synchronisation
@@ -96,6 +96,7 @@ PipelineMemoryPrintCalculator::MemoryPrintType
 PipelineMemoryPrintCalculator
 ::EvaluateMemoryPrint(ProcessObjectType * process)
 {
+  otbMsgDevMacro(<< "EvaluateMemoryPrint for " << process->GetNameOfClass() << " (" << process << ")")
   // This variable will store the final print
   MemoryPrintType print = 0;
 
@@ -150,6 +151,7 @@ PipelineMemoryPrintCalculator::MemoryPrintType
 PipelineMemoryPrintCalculator
 ::EvaluateDataObjectPrint(DataObjectType * data) const
 {
+  otbMsgDevMacro(<< "EvaluateMemoryPrint for " << data->GetNameOfClass() << " (" << data << ")")
 
 #define OTB_IMAGE_SIZE_BLOCK(type)                                      \
   if(dynamic_cast<itk::Image<type, 2> *>(data) != NULL)                  \
diff --git a/Code/Common/otbStandardFilterWatcher.cxx b/Code/Common/otbStandardFilterWatcher.cxx
index 1fd3e7d4dc90205145af320af5f45e75f5238914..ce47e316a5e22818ab789ac98a6a59c4994f788e 100644
--- a/Code/Common/otbStandardFilterWatcher.cxx
+++ b/Code/Common/otbStandardFilterWatcher.cxx
@@ -29,6 +29,7 @@ StandardFilterWatcher
   : FilterWatcherBase(process, comment)
 {
   m_StarsCount = 50;
+  m_CurrentNbStars = -1;
 }
 
 StandardFilterWatcher
@@ -80,9 +81,14 @@ StandardFilterWatcher
       progressPercent = 100;
       }
 
-    std::string stars(nbStars, '*');
-    std::string blanks(nbBlanks, ' ');
-    std::cout << "\rProcessing progress: " << progressPercent << "% [" << stars << blanks << "]" << std::flush;
+    if (nbStars > m_CurrentNbStars)
+      {
+      std::string stars(nbStars, '*');
+      std::string blanks(nbBlanks, ' ');
+      std::cout << "\rProcessing progress: " << progressPercent << "% [" << stars << blanks << "]" << std::flush;
+      }
+
+    m_CurrentNbStars = nbStars;
     }
 }
 
diff --git a/Code/Common/otbStandardFilterWatcher.h b/Code/Common/otbStandardFilterWatcher.h
index 1f3cbe6e91d41608d74108a307b628b6e6f3198c..5e4fd7f69037855a477e3e2c9b89a0605bf2bc07 100644
--- a/Code/Common/otbStandardFilterWatcher.h
+++ b/Code/Common/otbStandardFilterWatcher.h
@@ -92,6 +92,8 @@ private:
 
   /** Stars coutning */
   int m_StarsCount;
+
+  int m_CurrentNbStars;
 };
 
 } // end namespace otb
diff --git a/Code/Common/otbStreamingManager.h b/Code/Common/otbStreamingManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d5d81b43aca507d7c8b05df9fb7ba93dc099047
--- /dev/null
+++ b/Code/Common/otbStreamingManager.h
@@ -0,0 +1,196 @@
+/*=========================================================================
+
+  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 __otbStreamingManager_h
+#define __otbStreamingManager_h
+
+#include "otbMacro.h"
+#include "otbConfigure.h"
+
+#include "itkLightObject.h"
+#include "itkImageRegionSplitter.h"
+
+namespace otb
+{
+
+namespace StreamingManagement
+{
+  enum StreamingMode
+  {
+    /** Estimates the memory used by the pipeline
+     * and set the strips size to fit the specified
+     * available RAM
+     */
+    STRIPPED_AVAILABLE_RAM,
+
+    /** Force the use of a specific number of lines per strips
+     */
+    STRIPPED_SET_NUMBEROFLINES,
+
+    /** Estimates the memory used that will be used during the pipeline
+     * execution and set the tile size to fit the specified
+     * available RAM.
+     */
+    TILED_AVAILABLE_RAM,
+
+    /** Force the use of a specific tile dimension
+     * The associated parameter is the size used in each dimension
+     */
+    TILED_SET_TILE_SIZE,
+  };
+}
+
+/** \class StreamingManager
+ *  \brief This class handles the streaming process used in the writers implementation
+ *
+ *  The streaming mode can be chosen with either SetStrippedRAMStreamingMode, SetStrippedNumberOfLinesStreamingMode,
+ *  SetTiledRAMStreamingMode, or SetTiledTileDimensionStreamingMode.
+ *
+ *  Then, PrepareStreaming must be called so that the stream type and dimensions are computed
+ *  This involves passing the actual DataObject who will be written, since it will be used
+ *  during memory estimation for some specific streaming modes.
+ *
+ *  After PrepareStreaming has been called, the actual number of splits and streaming mode which will be used
+ *  can be retrieved with GetStreamingMode and GetNumberOfSplits.
+ *  The different splits can be retrieved with GetSplit
+ *
+ * \sa StreamingImageFileWriter
+ * \sa StreamingImageVirtualFileWriter
+ */
+template<class TImage>
+class ITK_EXPORT StreamingManager : public itk::LightObject
+{
+public:
+  /** Standard class typedefs. */
+  typedef StreamingManager               Self;
+  typedef itk::LightObject               Superclass;
+  typedef itk::SmartPointer<Self>        Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+
+  typedef TImage                                 ImageType;
+  typedef typename ImageType::Pointer            ImagePointerType;
+  typedef typename ImageType::RegionType         RegionType;
+  typedef typename RegionType::IndexType         IndexType;
+  typedef typename RegionType::SizeType          SizeType;
+  typedef typename ImageType::InternalPixelType  PixelType;
+
+  typedef StreamingManagement::StreamingMode     StreamingModeType;
+
+  /** Creation through object factory macro */
+  itkNewMacro(Self);
+
+  /** Type macro */
+  itkTypeMacro(StreamingManager, itk::LightObject);
+
+  /** Dimension of input image. */
+  itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+
+  /** Use stripped mode.
+   * The number of lines of the strips are computed by estimating the
+   * memory footprint of the pipeline, and chosen so that no more than
+   * availableRAM MBytes of memory are used.
+   * If no parameter is given, then the available RAM is retrieved from the
+   * OTB configuration file or build configuration option */
+  virtual void SetStrippedRAMStreamingMode( unsigned int availableRAMInMB = 0 );
+
+  /** Use stripped mode.
+   * The number of lines of the strips are explicitely specified */
+  virtual void SetStrippedNumberOfLinesStreamingMode( unsigned int numberOfLines );
+
+  /** Use tiled mode.
+   * The dimensions of the tiles are computed by estimating the
+   * memory footprint of the pipeline, and chosen so that no more than
+   * availableRAM MBytes of memory are used.
+   *
+   * If no parameter is given, then the available RAM is retrieved from the
+   * OTB configuration file or build configuration option.
+   *
+   * The tiles are set to be square, with dimension aligned with multiple of 16 */
+  virtual void SetTiledRAMStreamingMode( unsigned int availableRAMInMB = 0 );
+
+  /** Use tiled mode.
+   * The dimension of the tile are explicitely specified.
+   * The parameter specifies the size of the tile in each dimension.  */
+  virtual void SetTiledTileDimensionStreamingMode( unsigned int tileDimension );
+
+  /** Actually computes the stream divisions, accorfing to the specified streaming mode,
+   * eventually using the input parameter to estimate memory consumption */
+  virtual void PrepareStreaming(itk::DataObject * input, const RegionType &region);
+
+  /** Returns the actual streaming mode that will be used to process the image.
+   * PrepareStreaming() must have been called before.
+   * This can be different than the required streaming mode. For example, if
+   * the input passed to PrepareStreaming() is fully buffered, then
+   * the STRIPPED_SET_NUMBEROFLINES mode is used with only one strip */
+  virtual StreamingManagement::StreamingMode GetStreamingMode();
+
+  /** Returns the actual number of pieces that will be used to process the image.
+   * PrepareStreaming() must have been called before.
+   * This can be different than the requested number */
+  virtual unsigned int GetNumberOfSplits();
+
+  /** Get a region definition that represents the ith piece a specified region.
+   * The "numberOfPieces" must be equal to what
+   * GetNumberOfSplits() returns. */
+  virtual RegionType GetSplit(unsigned int i);
+
+
+public:
+  StreamingManager();
+  virtual ~StreamingManager();
+
+  virtual unsigned int EstimateOptimalNumberOfDivisions(itk::DataObject * input, const RegionType &region);
+
+  /** The desired streaming mode specified by the user */
+  StreamingManagement::StreamingMode m_DesiredMode;
+
+  /** The actual streaming mode which will be used */
+  StreamingManagement::StreamingMode m_ActualMode;
+
+  /** The available RAM set as parameter when using the STRIPPED_AVAILABLE_RAM or TILED_AVAILABLE_RAM mode */
+  unsigned int m_AvailableRAMInMB;
+
+  /** The desired number of lines when using the STRIPPED_SET_NUMBEROFLINES streaming mode */
+  unsigned int m_DesiredNumberOfLines;
+
+  /** The desired tile dimension when using the TILED_SET_TILE_SIZE streaming mode */
+  unsigned int m_DesiredTileDimension;
+
+  /** The computed number of splits after PrepareStreaming has been called */
+  unsigned int m_ComputedNumberOfSplits;
+
+  /** The region to stream */
+  RegionType m_Region;
+
+  /** The splitter used to compute the different strips */
+  typedef itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)> AbstractSplitterType;
+  typedef typename AbstractSplitterType::Pointer AbstractSplitterPointerType;
+  AbstractSplitterPointerType m_Splitter;
+
+private:
+  StreamingManager(const StreamingManager &); //purposely not implemented
+  void operator =(const StreamingManager&); //purposely not implemented
+
+};
+
+} // End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbStreamingManager.txx"
+#endif
+
+#endif
diff --git a/Code/Common/otbStreamingManager.txx b/Code/Common/otbStreamingManager.txx
new file mode 100644
index 0000000000000000000000000000000000000000..86d5929ff1cc066ec5ea7dd3514b4e30db9769cc
--- /dev/null
+++ b/Code/Common/otbStreamingManager.txx
@@ -0,0 +1,298 @@
+/*=========================================================================
+
+  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 __otbStreamingManager_txx
+#define __otbStreamingManager_txx
+
+#include "otbStreamingManager.h"
+#include "otbMacro.h"
+#include "otbConfigure.h"
+#include "otbConfigurationFile.h"
+#include "otbPipelineMemoryPrintCalculator.h"
+#include "itkExtractImageFilter.h"
+
+#include "otbImageRegionSquareTileSplitter.h"
+#include "itkImageRegionSplitter.h"
+
+namespace otb
+{
+
+template <class TImage>
+StreamingManager<TImage>::StreamingManager()
+  : m_DesiredMode(StreamingManagement::TILED_AVAILABLE_RAM),
+    m_ActualMode(StreamingManagement::TILED_AVAILABLE_RAM),
+    m_AvailableRAMInMB(0),
+    m_DesiredNumberOfLines(0),
+    m_DesiredTileDimension(0),
+    m_ComputedNumberOfSplits(0)
+{
+}
+
+template <class TImage>
+StreamingManager<TImage>::~StreamingManager()
+{
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetStrippedRAMStreamingMode( unsigned int availableRAMInMB )
+{
+  m_DesiredMode = StreamingManagement::STRIPPED_AVAILABLE_RAM;
+  m_AvailableRAMInMB = availableRAMInMB;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetStrippedNumberOfLinesStreamingMode( unsigned int numberOfLines )
+{
+  m_DesiredMode = StreamingManagement::STRIPPED_SET_NUMBEROFLINES;
+  m_DesiredNumberOfLines = numberOfLines;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetTiledRAMStreamingMode( unsigned int availableRAMInMB )
+{
+  otbMsgDevMacro(<< "StreamingManager::SetTiledRAMStreamingMode " << availableRAMInMB)
+  m_DesiredMode = StreamingManagement::TILED_AVAILABLE_RAM;
+  m_AvailableRAMInMB = availableRAMInMB;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::SetTiledTileDimensionStreamingMode( unsigned int tileDimension )
+{
+  m_DesiredMode = StreamingManagement::TILED_SET_TILE_SIZE;
+  m_DesiredTileDimension = tileDimension;
+}
+
+template <class TImage>
+void
+StreamingManager<TImage>::PrepareStreaming( itk::DataObject * input, const RegionType &region )
+{
+  switch (m_DesiredMode)
+  {
+    case StreamingManagement::STRIPPED_AVAILABLE_RAM:
+      {
+      otbMsgDevMacro(<< "Activating STRIPPED_AVAILABLE_RAM streaming mode")
+      unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+      m_Splitter = itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDivisions);
+
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::STRIPPED_SET_NUMBEROFLINES:
+      {
+      otbMsgDevMacro(<< "Activating STRIPPED_SET_NUMBEROFLINES streaming mode")
+      if (m_DesiredNumberOfLines < 1)
+        {
+        itkWarningMacro(<< "DesiredNumberOfLines set to 0 : streaming disabled")
+        }
+
+      /* Calculate number of split */
+      unsigned long numberLinesOfRegion = region.GetSize()[1]; // Y dimension
+      unsigned long nbSplit;
+      if (numberLinesOfRegion > m_DesiredNumberOfLines && m_DesiredNumberOfLines > 0)
+        {
+        nbSplit =
+          static_cast<unsigned long>(vcl_ceil(static_cast<double>(numberLinesOfRegion) /
+                                              static_cast<double>(m_DesiredNumberOfLines)));
+        }
+      else
+        {
+        // Don't stream
+        nbSplit = 1;
+        }
+
+      m_Splitter = itk::ImageRegionSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbSplit);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::TILED_AVAILABLE_RAM:
+      {
+      otbMsgDevMacro(<< "Activating TILED_AVAILABLE_RAM streaming mode")
+      unsigned long nbDivisions = EstimateOptimalNumberOfDivisions(input, region);
+      m_Splitter = otb::ImageRegionSquareTileSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDivisions);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+
+    case StreamingManagement::TILED_SET_TILE_SIZE:
+      {
+      if (m_DesiredTileDimension  == 0)
+        {
+        itkWarningMacro(<< "DesiredTileDimension is 0 : switching to mode STRIPPED_SET_NUMBEROFLINES, disabling streaming")
+        this->SetStrippedNumberOfLinesStreamingMode(0);
+        this->PrepareStreaming(input, region);
+        break;
+        }
+
+      otbMsgDevMacro(<< "Activating TILED_SET_TILE_SIZE streaming mode")
+      if (m_DesiredTileDimension < 16)
+        {
+        itkWarningMacro(<< "DesiredTileDimension inferior to 16 : use 16 as tile dimension")
+        m_DesiredTileDimension = 16;
+        }
+
+      // Calculate number of split
+      m_Splitter = otb::ImageRegionSquareTileSplitter<itkGetStaticConstMacro(ImageDimension)>::New();
+      unsigned int nbDesiredTiles = itk::Math::Ceil<unsigned int>( double(region.GetNumberOfPixels()) / (m_DesiredTileDimension * m_DesiredTileDimension) );
+      m_ComputedNumberOfSplits = m_Splitter->GetNumberOfSplits(region, nbDesiredTiles);
+      otbMsgDevMacro(<< "Number of split : " << m_ComputedNumberOfSplits)
+      }
+      break;
+  }
+
+  // Save the region to generate the splits later
+  m_Region = region;
+}
+
+
+template <class TImage>
+unsigned int
+StreamingManager<TImage>::EstimateOptimalNumberOfDivisions(itk::DataObject * input, const RegionType &region)
+{
+  otbMsgDevMacro(<< "m_AvailableRAMInMB " << m_AvailableRAMInMB)
+  unsigned int availableRAMInBytes = m_AvailableRAMInMB * 1024 * 1024;
+
+  if (availableRAMInBytes == 0)
+    {
+    otbMsgDevMacro(<< "Retrieving available RAM size from configuration")
+    // Retrieve it from the configuration
+    try
+      {
+      typedef otb::ConfigurationFile ConfigurationType;
+      ConfigurationType::Pointer conf = ConfigurationType::GetInstance();
+
+      availableRAMInBytes = conf->GetParameter<unsigned int>(
+        "OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING");
+      }
+    catch(...)
+      {
+      // We should never have to go here if the configuration file is
+      // correct and found.
+      // In case it is not fallback on the cmake
+      // defined constants.
+      availableRAMInBytes = OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING;
+      }
+    }
+
+  otbMsgDevMacro("RAM used to estimate memory footprint : " << availableRAMInBytes / 1024 / 1024  << " MB")
+
+  otb::PipelineMemoryPrintCalculator::Pointer memoryPrintCalculator;
+  memoryPrintCalculator = otb::PipelineMemoryPrintCalculator::New();
+
+  memoryPrintCalculator->SetAvailableMemory( availableRAMInBytes );
+
+  // Trick to avoid having the resampler compute the whole
+  // deformation field
+  double regionTrickFactor = 1;
+  ImageType* inputImage = dynamic_cast<ImageType*>(input);
+  //inputImage = 0;
+  if (inputImage)
+    {
+
+    typedef itk::ExtractImageFilter<ImageType, ImageType> ExtractFilterType;
+    typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
+    extractFilter->SetInput(inputImage);
+
+    // Define a small region to run the memory footprint estimation,
+    // around the image center, 100 pixels wide in each dimension
+    SizeType smallSize;
+    smallSize.Fill(100);
+    IndexType index;
+    index[0] = region.GetIndex()[0] + region.GetSize()[0]/2 - 50;
+    index[1] = region.GetIndex()[1] + region.GetSize()[1]/2 - 50;
+
+    RegionType smallRegion;
+    smallRegion.SetSize(smallSize);
+    smallRegion.SetIndex(index);
+
+    // In case the image is smaller than 100 pixels in a direction
+    smallRegion.Crop(region);
+
+    extractFilter->SetExtractionRegion(smallRegion);
+
+    bool smallRegionSuccess = smallRegion.Crop(region);
+
+    if (smallRegionSuccess)
+      {
+      otbMsgDevMacro("Using an extract to estimate memory : " << smallRegion)
+      // the region is well behaved, inside the largest possible region
+      memoryPrintCalculator->SetDataToWrite(extractFilter->GetOutput());
+      regionTrickFactor = static_cast<double>( region.GetNumberOfPixels() )
+          / static_cast<double>(smallRegion.GetNumberOfPixels());
+
+      memoryPrintCalculator->SetBiasCorrectionFactor(regionTrickFactor);
+      }
+    else
+      {
+      otbMsgDevMacro("Using the input region to estimate memory : " << region)
+      // the region is not well behaved
+      // use the full region
+      memoryPrintCalculator->SetDataToWrite(input);
+      memoryPrintCalculator->SetBiasCorrectionFactor(1.0);
+      }
+
+    memoryPrintCalculator->Compute();
+    }
+  else
+    {
+    // Use the original object to estimate memory footprint
+    memoryPrintCalculator->SetDataToWrite(input);
+    memoryPrintCalculator->SetBiasCorrectionFactor(1.0);
+
+    memoryPrintCalculator->Compute();
+    }
+
+  otbMsgDevMacro( "Estimated Memory print for the full image : "
+                   << static_cast<unsigned int>(memoryPrintCalculator->GetMemoryPrint() / 1024 / 1024 ) << std::endl)
+  otbMsgDevMacro( "Optimal number of stream divisions: "
+                   << memoryPrintCalculator->GetOptimalNumberOfStreamDivisions() << std::endl)
+
+  return memoryPrintCalculator->GetOptimalNumberOfStreamDivisions();
+}
+
+template <class TImage>
+StreamingManagement::StreamingMode
+StreamingManager<TImage>::GetStreamingMode()
+{
+  return m_ActualMode;
+}
+
+template <class TImage>
+unsigned int
+StreamingManager<TImage>::GetNumberOfSplits()
+{
+  return m_ComputedNumberOfSplits;
+}
+
+template <class TImage>
+typename StreamingManager<TImage>::RegionType
+StreamingManager<TImage>::GetSplit(unsigned int i)
+{
+  return m_Splitter->GetSplit(i, m_ComputedNumberOfSplits, m_Region);
+}
+
+} // End namespace otb
+
+#endif
diff --git a/Code/Gui/otbFltkFilterWatcher.cxx b/Code/Gui/otbFltkFilterWatcher.cxx
index 65ef6e5452a735dac780f2733e76410593149bf7..8136428c449e14a816a93b49b6cf025d22edb686 100644
--- a/Code/Gui/otbFltkFilterWatcher.cxx
+++ b/Code/Gui/otbFltkFilterWatcher.cxx
@@ -27,7 +27,8 @@ FltkFilterWatcher
 ::FltkFilterWatcher(itk::ProcessObject* process,
                     int x, int y, int w, int h,
                     const char *comment)
-  : FilterWatcherBase(process, comment)
+  : FilterWatcherBase(process, comment),
+    m_CurrentProgress(0)
 {
   m_Window = new Fl_Window(x, y, w + 10, h + 10);
   m_Window->label(m_Comment.c_str());
@@ -46,4 +47,39 @@ FltkFilterWatcher
   delete m_Window;
 }
 
+void
+FltkFilterWatcher
+::StartFilter()
+{
+  m_Window->show();
+  m_Progress->value(0);
+  m_Progress->show();
+  Fl::check();
+}
+
+void
+FltkFilterWatcher
+::ShowProgress()
+{
+  if (m_Process)
+    {
+    double progress = m_Process->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentProgress > 0.005)
+      {
+      m_Progress->value(progress);
+      m_CurrentProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkFilterWatcher
+::EndFilter()
+{
+  m_Window->hide();
+}
+
 } // end namespace otb
diff --git a/Code/Gui/otbFltkFilterWatcher.h b/Code/Gui/otbFltkFilterWatcher.h
index f15a47bcf437d41aaf4bc240c279e1c384010451..c8bc02ce51516d685557265c15eee4f8f847fc77 100644
--- a/Code/Gui/otbFltkFilterWatcher.h
+++ b/Code/Gui/otbFltkFilterWatcher.h
@@ -38,9 +38,6 @@ namespace otb
 class ITK_EXPORT FltkFilterWatcher : public FilterWatcherBase
 {
 public:
-  /** Classes that need access to filter's private data */
-  // friend class XMLFilterWatcher;
-
   /** Constructor. Takes a ProcessObject to monitor and an optional
    * comment string that is prepended to each event message. */
   FltkFilterWatcher(itk::ProcessObject * process,
@@ -50,35 +47,21 @@ public:
   /** Destructor. */
   virtual ~FltkFilterWatcher();
 
-  /** Callback method to show the EndEvent */
-  virtual void EndFilter()
-  {
-    m_Window->hide();
-  }
-
 protected:
-
   /** Callback method to show the ProgressEvent */
-  virtual void ShowProgress()
-  {
-    if (m_Process)
-      {
-      m_Progress->value(m_Process->GetProgress());
-      Fl::check();
-      }
-  }
+  virtual void ShowProgress();
 
   /** Callback method to show the StartEvent */
-  virtual void StartFilter()
-  {
-    m_Window->show();
-    m_Progress->show();
-  }
+  virtual void StartFilter();
 
-private:
+  /** Callback method to show the EndEvent */
+  virtual void EndFilter();
 
+private:
   Fl_Window *   m_Window;
   Fl_Progress * m_Progress;
+
+  double m_CurrentProgress;
 };
 
 } // end namespace otb
diff --git a/Code/Gui/otbFltkWriterWatcher.cxx b/Code/Gui/otbFltkWriterWatcher.cxx
index a3779c4ba24d427f5a20683485808ebaf9d2de2f..b99700274ff272789ca907bca81041a67e105b1f 100644
--- a/Code/Gui/otbFltkWriterWatcher.cxx
+++ b/Code/Gui/otbFltkWriterWatcher.cxx
@@ -27,7 +27,9 @@ FltkWriterWatcher
 ::FltkWriterWatcher(itk::ProcessObject* process,
                     int x, int y, int w, int h,
                     const char *comment)
-  : WriterWatcherBase(process, comment)
+  : WriterWatcherBase(process, comment),
+    m_CurrentFilterProgress(0),
+    m_CurrentWriterProgress(0)
 {
   this->BuildGUI(x, y, w, h, comment);
 }
@@ -37,7 +39,9 @@ FltkWriterWatcher
                     itk::ProcessObject* source,
                     int x, int y, int w, int h,
                     const char *comment)
-  : WriterWatcherBase(process, source, comment)
+  : WriterWatcherBase(process, source, comment),
+    m_CurrentFilterProgress(0),
+    m_CurrentWriterProgress(0)
 {
   this->BuildGUI(x, y, w, h, comment);
 }
@@ -78,4 +82,74 @@ FltkWriterWatcher
   delete m_Window;
 }
 
+
+void
+FltkWriterWatcher
+::StartFilter()
+{
+  m_Window->show();
+  m_FilterProgress->show();
+  m_WriterProgress->show();
+  Fl::check();
+}
+
+void
+FltkWriterWatcher
+::ShowFilterProgress()
+{
+  if (m_SourceProcess)
+    {
+    double progress = m_SourceProcess->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentFilterProgress > 0.005)
+      {
+      m_FilterProgress->value(progress);
+      m_CurrentFilterProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkWriterWatcher
+::EndFilter()
+{
+}
+
+void
+FltkWriterWatcher
+::StartWriter()
+{
+  m_Window->show();
+  m_FilterProgress->show();
+  m_WriterProgress->show();
+  Fl::check();
+}
+
+void
+FltkWriterWatcher
+::ShowWriterProgress()
+{
+  if (m_Process)
+    {
+    double progress = m_Process->GetProgress();
+
+    // Update only at each 0.5 percent
+    if (progress - m_CurrentWriterProgress > 0.005)
+      {
+      m_WriterProgress->value(progress);
+      m_CurrentWriterProgress = progress;
+      Fl::check();
+      }
+    }
+}
+
+void
+FltkWriterWatcher
+::EndWriter()
+{
+  m_Window->hide();
+}
+
 } // end namespace otb
diff --git a/Code/Gui/otbFltkWriterWatcher.h b/Code/Gui/otbFltkWriterWatcher.h
index e03ecd03f0586060f5618936177461f1535c1814..224d69a6ea55db32fa13f022e5e5fc720ad8c1e1 100644
--- a/Code/Gui/otbFltkWriterWatcher.h
+++ b/Code/Gui/otbFltkWriterWatcher.h
@@ -55,54 +55,25 @@ public:
   /** Destructor. */
   virtual ~FltkWriterWatcher();
 
-  /** Callback method to show the EndEvent */
-  virtual void EndWriter()
-  {
-    m_Window->hide();
-  }
+protected:
 
-  virtual void EndFilter()
-  {}
+  /** Callback method to show the ProgressEvent from the writer */
+  virtual void ShowWriterProgress();
 
-protected:
+  /** Callback method to show the StartEvent from the writer*/
+  virtual void StartWriter();
+
+  /** Callback method to show the EndEvent from the writer*/
+  virtual void EndWriter();
 
-  /** Callback method to show the ProgressEvent */
-  virtual void ShowFilterProgress()
-  {
-    if (m_SourceProcess)
-      {
-      m_FilterProgress->value(m_SourceProcess->GetProgress());
-      Fl::check();
-      }
-  }
-
-  /** Callback method to show the ProgressEvent */
-  virtual void ShowWriterProgress()
-  {
-    if (m_Process)
-      {
-      m_WriterProgress->value(m_Process->GetProgress());
-      Fl::check();
-      }
-  }
-
-  /** Callback method to show the StartEvent */
-  virtual void StartWriter()
-  {
-    m_Window->show();
-    m_FilterProgress->show();
-    m_WriterProgress->show();
-    Fl::check();
-  }
-
-  /** Callback method to show the StartEvent */
-  virtual void StartFilter()
-  {
-    m_Window->show();
-    m_FilterProgress->show();
-    m_WriterProgress->show();
-    Fl::check();
-  }
+  /** Callback method to show the ProgressEvent from the filter */
+  virtual void ShowFilterProgress();
+
+  /** Callback method to show the StartEvent from the filter*/
+  virtual void StartFilter();
+
+  /** Callback method to show the EndEvent from the filter*/
+  virtual void EndFilter();
 
   void BuildGUI(int x, int y, int w, int h, const char * comment);
 
@@ -111,6 +82,9 @@ private:
   Fl_Window *   m_Window;
   Fl_Progress * m_WriterProgress;
   Fl_Progress * m_FilterProgress;
+
+  double m_CurrentFilterProgress;
+  double m_CurrentWriterProgress;
 };
 
 } // end namespace otb
diff --git a/Code/IO/CMakeLists.txt b/Code/IO/CMakeLists.txt
index 54cc874302720870751213a7ca50d27a73402078..437b1e4ce1fd0d4ff6a06665a7e925a2cb190c3d 100644
--- a/Code/IO/CMakeLists.txt
+++ b/Code/IO/CMakeLists.txt
@@ -29,7 +29,7 @@ ADD_LIBRARY(OTBIO ${OTBIO_SRCS})
 #    PROPERTIES
 #    LINK_INTERFACE_LIBRARIES ""
 #  )
-TARGET_LINK_LIBRARIES (OTBIO  ${TIFF_LIBRARY} ${GEOTIFF_LIBRARY}  ${GDAL_LIBRARY} ${OGR_LIBRARY} ${JPEG_LIBRARY} OTBCommon)
+TARGET_LINK_LIBRARIES (OTBIO  ${TIFF_LIBRARY} ${GEOTIFF_LIBRARY}  ${GDAL_LIBRARY} ${OGR_LIBRARY} ${JPEG_LIBRARY} OTBCommon OTBBasicFilters)
 TARGET_LINK_LIBRARIES (OTBIO otbossim otbossimplugins ITKIO ITKCommon otbkml tinyXML)
 
 IF (OTB_USE_LIBLAS)
diff --git a/Code/IO/otbMapFileProductWriter.txx b/Code/IO/otbMapFileProductWriter.txx
index 1463bb05def7feb40c1bb7f8079eb38dcff4f9b0..f74f55fff44dc25647c890a3cf25f03b7468a24e 100644
--- a/Code/IO/otbMapFileProductWriter.txx
+++ b/Code/IO/otbMapFileProductWriter.txx
@@ -237,6 +237,7 @@ MapFileProductWriter<TInputImage>
 
       m_StreamingShrinkImageFilter->SetShrinkFactor(sampleRatioValue);
       m_StreamingShrinkImageFilter->SetInput(m_VectorImage);
+      m_StreamingShrinkImageFilter->Update();
 
       m_VectorRescaleIntensityImageFilter = VectorRescaleIntensityImageFilterType::New();
       m_VectorRescaleIntensityImageFilter->SetInput(m_StreamingShrinkImageFilter->GetOutput());
diff --git a/Code/IO/otbStreamingImageVirtualWriter.h b/Code/IO/otbStreamingImageVirtualWriter.h
index 9ae59e84295c01dce381482e85a1852d6378d888..99e72c1c06736795f2aedfb9f58b02bfa16a7e82 100644
--- a/Code/IO/otbStreamingImageVirtualWriter.h
+++ b/Code/IO/otbStreamingImageVirtualWriter.h
@@ -20,8 +20,7 @@
 
 #include "itkMacro.h"
 #include "itkImageToImageFilter.h"
-#include "itkImageRegionSplitter.h"
-#include "otbStreamingTraits.h"
+#include "otbStreamingManager.h"
 
 namespace otb
 {
@@ -45,7 +44,7 @@ namespace otb
  * \sa PersistentStatisticsImageFilter
  * \sa PersistentImageStreamingDecorator.
  */
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager = StreamingManager<TInputImage> >
 class ITK_EXPORT StreamingImageVirtualWriter : public itk::ImageToImageFilter<TInputImage, TInputImage>
 {
 public:
@@ -68,86 +67,62 @@ public:
   typedef typename InputImageType::PixelType  InputImagePixelType;
 
   /** Streaming traits helper typedef */
-  typedef StreamingTraits<InputImageType> StreamingTraitsType;
+  typedef TStreamingManager                      StreamingManagerType;
+  typedef typename StreamingManagerType::Pointer StreamingManagerPointerType;
 
   /** Dimension of input image. */
   itkStaticConstMacro(InputImageDimension, unsigned int,
                       InputImageType::ImageDimension);
 
-  /** Set/Get the image input of this writer.  */
-  void SetInput(const InputImageType *input);
-  const InputImageType * GetInput(void);
-  const InputImageType * GetInput(unsigned int idx);
+  StreamingManagerType* GetStreamingManager(void)
+    {
+    return m_StreamingManager;
+    }
 
-  void SetNthInput(unsigned int idx, const InputImageType *input);
-
-
-  /** SmartPointer to a region splitting object */
-  typedef itk::ImageRegionSplitter<itkGetStaticConstMacro(InputImageDimension)> SplitterType;
-  typedef typename SplitterType::Pointer                                        RegionSplitterPointer;
-
-  /**  Set buffer memory size (in bytes) use to calculate the number of stream divisions */
-  void SetBufferMemorySize(unsigned long);
-
-  /**  Set the buffer number of lines use to calculate the number of stream divisions */
-  void SetBufferNumberOfLinesDivisions(unsigned long);
-
-  /**  The number of stream divisions is calculate by using
-   * OTB_STREAM_IMAGE_SIZE_TO_ACTIVATE_STREAMING and
-   * OTB_STREAM_MAX_SIZE_BUFFER_FOR_STREAMING cmake variables.
-   */
-  void SetAutomaticNumberOfStreamDivisions(void);
-
-  /** Set the tiling automatic mode for streaming division */
-  void SetTilingStreamDivisions(void);
-  /** Choose number of divisions in tiling streaming division */
-  void SetTilingStreamDivisions(unsigned long);
-
-  /** Return the string to indicate the method use to calculate number of stream divisions. */
-  std::string GetMethodUseToCalculateNumberOfStreamDivisions(void);
-
-  /** Set the number of pieces to divide the input.  The upstream pipeline
-   * will be executed this many times. */
-  void SetNumberOfStreamDivisions(unsigned long);
-
-  /** Get the number of pieces to divide the input. The upstream pipeline
-   * will be executed this many times. */
-  unsigned long GetNumberOfStreamDivisions(void);
-
-  /** Set the helper class for dividing the input into chunks. */
-  itkSetObjectMacro(RegionSplitter, SplitterType);
-
-  /** Get the helper class for dividing the input into chunks. */
-  itkGetObjectMacro(RegionSplitter, SplitterType);
-
-  /** Type use to define number of divisions */
-  typedef StreamingMode CalculationDivisionEnumType;
-
-  virtual void GenerateInputRequestedRegion(void);
+  void SetStreamingManager(StreamingManagerType* streamingManager)
+    {
+    m_StreamingManager = streamingManager;
+    }
 
 protected:
   StreamingImageVirtualWriter();
+
   virtual ~StreamingImageVirtualWriter();
+
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
   virtual void GenerateData(void);
 
+  virtual void GenerateInputRequestedRegion(void);
+
 private:
   StreamingImageVirtualWriter(const StreamingImageVirtualWriter &); //purposely not implemented
   void operator =(const StreamingImageVirtualWriter&); //purposely not implemented
 
-  /** This method calculate the number of stream divisions, by using the CalculationDivision type */
-  unsigned long CalculateNumberOfStreamDivisions(void);
+  void ObserveSourceFilterProgress(itk::Object* object, const itk::EventObject & event )
+  {
+    if (typeid(event) != typeid(itk::ProgressEvent))
+      {
+      return;
+      }
+
+    itk::ProcessObject* processObject = dynamic_cast<itk::ProcessObject*>(object);
+    if (processObject)
+      m_DivisionProgress = processObject->GetProgress();
+
+    this->UpdateFilterProgress();
+  }
 
-  /** Use to define the method used to calculate number of divisions */
-  unsigned long m_BufferMemorySize;
-  unsigned long m_BufferNumberOfLinesDivisions;
-  unsigned long m_NumberOfStreamDivisions;
+  void UpdateFilterProgress()
+  {
+    this->UpdateProgress( (m_DivisionProgress + m_CurrentDivision) / m_NumberOfDivisions );
+  }
 
-  RegionSplitterPointer m_RegionSplitter;
+  unsigned int m_NumberOfDivisions;
+  unsigned int m_CurrentDivision;
+  float m_DivisionProgress;
 
-  /** Use to determine method of calculation number of divisions */
-  CalculationDivisionEnumType m_CalculationDivision;
+  StreamingManagerPointerType m_StreamingManager;
 };
 
 } // end namespace otb
diff --git a/Code/IO/otbStreamingImageVirtualWriter.txx b/Code/IO/otbStreamingImageVirtualWriter.txx
index ce0b5938974e80d17265524e360b278f9aa013df..73df70a34af41b0802a90c3e89872ec9c46ddea0 100644
--- a/Code/IO/otbStreamingImageVirtualWriter.txx
+++ b/Code/IO/otbStreamingImageVirtualWriter.txx
@@ -19,231 +19,55 @@
 #define __otbStreamingImageVirtualWriter_txx
 #include "otbStreamingImageVirtualWriter.h"
 
-#include "itkCommand.h"
-#include "itkImageRegionIterator.h"
-#include "itkObjectFactoryBase.h"
-#include "itkImageFileWriter.h"
-#include "itkImageRegionMultidimensionalSplitter.h"
-
 #include "otbMacro.h"
 #include "otbConfigure.h"
+#include "itkCommand.h"
 
 namespace otb
 {
-/**
- *
- */
-template <class TInputImage>
-StreamingImageVirtualWriter<TInputImage>
+
+template <class TInputImage, class TStreamingManager>
+StreamingImageVirtualWriter<TInputImage, TStreamingManager>
 ::StreamingImageVirtualWriter()
 {
-  m_BufferMemorySize = 0;
-  m_BufferNumberOfLinesDivisions = 0;
-  // default to 10 divisions
-  m_NumberOfStreamDivisions = 0;
-  // default to AUTOMATIC_NUMBER_OF_DIVISIONS
-  m_CalculationDivision = SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-
-  // create default region splitter
-  m_RegionSplitter = itk::ImageRegionSplitter<InputImageDimension>::New();
+  m_StreamingManager = StreamingManagerType::New();
 }
 
-/**
- *
- */
-template <class TInputImage>
-StreamingImageVirtualWriter<TInputImage>
+template <class TInputImage, class TStreamingManager>
+StreamingImageVirtualWriter<TInputImage, TStreamingManager>
 ::~StreamingImageVirtualWriter()
 {
 }
 
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetBufferMemorySize(unsigned long memory_size_divisions)
-{
-  m_BufferMemorySize = memory_size_divisions;
-  m_CalculationDivision = SET_BUFFER_MEMORY_SIZE;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetBufferNumberOfLinesDivisions(unsigned long nb_lines_divisions)
-{
-  m_BufferNumberOfLinesDivisions = nb_lines_divisions;
-  m_CalculationDivision = SET_BUFFER_NUMBER_OF_LINES;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetNumberOfStreamDivisions(unsigned long nb_divisions)
-{
-  m_NumberOfStreamDivisions = nb_divisions;
-  m_CalculationDivision = SET_NUMBER_OF_STREAM_DIVISIONS;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetAutomaticNumberOfStreamDivisions(void)
-{
-  m_CalculationDivision = SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-  this->Modified();
-}
-
-/**
- *
- */
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
-::SetTilingStreamDivisions(void)
-{
-  m_CalculationDivision = SET_TILING_WITH_SET_AUTOMATIC_NUMBER_OF_STREAM_DIVISIONS;
-  m_RegionSplitter = itk::ImageRegionMultidimensionalSplitter<InputImageDimension>::New();
-  this->Modified();
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetTilingStreamDivisions(unsigned long nb_divisions)
-{
-  m_CalculationDivision = SET_TILING_WITH_SET_NUMBER_OF_STREAM_DIVISIONS;
-  m_NumberOfStreamDivisions = nb_divisions;
-  m_RegionSplitter = itk::ImageRegionMultidimensionalSplitter<InputImageDimension>::New();
-  this->Modified();
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetInput(const InputImageType *input)
-{
-  this->SetNthInput(0, input);
-}
-
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::SetNthInput(unsigned int idx, const InputImageType *input)
-{
-  // ProcessObject is not const_correct so this cast is required here.
-  this->itk::ProcessObject::SetNthInput(idx,
-                                        const_cast<TInputImage *>(input));
-}
-
-template <class TInputImage>
-const typename StreamingImageVirtualWriter<TInputImage>::InputImageType *
-StreamingImageVirtualWriter<TInputImage>
-::GetInput(void)
-{
-  if (this->GetNumberOfInputs() < 1)
-    {
-    return 0;
-    }
-
-  return static_cast<TInputImage*>
-           (this->itk::ProcessObject::GetInput(0));
-}
-
-template <class TInputImage>
-const typename StreamingImageVirtualWriter<TInputImage>::InputImageType *
-StreamingImageVirtualWriter<TInputImage>
-::GetInput(unsigned int idx)
+StreamingImageVirtualWriter<TInputImage, TStreamingManager>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
-  return static_cast<TInputImage*> (this->itk::ProcessObject::GetInput(idx));
+  Superclass::PrintSelf(os, indent);
 }
 
-template <class TInputImage>
+template <class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
+StreamingImageVirtualWriter<TInputImage, TStreamingManager>
 ::GenerateInputRequestedRegion(void)
 {
   InputImagePointer                        inputPtr = const_cast<InputImageType *>(this->GetInput(0));
+
+  InputImageRegionType                     region;
   typename InputImageRegionType::SizeType  size;
   typename InputImageRegionType::IndexType index;
-  InputImageRegionType                     region;
+
   index.Fill(0);
   size.Fill(0);
   region.SetSize(size);
   region.SetIndex(index);
   inputPtr->SetRequestedRegion(region);
 }
-/**
- *
- */
-template <class TInputImage>
-unsigned long
-StreamingImageVirtualWriter<TInputImage>
-::GetNumberOfStreamDivisions(void)
-{
-  return (CalculateNumberOfStreamDivisions());
-}
-template<class TInputImage>
-unsigned long
-StreamingImageVirtualWriter<TInputImage>
-::CalculateNumberOfStreamDivisions(void)
-{
-  return StreamingTraitsType
-         ::CalculateNumberOfStreamDivisions(this->GetInput(),
-                                            this->GetInput()->GetLargestPossibleRegion(),
-                                            m_RegionSplitter,
-                                            m_CalculationDivision,
-                                            m_NumberOfStreamDivisions,
-                                            m_BufferMemorySize,
-                                            m_BufferNumberOfLinesDivisions);
-}
-/**
- *
- */
-template <class TInputImage>
-std::string
-StreamingImageVirtualWriter<TInputImage>
-::GetMethodUseToCalculateNumberOfStreamDivisions(void)
-{
-  return (StreamingTraitsType::GetMethodUseToCalculateNumberOfStreamDivisions(m_CalculationDivision));
-}
-/**
- *
- */
-template <class TInputImage>
-void
-StreamingImageVirtualWriter<TInputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-  os << indent << "Number of stream divisions: " << m_NumberOfStreamDivisions
-     << std::endl;
-  if (m_RegionSplitter)
-    {
-    os << indent << "Region splitter:" << m_RegionSplitter << std::endl;
-    }
-  else
-    {
-    os << indent << "Region splitter: (none)" << std::endl;
-    }
-}
-template<class TInputImage>
+
+template<class TInputImage, class TStreamingManager>
 void
-StreamingImageVirtualWriter<TInputImage>
+StreamingImageVirtualWriter<TInputImage, TStreamingManager>
 ::GenerateData(void)
 {
   /**
@@ -257,6 +81,7 @@ StreamingImageVirtualWriter<TInputImage>
    * Tell all Observers that the filter is starting
    */
   this->InvokeEvent(itk::StartEvent());
+
   /**
    * Grab the input
    */
@@ -267,25 +92,47 @@ StreamingImageVirtualWriter<TInputImage>
    * minimum of what the user specified via SetNumberOfStreamDivisions()
    * and what the Splitter thinks is a reasonable value.
    */
-  unsigned int numDivisions;
-  numDivisions = static_cast<unsigned int>(CalculateNumberOfStreamDivisions());
+  m_StreamingManager->PrepareStreaming(inputPtr, outputRegion);
+  m_NumberOfDivisions = m_StreamingManager->GetNumberOfSplits();
+
+  /**
+   * Register to the ProgressEvent of the source filter
+   */
+  // Get the source process object
+  itk::ProcessObject* source = inputPtr->GetSource();
+
+  // Check if source exists
+  if(source)
+    {
+    typedef itk::MemberCommand<Self> CommandType;
+    typedef typename CommandType::Pointer CommandPointerType;
+
+    CommandPointerType command = CommandType::New();
+    command->SetCallbackFunction(this, &Self::ObserveSourceFilterProgress);
+
+    source->AddObserver(itk::ProgressEvent(), command);
+    }
+  else
+    {
+    itkWarningMacro(<< "Could not get the source process object. Progress report might be buggy");
+    }
 
   /**
    * Loop over the number of pieces, execute the upstream pipeline on each
    * piece, and copy the results into the output image.
    */
   InputImageRegionType streamRegion;
-  unsigned int         piece;
-  for (piece = 0;
-       piece < numDivisions && !this->GetAbortGenerateData();
-       piece++)
+  for (m_CurrentDivision = 0;
+       m_CurrentDivision < m_NumberOfDivisions && !this->GetAbortGenerateData();
+       m_CurrentDivision++, m_DivisionProgress = 0, this->UpdateFilterProgress())
     {
-    streamRegion = m_RegionSplitter->GetSplit(piece, numDivisions, outputRegion);
+    streamRegion = m_StreamingManager->GetSplit(m_CurrentDivision);
+    otbMsgDevMacro(<< "Processing region : " << streamRegion )
     inputPtr->ReleaseData();
     inputPtr->SetRequestedRegion(streamRegion);
     inputPtr->Update();
-    this->UpdateProgress((float) piece / numDivisions);
     }
+
   /**
    * If we ended due to aborting, push the progress up to 1.0 (since
    * it probably didn't end there)
@@ -308,11 +155,14 @@ StreamingImageVirtualWriter<TInputImage>
       this->GetOutput(idx)->DataHasBeenGenerated();
       }
     }
+
   /**
    * Release any inputs if marked for release
    */
   this->ReleaseInputs();
 }
+
+
 } // end namespace otb
 
 #endif
diff --git a/Code/Projections/otbUtmMapProjection.h b/Code/Projections/otbUtmMapProjection.h
index f30ba4e544d5556335f0d9dd1a83dba8b073404c..b031c63ba05f9d1af083d8a87db9774d4dd34a51 100644
--- a/Code/Projections/otbUtmMapProjection.h
+++ b/Code/Projections/otbUtmMapProjection.h
@@ -53,7 +53,7 @@ public:
   virtual void SetZone(long zone);
   virtual void SetHemisphere(char hemisphere);
   virtual int GetZone() const;
-  virtual const char GetHemisphere() const;
+  virtual char GetHemisphere() const;
 
   virtual void SetZoneAndHemisphereFromGeoPoint(const InputPointType& geoPoint);
   virtual int GetZoneFromGeoPoint(const InputPointType& geoPoint) const;
diff --git a/Code/Projections/otbUtmMapProjection.txx b/Code/Projections/otbUtmMapProjection.txx
index 6d1ffd46ea162ca99625b078f2b89c2b653aba1b..450e166099ed39206dfaeda9483066bc5a1e91db 100644
--- a/Code/Projections/otbUtmMapProjection.txx
+++ b/Code/Projections/otbUtmMapProjection.txx
@@ -68,7 +68,7 @@ int UtmMapProjection<TTransform>
 
 ///\return the hemisphere
 template <TransformDirection::TransformationDirection TTransform>
-const char UtmMapProjection<TTransform>
+char UtmMapProjection<TTransform>
 ::GetHemisphere() const
 {
   char hemisphere = this->m_MapProjection->getHemisphere();
diff --git a/Code/SARPolarimetry/otbHermitianEigenAnalysis.h b/Code/SARPolarimetry/otbHermitianEigenAnalysis.h
deleted file mode 100644
index 16001824ae9bba73af0305911c6044885f74d341..0000000000000000000000000000000000000000
--- a/Code/SARPolarimetry/otbHermitianEigenAnalysis.h
+++ /dev/null
@@ -1,342 +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 __otbHermitianEigenAnalysis_h
-#define __otbHermitianEigenAnalysis_h
-
-#include "itkMacro.h"
-#include "itkVector.h"
-#include "itkArray2D.h"
-
-namespace otb
-{
-  
-/** \class HermitianEigenAnalysis
- * \brief Find Eigen values of a real 2D symmetric matrix. It
- * serves as a thread safe alternative to the class:
- * vnl_symmetric_eigensystem, which uses netlib routines.
- *
- * The class is templated over the input matrix, (which is expected to provide
- * access to its elements with the [][] operator), matrix to store eigen
- * values, (must provide write operations on its elements with the [] operator),
- * EigenMatrix to store eigen vectors (must provide write access to its elements
- * with the [][] operator).
- *
- * The SetOrderEigenValues() method can be used to order eigen values (and their
- * corresponding eigen vectors if computed) in ascending order. This is the
- * default ordering scheme. Eigen vectors and values can be obtained without
- * ordering by calling SetOrderEigenValues(false)
- *
- * The SetOrderEigenMagnitudes() method can be used to order eigen values (and
- * their corresponding eigen vectors if computed) by magnitude in ascending order.
- *
- * The user of this class is explicitly supposed to set the dimension of the
- * 2D matrix using the SetDimension() method.
- *
- * The class contains routines taken from netlib sources. (www.netlib.org).
- * netlib/tql1.c
- * netlib/tql2.c
- * netlib/tred1.c
- * netlib/tred2.c
- *
- * Reference:
- *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
- *     wilkinson.
- *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
- *
- * \ingroup SARPolarimetry
- */
-
-template < typename TMatrix, typename TVector, typename TEigenMatrix=TMatrix >
-class HermitianEigenAnalysis
-{
-public:
-  typedef enum {
-    OrderByValue=1,
-    OrderByMagnitude,
-    DoNotOrder
-  }EigenValueOrderType;
-
-  typedef itk::Vector<float, 2> ComplexVectorType;
-  typedef itk::Vector<ComplexVectorType, 3> HermitianVectorType;
-  typedef itk::Vector<HermitianVectorType, 3> HermitianMatrixType;
- 
-  
-  HermitianEigenAnalysis():
-      m_Dimension(0),
-      m_Order(0),
-      m_OrderEigenValues(OrderByValue)
-    {};
-  
-  HermitianEigenAnalysis( const unsigned int dimension ):
-      m_Dimension(dimension),
-      m_Order(dimension),
-      m_OrderEigenValues(OrderByValue)
-    {};
-
-  virtual ~HermitianEigenAnalysis() {};
-
-  typedef TMatrix      MatrixType;
-  typedef TEigenMatrix EigenMatrixType;
-  typedef TVector      VectorType;
-
-  
-
-
-  /** Compute Eigen values of A
-   * A is any type that overloads the [][] operator and contains the
-   * symmetric matrix. In practice only the upper triangle of the
-   * matrix will be accessed. (Both itk::Matrix and vnl_matrix
-   * overload [][] operator.)
-   *
-   * 'EigenValues' is any type that overloads the []   operator and will contain
-   * the eigen values.
-   *
-   * No size checking is performed. A is expected to be a square matrix of size
-   * m_Dimension.  'EigenValues' is expected to be of length m_Dimension.
-   * The matrix is not checked to see if it is symmetric.
-   */
-  unsigned int ComputeEigenValues(
-              const TMatrix  & A,
-              TVector        & EigenValues) const;
-              
-  /** Compute Eigen values and vectors of A
-   * A is any type that overloads the [][] operator and contains the
-   * symmetric matrix. In practice only the upper triangle of the
-   * matrix will be accessed. (Both itk::Matrix and vnl_matrix
-   * overload [][] operator.)
-   *
-   * 'EigenValues' is any type that overloads the []   operator and will contain
-   * the eigen values.
-   *
-   * 'EigenVectors' is any type that provides access to its elements with the
-   * [][] operator. It is expected be of size m_Dimension * m_Dimension.
-   *
-   * No size checking is performed. A is expected to be a square matrix of size
-   * m_Dimension.  'EigenValues' is expected to be of length m_Dimension.
-   * The matrix is not checked to see if it is symmetric.
-   *
-   * Each row of the matrix 'EigenVectors' represents an eigen vector. (unlike MATLAB
-   * where the columns of the [EigenVectors, EigenValues] = eig(A) contains the
-   * eigenvectors).
-   */
-  unsigned int ComputeEigenValuesAndVectors(
-              const TMatrix  & A,
-              TVector        & EigenValues,
-              TEigenMatrix   & EigenVectors ) const;
-
-  
-  /** Matrix order. Defaults to matrix dimension if not set **/
-  void SetOrder(const unsigned int n)
-    {
-    m_Order = n;
-    }
-  
-  /** Get the Matrix order. Will be 0 unless explicitly set, or unless a
-   * call to SetDimension has been made in which case it will be the
-   * matrix dimension. */
-  unsigned int GetOrder() const { return m_Order; }
-
-  /** Set/Get methods to order the eigen values in ascending order.
-   * This is the default. ie lambda_1 < lambda_2 < ....
-   */
-  void SetOrderEigenValues( const bool b )
-    {
-    if (b) { m_OrderEigenValues = OrderByValue;     }
-    else   { m_OrderEigenValues = DoNotOrder;       }
-    }
-  bool GetOrderEigenValues() const { return (m_OrderEigenValues == OrderByValue); }
-
-  /** Set/Get methods to order the eigen value magnitudes in ascending order.
-   * In other words, |lambda_1| < |lambda_2| < .....
-   */
-  void SetOrderEigenMagnitudes( const bool b )
-    {
-    if (b) { m_OrderEigenValues = OrderByMagnitude; }
-    else   { m_OrderEigenValues = DoNotOrder;       }
-    }
-  bool GetOrderEigenMagnitudes() const { return (m_OrderEigenValues == OrderByMagnitude); }
-
-  /** Set the dimension of the input matrix A. A is a square matrix of
-   * size m_Dimension. */
-  void SetDimension( const unsigned int n )
-    {
-    m_Dimension = n;
-    if (m_Order == 0 )
-      {
-      m_Order = m_Dimension;
-      }
-    }
-  
-  /** Get Matrix dimension, Will be 0 unless explicitly set by a
-   * call to SetDimension. */
-  unsigned int GetDimension() const { return m_Dimension; }
-
-
-private:
-  unsigned int m_Dimension;
-  unsigned int m_Order;
-  EigenValueOrderType         m_OrderEigenValues;
-
- 
-  /** Reduces a real symmetric matrix to a symmetric tridiagonal matrix using
-   *  orthogonal similarity transformations.
-   *  'inputMatrix' contains the real symmetric input matrix. Only the lower
-   *  triangle of the matrix need be supplied. The upper triangle is unaltered.
-   *  'd' contains the diagonal elements of the tridiagonal matrix.
-   *  'e' contains the subdiagonal elements of the tridiagonal matrix in its
-   *  last n-1 positions.  e(1) is set to zero.
-   *  'e2' contains the squares of the corresponding elements of e.
-   *  'e2' may coincide with e if the squares are not needed.
-   *  questions and comments should be directed to burton s. garbow.
-   *  mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tred1.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary].
-   *  Reference:
-   *  num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson.
-   *    handbook for auto. comp., vol.ii-linear algebra, 212-226(1971).    */
-  void ReduceToTridiagonalMatrix(double *inputMatrix, VectorType &d,
-                                 double *e, double *e2) const;
-
-
-  
-  /** Reduces a real symmetric matrix to a symmetric tridiagonal matrix using
-   *  and accumulating orthogonal similarity transformations.
-   *  'inputMatrix' contains the real symmetric input matrix. Only the lower
-   *  triangle of the matrix need be supplied. The upper triangle is unaltered.
-   *  'diagonalElements' will contains the diagonal elements of the tridiagonal
-   *  matrix.
-   *  'subDiagonalElements' will contain the subdiagonal elements of the tridiagonal
-   *  matrix in its last n-1 positions.  subDiagonalElements(1) is set to zero.
-   *  'transformMatrix' contains the orthogonal transformation matrix produced
-   *  in the reduction.
-   *
-   *  questions and comments should be directed to burton s. garbow.
-   *  mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tred2.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary].
-   *  Reference:
-   *  num. math. 11, 181-195(1968) by martin, reinsch, and wilkinson.
-   *    handbook for auto. comp., vol.ii-linear algebra, 212-226(1971).    */
-  void ReduceToTridiagonalMatrixAndGetTransformation(
-                  double *inputMatrix, VectorType &diagonalElements,
-                  double *subDiagonalElements, double *transformMatrix) const;
-  
-
-  
-  /* Finds the eigenvalues of a symmetric tridiagonal matrix by the ql method.
-   *
-   * On input:
-   * 'd' contains the diagonal elements of the input matrix.
-   * 'e' contains the subdiagonal elements of the input matrix
-   * in its last n-1 positions.  e(1) is arbitrary.
-   * On Output:
-   * 'd' contains the eigenvalues.
-   * 'e' has been destroyed.
-   *
-   * Returns:
-   *          zero       for normal return,
-   *          j          if the j-th eigenvalue has not been
-   *                     determined after 30 iterations.
-   *
-   *
-   * Reference
-   *     this subroutine is a translation of the algol procedure tql1,
-   *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
-   *     wilkinson.
-   *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
-   *
-   *     Questions and comments should be directed to burton s. garbow,
-   *     mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tql1.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary]                      */
-  unsigned int ComputeEigenValuesUsingQL(
-                         VectorType &d, double *e) const;
-
-  
-  /* Finds the eigenvalues and eigenvectors of a symmetric tridiagonal matrix
-   * by the ql method.
-   *
-   * On input:
-   * 'd' contains the diagonal elements of the input matrix.
-   * 'e' contains the subdiagonal elements of the input matrix
-   * in its last n-1 positions.  e(1) is arbitrary.
-   * 'z' contains the transformation matrix produced in the reduction by
-   * ReduceToTridiagonalMatrixAndGetTransformation(), if performed. If the
-   * eigenvectors of the tridiagonal matrix are desired, z must contain
-   * the identity matrix.
-
-   * On Output:
-   * 'd' contains the eigenvalues.
-   * 'e' has been destroyed.
-   * 'z' contains orthonormal eigenvectors of the symmetric tridiagonal
-   * (or full) matrix.
-   *
-   * Returns:
-   *          zero       for normal return,
-   *          j          if the j-th eigenvalue has not been
-   *                     determined after 1000 iterations.
-   *
-   * Reference
-   *     this subroutine is a translation of the algol procedure tql1,
-   *     num. math. 11, 293-306(1968) by bowdler, martin, reinsch, and
-   *     wilkinson.
-   *     handbook for auto. comp., vol.ii-linear algebra, 227-240(1971).
-   *
-   *     Questions and comments should be directed to burton s. garbow,
-   *     mathematics and computer science div, argonne national laboratory
-   *     this version dated august 1983.
-   *
-   *  Function Adapted from netlib/tql2.c.
-   *  [Changed: remove static vars, enforce const correctness.
-   *            Use vnl routines as necessary]
-   */
-  unsigned int ComputeEigenValuesAndVectorsUsingQL(
-                                   VectorType &d, double *e, double *z) const;
-  
-};
-
-template< typename TMatrix, typename TVector, typename TEigenMatrix >
-std::ostream & operator<<(std::ostream& os,
-    const HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix > &s)
-{
-  os << "[ClassType: HermitianEigenAnalysis]" << std::endl;
-  os << "  Dimension : " << s.GetDimension() << std::endl;
-  os << "  Order : " << s.GetOrder() << std::endl;
-  os << "  OrderEigenValues: " << s.GetOrderEigenValues() << std::endl;
-  os << "  OrderEigenMagnitudes: " << s.GetOrderEigenMagnitudes() << std::endl;
-  return os;
-}
-
-} // end namespace otb
-
-
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "otbHermitianEigenAnalysis.txx"
-#endif
-
-#endif
-
diff --git a/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx b/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx
deleted file mode 100644
index 04d32590c9f90d07754167c52d4efa424cef122c..0000000000000000000000000000000000000000
--- a/Code/SARPolarimetry/otbHermitianEigenAnalysis.txx
+++ /dev/null
@@ -1,983 +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 __otbHermitianEigenAnalysis_txx
-#define __otbHermitianEigenAnalysis_txx
-
-#include "otbHermitianEigenAnalysis.h"
-#include "vnl/vnl_math.h"
-
-namespace otb
-{
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValues(const TMatrix  & A,
-                         TVector  & D) const
-{
-  double *workArea1 = new double[ m_Dimension ];
-
-  // Copy the input matrix
-  double *inputMatrix = new double [ m_Dimension * m_Dimension ];
-  
-  unsigned int k = 0;
-
-  for( unsigned int row=0; row < m_Dimension; row++ )
-    {
-    for( unsigned int col=0; col < m_Dimension; col++ )
-      {
-      inputMatrix[k++] = A(row, col);
-      }
-    }
-
-  ReduceToTridiagonalMatrix( inputMatrix, D, workArea1, workArea1 );
-  const unsigned int eigenErrIndex =
-          ComputeEigenValuesUsingQL( D, workArea1 );
-  
-  delete[] workArea1;
-  delete[] inputMatrix;
-
-  return eigenErrIndex; //index of eigen value that could not be computed
-}
-
-
-/*******************************************************************************
-Routine  : diagonalisation
-Authors  : Eric POTTIER, Laurent FERRO-FAMIL
-Creation : 01/2002
-Update   :
-*-------------------------------------------------------------------------------
-Description :  Computes the eigenvectors and eigenvalues of a N*N hermitian
-matrix (with N < 10)
-*-------------------------------------------------------------------------------
-Inputs arguments :
-MatrixDim : Dimension of the Hermitian Matrix (N)
-HermitianMatrix : N*N*2 complex hermitian matrix
-Returned values  :
-EigenVect : N*N*2 complex eigenvector matrix
-EigenVal  : N elements eigenvalue real vector
-*******************************************************************************/
-
-static void HermitianDiagonalisation( float HM[3][3][2], float EigenVect[3][3][2], float EigenVal[3])
-{
-
-    double a[10][10][2], v[10][10][2], d[10], b[10], z[10];
-    double w[2], s[2], c[2], titi[2], gc[2], hc[2];
-    double sm, tresh, x, toto, e, f, g, h, r, d1, d2;
-    int n, p, q, ii, i, j, k;
-
-    //n = MatrixDim;
-    n=3;
-   
-  
-
-    for (i = 1; i < n + 1; i++)
-      {
-        for (j = 1; j < n + 1; j++)
-          {
-            a[i][j][0] = HM[i - 1][j - 1][0];
-            a[i][j][1] = HM[i - 1][j - 1][1];
-            v[i][j][0] = 0.;
-            v[i][j][1] = 0.;
-          }
-        v[i][i][0] = 1.;
-        v[i][i][1] = 0.;
-      }
-
-    for (p = 1; p < n + 1; p++)
-      {
-        d[p] = a[p][p][0];
-        b[p] = d[p];
-        z[p] = 0.;
-      }
-
-    for (ii = 1; ii < 1000 * n * n; ii++)
-      {
-        sm = 0.;
-        for (p = 1; p < n; p++)
-          {
-            for (q = p + 1; q < n + 1; q++)
-              {
-                sm = sm + 2. * sqrt(a[p][q][0] * a[p][q][0] + a[p][q][1] * a[p][q][1]);
-              }
-          }
-        sm = sm / (n * (n - 1));
-        if (sm < 1.E-16)
-          {
-            goto Sortie;
-          }
-        tresh = 1.E-17;
-        if (ii < 4)
-          {
-            tresh = (long) 0.2 *sm / (n * n);
-          }
-        x = -1.E-15;
-        for (i = 1; i < n; i++)
-          {
-            for (j = i + 1; j < n + 1; j++)
-              {
-                toto = sqrt(a[i][j][0] * a[i][j][0] + a[i][j][1] * a[i][j][1]);
-                if (x < toto)
-                  {
-                    x = toto;
-                    p = i;
-                    q = j;
-                  }
-              }
-          }
-        toto = sqrt(a[p][q][0] * a[p][q][0] + a[p][q][1] * a[p][q][1]);
-        if (toto > tresh)
-          {
-            e = d[p] - d[q];
-            w[0] = a[p][q][0];
-            w[1] = a[p][q][1];
-            g = sqrt(w[0] * w[0] + w[1] * w[1]);
-            g = g * g;
-            f = sqrt(e * e + 4. * g);
-            d1 = e + f;
-            d2 = e - f;
-            if (fabs(d2) > fabs(d1))
-              {
-                d1 = d2;
-              }
-            r = fabs(d1) / sqrt(d1 * d1 + 4. * g);
-            s[0] = r;
-            s[1] = 0.;
-            titi[0] = 2. * r / d1;
-            titi[1] = 0.;
-            c[0] = titi[0] * w[0] - titi[1] * w[1];
-            c[1] = titi[0] * w[1] + titi[1] * w[0];
-            r = sqrt(s[0] * s[0] + s[1] * s[1]);
-            r = r * r;
-            h = (d1 / 2. + 2. * g / d1) * r;
-            d[p] = d[p] - h;
-            z[p] = z[p] - h;
-            d[q] = d[q] + h;
-            z[q] = z[q] + h;
-            a[p][q][0] = 0.;
-            a[p][q][1] = 0.;
-            
-            for (j = 1; j < p; j++)
-              {
-                gc[0] = a[j][p][0];
-                gc[1] = a[j][p][1];
-                hc[0] = a[j][q][0];
-                hc[1] = a[j][q][1];
-                a[j][p][0] = c[0] * gc[0] - c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                a[j][p][1] = c[0] * gc[1] + c[1] * gc[0] - s[0] * hc[1] + s[1] * hc[0];
-                a[j][q][0] = s[0] * gc[0] - s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                a[j][q][1] = s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-            for (j = p + 1; j < q; j++)
-              {
-                gc[0] = a[p][j][0];
-                gc[1] = a[p][j][1];
-                hc[0] = a[j][q][0];
-                hc[1] = a[j][q][1];
-                a[p][j][0] = c[0] * gc[0] + c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                a[p][j][1] = c[0] * gc[1] - c[1] * gc[0] + s[0] * hc[1] - s[1] * hc[0];
-                a[j][q][0] = s[0] * gc[0] + s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                a[j][q][1] = -s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-            for (j = q + 1; j < n + 1; j++)
-              {
-                gc[0] = a[p][j][0];
-                gc[1] = a[p][j][1];
-                hc[0] = a[q][j][0];
-                hc[1] = a[q][j][1];
-                a[p][j][0] = c[0] * gc[0] + c[1] * gc[1] - s[0] * hc[0] + s[1] * hc[1];
-                a[p][j][1] = c[0] * gc[1] - c[1] * gc[0] - s[0] * hc[1] - s[1] * hc[0];
-                a[q][j][0] = s[0] * gc[0] + s[1] * gc[1] + c[0] * hc[0] - c[1] * hc[1];
-                a[q][j][1] = s[0] * gc[1] - s[1] * gc[0] + c[0] * hc[1] + c[1] * hc[0];
-              }
-            for (j = 1; j < n + 1; j++)
-              {
-                gc[0] = v[j][p][0];
-                gc[1] = v[j][p][1];
-                hc[0] = v[j][q][0];
-                hc[1] = v[j][q][1];
-                v[j][p][0] = c[0] * gc[0] - c[1] * gc[1] - s[0] * hc[0] - s[1] * hc[1];
-                v[j][p][1] = c[0] * gc[1] + c[1] * gc[0] - s[0] * hc[1] + s[1] * hc[0];
-                v[j][q][0] = s[0] * gc[0] - s[1] * gc[1] + c[0] * hc[0] + c[1] * hc[1];
-                v[j][q][1] = s[0] * gc[1] + s[1] * gc[0] + c[0] * hc[1] - c[1] * hc[0];
-              }
-          }
-      }
-    
- Sortie:
-    
-    for (k = 1; k < n + 1; k++)
-      {
-        d[k] = 0;
-        for (i = 1; i < n + 1; i++)
-          {
-            for (j = 1; j < n + 1; j++)
-              {
-                d[k] = d[k] + v[i][k][0] * (HM[i - 1][j - 1][0] * v[j][k][0] - HM[i - 1][j - 1][1] * v[j][k][1]);
-                d[k] = d[k] + v[i][k][1] * (HM[i - 1][j - 1][0] * v[j][k][1] + HM[i - 1][j - 1][1] * v[j][k][0]);
-              }
-          }
-      }
-    
-    for (i = 1; i < n + 1; i++)
-      {
-        for (j = i + 1; j < n + 1; j++)
-          {
-            if (d[j] > d[i])
-              {
-                x = d[i];
-                d[i] = d[j];
-                d[j] = x;
-                for (k = 1; k < n + 1; k++)
-                  {
-                    c[0] = v[k][i][0];
-                    c[1] = v[k][i][1];
-                    v[k][i][0] = v[k][j][0];
-                    v[k][i][1] = v[k][j][1];
-                    v[k][j][0] = c[0];
-                    v[k][j][1] = c[1];
-                  }
-              }
-          }
-      }
-    
-    for (i = 0; i < n; i++)
-      {
-        EigenVal[i] = d[i + 1];
-        for (j = 0; j < n; j++)
-          {
-            EigenVect[i][j][0] = v[i + 1][j + 1][0];
-            EigenVect[i][j][1] = v[i + 1][j + 1][1];
-          }
-      }
-    
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesAndVectors(
-            const TMatrix  & T,
-            TVector        & EigenValues,
-            TEigenMatrix   & EigenVectors ) const
-{
-  // double *workArea1 = new double[ m_Dimension ];
-//   double *workArea2 = new double [ m_Dimension * m_Dimension ];
-
-  // Copy the input matrix
- 
-  unsigned int k = 0;
-  
-  float HM[3][3][2];
-
-
-// Passage de la matrice T T1....T9  une matrice 3*3*2 compatible avec la methode HermitianDiagonalisation
-
-
-  HM[0][0][0]=T[0];    HM[0][0][1]=0.;
-  HM[0][1][0]=T[3];    HM[0][1][1]=-T[4];
-  HM[0][2][0]=T[5];    HM[0][2][1]=-T[6];
-  HM[1][0][0]=T[3];    HM[1][0][1]=T[4];
-  HM[1][1][0]=T[1];    HM[1][1][1]=0.;
-  HM[1][2][0]=T[7];    HM[1][2][1]=-T[8];
-  HM[2][0][0]=T[5];    HM[2][0][1]=T[6];
-  HM[2][1][0]=T[7];    HM[2][1][1]=T[8];
-  HM[2][2][0]=T[2];    HM[2][2][1]=0.;
-
- 
-
-
-  //Acrobatie pour convectir EigenVectors en un float *** et EigenValues en float*
-
-  float eigenVect[3][3][2];
- float eigenVal[3];
-
-  for (int i=0; i<3; i++)
-    for (int j=0; j<3; j++)
-      {
-       eigenVect[i][j][0]=0.;
-       eigenVect[i][j][1]=0.;
-      }
-
-  for (int i=0; i<3; i++)
-    eigenVal[i]=0.;
-    
-  
-  
-  HermitianDiagonalisation( HM, eigenVect, eigenVal);
-
-  
-  //std::cout << HM[0][0][0] << " " << HM[0][1][0]<<"+j"<<HM[0][1][1] << " " << HM[0][2][0]<<"+j"<<HM[0][2][1]<<std::endl;
-  //std::cout << HM[1][0][0]<<"+j"<<HM[1][0][1] << " " << HM[1][1][0] << " " << HM[1][2][0]<<"+j"<<HM[1][2][1]<<std::endl;
-  //std::cout << HM[2][0][0]<<"+j"<<HM[2][0][1] << " " << HM[2][1][0]<<"+j"<< HM[2][1][1] << " " <<HM[2][2][0]<<std::endl;
-  //std::cout << "Valeurs propres : " << eigenVal[0] << "...." << eigenVal[1] <<  "...." << eigenVal[2] << std::endl<< std::endl;
-   
-  
-  // Recuperation des sorties
-  for (int i=0; i<3; i++)
-    for (int j=0; j<3; j++)
-       {
-          EigenVectors[i][2*j]=eigenVect[i][j][0];
-          EigenVectors[i][2*j+1]=eigenVect[i][j][1];
-       }
-  
-
-  for (int i=0; i<3; i++)
-    EigenValues[i]=eigenVal[i];
-   
-  
-  
-
- 
-  int eigenErrIndex=0;
-  return eigenErrIndex; //index of eigen value that could not be computed
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-void
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ReduceToTridiagonalMatrix(double * a, VectorType &d,
-                          double *e, double *e2) const
-{
-  double d__1;
-
-  /* Local variables */
-  double f, g, h;
-  int i, j, k, l;
-  double scale;
-  
-  for (i = 0; i < static_cast< int >(m_Order); ++i)
-    {
-    d[i] = a[m_Order-1 + i * m_Dimension];
-    a[m_Order-1 + i * m_Dimension] = a[i + i * m_Dimension];
-    }
-
-
-  for (i = m_Order-1; i >= 0; --i)
-    {
-    l = i - 1;
-    h = 0.;
-    scale = 0.;
-
-    /*     .......... scale row (algol tol then not needed) .......... */
-    for (k = 0; k <= l; ++k)
-      {
-      scale += vnl_math_abs(d[k]);
-      }
-    if (scale == 0.)
-      {
-      for (j = 0; j <= l; ++j)
-        {
-        d[j] = a[l + j * m_Dimension];
-        a[l + j * m_Dimension] = a[i + j * m_Dimension];
-        a[i + j * m_Dimension] = 0.;
-        }
-        e[i] = 0.;
-        e2[i] = 0.;
-        continue;
-      }
-    for (k = 0; k <= l; ++k)
-      {
-      d[k] /= scale;
-      h += d[k] * d[k];
-      }
-
-    e2[i] = scale * scale * h;
-    f = d[l];
-    d__1 = vcl_sqrt(h);
-    g = (-1.0) * vnl_math_sgn0(f) * vnl_math_abs(d__1);
-    e[i] = scale * g;
-    h -= f * g;
-    d[l] = f - g;
-    if (l != 0)
-      {
-
-      /*     .......... form a*u .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] = 0.;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j] + a[j + j * m_Dimension] * f;
-
-        for (k = j+1; k <= l; ++k)
-          {
-          g += a[k + j * m_Dimension] * d[k];
-          e[k] += a[k + j * m_Dimension] * f;
-          }
-        e[j] = g;
-        }
-    
-      /*     .......... form p .......... */
-      f = 0.;
-
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] /= h;
-        f += e[j] * d[j];
-        }
-
-      h = f / (h + h);
-      /*     .......... form q .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] -= h * d[j];
-        }
-
-      /*     .......... form reduced a .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j];
-
-        for (k = j; k <= l; ++k)
-          {
-          a[k + j * m_Dimension] = a[k + j * m_Dimension] - f * e[k] - g * d[k];
-          }
-        }
-      }
-
-    for (j = 0; j <= l; ++j)
-      {
-      f = d[j];
-      d[j] = a[l + j * m_Dimension];
-      a[l + j * m_Dimension] = a[i + j * m_Dimension];
-      a[i + j * m_Dimension] = f * scale;
-      }
-    }
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-void
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ReduceToTridiagonalMatrixAndGetTransformation(double * a, VectorType &d,
-                                              double *e, double *z) const
-{
-  double d__1;
-
-  /* Local variables */
-  double f, g, h;
-  unsigned int i, j, k, l;
-  double scale, hh;
-
-  for (i = 0; i < m_Order; ++i)
-    {
-    for (j = i; j < m_Order; ++j)
-      {
-      z[j + i * m_Dimension] = a[j + i * m_Dimension];
-      }
-    d[i] = a[m_Order -1 + i * m_Dimension];
-    }
-
-  for (i = m_Order-1; i > 0; --i)
-    {
-    l = i - 1;
-    h = 0.0;
-    scale = 0.0;
-    
-    /*     .......... scale row (algol tol then not needed) .......... */
-    for (k = 0; k <= l; ++k)
-      {
-      scale += vnl_math_abs(d[k]);
-      }
-    if (scale == 0.0)
-      {
-      e[i] = d[l];
-
-      for (j = 0; j <= l; ++j)
-        {
-        d[j] = z[l + j * m_Dimension];
-        z[i + j * m_Dimension] = 0.0;
-        z[j + i * m_Dimension] = 0.0;
-        }
-      }
-    else
-      {
-      for (k = 0; k <= l; ++k)
-        {
-        d[k] /= scale;
-        h += d[k] * d[k];
-        }
-
-      f = d[l];
-      d__1 = vcl_sqrt(h);
-      g = (-1.0) * vnl_math_sgn0(f) * vnl_math_abs(d__1);
-      e[i] = scale * g;
-      h -= f * g;
-      d[l] = f - g;
-      
-      /*     .......... form a*u .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] = 0.0;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        z[j + i * m_Dimension] = f;
-        g = e[j] + z[j + j * m_Dimension] * f;
-
-        for (k = j+1; k <= l; ++k)
-          {
-          g += z[k + j * m_Dimension] * d[k];
-          e[k] += z[k + j * m_Dimension] * f;
-          }
-
-          e[j] = g;
-        }
-      
-      /*     .......... form p .......... */
-      f = 0.0;
-
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] /= h;
-        f += e[j] * d[j];
-        }
-
-      hh = f / (h + h);
-      
-      /*     .......... form q .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        e[j] -= hh * d[j];
-        }
-
-      /*     .......... form reduced a .......... */
-      for (j = 0; j <= l; ++j)
-        {
-        f = d[j];
-        g = e[j];
-
-        for (k = j; k <= l; ++k)
-          {
-          z[k + j * m_Dimension] = z[k + j * m_Dimension] - f * e[k] - g * d[k];
-          }
-
-        d[j] = z[l + j * m_Dimension];
-        z[i + j * m_Dimension] = 0.0;
-        }
-      }
-
-    d[i] = h;
-    }
-
-  /*     .......... accumulation of transformation matrices .......... */
-  for (i = 1; i < m_Order; ++i)
-    {
-    l = i - 1;
-    z[m_Order-1 + l * m_Dimension] = z[l + l * m_Dimension];
-    z[l + l * m_Dimension] = 1.0;
-    h = d[i];
-    if (h != 0.0)
-      {
-      for (k = 0; k <= l; ++k)
-        {
-        d[k] = z[k + i * m_Dimension] / h;
-        }
-
-      for (j = 0; j <= l; ++j)
-        {
-        g = 0.0;
-
-        for (k = 0; k <= l; ++k)
-          {
-          g += z[k + i * m_Dimension] * z[k + j * m_Dimension];
-          }
-
-        for (k = 0; k <= l; ++k)
-          {
-          z[k + j * m_Dimension] -= g * d[k];
-          }
-        }
-      }
-    
-    for (k = 0; k <= l; ++k)
-      {
-      z[k + i * m_Dimension] = 0.0;
-      }
-    
-    }
-    
-  for (i = 0; i < m_Order; ++i)
-    {
-    d[i] = z[m_Order-1 + i * m_Dimension];
-    z[m_Order-1 + i * m_Dimension] = 0.0;
-    }
-
-  z[m_Order-1 + (m_Order-1) * m_Dimension] = 1.0;
-  e[0] = 0.0;
-
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesUsingQL(VectorType &d, double *e) const
-{
-  
-  const double c_b10 = 1.0;
-
-  /* Local variables */
-  double c, f, g, h;
-  unsigned int i, j, l, m;
-  double p, r, s, c2, c3=0.0;
-  double s2=0.0;
-  double dl1, el1;
-  double tst1, tst2;
-
-  unsigned int ierr = 0;
-  if (m_Order == 1) {
-       return 1;
-  }
-
-  for (i = 1; i < m_Order; ++i) {
-      e[i-1] = e[i];
-  }
-
-  f = 0.;
-  tst1 = 0.;
-  e[m_Order-1] = 0.;
-
-  for (l = 0; l < m_Order; ++l)
-    {
-    j = 0;
-    h = vnl_math_abs(d[l]) + vnl_math_abs(e[l]);
-    if (tst1 < h)
-      {
-      tst1 = h;
-      }
-    /*     .......... look for small sub-diagonal element .......... */
-    for (m = l; m < m_Order; ++m)
-      {
-      tst2 = tst1 + vnl_math_abs(e[m]);
-      if (tst2 == tst1)
-        {
-        break;
-        }
-      /*     .......... e(n) is always zero, so there is no exit */
-      /*                through the bottom of the loop .......... */
-      }
-
-    if (m != l)
-      {
-    
-      do
-        {
-        if (j == 30)
-          {
-          /*     .......... set error -- no convergence to an */
-          /*                eigenvalue after 30 iterations .......... */
-          ierr = l+1;
-          return ierr;
-          }
-        ++j;
-        /*     .......... form shift .......... */
-        g = d[l];
-        p = (d[l+1] - g) / (e[l] * 2.);
-        r = vnl_math_hypot(p, c_b10);
-        d[l] = e[l] / (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        d[l+1] = e[l] * (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        dl1 = d[l+1];
-        h = g - d[l];
-
-        for (i = l+2; i < m_Order; ++i)
-        {
-            d[i] -= h;
-        }
-
-        f += h;
-        /*     .......... ql transformation .......... */
-        p = d[m];
-        c = 1.;
-        c2 = c;
-        el1 = e[l+1];
-        s = 0.;
-        for (i = m-1; i >= l; --i)
-          {
-          c3 = c2;
-          c2 = c;
-          s2 = s;
-          g = c * e[i];
-          h = c * p;
-          r = vnl_math_hypot(p, e[i]);
-          e[i+1] = s * r;
-          s = e[i] / r;
-          c = p / r;
-          p = c * d[i] - s * g;
-          d[i+1] = h + s * (c * g + s * d[i]);
-          if( i == l )
-            {
-            break;
-            }
-          }
-
-        p = -s * s2 * c3 * el1 * e[l] / dl1;
-        e[l] = s * p;
-        d[l] = c * p;
-        tst2 = tst1 + vnl_math_abs(e[l]);
-        } while (tst2 > tst1);
-      }
-
-    p = d[l] + f;
- 
-    if( m_OrderEigenValues == OrderByValue )
-      {
-      // Order by value
-      for (i = l; i > 0; --i)
-        {
-        if (p >= d[i-1])
-          break;
-        d[i] = d[i-1];
-        }
-      d[i] = p;
-      }
-    else if( m_OrderEigenValues == OrderByMagnitude )
-      {
-      // Order by magnitude.. make eigen values positive
-      for (i = l; i > 0; --i)
-        {
-        if (vnl_math_abs(p) >= vnl_math_abs(d[i-1]))
-          break;
-        d[i] = vnl_math_abs(d[i-1]);
-        }
-      d[i] = vnl_math_abs(p);
-      }
-    else
-      {
-      d[l] = p;
-      }
-    }
-
-  return ierr;    //ierr'th eigen value that couldn't be computed
-  
-}
-
-
-template< class TMatrix, class TVector, class TEigenMatrix >
-unsigned int
-HermitianEigenAnalysis< TMatrix, TVector, TEigenMatrix >::
-ComputeEigenValuesAndVectorsUsingQL(VectorType &d, double *e, double *z) const
-{
-  
-  const double c_b10 = 1.0;
-
-  /* Local variables */
-  double c, f, g, h;
-  unsigned int i, j, k, l, m;
-  double p, r, s, c2, c3=0.0;
-  double s2=0.0;
-  double dl1, el1;
-  double tst1, tst2;
-
-  unsigned int ierr = 0;
-  if (m_Order == 1)
-    {
-    return 1;
-    }
-
-  for (i = 1; i < m_Order; ++i)
-    {
-    e[i - 1] = e[i];
-    }
-
-  f = 0.0;
-  tst1 = 0.;
-  e[m_Order-1] = 0.;
-
-  for (l = 0; l < m_Order; ++l)
-    {
-    j = 0;
-    h = vnl_math_abs(d[l]) + vnl_math_abs(e[l]);
-    if (tst1 < h)
-      {
-      tst1 = h;
-      }
-    
-    /*     .......... look for small sub-diagonal element .......... */
-    for (m = l; m < m_Order; ++m)
-      {
-      tst2 = tst1 + vnl_math_abs(e[m]);
-      if (tst2 == tst1)
-        {
-        break;
-        }
-      
-      /*     .......... e(n) is always zero, so there is no exit */
-      /*                through the bottom of the loop .......... */
-      }
-
-    if (m != l)
-      {
-      do
-        {
-          
-        if (j == 1000)
-          {
-          /*     .......... set error -- no convergence to an */
-          /*                eigenvalue after 1000 iterations .......... */
-          ierr = l+1;
-          return ierr;
-          }
-        ++j;
-        /*     .......... form shift .......... */
-        g = d[l];
-        p = (d[l+1] - g) / (e[l] * 2.);
-        r = vnl_math_hypot(p, c_b10);
-        d[l] = e[l] / (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        d[l+1] = e[l] * (p + vnl_math_sgn0(p) * vnl_math_abs(r));
-        dl1 = d[l+1];
-        h = g - d[l];
-
-        for (i = l+2; i < m_Order; ++i)
-          {
-          d[i] -= h;
-        }
-
-        f += h;
-        /*     .......... ql transformation .......... */
-        p = d[m];
-        c = 1.0;
-        c2 = c;
-        el1 = e[l+1];
-        s = 0.;
-        
-        for (i = m-1; i >= l; --i)
-          {
-          c3 = c2;
-          c2 = c;
-          s2 = s;
-          g = c * e[i];
-          h = c * p;
-          r = vnl_math_hypot(p, e[i]);
-          e[i + 1] = s * r;
-          s = e[i] / r;
-          c = p / r;
-          p = c * d[i] - s * g;
-          d[i + 1] = h + s * (c * g + s * d[i]);
-          
-          /*     .......... form vector .......... */
-          for (k = 0; k < m_Order; ++k)
-            {
-            h = z[k + (i + 1) * m_Dimension];
-            z[k + (i + 1) * m_Dimension] = s * z[k + i * m_Dimension] + c * h;
-            z[k + i * m_Dimension] = c * z[k + i * m_Dimension] - s * h;
-            }
-          if( i == l )
-            {
-            break;
-            }
-          }
-
-        p = -s * s2 * c3 * el1 * e[l] / dl1;
-        e[l] = s * p;
-        d[l] = c * p;
-        tst2 = tst1 + vnl_math_abs(e[l]);
-        } while (tst2 > tst1);
-  
-      }
-
-    d[l] += f;
-    }
-  
-  /*     .......... order eigenvalues and eigenvectors .......... */
-  if( m_OrderEigenValues == OrderByValue )
-    {
-    // Order by value
-    for (i = 0; i < m_Order-1; ++i)
-      {
-      k = i;
-      p = d[i];
-
-      for (j = i+1; j < m_Order; ++j)
-        {
-        if (d[j] >= p)
-          {
-          continue;
-          }
-        k = j;
-        p = d[j];
-      }
-
-      if (k == i)
-        {
-        continue;
-        }
-      d[k] = d[i];
-      d[i] = p;
-
-      for (j = 0; j < m_Order; ++j)
-        {
-        p = z[j + i * m_Dimension];
-        z[j + i * m_Dimension] = z[j + k * m_Dimension];
-        z[j + k * m_Dimension] = p;
-        }
-      }
-    }
-  else if( m_OrderEigenValues == OrderByMagnitude )
-    {
-    // Order by magnitude
-    for (i = 0; i < m_Order-1; ++i)
-      {
-      k = i;
-      p = d[i];
-
-      for (j = i+1; j < m_Order; ++j)
-        {
-        if (vnl_math_abs(d[j]) >= vnl_math_abs(p))
-          {
-          continue;
-          }
-        k = j;
-        p = d[j];
-      }
-
-      if (k == i)
-        {
-        continue;
-        }
-      d[k] = vnl_math_abs(d[i]);
-      d[i] = vnl_math_abs(p);
-
-      for (j = 0; j < m_Order; ++j)
-        {
-        p = z[j + i * m_Dimension];
-        z[j + i * m_Dimension] = z[j + k * m_Dimension];
-        z[j + k * m_Dimension] = p;
-        }
-      }
-    }
- 
-  
-  return ierr;
-}
-
-
-}  // end namespace otb
- 
-#endif
- 
diff --git a/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h b/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
index 18292eca3bce5cb5dbd14873378fb639edb9bd31..04863bc98651081ceb15499e3bdbfb982eecbcdc 100644
--- a/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
+++ b/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.h
@@ -20,9 +20,9 @@
 #define __ReciprocalHAlphaImageFilter_h
 
 #include "otbUnaryFunctorImageFilter.h"
-#include "otbHermitianEigenAnalysis.h"
-#include "itkVector.h"
 #include "otbMath.h"
+#include "vnl/algo/vnl_complex_eigensystem.h"
+#include <algorithm>
 
 namespace otb
  {
@@ -44,60 +44,68 @@ template< class TInput, class TOutput>
 class ReciprocalHAlphaFunctor
 {
 public:
-  typedef typename std::complex <double>         ComplexType;
-  typedef typename TOutput::ValueType              OutputValueType;
-
-  /** CoherencyMatrix type **/
-  typedef itk::Vector<double, 9> CoherencyMatrixType;
-
-  /** Vector type used to store eigenvalues. */
-  typedef itk::Vector<double, 3> EigenvalueType;
-
-  /** Matrix type used to store eigenvectors. */
-  typedef itk::Vector<float, 2> VectorType;
-  typedef itk::Vector<VectorType, 3> EigenVectorFirstComposantType;
-  typedef itk::Vector<VectorType, 3> EigenVectorType; // eigenvector type (real part, imaginary part)
-  typedef itk::Vector<itk::Vector<float, 6>, 3> EigenMatrixType;
-  typedef itk::Image<EigenVectorType, 2> EigenVectorImageType;
-  typedef itk::Image<double, 2> EigenValueImageType;
-
-  typedef itk::Vector<double, 3> OutputVectorType;
-
-  typedef itk::Vector<float, 2> ComplexVectorType;
-  typedef itk::Vector<ComplexVectorType, 3> HermitianVectorType;
-  typedef itk::Vector<HermitianVectorType, 3> HermitianMatrixType;
-  typedef otb::HermitianEigenAnalysis<CoherencyMatrixType, EigenvalueType, EigenMatrixType> HermitianAnalysisType;
-
-
+  typedef typename std::complex<double> ComplexType;
+  typedef vnl_matrix<ComplexType>       VNLMatrixType;
+  typedef vnl_vector<ComplexType>       VNLVectorType;
+  typedef vnl_vector<double>           VNLDoubleVectorType;
+  typedef std::vector<double>           VectorType;
+  typedef typename TOutput::ValueType   OutputValueType;
+  
+  
   inline TOutput operator()( const TInput & Coherency ) const
     {
     TOutput result;
     result.SetSize(m_NumberOfComponentsPerPixel);
  
-    CoherencyMatrixType T;
-    EigenvalueType eigenValues;
-    EigenMatrixType eigenVectors;
-    HermitianAnalysisType HermitianAnalysis;
-
-    T[0] = static_cast<double>(Coherency[0].real());
-    T[1] = static_cast<double>(Coherency[3].real());
-    T[2] = static_cast<double>(Coherency[5].real());
-    T[3] = static_cast<double>(Coherency[1].real());
-    T[4] = static_cast<double>(Coherency[1].imag());
-    T[5] = static_cast<double>(Coherency[2].real());
-    T[6] = static_cast<double>(Coherency[2].imag());
-    T[7] = static_cast<double>(Coherency[4].real());
-    T[8] = static_cast<double>(Coherency[4].imag());
-    HermitianAnalysis.ComputeEigenValuesAndVectors(T, eigenValues, eigenVectors);
-
+    const double T0 = static_cast<double>(Coherency[0].real());
+    const double T1 = static_cast<double>(Coherency[3].real());
+    const double T2 = static_cast<double>(Coherency[5].real());
+    
+    VNLMatrixType vnlMat(3, 3, 0.);
+    vnlMat[0][0] = ComplexType(T0,  0.);
+    vnlMat[0][1] = std::conj(ComplexType(Coherency[1]));
+    vnlMat[0][2] = std::conj(ComplexType(Coherency[2]));
+    vnlMat[1][0] = ComplexType(Coherency[1]);
+    vnlMat[1][1] = ComplexType(T1,  0.);
+    vnlMat[1][2] = std::conj(ComplexType(Coherency[4]));
+    vnlMat[2][0] = ComplexType(Coherency[2]);
+    vnlMat[2][1] = ComplexType(Coherency[4]);
+    vnlMat[2][2] = ComplexType(T2,  0.);
+    
+    // Only compute the left symetry to respect the previous Hermitian Analisys code
+    vnl_complex_eigensystem syst(vnlMat, false, true);
+    const VNLMatrixType eigenVectors( syst.L );
+    const VNLVectorType eigenValues(syst.W);
+    
     // Entropy estimation
     double  totalEigenValues(0.0);
     double  p[3];
     double entropy;
     double alpha;
     double anisotropy;
-
-    totalEigenValues = static_cast<double>( eigenValues[0] + eigenValues[1] + eigenValues[2]);
+    
+    // Sort eigen values in decreasing order
+    VectorType sortedRealEigenValues(3,  eigenValues[0].real());
+    sortedRealEigenValues[1] = eigenValues[1].real();
+    sortedRealEigenValues[2] = eigenValues[2].real();
+    std::sort( sortedRealEigenValues.begin(), sortedRealEigenValues.end() );
+    std::reverse( sortedRealEigenValues.begin(), sortedRealEigenValues.end() );
+    
+    // Extract the first component of each the eigen vector sorted by eigen value decrease order
+    VNLVectorType sortedGreaterEigenVector(3, eigenVectors[0][0]);
+    for(unsigned int i=0; i<3; i++)
+      {
+        if( vcl_abs( eigenValues[1].real()-sortedRealEigenValues[i] ) < m_Epsilon )
+          {
+            sortedGreaterEigenVector[i] = eigenVectors[1][0];
+          }
+        else if( vcl_abs( eigenValues[2].real()-sortedRealEigenValues[i] ) < m_Epsilon )  
+          {
+            sortedGreaterEigenVector[i] = eigenVectors[2][0];
+          }
+      }
+ 
+    totalEigenValues = sortedRealEigenValues[0] + sortedRealEigenValues[1] + sortedRealEigenValues[2];
     if (totalEigenValues <m_Epsilon)
       {
         totalEigenValues = m_Epsilon;
@@ -105,12 +113,7 @@ public:
 
     for (unsigned int k = 0; k < 3; k++)
       {
-        if (eigenValues[k] <0.)
-          {
-            eigenValues[k] = 0.;
-          }
-
-        p[k] = static_cast<double>(eigenValues[k]) / totalEigenValues;
+        p[k] = std::max(sortedRealEigenValues[k], 0.) / totalEigenValues;
       }
 
     if ( (p[0] < m_Epsilon) || (p[1] < m_Epsilon) || (p[2] < m_Epsilon) )
@@ -129,7 +132,7 @@ public:
 
     for(unsigned int k = 0; k < 3; k++)
       {
-         p[k] = eigenValues[k] / totalEigenValues;
+         p[k] = sortedRealEigenValues[k] / totalEigenValues;
 
          if (p[k] < 0.)
            {
@@ -142,13 +145,13 @@ public:
            }
       }
 
-    val0=sqrt(static_cast<double>(eigenVectors[0][0]*eigenVectors[0][0]) + static_cast<double>(eigenVectors[0][1]*eigenVectors[0][1]));
+    val0 = std::abs(sortedGreaterEigenVector[0]);
     a0=acos(vcl_abs(val0)) * CONST_180_PI;
 
-    val1=sqrt(static_cast<double>(eigenVectors[0][2]*eigenVectors[0][2]) + static_cast<double>(eigenVectors[0][3]*eigenVectors[0][3]));
+    val1 = std::abs(sortedGreaterEigenVector[1]);
     a1=acos(vcl_abs(val1)) * CONST_180_PI;
 
-    val2=sqrt(static_cast<double>(eigenVectors[0][4]*eigenVectors[0][4]) + static_cast<double>(eigenVectors[0][5]*eigenVectors[0][5]));
+    val2= std::abs(sortedGreaterEigenVector[2]);
     a2=acos(vcl_abs(val2)) * CONST_180_PI;
 
     alpha=p[0]*a0 + p[1]*a1 + p[2]*a2;
@@ -159,11 +162,11 @@ public:
       }
 
     // Anisotropy estimation
-    anisotropy=(eigenValues[1] - eigenValues[2])/(eigenValues[1] + eigenValues[2]+m_Epsilon);
+    anisotropy=(sortedRealEigenValues[1] - sortedRealEigenValues[2])/(sortedRealEigenValues[1] + sortedRealEigenValues[2] + m_Epsilon);
 
-    result[0] = entropy;
-    result[1] = alpha;
-    result[2] = anisotropy;
+    result[0] = static_cast<OutputValueType>(entropy);
+    result[1] = static_cast<OutputValueType>(alpha);
+    result[2] = static_cast<OutputValueType>(anisotropy);
 
     return result;
     }
diff --git a/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx b/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
index 60c2881d52cccbf547e65e3942088de115aacdb8..483d6afb84f6a5749726343a7fdcb0da0601e64f 100644
--- a/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
+++ b/Testing/Code/BasicFilters/otbMatrixImageFilterTest.cxx
@@ -28,9 +28,6 @@
 
 int otbMatrixImageFilterNew(int argc, char * argv[])
 {
-  const char * inputFilename  = argv[1];
-  const char * outputFilename = argv[2];
-
   typedef std::complex<double> PixelType;
 
   typedef otb::VectorImage<PixelType> ImageType;
diff --git a/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx b/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
index beebc71c1231462c0535364c697f48eab7e090c4..91f728949ad2065b9788f7ee83f2da0b14ca72d0 100644
--- a/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbMatrixTransposeMatrixImageFilter.cxx
@@ -49,8 +49,7 @@ int otbMatrixTransposeMatrixImageFilter(int argc, char * argv[])
   reader1->SetFileName(infname1);
   reader2->SetFileName(infname2);
 
-  // filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(200);
   filter->SetFirstInput(reader1->GetOutput());
   filter->SetSecondInput(reader2->GetOutput());
   filter->SetUsePadFirstInput(true);
diff --git a/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
index 2987a0f63604e0d6c49050e4f7a50c7fef9babd6..842fde27ecac9a100baad9058c6ea2471932672c 100644
--- a/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingInnerProductVectorImageFilter.cxx
@@ -39,8 +39,7 @@ int otbStreamingInnerProductVectorImageFilter(int argc, char* argv[])
 
   // Instantiation object
   FilterType::Pointer filter = FilterType::New();
-
-  filter->GetStreamer()->SetNumberOfStreamDivisions(10);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(10);
   filter->SetCenterData(centerdata);
   filter->SetInput(reader->GetOutput());
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
index 0a4493c8306a063c2fb731fcc211a1684372a1a9..8cb67d368012f70209198445bf2ddf1dc34319c2 100644
--- a/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingMinMaxImageFilter.cxx
@@ -42,8 +42,7 @@ int otbStreamingMinMaxImageFilter(int argc, char * argv[])
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
 
-  //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(200);
   filter->SetInput(reader->GetOutput());
   otb::StandardFilterWatcher watcher(filter, "Min Max Computation");
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
index 778df22c3a34f2eddc7ae02ed10113fb4bdd8985..d114e5d7a0d89ecd86b1d70033843bdbd0850126 100644
--- a/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingMinMaxVectorImageFilter.cxx
@@ -42,8 +42,7 @@ int otbStreamingMinMaxVectorImageFilter(int argc, char * argv[])
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
 
-  //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(200);
   filter->SetInput(reader->GetOutput());
   otb::StandardFilterWatcher watcher(filter, "Min Max Computation");
   filter->Update();
diff --git a/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
index adb2fc6c71399e1afc7f9dd2c4d40aa702d292a5..474097031e76b937fca9336ec1b2084ea68e249a 100644
--- a/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingStatisticsImageFilter.cxx
@@ -42,8 +42,7 @@ int otbStreamingStatisticsImageFilter(int argc, char * argv[])
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
 
-  //filter->GetStreamer()->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(200);
   filter->SetInput(reader->GetOutput());
   filter->Update();
 
diff --git a/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx b/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
index e0c312c80be531fb50907cce675f0ec7d0bbd90a..6ff493c558e7fa82c7b61fafb3d4675028808e0a 100644
--- a/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
+++ b/Testing/Code/BasicFilters/otbStreamingStatisticsVectorImageFilter.cxx
@@ -41,8 +41,7 @@ int otbStreamingStatisticsVectorImageFilter(int argc, char * argv[])
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
 
-  //filter->SetStreamingMode(otb::SET_NUMBER_OF_STREAM_DIVISIONS);
-  filter->GetStreamer()->SetNumberOfStreamDivisions(200);
+  filter->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(200);
   filter->SetInput(reader->GetOutput());
   filter->Update();
 
diff --git a/Testing/Code/Common/CMakeLists.txt b/Testing/Code/Common/CMakeLists.txt
index a598f4ed523f02bf5972055c2e6eaaef5588f577..ef1cf514ef8833f72f36486c0297351017271db5 100644
--- a/Testing/Code/Common/CMakeLists.txt
+++ b/Testing/Code/Common/CMakeLists.txt
@@ -736,6 +736,19 @@ ADD_TEST(coTvImageRegionTileMapSplitter ${COMMON_TESTS8}
         ${TEMP}/coImageRegionTileMapSplitter.txt
 )
 
+# -------------  otb::ImageRegionSquareTileSplitter ----------------------------
+ADD_TEST(coTuImageRegionSquareTileSplitterNew ${COMMON_TESTS8}
+         otbImageRegionSquareTileSplitterNew
+)
+
+ADD_TEST(coTvImageRegionSquareTileSplitter ${COMMON_TESTS8}
+    --compare-ascii ${NOTOL}
+        ${BASELINE_FILES}/coImageRegionSquareTileSplitter.txt
+        ${TEMP}/coImageRegionSquareTileSplitter.txt
+    otbImageRegionSquareTileSplitter
+        ${TEMP}/coImageRegionSquareTileSplitter.txt
+)
+
 # -------------  otb::ImageOfVectorsToMonoChannelExtractROI ----------------------------
 ADD_TEST(coTuImageOfVectorsToMonoChannelExtractROINew ${COMMON_TESTS8}
 otbImageOfVectorsToMonoChannelExtractROINew
@@ -1103,6 +1116,7 @@ otbQuickLookImageGeneratorNew.cxx
 otbQuickLookImageGenerator.cxx
 otbImageRegionTileMapSplitterNew.cxx
 otbImageRegionTileMapSplitter.cxx
+otbImageRegionSquareTileSplitter.cxx
 otbImageOfVectorsToMonoChannelExtractROINew.cxx
 otbImageOfVectorsToMonoChannelExtractROI.cxx
 otbImageRegionNonUniformMultidimensionalSplitterNew.cxx
diff --git a/Testing/Code/Common/otbCommonTests8.cxx b/Testing/Code/Common/otbCommonTests8.cxx
index 63e946336f54ae8d97a12ce41cfe3478225f0214..c948600503a217f1a6f89e33618659d644aab84a 100644
--- a/Testing/Code/Common/otbCommonTests8.cxx
+++ b/Testing/Code/Common/otbCommonTests8.cxx
@@ -30,6 +30,8 @@ void RegisterTests()
   REGISTER_TEST(otbQuickLookImageGenerator);
   REGISTER_TEST(otbImageRegionTileMapSplitterNew);
   REGISTER_TEST(otbImageRegionTileMapSplitter);
+  REGISTER_TEST(otbImageRegionSquareTileSplitterNew);
+  REGISTER_TEST(otbImageRegionSquareTileSplitter);
   REGISTER_TEST(otbImageOfVectorsToMonoChannelExtractROINew);
   REGISTER_TEST(otbImageOfVectorsToMonoChannelExtractROI);
   REGISTER_TEST(otbImageRegionNonUniformMultidimensionalSplitterNew);
diff --git a/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx b/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..89c790ebca52e0ceb456886d77d74b2a98bd1460
--- /dev/null
+++ b/Testing/Code/Common/otbImageRegionSquareTileSplitter.cxx
@@ -0,0 +1,146 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#include "otbImageRegionSquareTileSplitter.h"
+#include <fstream>
+
+const int Dimension = 2;
+typedef otb::ImageRegionSquareTileSplitter<Dimension> SquareTileSplitterType;
+typedef SquareTileSplitterType::IndexType                       IndexType;
+typedef SquareTileSplitterType::SizeType                        SizeType;
+typedef SquareTileSplitterType::RegionType                      RegionType;
+
+
+int otbImageRegionSquareTileSplitterNew(int argc, char * argv[])
+{
+  SquareTileSplitterType::Pointer splitter = SquareTileSplitterType::New();
+
+  std::cout << splitter << std::endl;
+
+  return EXIT_SUCCESS;
+}
+
+int TestSplitter(const RegionType& region, unsigned int PixelSize, unsigned int MaxTileSize, std::ostream& os)
+{
+  os << "----------------------------------" << std::endl;
+  os << "Region    : " << region << std::endl;
+  os << "PixelSize : " << PixelSize << std::endl;
+  os << "MaxTileSize  : " << MaxTileSize << std::endl;
+
+  SquareTileSplitterType::Pointer splitter;
+  splitter = SquareTileSplitterType::New();
+
+  unsigned int requestedNbSplits = region.GetNumberOfPixels() * PixelSize / MaxTileSize;
+  if (requestedNbSplits == 0)
+    requestedNbSplits = 1;
+  os << "Requested Number of splits  : " << requestedNbSplits << std::endl;
+
+  const unsigned int nbSplits = splitter->GetNumberOfSplits(region, requestedNbSplits);
+  os << "Actual Number of splits  : " << nbSplits << std::endl;
+
+
+  RegionType split;
+
+  // First split :
+  split = splitter->GetSplit(0, nbSplits, region);
+  os << "First Split : " << split
+     << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+
+  if (nbSplits > 1)
+    {
+    // Second split :
+    split = splitter->GetSplit(1, nbSplits, region);
+    os << "Second Split : " << split
+       << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+    }
+
+  if (nbSplits > 2)
+    {
+    // Last split :
+    split = splitter->GetSplit(nbSplits - 1, nbSplits, region);
+    os << "Last Split : " << split
+       << "(" << split.GetNumberOfPixels() * PixelSize << " bytes)" << std::endl;
+    }
+
+  return EXIT_SUCCESS;
+}
+
+
+int otbImageRegionSquareTileSplitter(int argc, char * argv[])
+{
+  std::ofstream outfile(argv[1]);
+  RegionType region;
+
+  // Test with a 0-based indexed region
+  region.SetIndex(0, 0);
+  region.SetIndex(1, 0);
+  region.SetSize(0, 1024);
+  region.SetSize(1, 1024);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a shifted region
+  region.SetIndex(0, 42);
+  region.SetIndex(1, 42);
+  region.SetSize(0, 1000);
+  region.SetSize(1, 1000);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a negative shift
+  region.SetIndex(0, -42);
+  region.SetIndex(1, -42);
+  region.SetSize(0, 1000);
+  region.SetSize(1, 1000);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a reduced size
+  region.SetIndex(0, 0);
+  region.SetIndex(1, 0);
+  region.SetSize(0, 1);
+  region.SetSize(1, 1);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  // Test with a reduced size, shifted
+  region.SetIndex(0, 42);
+  region.SetIndex(1, 42);
+  region.SetSize(0, 1);
+  region.SetSize(1, 1);
+  TestSplitter(region, 1, 128, outfile);
+  TestSplitter(region, 1, 512*512, outfile);
+  TestSplitter(region, 2, 512*512, outfile);
+  TestSplitter(region, 4, 512*512, outfile);
+  TestSplitter(region, 8, 512*512, outfile);
+
+  outfile.close();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/Common/otbQuickLookImageGenerator.cxx b/Testing/Code/Common/otbQuickLookImageGenerator.cxx
index 071f7fd5c642a1bccebd3e308f9f994181a34261..8e86c247de19a0801e2741ae603c9c1805a68608 100644
--- a/Testing/Code/Common/otbQuickLookImageGenerator.cxx
+++ b/Testing/Code/Common/otbQuickLookImageGenerator.cxx
@@ -49,6 +49,8 @@ int otbQuickLookImageGenerator(int argc, char* argv[])
   filter->SetMaximumKernelWidth(atoi(argv[6]));
   filter->UseImageSpacing(atoi(argv[7]));
 
+  filter->Update();
+
   writer->SetInput(filter->GetOutput());
   writer->SetFileName(outputFileName);
 
diff --git a/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
index d6576ab6e6be1de99c0fdb18cfc6ae756c807d08..6c9733dadd957382625aba51c521c9e133aae49b 100644
--- a/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbImageFileWriterTestWithoutInput.cxx
@@ -70,9 +70,6 @@ int otbImageScalarFileWriterTestWithoutInputGeneric(int argc, char* argv[])
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
-  ImagePixelType pixVal;
-
   while (!it.IsAtEnd())
     {
     it.Set(static_cast<PixelType> (size[0] * it.GetIndex()[1] + it.GetIndex()[0]));
diff --git a/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
index 372218fe4c2692489c0d638f1ff19d39c30f8507..cff8ed3b03c25fbcfde335d591029c4d29b541c4 100644
--- a/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbImageStreamingFileWriterTestWithoutInput.cxx
@@ -71,9 +71,6 @@ int otbImageScalarStreamingFileWriterTestWithoutInputGeneric(int argc, char* arg
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
-  ImagePixelType pixVal;
-
   while (!it.IsAtEnd())
     {
     it.Set(static_cast<PixelType> (size[0] * it.GetIndex()[1] + it.GetIndex()[0]));
diff --git a/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
index fbb4b31b2992fd0911f2ff9ab669c934721448e4..00ce431586e39b497718303d0fcc25d1c691d5b6 100644
--- a/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbVectorImageFileWriterTestWithoutInput.cxx
@@ -84,7 +84,6 @@ int otbVectorImageFileWriterScalarTestWithoutInputGeneric(int argc, char* argv[]
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
@@ -179,7 +178,6 @@ int otbVectorImageFileWriterComplexTestWithoutInputGeneric(int argc, char* argv[
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
diff --git a/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx b/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
index b5768ec8717bca133d584a2605f5cb3da1750502..023d3c6adb4941ae625c5d63d45370e3f3bc1ba5 100644
--- a/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
+++ b/Testing/Code/IO/otbVectorImageStreamingFileWriterTestWithoutInput.cxx
@@ -84,7 +84,6 @@ int otbVectorImageStreamingFileWriterScalarTestWithoutInputGeneric(int argc, cha
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
@@ -105,7 +104,6 @@ int otbVectorImageStreamingFileWriterScalarTestWithoutInputGeneric(int argc, cha
   writer->SetInput(image);
   writer->Update();
 
-
   return EXIT_SUCCESS;
 }
 
@@ -180,7 +178,6 @@ int otbVectorImageStreamingFileWriterComplexTestWithoutInputGeneric(int argc, ch
   IteratorType it(image, image->GetLargestPossibleRegion());
   it.GoToBegin();
 
-  double val = 0.;
   ImagePixelType pixVal;
   pixVal.SetSize(atoi(argv[3]));
 
diff --git a/Testing/Code/ObjectDetection/otbDescriptorsListSampleGenerator.cxx b/Testing/Code/ObjectDetection/otbDescriptorsListSampleGenerator.cxx
index e52c587fc6da2f835a318a49af06f379b3915c7e..c4a7b9af956898cf608886499a3d2040dc6ccd92 100644
--- a/Testing/Code/ObjectDetection/otbDescriptorsListSampleGenerator.cxx
+++ b/Testing/Code/ObjectDetection/otbDescriptorsListSampleGenerator.cxx
@@ -157,15 +157,7 @@ int otbDescriptorsListSampleGenerator(int argc, char* argv[])
   descriptorsGenerator->SetDescriptorsFunction(descriptorsFunction.GetPointer());
   descriptorsGenerator->SetNeighborhoodRadius(neighborhood);
 
-  if (streaming == 0)
-    {
-    descriptorsGenerator->GetStreamer()->SetNumberOfStreamDivisions(1);
-    }
-  else
-    {
-    descriptorsGenerator->GetStreamer()->SetNumberOfStreamDivisions(streaming);
-    }
-
+  descriptorsGenerator->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(streaming);
   descriptorsGenerator->Update();
 
 
@@ -240,16 +232,7 @@ int otbDescriptorsSVMModelCreation(int argc, char* argv[])
   descriptorsGenerator->SetSamplesLocations(vectorDataReader->GetOutput());
   descriptorsGenerator->SetDescriptorsFunction(descriptorsFunction.GetPointer());
   descriptorsGenerator->SetNeighborhoodRadius(5);
-
-  if (streaming == 0)
-    {
-    descriptorsGenerator->GetStreamer()->SetNumberOfStreamDivisions(1);
-    }
-  else
-    {
-    descriptorsGenerator->GetStreamer()->SetNumberOfStreamDivisions(streaming);
-    }
-
+  descriptorsGenerator->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(streaming);
   descriptorsGenerator->Update();
 
   // Normalize the samples
diff --git a/Testing/Code/ObjectDetection/otbObjectDetectionClassifier.cxx b/Testing/Code/ObjectDetection/otbObjectDetectionClassifier.cxx
index fe3846df055eec4a684eaf7f6594ad4f6f2b7004..e394c2ea2b8c1114090f54b02b368c02a62f4cb9 100644
--- a/Testing/Code/ObjectDetection/otbObjectDetectionClassifier.cxx
+++ b/Testing/Code/ObjectDetection/otbObjectDetectionClassifier.cxx
@@ -135,15 +135,8 @@ int otbObjectDetectionClassifier(int argc, char* argv[])
   classifier->SetShifts(statisticsReader->GetStatisticVectorByName("mean"));
   classifier->SetScales(statisticsReader->GetStatisticVectorByName("stddev"));
 
-  if (streaming == 0)
-    {
-    classifier->GetStreamer()->SetNumberOfStreamDivisions(1);
-    }
-  else
-    {
-    classifier->GetStreamer()->SetNumberOfStreamDivisions(streaming);
-    }
-
+  // 0 means no streaming
+  classifier->GetStreamer()->GetStreamingManager()->SetStrippedNumberOfLinesStreamingMode(streaming);
   classifier->Update();
 
   std::vector<ObjectDetectionClassifierType::PointType> points;
diff --git a/Testing/Code/Projections/CMakeLists.txt b/Testing/Code/Projections/CMakeLists.txt
index 7b94e96cfdcadda6f49a1f88b1498dfcc33336ac..c2d6ebdaf1d3bdcf2c5daf7f0fe4e28ce4fb6c24 100644
--- a/Testing/Code/Projections/CMakeLists.txt
+++ b/Testing/Code/Projections/CMakeLists.txt
@@ -842,6 +842,20 @@ ADD_TEST(prTvGenericRSTransformFromImage ${PROJECTIONS_TESTS3}
 	       otbGenericRSTransformFromImage
 	       ${INPUTDATA}/WithoutProjRefWithKeywordlist.tif)
 
+IF(OTB_DATA_USE_LARGEINPUT)
+ADD_TEST(prTvGenericRSTransformQuickbirdToulouseGeodesicPointChecking ${PROJECTIONS_TESTS3}
+otbGenericRSTransformImageAndMNTToWGS84ConversionChecking
+${LARGEINPUT}/QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF
+${INPUTDATA}/DEM/srtm_directory/
+16271 15647 # IGN reference point in front of st sernin church pointed in image
+1.48353 43.55968 # IGN reference point lon/lat
+192.205 # IGN reference point elevation (prec < 10 cm)
+5
+0.00001
+)
+
+ENDIF(OTB_DATA_USE_LARGEINPUT)
+
 ADD_TEST(prTuVectorDataProjectionFilterNew ${PROJECTIONS_TESTS3}  otbVectorDataProjectionFilterNew )
 
 #test points
diff --git a/Testing/Code/Projections/otbGenericRSTransformFromImage.cxx b/Testing/Code/Projections/otbGenericRSTransformFromImage.cxx
index 415d40aefd1fec2b73dfabd8e497cdbacd9c4ba5..2386cea022af4756664f8cff3b93cd4eb1db524c 100644
--- a/Testing/Code/Projections/otbGenericRSTransformFromImage.cxx
+++ b/Testing/Code/Projections/otbGenericRSTransformFromImage.cxx
@@ -24,11 +24,14 @@
 #include "otbGenericRSTransform.h"
 #include <ogr_spatialref.h>
 #include <fstream>
+#include "itkEuclideanDistance.h"
+
 
 typedef otb::VectorImage<double, 2>       ImageType;
 typedef otb::ImageFileReader<ImageType>   ReaderType;
 typedef otb::GenericRSTransform<>         TransformType;
 typedef TransformType::InputPointType     PointType;
+typedef itk::Statistics::EuclideanDistance<ImageType::PointType> DistanceType;
 
 int otbGenericRSTransformFromImage(int argc, char* argv[])
 {
@@ -64,3 +67,125 @@ int otbGenericRSTransformFromImage(int argc, char* argv[])
 
   return EXIT_SUCCESS;
 }
+
+int otbGenericRSTransformImageAndMNTToWGS84ConversionChecking(int argc, char* argv[])
+{
+  std::string infname = argv[1];
+  std::string demdir = argv[2];
+  
+  ImageType::PointType refImgPt, refGeoPt, estimatedImgPt, estimatedGeoPt;
+  refImgPt[0] = atof(argv[3]);
+  refImgPt[1] = atof(argv[4]);
+  refGeoPt[0] = atof(argv[5]);
+  refGeoPt[1] = atof(argv[6]);
+  double refHeight = atof(argv[7]);
+  double imgTol = atof(argv[8]);
+  double geoTol = atof(argv[9]);
+
+  bool pass = true;
+
+// Reader
+  ReaderType::Pointer reader = ReaderType::New();
+  reader->SetFileName(argv[1]);
+  reader->UpdateOutputInformation();
+  
+  // Build wgs ref
+  OGRSpatialReference oSRS;
+  oSRS.SetWellKnownGeogCS("WGS84");
+  char * wgsRef = NULL;
+  oSRS.exportToWkt(&wgsRef);
+
+  DistanceType::Pointer distance = DistanceType::New();
+
+  // Instanciate WGS->Image transform
+  TransformType::Pointer wgs2img = TransformType::New();
+  wgs2img->SetInputProjectionRef(wgsRef);
+  wgs2img->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef());
+  wgs2img->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist());
+  wgs2img->SetDEMDirectory(argv[2]);
+  wgs2img->InstanciateTransform();
+
+  // Instanciate Image->WGS transform
+  TransformType::Pointer img2wgs = TransformType::New();
+  img2wgs->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef());
+  img2wgs->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist());
+  img2wgs->SetOutputProjectionRef(wgsRef);
+  img2wgs->SetDEMDirectory(argv[2]);
+  img2wgs->InstanciateTransform();
+
+  std::cout<< std::setprecision(8) << std::endl;
+
+  std::cout<<"References: "<<std::endl;
+  std::cout<<"Geo (wgs84): "<<refGeoPt<<std::endl;
+  std::cout<<"Image: "<<refImgPt<<std::endl;
+  std::cout<<"Height: "<<refHeight<<std::endl;
+
+  std::cout<<"Using elevation from "<<demdir<<std::endl;
+  
+  estimatedImgPt = wgs2img->TransformPoint(refGeoPt);
+  estimatedGeoPt = img2wgs->TransformPoint(refImgPt);
+
+  std::cout<<"Forward(refImg): "<<refImgPt<<" -> " << estimatedGeoPt<<std::endl;
+  std::cout<<"Inverse(refGeo): "<<refGeoPt<<" -> "<< estimatedImgPt <<std::endl;
+
+  double imgRes = distance->Evaluate(refImgPt, estimatedImgPt);
+  double geoRes = distance->Evaluate(refGeoPt, estimatedGeoPt);
+
+  if(imgRes > imgTol)
+    {
+    pass = false;
+    std::cerr<<"Image residual is too high: "<<imgRes<<std::endl;
+    }
+
+  if(geoRes > geoTol)
+    {
+    pass = false;
+    std::cerr<<"Geographic (WGS84) residual is too high: "<<geoRes<<std::endl;
+    }
+
+  std::cout<<"Using reference elevation: "<<std::endl;
+  wgs2img = TransformType::New();
+  wgs2img->SetInputProjectionRef(wgsRef);
+  wgs2img->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef());
+  wgs2img->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist());
+  wgs2img->SetAverageElevation(refHeight);
+  wgs2img->InstanciateTransform();
+
+  img2wgs = TransformType::New();
+  img2wgs->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef());
+  img2wgs->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist());
+  img2wgs->SetOutputProjectionRef(wgsRef);
+  img2wgs->SetAverageElevation(refHeight);
+  img2wgs->InstanciateTransform();
+
+  estimatedImgPt = wgs2img->TransformPoint(refGeoPt);
+  estimatedGeoPt = img2wgs->TransformPoint(refImgPt);
+
+  std::cout<<"Forward(refImg): "<<refImgPt<<" -> " << estimatedGeoPt<<std::endl;
+  std::cout<<"Inverse(refGeo): "<<refGeoPt<<" -> "<< estimatedImgPt <<std::endl;
+  
+  imgRes = distance->Evaluate(refImgPt, estimatedImgPt);
+  geoRes = distance->Evaluate(refGeoPt, estimatedGeoPt);
+  
+  if(imgRes > imgTol)
+    {
+    pass = false;
+    std::cerr<<"Image residual is too high: "<<imgRes<<std::endl;
+    }
+
+  if(geoRes > geoTol)
+    {
+    pass = false;
+    std::cerr<<"Geographic (WGS84) residual is too high: "<<geoRes<<std::endl;
+    }
+  
+  if(pass)
+    {
+    return EXIT_SUCCESS;
+    }
+  else
+    {
+    std::cerr<<"There were imprecise results."<<std::endl;
+    return EXIT_FAILURE;
+    }
+}
diff --git a/Testing/Code/Projections/otbProjectionsTests3.cxx b/Testing/Code/Projections/otbProjectionsTests3.cxx
index cfac112ba3e9ca38fab26036109da7b343ddca08..418a62ad10633f6427417c0bdad453eb32c3b770 100644
--- a/Testing/Code/Projections/otbProjectionsTests3.cxx
+++ b/Testing/Code/Projections/otbProjectionsTests3.cxx
@@ -34,6 +34,7 @@ void RegisterTests()
   REGISTER_TEST(otbGenericRSTransform);
   REGISTER_TEST(otbGenericRSTransformWithSRID);
   REGISTER_TEST(otbGenericRSTransformFromImage);
+  REGISTER_TEST(otbGenericRSTransformImageAndMNTToWGS84ConversionChecking);
   REGISTER_TEST(otbVectorDataProjectionFilterNew);
   REGISTER_TEST(otbVectorDataProjectionFilter);
   REGISTER_TEST(otbVectorDataProjectionFilterFromMapToSensor);
diff --git a/Testing/Code/SARPolarimetry/CMakeLists.txt b/Testing/Code/SARPolarimetry/CMakeLists.txt
index 654b91338eab7045ea798de4dbf7a08b944173ee..c291daf45d2e66c98f55facf982901265abd93a8 100644
--- a/Testing/Code/SARPolarimetry/CMakeLists.txt
+++ b/Testing/Code/SARPolarimetry/CMakeLists.txt
@@ -373,10 +373,6 @@ ADD_TEST(saTvMuellerToCovarianceImageFilter ${SARPOLARIMETRY_TESTS2}
         ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
         ${TEMP}/saTvMuellerToMLCImageFilter.tif
 	)
-# Hermitian eigen analysis class
-ADD_TEST(saTvHermitianEigenAnalysisTest ${SARPOLARIMETRY_TESTS2}
-		otbHermitianEigenAnalysisTest
-)
 
 # Polarimetric Data
 ADD_TEST(saTuPolarimetricDataNew ${SARPOLARIMETRY_TESTS2}
@@ -430,7 +426,6 @@ otbMuellerToPolarisationDegreeAndPowerImageFilterNew.cxx
 otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx
 otbMuellerToCovarianceImageFilterNew.cxx
 otbMuellerToCovarianceImageFilter.cxx
-otbHermitianEigenAnalysisTest.cxx
 otbPolarimetricData.cxx
 )
 
diff --git a/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx b/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
index d21ca4c3ddde6269fadc9742e7d8606c7d56ee1b..6ef54da7429f59bcfa0037dba639394e1f16b906 100644
--- a/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
+++ b/Testing/Code/SARPolarimetry/otbHermitianEigenAnalysisTest.cxx
@@ -26,6 +26,8 @@
 #include "otbVectorImage.h"
 #include "otbHermitianEigenAnalysis.h"
 #include "itkVariableLengthVector.h"
+#include "vnl/algo/vnl_complex_eigensystem.h"
+#include <complex>
 
 
 int otbHermitianEigenAnalysisTest(int argc, char * argv[])
@@ -37,6 +39,7 @@ int otbHermitianEigenAnalysisTest(int argc, char * argv[])
   typedef otb::HermitianEigenAnalysis<MatrixType, EigenvalueType, EigenMatrixType> FilterType;
 
   EigenMatrixType resEigVal;
+
   itk::Vector<float, 6> temp;
   temp[0] = 0.162793;
   temp[1] = -0.432753;
@@ -115,5 +118,43 @@ int otbHermitianEigenAnalysisTest(int argc, char * argv[])
     return EXIT_FAILURE;
   }
 
+  std::cout<<"Values: "<<vect<<std::endl;
+  std::cout<<"Vectors: "<<eigVal<<std::endl;
+
+
+  typedef std::complex<double> ComplexType;
+  vnl_matrix<ComplexType> vnlMat(3, 3, 0);
+  vnlMat[0][0] = ComplexType(0., 0.);
+  vnlMat[0][1] = ComplexType(1.5, 2.);
+  vnlMat[0][2] = ComplexType(2.5, 3.);
+  vnlMat[1][0] = ComplexType(1.5, -2.);
+  vnlMat[1][1] = ComplexType(0.5, 0.);
+  vnlMat[1][2] = ComplexType(3.5, 4.);
+  vnlMat[2][0] = ComplexType(2.5, -3.);
+  vnlMat[2][1] = ComplexType(3.5, -4.);
+  vnlMat[2][2] = ComplexType(1., 0.);
+
+  std::cout<<"Matrix:: "<<std::endl;
+  vnlMat.print(std::cout);
+
+  vnl_complex_eigensystem syst(vnlMat, true, true);
+
+  vnl_matrix< ComplexType > pm = syst.L;
+ std::cout<<"Left:: "<<std::endl;
+  pm.print(std::cout);
+  std::cout<<"Right:: "<<std::endl;
+
+
+  pm = syst.R;
+  pm.print(std::cout);
+  std::cout<<"W:: "<<std::endl;
+  vnl_vector< ComplexType > lol = syst.W;
+
+  for(unsigned i=0; i<lol.size(); i++)
+  {
+    std::cout<<"  "<<lol[i];
+  }
+  std::cout<<std::endl;
+
   return EXIT_SUCCESS;
 }
diff --git a/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx b/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
index ed970d31910f298a5b56d58a236f42131a5effd2..79c312c5cbeaf8059a450909ebb6e24aa2c14a17 100644
--- a/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
+++ b/Testing/Code/SARPolarimetry/otbReciprocalHAlphaImageFilter.cxx
@@ -89,9 +89,10 @@ int otbReciprocalHAlphaImageFilter(int argc, char * argv[])
 
   PerBandMeanFilterType::Pointer perBandMeanFilter = PerBandMeanFilterType::New();
   perBandMeanFilter->SetInput(sinclairToCoherencyFilter->GetOutput());
-
+ 
   FilterType::Pointer filter = FilterType::New();
   filter->SetInput(perBandMeanFilter->GetOutput());
+  filter->SetNumberOfThreads(1);
 
   ExtractType::Pointer extract = ExtractType::New();
   extract->SetInput(filter->GetOutput());
@@ -102,6 +103,8 @@ int otbReciprocalHAlphaImageFilter(int argc, char * argv[])
 
   writer->SetFileName(outputFilename);
   writer->SetInput(extract->GetOutput());
+  writer->SetNumberOfThreads(1);
+writer->SetNumberOfStreamDivisions(1);
   writer->Update();
 
   return EXIT_SUCCESS;
diff --git a/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx b/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
index bdda5c32405263bb9f8f4d1bf94de291a20a6d3d..97a622061338743fcbf26f51075f6c820ca6d614 100644
--- a/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
+++ b/Testing/Code/SARPolarimetry/otbSARPolarimetryTests2.cxx
@@ -42,7 +42,6 @@ void RegisterTests()
   REGISTER_TEST(otbMuellerToPolarisationDegreeAndPowerImageFilter);
   REGISTER_TEST(otbMuellerToCovarianceImageFilterNew);
   REGISTER_TEST(otbMuellerToCovarianceImageFilter);
-  REGISTER_TEST(otbHermitianEigenAnalysisTest);
   REGISTER_TEST(otbPolarimetricDataNew);
   REGISTER_TEST(otbPolarimetricDataTest);
 }
diff --git a/Testing/Code/Visualization/otbImageLayerScalar.cxx b/Testing/Code/Visualization/otbImageLayerScalar.cxx
index d14ac1518b77547d8c0632cd6bc211dbe82fe467..515e5e8dd2209a42cf008fc5bc35693202113bc7 100644
--- a/Testing/Code/Visualization/otbImageLayerScalar.cxx
+++ b/Testing/Code/Visualization/otbImageLayerScalar.cxx
@@ -53,6 +53,7 @@ int otbImageLayerScalar(int argc, char * argv[])
   // Quicklook
   shrinker->SetInput(reader->GetOutput());
   shrinker->SetShrinkFactor(ssrate);
+  shrinker->Update();
 
   // new layer
   LayerType::Pointer layer = LayerType::New();
diff --git a/Testing/Code/Visualization/otbImageLayerVector.cxx b/Testing/Code/Visualization/otbImageLayerVector.cxx
index 04ab0b7ca10fd739ef33b9336cdf88fb10a9ad8d..94e46a11af24b5373a0fc062b236dc7152119f13 100644
--- a/Testing/Code/Visualization/otbImageLayerVector.cxx
+++ b/Testing/Code/Visualization/otbImageLayerVector.cxx
@@ -65,6 +65,7 @@ int otbImageLayerVector(int argc, char * argv[])
   // Quicklook
   shrinker->SetInput(reader->GetOutput());
   shrinker->SetShrinkFactor(ssrate);
+  shrinker->Update();
 
   // new layer
   LayerType::Pointer layer = LayerType::New();
diff --git a/otbConfigure.h.in b/otbConfigure.h.in
index ab1f7d425524181d86d0022f76f02bbb8822b9be..29e21a97c10853e99033fb7e2de510ead5f3b417 100644
--- a/otbConfigure.h.in
+++ b/otbConfigure.h.in
@@ -1,5 +1,5 @@
 /*
- * here is where system comupted values get stored these values should only
+ * here is where system computed values get stored these values should only
  * change when the target compile platform changes
  */