summaryrefslogtreecommitdiff
path: root/libavcodec/interplayvideo.c
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2009-03-31 18:35:19 +0000
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2009-03-31 18:35:19 +0000
commit283531a81eaa934708b07b51aeba1ebdf109a204 (patch)
treeef3ea795bc757132474d1d958ad20c75cb532066 /libavcodec/interplayvideo.c
parent4472ad2cc444fce9060f1506218b1e45692387ca (diff)
Make ipvideo_decode_block_opcode_0x8 a lot simpler by decoding the pixels
in a more natural order. Originally committed as revision 18277 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/interplayvideo.c')
-rw-r--r--libavcodec/interplayvideo.c95
1 files changed, 22 insertions, 73 deletions
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 8ef365dea6..9bcc9f45e9 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -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 {