Fixes DIB image format

The DIB image format uses the 40 byte BMP header, followed by 3 masks
for RGB channels. We were reading 4 masks, consuming the first pixel
of the image.

Mostly fixes issue #1293. Remaining issue: alpha channel is actually a
transparency mask.
This commit is contained in:
wiredfool 2016-04-06 06:22:12 -07:00
parent fd7fa4e61d
commit e84e02997c
4 changed files with 12 additions and 1 deletions

View File

@ -109,7 +109,11 @@ class BmpImageFile(ImageFile.ImageFile):
for idx, mask in enumerate(['r_mask', 'g_mask', 'b_mask', 'a_mask']): for idx, mask in enumerate(['r_mask', 'g_mask', 'b_mask', 'a_mask']):
file_info[mask] = i32(header_data[36+idx*4:40+idx*4]) file_info[mask] = i32(header_data[36+idx*4:40+idx*4])
else: else:
for mask in ['r_mask', 'g_mask', 'b_mask', 'a_mask']: # 40 byte headers only have the three components in the bitfields masks,
# ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx
# See also https://github.com/python-pillow/Pillow/issues/1293
file_info['a_mask'] = 0xff000000
for mask in ['r_mask', 'g_mask', 'b_mask']:
file_info[mask] = i32(read(4)) file_info[mask] = i32(read(4))
file_info['rgb_mask'] = (file_info['r_mask'], file_info['g_mask'], file_info['b_mask']) file_info['rgb_mask'] = (file_info['r_mask'], file_info['g_mask'], file_info['b_mask'])
file_info['rgba_mask'] = (file_info['r_mask'], file_info['g_mask'], file_info['b_mask'], file_info['a_mask']) file_info['rgba_mask'] = (file_info['r_mask'], file_info['g_mask'], file_info['b_mask'], file_info['a_mask'])

BIN
Tests/images/clipboard.dib Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -70,6 +70,13 @@ class TestFileBmp(PillowTestCase):
self.assertEqual(im.size, reloaded.size) self.assertEqual(im.size, reloaded.size)
self.assertEqual(reloaded.format, "JPEG") self.assertEqual(reloaded.format, "JPEG")
def test_load_dib(self):
# test for #1293, Imagegrab returning Unsupported Bitfields Format
im = BmpImagePlugin.DibImageFile('Tests/images/clipboard.dib')
target = Image.open('Tests/images/clipboard_target.png')
self.assert_image_equal(im.convert('RGB'), target.convert('RGB'))
self.assert_image_similar(im, target, 1)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()