question: protected void readHeader ( ) throws IOException , IllegalArgumentException { if ( gotHeader ) return ; if ( iis == null ) { throw new IllegalStateException ( "Input source not set!" ) ; } int profileData = 0 , profileSize = 0 ; this . metadata = new BMPMetadata ( ) ; iis . mark ( ) ; byte [ ] marker = new byte [ 2 ] ; iis . read ( marker ) ; if ( marker [ 0 ] != 0x42 || marker [ 1 ] != 0x4d ) throw new IllegalArgumentException ( I18N . getString ( "BMPImageReader1" ) ) ; bitmapFileSize = iis . readUnsignedInt ( ) ; iis . skipBytes ( 4 ) ; bitmapOffset = iis . readUnsignedInt ( ) ; long size = iis . readUnsignedInt ( ) ; if ( size == 12 ) { width = iis . readShort ( ) ; height = iis . readShort ( ) ; } else { width = iis . readInt ( ) ; height = iis . readInt ( ) ; } metadata . width = width ; metadata . height = height ; int planes = iis . readUnsignedShort ( ) ; bitsPerPixel = iis . readUnsignedShort ( ) ; metadata . bitsPerPixel = ( short ) bitsPerPixel ; numBands = 3 ; if ( size == 12 ) { metadata . bmpVersion = VERSION_2 ; if ( bitsPerPixel == 1 ) { imageType = VERSION_2_1_BIT ; } else if ( bitsPerPixel == 4 ) { imageType = VERSION_2_4_BIT ; } else if ( bitsPerPixel == 8 ) { imageType = VERSION_2_8_BIT ; } else if ( bitsPerPixel == 24 ) { imageType = VERSION_2_24_BIT ; } int numberOfEntries = ( int ) ( ( bitmapOffset - 14 - size ) / 3 ) ; int sizeOfPalette = numberOfEntries * 3 ; palette = new byte [ sizeOfPalette ] ; iis . readFully ( palette , 0 , sizeOfPalette ) ; metadata . palette = palette ; metadata . paletteSize = numberOfEntries ; } else { compression = iis . readUnsignedInt ( ) ; imageSize = iis . readUnsignedInt ( ) ; long xPelsPerMeter = iis . readInt ( ) ; long yPelsPerMeter = iis . readInt ( ) ; long colorsUsed = iis . readUnsignedInt ( ) ; long colorsImportant = iis . readUnsignedInt ( ) ; metadata . compression = ( int ) compression ; metadata . xPixelsPerMeter = ( int ) xPelsPerMeter ; metadata . yPixelsPerMeter = ( int ) yPelsPerMeter ; metadata . colorsUsed = ( int ) colorsUsed ; metadata . colorsImportant = ( int ) colorsImportant ; if ( size == 40 ) { switch ( ( int ) compression ) { case BI_JPEG : case BI_PNG : metadata . bmpVersion = VERSION_3 ; imageType = VERSION_3_XP_EMBEDDED ; break ; case BI_RGB : case BI_RLE8 : case BI_RLE4 : if ( bitmapOffset < ( size + 14 ) ) { throw new IIOException ( I18N . getString ( "BMPImageReader7" ) ) ; } int numberOfEntries = ( int ) ( ( bitmapOffset - 14 - size ) / 4 ) ; int sizeOfPalette = numberOfEntries * 4 ; palette = new byte [ sizeOfPalette ] ; iis . readFully ( palette , 0 , sizeOfPalette ) ; metadata . palette = palette ; metadata . paletteSize = numberOfEntries ; if ( bitsPerPixel == 1 ) { imageType = VERSION_3_1_BIT ; } else if ( bitsPerPixel == 4 ) { imageType = VERSION_3_4_BIT ; } else if ( bitsPerPixel == 8 ) { imageType = VERSION_3_8_BIT ; } else if ( bitsPerPixel == 24 ) { imageType = VERSION_3_24_BIT ; } else if ( bitsPerPixel == 16 ) { imageType = VERSION_3_NT_16_BIT ; redMask = 0x7C00 ; greenMask = 0x3E0 ; blueMask = ( 1 << 5 ) - 1 ; metadata . redMask = redMask ; metadata . greenMask = greenMask ; metadata . blueMask = blueMask ; } else if ( bitsPerPixel == 32 ) { imageType = VERSION_3_NT_32_BIT ; redMask = 0x00FF0000 ; greenMask = 0x0000FF00 ; blueMask = 0x000000FF ; metadata . redMask = redMask ; metadata . greenMask = greenMask ; metadata . blueMask = blueMask ; } metadata . bmpVersion = VERSION_3 ; break ; case BI_BITFIELDS : if ( bitsPerPixel == 16 ) { imageType = VERSION_3_NT_16_BIT ; } else if ( bitsPerPixel == 32 ) { imageType = VERSION_3_NT_32_BIT ; } redMask = ( int ) iis . readUnsignedInt ( ) ; greenMask = ( int ) iis . readUnsignedInt ( ) ; blueMask = ( int ) iis . readUnsignedInt ( ) ; metadata . redMask = redMask ; metadata . greenMask = greenMask ; metadata . blueMask = blueMask ; if ( colorsUsed != 0 ) { sizeOfPalette = ( int ) colorsUsed * 4 ; palette = new byte [ sizeOfPalette ] ; iis . readFully ( palette , 0 , sizeOfPalette ) ; metadata . palette = palette ; metadata . paletteSize = ( int ) colorsUsed ; } metadata . bmpVersion = VERSION_3_NT ; break ; default : throw new IIOException ( I18N . getString ( "BMPImageReader2" ) ) ; } } else if ( size == 108 || size == 124 ) { if ( size == 108 ) metadata . bmpVersion = VERSION_4 ; else if ( size == 124 ) metadata . bmpVersion = VERSION_5 ; redMask = ( int ) iis . readUnsignedInt ( ) ; greenMask = ( int ) iis . readUnsignedInt ( ) ; blueMask = ( int ) iis . readUnsignedInt ( ) ; alphaMask = ( int ) iis . readUnsignedInt ( ) ; long csType = iis . readUnsignedInt ( ) ; int redX = iis . readInt ( ) ; int redY = iis . readInt ( ) ; int redZ = iis . readInt ( ) ; int greenX = iis . readInt ( ) ; int greenY = iis . readInt ( ) ; int greenZ = iis . readInt ( ) ; int blueX = iis . readInt ( ) ; int blueY = iis . readInt ( ) ; int blueZ = iis . readInt ( ) ; long gammaRed = iis . readUnsignedInt ( ) ; long gammaGreen = iis . readUnsignedInt ( ) ; long gammaBlue = iis . readUnsignedInt ( ) ; if ( size == 124 ) { metadata . intent = iis . readInt ( ) ; profileData = iis . readInt ( ) ; profileSize = iis . readInt ( ) ; iis . skipBytes ( 4 ) ; } metadata . colorSpace = ( int ) csType ; if ( csType == LCS_CALIBRATED_RGB ) { metadata . redX = redX ; metadata . redY = redY ; metadata . redZ = redZ ; metadata . greenX = greenX ; metadata . greenY = greenY ; metadata . greenZ = greenZ ; metadata . blueX = blueX ; metadata . blueY = blueY ; metadata . blueZ = blueZ ; metadata . gammaRed = ( int ) gammaRed ; metadata . gammaGreen = ( int ) gammaGreen ; metadata . gammaBlue = ( int ) gammaBlue ; } int numberOfEntries = ( int ) ( ( bitmapOffset - 14 - size ) / 4 ) ; int sizeOfPalette = numberOfEntries * 4 ; palette = new byte [ sizeOfPalette ] ; iis . readFully ( palette , 0 , sizeOfPalette ) ; metadata . palette = palette ; metadata . paletteSize = numberOfEntries ; switch ( ( int ) compression ) { case BI_JPEG : case BI_PNG : if ( size == 108 ) { imageType = VERSION_4_XP_EMBEDDED ; } else if ( size == 124 ) { imageType = VERSION_5_XP_EMBEDDED ; } break ; default : if ( bitsPerPixel == 1 ) { imageType = VERSION_4_1_BIT ; } else if ( bitsPerPixel == 4 ) { imageType = VERSION_4_4_BIT ; } else if ( bitsPerPixel == 8 ) { imageType = VERSION_4_8_BIT ; } else if ( bitsPerPixel == 16 ) { imageType = VERSION_4_16_BIT ; if ( ( int ) compression == BI_RGB ) { redMask = 0x7C00 ; greenMask = 0x3E0 ; blueMask = 0x1F ; } } else if ( bitsPerPixel == 24 ) { imageType = VERSION_4_24_BIT ; } else if ( bitsPerPixel == 32 ) { imageType = VERSION_4_32_BIT ; if ( ( int ) compression == BI_RGB ) { redMask = 0x00FF0000 ; greenMask = 0x0000FF00 ; blueMask = 0x000000FF ; } } metadata . redMask = redMask ; metadata . greenMask = greenMask ; metadata . blueMask = blueMask ; metadata . alphaMask = alphaMask ; } } else { throw new IIOException ( I18N . getString ( "BMPImageReader3" ) ) ; } } if ( height > 0 ) { isBottomUp = true ; } else { isBottomUp = false ; height = Math . abs ( height ) ; } ColorSpace colorSpace = ColorSpace . getInstance ( ColorSpace . CS_sRGB ) ; if ( metadata . colorSpace == PROFILE_LINKED || metadata . colorSpace == PROFILE_EMBEDDED ) { iis . mark ( ) ; iis . skipBytes ( profileData - size ) ; byte [ ] profile = new byte [ profileSize ] ; iis . readFully ( profile , 0 , profileSize ) ; iis . reset ( ) ; try { if ( metadata . colorSpace == PROFILE_LINKED && isLinkedProfileAllowed ( ) && ! isUncOrDevicePath ( profile ) ) { String path = new String ( profile , "windows-1252" ) ; colorSpace = new ICC_ColorSpace ( ICC_Profile . getInstance ( path ) ) ; } else { colorSpace = new ICC_ColorSpace ( ICC_Profile . getInstance ( profile ) ) ; } } catch ( Exception e ) { colorSpace = ColorSpace . getInstance ( ColorSpace . CS_sRGB ) ; } } if ( bitsPerPixel == 0 || compression == BI_JPEG || compression == BI_PNG ) { colorModel = null ; sampleModel = null ; } else if ( bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8 ) { numBands = 1 ; if ( bitsPerPixel == 8 ) { int [ ] bandOffsets = new int [ numBands ] ; for ( int i = 0 ; i < numBands ; i ++ ) { bandOffsets [ i ] = numBands - 1 - i ; } sampleModel = new PixelInterleavedSampleModel ( DataBuffer . TYPE_BYTE , width , height , numBands , numBands * width , bandOffsets ) ; } else { sampleModel = new MultiPixelPackedSampleModel ( DataBuffer . TYPE_BYTE , width , height , bitsPerPixel ) ; } byte r [ ] , g [ ] , b [ ] ; if ( imageType == VERSION_2_1_BIT || imageType == VERSION_2_4_BIT || imageType == VERSION_2_8_BIT ) { size = palette . length / 3 ; if ( size > 256 ) { size = 256 ; } int off ; r = new byte [ ( int ) size ] ; g = new byte [ ( int ) size ] ; b = new byte [ ( int ) size ] ; for ( int i = 0 ; i < ( int ) size ; i ++ ) { off = 3 * i ; b [ i ] = palette [ off ] ; g [ i ] = palette [ off + 1 ] ; r [ i ] = palette [ off + 2 ] ; } } else { size = palette . length / 4 ; if ( size > 256 ) { size = 256 ; } int off ; r = new byte [ ( int ) size ] ; g = new byte [ ( int ) size ] ; b = new byte [ ( int ) size ] ; for ( int i = 0 ; i < size ; i ++ ) { off = 4 * i ; b [ i ] = palette [ off ] ; g [ i ] = palette [ off + 1 ] ; r [ i ] = palette [ off + 2 ] ; } } if ( ImageUtil . isIndicesForGrayscale ( r , g , b ) ) colorModel = ImageUtil . createColorModel ( null , sampleModel ) ; else colorModel = new IndexColorModel ( bitsPerPixel , ( int ) size , r , g , b ) ; } else if ( bitsPerPixel == 16 ) { numBands = 3 ; sampleModel = new SinglePixelPackedSampleModel ( DataBuffer . TYPE_USHORT , width , height , new int [ ] { redMask , greenMask , blueMask } ) ; colorModel = new DirectColorModel ( colorSpace , 16 , redMask , greenMask , blueMask , 0 , false , DataBuffer . TYPE_USHORT ) ; } else if ( bitsPerPixel == 32 ) { numBands = alphaMask == 0 ? 3 : 4 ; int [ ] bitMasks = numBands == 3 ? new int [ ] { redMask , greenMask , blueMask } : new int [ ] { redMask , greenMask , blueMask , alphaMask } ; sampleModel = new SinglePixelPackedSampleModel ( DataBuffer . TYPE_INT , width , height , bitMasks ) ; colorModel = new DirectColorModel ( colorSpace , 32 , redMask , greenMask , blueMask , alphaMask , false , DataBuffer . TYPE_INT ) ; } else { numBands = 3 ; int [ ] bandOffsets = new int [ numBands ] ; for ( int i = 0 ; i < numBands ; i ++ ) { bandOffsets [ i ] = numBands - 1 - i ; } sampleModel = new PixelInterleavedSampleModel ( DataBuffer . TYPE_BYTE , width , height , numBands , numBands * width , bandOffsets ) ; colorModel = ImageUtil . createColorModel ( colorSpace , sampleModel ) ; } originalSampleModel = sampleModel ; originalColorModel = colorModel ; iis . reset ( ) ; iis . skipBytes ( bitmapOffset ) ; gotHeader = true ; }
target:  Process the image header.