Merge pull request #6087 from radarhere/tga

This commit is contained in:
Hugo van Kemenade 2022-02-27 18:25:21 +02:00 committed by GitHub
commit 841d60c35f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 21 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

Binary file not shown.

View File

@ -97,6 +97,11 @@ def test_id_field_rle():
assert im.size == (199, 199) 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): def test_save(tmp_path):
test_file = "Tests/images/tga_id_field.tga" test_file = "Tests/images/tga_id_field.tga"
with Image.open(test_file) as im: with Image.open(test_file) as im:

View File

@ -20,6 +20,8 @@ int
ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) { ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
int n, depth; int n, depth;
UINT8 *ptr; UINT8 *ptr;
UINT8 extra_data = 0;
int extra_bytes = 0;
ptr = buf; ptr = buf;
@ -42,15 +44,13 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
return ptr - buf; return ptr - buf;
} }
n = depth * ((ptr[0] & 0x7f) + 1);
if (ptr[0] & 0x80) { if (ptr[0] & 0x80) {
/* Run (1 + pixelsize bytes) */ /* Run (1 + pixelsize bytes) */
if (bytes < 1 + depth) { if (bytes < 1 + depth) {
break; break;
} }
n = depth * ((ptr[0] & 0x7f) + 1);
if (state->x + n > state->bytes) { if (state->x + n > state->bytes) {
state->errcode = IMAGING_CODEC_OVERRUN; state->errcode = IMAGING_CODEC_OVERRUN;
return -1; return -1;
@ -67,18 +67,17 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
ptr += 1 + depth; ptr += 1 + depth;
bytes -= 1 + depth; bytes -= 1 + depth;
} else { } else {
/* Literal (1+n+1 bytes block) */ /* Literal (1+n+1 bytes block) */
n = depth * (ptr[0] + 1);
if (bytes < 1 + n) { if (bytes < 1 + n) {
break; break;
} }
if (state->x + n > state->bytes) { if (state->x + n > state->bytes) {
state->errcode = IMAGING_CODEC_OVERRUN; extra_bytes = n; /* full value */
return -1; n = state->bytes - state->x;
extra_bytes -= n;
extra_data = ptr[1];
} }
memcpy(state->buffer + state->x, ptr + 1, n); memcpy(state->buffer + state->x, ptr + 1, n);
@ -87,6 +86,7 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
bytes -= 1 + n; bytes -= 1 + n;
} }
for (;;) {
state->x += n; state->x += n;
if (state->x >= state->bytes) { if (state->x >= state->bytes) {
@ -106,6 +106,24 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
return -1; 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;
}
} }
return ptr - buf; return ptr - buf;