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