]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/proresdec_lgpl.c
indeo3: Fix null ptr dereference
[ffmpeg] / libavcodec / proresdec_lgpl.c
index 156f87530a273e62e2c1184e5b9cbac9793f112a..5fe47755c23218df3b7eabba95e4e7c98e12ae2b 100644 (file)
@@ -28,7 +28,7 @@
  * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
  */
 
-#define A32_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
+#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
 
 #include <stdint.h>
 
@@ -71,6 +71,7 @@ typedef struct {
     int        slice_height_factor;
     int        num_x_mbs;
     int        num_y_mbs;
+    int        alpha_info;
 } ProresContext;
 
 
@@ -104,10 +105,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ctx->total_slices     = 0;
     ctx->slice_data       = NULL;
 
-    avctx->pix_fmt = PIX_FMT_YUV422P10; // set default pixel format
-
     avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
-    ff_proresdsp_init(&ctx->dsp);
+    ff_proresdsp_init(&ctx->dsp, avctx);
 
     avctx->coded_frame = &ctx->picture;
     avcodec_get_frame_defaults(&ctx->picture);
@@ -189,6 +188,10 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
         ctx->picture.top_field_first  = ctx->frame_type & 1;
     }
 
+    ctx->alpha_info = buf[17] & 0xf;
+    if (ctx->alpha_info)
+        av_log_missing_feature(avctx, "alpha channel", 0);
+
     ctx->qmat_changed = 0;
     ptr   = buf + 20;
     flags = buf[19];
@@ -496,8 +499,9 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
 }
 
 
-static int decode_slice(AVCodecContext *avctx, ProresThreadData *td)
+static int decode_slice(AVCodecContext *avctx, void *tdata)
 {
+    ProresThreadData *td = tdata;
     ProresContext *ctx = avctx->priv_data;
     int mb_x_pos  = td->x_pos;
     int mb_y_pos  = td->y_pos;
@@ -543,9 +547,11 @@ static int decode_slice(AVCodecContext *avctx, ProresThreadData *td)
     hdr_size    = buf[0] >> 3;
     y_data_size = AV_RB16(buf + 2);
     u_data_size = AV_RB16(buf + 4);
-    v_data_size = slice_data_size - y_data_size - u_data_size - hdr_size;
+    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
+        slice_data_size - y_data_size - u_data_size - hdr_size;
 
-    if (v_data_size < 0 || hdr_size < 6) {
+    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
+        v_data_size < 0 || hdr_size < 6) {
         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
         return AVERROR_INVALIDDATA;
     }
@@ -554,7 +560,7 @@ static int decode_slice(AVCodecContext *avctx, ProresThreadData *td)
     sf = sf > 128 ? (sf - 96) << 2 : sf;
 
     /* scale quantization matrixes according with slice's scale factor */
-    /* TODO: this can be SIMD-optimized alot */
+    /* TODO: this can be SIMD-optimized a lot */
     if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
         ctx->prev_slice_sf = sf;
         for (i = 0; i < 64; i++) {
@@ -616,7 +622,7 @@ static int decode_picture(ProresContext *ctx, int pic_num,
         }
     }
 
-    return avctx->execute(avctx, (void *) decode_slice,
+    return avctx->execute(avctx, decode_slice,
                           ctx->slice_data, NULL, slice_num,
                           sizeof(ctx->slice_data[0]));
 }