@ -5320,6 +5320,32 @@ typedef struct
int extra_read ;
} stbi__bmp_data ;
static int stbi__bmp_set_mask_defaults ( stbi__bmp_data * info , int compress )
{
// BI_BITFIELDS specifies masks explicitly, don't override
if ( compress = = 3 )
return 1 ;
if ( compress = = 0 ) {
if ( info - > bpp = = 16 ) {
info - > mr = 31u < < 10 ;
info - > mg = 31u < < 5 ;
info - > mb = 31u < < 0 ;
} else if ( info - > bpp = = 32 ) {
info - > mr = 0xffu < < 16 ;
info - > mg = 0xffu < < 8 ;
info - > mb = 0xffu < < 0 ;
info - > ma = 0xffu < < 24 ;
info - > all_a = 0 ; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
} else {
// otherwise, use defaults, which is all-0
info - > mr = info - > mg = info - > mb = info - > ma = 0 ;
}
return 1 ;
}
return 0 ; // error
}
static void * stbi__bmp_parse_header ( stbi__context * s , stbi__bmp_data * info )
{
int hsz ;
@ -5347,6 +5373,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
if ( hsz ! = 12 ) {
int compress = stbi__get32le ( s ) ;
if ( compress = = 1 | | compress = = 2 ) return stbi__errpuc ( " BMP RLE " , " BMP type not supported: RLE " ) ;
if ( compress > = 4 ) return stbi__errpuc ( " BMP JPEG/PNG " , " BMP type not supported: unsupported compression " ) ; // this includes PNG/JPEG modes
if ( compress = = 3 & & info - > bpp ! = 16 & & info - > bpp ! = 32 ) return stbi__errpuc ( " bad BMP " , " bad BMP " ) ; // bitfields requires 16 or 32 bits/pixel
stbi__get32le ( s ) ; // discard sizeof
stbi__get32le ( s ) ; // discard hres
stbi__get32le ( s ) ; // discard vres
@ -5361,17 +5389,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
}
if ( info - > bpp = = 16 | | info - > bpp = = 32 ) {
if ( compress = = 0 ) {
if ( info - > bpp = = 32 ) {
info - > mr = 0xffu < < 16 ;
info - > mg = 0xffu < < 8 ;
info - > mb = 0xffu < < 0 ;
info - > ma = 0xffu < < 24 ;
info - > all_a = 0 ; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
} else {
info - > mr = 31u < < 10 ;
info - > mg = 31u < < 5 ;
info - > mb = 31u < < 0 ;
}
stbi__bmp_set_mask_defaults ( info , compress ) ;
} else if ( compress = = 3 ) {
info - > mr = stbi__get32le ( s ) ;
info - > mg = stbi__get32le ( s ) ;
@ -5386,6 +5404,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
return stbi__errpuc ( " bad BMP " , " bad BMP " ) ;
}
} else {
// V4/V5 header
int i ;
if ( hsz ! = 108 & & hsz ! = 124 )
return stbi__errpuc ( " bad BMP " , " bad BMP " ) ;
@ -5393,6 +5412,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info - > mg = stbi__get32le ( s ) ;
info - > mb = stbi__get32le ( s ) ;
info - > ma = stbi__get32le ( s ) ;
if ( compress ! = 3 ) // override mr/mg/mb unless in BI_BITFIELDS mode, as per docs
stbi__bmp_set_mask_defaults ( info , compress ) ;
stbi__get32le ( s ) ; // discard color space
for ( i = 0 ; i < 12 ; + + i )
stbi__get32le ( s ) ; // discard color space parameters