]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/xan.c
Store original width/height so that rv20 does not get stuck with some
[ffmpeg] / libavcodec / xan.c
index 748f4d1eab23a195171a93016dfab50af8b0c6f9..fcfd9c6d0c12c67feed2c0472fa305a9a30fcc3a 100644 (file)
@@ -31,7 +31,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
@@ -75,9 +74,6 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = PIX_FMT_PAL8;
 
-    if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
-        return -1;
-
     s->buffer1_size = avctx->width * avctx->height;
     s->buffer1 = av_malloc(s->buffer1_size);
     s->buffer2_size = avctx->width * avctx->height;
@@ -157,17 +153,14 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l
             av_memcpy_backptr(dest, back, size2);
             dest += size2;
         } else {
-            size = ((opcode & 0x1f) << 2) + 4;
-
-            if (size > 0x70)
-                break;
+            int finish = opcode >= 0xfc;
+            size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
 
             memcpy(dest, src, size);  dest += size;  src += size;
+            if (finish)
+                return;
         }
     }
-
-    size = opcode & 3;
-    memcpy(dest, src, size);  dest += size;  src += size;
 }
 
 static inline void xan_wc3_output_pixel_run(XanContext *s,
@@ -185,13 +178,14 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
     line_inc = stride - width;
     index = y * stride + x;
     current_x = x;
-    while((pixel_count--) && (index < s->frame_size)) {
-
-        /* don't do a memcpy() here; keyframes generally copy an entire
-         * frame of data and the stride needs to be accounted for */
-        palette_plane[index++] = *pixel_buffer++;
+    while(pixel_count && (index < s->frame_size)) {
+        int count = FFMIN(pixel_count, width - current_x);
+        memcpy(palette_plane + index, pixel_buffer, count);
+        pixel_count  -= count;
+        index        += count;
+        pixel_buffer += count;
+        current_x    += count;
 
-        current_x++;
         if (current_x >= width) {
             index += line_inc;
             current_x = 0;
@@ -217,18 +211,21 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s,
     curframe_x = x;
     prevframe_index = (y + motion_y) * stride + x + motion_x;
     prevframe_x = x + motion_x;
-    while((pixel_count--) && (curframe_index < s->frame_size)) {
+    while(pixel_count && (curframe_index < s->frame_size)) {
+        int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x);
 
-        palette_plane[curframe_index++] =
-            prev_palette_plane[prevframe_index++];
+        memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count);
+        pixel_count     -= count;
+        curframe_index  += count;
+        prevframe_index += count;
+        curframe_x      += count;
+        prevframe_x     += count;
 
-        curframe_x++;
         if (curframe_x >= width) {
             curframe_index += line_inc;
             curframe_x = 0;
         }
 
-        prevframe_x++;
         if (prevframe_x >= width) {
             prevframe_index += line_inc;
             prevframe_x = 0;