22 #include <itksys/SystemTools.hxx>
70 std::string fname = filename;
73 itkDebugMacro(<<
"No filename specified.");
76 bool extensionFound =
false;
77 std::string::size_type BMPPos = fname.rfind(
".bmp");
78 if ((BMPPos != std::string::npos)
79 && (BMPPos == fname.length() - 4))
81 extensionFound =
true;
84 BMPPos = fname.rfind(
".BMP");
85 if ((BMPPos != std::string::npos)
86 && (BMPPos == fname.length() - 4))
88 extensionFound =
true;
93 itkDebugMacro(<<
"The filename extension is not recognized");
98 std::ifstream inputStream;
99 inputStream.open( filename, std::ios::in | std::ios::binary );
100 if( inputStream.fail() )
105 char magic_number1, magic_number2;
106 inputStream.read((
char*)&magic_number1,
sizeof(
char));
107 inputStream.read((
char*)&magic_number2,
sizeof(
char));
109 if ((magic_number1 !=
'B')||(magic_number2 !=
'M'))
111 std::cerr <<
"BMPImageIO : Magic Number Fails = " << magic_number1 <<
" : " << magic_number2 << std::endl;
122 ::size_t sizeLong =
sizeof(long);
125 inputStream.read((
char*)&tmp,4);
127 inputStream.read((
char*)&tmp,4);
129 inputStream.read((
char*)&tmp,4);
133 inputStream.read((
char*)&itmp,4);
135 inputStream.read((
char*)&itmp,4);
137 inputStream.read((
char*)&itmp,4);
143 inputStream.read((
char*)&infoSize,
sizeof(
long));
146 if ((infoSize != 40)&&(infoSize != 12))
154 inputStream.read((
char*)&iinfoSize,4);
156 infoSize = iinfoSize;
159 if ((infoSize != 40)&&(infoSize != 12))
173 std::string filename = name;
174 if ( filename ==
"" )
176 itkDebugMacro(<<
"No filename specified.");
179 bool extensionFound =
false;
180 std::string::size_type BMPPos = filename.rfind(
".bmp");
181 if ((BMPPos != std::string::npos)
182 && (BMPPos == filename.length() - 4))
184 extensionFound =
true;
187 BMPPos = filename.rfind(
".BMP");
188 if ((BMPPos != std::string::npos)
189 && (BMPPos == filename.length() - 4))
191 extensionFound =
true;
194 if( !extensionFound )
196 itkDebugMacro(<<
"The filename extension is not recognized");
209 char * p =
static_cast<char *
>(buffer);
216 long paddedStreamRead = streamRead;
219 paddedStreamRead = ( ( streamRead / 4 ) + 1 ) * 4;
222 char* value =
new char[paddedStreamRead+1];
233 unsigned int posLine=0;
237 unsigned long n = value[i];
239 unsigned char valpix = value[i];
240 for(
unsigned long j=0;j<n;j++)
273 m_Ifstream.read((
char *)value, paddedStreamRead);
274 for(
long i=0;i<streamRead;i++)
301 unsigned char val = value[i];
330 for(
long i=0;i<streamRead;i+=step)
366 itkExceptionMacro(
"BMPImageIO could not open file: "
370 << itksys::SystemTools::GetLastSystemError());
373 char magic_number1, magic_number2;
374 m_Ifstream.read((
char*)&magic_number1,
sizeof(
char));
375 m_Ifstream.read((
char*)&magic_number2,
sizeof(
char));
377 if ((magic_number1 !=
'B')||(magic_number2 !=
'M'))
380 itkExceptionMacro(
"BMPImageIO : Magic Number Fails = " << magic_number1 <<
" : " << magic_number2 );
385 ::size_t sizeLong =
sizeof(long);
413 if ((infoSize != 40)&&(infoSize != 12))
415 itkExceptionMacro(<<
"Unknown file type! " <<
m_FileName.c_str()
416 <<
" is not a Windows BMP file!");
442 m_Ifstream.read((
char*)&iinfoSize,
sizeof(
int));
445 infoSize = iinfoSize;
448 if ((infoSize != 40)&&(infoSize != 12))
450 itkExceptionMacro(<<
"Unknown file type! " <<
m_FileName.c_str()
451 <<
" is not a Windows BMP file!");
501 itkExceptionMacro(
"Only BMP depths of (8,24,32) are supported. Not " <<
m_Depth );
619 switch(m_ComponentType)
623 if ( m_ByteOrder == LittleEndian )
626 (
char*)buffer, numberOfPixels );
628 else if ( m_ByteOrder == BigEndian )
631 (
char *)buffer, numberOfPixels );
637 if ( m_ByteOrder == LittleEndian )
640 (
unsigned char*)buffer, numberOfPixels );
642 else if ( m_ByteOrder == BigEndian )
645 (
unsigned char *)buffer, numberOfPixels );
651 if ( m_ByteOrder == LittleEndian )
654 (
short*)buffer, numberOfPixels );
656 else if ( m_ByteOrder == BigEndian )
659 (
short *)buffer, numberOfPixels );
665 if ( m_ByteOrder == LittleEndian )
668 (
unsigned short*)buffer, numberOfPixels );
670 else if ( m_ByteOrder == BigEndian )
673 (
unsigned short *)buffer, numberOfPixels );
678 itkExceptionMacro(<<
"Pixel Type Unknown");
689 m_Ofstream.write(&tmp,
sizeof(
char));
690 tmp =
static_cast<char>((value%65536L)/256);
691 m_Ofstream.write(&tmp,
sizeof(
char));
692 tmp =
static_cast<char>((value/65536L)%256);
693 m_Ofstream.write(&tmp,
sizeof(
char));
694 tmp =
static_cast<char>((value/65536L)/256);
695 m_Ofstream.write(&tmp,
sizeof(
char));
704 m_Ofstream.write(&tmp,
sizeof(
char));
705 tmp =
static_cast<char>((value%65536L)/256);
706 m_Ofstream.write(&tmp,
sizeof(
char));
722 unsigned int nDims = this->GetNumberOfDimensions();
726 itkExceptionMacro(<<
"BMPImageIO cannot write images with a dimension != 2");
729 if(this->GetComponentType() != UCHAR)
731 itkExceptionMacro(<<
"BMPImageIO supports unsigned char only");
733 if( (this->m_NumberOfComponents != 1) &&
734 (this->m_NumberOfComponents != 3) &&
735 (this->m_NumberOfComponents != 4) )
737 itkExceptionMacro(<<
"BMPImageIO supports 1,3 or 4 components only");
743 std::ofstream tFile(m_FileName.c_str(),std::ios::out);
747 m_Ofstream.open(m_FileName.c_str(), std::ios::binary | std::ios::out);
748 if( m_Ofstream.fail() )
750 itkExceptionMacro(<<
"File: " << this->GetFileName() <<
" cannot be written."
753 << itksys::SystemTools::GetLastSystemError());
789 m_Ofstream.write(&tmp,
sizeof(
char));
791 m_Ofstream.write(&tmp,
sizeof(
char));
793 const unsigned int bpp = this->GetNumberOfComponents();
794 long bytesPerRow = m_Dimensions[0]*bpp;
795 if ( bytesPerRow % 4 )
797 bytesPerRow = ( ( bytesPerRow / 4 ) + 1 ) * 4;
799 const unsigned long paddedBytes = bytesPerRow - (m_Dimensions[0]*bpp);
801 const unsigned int rawImageDataSize =
static_cast<unsigned int>(( bytesPerRow * m_Dimensions[1]));
802 unsigned int fileSize = ( rawImageDataSize ) + 54;
807 this->Write32BitsInteger( fileSize );
809 const unsigned short applicationReservedValue = 0;
810 this->Write16BitsInteger( applicationReservedValue );
811 this->Write16BitsInteger( applicationReservedValue );
813 unsigned int offsetToBinaryDataStart = 54;
816 offsetToBinaryDataStart += 1024;
818 this->Write32BitsInteger( offsetToBinaryDataStart );
840 const unsigned int bitmapHeaderSize = 40;
841 this->Write32BitsInteger( bitmapHeaderSize );
844 this->Write32BitsInteger( m_Dimensions[0] );
847 this->Write32BitsInteger( m_Dimensions[1] );
850 const unsigned short numberOfColorPlanes = 1;
851 this->Write16BitsInteger( numberOfColorPlanes );
854 unsigned short numberOfBitsPerPixel = 0;
858 numberOfBitsPerPixel = 32;
861 numberOfBitsPerPixel = 24;
864 numberOfBitsPerPixel = 8;
867 itkExceptionMacro(<<
"Number of components not supported.");
869 this->Write16BitsInteger( numberOfBitsPerPixel );
871 const unsigned int compressionMethod = 0;
872 this->Write32BitsInteger( compressionMethod );
873 this->Write32BitsInteger( rawImageDataSize );
880 const unsigned int horizontalResolution = Math::Round<unsigned int>( 1000.0 / m_Spacing[0] );
881 const unsigned int verticalResolution = Math::Round<unsigned int>( 1000.0 / m_Spacing[1] );
883 this->Write32BitsInteger( horizontalResolution );
884 this->Write32BitsInteger( verticalResolution );
887 const unsigned int numberOfColorsInPalette = 0;
888 this->Write32BitsInteger( numberOfColorsInPalette );
891 const unsigned int numberOfImportantColorsInPalette = 0;
892 this->Write32BitsInteger( numberOfImportantColorsInPalette );
905 for (
unsigned int n=0; n < 256; n++)
907 char tmp2 =
static_cast< unsigned char >( n );
908 m_Ofstream.write(&tmp2,
sizeof(
char));
909 m_Ofstream.write(&tmp2,
sizeof(
char));
910 m_Ofstream.write(&tmp2,
sizeof(
char));
911 m_Ofstream.write(&tmp,
sizeof(
char));
920 for (
unsigned int h = 0; h < m_Dimensions[1]; h++)
922 const char paddingValue = 0;
923 const char * ptr =
static_cast<const char*
>(buffer);
924 ptr += (m_Dimensions[1]-(h+1))*m_Dimensions[0]*bpp;
927 for (i = 0; i < m_Dimensions[0]; i++)
929 m_Ofstream.write(ptr,
sizeof(
char));
932 for (i = 0; i < paddedBytes; i++)
934 m_Ofstream.write(&paddingValue,
sizeof(
char));
939 for (i = 0; i < m_Dimensions[0]; i++)
942 m_Ofstream.write(ptr,
sizeof(
char));
944 m_Ofstream.write(ptr,
sizeof(
char));
946 m_Ofstream.write(ptr,
sizeof(
char));
949 for (i = 0; i < paddedBytes; i++)
951 m_Ofstream.write(&paddingValue,
sizeof(
char));
956 for (i = 0; i < m_Dimensions[0]; i++)
959 m_Ofstream.write(ptr,
sizeof(
char));
961 m_Ofstream.write(ptr,
sizeof(
char));
963 m_Ofstream.write(ptr,
sizeof(
char));
965 m_Ofstream.write(ptr,
sizeof(
char));
968 for (i = 0; i < paddedBytes; i++)
970 m_Ofstream.write(&paddingValue,
sizeof(
char));
980 os << indent <<
"Depth " <<
m_Depth <<
"\n";
985 os << indent <<
"m_Allow8BitBMP : True" <<
"\n";
989 os << indent <<
"m_Allow8BitBMP : False" <<
"\n";