diff --git a/Code/IO/otbScalarBufferToImageFileWriter.h b/Code/IO/otbScalarBufferToImageFileWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..f720d9a9dbf79e65242c961b987e5e5de39aeeb7 --- /dev/null +++ b/Code/IO/otbScalarBufferToImageFileWriter.h @@ -0,0 +1,133 @@ +/*========================================================================= + + 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 __otbScalarBufferToImageFileWriter_h +#define __otbScalarBufferToImageFileWriter_h + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "itkProcessObject.h" +#include "otbVectorImage.h" +#include "otbImageFileWriter.h" + +namespace otb +{ +/** \class ScalarBufferToImageFileWriter + * + * \brief Record an image stored in a buffer. + * + * TBufferType is the scalar buffer type, TOutputPixelType is the type in which the image will be recorded. + * User have to precise the image size, the number of channel will be computed automatically. + * The SetFilename method precises the image name. + */ + +template <class TBufferType, class TOutputPixelType=TBufferType> +class ITK_EXPORT ScalarBufferToImageFileWriter : public itk::ProcessObject +{ +public: + + typedef ScalarBufferToImageFileWriter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(ScalarBufferToImageFileWriter, itk::ProcessObject); + + /** INput typedefs */ + typedef TBufferType BufferType; + typedef TOutputPixelType OutputPixelType; + + /** Output image type */ + typedef otb::VectorImage<OutputPixelType, 2> ImageType; + typedef typename ImageType::PixelType PixelType; + typedef typename ImageType::RegionType RegionType; + typedef typename ImageType::SizeType SizeType; + typedef typename ImageType::IndexType IndexType; + + /** Writer Type*/ + typedef otb::ImageFileWriter<ImageType> WriterType; + typedef typename WriterType::Pointer WriterPointer; + + /** Filename accessor */ + otbGetObjectMemberMacro(Writer, FileName, std::string); + otbSetObjectMemberMacro(Writer, FileName, std::string); + + /** Size accessors */ + itkGetMacro(ImageSize, SizeType); + itkSetMacro(ImageSize, SizeType); + + /** Number of channels */ + itkGetMacro(NumberOfChannels, unsigned int); + itkSetMacro(NumberOfChannels, unsigned int); + + /** Inverse X spacing accessors. */ + itkGetMacro(InverseXSpacing, bool); + itkSetMacro(InverseXSpacing, bool); + + /** Buffer accessors */ + void SetBuffer( BufferType * pBuff ) + { + m_Buffer = pBuff; + } + + virtual void GenerateData(); + + virtual void Update() + { + this->GenerateData(); +} + +protected: + ScalarBufferToImageFileWriter(); + virtual ~ScalarBufferToImageFileWriter() { /* don't call ClearBuffer, user's care */} + void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + + ScalarBufferToImageFileWriter(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + + /** Writer */ + WriterPointer m_Writer; + + /** Scalar tab buffer to writer */ + BufferType * m_Buffer; + + /**Output image number of channels */ + unsigned int m_NumberOfChannels; + + /** Output image size */ + SizeType m_ImageSize; + + /** Inverse biffer among X */ + bool m_InverseXSpacing; +}; + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbScalarBufferToImageFileWriter.txx" +#endif + +#endif diff --git a/Code/IO/otbScalarBufferToImageFileWriter.txx b/Code/IO/otbScalarBufferToImageFileWriter.txx new file mode 100644 index 0000000000000000000000000000000000000000..64f0cf905747ce17b2bf71db45d862af1d2affa6 --- /dev/null +++ b/Code/IO/otbScalarBufferToImageFileWriter.txx @@ -0,0 +1,128 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif + +#include "otbMacro.h" + +#include "otbScalarBufferToImageFileWriter.h" +#include "itkImageRegionIterator.h" +#include "itkImageRegionIteratorWithIndex.h" + +namespace otb +{ +template<class TBufferType, class TOutputPixelType> +ScalarBufferToImageFileWriter<TBufferType, TOutputPixelType> +::ScalarBufferToImageFileWriter() : m_Buffer(NULL), m_NumberOfChannels(0), m_InverseXSpacing(false) +{ + m_Writer = WriterType::New(); + m_ImageSize.Fill(0); +} + + +template<class TBufferType, class TOutputPixelType> +void +ScalarBufferToImageFileWriter<TBufferType, TOutputPixelType>::GenerateData() +{ + // Check image parameters + if( (m_ImageSize[0]==0) || (m_ImageSize[0]==0) ) + { + itkExceptionMacro("Invalid output image size, Size can't be null."); + } + + if( m_NumberOfChannels==0 ) + { + itkExceptionMacro("Invalid output image number of channels."); + } + + RegionType l_Region; + IndexType l_Id; + l_Id.Fill(0); + l_Region.SetIndex(l_Id); + l_Region.SetSize(m_ImageSize); + + ImageType::Pointer l_Image = ImageType::New(); + l_Image->SetRegions( l_Region ); + l_Image->SetNumberOfComponentsPerPixel(m_NumberOfChannels); + l_Image->Allocate(); + PixelType l_Pix; + + l_Pix.SetSize(m_NumberOfChannels); + l_Pix.Fill( itk::NumericTraits<OutputPixelType>::Zero ); + l_Image->FillBuffer(l_Pix); + + // 1 specific loop for each case to save time processing + if(m_InverseXSpacing == false) + { + itk::ImageRegionIterator<ImageType> it(l_Image, l_Region); + it.GoToBegin(); + + unsigned int cpt(0); + while( it.IsAtEnd()==false ) + { + for(unsigned int i=0; i<m_NumberOfChannels; i++) + { + l_Pix[i] = static_cast<OutputPixelType>(m_Buffer[cpt]); + cpt++; + } + + it.Set( l_Pix ); + ++it; + } + } + else + { + itk::ImageRegionIteratorWithIndex<ImageType> it(l_Image, l_Region); + it.GoToBegin(); + // cpt is the first component of the last pixel + unsigned int cpt(0); + while( it.IsAtEnd()==false ) + { + IndexType index = it.GetIndex(); + cpt = (m_ImageSize[1] - 1 - index[1]) * m_NumberOfChannels * m_ImageSize[0] + m_NumberOfChannels * index[0]; + + for(unsigned int i=0; i<m_NumberOfChannels; i++) + { + l_Pix[i] = static_cast<OutputPixelType>(m_Buffer[cpt+i]); + } + + it.Set( l_Pix ); + ++it; + } + } + + m_Writer->WriteGeomFileOff(); + m_Writer->SetInput( l_Image ); + m_Writer->Update(); +} + +template<class TBufferType, class TOutputPixelType> +void +ScalarBufferToImageFileWriter<TBufferType, TOutputPixelType> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "FileName" << m_Writer->GetFileName() << std::endl; + os << indent << "Size" << m_ImageSize << std::endl; + os << indent << "NumberOfChannels" << m_NumberOfChannels << std::endl; +} + +} // end namespace otb + diff --git a/Testing/Code/IO/CMakeLists.txt b/Testing/Code/IO/CMakeLists.txt index 057106b3a485d14b11df6c1e8f81bc52df0d26f2..49c93ccd122f39a977e714b9c377624dd7eee938 100644 --- a/Testing/Code/IO/CMakeLists.txt +++ b/Testing/Code/IO/CMakeLists.txt @@ -2660,6 +2660,20 @@ ADD_TEST(ioTuSarDefaultImageMetadataInterfaceNew ${IO_TESTS20} ADD_TEST(ioTuSarDefaultImageMetadataInterface ${IO_TESTS20} otbSarDefaultImageMetadataInterface ) +ADD_TEST(ioTuScalarBufferToImageFileWriter ${IO_TESTS20} + otbScalarBufferToImageFileWriterNew ) + +ADD_TEST(ioTvScalarBufferToImageFileWriterTest ${IO_TESTS20} + --compare-image ${NOTOL} + ${BASELINE}/ioTvScalarBufferToImageFileWriterTest.tif + ${TEMP}/ioTvScalarBufferToImageFileWriterTest.tif + otbScalarBufferToImageFileWriterTest + 4 + 50 + 75 + ${TEMP}/ioTvScalarBufferToImageFileWriterTest.tif +) + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbIOTESTS21 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2853,6 +2867,8 @@ ADD_TEST(ioTvGDALReadPxlComplex${INPUTFILE_PIXELTYPE} ${IO_TESTS21} ENDFOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbIOTESTS22 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2928,6 +2944,7 @@ ADD_TEST(ioTvMultiChannelROI_HDF5_2_TIF ${COMMON_TESTS2} ENDIF(CHECK_GDAL_BUILDED_WITH_HDF) + #---------------------------------------------------------------------------------- SET(BasicIO_SRCS1 otbIOTests1.cxx @@ -3128,6 +3145,8 @@ otbOpticalDefaultImageMetadataInterface.cxx otbSarDefaultImageMetadataInterfaceFactoryNew.cxx otbSarDefaultImageMetadataInterfaceNew.cxx otbSarDefaultImageMetadataInterface.cxx +otbScalarBufferToImageFileWriterNew.cxx +otbScalarBufferToImageFileWriterTest.cxx ) SET(BasicIO_SRCS21 diff --git a/Testing/Code/IO/otbIOTests20.cxx b/Testing/Code/IO/otbIOTests20.cxx index 2ecd94929ce388b0de2e77c68009ef14374d7d4d..485452d99123839cf8a328f52cf7cf244d30f275 100644 --- a/Testing/Code/IO/otbIOTests20.cxx +++ b/Testing/Code/IO/otbIOTests20.cxx @@ -35,4 +35,6 @@ void RegisterTests() REGISTER_TEST(otbSarDefaultImageMetadataInterfaceFactoryNew); REGISTER_TEST(otbSarDefaultImageMetadataInterfaceNew); REGISTER_TEST(otbSarDefaultImageMetadataInterface); + REGISTER_TEST(otbScalarBufferToImageFileWriterNew); + REGISTER_TEST(otbScalarBufferToImageFileWriterTest); } diff --git a/Testing/Code/IO/otbScalarBufferToImageFileWriterNew.cxx b/Testing/Code/IO/otbScalarBufferToImageFileWriterNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1d1aa9d9c29b0c5766603782499ab12a7689a499 --- /dev/null +++ b/Testing/Code/IO/otbScalarBufferToImageFileWriterNew.cxx @@ -0,0 +1,32 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbScalarBufferToImageFileWriter.h" + + +int otbScalarBufferToImageFileWriterNew(int argc, char* argv[]) +{ + typedef otb::ScalarBufferToImageFileWriter<int, double> FilterType; + FilterType::Pointer filter = FilterType::New(); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/IO/otbScalarBufferToImageFileWriterTest.cxx b/Testing/Code/IO/otbScalarBufferToImageFileWriterTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e418b37598f4e3e89c791986782e5052352d57ac --- /dev/null +++ b/Testing/Code/IO/otbScalarBufferToImageFileWriterTest.cxx @@ -0,0 +1,65 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbScalarBufferToImageFileWriter.h" + + +int otbScalarBufferToImageFileWriterTest(int argc, char* argv[]) +{ + unsigned int nbCh = atoi(argv[1]); + unsigned int sizeX = atoi(argv[2]); + unsigned int sizeY = atoi(argv[3]); + + typedef otb::ScalarBufferToImageFileWriter<float, unsigned int> FilterType; + FilterType::Pointer filter = FilterType::New(); + + float * tab = new float[nbCh*sizeX*sizeY]; + + int cpt=0; + double val = 0.; + for(unsigned int sx=0; sx<sizeX; sx++) + { + for(unsigned int sy=0; sy<sizeY; sy++) + { + for(unsigned int i=0; i<nbCh; i++) + { + tab[cpt++] = val; + val++; + } + } + } + + FilterType::SizeType size; + size[0] = sizeX; + size[1] = sizeY; + filter->SetImageSize(size); + filter->SetNumberOfChannels(nbCh); + filter->SetBuffer(tab); + filter->SetFileName(argv[4]); + filter->SetInverseXSpacing(true); + filter->Update(); + + delete[] tab; + tab = NULL; + + return EXIT_SUCCESS; +}