Mercurial > mplayer.hg
comparison qtrle.c @ 3687:7fb817c9060b
This commit adds initial support for Quicktime Animation (RLE) video. It
also fixes a FLI function name (FLI is not an AVI decoder).
author | melanson |
---|---|
date | Sun, 23 Dec 2001 22:20:46 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3686:bed6226ffb46 | 3687:7fb817c9060b |
---|---|
1 /* | |
2 Quicktime Animation (RLE) Decoder for MPlayer | |
3 | |
4 (C) 2001 Mike Melanson | |
5 */ | |
6 | |
7 #include "config.h" | |
8 #include "bswap.h" | |
9 | |
10 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | |
11 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | |
12 | |
13 // 256 RGB entries; 25% of these bytes will be unused, but it's faster | |
14 // to index 4-byte entries | |
15 static unsigned char palette[256 * 4]; | |
16 | |
17 void qt_decode_rle24( | |
18 unsigned char *encoded, | |
19 int encoded_size, | |
20 unsigned char *decoded, | |
21 int width, | |
22 int height, | |
23 int bytes_per_pixel) | |
24 { | |
25 int stream_ptr; | |
26 int header; | |
27 int start_line; | |
28 int lines_to_change; | |
29 signed char rle_code; | |
30 int row_ptr, pixel_ptr; | |
31 int row_inc = bytes_per_pixel * width; | |
32 unsigned char r, g, b; | |
33 | |
34 // check if this frame is even supposed to change | |
35 if (encoded_size < 8) | |
36 return; | |
37 | |
38 // start after the chunk size | |
39 stream_ptr = 4; | |
40 | |
41 // fetch the header | |
42 header = BE_16(&encoded[stream_ptr]); | |
43 stream_ptr += 2; | |
44 | |
45 // if a header is present, fetch additional decoding parameters | |
46 if (header & 0x0008) | |
47 { | |
48 start_line = BE_16(&encoded[stream_ptr]); | |
49 stream_ptr += 4; | |
50 lines_to_change = BE_16(&encoded[stream_ptr]); | |
51 stream_ptr += 4; | |
52 } | |
53 else | |
54 { | |
55 start_line = 0; | |
56 lines_to_change = height; | |
57 } | |
58 | |
59 row_ptr = row_inc * start_line; | |
60 while (lines_to_change--) | |
61 { | |
62 pixel_ptr = row_ptr + ((encoded[stream_ptr++] - 1) * bytes_per_pixel); | |
63 | |
64 while ((rle_code = (signed char)encoded[stream_ptr++]) != -1) | |
65 { | |
66 if (rle_code == 0) | |
67 // there's another skip code in the stream | |
68 pixel_ptr += ((encoded[stream_ptr++] - 1) * bytes_per_pixel); | |
69 else if (rle_code < 0) | |
70 { | |
71 // decode the run length code | |
72 rle_code = -rle_code; | |
73 r = encoded[stream_ptr++]; | |
74 g = encoded[stream_ptr++]; | |
75 b = encoded[stream_ptr++]; | |
76 while (rle_code--) | |
77 { | |
78 decoded[pixel_ptr++] = b; | |
79 decoded[pixel_ptr++] = g; | |
80 decoded[pixel_ptr++] = r; | |
81 if (bytes_per_pixel == 4) | |
82 pixel_ptr++; | |
83 } | |
84 } | |
85 else | |
86 { | |
87 // copy pixels directly to output | |
88 while (rle_code--) | |
89 { | |
90 decoded[pixel_ptr++] = encoded[stream_ptr + 2]; | |
91 decoded[pixel_ptr++] = encoded[stream_ptr + 1]; | |
92 decoded[pixel_ptr++] = encoded[stream_ptr + 0]; | |
93 stream_ptr += 3; | |
94 if (bytes_per_pixel == 4) | |
95 pixel_ptr++; | |
96 } | |
97 } | |
98 } | |
99 | |
100 row_ptr += row_inc; | |
101 } | |
102 } | |
103 | |
104 void qt_decode_rle( | |
105 unsigned char *encoded, | |
106 int encoded_size, | |
107 unsigned char *decoded, | |
108 int width, | |
109 int height, | |
110 int encoded_bpp, | |
111 int bytes_per_pixel) | |
112 { | |
113 switch (encoded_bpp) | |
114 { | |
115 case 24: | |
116 qt_decode_rle24( | |
117 encoded, | |
118 encoded_size, | |
119 decoded, | |
120 width, | |
121 height, | |
122 bytes_per_pixel); | |
123 break; | |
124 } | |
125 } |