use UINT32 instead of ULONG

This commit is contained in:
Mickael Bonfill 2017-07-26 17:01:45 -04:00 committed by Eric Soroos
parent f833cd7f38
commit 9caf8c5889
2 changed files with 70 additions and 61 deletions

View File

@ -23,10 +23,11 @@
from . import Image, ImageFile from . import Image, ImageFile
from ._binary import i8, o8, i16be as i16 from ._binary import i8, o8, i16be as i16, o16be as o16
import struct import struct
import os import os
__version__ = "0.3" __version__ = "0.3"
@ -123,14 +124,22 @@ def _save(im, fp, filename):
if im.mode != "RGB" and im.mode != "RGBA" and im.mode != "L": if im.mode != "RGB" and im.mode != "RGBA" and im.mode != "L":
raise ValueError("Unsupported SGI image mode") raise ValueError("Unsupported SGI image mode")
# Get the keyword arguments
info = im.encoderinfo
# Byte-per-pixel precision, 1 = 8bits per pixel
bpc = info.get("bpc", 1)
if bpc != 1 and bpc != 2:
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) im = im.transpose(Image.FLIP_TOP_BOTTOM)
# 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
rle = 0 rle = 0
# Byte-per-pixel precision, 1 = 8bits per pixel
bpc = 1
# Number of dimensions (x,y,z) # Number of dimensions (x,y,z)
dim = 3 dim = 3
# X Dimension = width / Y Dimension = height # X Dimension = width / Y Dimension = height
@ -176,19 +185,27 @@ def _save(im, fp, filename):
fp.write(struct.pack('404s', b'')) # dummy fp.write(struct.pack('404s', b'')) # dummy
for channel in im.split(): for channel in im.split():
fp.write(channel.tobytes()) rawchannel = channel.tobytes()
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 = False _pulls_fd = True
def decode(self, buffer): def decode(self, buffer):
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) data = bytearray(pagesize * zsize)
self.fd.seek(512)
s = self.fd.read(2 * pagesize * zsize)
print(len(s))
i = 0 i = 0
y = 0 y = 0
if orientation < 0: if orientation < 0:
@ -198,7 +215,7 @@ class SGI16Decoder(ImageFile.PyDecoder):
for z in range(zsize): for z in range(zsize):
bi = (x + y * self.state.xsize + bi = (x + y * self.state.xsize +
y * stride + z * pagesize) * 2 y * stride + z * pagesize) * 2
pixel = i16(buffer, o=bi) pixel = i16(s, o=bi)
pixel = int(pixel // 256) pixel = int(pixel // 256)
data[i] = o8(pixel) data[i] = o8(pixel)
i += 1 i += 1

View File

@ -17,11 +17,9 @@
#define SGI_HEAD_LEN 512 #define SGI_HEAD_LEN 512
typedef unsigned long ULONG; static UINT32 getlong(UINT8 *buf)
static ULONG getlong(UINT8 *buf)
{ {
return (ULONG)(buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0); return (UINT32)(buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]<<0);
} }
static void expandrow(UINT8* optr,UINT8* iptr, int ooffset, int ioffset) static void expandrow(UINT8* optr,UINT8* iptr, int ooffset, int ioffset)
@ -50,9 +48,9 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
UINT8* buf, int bytes) UINT8* buf, int bytes)
{ {
UINT8 *ptr, *scanline; UINT8 *ptr, *scanline;
ULONG *starttab, *lengthtab; UINT32 *starttab, *lengthtab;
ULONG rleoffset, rlelength; UINT32 rleoffset, rlelength;
int zsize, tablen, rowno, channo, bpc; int zsize, tablen, rowno, channo;
/* "working copy" of buffer pointer */ /* "working copy" of buffer pointer */
ptr = buf; ptr = buf;
@ -60,9 +58,6 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
/* get the channels count */ /* get the channels count */
zsize = im->bands; zsize = im->bands;
/* get bytes channel per pixel */
bpc = state->count;
/* initialization */ /* initialization */
if (state->state == 0) { if (state->state == 0) {
@ -75,22 +70,19 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
state->y = 0; state->y = 0;
} }
free(state->buffer); state->state = 1;
/* allocate memory for the buffer used for full lines later */ }
state->buffer = (UINT8*)malloc(sizeof(UINT8) * state->xsize * zsize);
/* allocate memory for compressed and uncompressed rows */ /* allocate memory for compressed and uncompressed rows */
scanline = (UINT8*)malloc(sizeof(UINT8) * state->xsize); scanline = (UINT8*)malloc(sizeof(UINT8) * state->xsize);
/* allocate memory for rle tabs */ /* allocate memory for rle tabs */
tablen = state->ysize * zsize * sizeof(ULONG); tablen = state->ysize * zsize * sizeof(UINT32);
starttab = (ULONG*)malloc(tablen); starttab = (UINT32*)malloc(tablen);
lengthtab = (ULONG*)malloc(tablen); lengthtab = (UINT32*)malloc(tablen);
state->state = 1;
}
/* get RLE offset and length tabs */ /* get RLE offset and length tabs */
int i; int i;