diff --git a/Modules/IO/IOGDAL/include/otbGDALDatasetWrapper.h b/Modules/IO/IOGDAL/include/otbGDALDatasetWrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..89c4a1a82ee75c6f7a721382dcab369f9e5ee5e5 --- /dev/null +++ b/Modules/IO/IOGDAL/include/otbGDALDatasetWrapper.h @@ -0,0 +1,90 @@ +/*========================================================================= + + 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 otbGDALDatasetWrapper_h +#define otbGDALDatasetWrapper_h + +#include "itkLightObject.h" +#include "itkObjectFactory.h" + +#include "otbConfigure.h" + + +class GDALDataset; + + +namespace otb +{ + +// only two states : the Pointer is Null or GetDataSet() returns a +// valid dataset +class GDALDatasetWrapper : public itk::LightObject +{ + friend class GDALDriverManagerWrapper; + +public: + typedef GDALDatasetWrapper Self; + typedef itk::LightObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(GDALImageIO, itk::LightObject); + + /** Easy access to the internal GDALDataset object. + * Don't close it, it will be automatic */ + const GDALDataset * GetDataSet() const; + GDALDataset * GetDataSet(); + + /** Test if the dataset corresponds to a Jpeg2000 file format + * Return true if the dataset exists and has a JPEG2000 driver + * Return false in all other cases */ + bool IsJPEG2000() const; + + /** + */ + int GetOverviewsCount() const; + + /** + */ + unsigned int GetWidth() const; + + /** + */ + unsigned int GetHeight() const; + + /** + */ + size_t GetPixelBytes() const; + +protected : + GDALDatasetWrapper(); + + virtual ~GDALDatasetWrapper(); + + +private: + GDALDataset * m_Dataset; +}; // end of GDALDatasetWrapper + + +} // end namespace otb + + +#endif // otbGDALDatasetWrapper_h diff --git a/Modules/IO/IOGDAL/include/otbGDALDriverManagerWrapper.h b/Modules/IO/IOGDAL/include/otbGDALDriverManagerWrapper.h index d7cdaff63358d1c2cf84686212545ee0074797a8..96c2679dfafa8bb5eb9573a2630e6a810e3ed794 100644 --- a/Modules/IO/IOGDAL/include/otbGDALDriverManagerWrapper.h +++ b/Modules/IO/IOGDAL/include/otbGDALDriverManagerWrapper.h @@ -15,6 +15,10 @@ PURPOSE. See the above copyright notices for more information. =========================================================================*/ +#ifndef otbGDALDriverManagerWrapper_h +#define otbGDALDriverManagerWrapper_h + + #include "itkLightObject.h" #include "itkProcessObject.h" #include "otbConfigure.h" @@ -28,44 +32,13 @@ class GDALDriver; #include "gdal_priv.h" #include "gdal_alg.h" -namespace otb -{ +#include "otbGDALDatasetWrapper.h" +// otb::GDALOverviewsBuilder moved to self header & body files. +// Including its header file here for compile time compatibility. +#include "otbGDALOverviewsBuilder.h" -// only two states : the Pointer is Null or GetDataSet() returns a -// valid dataset -class GDALDatasetWrapper : public itk::LightObject +namespace otb { - friend class GDALDriverManagerWrapper; - -public: - typedef GDALDatasetWrapper Self; - typedef itk::LightObject Superclass; - typedef itk::SmartPointer<Self> Pointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(GDALImageIO, itk::LightObject); - - /** Easy access to the internal GDALDataset object. - * Don't close it, it will be automatic */ - GDALDataset* GetDataSet() const; - - /** Test if the dataset corresponds to a Jpeg2000 file format - * Return true if the dataset exists and has a JPEG2000 driver - * Return false in all other cases */ - bool IsJPEG2000() const; - -protected : - GDALDatasetWrapper(); - - ~GDALDatasetWrapper(); - - -private: - GDALDataset* m_Dataset; -}; // end of GDALDatasetWrapper /** \class GDALDriverManagerWrapper * @@ -115,61 +88,8 @@ private : ~GDALDriverManagerWrapper(); }; // end of GDALDriverManagerWrapper -typedef enum {NONE, NEAREST, GAUSS, CUBIC, AVERAGE, MODE, AVERAGE_MAGPHASE } GDALResamplingType; - - -class GDALOverviewsBuilder : public itk::ProcessObject -{ -public: - typedef GDALOverviewsBuilder Self; - typedef ProcessObject Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - void SetResamplingMethod(GDALResamplingType resampMethod) - { - m_ResamplingMethod = resampMethod; - }; - - void SetNbOfResolutions(unsigned int nbResol) - { - m_NbOfResolutions = nbResol; - }; - - void SetResolutionFactor(unsigned int factor) - { - m_ResolutionFactor = factor; - } - - void SetInputFileName(std::string str) - { - m_InputFileName = str; - }; - - void Update(); - -protected: - GDALOverviewsBuilder(); - virtual ~GDALOverviewsBuilder() {}; - - void PrintSelf(std::ostream& os,itk::Indent indent) const; - -private: - - GDALOverviewsBuilder(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - - std::string m_InputFileName; - unsigned int m_NbOfResolutions; - unsigned int m_ResolutionFactor; - GDALResamplingType m_ResamplingMethod; - - void GetGDALResamplingMethod(std::string &resamplingMethod); - -}; // end of GDALOverviewsBuilder } // end namespace otb + +#endif // otbGDALDriverManagerWrapper_h diff --git a/Modules/IO/IOGDAL/include/otbGDALOverviewsBuilder.h b/Modules/IO/IOGDAL/include/otbGDALOverviewsBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..e0335c34033851fc10130c70bf0638278a690536 --- /dev/null +++ b/Modules/IO/IOGDAL/include/otbGDALOverviewsBuilder.h @@ -0,0 +1,189 @@ +/*========================================================================= + + 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 otbGDALOverviewsBuilder_h +#define otbGDALOverviewsBuilder_h + + +// #include "itkLightObject.h" +#include "itkProcessObject.h" +#include "itkSize.h" + +#include "otbGDALDatasetWrapper.h" +#include "otbConfigure.h" + +namespace otb +{ + +/** + */ +enum GDALResampling +{ + GDAL_RESAMPLING_NONE = 0, + // + GDAL_RESAMPLING_NEAREST, + GDAL_RESAMPLING_GAUSS, + GDAL_RESAMPLING_CUBIC, + GDAL_RESAMPLING_AVERAGE, + GDAL_RESAMPLING_MODE, + GDAL_RESAMPLING_AVERAGE_MAGPHASE, + // + GDAL_RESAMPLING_COUNT +}; + + +// Compile-time compatibility alias. +typedef GDALResampling GDALResamplingType; + +/** + */ +enum GDALCompression +{ + GDAL_COMPRESSION_NONE = 0, + // + GDAL_COMPRESSION_JPEG, + GDAL_COMPRESSION_LZW, + GDAL_COMPRESSION_PACKBITS, + GDAL_COMPRESSION_DEFLATE, + // + GDAL_COMPRESSION_COUNT, +}; + + +/** + */ +enum GDALFormat +{ + GDAL_FORMAT_ERDAS, + GDAL_FORMAT_GEOTIFF, + // + GDAL_FORMAT_COUNT, +}; + + +/** + */ +class GDALOverviewsBuilder : public itk::ProcessObject +{ +public: + typedef GDALOverviewsBuilder Self; + typedef ProcessObject Superclass; + typedef itk::SmartPointer< Self> Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + typedef itk::Size< 2 > Size; + typedef std::vector< Size > SizeVector; + + /** Method for creation through the object factory. */ + itkNewMacro( Self ); + + /** + */ + static + bool CanGenerateOverviews( const std::string & filename ); + + /** + * \brief Count the number of resolution levels larger than + * factor^n. + */ + unsigned int + CountResolutions( unsigned int factor, unsigned int size =1 ) const; + + unsigned int + CountResolutions() const; + + void ListResolutions( SizeVector &, unsigned int factor, unsigned int count ); + + void ListResolutions( SizeVector & ); + + unsigned int GetOverviewsCount() const; + + + size_t GetEstimatedSize() const; + + GDALResampling GetResamplingMethod() const; + + void SetResamplingMethod( GDALResampling ); + + + void SetBypassEnabled( bool ); + + bool IsBypassEnabled() const; + + unsigned int GetWidth() const; + + unsigned int GetHeight() const; + + GDALCompression GetCompressionMethod() const; + + void SetCompressionMethod( GDALCompression ); + + + GDALFormat GetFormat() const; + + void SetFormat( GDALFormat ); + + + unsigned int GetNbResolutions() const; + + void SetNbResolutions( unsigned int ); + + unsigned int GetResolutionFactor() const; + + void SetResolutionFactor( unsigned int ); + + + const std::string & GetInputFileName() const; + + void SetInputFileName( const std::string & str ); + + + void Update(); + + +protected: + GDALOverviewsBuilder(); + + virtual ~GDALOverviewsBuilder() {}; + + void PrintSelf( std::ostream & os, itk::Indent indent ) const; + + +private: + GDALOverviewsBuilder( const Self & ); //purposely not implemented + + void operator = ( const Self & ); //purposely not implemented + + // void GetGDALResamplingMethod( std::string & resamplingMethod ); + + void OpenDataset( const std::string & filename ); + + + GDALDatasetWrapper::Pointer m_GDALDataset; + std::string m_InputFileName; + unsigned int m_NbResolutions; + unsigned int m_ResolutionFactor; + GDALResampling m_ResamplingMethod; + GDALCompression m_CompressionMethod; + GDALFormat m_Format; + bool m_IsBypassEnabled : 1; + +}; // end of GDALOverviewsBuilder + +} // end namespace otb + +#endif // otbGDALOverviewsBuilder_h diff --git a/Modules/IO/IOGDAL/src/CMakeLists.txt b/Modules/IO/IOGDAL/src/CMakeLists.txt index 33e70edc54a27053bdb09e145e4e8caaf3785ab4..9b3da9d60101bdd1c4afe206bcc29c1bea7649cd 100644 --- a/Modules/IO/IOGDAL/src/CMakeLists.txt +++ b/Modules/IO/IOGDAL/src/CMakeLists.txt @@ -1,10 +1,12 @@ set(OTBIOGDAL_SRC - otbGDALImageIOFactory.cxx + otbGDALDatasetWrapper.cxx + otbGDALDriverManagerWrapper.cxx otbGDALImageIO.cxx - otbOGRVectorDataIO.cxx + otbGDALImageIOFactory.cxx + otbGDALOverviewsBuilder.cxx otbOGRIOHelper.cxx + otbOGRVectorDataIO.cxx otbOGRVectorDataIOFactory.cxx - otbGDALDriverManagerWrapper.cxx ) add_library(OTBIOGDAL ${OTBIOGDAL_SRC}) @@ -17,7 +19,6 @@ target_link_libraries(OTBIOGDAL ${OTBGDAL_LIBRARIES} ${OTBBoost_LIBRARIES} ${OTBOSSIMAdapters_LIBRARIES} - ) otb_module_target(OTBIOGDAL) diff --git a/Modules/IO/IOGDAL/src/otbGDALDatasetWrapper.cxx b/Modules/IO/IOGDAL/src/otbGDALDatasetWrapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c1d23d23a190c7037ccfadc494b5c722f0b66f3c --- /dev/null +++ b/Modules/IO/IOGDAL/src/otbGDALDatasetWrapper.cxx @@ -0,0 +1,168 @@ +/*========================================================================= + + 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 "otbGDALDriverManagerWrapper.h" + +#include <vector> + +#include "otb_boost_string_header.h" +#include "otbSystem.h" + +namespace otb +{ + +GDALDatasetWrapper +::GDALDatasetWrapper(): m_Dataset(NULL) +{ +} + +GDALDatasetWrapper +::~GDALDatasetWrapper() +{ + if( m_Dataset ) + { + GDALClose(m_Dataset); + + // GDALDataset * is statically cast from GDALDatasetH in + // GDALDriverManagerWrapper::Open(). So, it should be destroyed by + // GDALClose() (see + // http://gdal.org/classGDALDataset.html#a4d110533d799bac7dcfad3c41d30c0e7). + m_Dataset = NULL; + } +} + +// GetDataSet +const GDALDataset * +GDALDatasetWrapper +::GetDataSet() const +{ + return m_Dataset; +} + + +GDALDataset * +GDALDatasetWrapper +::GetDataSet() +{ + return m_Dataset; +} + + +// IsJPEG2000 +bool +GDALDatasetWrapper::IsJPEG2000() const +{ + if (m_Dataset == NULL) + { + return false; + } + std::string driverName(m_Dataset->GetDriver()->GetDescription()); + if (driverName.compare("JP2OpenJPEG") == 0 || + driverName.compare("JP2KAK") == 0 || + driverName.compare("JP2ECW") == 0) + { + return true; + } + return false; +} + + +int +GDALDatasetWrapper +::GetOverviewsCount() const +{ + assert( m_Dataset!=NULL ); + assert( m_Dataset->GetRasterCount()>0 ); + assert( m_Dataset->GetRasterBand( 1 )!=NULL ); + + return m_Dataset->GetRasterBand( 1 )->GetOverviewCount(); +} + + +unsigned int +GDALDatasetWrapper +::GetWidth() const +{ + assert( m_Dataset!=NULL ); + + return m_Dataset->GetRasterXSize(); +} + + +unsigned int +GDALDatasetWrapper +::GetHeight() const +{ + assert( m_Dataset!=NULL ); + + return m_Dataset->GetRasterYSize(); +} + + +size_t +GDALDatasetWrapper +::GetPixelBytes() const +{ + assert( m_Dataset!=NULL ); + + size_t size = 0; + + int count = m_Dataset->GetRasterCount(); + + for( int i=1; i<=count; ++i ) + { + assert( m_Dataset->GetRasterBand( i )!=NULL ); + + switch( m_Dataset->GetRasterBand( i )->GetRasterDataType() ) + { + case GDT_Unknown: + assert( false && "Unexpected GDALDataType GDT_Unknown value." ); + break; + + case GDT_Byte: + size += 1; + break; + + case GDT_UInt16: + case GDT_Int16 : + case GDT_CInt16: + size += 2; + break; + + case GDT_UInt32: + case GDT_Int32: + case GDT_Float32: + case GDT_CInt32: + case GDT_CFloat32: + size += 4; + break; + + case GDT_Float64: + case GDT_CFloat64: + size += 8; + break; + + default: + assert( false && "Unhandled GDALDataType enum value." ); + break; + } + } + + return size; +} + +} // end namespace otb diff --git a/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx b/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx index 33fd313a066079aacfcd2e8b852528d5b7e27e79..747d851f3a4b7d60c0e4936af49b69a76460ac1e 100644 --- a/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx +++ b/Modules/IO/IOGDAL/src/otbGDALDriverManagerWrapper.cxx @@ -23,43 +23,6 @@ namespace otb { -GDALDatasetWrapper::GDALDatasetWrapper(): m_Dataset(NULL) -{ -} - -GDALDatasetWrapper::~GDALDatasetWrapper() -{ - if (m_Dataset) - { - GDALClose(m_Dataset); - } -} - -// GetDataSet -GDALDataset* -GDALDatasetWrapper::GetDataSet() const -{ - return m_Dataset; -} - -// IsJPEG2000 -bool -GDALDatasetWrapper::IsJPEG2000() const -{ - if (m_Dataset == NULL) - { - return false; - } - std::string driverName(m_Dataset->GetDriver()->GetDescription()); - if (driverName.compare("JP2OpenJPEG") == 0 || - driverName.compare("JP2KAK") == 0 || - driverName.compare("JP2ECW") == 0) - { - return true; - } - return false; -} - // GDALDriverManagerWrapper method implementation GDALDriverManagerWrapper::GDALDriverManagerWrapper() @@ -153,126 +116,10 @@ GDALDriverManagerWrapper::Create( std::string driverShortName, std::string filen return datasetWrapper; } - GDALDriver* GDALDriverManagerWrapper::GetDriverByName( std::string driverShortName ) const { return GetGDALDriverManager()->GetDriverByName(driverShortName.c_str()); } -GDALOverviewsBuilder::GDALOverviewsBuilder() -{ - m_NbOfResolutions = 1; - m_ResolutionFactor = 2; - m_ResamplingMethod = NEAREST; - Superclass::SetNumberOfRequiredInputs(0); - Superclass::SetNumberOfRequiredOutputs(0); -} - -void GDALOverviewsBuilder:: -PrintSelf(std::ostream& os, itk::Indent indent) const -{ - Superclass::PrintSelf(os,indent); - - os << indent << "Input Filename: " << m_InputFileName << std::endl; - os << indent << "Number of Resolution requested: " << m_NbOfResolutions << std::endl; - os << indent << "Resampling method: " << m_ResamplingMethod << std::endl; -} - -void GDALOverviewsBuilder::GetGDALResamplingMethod(std::string &resamplingMethod) -{ - resamplingMethod.clear(); - switch(m_ResamplingMethod) - { - case NONE: - resamplingMethod = "NONE"; - break; - case NEAREST: - resamplingMethod = "NEAREST"; - break; - case GAUSS: - resamplingMethod = "GAUSS"; - break; - case CUBIC: - resamplingMethod = "CUBIC"; - break; - case AVERAGE: - resamplingMethod = "AVERAGE"; - break; - case MODE: - resamplingMethod = "MODE"; - break; - case AVERAGE_MAGPHASE: - resamplingMethod = "AVERAGE_MAGPHASE"; - break; - default: - resamplingMethod = "NONE"; - break; - } -} - -// Progress reporting functions compatible with GDAL C API -extern "C" -{ - static int CPL_STDCALL otb_UpdateGDALProgress(double dfComplete, - const char *itkNotUsed(pszMessage), - void * pProgressArg) - { - otb::GDALOverviewsBuilder* _this = (otb::GDALOverviewsBuilder*)pProgressArg; - _this->UpdateProgress(dfComplete); - return 1; - } -} - -void GDALOverviewsBuilder::Update() -{ - typedef itk::SmartPointer<GDALDatasetWrapper> GDALDatasetWrapperPointer; - GDALDatasetWrapperPointer wrappedDataset = - GDALDriverManagerWrapper::GetInstance().Open(m_InputFileName); - if (wrappedDataset.IsNull()) - { - itkExceptionMacro(<< "Error while opening the file "<< m_InputFileName.c_str() << "."); - } - - - if( m_NbOfResolutions==0 ) - { - itkExceptionMacro( - << "Wrong number of resolutions: " << m_NbOfResolutions - ); - } - - // Build the overviews list from nb of resolution desired - std::vector<int> ovwlist; - unsigned int factor = 1; - for (unsigned int i = 1; i < m_NbOfResolutions; i++) - { - factor*=m_ResolutionFactor; - ovwlist.push_back(factor); - } - - /*std::cout << "list of overviews level= "; - for (unsigned int i = 0; i < ovwlist.size(); i++) - { - std::cout << ovwlist[i] << ","; - } - std::cout << std::endl; */ - - std::string resampMethod; - this->GetGDALResamplingMethod(resampMethod); - - CPLErr lCrGdal = wrappedDataset->GetDataSet()-> - BuildOverviews( resampMethod.c_str(), - static_cast<int>(m_NbOfResolutions-1), - &ovwlist.front(), - 0, // All bands - NULL, // All bands - (GDALProgressFunc)otb_UpdateGDALProgress, - this); - if (lCrGdal == CE_Failure) - { - itkExceptionMacro(<< "Error while building the GDAL overviews from " << m_InputFileName.c_str() << "."); - } -} - } // end namespace otb diff --git a/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c61bb67a4b623ebe00e9f970b2d0a0b1356172fd --- /dev/null +++ b/Modules/IO/IOGDAL/src/otbGDALOverviewsBuilder.cxx @@ -0,0 +1,552 @@ +/*========================================================================= + + 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 "otbGDALOverviewsBuilder.h" + + +#include <vector> + +#include "gdal.h" +#include "otb_boost_string_header.h" + +#include "otbGDALDriverManagerWrapper.h" +#include "otbGDALImageIO.h" +#include "otbSystem.h" + + +namespace otb +{ + +// Progress reporting functions compatible with GDAL C API +extern "C" +{ + static int CPL_STDCALL otb_UpdateGDALProgress( double dfComplete, + const char * itkNotUsed( pszMessage ), + void * pProgressArg ) + { + otb::GDALOverviewsBuilder* _this = (otb::GDALOverviewsBuilder*)pProgressArg; + _this->UpdateProgress(dfComplete); + return 1; + } +} + +char const * const +GDAL_RESAMPLING_NAMES[ GDAL_RESAMPLING_COUNT ] = +{ + "NONE", + "NEAREST", + "GAUSS", + "CUBIC", + "AVERAGE", + "MODE", + "AVERAGE_MAGPHASE" +}; + + +char const * const +GDAL_COMPRESSION_NAMES[ GDAL_COMPRESSION_COUNT ] = +{ + "", + "JPEG", + "LZW", + "PACKBITS", + "DEFLATE", +}; + + +/***************************************************************************/ +std::string +GetConfigOption( const char * key ) +{ + const char * value = CPLGetConfigOption( key, NULL ); + + return + value==NULL + ? std::string() + : std::string( value ); +} + +/***************************************************************************/ +bool +GDALOverviewsBuilder +::CanGenerateOverviews( const std::string & filename ) +{ + GDALImageIO::Pointer io( GDALImageIO::New() ); + + typedef std::vector< std::string > StringVector; + + StringVector names; + StringVector descs; + + if( !io->CanReadFile( filename.c_str() ) ) + return false; + + io->SetFileName( filename ); + + return !io->GetSubDatasetInfo( names, descs ); +} + +/***************************************************************************/ +GDALOverviewsBuilder +::GDALOverviewsBuilder() : + m_GDALDataset(), + m_InputFileName(), + m_NbResolutions( 1 ), + m_ResolutionFactor( 2 ), + m_ResamplingMethod( GDAL_RESAMPLING_NEAREST ), + m_CompressionMethod( GDAL_COMPRESSION_NONE ), + m_Format( GDAL_FORMAT_GEOTIFF ), + m_IsBypassEnabled( false ) +{ + Superclass::SetNumberOfRequiredInputs(0); + Superclass::SetNumberOfRequiredOutputs(0); +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::CountResolutions( unsigned int factor, unsigned int minSize ) const +{ + assert( factor>1 ); + + if( factor<=1 ) + return 0; + + assert( minSize>0 ); + + if( minSize<=0 ) + return 0; + + assert( !m_GDALDataset.IsNull() ); + + // unsigned int minSize = static_cast< unsigned int >( pow( factor, n ) ); + + unsigned int size = + std::min( + m_GDALDataset->GetWidth(), + m_GDALDataset->GetHeight() + ); + + if( size<minSize ) + return 0; + + unsigned int count = 0; + + while( size >= minSize ) + { + ++ count; + + size /= factor; + } + + return count; +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::CountResolutions() const +{ + return CountResolutions( m_ResolutionFactor ); +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::ListResolutions( SizeVector & sizes ) +{ + ListResolutions( sizes, m_ResolutionFactor, m_NbResolutions ); +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::ListResolutions( SizeVector & sizes, unsigned int factor, unsigned int count ) +{ + assert( factor>1 ); + + if( factor<=1 ) + return; + + assert( !m_GDALDataset.IsNull() ); + + Size s; + + s[ 0 ] = m_GDALDataset->GetWidth(); + s[ 1 ] = m_GDALDataset->GetHeight(); + + unsigned int n = + std::min( + count, + CountResolutions( factor ) + ); + + for( unsigned int i=0; i<n; ++i ) + { + sizes.push_back( s ); + + s[ 0 ] /= factor; + s[ 1 ] /= factor; + } +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetBypassEnabled( bool isEnabled ) +{ + m_IsBypassEnabled = isEnabled; +} + +/***************************************************************************/ +bool +GDALOverviewsBuilder +::IsBypassEnabled() const +{ + return m_IsBypassEnabled; +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::GetWidth() const +{ + assert( !m_GDALDataset.IsNull() ); + + return m_GDALDataset->GetWidth(); +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::GetHeight() const +{ + assert( !m_GDALDataset.IsNull() ); + + return m_GDALDataset->GetHeight(); +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::GetOverviewsCount() const +{ + assert( !m_GDALDataset.IsNull() ); + + // Return only GDAL already generated overview count as opposed to + // ImageIO::GetOverviewsCount() which include full image as one level. + return m_GDALDataset->GetOverviewsCount(); +} + +/***************************************************************************/ +size_t +GDALOverviewsBuilder +::GetEstimatedSize() const +{ + if( m_IsBypassEnabled ) + return 0; + + assert( !m_GDALDataset.IsNull() ); + assert( m_ResolutionFactor>0 ); + + size_t bytes = m_GDALDataset->GetPixelBytes(); + + assert( bytes>0 ); + + size_t size = 0; + + unsigned int w = m_GDALDataset->GetWidth(); + unsigned int h = m_GDALDataset->GetHeight(); + + for( unsigned int i=0; i<m_NbResolutions; ++i ) + { + w /= m_ResolutionFactor; + h /= m_ResolutionFactor; + + size += w * h * bytes; + } + + return size; +} + +/***************************************************************************/ +GDALResampling +GDALOverviewsBuilder +::GetResamplingMethod() const +{ + return m_ResamplingMethod; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetResamplingMethod( GDALResamplingType resampling ) +{ + m_ResamplingMethod = resampling; +}; + +/***************************************************************************/ +GDALCompression +GDALOverviewsBuilder +::GetCompressionMethod() const +{ + return m_CompressionMethod; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetCompressionMethod( GDALCompression compression ) +{ + m_CompressionMethod = compression; +} + + +/***************************************************************************/ +GDALFormat +GDALOverviewsBuilder +::GetFormat() const +{ + return m_Format; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetFormat( GDALFormat format ) +{ + m_Format = format; +} + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::GetNbResolutions() const +{ + return m_NbResolutions; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetNbResolutions( unsigned int n ) +{ + m_NbResolutions = n; +}; + +/***************************************************************************/ +unsigned int +GDALOverviewsBuilder +::GetResolutionFactor() const +{ + return m_ResolutionFactor; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetResolutionFactor( unsigned int factor ) +{ + m_ResolutionFactor = factor; +} + +/***************************************************************************/ +const std::string & +GDALOverviewsBuilder +::GetInputFileName() const +{ + return m_InputFileName; +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::SetInputFileName( const std::string & filename ) +{ + try + { + OpenDataset( filename ); + } + catch( ... ) + { + throw; + } + + m_InputFileName = filename; +}; + +/***************************************************************************/ +void +GDALOverviewsBuilder +::PrintSelf( std::ostream& os, itk::Indent indent ) const +{ + Superclass::PrintSelf(os,indent); + + os << indent << "Input Filename: " << m_InputFileName << std::endl; + os << indent << "Number of Resolution requested: " << m_NbResolutions << std::endl; + os << indent << "Resampling method: " << m_ResamplingMethod << std::endl; +} + +/***************************************************************************/ +/* +void +GDALOverviewsBuilder +::GetGDALResamplingMethod( std::string & resamplingMethod ) +{ + resamplingMethod.clear(); + switch(m_ResamplingMethod) + { + case GDAL_RESAMPLING_NONE: + resamplingMethod = "NONE"; + break; + case GDAL_RESAMPLING_NEAREST: + resamplingMethod = "NEAREST"; + break; + case GDAL_RESAMPLING_GAUSS: + resamplingMethod = "GAUSS"; + break; + case GDAL_RESAMPLING_CUBIC: + resamplingMethod = "CUBIC"; + break; + case GDAL_RESAMPLING_AVERAGE: + resamplingMethod = "AVERAGE"; + break; + case GDAL_RESAMPLING_MODE: + resamplingMethod = "MODE"; + break; + case GDAL_RESAMPLING_AVERAGE_MAGPHASE: + resamplingMethod = "AVERAGE_MAGPHASE"; + break; + default: + resamplingMethod = "NONE"; + break; + } +} +*/ + +/***************************************************************************/ +void +GDALOverviewsBuilder +::Update() +{ + // typedef itk::SmartPointer<GDALDatasetWrapper> GDALDatasetWrapperPointer; + // GDALDatasetWrapperPointer wrappedDataset = + // GDALDriverManagerWrapper::GetInstance().Open(m_InputFileName); + // if (wrappedDataset.IsNull()) + // { + // itkExceptionMacro(<< "Error while opening the file "<< m_InputFileName.c_str() << "."); + // } + + + assert( !m_GDALDataset.IsNull() ); + + assert( m_NbResolutions>0 ); + + if( m_NbResolutions==0 ) + { + itkExceptionMacro( + << "Wrong number of resolutions: " << m_NbResolutions + ); + } + + if( m_IsBypassEnabled ) + return; + + // Build the overviews list from nb of resolution desired + std::vector< int > ovwlist; + unsigned int factor = 1; + for( unsigned int i = 1; i < m_NbResolutions; i++ ) + { + factor*=m_ResolutionFactor; + ovwlist.push_back(factor); + } + + /*std::cout << "list of overviews level= "; + for (unsigned int i = 0; i < ovwlist.size(); i++) + { + std::cout << ovwlist[i] << ","; + } + std::cout << std::endl; */ + + std::string erdas( GetConfigOption( "USE_RRD" ) ); + + CPLSetConfigOption( + "USE_RRD", + m_Format==GDAL_FORMAT_ERDAS + ? "YES" + : "NO" + ); + + + assert( + m_CompressionMethod>=GDAL_COMPRESSION_NONE && + m_CompressionMethod<GDAL_COMPRESSION_COUNT + ); + + std::string compression( GetConfigOption( "COMPRESS_OVERVIEW" ) ); + + CPLSetConfigOption( + "COMPRESS_OVERVIEW", + GDAL_COMPRESSION_NAMES[ m_CompressionMethod ] + ); + + + assert( + m_ResamplingMethod>=GDAL_RESAMPLING_NONE && + m_ResamplingMethod<GDAL_RESAMPLING_COUNT + ); + + CPLErr lCrGdal = + m_GDALDataset->GetDataSet()->BuildOverviews( + GDAL_RESAMPLING_NAMES[ m_ResamplingMethod ], + static_cast< int >( m_NbResolutions - 1 ), + &ovwlist.front(), + 0, // All bands + NULL, // All bands + ( GDALProgressFunc )otb_UpdateGDALProgress, + this ); + + CPLSetConfigOption( "USE_RRD", erdas.c_str() ); + CPLSetConfigOption( "COMPRESS_OVERVIEW", compression.c_str() ); + + if (lCrGdal == CE_Failure) + { + itkExceptionMacro(<< "Error while building the GDAL overviews from " << m_InputFileName.c_str() << "."); + } +} + +/***************************************************************************/ +void +GDALOverviewsBuilder +::OpenDataset( const std::string & filename ) +{ + GDALDatasetWrapper::Pointer dataset( + GDALDriverManagerWrapper::GetInstance().Open( filename ) + ); + + if( dataset.IsNull() ) + itkExceptionMacro( + << "Error while opening file '" + << filename.c_str() + << "' as GDAL dataset." + ); + + m_GDALDataset = dataset; +} + + +} // end namespace otb diff --git a/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx b/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx index 3b16727b727e40f9e550cbcca1773e5443c964fe..7eda724510b56bc868dc354317ffcdc6fd08e6ff 100644 --- a/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx +++ b/Modules/IO/IOGDAL/test/otbGDALOverviewsBuilder.cxx @@ -41,10 +41,10 @@ int otbGDALOverviewsBuilder(int itkNotUsed(argc), char* argv[]) typedef otb::GDALOverviewsBuilder FilterType; FilterType::Pointer filter = FilterType::New(); - otb::GDALResamplingType resamp = AVERAGE; + otb::GDALResamplingType resamp = GDAL_RESAMPLING_AVERAGE; filter->SetInputFileName(filename); - filter->SetNbOfResolutions(nbResolution); + filter->SetNbResolutions(nbResolution); filter->SetResamplingMethod(resamp); {