Skip to content

Commit 841d60c

Browse files
authored
Merge pull request #6087 from radarhere/tga
2 parents 6b9b392 + 0d72994 commit 841d60c

File tree

4 files changed

+44
-21
lines changed

4 files changed

+44
-21
lines changed

Tests/images/cross_scan_line.png

71 Bytes
Loading

Tests/images/cross_scan_line.tga

49 Bytes
Binary file not shown.

Tests/test_file_tga.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ def test_id_field_rle():
9797
assert im.size == (199, 199)
9898

9999

100+
def test_cross_scan_line():
101+
with Image.open("Tests/images/cross_scan_line.tga") as im:
102+
assert_image_equal_tofile(im, "Tests/images/cross_scan_line.png")
103+
104+
100105
def test_save(tmp_path):
101106
test_file = "Tests/images/tga_id_field.tga"
102107
with Image.open(test_file) as im:

src/libImaging/TgaRleDecode.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ int
2020
ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t bytes) {
2121
int n, depth;
2222
UINT8 *ptr;
23+
UINT8 extra_data = 0;
24+
int extra_bytes = 0;
2325

2426
ptr = buf;
2527

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

47+
n = depth * ((ptr[0] & 0x7f) + 1);
4548
if (ptr[0] & 0x80) {
4649
/* Run (1 + pixelsize bytes) */
47-
4850
if (bytes < 1 + depth) {
4951
break;
5052
}
5153

52-
n = depth * ((ptr[0] & 0x7f) + 1);
53-
5454
if (state->x + n > state->bytes) {
5555
state->errcode = IMAGING_CODEC_OVERRUN;
5656
return -1;
@@ -67,18 +67,17 @@ ImagingTgaRleDecode(Imaging im, ImagingCodecState state, UINT8 *buf, Py_ssize_t
6767

6868
ptr += 1 + depth;
6969
bytes -= 1 + depth;
70-
7170
} else {
7271
/* Literal (1+n+1 bytes block) */
73-
n = depth * (ptr[0] + 1);
74-
7572
if (bytes < 1 + n) {
7673
break;
7774
}
7875

7976
if (state->x + n > state->bytes) {
80-
state->errcode = IMAGING_CODEC_OVERRUN;
81-
return -1;
77+
extra_bytes = n; /* full value */
78+
n = state->bytes - state->x;
79+
extra_bytes -= n;
80+
extra_data = ptr[1];
8281
}
8382

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

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

92-
if (state->x >= state->bytes) {
93-
/* Got a full line, unpack it */
94-
state->shuffle(
95-
(UINT8 *)im->image[state->y + state->yoff] +
96-
state->xoff * im->pixelsize,
97-
state->buffer,
98-
state->xsize);
92+
if (state->x >= state->bytes) {
93+
/* Got a full line, unpack it */
94+
state->shuffle(
95+
(UINT8 *)im->image[state->y + state->yoff] +
96+
state->xoff * im->pixelsize,
97+
state->buffer,
98+
state->xsize);
9999

100-
state->x = 0;
100+
state->x = 0;
101101

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

104-
if (state->y < 0 || state->y >= state->ysize) {
105-
/* End of file (errcode = 0) */
106-
return -1;
104+
if (state->y < 0 || state->y >= state->ysize) {
105+
/* End of file (errcode = 0) */
106+
return -1;
107+
}
108+
}
109+
110+
if (extra_bytes == 0) {
111+
break;
112+
}
113+
114+
if (state->x > 0) {
115+
break; // assert
116+
}
117+
118+
if (extra_bytes >= state->bytes) {
119+
n = state->bytes;
120+
} else {
121+
n = extra_bytes;
107122
}
123+
memcpy(state->buffer + state->x, ptr, n);
124+
ptr += n;
125+
extra_bytes -= n;
108126
}
109127
}
110128

0 commit comments

Comments
 (0)