Make ipvideo_decode_block_opcode_0x8 a lot simpler by decoding the pixels
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>
Tue, 31 Mar 2009 18:35:19 +0000 (18:35 +0000)
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>
Tue, 31 Mar 2009 18:35:19 +0000 (18:35 +0000)
in a more natural order.

Originally committed as revision 18277 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/interplayvideo.c

index 8ef365d..9bcc9f4 100644 (file)
@@ -243,11 +243,8 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
 static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
 {
     int x, y;
-    unsigned char P[8];
-    unsigned char B[8];
+    unsigned char P[2];
     unsigned int flags = 0;
-    unsigned char P0 = 0, P1 = 0;
-    int lower_half = 0;
 
     /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
      * either top and bottom or left and right halves */
@@ -259,46 +256,21 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
     if (P[0] <= P[1]) {
 
         CHECK_STREAM_PTR(14);
-        B[0] = *s->stream_ptr++;  B[1] = *s->stream_ptr++;
-        P[2] = *s->stream_ptr++;  P[3] = *s->stream_ptr++;
-        B[2] = *s->stream_ptr++;  B[3] = *s->stream_ptr++;
-        P[4] = *s->stream_ptr++;  P[5] = *s->stream_ptr++;
-        B[4] = *s->stream_ptr++;  B[5] = *s->stream_ptr++;
-        P[6] = *s->stream_ptr++;  P[7] = *s->stream_ptr++;
-        B[6] = *s->stream_ptr++;  B[7] = *s->stream_ptr++;
-
-        for (y = 0; y < 8; y++) {
+        s->stream_ptr -= 2;
 
-            /* time to reload flags? */
-            if (y == 0) {
-                flags =
-                    ((B[0] & 0xF0) <<  4) | ((B[4] & 0xF0) <<  8) |
-                    ((B[0] & 0x0F)      ) | ((B[4] & 0x0F) <<  4) |
-                    ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) |
-                    ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20);
-                lower_half = 0;  /* still on top half */
-            } else if (y == 4) {
-                flags =
-                    ((B[2] & 0xF0) <<  4) | ((B[6] & 0xF0) <<  8) |
-                    ((B[2] & 0x0F)      ) | ((B[6] & 0x0F) <<  4) |
-                    ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) |
-                    ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20);
-                lower_half = 2;
+        for (y = 0; y < 16; y++) {
+            // new values for each 4x4 block
+            if (!(y & 3)) {
+                P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
+                flags = bytestream_get_le16(&s->stream_ptr);
             }
 
-            for (x = 0; x < 8; x++, flags >>= 1) {
-                /* get the pixel values ready for this quadrant */
-                if (x == 0) {
-                    P0 = P[lower_half + 0];
-                    P1 = P[lower_half + 1];
-                } else if (x == 4) {
-                    P0 = P[lower_half + 4];
-                    P1 = P[lower_half + 5];
-                }
-
-                *s->pixel_ptr++ = flags & 1 ? P1 : P0;
+            for (x = 0; x < 4; x++, flags >>= 1) {
+                *s->pixel_ptr++ = P[flags & 1];
             }
-            s->pixel_ptr += s->line_inc;
+            s->pixel_ptr += s->stride - 4;
+            // switch to right half
+            if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
         }
 
     } else {
@@ -308,44 +280,21 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
 
         if (s->stream_ptr[4] <= s->stream_ptr[5]) {
 
-            B[0] = *s->stream_ptr++;  B[1] = *s->stream_ptr++;
-            B[2] = *s->stream_ptr++;  B[3] = *s->stream_ptr++;
-            P[2] = *s->stream_ptr++;  P[3] = *s->stream_ptr++;
-            B[4] = *s->stream_ptr++;  B[5] = *s->stream_ptr++;
-            B[6] = *s->stream_ptr++;  B[7] = *s->stream_ptr++;
+            flags = bytestream_get_le32(&s->stream_ptr);
 
             /* vertical split; left & right halves are 2-color encoded */
 
-            for (y = 0; y < 8; y++) {
-
-                /* time to reload flags? */
-                if (y == 0) {
-                    flags =
-                        ((B[0] & 0xF0) <<  4) | ((B[4] & 0xF0) <<  8) |
-                        ((B[0] & 0x0F)      ) | ((B[4] & 0x0F) <<  4) |
-                        ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) |
-                        ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20);
-                } else if (y == 4) {
-                    flags =
-                        ((B[2] & 0xF0) <<  4) | ((B[6] & 0xF0) <<  8) |
-                        ((B[2] & 0x0F)      ) | ((B[6] & 0x0F) <<  4) |
-                        ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) |
-                        ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20);
+            for (y = 0; y < 16; y++) {
+                for (x = 0; x < 4; x++, flags >>= 1) {
+                    *s->pixel_ptr++ = P[flags & 1];
                 }
-
-                for (x = 0; x < 8; x++, flags >>= 1) {
-                    /* get the pixel values ready for this half */
-                    if (x == 0) {
-                        P0 = P[0];
-                        P1 = P[1];
-                    } else if (x == 4) {
-                        P0 = P[2];
-                        P1 = P[3];
-                    }
-
-                    *s->pixel_ptr++ = flags & 1 ? P1 : P0;
+                s->pixel_ptr += s->stride - 4;
+                // switch to right half
+                if (y == 7) {
+                    s->pixel_ptr -= 8 * s->stride - 4;
+                    P[0] = *s->stream_ptr++; P[1] = *s->stream_ptr++;
+                    flags = bytestream_get_le32(&s->stream_ptr);
                 }
-                s->pixel_ptr += s->line_inc;
             }
 
         } else {