use raw pack/unpack instead of python math

This commit is contained in:
Eric Soroos 2017-09-29 13:41:27 +00:00
parent 7c629d7814
commit a4d48b6cf5

View File

@ -131,11 +131,11 @@ def _save(im, fp, filename):
# Byte-per-pixel precision, 1 = 8bits per pixel # Byte-per-pixel precision, 1 = 8bits per pixel
bpc = info.get("bpc", 1) bpc = info.get("bpc", 1)
if bpc != 1 and bpc != 2: if bpc not in (1, 2):
raise ValueError("Unsupported number of bytes per pixel") raise ValueError("Unsupported number of bytes per pixel")
# Flip the image, since the origin of SGI file is the bottom-left corner # Flip the image, since the origin of SGI file is the bottom-left corner
im = im.transpose(Image.FLIP_TOP_BOTTOM) orientation = -1
# Define the file as SGI File Format # Define the file as SGI File Format
magicNumber = 474 magicNumber = 474
# Run-Length Encoding Compression - Unsupported at this time # Run-Length Encoding Compression - Unsupported at this time
@ -185,17 +185,15 @@ def _save(im, fp, filename):
fp.write(struct.pack('>l', colormap)) fp.write(struct.pack('>l', colormap))
fp.write(struct.pack('404s', b'')) # dummy fp.write(struct.pack('404s', b'')) # dummy
rawmode = 'L'
if bpc == 2:
rawmode = 'L;16B'
for channel in im.split(): for channel in im.split():
rawchannel = channel.tobytes() fp.write(channel.tobytes('raw', rawmode, 0, orientation))
if bpc == 1:
fp.write(rawchannel)
else:
for pixel in rawchannel:
fp.write(o16(i8(pixel) * 256))
fp.close() fp.close()
class SGI16Decoder(ImageFile.PyDecoder): class SGI16Decoder(ImageFile.PyDecoder):
_pulls_fd = True _pulls_fd = True
@ -203,27 +201,14 @@ class SGI16Decoder(ImageFile.PyDecoder):
rawmode, stride, orientation = self.args rawmode, stride, orientation = self.args
pagesize = self.state.xsize * self.state.ysize pagesize = self.state.xsize * self.state.ysize
zsize = len(self.mode) zsize = len(self.mode)
data = bytearray(pagesize * zsize)
self.fd.seek(512) self.fd.seek(512)
s = self.fd.read(2 * pagesize * zsize)
i = 0 for band in range(zsize):
y = 0 channel = Image.new('L', (self.state.xsize, self.state.ysize))
if orientation < 0: channel.frombytes(self.fd.read(2 * pagesize), 'raw',
y = self.state.ysize - 1 'L;16B', stride, orientation)
while y >= 0 and y < self.state.ysize: self.im.putband(channel.im, band)
for x in range(self.state.xsize):
for z in range(zsize):
bi = (x + y * self.state.xsize +
y * stride + z * pagesize) * 2
pixel = i16(s, o=bi)
pixel = int(pixel // 256)
if sys.version_info.major == 3:
data[i] = pixel
else:
data[i] = o8(pixel)
i += 1
y += orientation
self.set_as_raw(bytes(data))
return -1, 0 return -1, 0
# #