Mercurial > mplayer.hg
annotate fli.c @ 4303:a53d7ca1ed84
move bug fixed
author | pontscho |
---|---|
date | Tue, 22 Jan 2002 12:00:15 +0000 |
parents | 04ca2b6ddb1e |
children | 2973e997c4a5 |
rev | line source |
---|---|
3155 | 1 /* |
2 FLI Decoder for MPlayer | |
3 | |
4 (C) 2001 Mike Melanson | |
3185 | 5 |
6 32bpp support (c) alex | |
3155 | 7 */ |
8 | |
3509
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
9 #include "config.h" |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
10 #include "bswap.h" |
3737 | 11 #include <stdio.h> |
3509
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
12 |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
13 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
14 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) |
3155 | 15 |
16 #define FLI_256_COLOR 4 | |
17 #define FLI_DELTA 7 | |
18 #define FLI_COLOR 11 | |
19 #define FLI_LC 12 | |
20 #define FLI_BLACK 13 | |
21 #define FLI_BRUN 15 | |
22 #define FLI_COPY 16 | |
23 #define FLI_MINI 18 | |
24 | |
25 // 256 RGB entries; 25% of these bytes will be unused, but it's faster | |
26 // to index 4-byte entries | |
27 static unsigned char palette[256 * 4]; | |
28 | |
3687
7fb817c9060b
This commit adds initial support for Quicktime Animation (RLE) video. It
melanson
parents:
3509
diff
changeset
|
29 void Decode_Fli( |
3155 | 30 unsigned char *encoded, |
31 int encoded_size, | |
32 unsigned char *decoded, | |
33 int width, | |
34 int height, | |
35 int bytes_per_pixel) | |
36 { | |
37 int stream_ptr = 0; | |
38 int pixel_ptr; | |
39 int palette_ptr1; | |
40 int palette_ptr2; | |
41 | |
42 unsigned int frame_size; | |
43 int num_chunks; | |
44 | |
45 unsigned int chunk_size; | |
46 int chunk_type; | |
47 | |
48 int i, j; | |
49 | |
50 int color_packets; | |
51 int color_changes; | |
52 int color_scale; | |
53 | |
54 int lines; | |
55 int compressed_lines; | |
56 int starting_line; | |
57 signed short line_packets; | |
58 int y_ptr; | |
59 int line_inc; | |
60 signed char byte_run; | |
61 | |
62 frame_size = LE_32(&encoded[stream_ptr]); | |
63 stream_ptr += 6; // skip the magic number | |
64 num_chunks = LE_16(&encoded[stream_ptr]); | |
65 stream_ptr += 10; // skip padding | |
66 | |
67 // iterate through the chunks | |
68 frame_size -= 16; | |
69 while ((frame_size > 0) && (num_chunks > 0)) | |
70 { | |
71 chunk_size = LE_32(&encoded[stream_ptr]); | |
72 stream_ptr += 4; | |
73 chunk_type = LE_16(&encoded[stream_ptr]); | |
74 stream_ptr += 2; | |
75 | |
76 switch (chunk_type) | |
77 { | |
78 case FLI_256_COLOR: | |
79 case FLI_COLOR: | |
80 if (chunk_type == FLI_COLOR) | |
81 color_scale = 4; | |
82 else | |
83 color_scale = 1; | |
84 // set up the palette | |
85 color_packets = LE_16(&encoded[stream_ptr]); | |
86 stream_ptr += 2; | |
87 palette_ptr1 = 0; | |
88 for (i = 0; i < color_packets; i++) | |
89 { | |
90 // first byte is how many colors to skip | |
91 palette_ptr1 += (encoded[stream_ptr++] * 4); | |
92 // next byte indicates how many entries to change | |
93 color_changes = encoded[stream_ptr++]; | |
94 // if there are 0 color changes, there are actually 256 | |
95 if (color_changes == 0) | |
96 color_changes = 256; | |
97 for (j = 0; j < color_changes; j++) | |
98 { | |
99 palette[palette_ptr1++] = encoded[stream_ptr + 2] * color_scale; | |
100 palette[palette_ptr1++] = encoded[stream_ptr + 1] * color_scale; | |
101 palette[palette_ptr1++] = encoded[stream_ptr + 0] * color_scale; | |
102 palette_ptr1++; | |
103 stream_ptr += 3; | |
104 } | |
105 } | |
3509
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
106 // it seems that a color packet has to be an even number of bytes |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
107 // so account for a pad byte |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
108 if (stream_ptr & 0x01) |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
109 stream_ptr++; |
3155 | 110 break; |
111 | |
112 case FLI_DELTA: | |
113 line_inc = width * bytes_per_pixel; | |
114 y_ptr = 0; | |
115 compressed_lines = LE_16(&encoded[stream_ptr]); | |
116 stream_ptr += 2; | |
117 while (compressed_lines > 0) | |
118 { | |
119 line_packets = LE_16(&encoded[stream_ptr]); | |
120 stream_ptr += 2; | |
121 if (line_packets < 0) | |
122 { | |
123 line_packets = -line_packets; | |
124 y_ptr += (line_packets * line_inc); | |
125 } | |
126 else | |
127 { | |
128 pixel_ptr = y_ptr; | |
129 for (i = 0; i < line_packets; i++) | |
130 { | |
131 // account for the skip bytes | |
3185 | 132 pixel_ptr += encoded[stream_ptr++] * bytes_per_pixel; |
3155 | 133 byte_run = encoded[stream_ptr++]; |
134 if (byte_run < 0) | |
135 { | |
136 byte_run = -byte_run; | |
137 palette_ptr1 = encoded[stream_ptr++] * 4; | |
138 palette_ptr2 = encoded[stream_ptr++] * 4; | |
139 for (j = 0; j < byte_run; j++) | |
140 { | |
141 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
142 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
143 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 144 if (bytes_per_pixel == 4) /* 32bpp */ |
145 pixel_ptr++; | |
3155 | 146 |
147 decoded[pixel_ptr++] = palette[palette_ptr2 + 0]; | |
148 decoded[pixel_ptr++] = palette[palette_ptr2 + 1]; | |
149 decoded[pixel_ptr++] = palette[palette_ptr2 + 2]; | |
3185 | 150 if (bytes_per_pixel == 4) /* 32bpp */ |
151 pixel_ptr++; | |
3155 | 152 } |
153 } | |
154 else | |
155 { | |
156 for (j = 0; j < byte_run * 2; j++) | |
157 { | |
158 palette_ptr1 = encoded[stream_ptr++] * 4; | |
159 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
160 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
161 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 162 if (bytes_per_pixel == 4) /* 32bpp */ |
163 pixel_ptr++; | |
3155 | 164 } |
165 } | |
166 } | |
167 y_ptr += line_inc; | |
168 compressed_lines--; | |
169 } | |
170 } | |
171 break; | |
172 | |
173 case FLI_LC: | |
174 // line compressed | |
175 line_inc = width * bytes_per_pixel; | |
176 starting_line = LE_16(&encoded[stream_ptr]); | |
177 stream_ptr += 2; | |
178 y_ptr = starting_line * line_inc; | |
179 | |
180 compressed_lines = LE_16(&encoded[stream_ptr]); | |
181 stream_ptr += 2; | |
182 while (compressed_lines > 0) | |
183 { | |
184 pixel_ptr = y_ptr; | |
185 line_packets = encoded[stream_ptr++]; | |
186 if (line_packets > 0) | |
187 { | |
188 for (i = 0; i < line_packets; i++) | |
189 { | |
190 // account for the skip bytes | |
3185 | 191 pixel_ptr += encoded[stream_ptr++] * bytes_per_pixel; |
3155 | 192 byte_run = encoded[stream_ptr++]; |
193 if (byte_run > 0) | |
194 { | |
195 for (j = 0; j < byte_run; j++) | |
196 { | |
197 palette_ptr1 = encoded[stream_ptr++] * 4; | |
198 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
199 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
200 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 201 if (bytes_per_pixel == 4) /* 32bpp */ |
202 pixel_ptr++; | |
3155 | 203 } |
204 } | |
205 else | |
206 { | |
207 byte_run = -byte_run; | |
208 palette_ptr1 = encoded[stream_ptr++] * 4; | |
209 for (j = 0; j < byte_run; j++) | |
210 { | |
211 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
212 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
213 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 214 if (bytes_per_pixel == 4) /* 32bpp */ |
215 pixel_ptr++; | |
3155 | 216 } |
217 } | |
218 } | |
219 } | |
220 | |
221 y_ptr += line_inc; | |
222 compressed_lines--; | |
223 } | |
224 break; | |
225 | |
226 case FLI_BLACK: | |
227 // set the whole frame to color 0 (which is usually black) | |
3185 | 228 for (pixel_ptr = 0; pixel_ptr < (width * height * bytes_per_pixel); pixel_ptr++) |
3155 | 229 { |
230 decoded[pixel_ptr++] = palette[0]; | |
231 decoded[pixel_ptr++] = palette[1]; | |
232 decoded[pixel_ptr++] = palette[2]; | |
3185 | 233 if (bytes_per_pixel == 4) /* 32bpp */ |
234 pixel_ptr++; | |
3155 | 235 } |
236 break; | |
237 | |
238 case FLI_BRUN: | |
239 // byte run compression | |
240 line_inc = width * bytes_per_pixel; | |
241 y_ptr = 0; | |
242 for (lines = 0; lines < height; lines++) | |
243 { | |
244 pixel_ptr = y_ptr; | |
245 line_packets = encoded[stream_ptr++]; | |
246 for (i = 0; i < line_packets; i++) | |
247 { | |
248 byte_run = encoded[stream_ptr++]; | |
249 if (byte_run > 0) | |
250 { | |
251 palette_ptr1 = encoded[stream_ptr++] * 4; | |
252 for (j = 0; j < byte_run; j++) | |
253 { | |
254 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
255 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
256 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 257 if (bytes_per_pixel == 4) /* 32bpp */ |
258 pixel_ptr++; | |
3155 | 259 } |
260 } | |
261 else // copy bytes if byte_run < 0 | |
262 { | |
263 byte_run = -byte_run; | |
264 for (j = 0; j < byte_run; j++) | |
265 { | |
266 palette_ptr1 = encoded[stream_ptr++] * 4; | |
267 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; | |
268 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; | |
269 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; | |
3185 | 270 if (bytes_per_pixel == 4) /* 32bpp */ |
271 pixel_ptr++; | |
3155 | 272 } |
273 } | |
274 } | |
275 | |
276 y_ptr += line_inc; | |
277 } | |
278 break; | |
279 | |
280 case FLI_COPY: | |
3509
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
281 // copy the chunk (uncompressed frame) |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
282 for (pixel_ptr = 0; pixel_ptr < chunk_size - 6; pixel_ptr++) |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
283 { |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
284 palette_ptr1 = encoded[stream_ptr++] * 4; |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
285 decoded[pixel_ptr++] = palette[palette_ptr1 + 0]; |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
286 decoded[pixel_ptr++] = palette[palette_ptr1 + 1]; |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
287 decoded[pixel_ptr++] = palette[palette_ptr1 + 2]; |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
288 if (bytes_per_pixel == 4) /* 32bpp */ |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
289 pixel_ptr++; |
21c7b77b3e83
fixed endian-ness for FLI and MS Video 1 decoders; fixed padding bug in
melanson
parents:
3185
diff
changeset
|
290 } |
3155 | 291 break; |
292 | |
293 case FLI_MINI: | |
294 // sort of a thumbnail? disregard this chunk... | |
295 stream_ptr += chunk_size - 6; | |
296 break; | |
297 | |
298 default: | |
299 printf ("FLI: Unrecognized chunk type: %d\n", chunk_type); | |
300 break; | |
301 } | |
302 | |
303 frame_size -= chunk_size; | |
304 num_chunks--; | |
305 } | |
306 } |