diff options
author | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-07-12 17:49:04 +0000 |
---|---|---|
committer | alex <alex@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2002-07-12 17:49:04 +0000 |
commit | 3d0493357f977ea689c62fd0838e3f02d9d54e2d (patch) | |
tree | 47c748630bfc33189c71581f817e940eff5e6345 /libmpcodecs/native | |
parent | 4d25d1b68332c33ba129587ddc92ac0eb95d59b6 (diff) | |
download | mpv-3d0493357f977ea689c62fd0838e3f02d9d54e2d.tar.bz2 mpv-3d0493357f977ea689c62fd0838e3f02d9d54e2d.tar.xz |
8 and 16bpp qtrle support
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6721 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs/native')
-rw-r--r-- | libmpcodecs/native/qtrle.c | 180 |
1 files changed, 177 insertions, 3 deletions
diff --git a/libmpcodecs/native/qtrle.c b/libmpcodecs/native/qtrle.c index 89cf99c10c..23d761c038 100644 --- a/libmpcodecs/native/qtrle.c +++ b/libmpcodecs/native/qtrle.c @@ -2,6 +2,7 @@ Quicktime Animation (RLE) Decoder for MPlayer (C) 2001 Mike Melanson + 8 and 16bpp support by Alex Beregszaszi */ #include "config.h" @@ -10,9 +11,164 @@ #define BE_16(x) (be2me_16(*(unsigned short *)(x))) #define BE_32(x) (be2me_32(*(unsigned int *)(x))) -// 256 RGB entries; 25% of these bytes will be unused, but it's faster -// to index 4-byte entries -static unsigned char palette[256 * 4]; +void qt_decode_rle8( + unsigned char *encoded, + int encoded_size, + unsigned char *decoded, + int width, + int height, + int bytes_per_pixel) +{ + int stream_ptr; + int header; + int start_line; + int lines_to_change; + signed char rle_code; + int row_ptr, pixel_ptr; + int row_inc = bytes_per_pixel * width; + unsigned char pixel; + + // check if this frame is even supposed to change + if (encoded_size < 8) + return; + + // start after the chunk size + stream_ptr = 4; + + // fetch the header + header = BE_16(&encoded[stream_ptr]); + stream_ptr += 2; + + // if a header is present, fetch additional decoding parameters + if (header & 0x0008) + { + start_line = BE_16(&encoded[stream_ptr]); + stream_ptr += 4; + lines_to_change = BE_16(&encoded[stream_ptr]); + stream_ptr += 4; + } + else + { + start_line = 0; + lines_to_change = height; + } + + row_ptr = row_inc * start_line; + while (lines_to_change--) + { + pixel_ptr = row_ptr + ((encoded[stream_ptr++] - 1) * bytes_per_pixel); + + while (stream_ptr < encoded_size && + (rle_code = (signed char)encoded[stream_ptr++]) != -1) + { + if (rle_code == 0) + // there's another skip code in the stream + pixel_ptr += ((encoded[stream_ptr++] - 1) * bytes_per_pixel); + else if (rle_code < 0) + { + // decode the run length code + rle_code = -rle_code; + pixel = encoded[stream_ptr++]; + while (rle_code--) + { + decoded[pixel_ptr++] = pixel; + } + } + else + { + // copy pixels directly to output + while (rle_code--) + { + decoded[pixel_ptr++] = encoded[stream_ptr + 0]; + stream_ptr += 1; + } + } + } + + row_ptr += row_inc; + } +} + +void qt_decode_rle16( + unsigned char *encoded, + int encoded_size, + unsigned char *decoded, + int width, + int height, + int bytes_per_pixel) +{ + int stream_ptr; + int header; + int start_line; + int lines_to_change; + signed char rle_code; + int row_ptr, pixel_ptr; + int row_inc = bytes_per_pixel * width; + unsigned char p1, p2; + + // check if this frame is even supposed to change + if (encoded_size < 8) + return; + + // start after the chunk size + stream_ptr = 4; + + // fetch the header + header = BE_16(&encoded[stream_ptr]); + stream_ptr += 2; + + // if a header is present, fetch additional decoding parameters + if (header & 0x0008) + { + start_line = BE_16(&encoded[stream_ptr]); + stream_ptr += 4; + lines_to_change = BE_16(&encoded[stream_ptr]); + stream_ptr += 4; + } + else + { + start_line = 0; + lines_to_change = height; + } + + row_ptr = row_inc * start_line; + while (lines_to_change--) + { + pixel_ptr = row_ptr + ((encoded[stream_ptr++] - 1) * bytes_per_pixel); + + while (stream_ptr < encoded_size && + (rle_code = (signed char)encoded[stream_ptr++]) != -1) + { + if (rle_code == 0) + // there's another skip code in the stream + pixel_ptr += ((encoded[stream_ptr++] - 1) * bytes_per_pixel); + else if (rle_code < 0) + { + // decode the run length code + rle_code = -rle_code; + p1 = encoded[stream_ptr++]; + p2 = encoded[stream_ptr++]; + while (rle_code--) + { + decoded[pixel_ptr++] = p2; + decoded[pixel_ptr++] = p1; + } + } + else + { + // copy pixels directly to output + while (rle_code--) + { + decoded[pixel_ptr++] = encoded[stream_ptr + 1]; + decoded[pixel_ptr++] = encoded[stream_ptr + 0]; + stream_ptr += 2; + } + } + } + + row_ptr += row_inc; + } +} void qt_decode_rle24( unsigned char *encoded, @@ -113,6 +269,24 @@ void qt_decode_rle( { switch (encoded_bpp) { + case 8: + qt_decode_rle8( + encoded, + encoded_size, + decoded, + width, + height, + bytes_per_pixel); + break; + case 16: + qt_decode_rle16( + encoded, + encoded_size, + decoded, + width, + height, + bytes_per_pixel); + break; case 24: qt_decode_rle24( encoded, |