mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +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.
|
||||
*
|
||||
* history:
|
||||
* 97-01-04 fl Created
|
||||
* 97-01-04 fl Created
|
||||
*
|
||||
* Copyright (c) Fredrik Lundh 1997.
|
||||
* Copyright (c) Secret Labs AB 1997.
|
||||
|
@ -24,88 +24,106 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes)
|
|||
{
|
||||
int n;
|
||||
UINT8* ptr;
|
||||
UINT8 extra_data = 0;
|
||||
UINT8 extra_bytes = 0;
|
||||
int ct_bytes = 0;
|
||||
|
||||
ptr = buf;
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (bytes < 1)
|
||||
return ptr - buf;
|
||||
if (bytes < 1)
|
||||
return ptr - buf;
|
||||
|
||||
if (ptr[0] == 0x80) {
|
||||
if (ptr[0] == 0x80) {
|
||||
|
||||
if (bytes < 2)
|
||||
break;
|
||||
if (bytes < 2)
|
||||
break;
|
||||
|
||||
n = ptr[1];
|
||||
n = ptr[1];
|
||||
|
||||
if (n == 0) {
|
||||
|
||||
/* Literal 0x80 (2 bytes) */
|
||||
n = 1;
|
||||
if (n == 0) {
|
||||
|
||||
state->buffer[state->x] = 0x80;
|
||||
/* Literal 0x80 (2 bytes) */
|
||||
n = 1;
|
||||
ct_bytes += n;
|
||||
|
||||
ptr += 2;
|
||||
bytes -= 2;
|
||||
state->buffer[state->x] = 0x80;
|
||||
|
||||
} else {
|
||||
ptr += 2;
|
||||
bytes -= 2;
|
||||
|
||||
/* Run (3 bytes) */
|
||||
if (bytes < 3)
|
||||
break;
|
||||
} else {
|
||||
|
||||
if (state->x + n > state->bytes) {
|
||||
/* FIXME: is this correct? */
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
}
|
||||
/* Run (3 bytes) */
|
||||
if (bytes < 3)
|
||||
break;
|
||||
|
||||
memset(state->buffer + state->x, ptr[2], n);
|
||||
ct_bytes += n;
|
||||
|
||||
ptr += 3;
|
||||
bytes -= 3;
|
||||
if (state->x + n > state->bytes) {
|
||||
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)
|
||||
break;
|
||||
} else {
|
||||
|
||||
if (state->x + n > state->bytes) {
|
||||
/* FIXME: is this correct? */
|
||||
state->errcode = IMAGING_CODEC_OVERRUN;
|
||||
return -1;
|
||||
}
|
||||
/* Literal byte */
|
||||
n = 1;
|
||||
ct_bytes += n;
|
||||
|
||||
memcpy(state->buffer + state->x, ptr + 1, n);
|
||||
state->buffer[state->x] = ptr[0];
|
||||
|
||||
ptr += 1 + n;
|
||||
bytes -= 1 + n;
|
||||
ptr += 1;
|
||||
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->shuffle((UINT8*) im->image[state->y + state->yoff] +
|
||||
state->xoff * im->pixelsize, state->buffer,
|
||||
state->xsize);
|
||||
state->x = 0;
|
||||
|
||||
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) {
|
||||
/* End of file (errcode = 0) */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (state->x > 0) {
|
||||
break; // assert
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user