Page MenuHomePhabricator

List of extensions retrieved incorrectly
Closed, DuplicatePublic

Description

Problem occurs when saving an image with extension that is not by default supported by MITK. The dialog initiated by data manager context menu is calling
void mitk::QmitkIOUtil::SaveImageWithDialog(...) which acquires the list of supported file extensions correctly by calling mitk::CoreObjectFactory::GetInstance()->GetSaveFileExtensions() while a few lines later mitk::IOUtil::SaveImage is called which checks against the hard coded default extensions: in IOUtil::SaveImage the !imageWriter->IsExtensionValid(extension) call fails (mitkIOUtil.cpp line 187) with any non-standard extension.

Suggested solution:
The mitk::FileWriter::IsExtensionValid(std::string extension) method should be re-factored to get the full list of extensions from mitk::CoreObjectFactory.

bool mitk::FileWriter::IsExtensionValid(std::string extension)
{

std::string extListStr(mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
size_t pos = extListStr.find(extension);

if (pos != std::string::npos)
  return true;
else return false;

}

Event Timeline

Thank you for reporting this, unfortunately I won't be able to look after this bug before June 15th.

@Thomas: Would you have time to look at the mitk::IOUtil::SaveImage issue?

I will take care of this next Wednesday.

@gzombori: It seems like you already experimented with a solution. If you have code already, I would be glad to try your solution.

Hi Thomas,
the code is just here:

\MITK\Core\Code\IO\mitkFileWriter.cpp
Line 53-61:

bool mitk::FileWriter::IsExtensionValid(std::string extension)
{

std::string extListStr(mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
size_t pos = extListStr.find(extension);

if (pos != std::string::npos)
  return true;
else return false;

}

I've tested this on Win and Mac and it worked all right.

Hi gzombori,

what I don't understand (from just looking at your comment) is where I should call the mentioned method? That's why I asked for code or a patch. You could even give me a link to a get repository to ease the integration. I will have a look at this tomorrow in our weekly bugsquashing.

Regards,
Thomas

Hi Thomas,
The code is on a private branch of our MITK fork. I am happy to share it, but it depends on some code which does not exists within MITK itself. First let me try to explain what I did:

  1. I wrote a custom IO class to support PNM read / write operations:

class PNMImageIO : public itk::ImageIOBase {}

  1. I wrote a factory for the IO object:

class PNMImageIOFactory : public itk::ObjectFactoryBase {}

  1. I register this factory with our own CoreObjectFactory, which is derived from mitk::CoreObjectFactoryBase, by calling:

itk::PNMImageIOFactory::RegisterOneFactory();

  1. I also register the associated file extensions in the CoreObjectFactory:

mitk::NifTKCoreObjectFactory::MultimapType m_FileExtensionsMap;
mitk::NifTKCoreObjectFactory::MultimapType m_SaveFileExtensionsMap;

m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pgm", "Portable Gray Map"));
m_FileExtensionsMap.insert(std::pair<std::string, std::string>("*.pnm", "Portable aNy Map"));

m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.pgm", "Portable Gray Map"));
m_SaveFileExtensionsMap.insert(std::pair<std::string, std::string>("*.pnm", "Portable aNy Map"));

The CoreObjectFactory will return these maps when the following virtual methods are being called:

/// \see CoreObjectFactoryBase::GetFileExtensions
virtual const char* GetFileExtensions();

/// \see CoreObjectFactoryBase::GetFileExtensionsMap
virtual mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap();

/// \see CoreObjectFactoryBase::GetSaveFileExtensions
virtual const char* GetSaveFileExtensions();

/// \see CoreObjectFactoryBase::GetSaveFileExtensionsMap
virtual mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap();

This step will associate the pgm and pnm file extensions with the IO object.

Consequently, if you right click on an image node within the data storage and select the save option, the pgm and pnm extensions shall appear there.

As I mentioned in the first comment, the dialog initiated by data storage's context menu is calling:
MITK\Modules\QmitkExt\QmitkApplicationBase\QmitkIOUtil.cpp
Line 136:
void mitk::QmitkIOUtil::SaveImageWithDialog(...)

which acquires the list of supported file extensions correctly by calling:
Line 151:
mitk::CoreObjectFactory::GetInstance()->GetSaveFileExtensions().

Then in line 158 mitk::IOUtil::SaveImage(...) is called. (\MITK\Core\Code\IO\mitkIOUtil.cpp, Line 170)

This method will attempt to check if the extension is valid, but it only checks against the standard MITK extensions.
Line 187:
if (!imageWriter->IsExtensionValid(extension))....

If you change to code according to comment 4 the full list of extensions will be retrieved, including the custom ones as all extensions are merged from the custom factories.

To test this I suggest to plug in a custom IO class and register it's factory within the mitk::CoreObjectFactory, then try to trigger a save through to data manager's dialog.

If you have any questions let me know.

Cheers,
Gergely

Hi gzombori,

thanks for your detailed explanation. This made really clear to me what is going wrong. I will write a core change request and make sure that this will be integrated into the master.

New remote branch pushed: bug-14633-extensionlist-incorrect

Passing this bug to Keno. He will integrate this during his platform project.

This bug has a high severity and was not fixed within the 2013-06 release. Setting target milestone to next release.

This Will be fixed with the integration of T14866. I am closing this instance.