Commit e10fc3d0 authored by Guillaume Pasero's avatar Guillaume Pasero

Merge branch 'better_error_messages' into develop

parents 866ed790 cb4e1fcc
......@@ -1578,7 +1578,7 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
if (driverShortName == "NOT-FOUND")
{
itkExceptionMacro(
<< "GDAL Writing failed : the image file name '" << m_FileName.c_str() << "' is not recognized by GDAL.");
<< "GDAL Writing failed: the image file name '" << m_FileName.c_str() << "' is not recognized by GDAL.");
}
if (m_CanStreamWrite)
......@@ -1664,9 +1664,7 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer)
if (m_Dataset.IsNull())
{
itkExceptionMacro(
<< "GDAL Writing failed : Impossible to create the image file name '"
<< m_FileName << "' : " << CPLGetLastErrorMsg() );
itkExceptionMacro(<< CPLGetLastErrorMsg());
}
/*----------------------------------------------------------------------*/
......
......@@ -54,19 +54,14 @@ public:
/** Constructor. */
ImageFileReaderException(const char *file, unsigned int line,
const char* message = "Error in IO",
const char* loc = "Unknown") :
ExceptionObject(file, line, message, loc)
const std::string& desc = "",
const std::string& filename = "") :
ExceptionObject(file, line, desc),
m_Filename(filename)
{
}
/** Constructor. */
ImageFileReaderException(const std::string &file, unsigned int line,
const char* message = "Error in IO",
const char* loc = "Unknown") :
ExceptionObject(file, line, message, loc)
{
}
std::string m_Filename;
};
/** \class ImageFileReader
......@@ -170,12 +165,10 @@ protected:
void DoConvertBuffer(void* buffer, size_t numberOfPixels);
private:
/** Test whether the given filename exist and it is readable,
this is intended to be called before attempting to use
ImageIO classes for actually reading the file. If the file
doesn't exist or it is not readable, and exception with an
appropriate message will be thrown. */
void TestFileExistenceAndReadability();
/** Test whether m_ImageIO is valid (not NULL). This is intended to be called
* after trying to create it via an ImageIOFactory. Throws an exception with
* an appropriate message otherwise. */
void TestValidImageIO();
/** Generate the filename (for GDALImageI for example). If filename is a directory, look if is a
* CEOS product (file "DAT...") In this case, the GdalFileName contain the open image file.
......@@ -196,8 +189,6 @@ private:
bool m_UseStreaming;
std::string m_ExceptionMessage;
// The region that the ImageIO class will return when we ask to
// produce the requested region.
itk::ImageIORegion m_ActualIORegion;
......
......@@ -65,7 +65,6 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
m_UserSpecifiedImageIO(false),
m_FileName(""),
m_UseStreaming(true),
m_ExceptionMessage(""),
m_ActualIORegion(),
m_FilenameHelper(FNameHelperType::New()),
m_AdditionalNumber(0),
......@@ -129,9 +128,9 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
output->SetBufferedRegion(output->GetRequestedRegion());
output->Allocate();
// Test if the file exist and if it can be open.
// An exception will be thrown otherwise.
this->TestFileExistenceAndReadability();
// Raise an exception if the file could not be opened
// i.e. if this->m_ImageIO is Null
this->TestValidImageIO();
// Tell the ImageIO to read the file
OutputImagePixelType *buffer =
......@@ -242,8 +241,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
}
else
{
throw otb::ImageFileReaderException(__FILE__, __LINE__,
"Invalid output object type");
throw otb::ImageFileReaderException(__FILE__, __LINE__, "Invalid output object type");
}
}
}
......@@ -253,74 +251,32 @@ void
ImageFileReader<TOutputImage, ConvertPixelTraits>
::GenerateOutputInformation(void)
{
typename TOutputImage::Pointer output = this->GetOutput();
itkDebugMacro(<< "Reading file for GenerateOutputInformation()" << this->m_FileName);
// Check to see if we can read the file given the name or prefix
//
if (this->m_FileName == "")
{
throw otb::ImageFileReaderException(__FILE__, __LINE__, "FileName must be specified");
}
{
throw otb::ImageFileReaderException(__FILE__, __LINE__, "Filename must be specified.");
}
// Find real image file name
// !!!! Update FileName
std::string lFileName;
bool found = GetGdalReadImageFileName(this->m_FileName, lFileName);
if (found == false)
{
otbMsgDebugMacro(<< "Filename was NOT unknown. May be recognized by a Image factory ! ");
}
// Update FileName
this->m_FileName = lFileName;
// Test if the file exists and if it can be opened.
// An exception will be thrown otherwise.
// We catch the exception because some ImageIO's may not actually
// open a file. Still reports file error if no ImageIO is loaded.
try
{
m_ExceptionMessage = "";
this->TestFileExistenceAndReadability();
}
catch (itk::ExceptionObject & err)
{
m_ExceptionMessage = err.GetDescription();
}
bool found = GetGdalReadImageFileName(this->m_FileName, lFileName);
if (found)
{
// Update FileName
this->m_FileName = lFileName;
}
if (this->m_UserSpecifiedImageIO == false) //try creating via factory
{
{
this->m_ImageIO = ImageIOFactory::CreateImageIO(this->m_FileName.c_str(), otb::ImageIOFactory::ReadMode);
}
if (this->m_ImageIO.IsNull())
{
//this->Print(std::cerr);
otb::ImageFileReaderException e(__FILE__, __LINE__);
std::ostringstream msg;
msg << " Could not create IO object for file "
<< this->m_FileName.c_str() << std::endl;
msg << " Tried to create one of the following:" << std::endl;
std::list<itk::LightObject::Pointer> allobjects =
itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase");
for (std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin();
i != allobjects.end(); ++i)
{
otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer());
// IO should never be null, but we would better check for it
if(io)
msg << " " << io->GetNameOfClass() << std::endl;
}
msg << " You probably failed to set a file suffix, or" << std::endl;
msg << " set the suffix to an unsupported type." << std::endl;
e.SetDescription(msg.str().c_str());
throw e;
return;
}
}
// Raise an exception if the file could not be opened
// i.e. if this->m_ImageIO is Null
this->TestValidImageIO();
// Get the ImageIO MetaData Dictionary
itk::MetaDataDictionary& dict = this->m_ImageIO->GetMetaDataDictionary();
......@@ -331,7 +287,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
bool lVectorImage = false;
if (strcmp(output->GetNameOfClass(), "VectorImage") == 0)
lVectorImage= true;
this->m_ImageIO->SetOutputImagePixelType(PixelIsComplex(dummy),lVectorImage);
// Pass the dataset number (used for hdf files for example)
......@@ -435,9 +391,9 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
if(!m_KeywordListUpToDate && !m_FilenameHelper->GetSkipGeom())
{
std::string lFileNameOssimKeywordlist = GetDerivedDatasetSourceFileName(m_FileName);
// Update otb Keywordlist
ImageKeywordlist otb_kwl;
if (!m_FilenameHelper->ExtGEOMFileNameIsSet())
......@@ -450,7 +406,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName());
otbMsgDevMacro(<< "Loading external kwl");
}
// Don't add an empty ossim keyword list
if(!otb_kwl.Empty())
{
......@@ -511,7 +467,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
}
// If Skip ProjectionRef is activated, remove ProjRef from dict
if (m_FilenameHelper->GetSkipCarto())
{
......@@ -576,9 +532,9 @@ std::string
ImageFileReader<TOutputImage, ConvertPixelTraits>
::GetDerivedDatasetSourceFileName(const std::string & filename) const
{
const size_t dsds_pos = filename.find(DerivedSubdatasetPrefix);
if(dsds_pos != std::string::npos)
{
// Derived subdataset from gdal
......@@ -595,50 +551,22 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
template <class TOutputImage, class ConvertPixelTraits>
void
ImageFileReader<TOutputImage, ConvertPixelTraits>
::TestFileExistenceAndReadability()
::TestValidImageIO()
{
// Test if the file a server name : if so the test is skipped
if (this->m_FileName.find(std::string("http://")) == 0 ||
this->m_FileName.find(std::string("https://")) == 0)
{
return;
}
if (this->m_ImageIO.IsNull())
{
std::string fileToCheck = GetDerivedDatasetSourceFileName(m_FileName);
std::string fileToCheck = GetDerivedDatasetSourceFileName(m_FileName);
// Test if the file exists.
if (!itksys::SystemTools::FileExists(fileToCheck.c_str()))
// Test if the file exists.
if (!itksys::SystemTools::FileExists(fileToCheck.c_str()))
{
otb::ImageFileReaderException e(__FILE__, __LINE__);
std::ostringstream msg;
msg << "The file doesn't exist. "
<< std::endl << "Filename = " << fileToCheck
<< std::endl;
e.SetDescription(msg.str().c_str());
throw e;
return;
throw otb::ImageFileReaderException (__FILE__, __LINE__, "The file does not exist.", fileToCheck);
}
// Test if the file can be open for reading access.
//Only if m_FileName specify a filename (not a dirname)
if (itksys::SystemTools::FileExists(fileToCheck.c_str(), true))
else
{
std::ifstream readTester;
readTester.open(fileToCheck.c_str());
if (readTester.fail())
{
readTester.close();
std::ostringstream msg;
msg << "The file couldn't be opened for reading. "
<< std::endl << "Filename: " << fileToCheck
<< std::endl;
otb::ImageFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION);
throw e;
return;
}
readTester.close();
throw otb::ImageFileReaderException(__FILE__, __LINE__, "Probably unsupported format or incorrect filename extension.", this->m_FileName);
}
}
}
template <class TOutputImage, class ConvertPixelTraits>
......@@ -695,7 +623,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
}
fic_trouve = true;
}
otbMsgDevMacro(<< "lFileNameGdal : " << GdalFileName.c_str());
otbMsgDevMacro(<< "fic_trouve : " << fic_trouve);
return (fic_trouve);
......@@ -716,12 +644,12 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
{
const std::string skip_geom_key = "skipgeom";
const std::string geom_key = "geom";
if (in)
{
// First, see if the simple filename has changed
typename FNameHelperType::Pointer helper = FNameHelperType::New();
helper->SetExtendedFileName(in);
std::string simpleFileName = helper->GetSimpleFileName();
......@@ -735,7 +663,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
if(oldMap.size() != newMap.size() || !std::equal(oldMap.begin(),oldMap.end(),newMap.begin()))
{
this->Modified();
// Now check if keywordlist needs to be generated again
// Condition is: one of the old or new map has the skip_geom
// key and the other does not
......@@ -759,7 +687,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
m_KeywordListUpToDate = false;
this->Modified();
}
m_FilenameHelper = helper;
}
}
......@@ -781,15 +709,15 @@ ImageFileReader<TOutputImage, ConvertPixelTraits>
return this->m_ImageIO->GetOverviewsCount();
}
template <class TOutputImage, class ConvertPixelTraits>
std::vector<std::string>
ImageFileReader<TOutputImage, ConvertPixelTraits>
::GetOverviewsInfo()
{
this->UpdateOutputInformation();
return this->m_ImageIO->GetOverviewsInfo();
}
......
......@@ -448,20 +448,7 @@ ImageFileWriter<TInputImage>
{
itk::ImageFileWriterException e(__FILE__, __LINE__);
std::ostringstream msg;
msg << " Could not create IO object for file "
<< m_FileName.c_str() << std::endl;
msg << " Tried to create one of the following:" << std::endl;
std::list<itk::LightObject::Pointer> allobjects =
itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase");
for (std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin();
i != allobjects.end(); ++i)
{
otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer());
if(io)
msg << " " << io->GetNameOfClass() << std::endl;
}
msg << " You probably failed to set a file suffix, or" << std::endl;
msg << " set the suffix to an unsupported type." << std::endl;
msg << "Cannot write image " << m_FileName.c_str() << ". Probably unsupported format or incorrect filename extension.";
e.SetDescription(msg.str().c_str());
e.SetLocation(ITK_LOCATION);
throw e;
......
......@@ -48,38 +48,35 @@ ImageIOFactory::CreateImageIO(const char* path, FileModeType mode)
itk::ObjectFactoryBase::CreateAllInstance("otbImageIOBase");
for(std::list<itk::LightObject::Pointer>::iterator i = allobjects.begin();
i != allobjects.end(); ++i)
{
{
otb::ImageIOBase* io = dynamic_cast<otb::ImageIOBase*>(i->GetPointer());
if(io)
{
{
possibleImageIO.push_back(io);
}
else
{
std::cerr << "Error ImageIO factory did not return an ImageIOBase: "
<< (*i)->GetNameOfClass()
<< std::endl;
}
}
for(std::list<otb::ImageIOBase::Pointer>::iterator k = possibleImageIO.begin();
k != possibleImageIO.end(); ++k)
else
{
itkGenericExceptionMacro(<< "ImageIO factory did not return an ImageIOBase but a " << (*i)->GetNameOfClass());
}
}
for(std::list<otb::ImageIOBase::Pointer>::iterator k = possibleImageIO.begin(); k != possibleImageIO.end(); ++k)
{
if( mode == ReadMode )
{
{
if((*k)->CanReadFile(path))
{
{
return *k;
}
}
}
else if( mode == WriteMode )
{
{
if((*k)->CanWriteFile(path))
{
{
return *k;
}
}
}
}
return ITK_NULLPTR;
}
......
......@@ -16,7 +16,7 @@ BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "OrfeoToolbox"
VALUE "FileDescription", "Monteverdi 2"
VALUE "FileDescription", "Monteverdi"
VALUE "FileVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0"
VALUE "LegalCopyright", "Copyright (c) 2012-2013 Centre National d'Etudes Spatiales. All rights reserved."
VALUE "InternalName", "mapla"
......
......@@ -16,12 +16,12 @@ BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "OrfeoToolbox"
VALUE "FileDescription", "Monteverdi 2"
VALUE "FileDescription", "Monteverdi"
VALUE "FileVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0"
VALUE "LegalCopyright", "Copyright (c) 2012-2013 Centre National d'Etudes Spatiales. All rights reserved."
VALUE "InternalName", "monteverdi"
VALUE "OriginalFilename", "monteverdi.exe"
VALUE "ProductName", "Monteverdi 2"
VALUE "ProductName", "Monteverdi"
VALUE "ProductVersion", "@Monteverdi_VERSION_MAJOR@.@Monteverdi_VERSION_MINOR@.@Monteverdi_VERSION_PATCH@.0"
END
END
......
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbLogger_h
#define otbLogger_h
#include "itkLoggerBase.h"
#include "itkLogger.h"
namespace otb {
/** \class Logger
* \brief An ITK logger specialized for OTB
*
* Sets OTB wide settings in its constructor
*
* \ingroup OTBApplicationEngine
*/
class Logger : public itk::Logger
{
public:
typedef Logger Self;
typedef itk::Logger Superclass;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer< const Self > ConstPointer;
itkTypeMacro(Logger, Object);
itkNewMacro(Self);
// Overwrite this to provide custom formatting of log entries
std::string BuildFormattedEntry(itk::Logger::PriorityLevelType, std::string const&) ITK_OVERRIDE;
protected:
Logger();
virtual ~Logger();
}; // class Logger
} // namespace otb
#endif // otbLogger_h
......@@ -26,7 +26,7 @@
#include "otbWrapperTags.h"
#include "otbWrapperParameterGroup.h"
#include "itkLogger.h"
#include "otbLogger.h"
#include "itkTimeProbe.h"
#include "otbWrapperMacros.h"
#include "otbWrapperInputImageParameter.h"
......@@ -40,6 +40,37 @@
namespace otb
{
/** \class ApplicationException
* \brief Exception for runtime errors in OTB Applications
*
* Usually thrown with the otbAppLogFATAL macro
*
* \ingroup OTBApplicationEngine
*/
class ApplicationException : public itk::ExceptionObject
{
public:
/** Run-time information. */
itkTypeMacro( ApplicationException, ExceptionObject );
/** Constructor. */
ApplicationException(const char *file, unsigned int line,
const char* message = "Application error.",
const char* loc = "Unknown") :
ExceptionObject(file, line, message, loc)
{
}
/** Constructor. */
ApplicationException(const std::string &file, unsigned int line,
const char* message = "Application error.",
const char* loc = "Unknown") :
ExceptionObject(file, line, message, loc)
{
}
};
namespace Wrapper
{
......@@ -70,6 +101,7 @@ public:
m_Name = name;
GetDocExample()->SetApplicationName(name);
this->Modified();
m_Logger->SetName(name);
}
itkGetStringMacro(Name);
......@@ -663,7 +695,7 @@ public:
*/
ComplexImagePixelType GetParameterComplexOutputImagePixelType(std::string parameter);
itk::Logger* GetLogger();
otb::Logger* GetLogger();
itk::ProcessObject* GetProgressSource() const;
......@@ -916,7 +948,6 @@ protected:
}
}
private:
/* Implement this method to add parameters */
virtual void DoInit() = 0;
......@@ -938,7 +969,7 @@ private:
std::string m_Name;
std::string m_Description;
ParameterGroup::Pointer m_ParameterList;
itk::Logger::Pointer m_Logger;
otb::Logger::Pointer m_Logger;
itk::ProcessObject::Pointer m_ProgressSource;
std::string m_ProgressSourceDescription;
......
......@@ -71,7 +71,9 @@ public:
/** Get one specific stored image filename. */
std::string GetNthFileName( unsigned int i ) const;
/** Get one list of the stored image. */
/** Get one list of the stored image. WARNING : if the parameter list changes,
* the returned image list may become obsolete. You should call
* GetImageList() again to make sure your image list is up-to-date. */
FloatVectorImageListType* GetImageList() const;
/** Get one specific stored image. */
......
......@@ -56,14 +56,7 @@ InputImageParameter::GetImage()
typename ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(m_FileName);
try