From 512c294b4865e2fab1d99f079eda64c517cdb252 Mon Sep 17 00:00:00 2001 From: melanson Date: Sun, 23 Dec 2001 22:20:46 +0000 Subject: This commit adds initial support for Quicktime Animation (RLE) video. It also fixes a FLI function name (FLI is not an AVI decoder). git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@3688 b3059339-0415-0410-9bf9-f77b7e298cf2 --- qtrle.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 qtrle.c (limited to 'qtrle.c') diff --git a/qtrle.c b/qtrle.c new file mode 100644 index 0000000000..6d46f9b32c --- /dev/null +++ b/qtrle.c @@ -0,0 +1,125 @@ +/* + Quicktime Animation (RLE) Decoder for MPlayer + + (C) 2001 Mike Melanson +*/ + +#include "config.h" +#include "bswap.h" + +#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_rle24( + 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 r, g, b; + + // 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 ((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; + r = encoded[stream_ptr++]; + g = encoded[stream_ptr++]; + b = encoded[stream_ptr++]; + while (rle_code--) + { + decoded[pixel_ptr++] = b; + decoded[pixel_ptr++] = g; + decoded[pixel_ptr++] = r; + if (bytes_per_pixel == 4) + pixel_ptr++; + } + } + else + { + // copy pixels directly to output + while (rle_code--) + { + decoded[pixel_ptr++] = encoded[stream_ptr + 2]; + decoded[pixel_ptr++] = encoded[stream_ptr + 1]; + decoded[pixel_ptr++] = encoded[stream_ptr + 0]; + stream_ptr += 3; + if (bytes_per_pixel == 4) + pixel_ptr++; + } + } + } + + row_ptr += row_inc; + } +} + +void qt_decode_rle( + unsigned char *encoded, + int encoded_size, + unsigned char *decoded, + int width, + int height, + int encoded_bpp, + int bytes_per_pixel) +{ + switch (encoded_bpp) + { + case 24: + qt_decode_rle24( + encoded, + encoded_size, + decoded, + width, + height, + bytes_per_pixel); + break; + } +} -- cgit v1.2.3