@@ -53,7 +53,7 @@ def _accept(prefix: bytes) -> bool:
5353
5454
5555def _dib_accept (prefix ):
56- return i32 (prefix ) in [12 , 40 , 64 , 108 , 124 ]
56+ return i32 (prefix ) in [12 , 40 , 52 , 56 , 64 , 108 , 124 ]
5757
5858
5959# =============================================================================
@@ -83,8 +83,9 @@ def _bitmap(self, header=0, offset=0):
8383 # read the rest of the bmp header, without its size
8484 header_data = ImageFile ._safe_read (self .fp , file_info ["header_size" ] - 4 )
8585
86- # -------------------------------------------------- IBM OS/2 Bitmap v1
86+ # ------------------------------- Windows Bitmap v2, IBM OS/2 Bitmap v1
8787 # ----- This format has different offsets because of width/height types
88+ # 12: BITMAPCOREHEADER/OS21XBITMAPHEADER
8889 if file_info ["header_size" ] == 12 :
8990 file_info ["width" ] = i16 (header_data , 0 )
9091 file_info ["height" ] = i16 (header_data , 2 )
@@ -93,9 +94,14 @@ def _bitmap(self, header=0, offset=0):
9394 file_info ["compression" ] = self .RAW
9495 file_info ["palette_padding" ] = 3
9596
96- # --------------------------------------------- Windows Bitmap v2 to v5
97- # v3, OS/2 v2, v4, v5
98- elif file_info ["header_size" ] in (40 , 64 , 108 , 124 ):
97+ # --------------------------------------------- Windows Bitmap v3 to v5
98+ # 40: BITMAPINFOHEADER
99+ # 52: BITMAPV2HEADER
100+ # 56: BITMAPV3HEADER
101+ # 64: BITMAPCOREHEADER2/OS22XBITMAPHEADER
102+ # 108: BITMAPV4HEADER
103+ # 124: BITMAPV5HEADER
104+ elif file_info ["header_size" ] in (40 , 52 , 56 , 64 , 108 , 124 ):
99105 file_info ["y_flip" ] = header_data [7 ] == 0xFF
100106 file_info ["direction" ] = 1 if file_info ["y_flip" ] else - 1
101107 file_info ["width" ] = i32 (header_data , 0 )
@@ -117,10 +123,13 @@ def _bitmap(self, header=0, offset=0):
117123 file_info ["palette_padding" ] = 4
118124 self .info ["dpi" ] = tuple (x / 39.3701 for x in file_info ["pixels_per_meter" ])
119125 if file_info ["compression" ] == self .BITFIELDS :
120- if len (header_data ) >= 52 :
121- for idx , mask in enumerate (
122- ["r_mask" , "g_mask" , "b_mask" , "a_mask" ]
123- ):
126+ masks = ["r_mask" , "g_mask" , "b_mask" ]
127+ if len (header_data ) >= 48 :
128+ if len (header_data ) >= 52 :
129+ masks .append ("a_mask" )
130+ else :
131+ file_info ["a_mask" ] = 0x0
132+ for idx , mask in enumerate (masks ):
124133 file_info [mask ] = i32 (header_data , 36 + idx * 4 )
125134 else :
126135 # 40 byte headers only have the three components in the
@@ -132,7 +141,7 @@ def _bitmap(self, header=0, offset=0):
132141 # location, but it is listed as a reserved component,
133142 # and it is not generally an alpha channel
134143 file_info ["a_mask" ] = 0x0
135- for mask in [ "r_mask" , "g_mask" , "b_mask" ] :
144+ for mask in masks :
136145 file_info [mask ] = i32 (read (4 ))
137146 file_info ["rgb_mask" ] = (
138147 file_info ["r_mask" ],
@@ -175,9 +184,11 @@ def _bitmap(self, header=0, offset=0):
175184 32 : [
176185 (0xFF0000 , 0xFF00 , 0xFF , 0x0 ),
177186 (0xFF000000 , 0xFF0000 , 0xFF00 , 0x0 ),
187+ (0xFF000000 , 0xFF00 , 0xFF , 0x0 ),
178188 (0xFF000000 , 0xFF0000 , 0xFF00 , 0xFF ),
179189 (0xFF , 0xFF00 , 0xFF0000 , 0xFF000000 ),
180190 (0xFF0000 , 0xFF00 , 0xFF , 0xFF000000 ),
191+ (0xFF000000 , 0xFF00 , 0xFF , 0xFF0000 ),
181192 (0x0 , 0x0 , 0x0 , 0x0 ),
182193 ],
183194 24 : [(0xFF0000 , 0xFF00 , 0xFF )],
@@ -186,9 +197,11 @@ def _bitmap(self, header=0, offset=0):
186197 MASK_MODES = {
187198 (32 , (0xFF0000 , 0xFF00 , 0xFF , 0x0 )): "BGRX" ,
188199 (32 , (0xFF000000 , 0xFF0000 , 0xFF00 , 0x0 )): "XBGR" ,
200+ (32 , (0xFF000000 , 0xFF00 , 0xFF , 0x0 )): "BGXR" ,
189201 (32 , (0xFF000000 , 0xFF0000 , 0xFF00 , 0xFF )): "ABGR" ,
190202 (32 , (0xFF , 0xFF00 , 0xFF0000 , 0xFF000000 )): "RGBA" ,
191203 (32 , (0xFF0000 , 0xFF00 , 0xFF , 0xFF000000 )): "BGRA" ,
204+ (32 , (0xFF000000 , 0xFF00 , 0xFF , 0xFF0000 )): "BGAR" ,
192205 (32 , (0x0 , 0x0 , 0x0 , 0x0 )): "BGRA" ,
193206 (24 , (0xFF0000 , 0xFF00 , 0xFF )): "BGR" ,
194207 (16 , (0xF800 , 0x7E0 , 0x1F )): "BGR;16" ,
0 commit comments