]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavcodec/xan.c
frsh: Export information about the last RTP contract and VRES
[frescor/ffmpeg.git] / libavcodec / xan.c
index 8a7ad240ad3919fefd25594f71f61098c2f3f982..aacdcc1b830fd8c7130e9eca74f959c5b8e04a55 100644 (file)
@@ -36,6 +36,8 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#define ALT_BITSTREAM_READER_LE
+#include "get_bits.h"
 // for av_memcpy_backptr
 #include "libavutil/lzo.h"
 
@@ -93,28 +95,20 @@ static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
     unsigned char ival = byte + 0x16;
     const unsigned char * ptr = src + byte*2;
     unsigned char val = ival;
-    int counter = 0;
     unsigned char *dest_end = dest + dest_len;
+    GetBitContext gb;
 
-    unsigned char bits = *ptr++;
+    init_get_bits(&gb, ptr, 0); // FIXME: no src size available
 
     while ( val != 0x16 ) {
-        if ( (1 << counter) & bits )
-            val = src[byte + val - 0x17];
-        else
-            val = src[val - 0x17];
+        val = src[val - 0x17 + get_bits1(&gb) * byte];
 
         if ( val < 0x16 ) {
-            if (dest + 1 > dest_end)
+            if (dest >= dest_end)
                 return 0;
             *dest++ = val;
             val = ival;
         }
-
-        if (counter++ == 7) {
-            counter = 0;
-            bits = *ptr++;
-        }
     }
 
     return 0;
@@ -163,17 +157,18 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l
             av_memcpy_backptr(dest, back, size2);
             dest += size2;
         } else {
+            int finish;
             size = ((opcode & 0x1f) << 2) + 4;
 
-            if (size > 0x70)
-                break;
+            finish = size > 0x70;
+            if (finish)
+                size = opcode & 3;
 
             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,
@@ -339,16 +334,10 @@ static void xan_wc3_decode_frame(XanContext *s) {
             }
         } else {
             /* run-based motion compensation from last frame */
-            motion_x = (*vector_segment >> 4) & 0xF;
-            motion_y = *vector_segment & 0xF;
+            motion_x = sign_extend(*vector_segment >> 4,  4);
+            motion_y = sign_extend(*vector_segment & 0xF, 4);
             vector_segment++;
 
-            /* sign extension */
-            if (motion_x & 0x8)
-                motion_x |= 0xFFFFFFF0;
-            if (motion_y & 0x8)
-                motion_y |= 0xFFFFFFF0;
-
             /* copy a run of pixels from the previous frame */
             xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
 
@@ -357,16 +346,8 @@ static void xan_wc3_decode_frame(XanContext *s) {
 
         /* coordinate accounting */
         total_pixels -= size;
-        while (size) {
-            if (x + size >= width) {
-                y++;
-                size -= (width - x);
-                x = 0;
-            } else {
-                x += size;
-                size = 0;
-            }
-        }
+        y += (x + size) / width;
+        x  = (x + size) % width;
     }
 }