]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vmdav.c
tiffdec: remove an unneeded variable
[ffmpeg] / libavcodec / vmdav.c
index 3a0cbf9424fede3b849f854abd61f36eee723fa4..a1e39c058818c7d4bbcde8d2e545a0b9d3f2ca81 100644 (file)
@@ -60,7 +60,7 @@
 typedef struct VmdVideoContext {
 
     AVCodecContext *avctx;
-    AVFrame prev_frame;
+    AVFrame *prev_frame;
 
     const unsigned char *buf;
     int size;
@@ -152,9 +152,10 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
     int src_count, int src_size, int dest_len)
 {
     unsigned char *pd;
-    int i, l;
+    int i, l, used = 0;
     unsigned char *dest_end = dest + dest_len;
     GetByteContext gb;
+    uint16_t run_val;
 
     bytestream2_init(&gb, src, src_size);
     pd = dest;
@@ -162,10 +163,9 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
         if (bytestream2_get_bytes_left(&gb) < 1)
             return 0;
         *pd++ = bytestream2_get_byteu(&gb);
+        used++;
     }
 
-    src_count >>= 1;
-    i = 0;
     do {
         if (bytestream2_get_bytes_left(&gb) < 1)
             break;
@@ -177,16 +177,17 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
             bytestream2_get_buffer(&gb, pd, l);
             pd += l;
         } else {
-            if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2)
+            if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < 2)
                 return bytestream2_tell(&gb);
+            run_val = bytestream2_get_ne16(&gb);
             for (i = 0; i < l; i++) {
-                *pd++ = bytestream2_get_byteu(&gb);
-                *pd++ = bytestream2_get_byteu(&gb);
+                AV_WN16(pd, run_val);
+                pd += 2;
             }
-            bytestream2_skip(&gb, 2);
+            l *= 2;
         }
-        i += l;
-    } while (i < src_count);
+        used += l;
+    } while (used < src_count);
 
     return bytestream2_tell(&gb);
 }
@@ -242,11 +243,11 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
 
     /* if only a certain region will be updated, copy the entire previous
      * frame before the decode */
-    if (s->prev_frame.data[0] &&
+    if (s->prev_frame->data[0] &&
         (frame_x || frame_y || (frame_width != s->avctx->width) ||
         (frame_height != s->avctx->height))) {
 
-        memcpy(frame->data[0], s->prev_frame.data[0],
+        memcpy(frame->data[0], s->prev_frame->data[0],
             s->avctx->height * frame->linesize[0]);
     }
 
@@ -277,6 +278,11 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
         return AVERROR_INVALIDDATA;
     meth = bytestream2_get_byteu(&gb);
     if (meth & 0x80) {
+        if (!s->unpack_buffer_size) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Trying to unpack LZ-compressed frame with no LZ buffer\n");
+            return AVERROR_INVALIDDATA;
+        }
         lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
                   s->unpack_buffer, s->unpack_buffer_size);
         meth &= 0x7F;
@@ -284,7 +290,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
     }
 
     dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
-    pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
+    pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
     switch (meth) {
     case 1:
         for (i = 0; i < frame_height; i++) {
@@ -300,7 +306,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
                     ofs += len;
                 } else {
                     /* interframe pixel copy */
-                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                    if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
                         return AVERROR_INVALIDDATA;
                     memcpy(&dp[ofs], &pp[ofs], len + 1);
                     ofs += len + 1;
@@ -313,7 +319,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
                 return AVERROR_INVALIDDATA;
             }
             dp += frame->linesize[0];
-            pp += s->prev_frame.linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
 
@@ -321,7 +327,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
         for (i = 0; i < frame_height; i++) {
             bytestream2_get_buffer(&gb, dp, frame_width);
             dp += frame->linesize[0];
-            pp += s->prev_frame.linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
 
@@ -332,16 +338,21 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
                 len = bytestream2_get_byte(&gb);
                 if (len & 0x80) {
                     len = (len & 0x7F) + 1;
-                    if (bytestream2_get_byte(&gb) == 0xFF)
+                    if (bytestream2_peek_byte(&gb) == 0xFF) {
+                        int slen = len;
+                        bytestream2_get_byte(&gb);
                         len = rle_unpack(gb.buffer, &dp[ofs],
                                          len, bytestream2_get_bytes_left(&gb),
                                          frame_width - ofs);
-                    else
+                        ofs += slen;
+                        bytestream2_skip(&gb, len);
+                    } else {
                         bytestream2_get_buffer(&gb, &dp[ofs], len);
-                    bytestream2_skip(&gb, len);
+                        ofs += len;
+                    }
                 } else {
                     /* interframe pixel copy */
-                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                    if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
                         return AVERROR_INVALIDDATA;
                     memcpy(&dp[ofs], &pp[ofs], len + 1);
                     ofs += len + 1;
@@ -354,13 +365,23 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
                 return AVERROR_INVALIDDATA;
             }
             dp += frame->linesize[0];
-            pp += s->prev_frame.linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
     }
     return 0;
 }
 
+static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
+{
+    VmdVideoContext *s = avctx->priv_data;
+
+    av_frame_free(&s->prev_frame);
+    av_free(s->unpack_buffer);
+
+    return 0;
+}
+
 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
 {
     VmdVideoContext *s = avctx->priv_data;
@@ -383,9 +404,11 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
     vmd_header = (unsigned char *)avctx->extradata;
 
     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
-    s->unpack_buffer = av_malloc(s->unpack_buffer_size);
-    if (!s->unpack_buffer)
-        return -1;
+    if (s->unpack_buffer_size) {
+        s->unpack_buffer = av_malloc(s->unpack_buffer_size);
+        if (!s->unpack_buffer)
+            return AVERROR(ENOMEM);
+    }
 
     /* load up the initial palette */
     raw_palette = &vmd_header[28];
@@ -397,6 +420,12 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
         palette32[i] = (r << 16) | (g << 8) | (b);
     }
 
+    s->prev_frame = av_frame_alloc();
+    if (!s->prev_frame) {
+        vmdvideo_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -428,8 +457,8 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
 
     /* shuffle frames */
-    av_frame_unref(&s->prev_frame);
-    if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
+    av_frame_unref(s->prev_frame);
+    if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
         return ret;
 
     *got_frame      = 1;
@@ -438,16 +467,6 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     return buf_size;
 }
 
-static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
-{
-    VmdVideoContext *s = avctx->priv_data;
-
-    av_frame_unref(&s->prev_frame);
-    av_free(s->unpack_buffer);
-
-    return 0;
-}
-
 
 /*
  * Audio Decoder
@@ -640,6 +659,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
 
 AVCodec ff_vmdvideo_decoder = {
     .name           = "vmdvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VMDVIDEO,
     .priv_data_size = sizeof(VmdVideoContext),
@@ -647,16 +667,15 @@ AVCodec ff_vmdvideo_decoder = {
     .close          = vmdvideo_decode_end,
     .decode         = vmdvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
 };
 
 AVCodec ff_vmdaudio_decoder = {
     .name           = "vmdaudio",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_VMDAUDIO,
     .priv_data_size = sizeof(VmdAudioContext),
     .init           = vmdaudio_decode_init,
     .decode         = vmdaudio_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
 };