From 79628533939f08b1adab1af887956606403d2d49 Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Wed, 30 Apr 2014 14:29:38 +0200
Subject: [PATCH] COMP: wrapperInputImageParameter : template method body put
 in header, specialized templates are placed in the cxx but they are declared
 in the header

---
 .../otbWrapperInputImageParameter.cxx         |  90 ++-----
 .../otbWrapperInputImageParameter.h           | 209 +++++-----------
 .../otbWrapperInputImageParameter.txx         | 232 ++++++++++++++++++
 3 files changed, 317 insertions(+), 214 deletions(-)
 create mode 100644 Code/ApplicationEngine/otbWrapperInputImageParameter.txx

diff --git a/Code/ApplicationEngine/otbWrapperInputImageParameter.cxx b/Code/ApplicationEngine/otbWrapperInputImageParameter.cxx
index c88d044306..623f7711fd 100644
--- a/Code/ApplicationEngine/otbWrapperInputImageParameter.cxx
+++ b/Code/ApplicationEngine/otbWrapperInputImageParameter.cxx
@@ -17,9 +17,6 @@
 =========================================================================*/
 #include "otbWrapperInputImageParameter.h"
 #include "itksys/SystemTools.hxx"
-#include "otbImageFileReader.h"
-#include "itkCastImageFilter.h"
-#include "otbImageToVectorImageCastFilter.h"
 #include "otbWrapperTypes.h"
 
 #include <boost/algorithm/string.hpp>
@@ -111,41 +108,32 @@ otbGetImageMacro(UInt8RGBImage);
 otbGetImageMacro(UInt8RGBAImage);
 
 
-template <class TInputImage, class TOutputImage>
-TOutputImage*
-InputImageParameter::SimpleCastImage()
+void
+InputImageParameter::SetImage(FloatVectorImageType* image)
 {
-  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
-
-  typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType;
-  typename CasterType::Pointer caster = CasterType::New();
-
-  caster->SetInput(realInputImage);
-  caster->UpdateOutputInformation();
-
-  m_Image = caster->GetOutput();
-  m_Caster = caster;
-
-  return caster->GetOutput();
+  m_UseFilename = false;
+  this->SetImage<FloatVectorImageType>( image );
 }
 
 
-template <class TInputImage, class TOutputImage>
-TOutputImage*
-InputImageParameter::CastVectorImageFromImage()
+bool
+InputImageParameter::HasValue() const
 {
-  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
-
-  typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType;
-  typename CasterType::Pointer caster = CasterType::New();
-
-  caster->SetInput(realInputImage);
-  caster->UpdateOutputInformation();
-
-  m_Image = caster->GetOutput();
-  m_Caster = caster;
+  if( m_FileName.empty() && m_Image.IsNull() )
+    return false;
+  else
+    return true;
+}
 
-  return caster->GetOutput();
+void
+InputImageParameter::ClearValue()
+{
+ m_Image  = NULL;
+ m_Reader = NULL;
+ m_Caster = NULL;
+ m_FileName = "";
+ m_PreviousFileName="";
+ m_UseFilename = true;
 }
 
 
@@ -202,44 +190,6 @@ otbGenericCastImageMacro(FloatImageType, CastVectorImageFromImage, Vector)
 otbGenericCastImageMacro(DoubleImageType, CastVectorImageFromImage, Vector)
 
 
-void
-InputImageParameter::SetImage(FloatVectorImageType* image)
-{
-  m_UseFilename = false;
-  this->SetImage<FloatVectorImageType>( image );
-}
-
-
-template <class TInputImage>
-void
-InputImageParameter::SetImage(TInputImage* image)
-{
-  m_UseFilename = false;
-  m_Image = image;
-}
-
-
-bool
-InputImageParameter::HasValue() const
-{
-  if( m_FileName.empty() && m_Image.IsNull() )
-    return false;
-  else
-    return true;
-}
-
-void
-InputImageParameter::ClearValue()
-{
- m_Image  = NULL;
- m_Reader = NULL;
- m_Caster = NULL;
- m_FileName = "";
- m_PreviousFileName="";
- m_UseFilename = true;
-}
-
-
 }
 }
 
diff --git a/Code/ApplicationEngine/otbWrapperInputImageParameter.h b/Code/ApplicationEngine/otbWrapperInputImageParameter.h
index 23fd78068c..4516326005 100644
--- a/Code/ApplicationEngine/otbWrapperInputImageParameter.h
+++ b/Code/ApplicationEngine/otbWrapperInputImageParameter.h
@@ -78,144 +78,7 @@ public:
 
   /** Get the input image as templated image type. */
   template <class TImageType>
-    TImageType* GetImage()
-  {
-  otbMsgDevMacro(<< "GetImage()");
-
-  // Used m_PreviousFileName because if not, when the user call twice GetImage,
-  // it without changing the filename, it returns 2 different
-  // image pointers
-  // Only one image type can be used
-
-  // 2 cases : the user set a filename vs. the user set an image
-  if (m_UseFilename)
-    {
-    if( m_PreviousFileName!=m_FileName && !m_FileName.empty() )
-      {
-      //////////////////////// Filename case:
-      // A new valid filename has been given : a reader is created
-      m_PreviousFileName = m_FileName;
-      typedef otb::ImageFileReader<TImageType> ReaderType;
-      typename ReaderType::Pointer reader = ReaderType::New();
-      reader->SetFileName(m_FileName);
-
-      try
-        {
-        reader->UpdateOutputInformation();
-        }
-      catch (itk::ExceptionObject &)
-        {
-        this->ClearValue();
-        }
-
-      m_Image = reader->GetOutput();
-      m_Reader = reader;
-
-      // Pay attention, don't return m_Image because it is a ImageBase...
-      return reader->GetOutput();
-      }
-    else
-      {
-      // In this case, the reader and the image should already be there
-      if (m_Image.IsNull())
-        {
-        itkExceptionMacro("No input image or filename detected...");
-        }
-      else
-        {
-        // Check if the image type asked here is the same as the one used for the reader
-        if (dynamic_cast<TImageType*> (m_Image.GetPointer()))
-          {
-          return dynamic_cast<TImageType*> (m_Image.GetPointer());
-          }
-        else
-          {
-          itkExceptionMacro("Cannot ask a different image type");
-          }
-        }
-      }
-    }
-  else
-    {
-    //////////////////////// Image case:
-    if (m_Image.IsNull())
-      {
-      itkExceptionMacro("No input image or filename detected...");
-      }
-    else
-      {
-      if (dynamic_cast<UInt8ImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt8ImageType, TImageType> ();
-        }
-      else if (dynamic_cast<Int16ImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<Int16ImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt16ImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt16ImageType, TImageType> ();
-        }
-      else if (dynamic_cast<Int32ImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<Int32ImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt32ImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt32ImageType, TImageType> ();
-        }
-      else if (dynamic_cast<FloatImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<FloatImageType, TImageType> ();
-        }
-      else if (dynamic_cast<DoubleImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<DoubleImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt8VectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<Int16VectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt16VectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<Int32VectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt32VectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<FloatVectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<DoubleVectorImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt8RGBAImageType, TImageType> ();
-        }
-      else if (dynamic_cast<UInt8RGBImageType*> (m_Image.GetPointer()))
-        {
-        return CastImage<UInt8RGBImageType, TImageType> ();
-        }
-      else
-        {
-        itkExceptionMacro("Unknown image type");
-        }
-      }
-    }
-  }
-
+    TImageType* GetImage();
 
   /** Set a FloatVectorImageType image.*/
   void SetImage(FloatVectorImageType* image);
@@ -225,13 +88,10 @@ public:
     void SetImage(TImageType* image);
 
 
-    /** Generic cast method that will be specified for each image type. */
+  /** Generic cast method that will be specified for each image type. */
   template <class TInputImage, class TOutputImage>
-    TOutputImage* CastImage()
-  {
-    itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TInputImage).name()<<" not authorized.");
-  }
-
+    TOutputImage* CastImage();
+    
   /** Cast an image to an image of the same type
   * Image to Image, VectorImage to VectorImage, RGBAImage to RGBAImage. */
   template <class TInputImage, class TOutputImage>
@@ -295,7 +155,68 @@ private:
 
 }; // End class InputImage Parameter
 
+
+// template specializations of CastImage<> should be declared in header
+// so that the linker knows they exist when building OTB Applications
+
+#define otbDeclareCastImageMacro(InputImageType, OutputImageType)   \
+  template<> OutputImageType *                                          \
+  InputImageParameter::CastImage<InputImageType , OutputImageType>();    \
+
+#define otbGenericDeclareCastImageMacro(InputImageType, prefix)     \
+  otbDeclareCastImageMacro(InputImageType, UInt8##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, UInt16##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, Int16##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, UInt32##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, Int32##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, Float##prefix##ImageType) \
+  otbDeclareCastImageMacro(InputImageType, Double##prefix##ImageType)
+
+  
+/*********************************************************************
+********************** Image -> Image
+**********************************************************************/
+otbGenericDeclareCastImageMacro(UInt8ImageType, )
+otbGenericDeclareCastImageMacro(Int16ImageType, )
+otbGenericDeclareCastImageMacro(UInt16ImageType, )
+otbGenericDeclareCastImageMacro(Int32ImageType, )
+otbGenericDeclareCastImageMacro(UInt32ImageType, )
+otbGenericDeclareCastImageMacro(FloatImageType, )
+otbGenericDeclareCastImageMacro(DoubleImageType, )
+
+
+/*********************************************************************
+********************** VectorImage -> VectorImage
+**********************************************************************/
+otbGenericDeclareCastImageMacro(UInt8VectorImageType, Vector)
+otbGenericDeclareCastImageMacro(Int16VectorImageType, Vector)
+otbGenericDeclareCastImageMacro(UInt16VectorImageType, Vector)
+otbGenericDeclareCastImageMacro(Int32VectorImageType, Vector)
+otbGenericDeclareCastImageMacro(UInt32VectorImageType, Vector)
+otbGenericDeclareCastImageMacro(FloatVectorImageType, Vector)
+otbGenericDeclareCastImageMacro(DoubleVectorImageType, Vector)
+
+
+/*********************************************************************
+********************** Image -> VectorImage
+**********************************************************************/
+otbGenericDeclareCastImageMacro(UInt8ImageType, Vector)
+otbGenericDeclareCastImageMacro(Int16ImageType, Vector)
+otbGenericDeclareCastImageMacro(UInt16ImageType, Vector)
+otbGenericDeclareCastImageMacro(Int32ImageType, Vector)
+otbGenericDeclareCastImageMacro(UInt32ImageType, Vector)
+otbGenericDeclareCastImageMacro(FloatImageType, Vector)
+otbGenericDeclareCastImageMacro(DoubleImageType, Vector)
+
+#undef otbDeclareCastImageMacro
+#undef otbGenericDeclareCastImageMacro
+
+
 } // End namespace Wrapper
 } // End namespace otb
 
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbWrapperInputImageParameter.txx"
+#endif
+
 #endif
diff --git a/Code/ApplicationEngine/otbWrapperInputImageParameter.txx b/Code/ApplicationEngine/otbWrapperInputImageParameter.txx
new file mode 100644
index 0000000000..df4b2a3030
--- /dev/null
+++ b/Code/ApplicationEngine/otbWrapperInputImageParameter.txx
@@ -0,0 +1,232 @@
+/*=========================================================================
+
+  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 __otbWrapperInputImageParameter_txx
+#define __otbWrapperInputImageParameter_txx
+
+#include "otbWrapperInputImageParameter.h"
+
+#include "otbImageFileReader.h"
+#include "itkCastImageFilter.h"
+#include "otbImageToVectorImageCastFilter.h"
+
+namespace otb
+{
+namespace Wrapper
+{
+
+
+template <class TImageType>
+TImageType* 
+InputImageParameter::GetImage()
+{
+  otbMsgDevMacro(<< "GetImage()");
+
+  // Used m_PreviousFileName because if not, when the user call twice GetImage,
+  // it without changing the filename, it returns 2 different
+  // image pointers
+  // Only one image type can be used
+
+  // 2 cases : the user set a filename vs. the user set an image
+  if (m_UseFilename)
+    {
+    if( m_PreviousFileName!=m_FileName && !m_FileName.empty() )
+      {
+      //////////////////////// Filename case:
+      // A new valid filename has been given : a reader is created
+      m_PreviousFileName = m_FileName;
+      typedef otb::ImageFileReader<TImageType> ReaderType;
+      typename ReaderType::Pointer reader = ReaderType::New();
+      reader->SetFileName(m_FileName);
+
+      try
+        {
+        reader->UpdateOutputInformation();
+        }
+      catch (itk::ExceptionObject &)
+        {
+        this->ClearValue();
+        }
+
+      m_Image = reader->GetOutput();
+      m_Reader = reader;
+
+      // Pay attention, don't return m_Image because it is a ImageBase...
+      return reader->GetOutput();
+      }
+    else
+      {
+      // In this case, the reader and the image should already be there
+      if (m_Image.IsNull())
+        {
+        itkExceptionMacro("No input image or filename detected...");
+        }
+      else
+        {
+        // Check if the image type asked here is the same as the one used for the reader
+        if (dynamic_cast<TImageType*> (m_Image.GetPointer()))
+          {
+          return dynamic_cast<TImageType*> (m_Image.GetPointer());
+          }
+        else
+          {
+          itkExceptionMacro("Cannot ask a different image type");
+          }
+        }
+      }
+    }
+  else
+    {
+    //////////////////////// Image case:
+    if (m_Image.IsNull())
+      {
+      itkExceptionMacro("No input image or filename detected...");
+      }
+    else
+      {
+      if (dynamic_cast<UInt8ImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt8ImageType, TImageType> ();
+        }
+      else if (dynamic_cast<Int16ImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<Int16ImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt16ImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt16ImageType, TImageType> ();
+        }
+      else if (dynamic_cast<Int32ImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<Int32ImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt32ImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt32ImageType, TImageType> ();
+        }
+      else if (dynamic_cast<FloatImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<FloatImageType, TImageType> ();
+        }
+      else if (dynamic_cast<DoubleImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<DoubleImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt8VectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<Int16VectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt16VectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<Int32VectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt32VectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<FloatVectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<DoubleVectorImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt8RGBAImageType, TImageType> ();
+        }
+      else if (dynamic_cast<UInt8RGBImageType*> (m_Image.GetPointer()))
+        {
+        return CastImage<UInt8RGBImageType, TImageType> ();
+        }
+      else
+        {
+        itkExceptionMacro("Unknown image type");
+        }
+      }
+    }
+}
+
+
+template <class TInputImage, class TOutputImage>
+TOutputImage*
+InputImageParameter::CastImage()
+{
+  itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TInputImage).name()<<" not authorized.");
+}
+
+
+template <class TInputImage, class TOutputImage>
+TOutputImage*
+InputImageParameter::SimpleCastImage()
+{
+  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
+
+  typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType;
+  typename CasterType::Pointer caster = CasterType::New();
+
+  caster->SetInput(realInputImage);
+  caster->UpdateOutputInformation();
+
+  m_Image = caster->GetOutput();
+  m_Caster = caster;
+
+  return caster->GetOutput();
+}
+
+
+template <class TInputImage, class TOutputImage>
+TOutputImage*
+InputImageParameter::CastVectorImageFromImage()
+{
+  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());
+
+  typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType;
+  typename CasterType::Pointer caster = CasterType::New();
+
+  caster->SetInput(realInputImage);
+  caster->UpdateOutputInformation();
+
+  m_Image = caster->GetOutput();
+  m_Caster = caster;
+
+  return caster->GetOutput();
+}
+
+
+template <class TInputImage>
+void
+InputImageParameter::SetImage(TInputImage* image)
+{
+  m_UseFilename = false;
+  m_Image = image;
+}
+
+
+} // End namespace Wrapper
+} // End namespace otb
+
+#endif
-- 
GitLab