diff --git a/Examples/Projections/test/CMakeLists.txt b/Examples/Projections/test/CMakeLists.txt
index d1ad300506a769e19cf24ed9747982cd7a4c5048..61c9985d0c46901bb172ebd19613d7871e78a3cd 100644
--- a/Examples/Projections/test/CMakeLists.txt
+++ b/Examples/Projections/test/CMakeLists.txt
@@ -48,7 +48,7 @@ otb_add_test(NAME prTeVectorDataProjectionExampleTest COMMAND ${OTB_TEST_DRIVER}
     ${BASELINE}/vectorDataProjectionExample.shp
     ${TEMP}/vectorDataProjectionExample.shp
   Execute $<TARGET_FILE:VectorDataProjectionExample>
-    ${INPUTDATA}/Capitole-Shadows.kml
+    ${OTB_DATA_ROOT}/Input/Capitole-Shadows.kml
     LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF}
     ${TEMP}/vectorDataProjectionExample.shp
 )
@@ -58,7 +58,7 @@ otb_add_test(NAME prTeGeometriesProjectionTest COMMAND ${OTB_TEST_DRIVER}
     ${BASELINE}/geometriesProjectionExample.shp
     ${TEMP}/geometriesProjectionExample.shp
   Execute $<TARGET_FILE:GeometriesProjectionExample>
-    ${INPUTDATA}/Capitole-Shadows.shp
+    ${OTB_DATA_ROOT}/Input/Capitole-Shadows.shp
     LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF}
     ${TEMP}/geometriesProjectionExample.shp
 )
diff --git a/Modules/Adapters/BoostAdapters/include/otbStringUtils.h b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b381c2285f028ea542933719f8ccaf66849fe89
--- /dev/null
+++ b/Modules/Adapters/BoostAdapters/include/otbStringUtils.h
@@ -0,0 +1,171 @@
+/*=========================================================================
+
+  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 otbStringUtils_h
+#define otbStringUtils_h
+
+#include <string>
+#include <vector>
+#include <cstdlib>
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
+
+namespace boost {
+
+/* I want raw performance and I don't want to use strtod, atoi at different
+* places. so here we are. */
+template<>
+inline int lexical_cast(const std::string& arg)
+{
+  char* stop;
+  int res = std::strtol( arg.c_str(), &stop, 10);
+    if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(int), typeid(std::string)));
+    return res;
+}
+
+template<>
+inline float lexical_cast(const std::string& arg)
+{
+    char* stop;
+    float res = std::strtof( arg.c_str(), &stop);
+    if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(float), typeid(std::string)));
+    return res;
+}
+
+template<>
+inline double lexical_cast(const std::string& arg)
+{
+    char* stop;
+    double res = std::strtod( arg.c_str(), &stop);
+    if ( *stop != 0 ) throw_exception(bad_lexical_cast(typeid(double), typeid(std::string)));
+    return res;
+}
+
+
+/* there could also be specialised vice-versa conversion below */
+// template<>
+// inline std::string lexical_cast(const int& arg)
+// {
+//     char buffer[20]; // large enough for arg < 2^200
+
+//     ltoa( arg, buffer, 10 );
+//     return std::string( buffer ); // RVO will take place here
+// }
+
+}//namespace boost
+
+
+namespace otb
+{
+namespace Utils
+{
+
+/**\ingroup Utils
+   * - convert a delimitter seperated string to std::vector of type T
+   * \tparam vec - std::vector of type T. Specialized boost::lexical_cast is used
+   * \tparam str - input string
+   * \tparam delims - delimitter space is default
+   * \t param T& ret - std::vector of type T
+   */
+
+template<typename T>
+void
+ConvertStringToVector(std::string const &str, T& ret, const char *  delims=" ")
+{
+  std::vector<std::string> splitted;
+
+  boost::split(splitted, str, boost::is_any_of(delims));
+
+//  split(str, delims, splitted);
+
+  for(size_t i = 0; i < splitted.size(); i++)
+    {
+    typename T::value_type value;
+    try
+      {
+      value = boost::lexical_cast<typename T::value_type> (splitted[i]);
+      }
+    catch (boost::bad_lexical_cast &)
+      {
+      std::cerr << "Error getting value" << value << "  at " << __FILE__ << ":" << __LINE__ << std::endl;
+      }
+
+    ret.push_back(value);
+    }
+}
+
+/*
+SplitStringToSingleKeyValue - split a given std::string of into key value based
+on given delimitter string. default delimitter is '='. If the string doesnot
+have a delimitter the key is set to input string and value is set to defValue.
+
+This function is templated over value type. It uses specialized
+boost::lexical_cast if the T is not of type std::string. only primitive types
+
+Arugments are:
+  str      - reference to input string of type std::string
+  key      - reference to std::string where key will be stored
+  value    - reference to T where value will be stored
+  defValue - default value if there is no delimitter found. (informally TRUE)
+  delims   - const std::string which contains the delimtter used. Default is '='
+  doTrim   - option to perform boost::trim() over key and values. Default is true.
+*/
+template<typename T>
+void SplitStringToSingleKeyValue(const std::string& str,
+                                 std::string& key, T& value, const T& defValue,
+                                 const std::string delims="=", bool doTrim=true)
+{
+  std::size_t pos = str.find(delims);
+  if (pos == std::string::npos)
+    {
+    key = str;
+    value = defValue;
+    }
+  key = str.substr(0, pos);
+
+  std::string value_ = str.substr(pos+delims.size(), str.size() - 1 );
+
+  //do optional trim
+  if(doTrim)
+    {
+    boost::trim_left(key);
+    boost::trim_right(value_);
+    }
+
+  if(typeid(value) != typeid(key))
+    {
+    try
+      {
+      value = boost::lexical_cast<T>(value_);
+      }
+    catch (boost::bad_lexical_cast &)
+      {
+      std::cerr << "Error getting value" << value_ << "  at " << __FILE__ << ":" << __LINE__ << std::endl;
+      }
+    }
+  else
+    {
+    value.swap(value_);
+    }
+}
+} // end namespace Utils
+} // end namespace otb
+
+#endif //otbStringUtils_h
diff --git a/Modules/Applications/AppImageUtils/app/CMakeLists.txt b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
index 82ef77a5887523595bdf30570c5bdebe3b3c5cdc..637eb926408db14daecc6cfd79401ada43a884a3 100644
--- a/Modules/Applications/AppImageUtils/app/CMakeLists.txt
+++ b/Modules/Applications/AppImageUtils/app/CMakeLists.txt
@@ -89,6 +89,6 @@ otb_create_application(
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
 
 otb_create_application(
-  NAME           NoDataMask
-  SOURCES        otbNoDataMask.cxx
+  NAME           ManageNoData
+  SOURCES        otbManageNoData.cxx
   LINK_LIBRARIES ${${otb-module}_LIBRARIES})
diff --git a/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2449029c861368d5d34121d875608b009e79a530
--- /dev/null
+++ b/Modules/Applications/AppImageUtils/app/otbManageNoData.cxx
@@ -0,0 +1,145 @@
+/*=========================================================================
+
+ 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 "otbWrapperApplication.h"
+#include "otbWrapperApplicationFactory.h"
+
+#include "otbImageToNoDataMaskFilter.h"
+#include "otbChangeNoDataValueFilter.h"
+
+namespace otb
+{
+namespace Wrapper
+{
+
+class ManageNoData : public Application
+{
+public:
+  /** Standard class typedefs. */
+  typedef ManageNoData                       Self;
+  typedef Application                   Superclass;
+  typedef itk::SmartPointer<Self>       Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
+
+  /** Standard macro */
+  itkNewMacro(Self);
+
+  itkTypeMacro(ManageNoData, otb::Application);
+
+  /** Filters typedef */
+  typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType,UInt8ImageType> FilterType;
+  typedef otb::ChangeNoDataValueFilter<FloatVectorImageType,FloatVectorImageType> ChangeNoDataFilterType;
+  
+private:
+  void DoInit()
+  {
+    SetName("ManageNoData");
+    SetDescription("Manage No-Data");
+    // Documentation
+    SetDocName("No Data management");
+    SetDocLongDescription("This application has two modes. The first allows to build a mask of no-data pixels from the no-data flags read from the image file. The second allows to update the change the no-data value of an image (pixels value and metadata). This last mode also allows to replace NaN in images with a proper no-data value. To do so, one should activate the NaN is no-data option.");
+    SetDocLimitations("None");
+    SetDocAuthors("OTB-Team");
+    SetDocSeeAlso("BanMath");
+    AddDocTag("Conversion");
+    AddDocTag("Image Dynamic");
+    AddDocTag(Tags::Manip);
+
+    AddParameter(ParameterType_InputImage,  "in",   "Input image");
+    SetParameterDescription("in", "Input image");
+
+    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
+    SetParameterDescription("out", "Output image");
+
+    AddParameter(ParameterType_Empty,"usenan", "Consider NaN as no-data");
+    SetParameterDescription("usenan","If active, the application will consider NaN as no-data values as well");
+    MandatoryOff("usenan");
+    DisableParameter("usenan");
+   
+    AddParameter(ParameterType_Choice,"mode","No-data handling mode");
+    SetParameterDescription("mode","Allows to choose between different no-data handling options");
+
+    AddChoice("mode.buildmask","Build a no-data Mask");
+    
+    AddParameter(ParameterType_Float,"mode.buildmask.inv","Inside Value");
+    SetParameterDescription("mode.buildmask.inv","Value given in the output mask to pixels that are not no data pixels");
+    SetDefaultParameterInt("mode.buildmask.inv",1);
+
+    AddParameter(ParameterType_Float,"mode.buildmask.outv","Outside Value");
+    SetParameterDescription("mode.buildmask.outv","Value given in the output mask to pixels that are no data pixels");
+    SetDefaultParameterInt("mode.buildmask.outv",0);
+
+    AddChoice("mode.changevalue","Change the no-data value");
+
+    AddParameter(ParameterType_Float,"mode.changevalue.newv","The new no-data value");
+    SetParameterDescription("mode.changevalue.newv","The new no-data value");
+    SetDefaultParameterInt("mode.changevalue.newv",0);
+
+    SetParameterString("mode","buildmask");
+    
+    AddRAMParameter();
+
+    // Doc example parameter settings
+    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
+    SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8");
+    SetDocExampleParameterValue("mode.buildmask.inv", "255");
+    SetDocExampleParameterValue("mode.buildmask.outv", "0");
+  }
+
+  void DoUpdateParameters()
+  {
+    // Nothing to do here for the parameters : all are independent
+  }
+
+
+ void DoExecute()
+  {
+    FloatVectorImageType::Pointer inputPtr = this->GetParameterImage("in");
+    
+    m_Filter = FilterType::New();
+    m_Filter->SetInsideValue(this->GetParameterFloat("mode.buildmask.inv"));
+    m_Filter->SetOutsideValue(this->GetParameterFloat("mode.buildmask.outv"));
+    m_Filter->SetNaNIsNoData(IsParameterEnabled("usenan"));
+    m_Filter->SetInput(inputPtr);
+
+    m_ChangeNoDataFilter = ChangeNoDataFilterType::New();
+    m_ChangeNoDataFilter->SetInput(inputPtr);
+    m_ChangeNoDataFilter->SetNaNIsNoData(IsParameterEnabled("usenan"));
+
+    std::vector<double> newNoData(inputPtr->GetNumberOfComponentsPerPixel(),GetParameterFloat("mode.changevalue.newv"));
+
+    m_ChangeNoDataFilter->SetNewNoDataValues(newNoData);
+    
+    if(GetParameterString("mode") == "buildmask")
+      {
+      SetParameterOutputImage("out",m_Filter->GetOutput());
+      }
+    else if(GetParameterString("mode") == "changevalue")
+      {
+      SetParameterOutputImage("out",m_ChangeNoDataFilter->GetOutput());
+      }
+  }
+
+  FilterType::Pointer m_Filter;
+  ChangeNoDataFilterType::Pointer m_ChangeNoDataFilter;
+};
+
+}
+}
+
+OTB_APPLICATION_EXPORT(otb::Wrapper::ManageNoData)
+
diff --git a/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx b/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx
deleted file mode 100644
index dd99a9a7949132a1bf64ab95684408b39cee873a..0000000000000000000000000000000000000000
--- a/Modules/Applications/AppImageUtils/app/otbNoDataMask.cxx
+++ /dev/null
@@ -1,107 +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.
-
- =========================================================================*/
-#include "otbWrapperApplication.h"
-#include "otbWrapperApplicationFactory.h"
-
-#include "otbImageToNoDataMaskFilter.h"
-
-namespace otb
-{
-namespace Wrapper
-{
-
-
-class NoDataMask : public Application
-{
-public:
-  /** Standard class typedefs. */
-  typedef NoDataMask                       Self;
-  typedef Application                   Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Standard macro */
-  itkNewMacro(Self);
-
-  itkTypeMacro(NoDataMask, otb::Application);
-
-  /** Filters typedef */
-  typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType,UInt8ImageType> FilterType;
-
-private:
-  void DoInit()
-  {
-    SetName("NoDataMask");
-    SetDescription("NoDataMask");
-    // Documentation
-    SetDocName("No Data Mask management");
-    SetDocLongDescription("This application builds a nodata mask from the no data flags found in metadata or from NaN pixels.");
-    SetDocLimitations("None");
-    SetDocAuthors("OTB-Team");
-    SetDocSeeAlso("BanMath");
-    AddDocTag("Conversion");
-    AddDocTag("Image Dynamic");
-    AddDocTag(Tags::Manip);
-
-    AddParameter(ParameterType_InputImage,  "in",   "Input image");
-    SetParameterDescription("in", "Input image");
-
-    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
-    SetParameterDescription("out", "Output image");
-
-    AddParameter(ParameterType_Int,"inv","Inside Value");
-    SetParameterDescription("inv","Value given in the output mask to pixels that are not no data pixels");
-    SetDefaultParameterInt("inv",1);
-
-    AddParameter(ParameterType_Int,"outv","Outside Value");
-    SetParameterDescription("outv","Value given in the output mask to pixels that are no data pixels");
-    SetDefaultParameterInt("outv",0);
-
-    AddRAMParameter();
-
-    // Doc example parameter settings
-    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
-    SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8");
-    SetDocExampleParameterValue("inv", "255");
-    SetDocExampleParameterValue("outv", "0");
-  }
-
-  void DoUpdateParameters()
-  {
-    // Nothing to do here for the parameters : all are independent
-  }
-
-
- void DoExecute()
-  {
-    m_Filter = FilterType::New();
-    m_Filter->SetInsideValue(this->GetParameterInt("inv"));
-    m_Filter->SetOutsideValue(this->GetParameterInt("outv"));
-    m_Filter->SetInput(this->GetParameterImage("in"));
-
-    SetParameterOutputImage("out",m_Filter->GetOutput());
-  }
-
-  FilterType::Pointer m_Filter;
-};
-
-}
-}
-
-OTB_APPLICATION_EXPORT(otb::Wrapper::NoDataMask)
-
diff --git a/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx b/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx
index 154c73b8c4805ade35f63410d841b2999b2fe751..9595466d47d0a1bb66768e6d241a8c26f8341f88 100644
--- a/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx
+++ b/Modules/Core/Common/include/otbImageRegionAdaptativeSplitter.txx
@@ -107,10 +107,14 @@ ImageRegionAdaptativeSplitter<VImageDimension>
   // Now we can handle the case where we have a tile hint and a
   // non-trivial requested number of splits
   SizeType tilesPerDim, splitsPerDim;
-
-  tilesPerDim[0] = (m_ImageRegion.GetSize()[0] + m_TileHint[0] -1) / m_TileHint[0];
-  tilesPerDim[1] = (m_ImageRegion.GetSize()[1] + m_TileHint[1] -1) / m_TileHint[1];
-
+  IndexType firstTileCovered;
+
+  // First, we need to get which tiles are covered by ROI
+  firstTileCovered[0] = m_ImageRegion.GetIndex()[0] / m_TileHint[0];
+  firstTileCovered[1] = m_ImageRegion.GetIndex()[1] / m_TileHint[1];
+  tilesPerDim[0] = (m_ImageRegion.GetIndex()[0] + m_ImageRegion.GetSize()[0] -1 + m_TileHint[0] -1) / m_TileHint[0] - firstTileCovered[0];
+  tilesPerDim[1] = (m_ImageRegion.GetIndex()[1] + m_ImageRegion.GetSize()[1] -1 + m_TileHint[1] -1) / m_TileHint[1] - firstTileCovered[1];
+  
   unsigned int totalTiles = tilesPerDim[0] * tilesPerDim[1];
 
   // In this case, we have to group input tiles
@@ -134,13 +138,14 @@ ImageRegionAdaptativeSplitter<VImageDimension>
       i = (i+1)%2;
       }
 
+   
     splitsPerDim[0] = tilesPerDim[0] / groupTiles[0];
+    splitsPerDim[1] = tilesPerDim[1] / groupTiles[1];
 
     // Handle the last small tile if any
     if(tilesPerDim[0] % groupTiles[0] > 0)
       splitsPerDim[0]++;
 
-    splitsPerDim[1] = tilesPerDim[1] / groupTiles[1];
     if(tilesPerDim[1] % groupTiles[1] > 0)
       splitsPerDim[1]++;
 
@@ -157,8 +162,8 @@ ImageRegionAdaptativeSplitter<VImageDimension>
         newSplitSize[0] = groupTiles[0] * m_TileHint[0];
         newSplitSize[1] = groupTiles[1] * m_TileHint[1];
 
-        newSplitIndex[0] = splitx * newSplitSize[0];
-        newSplitIndex[1] = splity * newSplitSize[1];
+        newSplitIndex[0] = firstTileCovered[0] * m_TileHint[0] + splitx * newSplitSize[0];
+        newSplitIndex[1] = firstTileCovered[1] * m_TileHint[1] + splity * newSplitSize[1];
 
         newSplit.SetIndex(newSplitIndex);
         newSplit.SetSize(newSplitSize);
@@ -208,8 +213,8 @@ ImageRegionAdaptativeSplitter<VImageDimension>
             RegionType newSplit;
             IndexType newSplitIndex;
 
-            newSplitIndex[0] = tilex * m_TileHint[0] + divx * splitSize[0];
-            newSplitIndex[1] = tiley * m_TileHint[1] + divy * splitSize[1];
+            newSplitIndex[0] = (tilex + firstTileCovered[0]) * m_TileHint[0] + divx * splitSize[0];
+            newSplitIndex[1] = (tiley + firstTileCovered[1]) * m_TileHint[1] + divy * splitSize[1];
 
             newSplit.SetIndex(newSplitIndex);
             newSplit.SetSize(splitSize);
diff --git a/Modules/Core/Common/test/CMakeLists.txt b/Modules/Core/Common/test/CMakeLists.txt
index e32118293bc838491f5be7754ed53d22c35699b3..40f89e72aeb1144f9fc5c7166c32aaef6d62870b 100644
--- a/Modules/Core/Common/test/CMakeLists.txt
+++ b/Modules/Core/Common/test/CMakeLists.txt
@@ -78,6 +78,24 @@ otb_add_test(NAME coTvImageRegionAdaptativeSplitterStripLargeStream COMMAND otbC
   ${TEMP}/coTvImageRegionAdaptativeSplitterStripLargeStreamOutput.txt
   )
 
+otb_add_test(NAME coTvImageRegionAdaptativeSplitterShiftedROILargeStream COMMAND otbCommonTestDriver
+  --compare-ascii ${NOTOL}
+  ${BASELINE_FILES}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt
+  ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt
+  otbImageRegionAdaptativeSplitter
+  1000 1000 4000 4000 2000 2000 5
+  ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROILargeStreamOutput.txt
+  )
+
+otb_add_test(NAME coTvImageRegionAdaptativeSplitterShiftedROISmallStream COMMAND otbCommonTestDriver
+  --compare-ascii ${NOTOL}
+  ${BASELINE_FILES}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt
+  ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt
+  otbImageRegionAdaptativeSplitter
+  1000 1000 4000 4000 2000 2000 10
+  ${TEMP}/coTvImageRegionAdaptativeSplitterShiftedROISmallStreamOutput.txt
+  )
+
 otb_add_test(NAME coTuRGBAPixelConverter COMMAND otbCommonTestDriver
   otbRGBAPixelConverterNew
   )
diff --git a/Modules/Core/ImageBase/include/otbNoDataHelper.h b/Modules/Core/ImageBase/include/otbNoDataHelper.h
deleted file mode 100644
index 16bfdc4cd85f916804b59d8c7ee05828d47e1897..0000000000000000000000000000000000000000
--- a/Modules/Core/ImageBase/include/otbNoDataHelper.h
+++ /dev/null
@@ -1,75 +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 __otbNoDataHelper_h
-#define __otbNoDataHelper_h
-#include <vector>
-#include <cassert>
-#include "vnl/vnl_math.h"
-#include <itkVariableLengthVector.h>
-
-namespace otb
-{
-/**
-* Test if the pixel corresponds to a no data pixel according to a
-* vector of no data flags, and a vector of no data values.
-* \param pixel The pixel to test
-* \param flags A vector of size > 1 containing a flag per band to
-* indicate if a no data value is available for this band
-* \param values A vector of size > 1 corresponding to the no data
-* value for each band. If flag is 0, the value will be ignored.
-*/
-template<typename T> bool IsNoData(const T & pixel, const
-std::vector<bool> & flags, const std::vector<double> & values) {
-  assert(flags.size()>0);
-  assert(values.size()>0);
-
-  if(vnl_math_isnan((int)flags[0]))
-    return true;
-
-
-  if(flags[0])
-    {
-    return (pixel == values[0]);
-    }
-  else
-    {
-    return false;
-    }
-}
-/**
- * Specialization of IsNoData function to handle itk::VariableLengthVector
- */
-template <typename T> bool IsNoData(const itk::VariableLengthVector<T> & pixel, const std::vector<bool> & flags, const std::vector<double> & values)
-{
-  assert(flags.size()>=pixel.Size());
-  assert(values.size()>=pixel.Size());
-
-  for(unsigned int i = 0; i < pixel.Size();++i)
-    {
-    if(vnl_math_isnan(pixel[i]) || (flags[i] && (pixel[i] == values[i])))
-      {
-      return true;
-      }
-    }
-  return false;
-}
-
-
-} // End namespace otb
-
-#endif
diff --git a/Modules/Core/ImageBase/test/CMakeLists.txt b/Modules/Core/ImageBase/test/CMakeLists.txt
index dd4ecc9d09b0a5477f4d0e66786ffeda21dab34c..46ff70cf251e17e8a4bd2be04073930a7dec7978 100644
--- a/Modules/Core/ImageBase/test/CMakeLists.txt
+++ b/Modules/Core/ImageBase/test/CMakeLists.txt
@@ -28,7 +28,7 @@ set(OTBImageBaseTests
   otbImageFunctionAdaptor.cxx
   otbMultiChannelExtractROINew.cxx
   otbMetaImageFunction.cxx
-  otbNoDataHelperTest.cxx
+
   )
 
 add_executable(otbImageBaseTestDriver ${OTBImageBaseTests})
@@ -825,6 +825,3 @@ otb_add_test(NAME ioTvOtbVectorImageTestRadarsat COMMAND otbImageBaseTestDriver
    otbVectorImageLegacyTest
    LARGEINPUT{/RADARSAT1/GOMA/SCENE01/}
    ${TEMP}/ioOtbVectorImageTestRadarsat.txt)
-
-otb_add_test(NAME coreImageBaseNoDataHelperTest COMMAND otbImageBaseTestDriver
-  otbNoDataHelperTest)
diff --git a/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx b/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx
index dcf63d236ebad2c066389989da824836833ab7d9..fc275609cb19c75305902543f926fc37e3cb3f83 100644
--- a/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx
+++ b/Modules/Core/ImageBase/test/otbImageBaseTestDriver.cxx
@@ -31,5 +31,4 @@ void RegisterTests()
   REGISTER_TEST(otbMultiChannelExtractROINew);
   REGISTER_TEST(otbMetaImageFunction);
   REGISTER_TEST(otbMetaImageFunctionNew);
-  REGISTER_TEST(otbNoDataHelperTest);
 }
diff --git a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h
index d9209574b68c59c32b82e7c7894e3855e988a28c..8340cedac73674309f124cc4c8b24499dc3c34b3 100644
--- a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h
+++ b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h
@@ -107,6 +107,12 @@ public:
   double GetGCPZ(unsigned int GCPnum) const;
 //  otbMetadataGetGCPnumMacro(GCPZ, double, GCPnum, unsigned int);
 
+  /** 
+   * Get The no data flags if existing
+   * return False otherwise
+   */
+  bool GetNoDataFlags(std::vector<bool> & flags, std::vector<double> & values) const;
+
   /** Get the six coefficients of affine geoTtransform. */
 
   VectorType GetGeoTransform() const;
diff --git a/Modules/Core/Metadata/include/otbNoDataHelper.h b/Modules/Core/Metadata/include/otbNoDataHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..57d927c78fb7bf737e11e3d6663b3f60cd52d828
--- /dev/null
+++ b/Modules/Core/Metadata/include/otbNoDataHelper.h
@@ -0,0 +1,165 @@
+/*=========================================================================
+
+  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 __otbNoDataHelper_h
+#define __otbNoDataHelper_h
+#include <vector>
+#include <cassert>
+#include "vnl/vnl_math.h"
+#include <itkVariableLengthVector.h>
+
+namespace itk
+{
+class MetaDataDictionary;
+}
+
+namespace otb
+{
+
+/** 
+ * Reads no data flag from the MetaDataDictionnary dict to flags and values
+ * vectors. Returns true upon success. 
+ */
+bool ReadNoDataFlags(const itk::MetaDataDictionary& dict, std::vector<bool> & flags, std::vector<double> & values);
+
+/** 
+ * Write no data flags to the MetaDataDictionnary dict from flags and values
+ * vectors. Returns true upon success. 
+ */
+void WriteNoDataFlags(const std::vector<bool> & flags, const std::vector<double> & values, itk::MetaDataDictionary& dict);
+
+/**
+* Test if the pixel corresponds to a no data pixel according to a
+* vector of no data flags, and a vector of no data values.
+* \param pixel The pixel to test
+* \param flags A vector of size > 1 containing a flag per band to
+* indicate if a no data value is available for this band
+* \param values A vector of size > 1 corresponding to the no data
+* value for each band. If flag is 0, the value will be ignored.
+* \param nanIsNoData If true, NaN values will be reported as no-data.
+*/
+template<typename T> bool IsNoData(const T & pixel, const
+                                   std::vector<bool> & flags, const std::vector<double> & values, bool nanIsNoData = false) {
+  assert(flags.size()>0);
+  assert(values.size()>0);
+
+  if(nanIsNoData && vnl_math_isnan(values[0]))
+    return true;
+
+
+  if(flags[0])
+    {
+    return (pixel == values[0]);
+    }
+  else
+    {
+    return false;
+    }
+}
+
+/**
+* Reads a pixel and change the no data value if it is found. No data
+* value is changed either if the pixel value is NaN or if the pixel
+* value equals the no data value and flag is true.
+* 
+* \param pixel The pixel to process \param flags A vector of size > 1
+* containing a flag per band to indicate if a no data value is
+* available for this band
+* \param values A vector of size > 1 corresponding to the current no data
+* value for each band. If flag is 0, the value will be ignored.
+* \param newValues A vector of size > 1 corresponding to the new no data
+* value for each band. If flag is 0, the value will be ignored 
+* \param nanIsNoData If true, NaN values will be considered as no-data
+* and changed as well.
+*
+*/
+template<typename T> T ChangeNoData(const T & pixel, const
+                                    std::vector<bool> & flags,
+                                    const std::vector<double> & values,
+                                    const std::vector<double> & newValues,
+                                    bool nanIsNoData = false) {
+  assert(flags.size()>0);
+  assert(values.size()>0);
+  assert(newValues.size()>0);
+  
+  if(nanIsNoData && vnl_math_isnan(pixel))
+    {
+    return static_cast<T>(newValues[0]);
+    }
+
+  if(flags[0] && pixel == values[0])
+    {
+    return static_cast<T>(newValues[0]);
+    }
+  return pixel;
+}
+
+
+/**
+ * Specialization of IsNoData function to handle itk::VariableLengthVector
+ */
+template <typename T> bool IsNoData(const itk::VariableLengthVector<T> & pixel, const std::vector<bool> & flags, const std::vector<double> & values, bool nanIsNoData = false)
+{
+  assert(flags.size()>=pixel.Size());
+  assert(values.size()>=pixel.Size());
+
+  for(unsigned int i = 0; i < pixel.Size();++i)
+    {
+    if((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i])))
+      {
+      return true;
+      }
+    }
+  return false;
+}
+
+
+/**
+ * Specialization of ChangeNoData function to handle itk::VariableLengthVector
+ */
+template <typename T> itk::VariableLengthVector<T> ChangeNoData(const itk::VariableLengthVector<T> & pixel,
+                                                                const std::vector<bool> & flags,
+                                                                const std::vector<double> & values,
+                                                                const std::vector<double> & newValues,
+                                                                bool nanIsNoData = false)
+{
+  assert(flags.size()>=pixel.Size());
+  assert(values.size()>=pixel.Size());
+  assert(newValues.size()>=pixel.Size());
+
+  itk::VariableLengthVector<T> outPixel(pixel.Size());
+  
+  for(unsigned int i = 0; i < pixel.Size();++i)
+    {
+    if((nanIsNoData && vnl_math_isnan(pixel[i])) || (flags[i] && (pixel[i] == values[i])))
+      {
+      outPixel[i] = newValues[i];
+      }
+    else
+      {
+      outPixel[i] = pixel[i];
+      }
+    }
+
+  return outPixel;
+}
+
+
+
+} // End namespace otb
+
+#endif
diff --git a/Modules/Core/Metadata/otb-module.cmake b/Modules/Core/Metadata/otb-module.cmake
index afaff0b86e39f5762ddb10689628e7ebf1be6e61..240e6a3ee1cec76586a97c0078a34861dfb410ee 100644
--- a/Modules/Core/Metadata/otb-module.cmake
+++ b/Modules/Core/Metadata/otb-module.cmake
@@ -9,12 +9,12 @@ otb_module(OTBMetadata
     OTBITK
     OTBOSSIMAdapters
     OTBCommon
-
+    
   TEST_DEPENDS
     OTBTestKernel
     OTBImageIO
     OTBImageBase
-
+    
   DESCRIPTION
     "${DOCUMENTATION}"
 )
diff --git a/Modules/Core/Metadata/src/CMakeLists.txt b/Modules/Core/Metadata/src/CMakeLists.txt
index bc3c9900f779896fc9396b52c4e36f60c0d77b57..458188d5246599d101d8cfa68384704f8e7929ae 100644
--- a/Modules/Core/Metadata/src/CMakeLists.txt
+++ b/Modules/Core/Metadata/src/CMakeLists.txt
@@ -24,6 +24,7 @@ set(OTBMetadata_SRC
   otbSarImageMetadataInterface.cxx
   otbPleiadesImageMetadataInterfaceFactory.cxx
   otbTerraSarImageMetadataInterfaceFactory.cxx
+  otbNoDataHelper.cxx
   )
 
 add_library(OTBMetadata ${OTBMetadata_SRC})
diff --git a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx
index 784f5847bca5369f0077f9b6441443aae5a35550..013e4f9c77d4932f351b2c17acfd04f4e3d2944e 100644
--- a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx
+++ b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx
@@ -18,9 +18,11 @@
 
 #include "otbImageMetadataInterfaceBase.h"
 
+#include "otbNoDataHelper.h"
 #include "itkMetaDataObject.h"
 #include "itksys/SystemTools.hxx"
 
+
 namespace otb
 {
 
@@ -222,6 +224,12 @@ ImageMetadataInterfaceBase::GetGCPZ(unsigned int GCPnum) const
   else return (0);
 }
 
+bool
+ImageMetadataInterfaceBase::GetNoDataFlags(std::vector<bool> & flags, std::vector<double> & values) const
+{
+  return ReadNoDataFlags(this->GetMetaDataDictionary(),flags,values);
+}
+
 ImageMetadataInterfaceBase::VectorType
 ImageMetadataInterfaceBase::GetGeoTransform() const
 {
diff --git a/Modules/Core/Metadata/src/otbNoDataHelper.cxx b/Modules/Core/Metadata/src/otbNoDataHelper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b5edf9dc49145ba6aae8e5089cc7a11335bf7037
--- /dev/null
+++ b/Modules/Core/Metadata/src/otbNoDataHelper.cxx
@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  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 "otbNoDataHelper.h"
+
+#include "itkMetaDataDictionary.h"
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
+
+namespace otb
+{
+
+bool ReadNoDataFlags(const itk::MetaDataDictionary& dict, std::vector<bool> & flags, std::vector<double> & values)
+{
+  bool ret = itk::ExposeMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,flags);
+
+  if (ret)
+    ret = itk::ExposeMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,values);
+  
+  return ret;
+}
+
+void WriteNoDataFlags(const std::vector<bool> & flags, const std::vector<double> & values, itk::MetaDataDictionary& dict)
+{
+ itk::EncapsulateMetaData<std::vector<bool> >(dict,MetaDataKey::NoDataValueAvailable,flags);
+ itk::EncapsulateMetaData<std::vector<double> >(dict,MetaDataKey::NoDataValue,values);
+}
+
+} // End namespace otb
diff --git a/Modules/Core/Metadata/test/CMakeLists.txt b/Modules/Core/Metadata/test/CMakeLists.txt
index 340324421e76181795985d0e7fea068ddb2fab43..b48fbffaef79197293daba9fec698e7fe0581bfb 100644
--- a/Modules/Core/Metadata/test/CMakeLists.txt
+++ b/Modules/Core/Metadata/test/CMakeLists.txt
@@ -22,6 +22,7 @@ otbTerraSarImageMetadataInterfaceNew.cxx
 otbWorldView2ImageMetadataInterfaceNew.cxx
 otbDefaultImageMetadataInterface.cxx
 otbImageMetadataInterfaceTest2.cxx
+otbNoDataHelperTest.cxx
 )
 
 add_executable(otbMetadataTestDriver ${OTBMetadataTests})
@@ -351,3 +352,7 @@ foreach( current_file ${GenericTestSPOT6_DATA_INPUTS} )
       ${TEMP}/ioTvOpticalImageMetadataInterface_${current_type}_OUT.txt
     )
 endforeach()
+
+
+otb_add_test(NAME coreMetaDataNoDataHelperTest COMMAND otbMetadataTestDriver
+  otbNoDataHelperTest)
diff --git a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
index d2dfb191518574ccf1829046d59c2ebb5b2550c0..cd06f2f46e9f46fb412b1f30a278374070ac7405 100644
--- a/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
+++ b/Modules/Core/Metadata/test/otbMetadataTestDriver.cxx
@@ -21,4 +21,5 @@ void RegisterTests()
   REGISTER_TEST(otbWorldView2ImageMetadataInterfaceNew);
   REGISTER_TEST(otbDefaultImageMetadataInterface);
   REGISTER_TEST(otbImageMetadataInterfaceTest2);
+  REGISTER_TEST(otbNoDataHelperTest);
 }
diff --git a/Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx b/Modules/Core/Metadata/test/otbNoDataHelperTest.cxx
similarity index 91%
rename from Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx
rename to Modules/Core/Metadata/test/otbNoDataHelperTest.cxx
index 5b32ec74768b446b80c18c3e2d4a643971e5246d..4db9ba0ab9f1bd23ff180ca3edf7577476895d13 100644
--- a/Modules/Core/ImageBase/test/otbNoDataHelperTest.cxx
+++ b/Modules/Core/Metadata/test/otbNoDataHelperTest.cxx
@@ -17,6 +17,7 @@
 =========================================================================*/
 
 #include "otbNoDataHelper.h"
+#include "itkMetaDataDictionary.h"
 #include "otbMacro.h"
 
 int otbNoDataHelperTest(int itkNotUsed(argc),char * itkNotUsed(argv) [])
@@ -24,6 +25,11 @@ int otbNoDataHelperTest(int itkNotUsed(argc),char * itkNotUsed(argv) [])
   std::vector<bool> b1(1,true);
   std::vector<double> v1(1,0);
 
+  itk::MetaDataDictionary dict;
+
+  otb::WriteNoDataFlags(b1,v1,dict);
+  otb::ReadNoDataFlags(dict,b1,v1);
+  
   otbControlConditionTestMacro(otb::IsNoData(10,b1,v1)," wrong output of IsNoData function");
   otbControlConditionTestMacro(!otb::IsNoData(0,b1,v1)," wrong output of IsNoData function");
   b1[0]=false;
diff --git a/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h b/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..59d4fca6e387e8dae4588678c76a479b91c5ed01
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbChangeNoDataValueFilter.h
@@ -0,0 +1,178 @@
+/*=========================================================================
+
+  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 __otbChangeNoDataValueFilter_h
+#define __otbChangeNoDataValueFilter_h
+
+#include "itkUnaryFunctorImageFilter.h"
+#include "itkMetaDataObject.h"
+#include "otbMetaDataKey.h"
+#include "otbNoDataHelper.h"
+
+namespace otb
+{
+namespace Functor
+{
+/** \class ChangeNoDataFunctor
+ *  \brief Functor used by ChangeNoDataValueFilter
+ *
+ *  See ChangeNoDataValueFilter for complete documentation. 
+ *  \ingroup OTBImageManipulation
+ */
+template <typename TInputPixel, typename TOutputPixel> 
+class ChangeNoDataFunctor
+{
+public:
+  ChangeNoDataFunctor():
+    m_Flags(),
+    m_Values(),
+    m_NewValues(),
+    m_NaNIsNoData(false)
+  {}
+  virtual ~ChangeNoDataFunctor(){}
+
+  inline TOutputPixel operator()(const TInputPixel& in) const
+  {
+    return otb::ChangeNoData(in,m_Flags,m_Values,m_NewValues,m_NaNIsNoData);
+  }
+
+  std::vector<bool>   m_Flags;
+  std::vector<double> m_Values;
+  std::vector<double> m_NewValues;
+  bool                m_NaNIsNoData;
+};
+
+} // End namespace Functor
+
+/** \class ChangeNoDataValueFilter
+ *  \brief Change no-data flags and values and replace them in image
+ *  
+ *  This filter reads the no-data flags (a boolean vector indicating
+ *  for each band if a no-data value exists) and values (the actual
+ *  value to be used as no-data for each band) from
+ *  MetaDataDictionary, and allows to change this value.
+ * 
+ *  The algorithm is the following: for each pixel, for each channel
+ *  in the pixel, if there is a no-data value for this channel
+ *  (according to no-data flags) and the current channel value equals
+ *  to the no-data value set for this channel, then the value is
+ *  changed for the new no-data value specified by the
+ *  users. Otherwise, value remains untouched.
+ * 
+ *  If NaNIsNoData is true:
+ *  - NaN values will be considered as no data and replaced as well
+ *  - Output image will have no-data flags and values for all bands
+ *
+ *  If NaNIsNoData is false:
+ *  - Band for which input no-data flags is false will remain
+ *    untouched
+ *  - Output image will have no-data flags and values only for bands
+ *    for which input no-data flag is true.
+ * 
+ * \ingroup Streamed
+ * \ingroup MultiThreaded
+ * \ingroup OTBImageManipulation
+ */
+template <typename TInputImage, typename TOutputImage>
+class ChangeNoDataValueFilter
+  : public itk::UnaryFunctorImageFilter<TInputImage,
+                                        TOutputImage,
+                                        Functor::ChangeNoDataFunctor<typename TInputImage::PixelType,
+                                                                     typename TOutputImage::PixelType> >
+{
+public:
+  typedef Functor::ChangeNoDataFunctor<typename TInputImage::PixelType,typename TOutputImage::PixelType> FunctorType;
+
+  typedef ChangeNoDataValueFilter                           Self;
+  typedef itk::UnaryFunctorImageFilter<TInputImage,
+                                        TOutputImage,
+                                       FunctorType>         Superclass;
+  typedef itk::SmartPointer<Self>                           Pointer;
+  typedef itk::SmartPointer<const Self>                     ConstPointer;
+
+  /** Type macro */
+  itkNewMacro(Self);
+
+  /** Creation through object factory macro */
+  itkTypeMacro(ChangeNoDataValueFilter, itk::ImageToImageFilter);
+
+  /**
+   * Set the new no-data values
+   * \param newValues The vector of new no-data values (size should be
+   * >= to number of bands)
+   */
+  void SetNewNoDataValues(std::vector<double> & newValues)
+  {
+    this->GetFunctor().m_NewValues = newValues;
+  }
+
+   /**
+   * Set the NaN is no data flags
+   * \param nanIsNoData If true, NaN values will be considered as
+   * no-data as well (default is false)
+   */
+  void SetNaNIsNoData(bool nanIsNoData)
+  {
+    this->GetFunctor().m_NaNIsNoData = nanIsNoData;
+  }
+
+protected:
+  ChangeNoDataValueFilter()
+  {}
+
+  virtual ~ChangeNoDataValueFilter()
+  {}
+
+  virtual void GenerateOutputInformation()
+  {
+    Superclass::GenerateOutputInformation();
+
+    std::vector<bool> noDataValueAvailable;
+    std::vector<double> noDataValues;
+
+    bool ret = ReadNoDataFlags(this->GetInput()->GetMetaDataDictionary(),noDataValueAvailable,noDataValues);
+
+    if(!ret)
+      {
+      noDataValueAvailable.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),false);
+      noDataValues.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),0);
+      }
+
+    this->GetFunctor().m_Flags = noDataValueAvailable;
+    this->GetFunctor().m_Values = noDataValues;
+    
+    std::vector<bool> flags = noDataValueAvailable;
+    
+    if(this->GetFunctor().m_NaNIsNoData)
+      {
+      flags = std::vector<bool>(flags.size(),true);
+      }
+    
+    WriteNoDataFlags(flags,this->GetFunctor().m_NewValues,this->GetOutput()->GetMetaDataDictionary());
+  }
+
+private:
+  ChangeNoDataValueFilter(const Self&); // purposely not implemented
+  void operator =(const Self&); // purposely not implemented
+
+}; 
+
+} // End namespace otb
+
+
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h b/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h
index 02e09dd22ec43533330cf59a4a41345d5aaa7570..a790b37a0ea031c3695ac7fcb8058d313f51e0ea 100644
--- a/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbImageToNoDataMaskFilter.h
@@ -27,6 +27,12 @@ namespace otb
 {
 namespace Functor
 {
+/** \class NoDataFunctor
+ *  \brief Functor used by ImageToNoDataMaskFilter
+ *
+ *  See ImageToNoDataMaskFilter for complete documentation. 
+ *  \ingroup OTBImageManipulation
+ */
 template <typename TInputPixel, typename TOutputPixel> 
 class NoDataFunctor
 {
@@ -35,25 +41,42 @@ public:
     m_Flags(),
     m_Values(),
     m_OutsideValue(0),
-    m_InsideValue(1)
+    m_InsideValue(1),
+    m_NaNIsNoData(false)
   {}
   virtual ~NoDataFunctor(){}
 
   inline TOutputPixel operator()(const TInputPixel& in) const
   {
-    return otb::IsNoData(in,m_Flags,m_Values)?m_OutsideValue:m_InsideValue;
+    return otb::IsNoData(in,m_Flags,m_Values,m_NaNIsNoData)?m_OutsideValue:m_InsideValue;
   }
 
   std::vector<bool>   m_Flags;
   std::vector<double> m_Values;
   TOutputPixel        m_OutsideValue;
   TOutputPixel        m_InsideValue;
+  bool                m_NaNIsNoData;
 };
 
 } // End namespace Functor
 
 
-
+/** \class ImageToNoDataMaskFilter 
+ *  \brief Builds a no-data mask image from no-data flags and values
+ *  
+ *  This filter reads the no-data flags (a boolean vector indicating
+ *  for each band if a no-data value exists) and values (the actual
+ *  value to be used as no-data for each band) from
+ *  MetaDataDictionary, and builds a binary mask indicating presence
+ *  or absence of no-data for each pixel.
+ * 
+ *  If NaNIsNoData is true, NaN pixels will also be considered as
+ *  no-data pixels.
+ * 
+ * \ingroup Streamed
+ * \ingroup MultiThreaded
+ * \ingroup OTBImageManipulation
+ */
 template <typename TInputImage, typename TOutputImage>
 class ImageToNoDataMaskFilter
   : public itk::UnaryFunctorImageFilter<TInputImage,
@@ -77,15 +100,31 @@ public:
   /** Creation through object factory macro */
   itkTypeMacro(SpectralAngleDistanceImageFilter, itk::ImageToImageFilter);
 
+  /**
+   * Set inside value of output mask. This value will be used to
+   * indicate absence of no-data for the pixel in the output mask
+   */ 
   void SetInsideValue(const typename TOutputImage::PixelType & value)
   {
     this->GetFunctor().m_InsideValue = value;
   }
-
+  /**
+   * Set outside value of output mask. This value will be used to
+   * indicate presence of no-data for the pixel in the output mask
+   */ 
   void SetOutsideValue(const typename TOutputImage::PixelType & value)
   {
     this->GetFunctor().m_OutsideValue = value;
   }
+  /**
+   * Set the NaN is no data flags
+   * \param nanIsNoData If true, NaN values will be considered as
+   * no-data as well (default is false)
+   */
+  void SetNaNIsNoData(bool nanIsNoData)
+  {
+    this->GetFunctor().m_NaNIsNoData=nanIsNoData;
+  }
 
 protected:
   ImageToNoDataMaskFilter()
@@ -97,23 +136,11 @@ protected:
   virtual void BeforeThreadedGenerateData()
   {
     std::vector<bool> noDataValueAvailable;
-    bool ret = itk::ExposeMetaData<std::vector<bool> >(this->GetInput()->GetMetaDataDictionary(),MetaDataKey::NoDataValueAvailable,noDataValueAvailable);
-
-    if(!ret)
-      {
-      noDataValueAvailable.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),false);
-      }
-
-    this->GetFunctor().m_Flags = noDataValueAvailable;
-
     std::vector<double> noDataValues;
-    ret = itk::ExposeMetaData<std::vector<double> >(this->GetInput()->GetMetaDataDictionary(),MetaDataKey::NoDataValue,noDataValues);
-
-    if(!ret)
-      {
-      noDataValues.resize(this->GetInput()->GetNumberOfComponentsPerPixel(),0);
-      }
 
+    ReadNoDataFlags(this->GetInput()->GetMetaDataDictionary(),noDataValueAvailable,noDataValues);
+    
+    this->GetFunctor().m_Flags = noDataValueAvailable;
     this->GetFunctor().m_Values = noDataValues;
   }
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h
new file mode 100644
index 0000000000000000000000000000000000000000..18f1465b0941b453bd5c9330dda92e2873f69d4f
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h
@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  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 __otbNRIBandImagesToOneNComplexBandsImage_h
+#define __otbNRIBandImagesToOneNComplexBandsImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+/*
+ * Inputs : N images made of two real bands 
+ * Output : one single image made of N complex bands
+ * 
+ * */
+
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT NRIBandImagesToOneNComplexBandsImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef NRIBandImagesToOneNComplexBandsImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(NRIBandImagesToOneNComplexBandsImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  NRIBandImagesToOneNComplexBandsImage();
+  virtual ~NRIBandImagesToOneNComplexBandsImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void GenerateOutputInformation(void);
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  NRIBandImagesToOneNComplexBandsImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbNRIBandImagesToOneNComplexBandsImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx
new file mode 100644
index 0000000000000000000000000000000000000000..46abbf79efee49136fe17fc0be5d36e9e6ae13cf
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx
@@ -0,0 +1,139 @@
+/*=========================================================================
+
+  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 __otbNRIBandImagesToOneNComplexBandsImage_txx
+#define __otbNRIBandImagesToOneNComplexBandsImage_txx
+
+#include "otbNRIBandImagesToOneNComplexBandsImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+#include "itkVariableLengthVector.h"
+
+
+
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::NRIBandImagesToOneNComplexBandsImage()
+{
+	//this->SetNumberOfThreads(1);
+}
+
+/**
+ * GenerateOutputInformation
+ */
+template<class TInputImage, class TOutputImage>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>
+::GenerateOutputInformation(void)
+{
+  Superclass::GenerateOutputInformation();
+  
+  unsigned int nbInputs = this->GetNumberOfInputs();
+  this->GetOutput()->SetNumberOfComponentsPerPixel(nbInputs);
+  
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	unsigned int nbInputs = this->GetNumberOfInputs();
+	
+	for (unsigned int i=0; i<nbInputs; i++)
+		if (this->GetInput(i)->GetNumberOfComponentsPerPixel() != 2 )
+			itkExceptionMacro("Input images must be made of two bands and only two (see input #" << i << ").");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+ 
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+	
+  unsigned int nbInputs = this->GetNumberOfInputs();	  
+  
+  itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbInputs);
+
+  std::vector< typename itk::ImageRegionConstIterator<TInputImage> > vInIt;
+  for (unsigned int i=0; i<nbInputs; i++)
+	vInIt.push_back( itk::ImageRegionConstIterator<TInputImage>(this->GetInput(i), outputRegionForThread) );
+
+	
+  itk::ImageRegionIterator<OutputImageType>      outIt;
+  outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread);
+  
+  for (unsigned int i=0; i<nbInputs; i++)
+	vInIt[i].GoToBegin();
+  outIt.GoToBegin();
+
+  while (!outIt.IsAtEnd())
+  {
+	  
+	  
+	  for (unsigned int i=0; i<nbInputs; i++)
+	  {
+		  vlv[i] = std::complex< typename InputPixelType::ValueType >(vInIt[i].Get()[0],vInIt[i].Get()[1]);
+		//std::cout << "i = " << i << " " << vInIt[i].Get()[0] << " " << vInIt[i].Get()[1] << std::endl;
+	  }
+
+	  
+	  outIt.Set(vlv);
+	  
+	  //std::cout << "outIt.Get() = " << outIt.Get() << std::endl;
+	  
+	  for (unsigned int i=0; i<nbInputs; i++)
+		++vInIt[i];
+	  ++outIt;
+	  
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
new file mode 100644
index 0000000000000000000000000000000000000000..745199721496ff2f6b9797cfa5e031ab3ec4ebde
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
@@ -0,0 +1,91 @@
+/*=========================================================================
+
+  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 __otbOneRIBandImageToOneComplexBandImage_h
+#define __otbOneRIBandImageToOneComplexBandImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+
+/*
+ * Inputs : one image made of two real bands 
+ * Output : one image made of one complex band
+ * 
+ * */
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT OneRIBandImageToOneComplexBandImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef OneRIBandImageToOneComplexBandImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(OneRIBandImageToOneComplexBandImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  OneRIBandImageToOneComplexBandImage();
+  virtual ~OneRIBandImageToOneComplexBandImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  OneRIBandImageToOneComplexBandImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbOneRIBandImageToOneComplexBandImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx
new file mode 100644
index 0000000000000000000000000000000000000000..8a7003a8eec8066ed212245a9ff0162310f38499
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx
@@ -0,0 +1,100 @@
+/*=========================================================================
+
+  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 __otbOneRIBandImageToOneComplexBandImage_txx
+#define __otbOneRIBandImageToOneComplexBandImage_txx
+
+#include "otbOneRIBandImageToOneComplexBandImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::OneRIBandImageToOneComplexBandImage()
+{
+  //this->SetNumberOfThreads(1);
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	if (this->GetInput()->GetNumberOfComponentsPerPixel() != 2 )
+			itkExceptionMacro("Input image must be made of two bands and only two.");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+	
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+	
+  typename OutputImageType::Pointer     output = this->GetOutput();
+  typename InputImageType::ConstPointer input  = this->GetInput();
+  
+  itk::ImageRegionIterator<OutputImageType>      it;
+   itk::ImageRegionConstIterator<TInputImage>      itIn;
+  
+  itIn = itk::ImageRegionConstIterator<TInputImage>(input, outputRegionForThread);
+  it = itk::ImageRegionIterator<OutputImageType>(output, outputRegionForThread);
+  
+  it.GoToBegin();
+  itIn.GoToBegin();
+  while (!it.IsAtEnd())
+  {
+	  
+	  it.Set(static_cast<OutputPixelType>(   std::complex< typename InputPixelType::ValueType >(itIn.Get()[0],itIn.Get()[1])   ));
+	  
+	  ++it;
+	  ++itIn;
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
index 841117429ac4d12b5f4a3a83dae272d5164816ba..71230c936c8dc49e53e2903af502c169a1830078 100644
--- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.h
@@ -171,6 +171,9 @@ public:
     m_DisplacementFilter->SetNumberOfThreads(nbThread);
   }
 
+  /** Override itk::ProcessObject method to let the internal filter do the propagation */
+  virtual void PropagateRequestedRegion(itk::DataObject *output);
+
 protected:
   StreamingResampleImageFilter();
 
@@ -181,8 +184,6 @@ protected:
 
   virtual void GenerateOutputInformation();
 
-  virtual void GenerateInputRequestedRegion();
-
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
 
 private:
diff --git a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
index 03ad4382b8651617bc2104bf0b3c89d22010afa4..8543b9e8881d3f3fe80db35cff33602cbc7eae74 100644
--- a/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
+++ b/Modules/Filtering/ImageManipulation/include/otbStreamingResampleImageFilter.txx
@@ -50,7 +50,7 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy
   progress->RegisterInternalFilter(m_WarpFilter, 1.f);
 
   m_WarpFilter->GraftOutput(this->GetOutput());
-  m_WarpFilter->Update();
+  m_WarpFilter->UpdateOutputData(m_WarpFilter->GetOutput());
   this->GraftOutput(m_WarpFilter->GetOutput());
 }
 
@@ -62,41 +62,14 @@ void
 StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType>
 ::GenerateOutputInformation()
 {
-  // call the superclass's implementation of this method
-  Superclass::GenerateOutputInformation();
-
-  typename OutputImageType::Pointer outputPtr = this->GetOutput();
-
-  outputPtr->SetSpacing( this->GetOutputSpacing() );
-  outputPtr->SetOrigin(  this->GetOutputOrigin() );
-
-  typename OutputImageType::RegionType region;
-  region.SetSize( this->GetOutputSize() );
-  region.SetIndex(this->GetOutputStartIndex() );
-
-  outputPtr->SetLargestPossibleRegion(region);
-
   // check the output spacing of the displacement field
   if(this->GetDisplacementFieldSpacing()== itk::NumericTraits<SpacingType>::ZeroValue())
     {
     this->SetDisplacementFieldSpacing(2.*this->GetOutputSpacing());
     }
-}
-
-template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
-void
-StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType>
-::GenerateInputRequestedRegion()
-{
-  // Retrieve output pointer
-  OutputImageType * outputPtr = this->GetOutput();
 
-  // Retrieve input pointer
-  const InputImageType * inputPtr = this->GetInput();
-
-  // Retrieve output requested region
-  RegionType requestedRegion = outputPtr->GetRequestedRegion();
-  SizeType largestSize       = outputPtr->GetLargestPossibleRegion().GetSize();
+  // Retrieve output largest region
+  SizeType largestSize       = this->GetOutputSize();
 
   // Set up displacement field filter
   SizeType displacementFieldLargestSize;
@@ -117,10 +90,20 @@ StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionTy
   m_DisplacementFilter->SetOutputSize(displacementFieldLargestSize);
   m_DisplacementFilter->SetOutputIndex(this->GetOutputStartIndex());
 
-  // Generate input requested region
-  m_WarpFilter->SetInput(inputPtr);
-  m_WarpFilter->GetOutput()->UpdateOutputInformation();
-  m_WarpFilter->GetOutput()->SetRequestedRegion(requestedRegion);
+  m_WarpFilter->SetInput(this->GetInput());
+  m_WarpFilter->GraftOutput(this->GetOutput());
+  m_WarpFilter->UpdateOutputInformation();
+  this->GraftOutput(m_WarpFilter->GetOutput());
+}
+
+template <class TInputImage, class TOutputImage, class TInterpolatorPrecisionType>
+void
+StreamingResampleImageFilter<TInputImage, TOutputImage, TInterpolatorPrecisionType>
+::PropagateRequestedRegion(itk::DataObject *output)
+{
+  if (this->m_Updating) return;
+
+  m_WarpFilter->GetOutput()->SetRequestedRegion(output);
   m_WarpFilter->GetOutput()->PropagateRequestedRegion();
 }
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
new file mode 100644
index 0000000000000000000000000000000000000000..e60a091176e80ff21ba52c3156aa2ba0413b3a13
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  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 __otbTwoNRIBandsImageToNComplexBandsImage_h
+#define __otbTwoNRIBandsImageToNComplexBandsImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+/*
+ * Inputs : one single image made of 2N real bands 
+ * Output : one single image made of N complex bands
+ * 
+ * */
+
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT TwoNRIBandsImageToNComplexBandsImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef TwoNRIBandsImageToNComplexBandsImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(TwoNRIBandsImageToNComplexBandsImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  TwoNRIBandsImageToNComplexBandsImage();
+  virtual ~TwoNRIBandsImageToNComplexBandsImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void GenerateOutputInformation(void);
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  TwoNRIBandsImageToNComplexBandsImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbTwoNRIBandsImageToNComplexBandsImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
new file mode 100644
index 0000000000000000000000000000000000000000..c61f07a9009b4fe2365f926e55c1a9c4111b27fa
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
@@ -0,0 +1,143 @@
+/*=========================================================================
+
+  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 __otbTwoNRIBandsImageToNComplexBandsImage_txx
+#define __otbTwoNRIBandsImageToNComplexBandsImage_txx
+
+#include "otbTwoNRIBandsImageToNComplexBandsImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+#include "itkVariableLengthVector.h"
+
+
+
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::TwoNRIBandsImageToNComplexBandsImage()
+{
+	//this->SetNumberOfThreads(1);
+}
+
+/**
+ * GenerateOutputInformation
+ */
+template<class TInputImage, class TOutputImage>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
+::GenerateOutputInformation(void)
+{
+  Superclass::GenerateOutputInformation();
+  
+  unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+  
+  if ( (nbCompo % 2) != 0 )
+  {
+	itkExceptionMacro("Number of bands of the input images must be an even number");
+  }
+  else
+	this->GetOutput()->SetNumberOfComponentsPerPixel(nbCompo/2);
+	
+	std::cout << "GenerateOutputInformation : " << this->GetOutput()->GetNumberOfComponentsPerPixel() << std::endl;
+  
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+			
+	if ( (nbCompo % 2) != 0 )
+	  itkExceptionMacro("Number of bands of the input images must be an even number");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+ 
+  unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+  
+  itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbCompo/2);
+  
+ 
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+
+  itk::ImageRegionConstIterator<TInputImage>  inIt;
+  inIt = itk::ImageRegionConstIterator<TInputImage>(this->GetInput(), outputRegionForThread);	
+	
+  itk::ImageRegionIterator<OutputImageType>      outIt;
+  outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread);
+  
+
+  inIt.GoToBegin();
+  outIt.GoToBegin();
+
+  while (!outIt.IsAtEnd())
+  {
+	  
+	  unsigned int k=0;
+	  for (unsigned int i=0; i<nbCompo-1; i=i+2)
+	  {
+		  vlv[k] = std::complex< typename InputPixelType::ValueType >(inIt.Get()[i],inIt.Get()[i+1]);
+		  k++;
+	  }
+
+	  
+	  outIt.Set(vlv);
+	  
+
+	  ++inIt;
+	  ++outIt;
+	  
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/otb-module.cmake b/Modules/Filtering/ImageManipulation/otb-module.cmake
index ca49464420ecf8215c1d36eacf45005fdcabc6c7..6a141566a1a1453663ce78f55c6ccf0f1742b5c8 100644
--- a/Modules/Filtering/ImageManipulation/otb-module.cmake
+++ b/Modules/Filtering/ImageManipulation/otb-module.cmake
@@ -10,6 +10,7 @@ otb_module(OTBImageManipulation
     OTBCommon
     OTBITK
     OTBImageBase
+    OTBMetadata
     OTBInterpolation
     OTBObjectList
     OTBStreaming
diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
index a167f9c62b9244001dddfbc4c2d215ee88fcc9bb..86e9cd72c67dca156fc4fd293c9b220ff186fc21 100644
--- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
@@ -70,6 +70,11 @@ otbSpectralAngleDistanceImageFilter.cxx
 otbFunctionWithNeighborhoodToImageFilterNew.cxx
 otbEuclideanDistanceMetricWithMissingValue.cxx
 otbEuclideanDistanceMetricWithMissingValueNew.cxx
+otbNRIBandImagesToOneNComplexBandsImage.cxx
+otbOneRIBandImageToOneComplexBandImage.cxx
+otbTwoNRIBandsImageToNComplexBandsImage.cxx
+otbChangeNoDataValueFilter.cxx
+otbImageToNoDataMaskFilter.cxx
 )
 
 add_executable(otbImageManipulationTestDriver ${OTBImageManipulationTests})
@@ -669,3 +674,39 @@ otb_add_test(NAME bfTvEuclideanDistanceMetricWithMissingValue COMMAND otbImageMa
   otbEuclideanDistanceMetricWithMissingValue)
 otb_add_test(NAME bfTuEuclideanDistanceMetricWithMissingValueNew COMMAND otbImageManipulationTestDriver
   otbEuclideanDistanceMetricWithMissingValueNew)
+
+otb_add_test(NAME bfTvTwoNRIBandsImageToNComplexBandsImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif
+  otbTwoNRIBandsImageToNComplexBandsImage
+  ${INPUTDATA}/RSAT_imagery_HH_HV_VV.tif
+  ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif
+  )
+  
+  
+otb_add_test(NAME bfTvNRIBandImagesToOneNComplexBandsImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  otbNRIBandImagesToOneNComplexBandsImage 
+  ${INPUTDATA}/RSAT_imagery_HH.tif
+  ${INPUTDATA}/RSAT_imagery_HV.tif
+  ${INPUTDATA}/RSAT_imagery_VV.tif
+  ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  )
+  
+otb_add_test(NAME bfTvOneRIBandImageToOneComplexBandImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_3}
+  ${INPUTDATA}/RSAT_imageryC_HH.tif
+  ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif
+  otbOneRIBandImageToOneComplexBandImage
+  ${INPUTDATA}/RSAT_imagery_HH.tif
+  ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif
+  )
+
+otb_add_test(NAME filteringImageManipulationChangeNoDataValueFilter COMMAND otbImageManipulationTestDriver
+  otbChangeNoDataValueFilter)
+
+otb_add_test(NAME filteringImageManipulationImageToNoDataMaskFilter COMMAND otbImageManipulationTestDriver
+  otbImageToNoDataMaskFilter)
diff --git a/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4bd558f4a9589795edaac72e023f28d1e67f737a
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbChangeNoDataValueFilter.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 "otbImage.h"
+#include "otbChangeNoDataValueFilter.h"
+#include "itkImageRegionIterator.h"
+
+int otbChangeNoDataValueFilter(int itkNotUsed(argc),char * itkNotUsed(argv) [])
+{
+
+  // Build an image
+  typedef otb::Image<double> ImageType;
+  ImageType::Pointer img = ImageType::New();
+
+  ImageType::SizeType size;
+  size.Fill(20);
+
+  ImageType::RegionType region;
+  region.SetSize(size);
+
+  // Fill it with a default value
+  img->SetRegions(region);
+  img->Allocate();
+  img->FillBuffer(10);
+
+  // Write no-data flags to it
+  std::vector<bool> flags(1,true);
+  std::vector<double> values(1,-10.);
+  otb::WriteNoDataFlags(flags,values,img->GetMetaDataDictionary());
+
+  // Fill half of the pixels with no-data values
+  itk::ImageRegionIterator<ImageType> it(img,region);
+  unsigned int count = 0;
+  for(it.GoToBegin();!it.IsAtEnd();++it,++count)
+    {
+    if (count%2 == 0)
+      it.Set(-10.);
+    }
+
+  // Instanciate filter
+  typedef otb::ChangeNoDataValueFilter<ImageType,ImageType> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  std::vector<double> newValues(1,-20.);
+
+  filter->SetInput(img);
+  filter->SetNewNoDataValues(newValues);
+  filter->Update();
+
+  // Check output
+  it = itk::ImageRegionIterator<ImageType>(filter->GetOutput(),region);
+  count = 0;
+
+  bool failed = false;
+  
+  for(it.GoToBegin();!it.IsAtEnd();++it,++count)
+    {
+    if (count%2 == 0 and it.Get()!=-20.)
+      {
+      std::cerr<<"Pixel should have new no-data value"<<std::endl;
+      failed = true;
+      }
+    else if(count%2 == 1 and it.Get()!=10.)
+      {
+      std::cerr<<"Pixel value should be unchanged"<<std::endl;
+      failed = true;
+      }
+    }
+  
+  otb::ReadNoDataFlags(filter->GetOutput()->GetMetaDataDictionary(),flags,values);
+
+  if(flags.empty() || !flags[0])
+    {
+    std::cerr<<"Output no-data flag should be [1] "<<std::endl;
+    failed = true;
+    }
+
+  if(values.empty() || values[0]!=-20)
+    {
+    std::cerr<<"Output no-data value should be [-20.]"<<std::endl;
+    failed = true;
+    }
+
+  if(failed)
+    return EXIT_FAILURE;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
index 361248a4fcbb5551d81813d644053459597fe768..f732d0d2a493a927ccfd34f1f5633d85b3508cf3 100644
--- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
@@ -76,4 +76,9 @@ void RegisterTests()
   REGISTER_TEST(otbFunctionWithNeighborhoodToImageFilterNew);
   REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValue);
   REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValueNew);
+  REGISTER_TEST(otbNRIBandImagesToOneNComplexBandsImage);
+  REGISTER_TEST(otbOneRIBandImageToOneComplexBandImage);
+  REGISTER_TEST(otbTwoNRIBandsImageToNComplexBandsImage);
+  REGISTER_TEST(otbChangeNoDataValueFilter);
+  REGISTER_TEST(otbImageToNoDataMaskFilter);
 }
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..109a2ec7d44c4ad2ff420337613260d64ba66b8a
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbImageToNoDataMaskFilter.cxx
@@ -0,0 +1,88 @@
+/*=========================================================================
+
+  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 "otbImage.h"
+#include "otbImageToNoDataMaskFilter.h"
+#include "itkImageRegionIterator.h"
+
+int otbImageToNoDataMaskFilter(int itkNotUsed(argc),char * itkNotUsed(argv) [])
+{
+
+  // Build an image
+  typedef otb::Image<double> ImageType;
+  ImageType::Pointer img = ImageType::New();
+
+  ImageType::SizeType size;
+  size.Fill(20);
+
+  ImageType::RegionType region;
+  region.SetSize(size);
+
+  // Fill it with a default value
+  img->SetRegions(region);
+  img->Allocate();
+  img->FillBuffer(10);
+
+  // Write no-data flags to it
+  std::vector<bool> flags(1,true);
+  std::vector<double> values(1,-10.);
+  otb::WriteNoDataFlags(flags,values,img->GetMetaDataDictionary());
+
+  // Fill half of the pixels with no-data values
+  itk::ImageRegionIterator<ImageType> it(img,region);
+  unsigned int count = 0;
+  for(it.GoToBegin();!it.IsAtEnd();++it,++count)
+    {
+    if (count%2 == 0)
+      it.Set(-10.);
+    }
+
+  // Instanciate filter
+  typedef otb::ImageToNoDataMaskFilter<ImageType,ImageType> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  filter->SetInput(img);
+  filter->SetInsideValue(255);
+  filter->SetOutsideValue(0);
+  filter->Update();
+
+  // Check output
+  it = itk::ImageRegionIterator<ImageType>(filter->GetOutput(),region);
+  count = 0;
+
+  bool failed = false;
+  
+  for(it.GoToBegin();!it.IsAtEnd();++it,++count)
+    {
+    if (count%2 == 0 and it.Get()!=0)
+      {
+      std::cerr<<"Pixel should be masked"<<std::endl;
+      failed = true;
+      }
+    else if(count%2 == 1 and it.Get()!=255)
+      {
+      std::cerr<<"Pixel should not be masked"<<std::endl;
+      failed = true;
+      }
+    }
+  
+  if(failed)
+    return EXIT_FAILURE;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..778f42146ea0b8ddd85ef72a63e121cf245d15c1
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx
@@ -0,0 +1,62 @@
+/*=========================================================================
+
+  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 "itkMacro.h"
+
+#include "otbNRIBandImagesToOneNComplexBandsImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbNRIBandImagesToOneNComplexBandsImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::VectorImage<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::NRIBandImagesToOneNComplexBandsImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer readerA = ReaderType::New();
+  ReaderType::Pointer readerB = ReaderType::New();
+  ReaderType::Pointer readerC = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  readerA->SetFileName(argv[1]);
+  readerB->SetFileName(argv[2]);
+  readerC->SetFileName(argv[3]);
+  writer->SetFileName(argv[4]);
+
+  filter->SetInput(0,readerA->GetOutput());
+  filter->SetInput(1,readerB->GetOutput());
+  filter->SetInput(2,readerC->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bbc4682269f0f3b7ea6f3bc3243810dd80d3099f
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
@@ -0,0 +1,56 @@
+/*=========================================================================
+
+  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 "itkMacro.h"
+
+#include "otbOneRIBandImageToOneComplexBandImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbOneRIBandImageToOneComplexBandImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::Image<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::OneRIBandImageToOneComplexBandImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  reader->SetFileName(argv[1]);
+  writer->SetFileName(argv[2]);
+
+  filter->SetInput(reader->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b4fed1963178ae79497fcdc18161b99261205dbc
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx
@@ -0,0 +1,56 @@
+/*=========================================================================
+
+  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 "itkMacro.h"
+
+#include "otbTwoNRIBandsImageToNComplexBandsImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbTwoNRIBandsImageToNComplexBandsImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::VectorImage<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::TwoNRIBandsImageToNComplexBandsImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  reader->SetFileName(argv[1]);
+  writer->SetFileName(argv[2]);
+
+  filter->SetInput(0,reader->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
index 26ac0e5470207740a37447551324c499a33afb2a..0aa2d8665815ca14c7005fd99fc32eb9f3532b64 100644
--- a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
@@ -79,34 +79,29 @@ public:
     const double M12 =  static_cast<double>(Mueller[1]);
     const double M13 =  static_cast<double>(Mueller[2]);
     const double M14 =  static_cast<double>(Mueller[3]);
-    const double M21 =  static_cast<double>(Mueller[4]);
     const double M22 =  static_cast<double>(Mueller[5]);
     const double M23 =  static_cast<double>(Mueller[6]);
     const double M24 =  static_cast<double>(Mueller[7]);
-    const double M31 =  static_cast<double>(Mueller[8]);
-    const double M32 =  static_cast<double>(Mueller[9]);
     const double M33 =  static_cast<double>(Mueller[10]);
     const double M34 =  static_cast<double>(Mueller[11]);
-    const double M41 =  static_cast<double>(Mueller[12]);
-    const double M42 =  static_cast<double>(Mueller[13]);
-    const double M43 =  static_cast<double>(Mueller[14]);
     const double M44 =  static_cast<double>(Mueller[15]);
 
-    const ComplexType hhhh(M11+M22+M12+M21, 0.0);
-    const ComplexType hvhv(M11+M12-M21-M22, 0.0);
-    const ComplexType vvvv(M11+M22-M12-M21, 0.0);
-    const ComplexType hhhv(M13+M23, M14+M24);
-    const ComplexType hhvv(-M33-M44, M43-M34);
-    const ComplexType hvvv(M32-M31, M41-M42);
-
-    result[0] = static_cast<OutputValueType>( hhhh );
-    result[1] = static_cast<OutputValueType>( 2.* hhhv );
-    result[2] = static_cast<OutputValueType>( hhvv );
-    result[3] = static_cast<OutputValueType>( 4.* hvhv );
-    result[4] = static_cast<OutputValueType>( 2.* hvvv );
-    result[5] = static_cast<OutputValueType>( vvvv );
-
-    return 0.5*result;
+    
+    const ComplexType A(0.5*(M11+M22+2*M12));
+    const ComplexType B(0.5*vcl_sqrt(2.0)*(M13+M23), 0.5*vcl_sqrt(2.0)*(M14+M24));
+    const ComplexType C(-0.5*(M33+M44), -M34);
+    const ComplexType E(M11-M22, 0.0);
+    const ComplexType F(0.5*vcl_sqrt(2.0)*(M13-M23), 0.5*vcl_sqrt(2.0)*(M14-M24));
+    const ComplexType I(0.5*(M11+M22-2*M12));
+
+    result[0] = static_cast<OutputValueType>( A );
+    result[1] = static_cast<OutputValueType>( B );
+    result[2] = static_cast<OutputValueType>( C );
+    result[3] = static_cast<OutputValueType>( E );
+    result[4] = static_cast<OutputValueType>( F );
+    result[5] = static_cast<OutputValueType>( I );
+
+    return result;
   }
 
   unsigned int GetOutputSize()
diff --git a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
index d465a986214b438a1ad706d0ae208eaa9770d064..e5539846c767445733336cd7952e937a42f6e60f 100644
--- a/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
+++ b/Modules/Filtering/Polarimetry/include/otbMultiChannelsPolarimetricSynthesisFilter.txx
@@ -40,6 +40,7 @@ MultiChannelsPolarimetricSynthesisFilter<TInputImage, TOutputImage, TFunction>
   SetEmissionH(false);
   SetEmissionV(false);
   SetGain(1);
+  SetMode(0);
   m_ArchitectureType = PolarimetricData::New();
 }
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
index 1081c263d908c91f7411bbadcc837b028aa0275d..a025d9c337a32c5865a964452bba75a247bb0373 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
@@ -30,26 +30,36 @@ namespace Functor {
  * \brief Evaluate the reciprocal Mueller matrix from the reciprocal coherency matrix image
  *
  * Outpus are:
- * - channel #0 : \f$ 0.5*\mathcal{Re}( Coherency[0]+Coherency[3]+Coherency[5]) \f$
- * - channel #1 : \f$ 0.5*\mathcal{Re}( Coherency[0]+Coherency[3]-Coherency[5]) \f$
- * - channel #2 : \f$ 0.5*\mathcal{Re}( Coherency[0]-Coherency[3]+Coherency[5]) \f$
- * - channel #3 : \f$ 0.5*\mathcal{Re}(-Coherency[0]+Coherency[3]+Coherency[5]) \f$
- * - channel #4 : \f$ \mathcal{Re}(Coherency[1]) \f$
- * - channel #5 : \f$ \mathcal{Re}(Coherency[2]) \f$
- * - channel #6 : \f$ \mathcal{Im}(Coherency[4]) \f$
- * - channel #7 : \f$ \mathcal{Re}(Coherency[4]) \f$
- * - channel #8 : \f$ \mathcal{Im}(Coherency[2]) \f$
- * - channel #9 : \f$ \mathcal{Im}(Coherency[1]) \f$
+ * - channel #0 : \f$ 0.5*( C_{11}+C_{22}+C_{33} ) \f$
+ * - channel #1 : \f$ Re(C_{12}) + Im(C_{22}) \f$
+ * - channel #2 : \f$ Re(C_{13}) \f$
+ * - channel #3 : \f$ Im(C_{23}) \f$
+ * - channel #4 : \f$ Re(C_{12}) \f$
+ * - channel #5 : \f$ 0.5*( C_{11}+C_{22}-C_{33} ) \f$
+ * - channel #6 : \f$ Re(C_{23}) \f$
+ * - channel #7 : \f$ Im(C_{13}) \f$
+ * - channel #8 : \f$ -Re(C_{13}) \f$
+ * - channel #9 : \f$ -Re(C_{23}) \f$
+ * - channel #10 : \f$ 0.5.Re(VAL1) \f$
+ * - channel #11 : \f$ 0.5.Im(VAL0) \f$
+ * - channel #12 : \f$ Im(C_{23}) \f$
+ * - channel #13 : \f$ Im(C_{13}) \f$
+ * - channel #14 : \f$ 0.5.Im(VAL1^{*}) \f$
+ * - channel #15 : \f$ 0.5.Re(VAL0) \f$
  *
+ * With:
+ * VAL0 = C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*}   
+ * VAL1 = -C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*} 
+ * 
  * Where Coherency is the input pixel and contains:
- * - channel #0 : \f$ (S_{hh}+S_{vv}).(S_{hh}+S_{vv})^{*} \f$
- * - channel #1 : \f$ (S_{hh}+S_{vv}).(S_{hh}-S_{vv})^{*} \f$
- * - channel #2 : \f$ (S_{hh}+S_{vv}).(2*S_{hv})^{*} \f$
- * - channel #3 : \f$ (S_{hh}-S_{vv}).(S_{hh}-S_{vv})^{*} \f$
- * - channel #4 : \f$ (S_{hh}-S_{vv}).(2*S_{hv})^{*} \f$
- * - channel #5 : \f$ (2*S_{hv}).(2*S_{hv})^{*} \f$
+ * - channel #0 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}+S_{vv})^{*} \f$
+ * - channel #1 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}-S_{vv})^{*} \f$
+ * - channel #2 : \f$ 0.5*(S_{hh}+S_{vv}).(2*S_{hv})^{*} \f$
+ * - channel #3 : \f$ 0.5*(S_{hh}-S_{vv}).(S_{hh}-S_{vv})^{*} \f$
+ * - channel #4 : \f$ 0.5*(S_{hh}-S_{vv}).(2*S_{hv})^{*} \f$
+ * - channel #5 : \f$ 0.5*(2*S_{hv}).(2*S_{hv})^{*} \f$
  *
- * The output pixel has 10 channels : the diagonal and the upper element of the matrix.
+ * The output pixel has 16 channels
  * Element are stored from left to right, line by line.
  *
  * \ingroup SARPolarimetry
@@ -72,17 +82,28 @@ public:
     const double T1 = static_cast<double>(Coherency[0].real());
     const double T2 = static_cast<double>(Coherency[3].real());
     const double T3 = static_cast<double>(Coherency[5].real());
-
-    result[0] = 0.5*(T1+T2+T3);                               // A0+B0
-    result[1] = 0.5*(T1+T2-T3);                               // A0+B
-    result[2] = 0.5*(T1-T2+T3);                               // A0-B
-    result[3] = 0.5*(-T1+T2+T3);                              // -A0+B0
-    result[4] = static_cast<double>( Coherency[1].real() );  // C
-    result[5] = static_cast<double>( Coherency[2].real() );  // H
-    result[6] = static_cast<double>( Coherency[4].imag() );  // F
-    result[7] = static_cast<double>( Coherency[4].real() );  // E
-    result[8] = static_cast<double>( Coherency[2].imag() );  // G
-    result[9] = -static_cast<double>( Coherency[1].imag() ); // D
+    
+    ComplexType VAL4 = static_cast<ComplexType>( (Coherency[1] - Coherency[3]) );
+    ComplexType VAL5 = static_cast<ComplexType>( (Coherency[1] - Coherency[0]) );
+	ComplexType VAL0 = static_cast<ComplexType>( Coherency[5] ) + VAL5 - vcl_conj(VAL4);
+    ComplexType VAL1 = static_cast<ComplexType>( -Coherency[5] ) + VAL5 - vcl_conj(VAL4);
+
+    result[0] = 0.5*(T1+T2+T3);                               
+    result[1] = static_cast<double>( Coherency[1].real()+Coherency[3].imag() );
+    result[2] = static_cast<double>( Coherency[2].real() );   
+    result[3] = static_cast<double>( Coherency[4].imag() );                           
+    result[4] = static_cast<double>( Coherency[1].real() );  
+    result[5] = 0.5*(T1+T2-T3); 
+    result[6] = static_cast<double>( Coherency[4].real() );
+    result[7] = static_cast<double>( Coherency[2].imag() ); 
+    result[8] = static_cast<double>( -Coherency[2].real() );
+    result[9] = static_cast<double>( -Coherency[4].real() );
+	result[10] = static_cast<double>( 0.5*VAL1.real() ); 
+	result[11] = static_cast<double>( 0.5*VAL0.imag() ); 
+	result[12] = static_cast<double>( Coherency[4].imag() ); 
+	result[13] = static_cast<double>( Coherency[2].imag() );
+	result[14] = static_cast<double>( 0.5*vcl_conj(VAL1).imag() ); 
+	result[15] = static_cast<double>( 0.5*VAL0.real() ); 
 
     return result;
     }
@@ -99,7 +120,7 @@ public:
    virtual ~ReciprocalCoherencyToReciprocalMuellerFunctor() {}
 
 private:
-   itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 10);
+   itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 16);
 };
 }
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
index 3ad4b0b79e093552605135c1ac7be75493ead173..f34b83c5035cb68cb302dfa1856a282298d65e9f 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
@@ -30,12 +30,12 @@ namespace Functor {
  * \brief Evaluate the Coherency matrix from the Covariance image
  *
  * Output value are:
- * - channel #0 : \f$ 0.5 * (S_{hh}+S_{vv}.(S_{hh}+S_{vv})^{*} \f$
- * - channel #1 : \f$ 0.5 * (S_{hh}+S_{vv}.(S_{hh}-S_{vv})^{*} \f$
- * - channel #2 : \f$ (S_{hh}+S_{vv}.(S_{hv})^{*} \f$
- * - channel #3 : \f$ 0.5 * (S_{hh}-S_{vv}.(S_{hh}-S_{vv})^{*} \f$
- * - channel #4 : \f$ (S_{hh}-S_{vv}.(S_{hv})^{*} \f$
- * - channel #5 : \f$ 2.0*S_{hv}.S_{hv}^{*} \f$
+ * - channel #0 : \f$ 0.5 . (C33 + C13 + C13^{*} + C11) \f$
+ * - channel #1 : \f$ 0.5 . (-C33 - C13 + C13^{*} + C11) \f$
+ * - channel #2 : \f$ 0.5 . (\sqrt{2}.C12 + \sqrt{2}.C23^{*}) \f$
+ * - channel #3 : \f$ 0.5 . (C33 - C13 - C13^{*} + C11 \f$)
+ * - channel #4 : \f$ 0.5 . (\sqrt{2}.C12 - \sqrt{2}.C23^{*}) \f$
+ * - channel #5 : \f$ 0.5 . (2 . C22) \f$
  *
  * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
@@ -61,31 +61,25 @@ public:
     TOutput result;
     result.SetSize(m_NumberOfComponentsPerPixel);
 
-    /* Using the convention
-     * \f$ C_{11} = S_{hh}*S_{hh}^* \f$
-     * \f$ C_{12} = S_{hh}*S_{hv}^* \f$
-     * \f$ C_{13} = S_{hh}*S_{vv}^* \f$
-     * \f$ C_{22} = S_{hv}*S_{hv}^* \f$
-     * \f$ C_{23} = S_{hv}*S_{vv}^* \f$
-     * \f$ C_{33} = S_{vv}*S_{vv}^* \f$
-     */
+   
     const ComplexType C11 =  static_cast<ComplexType>(Covariance[0]);
     const ComplexType C12 =  static_cast<ComplexType>(Covariance[1]);
     const ComplexType C13 =  static_cast<ComplexType>(Covariance[2]);
     const ComplexType C22 =  static_cast<ComplexType>(Covariance[3]);
     const ComplexType C23 =  static_cast<ComplexType>(Covariance[4]);
     const ComplexType C33 =  static_cast<ComplexType>(Covariance[5]);
-
-    //const ComplexType C21 =  vcl_conj(C12);
-    const ComplexType C31 =  vcl_conj(C13);
-    const ComplexType C32 =  vcl_conj(C23);
-
-    result[0] = static_cast<OutputValueType>( 0.5*(C11 + C13 + C31 + C33) );
-    result[1] = static_cast<OutputValueType>( 0.5*(C11 - C13 + C31 - C33) );
-    result[2] = static_cast<OutputValueType>( C12 + C32 );
-    result[3] = static_cast<OutputValueType>( 0.5*(C11 - C13 - C31 + C33) );
-    result[4] = static_cast<OutputValueType>( C12 - C32 );
-    result[5] = static_cast<OutputValueType>( 2.0 * C22 );
+    
+    const ComplexType two = ComplexType(2.0, 0.0);
+    const ComplexType rootTwo = ComplexType(vcl_sqrt(2.0), 0.0);
+    
+    result[0] = static_cast<OutputValueType>( C33 + C13 + vcl_conj(C13) + C11 );
+    result[1] = static_cast<OutputValueType>( -C33 - C13 + vcl_conj(C13) + C11 );
+    result[2] = static_cast<OutputValueType>( rootTwo*C12 + rootTwo*vcl_conj(C23) );
+    result[3] = static_cast<OutputValueType>( C33 - C13 - vcl_conj(C13) + C11 );
+    result[4] = static_cast<OutputValueType>( rootTwo*C12 - rootTwo*vcl_conj(C23) );
+    result[5] = static_cast<OutputValueType>( two * C22 );
+
+    result /= 2.0;
 
     return result;
     }
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
index 227b46a90d9f99523c1e70ece1d0784f24ad4b7b..8a8caa7b31c69756801047673bbab3706c614945 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
@@ -20,6 +20,7 @@
 #define __ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter_h
 
 #include "itkUnaryFunctorImageFilter.h"
+#include "vcl_complex.h"
 
 namespace otb
  {
@@ -31,23 +32,14 @@ namespace Functor {
  *  Extract from Antennas for radar and communications Harold Mott p 317.
  *
  *  Output value are:
- *  - channel #0 : \f$ 0.25 * (C_{1}+C_{3}+4*C_{2}-2*C_{6}-4*C_{5}-4*C_{9}) \f$
- *  - channel #1 : \f$ 0.25 * (C_{1}-C_{3}+2*C_{5}+2*C_{9} - 0.5\mathcal{i}.(C_{4}+C_{7}+C_{8}) \f$
- *  - channel #2 : \f$ 0.25 * (C_{1}+C_{3}-4*C_{2}-2*C_{6} - \mathcal{i}.(C_{4}+C_{8}) \f$
- *  - channel #3 : \f$ 0.25 * (C_{1}+C_{3}+2*C_{6} \f$
- *  - channel #4 : \f$ 0.25 * (C_{1}-C_{3}+2*C_{5}-2*C_{9} - 0.5\mathcal{i}.(C_{4}-C_{7}+C_{8}) \f$
- *  - channel #5 : \f$ 0.25 * (C_{1}+C_{3}+4*C_{2}-2*C_{6}+4*C_{5}+4*C_{9}) \f$
+ *  - channel #0 : \f$ 0.25 * (C33-i.\sqrt{2}.C23-C13+i.\sqrt{2}.C23^{*}-C13^{*}+2.C22-i.\sqrt{2}.C12+i.\sqrt{2}.C12^{*}+C11) \f$
+ *  - channel #1 : \f$ 0.25 * (i.\sqrt{2}.C33+2.C23-i.\sqrt{2}.C13+i.\sqrt{2}.C13^{*}+2.C12^{*}-i.\sqrt{2}.C11) \f$
+ *  - channel #2 : \f$ 0.25 * (-C33+i.\sqrt{2}.C23+C13+i.\sqrt{2}.C23^{*}+C13^{*}+2.C22-i.\sqrt{2}.C12-i.\sqrt{2}.C12^{*}-C11 ) \f$
+ *  - channel #3 : \f$ 0.25 * (2.C33+2.C13+2.C13^{*}+2.C11)\f$
+ *  - channel #4 : \f$ 0.25 * (i.\sqrt{2}.C33+i.\sqrt{2}.C13+2.C23^{*}-i.\sqrt{2}.C13^{*}+2.C12-i.\sqrt{2}.C11) \f$
+ *  - channel #5 : \f$ 0.25 * (C33+i.\sqrt{2}.C23-C13-i.\sqrt{2}.C23^{*}-C13^{*}+2.C22+i.\sqrt{2}.C12-i.\sqrt{2}.C12^{*}+C11) \f$
  *
- *  Where:
- *  - \f$ C_{1} = S_{hh}*S_{hh}}^{*} = \mathcal{Re}(input[0]) \f$
- *  - \f$ C_{2} = S_{hv}*S_{hv}}^{*} = \mathcal{Re}(input[3]) \f$
- *  - \f$ C_{3} = S_{vv}*S_{vv}}^{*} = \mathcal{Re}(input[5]) \f$
- *  - \f$ C_{4} = \mathcal{Re}(S_{hh}*S_{hv}}^{*}) = \mathcal{Re}(input[1]) \f$
- *  - \f$ C_{5} = \mathcal{Im}(S_{hh}*S_{hv}}^{*}) = \mathcal{Im}(input[1]) \f$
- *  - \f$ C_{6} = \mathcal{Re}(S_{hh}*S_{vv}}^{*}) = \mathcal{Re}(input[2]) \f$
- *  - \f$ C_{7} = \mathcal{Im}(S_{hh}*S_{vv}}^{*}) = \mathcal{Im}(input[2]) \f$
- *  - \f$ C_{8} = \mathcal{Re}(S_{hv}*S_{vv}}^{*}) = \mathcal{Re}(input[4]) \f$
- *  - \f$ C_{9} = \mathcal{Im}(S_{hv}*S_{vv}}^{*} = \mathcal{Im}(input[4])) \f$
+ *  Where Cij are related to the elements of the reciprocal linear covariance matrix.
  *
  * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
@@ -74,32 +66,27 @@ public:
     TOutput result;
     result.SetSize(m_NumberOfComponentsPerPixel);
     result.Fill(0.0);
-
-    const RealType C1 =  static_cast<RealType>(Covariance[0].real()); // C1  <hh.hh*>
-    const RealType C2 =  static_cast<RealType>(Covariance[3].real()); // C2  <hv.hv*>
-    const RealType C3 =  static_cast<RealType>(Covariance[5].real()); // C3  <vv.vv*>
-    const RealType C4 =  static_cast<RealType>(Covariance[1].real()); // C4  Re<hh.hv*>
-    const RealType C5 =  static_cast<RealType>(Covariance[1].imag()); // C5  Im<hh.hv*>
-    const RealType C6 =  static_cast<RealType>(Covariance[2].real()); // C6  Re<hh.vv*>
-    const RealType C7 =  static_cast<RealType>(Covariance[2].imag()); // C7  Im<hh.vv*>
-    const RealType C8 =  static_cast<RealType>(Covariance[4].real()); // C8  Re<hv.vv*>
-    const RealType C9 =  static_cast<RealType>(Covariance[4].imag()); // C9  Im<hv.vv*>
-
-    const RealType llrrReal = 0.25 * ( C1 + C3 - 4*C2 -2*C6);
-    const RealType llrrImag = -(C4 + C8);
-
-    const RealType lllrReal = 0.25 * ( C1 - C3 - 2*C5 + 2*C9);
-    const RealType lllrImag = -0.5*(C7+C4+C8);
-
-    const RealType rrlrReal = 0.25 * ( C1 -C3 + 2*C5 - 2*C9);
-    const RealType rrlrImag = 0.5 * (C4+C8-C7);
-
-    result[0] = ComplexType(0.25 * ( C1 + C3 + 4*C2 - 2*C6 - 4*C5 - 4*C9));
-    result[1] = ComplexType(lllrReal, lllrImag);
-    result[2] = ComplexType(llrrReal, llrrImag);
-    result[3] = ComplexType(0.25 * ( C1 + C3 + 2*C6));
-    result[4] = ComplexType(rrlrReal, -rrlrImag);
-    result[5] = ComplexType(0.25 * ( C1 + C3 + 4*C2 - 2*C6 + 4*C5 + 4*C9));
+    
+    
+    const ComplexType C11 =  static_cast<ComplexType>(  Covariance[0]    );     //   <hh.hh*>
+    const ComplexType C12 =  static_cast<ComplexType>(  Covariance[1]    );     //   <sqrt(2).hh.hv*>
+    const ComplexType C13 =  static_cast<ComplexType>(  Covariance[2]    );     //   <hh.vv*>
+    const ComplexType C22 =  static_cast<ComplexType>(  Covariance[3]    );     //   <2.hv.hv*>
+    const ComplexType C23 =  static_cast<ComplexType>(  Covariance[4]    );     //   <sqrt(2).hv.vv*>
+    const ComplexType C33 =  static_cast<ComplexType>(  Covariance[5]    );     //   <vv.vv*>
+    
+    
+    const ComplexType cst1 = ComplexType(0.0, vcl_sqrt(2.0));
+    const ComplexType two = ComplexType(2.0, 0 );
+
+    result[0] = static_cast<ComplexType>( C33-cst1*C23-C13+cst1*vcl_conj(C23)-vcl_conj(C13)+two*C22-cst1*C12+cst1*vcl_conj(C12)+C11  ) ;
+    result[1] = static_cast<ComplexType>( cst1*C33+two*C23-cst1*C13+cst1*vcl_conj(C13)+two*vcl_conj(C12)-cst1*C11 );
+    result[2] = static_cast<ComplexType>( -C33+cst1*C23+C13+cst1*vcl_conj(C23)+vcl_conj(C13)+two*C22-cst1*C12-cst1*vcl_conj(C12)-C11  ) ;
+    result[3] = static_cast<ComplexType>( two*C33+two*C13+two*vcl_conj(C13)+two*C11 ) ;
+    result[4] = static_cast<ComplexType>( cst1*C33+cst1*C13+two*vcl_conj(C23)-cst1*vcl_conj(C13)+two*C12-cst1*C11 ) ;
+    result[5] = static_cast<ComplexType>( C33+cst1*C23-C13-cst1*vcl_conj(C23)-vcl_conj(C13)+two*C22+cst1*C12-cst1*vcl_conj(C12)+C11 ) ;
+
+	result /= 4.0;
 
     return result;
     }
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h
index c3d4f81404863d17f6b9bcd8ae54354d2b35d4eb..08e10da87a53b51cbd79ae565c598240911c4965 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h
@@ -42,9 +42,9 @@ namespace Functor
  *  - channel #9 : \f$ S_{rr}.S_{rr}^{*} \f$
  *
  * With:
- * - \f$ S_{ll} = 0.5 * (-S_{hh}-i*S_{hv}-i*S_{vh}+S_{vv}) \f$
- * - \f$ S_{lr} = 0.5 * (-S_{hh}+i*S_{hv}-i*S_{vh}+S_{vv}) \f$
- * - \f$ S_{rl} = 0.5 * (-S_{hh}-i*S_{hv}+i*S_{vh}-S_{vv}) \f$
+ * - \f$ S_{ll} = 0.5 * (S_{hh}+i*S_{hv}+i*S_{vh}-S_{vv}) \f$
+ * - \f$ S_{lr} = 0.5 * (i*S_{hh}+S_{hv}-S_{vh}+i*S_{vv}) \f$
+ * - \f$ S_{rl} = 0.5 * (i*S_{hh}-S_{hv}+S_{vh}+i*S_{vv}) \f$
  * - \f$ S_{rr} = 0.5 * (-S_{hh}+i*S_{hv}+i*S_{vh}+S_{vv}) \f$
  *
  * Extract from Antennas for radar and communications Harold Mott p 317.
@@ -89,12 +89,14 @@ public:
     result.SetSize(m_NumberOfComponentsPerPixel);
     const ComplexType jS_hv = S_hv * ComplexType(0., 1.);
     const ComplexType jS_vh = S_vh * ComplexType(0., 1.);
-
+    const ComplexType jS_hh = S_hh * ComplexType(0., 1.);
+    const ComplexType jS_vv = S_vv * ComplexType(0., 1.);
+    
     const ComplexType coef(0.5);
 
-    const ComplexType Sll = coef*( -S_hh-jS_hv-jS_vh+S_vv );
-    const ComplexType Slr = coef*( -S_hh+jS_hv-jS_vh-S_vv );
-    const ComplexType Srl = coef*( -S_hh-jS_hv+jS_vh-S_vv );
+    const ComplexType Sll = coef*( S_hh+jS_hv+jS_vh-S_vv );
+    const ComplexType Slr = coef*( jS_hh+S_hv-S_vh+jS_vv );
+    const ComplexType Srl = coef*( jS_hh-S_hv+S_vh+jS_vv );
     const ComplexType Srr = coef*( -S_hh+jS_hv+jS_vh+S_vv );
 
     //const ComplexType conjSll = vcl_conj(Sll);
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h
index 5d31c330b76a66d0ddd7d8230cb00a06aae11bae..4bd338ccef5c7dbf1fcdd8eb92b79723a925ccf1 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h
@@ -50,8 +50,8 @@ namespace Functor
  * With :
  * - \f$ T_{xx} = -S_{hh} \f$
  * - \f$ T_{xy} = -S_{hv} \f$
- * - \f$ T_{yx} = -S_{vh} \f$
- * - \f$ T_{yy} = -S_{vv} \f$
+ * - \f$ T_{yx} = S_{vh} \f$
+ * - \f$ T_{yy} = S_{vv} \f$
  *
  * Output is a not a complex. The output pixel has 16 channels : each element of the Mueller matrix.
  * The order of the channels corresponds to :
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
index 53c62b6339bd7760c3f6ec3cdedfc0ec28c548ec..7dbb8322dc7cd0f7f01a5d0f0cd21f20c65c8c3b 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
@@ -80,14 +80,14 @@ public:
     const ComplexType coef(0.5);
 
     const ComplexType j2S_hv = S_hv * ComplexType(0.0, 2.0);
+    const ComplexType jS_hh = S_hh * ComplexType(0.0, 1.0);
+    const ComplexType jS_vv = S_vv * ComplexType(0.0, 1.0);
 
-    const ComplexType Sll = coef * ( -S_hh-j2S_hv+S_vv );
-    const ComplexType Slr = coef * ( -S_hh+-S_vv );
+
+    const ComplexType Sll = coef * ( S_hh+j2S_hv-S_vv );
+    const ComplexType Slr = coef * ( jS_hh + jS_vv );
     const ComplexType Srr = coef * ( -S_hh+j2S_hv+S_vv );
 
-    //const ComplexType conjSll = vcl_conj(Sll);
-    //const ComplexType conjSlr = vcl_conj(Slr);
-    //const ComplexType conjSrr = vcl_conj(Srr);
 
     SinclairToReciprocalCovarianceFunctorType funct;
     return ( funct(Sll, Slr, Srr ) );
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
index 98c7bba8edc51233f4a44b05522198f19515ff10..8ad714abef0d6c103c84e882489cf7d3fa634226 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
@@ -30,10 +30,10 @@ namespace Functor
  *
  *  Output value are:
  *  - channel #0 : \f$ S_{hh}.S_{hh}^{*} \f$
- *  - channel #1 : \f$ S_{hh}.S_{hv}^{*} \f$
+ *  - channel #1 : \f$ \sqrt{2}.S_{hh}.S_{hv}^{*} \f$
  *  - channel #2 : \f$ S_{hh}.S_{vv}^{*} \f$
- *  - channel #3 : \f$ S_{hv}.S_{hv}^{*} \f$
- *  - channel #4 : \f$ S_{hv}.S_{vv}^{*} \f$
+ *  - channel #3 : \f$ 2.S_{hv}.S_{hv}^{*} \f$
+ *  - channel #4 : \f$ \sqrt{2}.S_{hv}.S_{vv}^{*} \f$
  *  - channel #5 : \f$ S_{vv}.S_{vv}^{*} \f$
  *
  * This is a adaptation of the SinclairToCovarianceMatrixFunctor, where \f$ S_{hv}=S_{vh} \f$.
@@ -71,12 +71,12 @@ public:
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
-
+    
     result[0] = static_cast<OutputValueType>( std::norm( S_hh ) );
-    result[1] = static_cast<OutputValueType>( S_hh*vcl_conj(S_hv) );
+    result[1] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hh*vcl_conj(S_hv) );
     result[2] = static_cast<OutputValueType>( S_hh*vcl_conj(S_vv) );
-    result[3] = static_cast<OutputValueType>( std::norm( S_hv ) );
-    result[4] = static_cast<OutputValueType>( S_hv*vcl_conj(S_vv) );
+    result[3] = static_cast<OutputValueType>( 2.0*std::norm( S_hv ) );
+    result[4] = static_cast<OutputValueType>( vcl_sqrt(2.0)*S_hv*vcl_conj(S_vv) );
     result[5] = static_cast<OutputValueType>( std::norm( S_vv ) );
 
     return (result);
diff --git a/Modules/Filtering/Polarimetry/test/CMakeLists.txt b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
index f5657bab1c4723d1e3a977c4e2fa0cb725194698..c3825403977252f806d4e27ec4fa085eefcdbb5e 100644
--- a/Modules/Filtering/Polarimetry/test/CMakeLists.txt
+++ b/Modules/Filtering/Polarimetry/test/CMakeLists.txt
@@ -72,7 +72,7 @@ otb_add_test(NAME saTuReciprocalLinearCovarianceToReciprocalCircularCovarianceIm
   )
 
 otb_add_test(NAME saTvReciprocalCovarianceToReciprocalCoherencyImageFilter COMMAND otbPolarimetryTestDriver
-  --compare-image ${EPSILON_12}   ${BASELINE}/saTvMLCToCoherencyImageFilter.tif
+  --compare-image ${EPSILON_12}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif
   ${TEMP}/saTvMLCToCoherencyImageFilter.tif
   otbReciprocalCovarianceToReciprocalCoherencyImageFilter
   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
@@ -291,7 +291,7 @@ otb_add_test(NAME saTvSinclairReciprocalImageFilter_SinclairToReciprocalCoherenc
  
 
 otb_add_test(NAME saTvReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter COMMAND otbPolarimetryTestDriver
-  --compare-image ${EPSILON_12}   ${BASELINE}/saTvMLCToCircularCoherencyDegreeImageFilter.tif
+  --compare-image ${EPSILON_12}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCircularCovarianceMatrix.tif
   ${TEMP}/saTvMLCToCircularCoherencyDegreeImageFilter.tif
   otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
@@ -299,7 +299,7 @@ otb_add_test(NAME saTvReciprocalLinearCovarianceToReciprocalCircularCovarianceIm
   )
 
 otb_add_test(NAME saTvReciprocalCoherencyToReciprocalMuellerImageFilter COMMAND otbPolarimetryTestDriver
-  --compare-image ${EPSILON_12}   ${BASELINE}/saTvReciprocalCoherencyToMuellerImageFilter.tif
+  --compare-image ${EPSILON_12}   ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif 
   ${TEMP}/saTvReciprocalCoherencyToMuellerImageFilter.tif
   otbReciprocalCoherencyToReciprocalMuellerImageFilter
   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCoherency.tif
@@ -315,7 +315,7 @@ otb_add_test(NAME saTuReciprocalCovarianceToCoherencyDegreeImageFilterNew COMMAN
   )
 
 otb_add_test(NAME saTvMuellerToReciprocalCovarianceImageFilter COMMAND otbPolarimetryTestDriver
-  --compare-image ${EPSILON_12}   ${BASELINE}/saTvMuellerToMLCImageFilter.tif
+  --compare-image ${EPSILON_12}   ${BASELINE}/saTvSinclairImageFilter_SinclairToReciprocalCovariance.tif
   ${TEMP}/saTvMuellerToMLCImageFilter.tif
   otbMuellerToReciprocalCovarianceImageFilter
   ${BASELINE}/saTvSinclairImageFilter_SinclairToMueller.tif
diff --git a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
index e52054bd84825297e2fc4ae96b0c31f18e06206e..db596e64ebcca9b864e8e457e095775a9fd8fdde 100644
--- a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
@@ -43,12 +43,12 @@ int otbMuellerToReciprocalCovarianceFunctor(int itkNotUsed(argc), char * itkNotU
       val += 0.5;
     }
 
-  result[0] = ComplexType(2.5, 0.);
-  result[1] = ComplexType(4., 5.);
-  result[2] = ComplexType(-6.25, 0.75);
-  result[3] = ComplexType(-8, 0.);
-  result[4] = ComplexType(0.5, -0.5);
-  result[5] = ComplexType(0., 0.);
+  result[0] = ComplexType(1.75,0);
+  result[1] = ComplexType(2.82842712474619,3.53553390593274);
+  result[2] = ComplexType(-6.25,-5.5);
+  result[3] = ComplexType(-2.5,0);
+  result[4] = ComplexType(-1.4142135623731,-1.4142135623731);
+  result[5] = ComplexType(0.75,0);
 
   FunctorType funct;
   outputFunct = funct.operator ()( input );
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
index c883bdef933ac1ec90774d660e887c80d54bf66a..030cc9b5d4fdcecd6a6bacd7530423a2cde0baed 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
@@ -31,14 +31,14 @@ int otbSinclairToCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * it
   OutputType outputFunct;
 
   result[0] = ComplexType( 32.,  0. );
-  result[1] = ComplexType(  0., 24. );
-  result[2] = ComplexType(  0., 16.);
-  result[3] = ComplexType( -8.,   0  );
+  result[1] = ComplexType(  24., 0. );
+  result[2] = ComplexType(  16., 0.);
+  result[3] = ComplexType( 8.,   0  );
   result[4] = ComplexType( 18.,   0. );
   result[5] = ComplexType( 12. ,  0. );
-  result[6] = ComplexType(  0. ,  6. );
+  result[6] = ComplexType(  6. ,  0. );
   result[7] = ComplexType(  8,    0. );
-  result[8] = ComplexType(  0,    4. );
+  result[8] = ComplexType(  4.,   0. );
   result[9] = ComplexType(  2,    0. );
 
   outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) );
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
index 18c8d486a0e19f3b05b6e44e1a370b20e31c1b7f..af4666a19856e67e98264dbaff90863a30a8b0d6 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
@@ -31,11 +31,11 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc),
   OutputType outputFunct;
 
   result[0] = ComplexType( 25.,  0.);
-  result[1] = ComplexType(  1., 18.);
-  result[2] = ComplexType(-11.,  2.);
-  result[3] = ComplexType( 13.,  0.);
-  result[4] = ComplexType(  1.,  8.);
-  result[5] = ComplexType(  5.,  0.);
+  result[1] = ComplexType( 25.4558441227157,-1.4142135623731);
+  result[2] = ComplexType( 11.,  -2.);
+  result[3] = ComplexType( 26.,  0.);
+  result[4] = ComplexType( 11.3137084989848,-1.41421356237309);
+  result[5] = ComplexType( 5, .0);
 
   outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) );
 
@@ -46,6 +46,7 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc),
       vcl_abs(result[4]-outputFunct[4]) > 1e-10 ||
       vcl_abs(result[5]-outputFunct[5]) > 1e-10   )
   {
+	  std::cout.precision(15);
     std::cout<<"Test gives :"<<std::endl;
     std::cout<<outputFunct<<std::endl;
     std::cout<<"Wanted results are :"<<std::endl;
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
index 36ee6b133758ed2d680afa01fe146a129352ee56..bdf3ce3a36542b1365b8e07eaf23700fef75be57 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
@@ -32,10 +32,10 @@ int otbSinclairToReciprocalCovarianceMatrixFunctor(int itkNotUsed(argc), char *
   OutputType outputFunct;
 
   result[0] = ComplexType(17.,  0.);
-  result[1] = ComplexType(14.,  5.);
+  result[1] = ComplexType(19.7989898732233,7.07106781186548);
   result[2] = ComplexType(11., 10.);
-  result[3] = ComplexType(13.,  0.);
-  result[4] = ComplexType(12.,  5.);
+  result[3] = ComplexType(26.,  0.);
+  result[4] = ComplexType(16.9705627484771,7.07106781186548);
   result[5] = ComplexType(13.,  0.);
 
   outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) );
diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h
index 2b5c5a7f4d7c5c2af5f873172a490d6ca4c1db68..9442c163080f9e2770395788828ccfacdee21dae 100644
--- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h
+++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h
@@ -264,6 +264,9 @@ public:
     m_Resampler->SetDisplacementFilterNumberOfThreads(nbThread);
   }
 
+  /** Override itk::ProcessObject method to let the internal filter do the propagation */
+  virtual void PropagateRequestedRegion(itk::DataObject *output);
+
 protected:
   GenericRSResampleImageFilter();
   /** Destructor */
@@ -273,8 +276,6 @@ protected:
 
   virtual void GenerateOutputInformation();
 
-  virtual void GenerateInputRequestedRegion();
-
   virtual void UpdateTransform();
 
   void PrintSelf(std::ostream& os, itk::Indent indent) const;
diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
index 42eedb9ba479812413b7fae52aacad766fc6a243..a18dabf09aa8fb846a47750566db9bc813af35b7 100644
--- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
+++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.txx
@@ -67,7 +67,7 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
   progress->RegisterInternalFilter(m_Resampler, 1.f);
 
   m_Resampler->GraftOutput(this->GetOutput());
-  m_Resampler->Update();
+  m_Resampler->UpdateOutputData(m_Resampler->GetOutput());
   this->GraftOutput(m_Resampler->GetOutput());
 }
 
@@ -82,20 +82,8 @@ void
 GenericRSResampleImageFilter<TInputImage, TOutputImage>
 ::GenerateOutputInformation()
 {
-  // call the superclass's implementation of this method
-  Superclass::GenerateOutputInformation();
-
   typename OutputImageType::Pointer outputPtr = this->GetOutput();
 
-  outputPtr->SetSpacing( this->GetOutputSpacing() );
-  outputPtr->SetOrigin( this->GetOutputOrigin() );
-
-  typename OutputImageType::RegionType region;
-  region.SetSize(this->GetOutputSize());
-  region.SetIndex(this->GetOutputStartIndex() );
-
-  outputPtr->SetLargestPossibleRegion(region);
-
   // Get the Output MetaData Dictionary
   itk::MetaDataDictionary& dict = outputPtr->GetMetaDataDictionary();
 
@@ -112,6 +100,13 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
   // Estimate the output rpc Model if needed
   if (m_EstimateOutputRpcModel)
     this->EstimateOutputRpcModel();
+
+  m_Resampler->SetInput(this->GetInput());
+  m_Resampler->SetTransform(m_Transform);
+  m_Resampler->SetDisplacementFieldSpacing(this->GetDisplacementFieldSpacing());
+  m_Resampler->GraftOutput(this->GetOutput());
+  m_Resampler->UpdateOutputInformation();
+  this->GraftOutput(m_Resampler->GetOutput());
 }
 
 /**
@@ -128,7 +123,11 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
   // Temp image : not allocated but with the same metadata than the
   // output
   typename OutputImageType::Pointer tempPtr = OutputImageType::New();
-  tempPtr->SetRegions(this->GetOutput()->GetLargestPossibleRegion());
+
+  typename OutputImageType::RegionType region;
+  region.SetSize(this->GetOutputSize());
+  region.SetIndex(this->GetOutputStartIndex() );
+  tempPtr->SetRegions(region);
 
   // Encapsulate the output metadata in the temp image
   itk::MetaDataDictionary& tempDict = tempPtr->GetMetaDataDictionary();
@@ -171,41 +170,26 @@ GenericRSResampleImageFilter<TInputImage, TOutputImage>
   m_Transform->InstanciateTransform();
 }
 
- /**
-  * Generate Input requested region does only propagate the output
-  * requested region.
-  */
- template <class TInputImage, class TOutputImage>
- void
- GenericRSResampleImageFilter<TInputImage, TOutputImage>
- ::GenerateInputRequestedRegion()
- {
-   // Retrieve output pointer
-   OutputImageType * outputPtr = this->GetOutput();
-
-   // Retrieve input pointer
-   const InputImageType * inputPtr = this->GetInput();
-
-   // Retrieve output requested region
-   RegionType requestedRegion = outputPtr->GetRequestedRegion();
-
-   // Estimate the input rpc model if it is needed
-   if (m_EstimateInputRpcModel && !m_RpcEstimationUpdated)
-     {
-     this->EstimateInputRpcModel();
-     }
-
-   // Instanciate the RS transform
-   this->UpdateTransform();
-
-   // Generate input requested region
-   m_Resampler->SetInput(inputPtr);
-   m_Resampler->SetTransform(m_Transform);
-   m_Resampler->SetDisplacementFieldSpacing(this->GetDisplacementFieldSpacing());
-   m_Resampler->GetOutput()->UpdateOutputInformation();
-   m_Resampler->GetOutput()->SetRequestedRegion(requestedRegion);
-   m_Resampler->GetOutput()->PropagateRequestedRegion();
- }
+template <class TInputImage, class TOutputImage>
+void
+GenericRSResampleImageFilter<TInputImage, TOutputImage>
+::PropagateRequestedRegion(itk::DataObject *output)
+{
+  if (this->m_Updating) return;
+
+  // Estimate the input rpc model if it is needed
+  if (m_EstimateInputRpcModel && !m_RpcEstimationUpdated)
+    {
+    this->EstimateInputRpcModel();
+    }
+
+  // Instanciate the RS transform
+  this->UpdateTransform();
+
+  // Retrieve output requested region
+  m_Resampler->GetOutput()->SetRequestedRegion(output);
+  m_Resampler->GetOutput()->PropagateRequestedRegion();
+}
 
 
  /**
diff --git a/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx b/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx
index 32172e5b4ad969ae2859b0f251dff1a7db17942d..2a2a030b36e0fe027a133f51fb461646cbf4c93b 100644
--- a/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx
+++ b/Modules/Hyperspectral/Unmixing/include/otbMDMDNMFImageFilter.txx
@@ -193,13 +193,13 @@ MDMDNMFImageFilter<TInputImage, TOutputImage>
   //    = (A*S-X) * (transpose(S)) + m_LambdD*(A-1/nbBands*ones(L, L)*A)
   //    = (A*S-X) * (transpose(S)) + m_LambdD*A- m_LambdD*/nbBands*ones(L, L)*A)
 
-  MatrixType onesA;
   VectorType sumColulmnsOfA;
   sumColulmnsOfA.set_size(A.cols());
   unsigned int nbBands = A.rows();
 
-  // Computing vector onesA
-  for (unsigned int j=0; j<onesA.size(); ++j)
+  // Computing ones*A : all rows are the same,
+  // (ones*A)[i,j] = sum(k=0 to nbBands, A[k,j])
+  for (unsigned int j=0; j<A.cols(); ++j)
     {
     sumColulmnsOfA(j) = A.get_column(j).sum();
     }
diff --git a/Modules/Learning/LearningBase/include/otbSEMClassifier.txx b/Modules/Learning/LearningBase/include/otbSEMClassifier.txx
index afe3461be635e80be725cacfb0aaa4ddeff2fe4a..b4ef42b3e8423882433e97aa0c13ad60311989c5 100644
--- a/Modules/Learning/LearningBase/include/otbSEMClassifier.txx
+++ b/Modules/Learning/LearningBase/include/otbSEMClassifier.txx
@@ -150,7 +150,7 @@ SEMClassifier<TInputImage, TOutputImage>
   else
     {
     otbMsgDebugMacro(<< "m_ClassLabels size = " << GetClassLabels().size() << " / m_Sample size = " << m_NbSamples);
-    throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size missmatch", ITK_LOCATION);
+    throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size mismatch", ITK_LOCATION);
     }
 }
 
@@ -214,7 +214,7 @@ SEMClassifier<TInputImage, TOutputImage>
     otbMsgDebugMacro(
       << "m_ClassLabels size = " << GetClassLabels().size() << " size of the image = " << theSize <<
       " / m_Sample size = " << m_NbSamples);
-    throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size missmatch", ITK_LOCATION);
+    throw itk::ExceptionObject(__FILE__, __LINE__, "Vector size mismatch", ITK_LOCATION);
     }
 }
 
@@ -264,7 +264,7 @@ SEMClassifier<TInputImage, TOutputImage>
     typename TInputImage::SizeType size = m_Sample->GetBufferedRegion().GetSize();
     if ((size[0] * size[1]) != m_ClassLabels.size())
       throw itk::ExceptionObject(__FILE__, __LINE__,
-                                 "Vector size missmatch", ITK_LOCATION);
+                                 "Vector size mismatch", ITK_LOCATION);
     }
 }
 
@@ -315,7 +315,7 @@ SEMClassifier<TInputImage,TOutputImage>
   m_ComponentVector.clear();
   m_ComponentVector.resize(this->GetNumberOfClasses());
   m_ComponentDeclared = 0;
-  
+
 }
 
 template <class TInputImage, class TOutputImage>
@@ -353,7 +353,7 @@ SEMClassifier<TInputImage, TOutputImage>
         {
         //label = (int) floor( 0.5 + nbClassesDbl * ran / double(RAND_MAX+1) );
         label = rand() % nbClasses;
-        if (label >= nbClasses) 
+        if (label >= nbClasses)
           {
           label = nbClasses - 1;
           }
diff --git a/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx b/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx
index 4a08c8aca428b1a7a998f6ce20192c08807d20ab..efe218959c07b79c16d06361340e916908d9df80 100644
--- a/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx
+++ b/Modules/Learning/Supervised/include/otbConfusionMatrixCalculator.txx
@@ -70,7 +70,7 @@ ConfusionMatrixCalculator<TRefListLabel, TProdListLabel>
     {
     otbMsgDebugMacro(<< "refLabels size = " << m_ReferenceLabels->Size() <<
                      " / proLabels size = " << m_ProducedLabels->Size());
-    throw itk::ExceptionObject(__FILE__, __LINE__, "ListSample size missmatch", ITK_LOCATION);
+    throw itk::ExceptionObject(__FILE__, __LINE__, "ListSample size mismatch", ITK_LOCATION);
     }
 
   m_NumberOfSamples = m_ReferenceLabels->Size();
diff --git a/SuperBuild/CMake/External_gdal.cmake b/SuperBuild/CMake/External_gdal.cmake
index 7f501aad6459f5c5e7a089577f0170d6f8028e13..a76075af1adfc2996686a606df020c750f99f151 100644
--- a/SuperBuild/CMake/External_gdal.cmake
+++ b/SuperBuild/CMake/External_gdal.cmake
@@ -52,7 +52,7 @@ else()
       DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
       DEPENDS ${${proj}_DEPENDENCIES}
       UPDATE_COMMAND  ${CMAKE_COMMAND} -E copy_directory ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR}
-      PATCH_COMMAND ${CMAKE_COMMAND} -E touch ${GDAL_SB_SRC}/config.rpath COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/GDAL/GNUmakefile ${GDAL_SB_SRC}/swig/python/GNUmakefile
+      PATCH_COMMAND ${CMAKE_COMMAND} -E touch ${GDAL_SB_SRC}/config.rpath
       CONFIGURE_COMMAND
         # use 'env' because CTest launcher doesn't perform shell interpretation
         ${SB_ENV_CONFIGURE_CMD}
@@ -86,7 +86,7 @@ else()
        INSTALL_DIR ${SB_INSTALL_PREFIX}
       DOWNLOAD_DIR ${DOWNLOAD_LOCATION}
        DEPENDS ${${proj}_DEPENDENCIES}
-       PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory  ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/patches/GDAL/GNUmakefile ${GDAL_SB_SRC}/swig/python/GNUmakefile
+       PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory  ${GDAL_SB_SRC} ${GDAL_SB_BUILD_DIR}
        CONFIGURE_COMMAND  ${CMAKE_COMMAND} -E copy  ${CMAKE_SOURCE_DIR}/patches/${proj}/ogrsqlitevirtualogr.cpp
       ${GDAL_SB_BUILD_DIR}/ogr/ogrsf_frmts/sqlite/ogrsqlitevirtualogr.cpp
        BUILD_COMMAND nmake /f ${GDAL_SB_BUILD_DIR}/makefile.vc MSVC_VER=${MSVC_VERSION} EXT_NMAKE_OPT=${CMAKE_BINARY_DIR}/nmake_gdal_extra.opt
diff --git a/SuperBuild/patches/GDAL/GNUmakefile b/SuperBuild/patches/GDAL/GNUmakefile
deleted file mode 100644
index c9d481886286983c42ca8e3dc6ad6aea7d3f0859..0000000000000000000000000000000000000000
--- a/SuperBuild/patches/GDAL/GNUmakefile
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-include ../../GDALmake.opt
-
-ifndef PYTHON
-        PYTHON=python
-endif
-
-all: build
-
-BINDING = python
-include ../SWIGmake.base
-
-PACKAGE_DIR=osgeo
-SWIGOUTPUTDIR=extensions/
-
-SCRIPTS			= `ls ./scripts`
-PY_COMMANDS     =       epsg_tr.py gdalchksum.py gdal2xyz.py gcps2wld.py \
-                        gdalimport.py gdal_merge.py pct2rgb.py rgb2pct.py \
-                        gcps2vec.py
-PY_MODULES      =       ${PACKAGE_DIR}/gdal.py ${PACKAGE_DIR}/ogr.py ${PACKAGE_DIR}/osr.py ${PACKAGE_DIR}/gdalconst.py ${PACKAGE_DIR}/gdal_array.py
-
-clean:
-	-rm -f ${PACKAGE_DIR}/*.pyc
-	-rm -rf build
-	-rm -f *.pyc
-	-rm -rf *.egg-info
-	-rm -f *.so ./osgeo/*.so
-	-rm -rf dist
-
-SWIGARGS += -outdir "${PACKAGE_DIR}" 
-
-
-veryclean: clean
-	-rm -f ${WRAPPERS} ${PY_MODULES}
-	-rm -f ${SWIGOUTPUTDIR}/gdal_wrap.cpp 
-	-rm -f ${SWIGOUTPUTDIR}/gdalconst_wrap.c
-	-rm -f ${SWIGOUTPUTDIR}/ogr_wrap.cpp
-	-rm -f ${SWIGOUTPUTDIR}/osr_wrap.cpp
-	-rm -f ${SWIGOUTPUTDIR}/gdal_array_wrap.cpp
-
-gdal_wrap.cpp: ../include/python/gdal_python.i
-
-ogr_wrap.cpp: ../include/python/ogr_python.i
-
-osr_wrap.cpp: ../include/python/osr_python.i
-
-gdal_array_wrap.cpp:  ../include/gdal_array.i ../include/python/typemaps_python.i
-	$(SWIG) $(SWIGARGS) $(SWIGDEFINES) -I$(GDAL_ROOT) -c++ -$(BINDING) -o $(SWIGOUTPUTDIR)$@ gdal_array.i
-
-# A few hacks (cat, mv) : the first one for SWIG < 1.3.36 and the second one for SWIG <= 1.3.39 python 3.X on 64bit platforms
-# The python3.2.patch is from https://sourceforge.net/tracker/?func=detail&aid=3057804&group_id=1645&atid=101645
-# and is no longer necessary with swig 2.0.4
-generate: ${WRAPPERS} gdal_array_wrap.cpp
-	for i in gdal_wrap.cpp gdalconst_wrap.c ogr_wrap.cpp osr_wrap.cpp gdal_array_wrap.cpp; do sed "s/PyErr_Format(PyExc_RuntimeError, mesg)/PyErr_SetString(PyExc_RuntimeError, mesg)/" ${SWIGOUTPUTDIR}/$$i | sed "s/int len;/Py_ssize_t len;/" > ${SWIGOUTPUTDIR}/$$i.tmp; mv -f ${SWIGOUTPUTDIR}/$$i.tmp ${SWIGOUTPUTDIR}/$$i; done
-	-grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && patch -p0 < python3.2.patch
-	-grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/ogr_wrap/" | patch -p0
-	-grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/osr_wrap/" | patch -p0
-	-grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap\.cpp/gdalconst_wrap\.c/" | patch -p0
-	-grep "1\.3\.40" extensions/gdal_wrap.cpp >/dev/null && cat python3.2.patch | sed "s/gdal_wrap/gdal_array_wrap/" | patch -p0
-    
-build:
-	$(PYTHON) setup.py build
-
-egg:
-	$(PYTHON) setup.py bdist_egg 
-	
-install:
-
-ifeq ($(PY_HAVE_SETUPTOOLS),1)
-	$(PYTHON) setup.py install 
-else
-	$(PYTHON) setup.py install --prefix=$(DESTDIR) --prefix=$(prefix)
-endif
-
-	for f in $(SCRIPTS) ; do $(INSTALL) ./scripts/$$f $(DESTDIR)$(INST_BIN) ; done
-
-docs:
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrlayer_8cpp.xml ../include/python/docs/ogr_layer_docs.i OGRLayerShadow OGR_L_
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrgeometry_8cpp.xml ../include/python/docs/ogr_geometry_docs.i OGRGeometryShadow OGR_G_
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrdatasource_8cpp.xml ../include/python/docs/ogr_datasource_docs.i OGRDataSourceShadow OGR_DS_
-
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrsfdriver_8cpp.xml ../include/python/docs/ogr_driver_docs.i OGRDriverShadow OGR_Dr_
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfeature_8cpp.xml ../include/python/docs/ogr_feature_docs.i OGRFeatureShadow OGR_F_
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfeaturedefn_8cpp.xml ../include/python/docs/ogr_featuredef_docs.i OGRFeatureDefnShadow OGR_FD_
-
-	$(PYTHON) ../include/python/docs/doxy2swig.py ../../ogr/xml/ogrfielddefn_8cpp.xml ../include/python/docs/ogr_fielddef_docs.i OGRFieldDefnShadow OGR_Fld_
-
-epydoc: generate
-	epydoc --config epydoc.conf