avcodec/jpeglsdec: fix decoding of jpegls files with restart markers

This commit is contained in:
Ramiro Polla
2025-12-10 23:53:28 +01:00
parent 80edf78e58
commit 0accfde281
4 changed files with 27 additions and 17 deletions

View File

@@ -397,8 +397,6 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s)
goto end;
}
ff_jpegls_init_state(state);
if (s->bits <= 8)
shift = point_transform + (8 - s->bits);
else
@@ -419,6 +417,9 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s)
av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
ilv, point_transform, s->bits, s->cur_scan);
}
s->restart_count = -1;
if (ilv == 0) { /* separate planes */
if (s->cur_scan > s->nb_components) {
ret = AVERROR_INVALIDDATA;
@@ -429,6 +430,15 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s)
width = s->width * stride;
cur += off;
for (i = 0; i < s->height; i++) {
int restart;
ret = ff_mjpeg_handle_restart(s, &restart);
if (ret < 0)
goto end;
if (restart) {
ff_jpegls_init_state(state);
t = 0;
last = zero;
}
if (s->bits <= 8) {
ret = ls_decode_line(state, s, last, cur, t, width, stride, off, 8);
t = last[0];
@@ -440,11 +450,6 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s)
break;
last = cur;
cur += s->picture_ptr->linesize[0];
if (s->restart_interval && !--s->restart_count) {
align_get_bits(&s->gb);
skip_bits(&s->gb, 16); /* skip RSTn */
}
}
decoded_height = i;
} else if (ilv == 1) { /* line interleaving */
@@ -454,17 +459,21 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s)
memset(cur, 0, s->picture_ptr->linesize[0]);
width = s->width * stride;
for (i = 0; i < s->height; i++) {
int restart;
ret = ff_mjpeg_handle_restart(s, &restart);
if (ret < 0)
goto end;
if (restart) {
ff_jpegls_init_state(state);
memset(Rc, 0, sizeof(Rc));
last = zero;
}
for (j = 0; j < stride; j++) {
ret = ls_decode_line(state, s, last + j, cur + j,
Rc[j], width, stride, j, 8);
if (ret < 0)
break;
Rc[j] = last[j];
if (s->restart_interval && !--s->restart_count) {
align_get_bits(&s->gb);
skip_bits(&s->gb, 16); /* skip RSTn */
}
}
if (ret < 0)
break;

View File

@@ -1793,9 +1793,6 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s)
if (s->lossless) {
av_assert0(s->picture_ptr == s->picture);
if (CONFIG_JPEGLS_DECODER && s->ls) {
ret = ff_mjpeg_unescape_sos(s);
if (ret < 0)
return ret;
if ((ret = ff_jpegls_decode_picture(s)) < 0)
return ret;
} else {
@@ -2342,7 +2339,11 @@ found:
if (!(x & 0x80)) {
/* Stuffed zero bit */
put_bits(&pb, 15, 0x7f80 | x);
} else if (x >= RST0 && x <= RST7) {
/* Restart marker */
goto found_ls;
} else {
/* Non-restart marker */
ptr -= 2;
goto found_ls;
}

View File

@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 128x88
#sar 0: 0/1
0, 0, 0, 1, 33792, 0xca0c323c
0, 0, 0, 1, 33792, 0xafbc521d

View File

@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 128x88
#sar 0: 0/1
0, 0, 0, 1, 33792, 0x650630b1
0, 0, 0, 1, 33792, 0xafbc521d