Merge commit 'f337c29017b10c98ccb4dce20efced4c74b665f6'
[ffmpeg.git] / libavcodec / eatgq.c
index 1d1370b..cba9a16 100644 (file)
@@ -2,20 +2,20 @@
  * Electronic Arts TGQ Video Decoder
  * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
  *
  * Electronic Arts TGQ Video Decoder
  * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -142,7 +142,10 @@ static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8
     }
 }
 
     }
 }
 
-static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
+/**
+ * @return <0 on error
+ */
+static int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
     int mode;
     int i;
     int8_t dc[6];
     int mode;
     int i;
     int8_t dc[6];
@@ -150,7 +153,7 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
     mode = bytestream2_get_byte(&s->gb);
     if (mode>12) {
         GetBitContext gb;
     mode = bytestream2_get_byte(&s->gb);
     if (mode>12) {
         GetBitContext gb;
-        init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8);
+        init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode) * 8);
         for(i=0; i<6; i++)
             tgq_decode_block(s, s->block[i], &gb);
         tgq_idct_put_mb(s, s->block, mb_x, mb_y);
         for(i=0; i<6; i++)
             tgq_decode_block(s, s->block[i], &gb);
         tgq_idct_put_mb(s, s->block, mb_x, mb_y);
@@ -169,9 +172,11 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
             }
         }else{
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
             }
         }else{
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
+            return -1;
         }
         tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
     }
         }
         tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
     }
+    return 0;
 }
 
 static void tgq_calculate_qtable(TgqContext *s, int quant){
 }
 
 static void tgq_calculate_qtable(TgqContext *s, int quant){
@@ -190,12 +195,13 @@ static int tgq_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     TgqContext *s = avctx->priv_data;
     int x, y, ret;
     int buf_size = avpkt->size;
     TgqContext *s = avctx->priv_data;
     int x, y, ret;
-    int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
+    int big_endian;
 
     if (buf_size < 16) {
         av_log(avctx, AV_LOG_WARNING, "truncated header\n");
         return AVERROR_INVALIDDATA;
     }
 
     if (buf_size < 16) {
         av_log(avctx, AV_LOG_WARNING, "truncated header\n");
         return AVERROR_INVALIDDATA;
     }
+    big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
     if (big_endian) {
         s->width  = bytestream2_get_be16u(&s->gb);
     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
     if (big_endian) {
         s->width  = bytestream2_get_be16u(&s->gb);
@@ -225,7 +231,8 @@ static int tgq_decode_frame(AVCodecContext *avctx,
 
     for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
         for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
 
     for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
         for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
-            tgq_decode_mb(s, y, x);
+            if (tgq_decode_mb(s, y, x) < 0)
+                return AVERROR_INVALIDDATA;
 
     *got_frame = 1;
     *(AVFrame*)data = s->frame;
 
     *got_frame = 1;
     *(AVFrame*)data = s->frame;