]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/indeo4.c
sonic: mark as experimental
[ffmpeg] / libavcodec / indeo4.c
index 573718e374f9c9f1741d77fc6b179ad155090bf2..126520154188d5d3cc71d3d10e931de923aa47fc 100644 (file)
@@ -372,7 +372,8 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
 
         if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) {
             transform_id = get_bits(&ctx->gb, 5);
-            if (!transforms[transform_id].inv_trans) {
+            if (transform_id >= FF_ARRAY_ELEMS(transforms) ||
+                !transforms[transform_id].inv_trans) {
                 av_log_ask_for_sample(avctx, "Unimplemented transform: %d!\n", transform_id);
                 return AVERROR_PATCHWELCOME;
             }
@@ -403,6 +404,10 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
                 av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
                 return AVERROR_INVALIDDATA;
             }
+            if (band->quant_mat > 21) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n");
+                return AVERROR_INVALIDDATA;
+            }
         }
 
         /* decode block huffman codebook */
@@ -443,6 +448,11 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
 
     align_get_bits(&ctx->gb);
 
+    if (!band->scan) {
+        av_log(avctx, AV_LOG_ERROR, "band->scan not set\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
 
@@ -461,7 +471,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
                           IVITile *tile, AVCodecContext *avctx)
 {
     int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
-                mv_scale, mb_type_bits;
+                mv_scale, mb_type_bits, s;
     IVIMbInfo   *mb, *ref_mb;
     int         row_offset = band->mb_size * band->pitch;
 
@@ -511,7 +521,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
                     }
                 }
             } else {
-                if (band->inherit_mv) {
+                if (band->inherit_mv && ref_mb) {
                     mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
                 } else if (ctx->frame_type == FRAMETYPE_INTRA) {
                     mb->type = 0; /* mb_type is always INTRA for intra-frames */
@@ -557,6 +567,15 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
                 }
             }
 
+            s= band->is_halfpel;
+            if (mb->type)
+            if ( x +  (mv_x   >>s) +                 (y+               (mv_y   >>s))*band->pitch < 0 ||
+                 x + ((mv_x+s)>>s) + band->mb_size - 1
+                   + (y+band->mb_size - 1 +((mv_y+s)>>s))*band->pitch > band->height*band->pitch -1) {
+                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mv_x, y*s + mv_y);
+                return AVERROR_INVALIDDATA;
+            }
+
             mb++;
             if (ref_mb)
                 ref_mb++;
@@ -761,6 +780,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
             av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
     }
 
+    if (ctx->frame_type >= FRAMETYPE_NULL_FIRST)
+        return buf_size;
+
     if (ctx->frame.data[0])
         avctx->release_buffer(avctx, &ctx->frame);