21 #ifndef otbImageFileReader_hxx
22 #define otbImageFileReader_hxx
25 #include "otbConfigure.h"
28 #include <itksys/SystemTools.hxx>
32 #include "itkImageIOFactory.h"
33 #include "itkPixelTraits.h"
34 #include "itkVectorImage.h"
35 #include "itkMetaDataObject.h"
65 template <
class TOutputImage,
class ConvertPixelTraits>
68 m_UserSpecifiedImageIO(false),
73 m_AdditionalNumber(0),
78 template <
class TOutputImage,
class ConvertPixelTraits>
83 template <
class TOutputImage,
class ConvertPixelTraits>
86 Superclass::PrintSelf(os, indent);
90 os << indent <<
"ImageIO: \n";
91 this->m_ImageIO->Print(os, indent.GetNextIndent());
95 os << indent <<
"ImageIO: (null)"
99 os << indent <<
"UserSpecifiedImageIO flag: " << this->m_UserSpecifiedImageIO <<
"\n";
100 os << indent <<
"m_FileName: " << this->m_FileName <<
"\n";
101 os << indent <<
"m_UseStreaming flag: " << this->m_UseStreaming <<
"\n";
102 os << indent <<
"m_ActualIORegion: " << this->m_ActualIORegion <<
"\n";
103 os << indent <<
"m_AdditionalNumber: " << this->m_AdditionalNumber <<
"\n";
106 template <
class TOutputImage,
class ConvertPixelTraits>
109 if (this->m_ImageIO != imageIO)
111 this->m_ImageIO = imageIO;
114 m_UserSpecifiedImageIO =
true;
117 template <
class TOutputImage,
class ConvertPixelTraits>
121 typename TOutputImage::Pointer output = this->GetOutput();
124 output->SetBufferedRegion(output->GetRequestedRegion());
129 this->TestValidImageIO();
133 this->m_ImageIO->SetFileName(this->m_FileName);
135 itk::ImageIORegion ioRegion(TOutputImage::ImageDimension);
137 itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
138 itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();
142 for (
unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
144 if (i < this->m_ImageIO->GetNumberOfDimensions())
146 if (!this->m_ImageIO->CanStreamRead())
147 dimSize[i] = this->m_ImageIO->GetDimensions(i);
149 dimSize[i] = output->GetRequestedRegion().GetSize()[i];
160 for (
unsigned int i = 0; i < dimSize.GetSizeDimension(); ++i)
162 ioSize[i] = dimSize[i];
166 if (!this->m_ImageIO->CanStreamRead())
169 start = output->GetRequestedRegion().GetIndex();
170 for (
unsigned int i = 0; i < start.GetIndexDimension(); ++i)
172 ioStart[i] = start[i];
175 ioRegion.SetSize(ioSize);
176 ioRegion.SetIndex(ioStart);
178 this->m_ImageIO->SetIORegion(ioRegion);
183 if (this->m_ImageIO->GetComponentTypeInfo() ==
typeid(
typename ConvertOutputPixelTraits::ComponentType) &&
187 this->m_ImageIO->Read(buffer);
198 std::streamoff nbBytes = (this->m_ImageIO->GetComponentSize() * std::max(this->m_ImageIO->GetNumberOfComponents(), (
unsigned int)m_BandList.size())) *
199 static_cast<std::streamoff
>(region.GetNumberOfPixels());
201 char* loadBuffer =
new char[nbBytes];
203 this->m_ImageIO->Read(loadBuffer);
205 if (m_FilenameHelper->BandRangeIsSet())
206 this->m_ImageIO->DoMapBuffer(loadBuffer, region.GetNumberOfPixels(), this->m_BandList);
208 this->DoConvertBuffer(loadBuffer, region.GetNumberOfPixels());
214 template <
class TOutputImage,
class ConvertPixelTraits>
217 typename TOutputImage::Pointer out =
dynamic_cast<TOutputImage*
>(output);
221 if (!this->m_ImageIO->CanStreamRead())
225 out->SetRequestedRegion(out->GetLargestPossibleRegion());
234 template <
class TOutputImage,
class ConvertPixelTraits>
237 typename TOutputImage::Pointer output = this->GetOutput();
240 if (this->m_FileName ==
"")
247 std::string lFileName;
248 bool found = GetGdalReadImageFileName(this->m_FileName, lFileName);
252 this->m_FileName = lFileName;
255 if (this->m_UserSpecifiedImageIO ==
false)
262 this->TestValidImageIO();
265 itk::MetaDataDictionary& dict = this->m_ImageIO->GetMetaDataDictionary();
270 bool lVectorImage =
false;
271 if (strcmp(output->GetNameOfClass(),
"VectorImage") == 0)
274 this->m_ImageIO->SetOutputImagePixelType(
PixelIsComplex(dummy), lVectorImage);
277 if (m_FilenameHelper->SubDatasetIndexIsSet())
287 if (m_FilenameHelper->ResolutionFactorIsSet())
299 this->m_ImageIO->SetFileName(this->m_FileName);
300 this->m_ImageIO->ReadImageInformation();
306 double spacing[TOutputImage::ImageDimension];
307 double origin[TOutputImage::ImageDimension];
308 typename TOutputImage::DirectionType direction;
309 std::vector<double> axis;
312 for (
unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
314 if (i < this->m_ImageIO->GetNumberOfDimensions())
316 dimSize[i] = this->m_ImageIO->GetDimensions(i);
317 if (this->m_ImageIO->GetSpacing(i) < 0)
321 spacing[i] = spacing_sign * this->m_ImageIO->GetSpacing(i);
322 origin[i] = this->m_ImageIO->GetOrigin(i);
325 axis = this->m_ImageIO->GetDirection(i);
326 for (
unsigned j = 0; j < TOutputImage::ImageDimension; ++j)
328 if (j < this->m_ImageIO->GetNumberOfDimensions())
330 direction[j][i] = spacing_sign * axis[j];
334 direction[j][i] = 0.0;
346 for (
unsigned j = 0; j < TOutputImage::ImageDimension; ++j)
350 direction[j][i] = 1.0;
354 direction[j][i] = 0.0;
360 if (m_FilenameHelper->GetSkipCarto())
362 for (
unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
364 if (m_FilenameHelper->GetResolutionFactor() != 0)
366 spacing[i] = 1.0 * std::pow((
double)2, (
double)m_FilenameHelper->GetResolutionFactor());
372 origin[i] = 0.5 * spacing[i];
373 for (
unsigned j = 0; j < TOutputImage::ImageDimension; ++j)
377 direction[j][i] = 1.0;
381 direction[j][i] = 0.0;
387 output->SetOrigin(origin);
388 output->SetDirection(direction);
389 output->SetSpacing(spacing);
398 std::string DerivatedFileName = GetDerivedDatasetSourceFileName(m_FileName);
399 std::string extension = itksys::SystemTools::GetFilenameLastExtension(DerivatedFileName);
400 std::string attachedGeom = DerivatedFileName.substr(0, DerivatedFileName.size() - extension.size()) + std::string(
".geom");
402 if (!m_FilenameHelper->GetSkipGeom() && m_FilenameHelper->ExtGEOMFileNameIsSet())
407 geomSupplier.
FetchRPC(imd, 0.5, 0.5);
411 otbLogMacro(Info, <<
"Loading metadata from external geom file " << m_FilenameHelper->GetExtGEOMFileName());
414 else if (!m_FilenameHelper->GetSkipGeom() && itksys::SystemTools::FileExists(attachedGeom))
420 otbLogMacro(Info, <<
"Loading metadata from attached geom file " << attachedGeom);
426 if (gdalMetadataSupplierPointer)
429 otbLogMacro(Info, <<
"Loading metadata from official product");
434 if (m_FilenameHelper->GetSkipCarto())
442 if (!m_FilenameHelper->GetSkipGeom())
444 output->SetMetaDataDictionary(this->m_ImageIO->GetMetaDataDictionary());
445 this->SetMetaDataDictionary(this->m_ImageIO->GetMetaDataDictionary());
449 itk::MetaDataDictionary dictLight;
453 output->SetMetaDataDictionary(dictLight);
454 this->SetMetaDataDictionary(dictLight);
461 region.SetSize(dimSize);
462 region.SetIndex(start);
465 m_IOComponents = this->m_ImageIO->GetNumberOfComponents();
467 if (m_FilenameHelper->BandRangeIsSet())
469 bool ret = m_FilenameHelper->ResolveBandRange(m_FilenameHelper->GetBandRange(), m_IOComponents, m_BandList);
470 if (ret ==
false || m_BandList.size() == 0)
473 itkGenericExceptionMacro(
"The given band range is either empty or invalid for a " << m_IOComponents <<
" bands input image!");
477 for (
auto elem: m_BandList)
479 bandRangeMetadata.push_back(imd.
Bands[elem]);
481 imd.
Bands = bandRangeMetadata;
482 m_IOComponents = m_BandList.size();
497 if (strcmp(output->GetNameOfClass(),
"VectorImage") == 0)
499 typedef typename TOutputImage::AccessorFunctorType AccessorFunctorType;
500 AccessorFunctorType::SetVectorLength(output, m_IOComponents);
503 if (img_common !=
nullptr)
508 output->SetLargestPossibleRegion(region);
511 template <
class TOutputImage,
class ConvertPixelTraits>
517 if (dsds_pos != std::string::npos)
521 if (alg_pos != std::string::npos)
523 std::string sourceFilename = filename.substr(alg_pos + 1, filename.size() - alg_pos);
524 return sourceFilename;
530 template <
class TOutputImage,
class ConvertPixelTraits>
533 if (this->m_ImageIO.IsNull())
535 std::string fileToCheck = GetDerivedDatasetSourceFileName(m_FileName);
538 if (!itksys::SystemTools::FileExists(fileToCheck))
540 throw otb::ImageFileReaderException(__FILE__, __LINE__, std::string(
"Cannot open image ") + fileToCheck + std::string(
". The file does not exist."),
546 std::string(
". Probably unsupported format or incorrect filename extension."),
552 template <
class TOutputImage,
class ConvertPixelTraits>
555 std::vector<std::string> listFileSearch;
556 listFileSearch.push_back(
"DAT_01.001");
557 listFileSearch.push_back(
"dat_01.001");
558 listFileSearch.push_back(
"IMAGERY.TIF");
559 listFileSearch.push_back(
"imagery.tif");
562 listFileSearch.push_back(
"IMAG_01.DAT");
563 listFileSearch.push_back(
"imag_01.dat");
565 std::string str_FileName;
566 bool fic_trouve(
false);
569 std::vector<std::string> listFileFind;
571 if (listFileFind.empty() ==
false)
574 while ((cpt < listFileFind.size()) && (fic_trouve ==
false))
576 str_FileName = std::string(listFileFind[cpt]);
577 for (
unsigned int i = 0; i < listFileSearch.size(); ++i)
579 if (str_FileName.compare(listFileSearch[i]) == 0)
581 GdalFileName = std::string(filename) + str_FileName;
590 std::string strFileName(filename);
592 std::string extension = itksys::SystemTools::GetFilenameLastExtension(strFileName);
593 if ((extension ==
".HDR") || (extension ==
".hdr"))
600 GdalFileName = std::string(filename);
608 template <
class TOutputImage,
class ConvertPixelTraits>
611 const std::string skip_geom_key =
"skipgeom";
612 const std::string geom_key =
"geom";
617 helper->SetExtendedFileName(extendedFileName);
618 std::string simpleFileName = helper->GetSimpleFileName();
620 if (simpleFileName == this->m_FileName)
627 if (oldMap.size() != newMap.size() || !std::equal(oldMap.begin(), oldMap.end(), newMap.begin()))
634 this->m_FileName = simpleFileName;
638 m_FilenameHelper = helper;
641 template <
class TOutputImage,
class ConvertPixelTraits>
644 return this->m_FilenameHelper->GetSimpleFileName();
647 template <
class TOutputImage,
class ConvertPixelTraits>
650 this->UpdateOutputInformation();
652 return this->m_ImageIO->GetOverviewsCount();
656 template <
class TOutputImage,
class ConvertPixelTraits>
659 this->UpdateOutputInformation();
661 return this->m_ImageIO->GetOverviewsInfo();
664 template <
class TOutputImage,
class ConvertPixelTraits>
686 #define OTB_CONVERT_BUFFER_IF_BLOCK(type) \
687 else if (m_ImageIO->GetComponentTypeInfo() == typeid(type)) \
689 if (strcmp(this->GetOutput()->GetNameOfClass(), "VectorImage") == 0) \
691 ConvertPixelBuffer<type, OutputImagePixelType, ConvertPixelTraits>::ConvertVectorImage(static_cast<type*>(inputData), m_IOComponents, outputData, \
696 ConvertPixelBuffer<type, OutputImagePixelType, ConvertPixelTraits>::Convert(static_cast<type*>(inputData), m_IOComponents, outputData, numberOfPixels); \
699 #define OTB_CONVERT_CBUFFER_IF_BLOCK(type) \
700 else if (m_ImageIO->GetComponentTypeInfo() == typeid(type)) \
702 if (strcmp(this->GetOutput()->GetNameOfClass(), "VectorImage") == 0) \
704 if ((typeid(OutputImagePixelType) == typeid(std::complex<double>)) || (typeid(OutputImagePixelType) == typeid(std::complex<float>)) || \
705 (typeid(OutputImagePixelType) == typeid(std::complex<int>)) || (typeid(OutputImagePixelType) == typeid(std::complex<short>))) \
707 ConvertPixelBuffer<type::value_type, OutputImagePixelType, ConvertPixelTraits>::ConvertComplexVectorImageToVectorImageComplex( \
708 static_cast<type*>(inputData), m_IOComponents, outputData, numberOfPixels); \
712 ConvertPixelBuffer<type::value_type, OutputImagePixelType, ConvertPixelTraits>::ConvertComplexVectorImageToVectorImage( \
713 static_cast<type*>(inputData), m_IOComponents, outputData, numberOfPixels); \
718 ConvertPixelBuffer<type::value_type, OutputImagePixelType, ConvertPixelTraits>::ConvertComplexToGray(static_cast<type*>(inputData), m_IOComponents, \
719 outputData, numberOfPixels); \
743 std::ostringstream msg;
744 msg <<
"Couldn't convert component type: " << std::endl
746 <<
"to one of: " << std::endl
747 <<
" " <<
typeid(
unsigned char).name() << std::endl
748 <<
" " <<
typeid(char).name() << std::endl
749 <<
" " <<
typeid(
unsigned short).name() << std::endl
750 <<
" " <<
typeid(short).name() << std::endl
751 <<
" " <<
typeid(
unsigned int).name() << std::endl
752 <<
" " <<
typeid(int).name() << std::endl
753 <<
" " <<
typeid(
unsigned long).name() << std::endl
754 <<
" " <<
typeid(long).name() << std::endl
755 <<
" " <<
typeid(float).name() << std::endl
756 <<
" " <<
typeid(double).name() << std::endl;
757 e.SetDescription(msg.str());
758 e.SetLocation(ITK_LOCATION);
762 #undef OTB_CONVERT_BUFFER_IF_BLOCK
763 #undef OTB_CONVERT_CBUFFER_IF_BLOCK