PR #23090 opened by Ramiro Polla (ramiro) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23090 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23090.patch
A couple of patches from an earlier work of cleaning up mjpegdec that might be useful for !22917. >From 0d3f242f76b253e7af1d98f474123df1318dc99a Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Fri, 13 Feb 2026 19:55:11 +0100 Subject: [PATCH 1/2] avcodec/mjpegdec: remove redundant vpred variable for bayer The vpred variable in ljpeg_decode_rgb_scan() is redundant with buffer[0][i], which is used by the generic codepath. --- libavcodec/mjpegdec.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index f037d9f7aa..6e849ee80a 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1093,7 +1093,6 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) const int mask = ((1 << s->bits) - 1) << point_transform; int resync_mb_y = 0; int resync_mb_x = 0; - int vpred[6]; int ret; if (!s->bayer && s->nb_components < 3) @@ -1109,10 +1108,6 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) return AVERROR_INVALIDDATA; } - - for (i = 0; i < 6; i++) - vpred[i] = 1 << (s->bits - 1); - if (s->bayer) width = s->mb_width / nb_components; /* Interleaved, width stored is the total so need to divide */ else @@ -1166,19 +1161,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) topleft[i] = top[i]; top[i] = buffer[mb_x][i]; + PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); + ret = mjpeg_decode_dc(s, s->dc_index[i], &dc); if (ret < 0) return ret; - if (!s->bayer || mb_x) { - pred = left[i]; - } else { /* This path runs only for the first line in bayer images */ - vpred[i] += dc; - pred = vpred[i] - dc; - } - - PREDICT(pred, topleft[i], top[i], pred, modified_predictor); - left[i] = buffer[mb_x][i] = mask & (pred + (unsigned)(dc * (1 << point_transform))); } -- 2.52.0 >From 3435bd4a5c1d8d8bfd34ad25662ab5b1f2486a79 Mon Sep 17 00:00:00 2001 From: Ramiro Polla <[email protected]> Date: Fri, 13 Feb 2026 22:34:13 +0100 Subject: [PATCH 2/2] avcodec/mjpegdec: simplify bayer width handling Double s->avctx->width directly, simplifying width-related code in ljpeg_decode_rgb_scan(). --- libavcodec/mjpegdec.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 6e849ee80a..e6c4f4acfc 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -426,19 +426,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return AVERROR_PATCHWELCOME; } - if (s->bayer) { - if (nb_components == 2) { - /* Bayer images embedded in DNGs can contain 2 interleaved components and the - width stored in their SOF3 markers is the width of each one. We only output - a single component, therefore we need to adjust the output image width. We - handle the deinterleaving (but not the debayering) in this file. */ - width *= 2; - } - /* They can also contain 1 component, which is double the width and half the height - of the final image (rows are interleaved). We don't handle the decoding in this - file, but leave that to the TIFF/DNG decoder. */ - } - /* if different size, realloc/alloc picture */ if (width != s->width || height != s->height || bits != s->bits || memcmp(s->h_count, h_count, sizeof(h_count)) || @@ -475,6 +462,19 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->orig_height < height) s->avctx->height = AV_CEIL_RSHIFT(s->orig_height, s->avctx->lowres); + if (s->bayer) { + if (nb_components == 2) { + /* Bayer images embedded in DNGs can contain 2 interleaved components and the + * width stored in their SOF3 markers is the width of each one. We only output + * a single component, therefore we need to adjust the output image width. We + * handle the deinterleaving (but not the debayering) in this file. */ + s->avctx->width *= 2; + } + /* They can also contain 1 component, which is double the width and half the height + * of the final image (rows are interleaved). We don't handle the decoding in this + * file, but leave that to the TIFF/DNG decoder. */ + } + s->first_picture = 0; } else { size_change = 0; @@ -1086,7 +1086,6 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) int predictor = s->Ss; int point_transform = s->Al; int i, mb_x, mb_y; - unsigned width; uint16_t (*buffer)[4]; int left[4], top[4], topleft[4]; const int linesize = s->linesize[0]; @@ -1108,12 +1107,8 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) return AVERROR_INVALIDDATA; } - if (s->bayer) - width = s->mb_width / nb_components; /* Interleaved, width stored is the total so need to divide */ - else - width = s->mb_width; - - av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * sizeof(s->ljpeg_buffer[0][0])); + av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, + (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0])); if (!s->ljpeg_buffer) return AVERROR(ENOMEM); @@ -1133,7 +1128,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) for (i = 0; i < 4; i++) top[i] = left[i] = topleft[i] = buffer[0][i]; - for (mb_x = 0; mb_x < width; mb_x++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { int modified_predictor = predictor; int restart; @@ -1210,10 +1205,10 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s) return AVERROR_PATCHWELCOME; if (nb_components == 1) { /* Leave decoding to the TIFF/DNG decoder (see comment in ff_mjpeg_decode_sof) */ - for (mb_x = 0; mb_x < width; mb_x++) + for (mb_x = 0; mb_x < s->mb_width; mb_x++) ((uint16_t*)ptr)[mb_x] = buffer[mb_x][0]; } else if (nb_components == 2) { - for (mb_x = 0; mb_x < width; mb_x++) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { ((uint16_t*)ptr)[2 * mb_x + 0] = buffer[mb_x][0]; ((uint16_t*)ptr)[2 * mb_x + 1] = buffer[mb_x][1]; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
