Orfeo Toolbox  4.0
otbImageFileReader.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbImageFileReader_txx
19 #define __otbImageFileReader_txx
20 
21 #include "otbImageFileReader.h"
22 
23 #include "otbSystem.h"
24 #include <itksys/SystemTools.hxx>
25 #include <fstream>
26 
27 #include "itkObjectFactory.h"
28 #include "itkImageIOFactory.h"
29 #include "itkImageRegion.h"
30 #include "itkPixelTraits.h"
31 #include "itkVectorImage.h"
32 #include "itkMetaDataObject.h"
33 
34 #include "otbConvertPixelBuffer.h"
35 #include "otbMacro.h"
36 #include "otbImageIOFactory.h"
37 #include "otbImageKeywordlist.h"
38 #include "otbMetaDataKey.h"
39 
40 #include "otbGDALImageIO.h" //FIXME avoid requiring GDALImageIO here
41 #if defined(OTB_USE_JPEG2000)
42 #include "otbJPEG2000ImageIO.h" //FIXME avoid requiring JPEG2000ImageIO here
43 #endif
44 #include "otbTileMapImageIO.h" //FIXME avoid requiring TileMapImageIO here
45 #include "otbCurlHelper.h"
46 
47 namespace otb
48 {
49 
50 template<class T>
51 bool PixelIsComplex(const std::complex<T>& /*dummy*/)
52 {
53  return true;
54 }
55 template<class T>
56 bool PixelIsComplex(const T& /*dummy*/)
57 {
58  return false;
59 }
60 
61 template <class TOutputImage, class ConvertPixelTraits>
64  : m_ImageIO(),
65  m_UserSpecifiedImageIO(false),
66  m_FileName(""),
67  m_UseStreaming(true),
68  m_ExceptionMessage(""),
69  m_ActualIORegion(),
70  m_FilenameHelper(FNameHelperType::New()),
71  m_Curl(CurlHelper::New()),
72  m_AdditionalNumber(0)
73 {
74 }
75 
76 template <class TOutputImage, class ConvertPixelTraits>
79 {
80 }
81 
82 template <class TOutputImage, class ConvertPixelTraits>
84 ::PrintSelf(std::ostream& os, itk::Indent indent) const
85 {
86  Superclass::PrintSelf(os, indent);
87 
88  if (this->m_ImageIO)
89  {
90  os << indent << "ImageIO: \n";
91  this->m_ImageIO->Print(os, indent.GetNextIndent());
92  }
93  else
94  {
95  os << indent << "ImageIO: (null)" << "\n";
96  }
97 
98  os << indent << "UserSpecifiedImageIO flag: " << this->m_UserSpecifiedImageIO << "\n";
99  os << indent << "m_FileName: " << this->m_FileName << "\n";
100  os << indent << "m_UseStreaming flag: " << this->m_UseStreaming << "\n";
101  os << indent << "m_ActualIORegion: " << this->m_ActualIORegion << "\n";
102  os << indent << "m_AdditionalNumber: " << this->m_AdditionalNumber << "\n";
103 }
104 
105 template <class TOutputImage, class ConvertPixelTraits>
106 void
109 {
110  itkDebugMacro("setting ImageIO to " << imageIO );
111  if (this->m_ImageIO != imageIO )
112  {
113  this->m_ImageIO = imageIO;
114  this->Modified();
115  }
116  m_UserSpecifiedImageIO = true;
117 }
118 
119 template <class TOutputImage, class ConvertPixelTraits>
120 void
123 {
124 
125  typename TOutputImage::Pointer output = this->GetOutput();
126 
127  // allocate the output buffer
128  output->SetBufferedRegion(output->GetRequestedRegion());
129  output->Allocate();
130 
131  // Test if the file exist and if it can be open.
132  // An exception will be thrown otherwise.
133  this->TestFileExistanceAndReadability();
134 
135  // Tell the ImageIO to read the file
136  OutputImagePixelType *buffer =
137  output->GetPixelContainer()->GetBufferPointer();
138  this->m_ImageIO->SetFileName(this->m_FileName.c_str());
139 
140  itk::ImageIORegion ioRegion(TOutputImage::ImageDimension);
141 
142  itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize();
143  itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex();
144 
145  /* Init IORegion with size or streaming size */
146  SizeType dimSize;
147  for (unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
148  {
149  if (i < this->m_ImageIO->GetNumberOfDimensions())
150  {
151  if (!this->m_ImageIO->CanStreamRead()) dimSize[i] = this->m_ImageIO->GetDimensions(i);
152  else dimSize[i] = output->GetRequestedRegion().GetSize()[i];
153  }
154  else
155  {
156  // Number of dimensions in the output is more than number of dimensions
157  // in the ImageIO object (the file). Use default values for the size,
158  // spacing, and origin for the final (degenerate) dimensions.
159  dimSize[i] = 1;
160  }
161  }
162 
163  for (unsigned int i = 0; i < dimSize.GetSizeDimension(); ++i)
164  {
165  ioSize[i] = dimSize[i];
166  }
167 
168  typedef typename TOutputImage::IndexType IndexType;
169  IndexType start;
170  if (!this->m_ImageIO->CanStreamRead()) start.Fill(0);
171  else start = output->GetRequestedRegion().GetIndex();
172  for (unsigned int i = 0; i < start.GetIndexDimension(); ++i)
173  {
174  ioStart[i] = start[i];
175  }
176 
177  ioRegion.SetSize(ioSize);
178  ioRegion.SetIndex(ioStart);
179 
180  this->m_ImageIO->SetIORegion(ioRegion);
181 
184 
185  if (this->m_ImageIO->GetComponentTypeInfo()
186  == typeid(typename ConvertOutputPixelTraits::ComponentType)
187  && (this->m_ImageIO->GetNumberOfComponents()
188  == ConvertIOPixelTraits::GetNumberOfComponents()))
189  {
190  // Have the ImageIO read directly into the allocated buffer
191  this->m_ImageIO->Read(buffer);
192  return;
193  }
194  else // a type conversion is necessary
195  {
196  // note: char is used here because the buffer is read in bytes
197  // regardless of the actual type of the pixels.
198  ImageRegionType region = output->GetBufferedRegion();
199 
200  // Adapt the image size with the region
201  std::streamoff nbBytes = (this->m_ImageIO->GetComponentSize() * this->m_ImageIO->GetNumberOfComponents())
202  * static_cast<std::streamoff>(region.GetNumberOfPixels());
203 
204  char * loadBuffer = new char[nbBytes];
205 
206  otbMsgDevMacro(<< "size of Buffer to GDALImageIO::read = " << nbBytes << " = \n"
207  << "ComponentSize ("<< this->m_ImageIO->GetComponentSize() << ") x " \
208  << "Nb of Component (" << this->m_ImageIO->GetNumberOfComponents() << ") x " \
209  << "Nb of Pixel to read (" << region.GetNumberOfPixels() << ")" );
210 
211  this->m_ImageIO->Read(loadBuffer);
212 
213  this->DoConvertBuffer(loadBuffer, region.GetNumberOfPixels());
214 
215  delete[] loadBuffer;
216  }
217 }
218 
219 template <class TOutputImage, class ConvertPixelTraits>
220 void
223 {
224  typename TOutputImage::Pointer out = dynamic_cast<TOutputImage*>(output);
225 
226  // If the ImageIO object cannot stream, then set the RequestedRegion to the
227  // LargestPossibleRegion
228  if (!this->m_ImageIO->CanStreamRead())
229  {
230  if (out)
231  {
232  out->SetRequestedRegion(out->GetLargestPossibleRegion());
233  }
234  else
235  {
236  throw otb::ImageFileReaderException(__FILE__, __LINE__,
237  "Invalid output object type");
238  }
239  }
240 }
241 
242 template <class TOutputImage, class ConvertPixelTraits>
243 void
246 {
247 
248  typename TOutputImage::Pointer output = this->GetOutput();
249 
250  itkDebugMacro(<< "Reading file for GenerateOutputInformation()" << this->m_FileName);
251 
252  // Check to see if we can read the file given the name or prefix
253  //
254  if (this->m_FileName == "")
255  {
256  throw otb::ImageFileReaderException(__FILE__, __LINE__, "FileName must be specified");
257  }
258 
259  // Find real image file name
260  // !!!! Update FileName
261  std::string lFileName;
262  bool found = GetGdalReadImageFileName(this->m_FileName, lFileName);
263  if (found == false)
264  {
265  otbMsgDebugMacro(<< "Filename was NOT unknown. May be recognized by a Image factory ! ");
266  }
267  // Update FileName
268  this->m_FileName = lFileName;
269 
270  std::string lFileNameOssimKeywordlist = this->m_FileName;
271 
272  // Test if the file exists and if it can be opened.
273  // An exception will be thrown otherwise.
274  // We catch the exception because some ImageIO's may not actually
275  // open a file. Still reports file error if no ImageIO is loaded.
276 
277  try
278  {
279  m_ExceptionMessage = "";
280  this->TestFileExistanceAndReadability();
281  }
282  catch (itk::ExceptionObject & err)
283  {
284  m_ExceptionMessage = err.GetDescription();
285  }
286 
287  if (this->m_UserSpecifiedImageIO == false) //try creating via factory
288  {
289  this->m_ImageIO = ImageIOFactory::CreateImageIO(this->m_FileName.c_str(), otb::ImageIOFactory::ReadMode);
290  }
291 
292  if (this->m_ImageIO.IsNull())
293  {
294  this->Print(std::cerr);
295  otb::ImageFileReaderException e(__FILE__, __LINE__);
296  std::ostringstream msg;
297  msg << " Could not create IO object for file "
298  << this->m_FileName.c_str() << std::endl;
299  msg << " Tried to create one of the following:" << std::endl;
300  std::list<itk::LightObject::Pointer> allobjects =
302  for (std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin();
303  i != allobjects.end(); ++i)
304  {
305  otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer());
306  msg << " " << io->GetNameOfClass() << std::endl;
307  }
308  msg << " You probably failed to set a file suffix, or" << std::endl;
309  msg << " set the suffix to an unsupported type." << std::endl;
310  e.SetDescription(msg.str().c_str());
311  throw e;
312  return;
313  }
314 
315 
316  // Get the ImageIO MetaData Dictionary
317  itk::MetaDataDictionary& dict = this->m_ImageIO->GetMetaDataDictionary();
318 
319  // Special actions for the gdal image IO
320  if (strcmp(this->m_ImageIO->GetNameOfClass(), "GDALImageIO") == 0)
321  {
322  typename GDALImageIO::Pointer imageIO = dynamic_cast<GDALImageIO*>(this->GetImageIO());
323 
324  // Hint the IO whether the OTB image type takes complex pixels
325  // this will determine the strategy to fill up a vector image
326  OutputImagePixelType dummy;
327  imageIO->SetIsComplex(PixelIsComplex(dummy));
328 
329  // VectorImage ??
330  if (strcmp(output->GetNameOfClass(), "VectorImage") == 0)
331  imageIO->SetIsVectorImage(true);
332  else
333  imageIO->SetIsVectorImage(false);
334 
335  // Pass the dataset number (used for hdf files for example)
336  if (m_FilenameHelper->SubDatasetIndexIsSet())
337  {
338  imageIO->SetDatasetNumber(m_FilenameHelper->GetSubDatasetIndex());
339  }
340  else
341  {
342  imageIO->SetDatasetNumber(m_AdditionalNumber);
343  }
344  }
345 
346 
347  if (m_FilenameHelper->ResolutionFactorIsSet())
348  {
349  itk::EncapsulateMetaData<unsigned int>(dict, MetaDataKey::ResolutionFactor, m_FilenameHelper->GetResolutionFactor());
350  }
351  else
352  {
353  itk::EncapsulateMetaData<unsigned int>(dict, MetaDataKey::ResolutionFactor, m_AdditionalNumber);
354  }
355 
356  // Special actions for the JPEG2000ImageIO
357  if (strcmp(this->m_ImageIO->GetNameOfClass(), "JPEG2000ImageIO") == 0)
358  {
359  itk::EncapsulateMetaData<unsigned int>(dict, MetaDataKey::CacheSizeInBytes, 135000000);
360  }
361 
362  // Got to allocate space for the image. Determine the characteristics of
363  // the image.
364  //
365  this->m_ImageIO->SetFileName(this->m_FileName.c_str());
366  this->m_ImageIO->ReadImageInformation();
367  // Initialization du nombre de Composante par pixel
368 // THOMAS ceci n'est pas dans ITK !!
369 // output->SetNumberOfComponentsPerPixel(this->m_ImageIO->GetNumberOfComponents());
370 
371  SizeType dimSize;
372  double spacing[TOutputImage::ImageDimension];
373  double origin[TOutputImage::ImageDimension];
374  typename TOutputImage::DirectionType direction;
375  std::vector<double> axis;
376 
377  for (unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
378  {
379  if (i < this->m_ImageIO->GetNumberOfDimensions())
380  {
381  dimSize[i] = this->m_ImageIO->GetDimensions(i);
382  spacing[i] = this->m_ImageIO->GetSpacing(i);
383  origin[i] = this->m_ImageIO->GetOrigin(i);
384 // Please note: direction cosines are stored as columns of the
385 // direction matrix
386  axis = this->m_ImageIO->GetDirection(i);
387  for (unsigned j = 0; j < TOutputImage::ImageDimension; ++j)
388  {
389  if (j < this->m_ImageIO->GetNumberOfDimensions())
390  {
391  direction[j][i] = axis[j];
392  }
393  else
394  {
395  direction[j][i] = 0.0;
396  }
397  }
398  }
399  else
400  {
401  // Number of dimensions in the output is more than number of dimensions
402  // in the ImageIO object (the file). Use default values for the size,
403  // spacing, origin and direction for the final (degenerate) dimensions.
404  dimSize[i] = 1;
405  spacing[i] = 1.0;
406  origin[i] = 0.0;
407  for (unsigned j = 0; j < TOutputImage::ImageDimension; ++j)
408  {
409  if (i == j)
410  {
411  direction[j][i] = 1.0;
412  }
413  else
414  {
415  direction[j][i] = 0.0;
416  }
417  }
418  }
419  }
420 
421  if (m_FilenameHelper->GetSkipCarto())
422  {
423  for (unsigned int i = 0; i < TOutputImage::ImageDimension; ++i)
424  {
425  origin[i] = 0.0;
426  if ( m_FilenameHelper->GetResolutionFactor() != 0 )
427  {
428  spacing[i] = 1.0*vcl_pow((double)2, (double)m_FilenameHelper->GetResolutionFactor());
429  }
430  else
431  {
432  spacing[i] = 1.0;
433  }
434  }
435  }
436 
437  output->SetSpacing(spacing); // Set the image spacing
438  output->SetOrigin(origin); // Set the image origin
439  output->SetDirection(direction); // Set the image direction cosines
440 
441  // Update otb Keywordlist
442  ImageKeywordlist otb_kwl;
443  if (!m_FilenameHelper->ExtGEOMFileNameIsSet())
444  {
445  otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist);
446  otbMsgDevMacro(<< "Loading internal kwl");
447  }
448  else
449  {
450  otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName());
451  otbMsgDevMacro(<< "Loading external kwl");
452  }
453 
454  // Pass the depth parameter from the tilemap around
455  if (strcmp(this->m_ImageIO->GetNameOfClass(), "TileMapImageIO") == 0)
456  {
457  typename TileMapImageIO::Pointer imageIO = dynamic_cast<TileMapImageIO*>(this->GetImageIO());
458  std::ostringstream depth;
459  depth << imageIO->GetDepth();
460  otb_kwl.AddKey("depth", depth.str());
461  }
462 
463  otbMsgDevMacro(<< otb_kwl);
464 
465  // Don't add an empty ossim keyword list
466  if( otb_kwl.GetSize() != 0 )
467  {
468  itk::EncapsulateMetaData<ImageKeywordlist>(dict,
470  }
471  else
472  {
473  //
474  // For image with world file, we have a non-null GeoTransform, an empty kwl, but no projection ref.
475  // Decision made here : if the keywordlist is empty, and the geotransform is not the identity,
476  // then assume the file is in WGS84
477  //
478  std::string projRef;
480 
481  const double Epsilon = 1.0E-12;
482  if ( projRef.empty()
483  && vcl_abs(origin[0]) > Epsilon
484  && vcl_abs(origin[1]) > Epsilon
485  && vcl_abs(spacing[0] - 1) > Epsilon
486  && vcl_abs(spacing[1] - 1) > Epsilon)
487  {
488  std::string wgs84ProjRef =
489  "GEOGCS[\"GCS_WGS_1984\", DATUM[\"D_WGS_1984\", SPHEROID[\"WGS_1984\", 6378137, 298.257223563]],"
490  "PRIMEM[\"Greenwich\", 0], UNIT[\"Degree\", 0.017453292519943295]]";
491 
492  itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, wgs84ProjRef);
493  }
494  }
495 
496  // If Skip ProjectionRef is activated, remove ProjRef from dict
497  if (m_FilenameHelper->GetSkipCarto())
498  {
499  itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, "");
500  }
501 
502  //Copy MetaDataDictionary from instantiated reader to output image.
503  if (!m_FilenameHelper->GetSkipGeom())
504  {
505  output->SetMetaDataDictionary(this->m_ImageIO->GetMetaDataDictionary());
506  this->SetMetaDataDictionary(this->m_ImageIO->GetMetaDataDictionary());
507  }
508  else
509  {
510  itk::MetaDataDictionary dictLight;
511  std::string projRef;
513  itk::EncapsulateMetaData<std::string>(dictLight, MetaDataKey::ProjectionRefKey, projRef);
514  output->SetMetaDataDictionary(dictLight);
515  this->SetMetaDataDictionary(dictLight);
516  }
517 
518  typedef typename TOutputImage::IndexType IndexType;
519 
520  IndexType start;
521  start.Fill(0);
522 
523  ImageRegionType region;
524  region.SetSize(dimSize);
525  region.SetIndex(start);
526 
527 // THOMAS : ajout
528 // If a VectorImage, this requires us to set the
529 // VectorLength before allocate
530  if (strcmp(output->GetNameOfClass(), "VectorImage") == 0)
531  {
532  typedef typename TOutputImage::AccessorFunctorType AccessorFunctorType;
533  AccessorFunctorType::SetVectorLength(output, this->m_ImageIO->GetNumberOfComponents());
534  }
535 
536  output->SetLargestPossibleRegion(region);
537 
538 }
539 
540 template <class TOutputImage, class ConvertPixelTraits>
541 void
544 {
545  // Test if the file a server name
546  if (this->m_FileName[0] == 'h'
547  && this->m_FileName[1] == 't'
548  && this->m_FileName[2] == 't'
549  && this->m_FileName[3] == 'p')
550  {
551  // If the url is not available
552  if (!m_Curl->TestUrlAvailability(this->m_FileName))
553  {
554  otb::ImageFileReaderException e(__FILE__, __LINE__);
555  std::ostringstream msg;
556  msg << "File name is an http address, but curl fails to connect to it "
557  << std::endl << "Filename = " << this->m_FileName
558  << std::endl;
559  e.SetDescription(msg.str().c_str());
560  throw e;
561  }
562  return;
563  }
564 
565  // Test if the file exists.
566  if (!itksys::SystemTools::FileExists(this->m_FileName.c_str()))
567  {
568  otb::ImageFileReaderException e(__FILE__, __LINE__);
569  std::ostringstream msg;
570  msg << "The file doesn't exist. "
571  << std::endl << "Filename = " << this->m_FileName
572  << std::endl;
573  e.SetDescription(msg.str().c_str());
574  throw e;
575  return;
576  }
577 
578  // Test if the file can be open for reading access.
579  //Only if m_FileName specify a filename (not a dirname)
580  if (itksys::SystemTools::FileExists(this->m_FileName.c_str(), true) == true)
581  {
582  std::ifstream readTester;
583  readTester.open(this->m_FileName.c_str());
584  if (readTester.fail())
585  {
586  readTester.close();
587  std::ostringstream msg;
588  msg << "The file couldn't be opened for reading. "
589  << std::endl << "Filename: " << this->m_FileName
590  << std::endl;
591  otb::ImageFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
592  throw e;
593  return;
594 
595  }
596  readTester.close();
597  }
598 }
599 
600 template <class TOutputImage, class ConvertPixelTraits>
601 bool
603 ::GetGdalReadImageFileName(const std::string& filename, std::string& GdalFileName)
604 {
605  std::vector<std::string> listFileSearch;
606  listFileSearch.push_back("DAT_01.001");
607  listFileSearch.push_back("dat_01.001"); // RADARSAT or SAR_ERS2
608  listFileSearch.push_back("IMAGERY.TIF");
609  listFileSearch.push_back("imagery.tif"); //For format SPOT5TIF
610 // Not recognized as a supported file format by GDAL.
611 // listFileSearch.push_back("IMAGERY.BIL"); listFileSearch.push_back("imagery.bil"); //For format SPOT5BIL
612  listFileSearch.push_back("IMAG_01.DAT");
613  listFileSearch.push_back("imag_01.dat"); //For format SPOT4
614 
615  std::string str_FileName;
616  bool fic_trouve(false);
617 
618  // Si c'est un repertoire, on regarde le contenu pour voir si c'est pas du RADARSAT, ERS
619  std::vector<std::string> listFileFind;
620  listFileFind = System::Readdir(filename);
621  if (listFileFind.empty() == false)
622  {
623  unsigned int cpt(0);
624  while ((cpt < listFileFind.size()) && (fic_trouve == false))
625  {
626  str_FileName = std::string(listFileFind[cpt]);
627  for (unsigned int i = 0; i < listFileSearch.size(); ++i)
628  {
629  if (str_FileName.compare(listFileSearch[i]) == 0)
630  {
631  GdalFileName = std::string(filename) + str_FileName; //listFileSearch[i];
632  fic_trouve = true;
633  }
634  }
635  ++cpt;
636  }
637  }
638  else
639  {
640  std::string strFileName(filename);
641 
642  std::string extension = itksys::SystemTools::GetFilenameLastExtension(strFileName);
643  if ((extension == ".HDR") || (extension == ".hdr"))
644  {
645  //Supprime l'extension
646  GdalFileName = System::GetRootName(strFileName);
647  }
648 
649  else
650  {
651  // Sinon le filename est le nom du fichier a ouvrir
652  GdalFileName = std::string(filename);
653  }
654  fic_trouve = true;
655  }
656  otbMsgDevMacro(<< "lFileNameGdal : " << GdalFileName.c_str());
657  otbMsgDevMacro(<< "fic_trouve : " << fic_trouve);
658  return (fic_trouve);
659 }
660 
661 template <class TOutputImage, class ConvertPixelTraits>
662 void
664 ::SetFileName(std::string extendedFileName)
665 {
666  this->SetFileName(extendedFileName.c_str());
667 }
668 
669 template <class TOutputImage, class ConvertPixelTraits>
670 void
672 ::SetFileName(const char* extendedFileName)
673 {
674  this->m_FilenameHelper->SetExtendedFileName(extendedFileName);
675  this->m_FileName = this->m_FilenameHelper->GetSimpleFileName();
676  this->Modified();
677 }
678 
679 template <class TOutputImage, class ConvertPixelTraits>
680 const char*
683 {
684 return this->m_FilenameHelper->GetSimpleFileName();
685 }
686 
687 template <class TOutputImage, class ConvertPixelTraits>
688 std::vector<unsigned int>
691  {
692  this->UpdateOutputInformation();
693 
694  std::vector<unsigned int> res;
695  // GDAL image IO
696  if (strcmp(this->m_ImageIO->GetNameOfClass(), "GDALImageIO") == 0)
697  {
698  typename GDALImageIO::Pointer imageIO = dynamic_cast<GDALImageIO*>(this->GetImageIO());
699  imageIO->GetAvailableResolutions(res);
700  return res;
701  }
702 
703 #if defined(OTB_USE_JPEG2000)
704  // JPEG2000 image IO
705  if (strcmp(this->m_ImageIO->GetNameOfClass(), "JPEG2000ImageIO") == 0)
706  {
707  typename JPEG2000ImageIO::Pointer imageIO = dynamic_cast<JPEG2000ImageIO*>(this->GetImageIO());
708  imageIO->GetAvailableResolutions(res);
709  return res;
710  }
711 #endif
712 
713  // other imageIO
714  res.clear();
715  res.push_back(0);
716  return res;
717  }
718 
719 template <class TOutputImage, class ConvertPixelTraits>
720 bool
722 ::GetResolutionsInfo( std::vector<unsigned int>& res, std::vector<std::string>& desc)
723  {
724  this->UpdateOutputInformation();
725 
726  // GDAL image IO
727  if (strcmp(this->m_ImageIO->GetNameOfClass(), "GDALImageIO") == 0)
728  {
729  typename GDALImageIO::Pointer imageIO = dynamic_cast<GDALImageIO*>(this->GetImageIO());
730  imageIO->GetResolutionInfo(res,desc);
731  return true;
732  }
733 
734 #if defined(OTB_USE_JPEG2000)
735  // JPEG2000 image IO
736  if (strcmp(this->m_ImageIO->GetNameOfClass(), "JPEG2000ImageIO") == 0)
737  {
738  typename JPEG2000ImageIO::Pointer imageIO = dynamic_cast<JPEG2000ImageIO*>(this->GetImageIO());
739  imageIO->GetResolutionInfo(res,desc);
740  return true;
741  }
742 #endif
743 
744  // other imageIO
745  res.clear();
746  desc.clear();
747 
748  res.push_back(0);
749 
750  // TODO MSD : manage the tile information or not ?
751  std::ostringstream oss;
752  oss << "Resolution: " << 0 << " (Image [w x h]: "
753  << this->m_ImageIO->GetDimensions(0) << "x" << this->m_ImageIO->GetDimensions(1)
754  << ", Tile [w x h]: " << "not defined x not defined" << ")";
755  desc.push_back(oss.str());
756 
757  return true;
758  }
759 
760 template <class TOutputImage, class ConvertPixelTraits>
761 unsigned int
764  {
765  this->UpdateOutputInformation();
766 
767  // GDAL image IO
768  if (strcmp(this->m_ImageIO->GetNameOfClass(), "GDALImageIO") == 0)
769  {
770  typename GDALImageIO::Pointer imageIO = dynamic_cast<GDALImageIO*>(this->GetImageIO());
771  return imageIO->GetNumberOfOverviews();
772  }
773 
774 #if defined(OTB_USE_JPEG2000)
775  // JPEG2000 image IO
776  if (strcmp(this->m_ImageIO->GetNameOfClass(), "JPEG2000ImageIO") == 0)
777  {
778  typename JPEG2000ImageIO::Pointer imageIO = dynamic_cast<JPEG2000ImageIO*>(this->GetImageIO());
779  return imageIO->GetNumberOfOverviews();
780  }
781 #endif
782 
783  // other imageIO whi
784  return 0;
785  }
786 
787 template <class TOutputImage, class ConvertPixelTraits>
788 bool
791  {
792  this->UpdateOutputInformation();
793 
794  // GDAL image IO
795  if (strcmp(this->m_ImageIO->GetNameOfClass(), "GDALImageIO") == 0)
796  {
797  return true;
798  }
799 
800 #if defined(OTB_USE_JPEG2000)
801  // JPEG2000 image IO
802  if (strcmp(this->m_ImageIO->GetNameOfClass(), "JPEG2000ImageIO") == 0)
803  {
804  return true;
805  }
806 #endif
807 
808  // Other imageIO
809  return false;
810  }
811 
812 template <class TOutputImage, class ConvertPixelTraits>
813 void
815 ::DoConvertBuffer(void* inputData,
816  size_t numberOfPixels)
817 {
818  // get the pointer to the destination buffer
819  OutputImagePixelType *outputData =
820  this->GetOutput()->GetPixelContainer()->GetBufferPointer();
821 
822  // TODO:
823  // Pass down the PixelType (RGB, VECTOR, etc.) so that any vector to
824  // scalar conversion be type specific. i.e. RGB to scalar would use
825  // a formula to convert to luminance, VECTOR to scalar would use
826  // vector magnitude.
827 
828 
829  // Create a macro as this code is a bit lengthy and repetitive
830  // if the ImageIO pixel type is typeid(type) then use the ConvertPixelBuffer
831  // class to convert the data block to TOutputImage's pixel type
832  // see DefaultConvertPixelTraits and ConvertPixelBuffer
833 
834  // The first else if block applies only to images of type itk::VectorImage
835  // VectorImage needs to copy out the buffer differently.. The buffer is of
836  // type InternalPixelType, but each pixel is really 'k' consecutive pixels.
837 
838 #define OTB_CONVERT_BUFFER_IF_BLOCK(type) \
839  else if( m_ImageIO->GetComponentTypeInfo() == typeid(type) ) \
840  { \
841  if( strcmp( this->GetOutput()->GetNameOfClass(), "VectorImage" ) == 0 ) \
842  { \
843  ConvertPixelBuffer< \
844  type, \
845  OutputImagePixelType, \
846  ConvertPixelTraits \
847  > \
848  ::ConvertVectorImage( \
849  static_cast<type*>(inputData), \
850  m_ImageIO->GetNumberOfComponents(), \
851  outputData, \
852  numberOfPixels); \
853  } \
854  else \
855  { \
856  ConvertPixelBuffer< \
857  type, \
858  OutputImagePixelType, \
859  ConvertPixelTraits \
860  > \
861  ::Convert( \
862  static_cast<type*>(inputData), \
863  m_ImageIO->GetNumberOfComponents(), \
864  outputData, \
865  numberOfPixels); \
866  } \
867  }
868 #define OTB_CONVERT_CBUFFER_IF_BLOCK(type) \
869  else if( m_ImageIO->GetComponentTypeInfo() == typeid(type) ) \
870  { \
871  if( strcmp( this->GetOutput()->GetNameOfClass(), "VectorImage" ) == 0 ) \
872  { \
873  if( (typeid(OutputImagePixelType) == typeid(std::complex<double>)) \
874  || (typeid(OutputImagePixelType) == typeid(std::complex<float>)) \
875  || (typeid(OutputImagePixelType) == typeid(std::complex<int>)) \
876  || (typeid(OutputImagePixelType) == typeid(std::complex<short>)) ) \
877  {\
878  ConvertPixelBuffer< \
879  type::value_type, \
880  OutputImagePixelType, \
881  ConvertPixelTraits \
882  > \
883  ::ConvertComplexVectorImageToVectorImageComplex( \
884  static_cast<type*>(inputData), \
885  m_ImageIO->GetNumberOfComponents(), \
886  outputData, \
887  numberOfPixels); \
888  }\
889  else\
890  {\
891  ConvertPixelBuffer< \
892  type::value_type, \
893  OutputImagePixelType, \
894  ConvertPixelTraits \
895  > \
896  ::ConvertComplexVectorImageToVectorImage( \
897  static_cast<type*>(inputData), \
898  m_ImageIO->GetNumberOfComponents(), \
899  outputData, \
900  numberOfPixels); \
901  }\
902  } \
903  else \
904  { \
905  ConvertPixelBuffer< \
906  type::value_type, \
907  OutputImagePixelType, \
908  ConvertPixelTraits \
909  > \
910  ::ConvertComplexToGray( \
911  static_cast<type*>(inputData), \
912  m_ImageIO->GetNumberOfComponents(), \
913  outputData, \
914  numberOfPixels); \
915  } \
916  }
917 
918  if(0)
919  {
920  }
921  OTB_CONVERT_BUFFER_IF_BLOCK(unsigned char)
923  OTB_CONVERT_BUFFER_IF_BLOCK(unsigned short)
925  OTB_CONVERT_BUFFER_IF_BLOCK(unsigned int)
927  OTB_CONVERT_BUFFER_IF_BLOCK(unsigned long)
931  OTB_CONVERT_CBUFFER_IF_BLOCK(std::complex<short>)
932  OTB_CONVERT_CBUFFER_IF_BLOCK(std::complex<int>)
933  OTB_CONVERT_CBUFFER_IF_BLOCK(std::complex<float>)
934  OTB_CONVERT_CBUFFER_IF_BLOCK(std::complex<double>)
935  else
936  {
937  otb::ImageFileReaderException e(__FILE__, __LINE__);
938  std::ostringstream msg;
939  msg <<"Couldn't convert component type: "
940  << std::endl << " "
941  << m_ImageIO->GetComponentTypeAsString(m_ImageIO->GetComponentType())
942  << std::endl << "to one of: "
943  << std::endl << " " << typeid(unsigned char).name()
944  << std::endl << " " << typeid(char).name()
945  << std::endl << " " << typeid(unsigned short).name()
946  << std::endl << " " << typeid(short).name()
947  << std::endl << " " << typeid(unsigned int).name()
948  << std::endl << " " << typeid(int).name()
949  << std::endl << " " << typeid(unsigned long).name()
950  << std::endl << " " << typeid(long).name()
951  << std::endl << " " << typeid(float).name()
952  << std::endl << " " << typeid(double).name()
953  << std::endl;
954  e.SetDescription(msg.str().c_str());
955  e.SetLocation(ITK_LOCATION);
956  throw e;
957  return;
958  }
959 #undef OTB_CONVERT_BUFFER_IF_BLOCK
960 #undef OTB_CONVERT_CBUFFER_IF_BLOCK
961 }
962 
963 } //namespace otb
964 
965 #endif

Generated at Sat Mar 8 2014 15:58:25 for Orfeo Toolbox with doxygen 1.8.3.1