[Insight-users] Two bugs in MetaImageIO

Jarek Sacha jpsacha@poczta.onet.pl
Sat, 18 May 2002 00:25:52 -0400


Just noticed two bugs in itkMetaImageIO.cxx (revision 1.18)

1) Once a header is read there is no check if the input steam is fine. In 
result an incorrect image data can be read, for instance you can load data 
from a non-existing file without error.

2) If a header and image data are in separate files and header name does 
not start with a path then the name of the image data file gets corrupted 
(first letter in the name is duplicated)

Possible fixes:
Bug 1: Change method MetaImageIO::Read from

   void MetaImageIO::Read(void* buffer)
   {
     unsigned int dimensions = this->GetNumberOfDimensions();
     unsigned int numberOfPixels = 1;
     for( unsigned int dim=0; dim< dimensions; dim++ )
       {
       numberOfPixels *= m_Dimensions[ dim ];
       }

     unsigned int pixelSize =  this->GetComponentSize();

     char * p = static_cast<char *>(buffer);
     for( unsigned int pixelnumber = 0; pixelnumber< numberOfPixels; 
pixelnumber++)
     {
       for(unsigned int bytes=0; bytes<pixelSize; bytes++)
       {
         *p = m_Ifstream.get();
         p++;
       }
     }

     SwapBytesIfNecessary( buffer, numberOfPixels );

   }

to something like (for clarity ImageIORegion is ignored below):

   void MetaImageIO::Read(void* buffer)
   {
     char * p = static_cast<char *>(buffer);
     m_Ifstream.read(p, GetImageSizeInBytes());
     bool success = !m_Ifstream.bad();
     m_Ifstream.close();
     if( !success )
       {
       itkExceptionMacro("Error reading image data.");
       }

     SwapBytesIfNecessary(buffer, GetImageSizeInPixels());
   }

Bug 2: In method MetaImageIO::ReadImageInformation, in the "if" statement 
checking for "ElementDataFile" replace

       {
       size_t endOfPath = m_FileName.find_last_of( "\\/" );
       if( endOfPath > m_FileName.max_size() )
         {
         endOfPath = 0; // there is no path
         }
       m_Ifstream.close();        // Close the header
       std::string dataFileName;
       dataFileName = m_FileName.substr( 0, endOfPath+1 );
       dataFileName += key;
       m_FileName = dataFileName;    // Compose the data filename
       m_Ifstream.open( m_FileName.c_str(), std::ios::in | std::ios::binary );
       return;
       }

with something like:

       {
       m_Ifstream.close();        // Close the header

       std::string dataFileName;
       size_t endOfPath = m_FileName.find_last_of( "\\/" );
       if( endOfPath == std::string::npos )
         {
         dataFileName = key;     // there is no path
         }
       else
         {
         dataFileName = m_FileName.substr( 0, endOfPath+1 );
         dataFileName += key;
         }

       m_FileName = dataFileName;    // Compose the data filename
       m_Ifstream.open( m_FileName.c_str(), std::ios::in | std::ios::binary );
       if( !m_Ifstream )
         {
         itkExceptionMacro("Error opening image data file.");
         }

       return;
       }

Home this helps,

Jarek