Skip to content

Commit

Permalink
Merge pull request #6087 from radarhere/tga
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed Feb 27, 2022
2 parents 6b9b392 + 0d72994 commit 841d60c
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 21 deletions.
Binary file added Tests/images/cross_scan_line.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Tests/images/cross_scan_line.tga
Binary file not shown.
5 changes: 5 additions & 0 deletions Tests/test_file_tga.py
Expand Up @@ -97,6 +97,11 @@ def test_id_field_rle():
assert im.size == (199, 199)


def test_cross_scan_line():
with Image.open("Tests/images/cross_scan_line.tga") as im:
assert_image_equal_tofile(im, "Tests/images/cross_scan_line.png")


def test_save(tmp_path):
test_file = "Tests/images/tga_id_field.tga"
with Image.open(test_file) as im:
Expand Down
60 changes: 39 additions & 21 deletions src/libImaging/TgaRleDecode.c
Expand Up @@ -20,6 +20,8 @@ int
ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
int n, depth;
UINT8 *ptr;
UINT8 extra_data = 0;
int extra_bytes = 0;

ptr = buf;

Expand All @@ -42,15 +44,13 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
return ptr - buf;
}

n = depth * ((ptr[0] & 0x7f) + 1);
if (ptr[0] & 0x80) {
/* Run (1 + pixelsize bytes) */

if (bytes < 1 + depth) {
break;
}

n = depth * ((ptr[0] & 0x7f) + 1);

if (state->x + n > state->bytes) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
Expand All @@ -67,18 +67,17 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t

ptr += 1 + depth;
bytes -= 1 + depth;

} else {
/* Literal (1+n+1 bytes block) */
n = depth * (ptr[0] + 1);

if (bytes < 1 + n) {
break;
}

if (state->x + n > state->bytes) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
extra_bytes = n; /* full value */
n = state->bytes - state->x;
extra_bytes -= n;
extra_data = ptr[1];
}

memcpy(state->buffer + state->x, ptr + 1, n);
Expand All @@ -87,24 +86,43 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
bytes -= 1 + n;
}

state->x += n;
for (;;) {
state->x += n;

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);
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);

state->x = 0;
state->x = 0;

state->y += state->ystep;
state->y += state->ystep;

if (state->y < 0 || state->y >= state->ysize) {
/* End of file (errcode = 0) */
return -1;
if (state->y < 0 || state->y >= state->ysize) {
/* End of file (errcode = 0) */
return -1;
}
}

if (extra_bytes == 0) {
break;
}

if (state->x > 0) {
break; // assert
}

if (extra_bytes >= state->bytes) {
n = state->bytes;
} else {
n = extra_bytes;
}
memcpy(state->buffer + state->x, ptr, n);
ptr += n;
extra_bytes -= n;
}
}

Expand Down

0 comments on commit 841d60c

Please sign in to comment.