mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-28 02:46:18 +03:00
Fixed literal expansion, allowed run length > line length
This commit is contained in:
parent
17d38d0905
commit
5df2851f85
|
@ -7,7 +7,7 @@
|
||||||
* decoder for SUN RLE data.
|
* decoder for SUN RLE data.
|
||||||
*
|
*
|
||||||
* history:
|
* history:
|
||||||
* 97-01-04 fl Created
|
* 97-01-04 fl Created
|
||||||
*
|
*
|
||||||
* Copyright (c) Fredrik Lundh 1997.
|
* Copyright (c) Fredrik Lundh 1997.
|
||||||
* Copyright (c) Secret Labs AB 1997.
|
* Copyright (c) Secret Labs AB 1997.
|
||||||
|
@ -24,88 +24,106 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
UINT8* ptr;
|
UINT8* ptr;
|
||||||
|
UINT8 extra_data = 0;
|
||||||
|
UINT8 extra_bytes = 0;
|
||||||
|
int ct_bytes = 0;
|
||||||
|
|
||||||
ptr = buf;
|
ptr = buf;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (bytes < 1)
|
if (bytes < 1)
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
|
||||||
if (ptr[0] == 0x80) {
|
if (ptr[0] == 0x80) {
|
||||||
|
|
||||||
if (bytes < 2)
|
if (bytes < 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
n = ptr[1];
|
n = ptr[1];
|
||||||
|
|
||||||
if (n == 0) {
|
|
||||||
|
|
||||||
/* Literal 0x80 (2 bytes) */
|
if (n == 0) {
|
||||||
n = 1;
|
|
||||||
|
|
||||||
state->buffer[state->x] = 0x80;
|
/* Literal 0x80 (2 bytes) */
|
||||||
|
n = 1;
|
||||||
|
ct_bytes += n;
|
||||||
|
|
||||||
ptr += 2;
|
state->buffer[state->x] = 0x80;
|
||||||
bytes -= 2;
|
|
||||||
|
|
||||||
} else {
|
ptr += 2;
|
||||||
|
bytes -= 2;
|
||||||
|
|
||||||
/* Run (3 bytes) */
|
} else {
|
||||||
if (bytes < 3)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (state->x + n > state->bytes) {
|
/* Run (3 bytes) */
|
||||||
/* FIXME: is this correct? */
|
if (bytes < 3)
|
||||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
break;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(state->buffer + state->x, ptr[2], n);
|
ct_bytes += n;
|
||||||
|
|
||||||
ptr += 3;
|
if (state->x + n > state->bytes) {
|
||||||
bytes -= 3;
|
extra_bytes = n; /* full value */
|
||||||
|
n = state->bytes - state->x;
|
||||||
|
extra_bytes -= n;
|
||||||
|
extra_data = ptr[2];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
memset(state->buffer + state->x, ptr[2], n);
|
||||||
|
|
||||||
} else {
|
ptr += 3;
|
||||||
|
bytes -= 3;
|
||||||
|
|
||||||
/* Literal (1+n bytes block) */
|
}
|
||||||
n = ptr[0];
|
|
||||||
|
|
||||||
if (bytes < 1 + n)
|
} else {
|
||||||
break;
|
|
||||||
|
|
||||||
if (state->x + n > state->bytes) {
|
/* Literal byte */
|
||||||
/* FIXME: is this correct? */
|
n = 1;
|
||||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
ct_bytes += n;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(state->buffer + state->x, ptr + 1, n);
|
state->buffer[state->x] = ptr[0];
|
||||||
|
|
||||||
ptr += 1 + n;
|
ptr += 1;
|
||||||
bytes -= 1 + n;
|
bytes -= 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->x += n;
|
for (;;) {
|
||||||
|
state->x += n;
|
||||||
|
|
||||||
|
if (state->x >= state->bytes) {
|
||||||
|
|
||||||
if (state->x >= state->bytes) {
|
/* Got a full line, unpack it */
|
||||||
|
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
||||||
|
state->xoff * im->pixelsize, state->buffer,
|
||||||
|
state->xsize);
|
||||||
|
|
||||||
/* Got a full line, unpack it */
|
state->x = 0;
|
||||||
state->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
|
||||||
state->xoff * im->pixelsize, state->buffer,
|
|
||||||
state->xsize);
|
|
||||||
|
|
||||||
state->x = 0;
|
if (++state->y >= state->ysize) {
|
||||||
|
/* End of file (errcode = 0) */
|
||||||
|
printf("%d", ct_bytes);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extra_bytes == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (++state->y >= state->ysize) {
|
if (state->x > 0) {
|
||||||
/* End of file (errcode = 0) */
|
break; // assert
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (extra_bytes >= state->bytes) {
|
||||||
|
n = state->bytes;
|
||||||
|
} else {
|
||||||
|
n = extra_bytes;
|
||||||
|
}
|
||||||
|
memset(state->buffer + state->x, extra_data, n);
|
||||||
|
extra_bytes -= n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr - buf;
|
return ptr - buf;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user