Browse Source

avcodec/jpeglsdec: Don't presume the context to contain a JLSState

Before 9b3c46a081 every call to
ff_jpegls_decode_picture() allocated and freed a JLSState. This commit
instead put said structure into the context of the JPEG-LS decoder to
avoid said allocation. But said function can also be called from other
MJPEG-based decoders and their contexts doesn't contain said structure,
leading to segfaults. This commit fixes this: The JLSState is now
allocated on the first call to ff_jpegls_decode_picture() and stored in
the context.

Found-by: Michael Niedermayer <michael@niedermayer.cc>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
master
Andreas Rheinhardt 4 years ago
parent
commit
718e03e5f2
3 changed files with 12 additions and 7 deletions
  1. +8
    -7
      libavcodec/jpeglsdec.c
  2. +1
    -0
      libavcodec/mjpegdec.c
  3. +3
    -0
      libavcodec/mjpegdec.h

+ 8
- 7
libavcodec/jpeglsdec.c View File

@@ -45,11 +45,6 @@
*/ */
//#define JLS_BROKEN //#define JLS_BROKEN


typedef struct JpegLSDecodeContext {
MJpegDecodeContext mjpeg;
JLSState state;
} JpegLSDecodeContext;

/** /**
* Decode LSE block with initialization parameters * Decode LSE block with initialization parameters
*/ */
@@ -355,10 +350,16 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
{ {
int i, t = 0; int i, t = 0;
uint8_t *zero, *last, *cur; uint8_t *zero, *last, *cur;
JLSState *const state = &((JpegLSDecodeContext*)s)->state;
JLSState *state = s->jls_state;
int off = 0, stride = 1, width, shift, ret = 0; int off = 0, stride = 1, width, shift, ret = 0;
int decoded_height = 0; int decoded_height = 0;


if (!state) {
state = av_malloc(sizeof(*state));
if (!state)
return AVERROR(ENOMEM);
s->jls_state = state;
}
zero = av_mallocz(s->picture_ptr->linesize[0]); zero = av_mallocz(s->picture_ptr->linesize[0]);
if (!zero) if (!zero)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
@@ -548,7 +549,7 @@ AVCodec ff_jpegls_decoder = {
.long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_JPEGLS, .id = AV_CODEC_ID_JPEGLS,
.priv_data_size = sizeof(JpegLSDecodeContext),
.priv_data_size = sizeof(MJpegDecodeContext),
.init = ff_mjpeg_decode_init, .init = ff_mjpeg_decode_init,
.close = ff_mjpeg_decode_end, .close = ff_mjpeg_decode_end,
.receive_frame = ff_mjpeg_receive_frame, .receive_frame = ff_mjpeg_receive_frame,


+ 1
- 0
libavcodec/mjpegdec.c View File

@@ -2916,6 +2916,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
reset_icc_profile(s); reset_icc_profile(s);


av_freep(&s->hwaccel_picture_private); av_freep(&s->hwaccel_picture_private);
av_freep(&s->jls_state);


return 0; return 0;
} }


+ 3
- 0
libavcodec/mjpegdec.h View File

@@ -49,6 +49,8 @@ typedef struct ICCEntry {
int length; int length;
} ICCEntry; } ICCEntry;


struct JLSState;

typedef struct MJpegDecodeContext { typedef struct MJpegDecodeContext {
AVClass *class; AVClass *class;
AVCodecContext *avctx; AVCodecContext *avctx;
@@ -163,6 +165,7 @@ typedef struct MJpegDecodeContext {
enum AVPixelFormat hwaccel_sw_pix_fmt; enum AVPixelFormat hwaccel_sw_pix_fmt;
enum AVPixelFormat hwaccel_pix_fmt; enum AVPixelFormat hwaccel_pix_fmt;
void *hwaccel_picture_private; void *hwaccel_picture_private;
struct JLSState *jls_state;
} MJpegDecodeContext; } MJpegDecodeContext;


int ff_mjpeg_build_vlc(VLC *vlc, const uint8_t *bits_table, int ff_mjpeg_build_vlc(VLC *vlc, const uint8_t *bits_table,


Loading…
Cancel
Save