]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vmdav.c
vda: removes useless doxygen command.
[ffmpeg] / libavcodec / vmdav.c
index 89b5c2bc6a3380d2d7d4567156757d1c73ff2a1d..7006f61f2b52d5be721fbb89da10ba1ff2f91c8e 100644 (file)
@@ -2,20 +2,20 @@
  * Sierra VMD Audio & Video Decoders
  * Copyright (C) 2004 the ffmpeg project
  *
- * 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.
  *
- * 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
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,7 +76,7 @@ static void lz_unpack(const unsigned char *src, int src_len,
                       unsigned char *dest, int dest_len)
 {
     const unsigned char *s;
-    unsigned int s_len;
+    const unsigned char *s_end;
     unsigned char *d;
     unsigned char *d_end;
     unsigned char queue[QUEUE_SIZE];
@@ -89,16 +89,17 @@ static void lz_unpack(const unsigned char *src, int src_len,
     unsigned int i, j;
 
     s = src;
-    s_len = src_len;
+    s_end = src + src_len;
     d = dest;
     d_end = d + dest_len;
+
+    if (s_end - s < 8)
+        return;
     dataleft = AV_RL32(s);
-    s += 4; s_len -= 4;
+    s += 4;
     memset(queue, 0x20, QUEUE_SIZE);
-    if (s_len < 4)
-        return;
     if (AV_RL32(s) == 0x56781234) {
-        s += 4; s_len -= 4;
+        s += 4;
         qpos = 0x111;
         speclen = 0xF + 3;
     } else {
@@ -106,42 +107,38 @@ static void lz_unpack(const unsigned char *src, int src_len,
         speclen = 100;  /* no speclen */
     }
 
-    while (dataleft > 0 && s_len > 0) {
-        tag = *s++; s_len--;
+    while (s_end - s > 0 && dataleft > 0) {
+        tag = *s++;
         if ((tag == 0xFF) && (dataleft > 8)) {
-            if (d + 8 > d_end || s_len < 8)
+            if (d_end - d < 8 || s_end - s < 8)
                 return;
             for (i = 0; i < 8; i++) {
                 queue[qpos++] = *d++ = *s++;
                 qpos &= QUEUE_MASK;
             }
-            s_len -= 8;
             dataleft -= 8;
         } else {
             for (i = 0; i < 8; i++) {
                 if (dataleft == 0)
                     break;
                 if (tag & 0x01) {
-                    if (d + 1 > d_end || s_len < 1)
+                    if (d_end - d < 1 || s_end - s < 1)
                         return;
                     queue[qpos++] = *d++ = *s++;
                     qpos &= QUEUE_MASK;
                     dataleft--;
-                    s_len--;
                 } else {
-                    if (s_len < 2)
+                    if (s_end - s < 2)
                         return;
                     chainofs = *s++;
                     chainofs |= ((*s & 0xF0) << 4);
                     chainlen = (*s++ & 0x0F) + 3;
-                    s_len -= 2;
                     if (chainlen == speclen) {
-                        if (s_len < 1)
+                        if (s_end - s < 1)
                             return;
                         chainlen = *s++ + 0xF + 3;
-                        s_len--;
                     }
-                    if (d + chainlen > d_end)
+                    if (d_end - d < chainlen)
                         return;
                     for (j = 0; j < chainlen; j++) {
                         *d = queue[chainofs++ & QUEUE_MASK];
@@ -156,47 +153,45 @@ static void lz_unpack(const unsigned char *src, int src_len,
     }
 }
 
-static int rle_unpack(const unsigned char *src, unsigned char *dest,
-    int src_count, int src_size, int dest_len)
+static int rle_unpack(const unsigned char *src, int src_len, int src_count,
+                      unsigned char *dest, int dest_len)
 {
     const unsigned char *ps;
+    const unsigned char *ps_end;
     unsigned char *pd;
     int i, l;
     unsigned char *dest_end = dest + dest_len;
 
     ps = src;
+    ps_end = src + src_len;
     pd = dest;
     if (src_count & 1) {
-        if (src_size < 1)
+        if (ps_end - ps < 1)
             return 0;
         *pd++ = *ps++;
-        src_size--;
     }
 
     src_count >>= 1;
     i = 0;
     do {
-        if (src_size < 1)
+        if (ps_end - ps < 1)
             break;
         l = *ps++;
-        src_size--;
         if (l & 0x80) {
             l = (l & 0x7F) * 2;
-            if (pd + l > dest_end || src_size < l)
+            if (dest_end - pd < l || ps_end - ps < l)
                 return ps - src;
             memcpy(pd, ps, l);
             ps += l;
-            src_size -= l;
             pd += l;
         } else {
-            if (pd + i > dest_end || src_size < 2)
+            if (dest_end - pd < i || ps_end - ps < 2)
                 return ps - src;
             for (i = 0; i < l; i++) {
                 *pd++ = ps[0];
                 *pd++ = ps[1];
             }
             ps += 2;
-            src_size -= 2;
         }
         i += l;
     } while (i < src_count);
@@ -212,9 +207,10 @@ static void vmd_decode(VmdVideoContext *s)
 
     /* point to the start of the encoded data */
     const unsigned char *p = s->buf + 16;
+    const unsigned char *p_end = s->buf + s->size;
 
     const unsigned char *pb;
-    unsigned int pb_size;
+    const unsigned char *pb_end;
     unsigned char meth;
     unsigned char *dp;   /* pointer to current frame */
     unsigned char *pp;   /* pointer to previous frame */
@@ -260,29 +256,28 @@ static void vmd_decode(VmdVideoContext *s)
 
     /* check if there is a new palette */
     if (s->buf[15] & 0x02) {
+        if (p_end - p < 2 + 3 * PALETTE_COUNT)
+            return;
         p += 2;
         palette32 = (unsigned int *)s->palette;
         for (i = 0; i < PALETTE_COUNT; i++) {
             r = *p++ * 4;
             g = *p++ * 4;
             b = *p++ * 4;
-            palette32[i] = (r << 16) | (g << 8) | (b);
+            palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b;
+            palette32[i] |= palette32[i] >> 6 & 0x30303;
         }
-        s->size -= (256 * 3 + 2);
     }
-    if (s->size > 0) {
+    if (p < p_end) {
         /* originally UnpackFrame in VAG's code */
         pb = p;
-        pb_size = s->buf + s->size - pb;
-        if (pb_size < 1)
-            return;
-        meth = *pb++; pb_size--;
+        pb_end = p_end;
+        meth = *pb++;
         if (meth & 0x80) {
-            lz_unpack(pb, pb_size,
-                      s->unpack_buffer, s->unpack_buffer_size);
+            lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
             meth &= 0x7F;
             pb = s->unpack_buffer;
-            pb_size = s->unpack_buffer_size;
+            pb_end = s->unpack_buffer + s->unpack_buffer_size;
         }
 
         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
@@ -292,17 +287,15 @@ static void vmd_decode(VmdVideoContext *s)
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
-                    if (pb_size < 1)
+                    if (pb_end - pb < 1)
                         return;
                     len = *pb++;
-                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
-                        if (ofs + len > frame_width || pb_size < len)
+                        if (ofs + len > frame_width || pb_end - pb < len)
                             return;
                         memcpy(&dp[ofs], pb, len);
                         pb += len;
-                        pb_size -= len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
@@ -324,11 +317,10 @@ static void vmd_decode(VmdVideoContext *s)
 
         case 2:
             for (i = 0; i < frame_height; i++) {
-                if (pb_size < frame_width)
+                if (pb_end -pb < frame_width)
                     return;
                 memcpy(dp, pb, frame_width);
                 pb += frame_width;
-                pb_size -= frame_width;
                 dp += s->frame.linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
@@ -338,23 +330,21 @@ static void vmd_decode(VmdVideoContext *s)
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
-                    if (pb_size < 1)
+                    if (pb_end - pb < 1)
                         return;
                     len = *pb++;
-                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
-                        if (pb_size < 1)
+                        if (pb_end - pb < 1)
                             return;
                         if (*pb++ == 0xFF)
-                            len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
+                            len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
                         else {
-                            if (pb_size < len)
-                                return;
+                        if (pb_end - pb < len)
+                            return;
                             memcpy(&dp[ofs], pb, len);
                         }
                         pb += len;
-                        pb_size -= 1 + len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
@@ -412,6 +402,9 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
         palette32[i] = (r << 16) | (g << 8) | (b);
     }
 
+    avcodec_get_frame_defaults(&s->frame);
+    avcodec_get_frame_defaults(&s->prev_frame);
+
     return 0;
 }
 
@@ -429,7 +422,7 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     if (buf_size < 16)
         return buf_size;
 
-    s->frame.reference = 1;
+    s->frame.reference = 3;
     if (avctx->get_buffer(avctx, &s->frame)) {
         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
         return -1;
@@ -625,7 +618,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
     /* decode audio chunks */
     if (audio_chunks > 0) {
         buf_end = buf + buf_size;
-        while (buf < buf_end) {
+        while ( buf_end - buf >= s->chunk_size) {
             if (s->out_bps == 2) {
                 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
                                  avctx->channels);