mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 18:36:17 +03:00
Fix SunImagePlugin.
SunImagePlugin now loads all the images here: https://samples.libav.org/image-samples/sunrast/ without LOAD_TRUNCATED_IMAGES set, verified visually. Prior to this commit: Could not open 32bpp.ras Could not open 4bpp.ras Could not open gray.ras Could not open lena-1bit-rle.sun Could not open lena-24bit-rle.sun Could not open lena-8bit-raw.sun Could not open lena-8bit-rle.sun Could not open MARBLES.SUN
This commit is contained in:
parent
372b1abe69
commit
816c74ac81
|
@ -38,6 +38,21 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
def _open(self):
|
def _open(self):
|
||||||
|
|
||||||
|
# The Sun Raster file header is 32 bytes in length and has the following format:
|
||||||
|
|
||||||
|
# typedef struct _SunRaster
|
||||||
|
# {
|
||||||
|
# DWORD MagicNumber; /* Magic (identification) number */
|
||||||
|
# DWORD Width; /* Width of image in pixels */
|
||||||
|
# DWORD Height; /* Height of image in pixels */
|
||||||
|
# DWORD Depth; /* Number of bits per pixel */
|
||||||
|
# DWORD Length; /* Size of image data in bytes */
|
||||||
|
# DWORD Type; /* Type of raster file */
|
||||||
|
# DWORD ColorMapType; /* Type of color map */
|
||||||
|
# DWORD ColorMapLength; /* Size of the color map in bytes */
|
||||||
|
# } SUNRASTER;
|
||||||
|
|
||||||
|
|
||||||
# HEAD
|
# HEAD
|
||||||
s = self.fp.read(32)
|
s = self.fp.read(32)
|
||||||
if i32(s) != 0x59a66a95:
|
if i32(s) != 0x59a66a95:
|
||||||
|
@ -48,10 +63,15 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
self.size = i32(s[4:8]), i32(s[8:12])
|
self.size = i32(s[4:8]), i32(s[8:12])
|
||||||
|
|
||||||
depth = i32(s[12:16])
|
depth = i32(s[12:16])
|
||||||
|
data_length = i32(s[16:20]) # unreliable, ignore.
|
||||||
file_type = i32(s[20:24])
|
file_type = i32(s[20:24])
|
||||||
|
palette_type = i32(s[24:28]) # 0: None, 1: RGB, 2: Raw/arbitrary
|
||||||
|
palette_length = i32(s[28:32])
|
||||||
|
|
||||||
if depth == 1:
|
if depth == 1:
|
||||||
self.mode, rawmode = "1", "1;I"
|
self.mode, rawmode = "1", "1;I"
|
||||||
|
elif depth == 4:
|
||||||
|
self.mode, rawmode = "L", "L;4"
|
||||||
elif depth == 8:
|
elif depth == 8:
|
||||||
self.mode = rawmode = "L"
|
self.mode = rawmode = "L"
|
||||||
elif depth == 24:
|
elif depth == 24:
|
||||||
|
@ -59,17 +79,31 @@ class SunImageFile(ImageFile.ImageFile):
|
||||||
self.mode, rawmode = "RGB", "RGB"
|
self.mode, rawmode = "RGB", "RGB"
|
||||||
else:
|
else:
|
||||||
self.mode, rawmode = "RGB", "BGR"
|
self.mode, rawmode = "RGB", "BGR"
|
||||||
|
elif depth == 32:
|
||||||
|
if file_type == 3:
|
||||||
|
self.mode, rawmode = 'RGB', 'RGBX'
|
||||||
else:
|
else:
|
||||||
raise SyntaxError("unsupported mode")
|
self.mode, rawmode = 'RGB', 'BGRX'
|
||||||
|
else:
|
||||||
|
raise SyntaxError("Unsupported Mode/Bit Depth")
|
||||||
|
|
||||||
if i32(s[24:28]) != 0:
|
|
||||||
length = i32(s[28:32])
|
|
||||||
offset = offset + length
|
if palette_length:
|
||||||
self.palette = ImagePalette.raw("RGB;L", self.fp.read(length))
|
if palette_length > 1024:
|
||||||
|
raise SyntaxError("Unsupported Color Palette Length")
|
||||||
|
|
||||||
|
if palette_type != 1:
|
||||||
|
raise SyntaxError("Unsupported Palette Type")
|
||||||
|
|
||||||
|
offset = offset + palette_length
|
||||||
|
self.palette = ImagePalette.raw("RGB;L", self.fp.read(palette_length))
|
||||||
if self.mode == "L":
|
if self.mode == "L":
|
||||||
self.mode = rawmode = "P"
|
self.mode = "P"
|
||||||
|
rawmode = rawmode.replace('L', 'P')
|
||||||
|
|
||||||
stride = (((self.size[0] * depth + 7) // 8) + 3) & (~3)
|
# 16 bit boundaries on stride
|
||||||
|
stride = ((self.size[0] * depth + 15) // 16) * 2
|
||||||
|
|
||||||
# file type: Type is the version (or flavor) of the bitmap
|
# file type: Type is the version (or flavor) of the bitmap
|
||||||
# file. The following values are typically found in the Type
|
# file. The following values are typically found in the Type
|
||||||
|
|
Loading…
Reference in New Issue
Block a user