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
@@ -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, | ||||
@@ -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; | ||||
} | } | ||||
@@ -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, | ||||