Mercurial > mplayer.hg
comparison msvidc.c @ 2827:b4d46817f050
ms video1 (cram) codecs by Mike Melanson <melanson@pcisys.net>
author | arpi |
---|---|
date | Sun, 11 Nov 2001 13:35:00 +0000 |
parents | |
children | 6b69f306cf6e |
comparison
equal
deleted
inserted
replaced
2826:17f46b2330e9 | 2827:b4d46817f050 |
---|---|
1 | |
2 #define LE_16(x) *(unsigned short *)(x) | |
3 | |
4 #define DECODE_BGR555_TO_BGR888(x) \ | |
5 x.c1_b = (x.c1 >> 7) & 0xF8; \ | |
6 x.c1_g = (x.c1 >> 2) & 0xF8; \ | |
7 x.c1_r = (x.c1 << 3) & 0xF8; \ | |
8 x.c2_b = (x.c2 >> 7) & 0xF8; \ | |
9 x.c2_g = (x.c2 >> 2) & 0xF8; \ | |
10 x.c2_r = (x.c2 << 3) & 0xF8; | |
11 | |
12 #define DECODE_PALETTE_TO_BGR888(x) \ | |
13 x.c1_b = palette_map[x.c1 * 4 + 2]; \ | |
14 x.c1_g = palette_map[x.c1 * 4 + 1]; \ | |
15 x.c1_r = palette_map[x.c1 * 4 + 0]; \ | |
16 x.c2_b = palette_map[x.c2 * 4 + 2]; \ | |
17 x.c2_g = palette_map[x.c2 * 4 + 1]; \ | |
18 x.c2_r = palette_map[x.c2 * 4 + 0]; | |
19 | |
20 struct | |
21 { | |
22 unsigned short c1, c2; | |
23 unsigned char c1_r, c1_g, c1_b; | |
24 unsigned char c2_r, c2_g, c2_b; | |
25 } quad[2][2]; | |
26 | |
27 void AVI_Decode_Video1_16( | |
28 char *encoded, | |
29 int encoded_size, | |
30 char *decoded, | |
31 int width, | |
32 int height, | |
33 int bytes_per_pixel) | |
34 { | |
35 int block_ptr, pixel_ptr; | |
36 int pixel_x, pixel_y; // pixel width and height iterators | |
37 int block_x, block_y; // block width and height iterators | |
38 int blocks_wide, blocks_high; // width and height in 4x4 blocks | |
39 int block_inc; | |
40 int row_dec; | |
41 | |
42 // decoding parameters | |
43 int stream_ptr; | |
44 unsigned char byte_a, byte_b; | |
45 unsigned short flags; | |
46 int skip_blocks; | |
47 | |
48 stream_ptr = 0; | |
49 skip_blocks = 0; | |
50 blocks_wide = width / 4; | |
51 blocks_high = height / 4; | |
52 block_inc = 4 * bytes_per_pixel; | |
53 row_dec = (width + 4) * bytes_per_pixel; | |
54 | |
55 for (block_y = blocks_high; block_y > 0; block_y--) | |
56 { | |
57 block_ptr = ((block_y * 4) - 1) * (width * bytes_per_pixel); | |
58 for (block_x = blocks_wide; block_x > 0; block_x--) | |
59 { | |
60 // check if this block should be skipped | |
61 if (skip_blocks) | |
62 { | |
63 block_ptr += block_inc; | |
64 skip_blocks--; | |
65 continue; | |
66 } | |
67 | |
68 pixel_ptr = block_ptr; | |
69 | |
70 // get the next two bytes in the encoded data stream | |
71 byte_a = encoded[stream_ptr++]; | |
72 byte_b = encoded[stream_ptr++]; | |
73 | |
74 // check if the decode is finished | |
75 if ((byte_a == 0) && (byte_b == 0)) | |
76 return; | |
77 | |
78 // check if this is a skip code | |
79 else if ((byte_b & 0xFC) == 0x84) | |
80 { | |
81 // but don't count the current block | |
82 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1; | |
83 } | |
84 | |
85 // check if this is in the 2- or 8-color classes | |
86 else if (byte_b < 0x80) | |
87 { | |
88 flags = (byte_b << 8) | byte_a; | |
89 | |
90 quad[0][0].c1 = LE_16(&encoded[stream_ptr]); | |
91 stream_ptr += 2; | |
92 quad[0][0].c2 = LE_16(&encoded[stream_ptr]); | |
93 stream_ptr += 2; | |
94 | |
95 DECODE_BGR555_TO_BGR888(quad[0][0]); | |
96 | |
97 if (quad[0][0].c1 & 0x8000) | |
98 { | |
99 // 8-color encoding | |
100 quad[1][0].c1 = LE_16(&encoded[stream_ptr]); | |
101 stream_ptr += 2; | |
102 quad[1][0].c2 = LE_16(&encoded[stream_ptr]); | |
103 stream_ptr += 2; | |
104 quad[0][1].c1 = LE_16(&encoded[stream_ptr]); | |
105 stream_ptr += 2; | |
106 quad[0][1].c2 = LE_16(&encoded[stream_ptr]); | |
107 stream_ptr += 2; | |
108 quad[1][1].c1 = LE_16(&encoded[stream_ptr]); | |
109 stream_ptr += 2; | |
110 quad[1][1].c2 = LE_16(&encoded[stream_ptr]); | |
111 stream_ptr += 2; | |
112 | |
113 DECODE_BGR555_TO_BGR888(quad[0][1]); | |
114 DECODE_BGR555_TO_BGR888(quad[1][0]); | |
115 DECODE_BGR555_TO_BGR888(quad[1][1]); | |
116 | |
117 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
118 { | |
119 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
120 { | |
121 if (flags & 1) | |
122 { | |
123 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_r; | |
124 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_g; | |
125 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_b; | |
126 } | |
127 else | |
128 { | |
129 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_r; | |
130 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_g; | |
131 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_b; | |
132 } | |
133 | |
134 // get the next flag ready to go | |
135 flags >>= 1; | |
136 } | |
137 pixel_ptr -= row_dec; | |
138 } | |
139 } | |
140 else | |
141 { | |
142 // 2-color encoding | |
143 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
144 { | |
145 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
146 { | |
147 if (flags & 1) | |
148 { | |
149 decoded[pixel_ptr++] = quad[0][0].c1_r; | |
150 decoded[pixel_ptr++] = quad[0][0].c1_g; | |
151 decoded[pixel_ptr++] = quad[0][0].c1_b; | |
152 } | |
153 else | |
154 { | |
155 decoded[pixel_ptr++] = quad[0][0].c2_r; | |
156 decoded[pixel_ptr++] = quad[0][0].c2_g; | |
157 decoded[pixel_ptr++] = quad[0][0].c2_b; | |
158 } | |
159 | |
160 // get the next flag ready to go | |
161 flags >>= 1; | |
162 } | |
163 pixel_ptr -= row_dec; | |
164 } | |
165 } | |
166 } | |
167 | |
168 // otherwise, it's a 1-color block | |
169 else | |
170 { | |
171 quad[0][0].c1 = (byte_b << 8) | byte_a; | |
172 DECODE_BGR555_TO_BGR888(quad[0][0]); | |
173 | |
174 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
175 { | |
176 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
177 { | |
178 decoded[pixel_ptr++] = quad[0][0].c1_r; | |
179 decoded[pixel_ptr++] = quad[0][0].c1_g; | |
180 decoded[pixel_ptr++] = quad[0][0].c1_b; | |
181 } | |
182 pixel_ptr -= row_dec; | |
183 } | |
184 } | |
185 | |
186 block_ptr += block_inc; | |
187 } | |
188 } | |
189 } | |
190 | |
191 void AVI_Decode_Video1_8( | |
192 char *encoded, | |
193 int encoded_size, | |
194 char *decoded, | |
195 int width, | |
196 int height, | |
197 unsigned char *palette_map, | |
198 int bytes_per_pixel) | |
199 { | |
200 int block_ptr, pixel_ptr; | |
201 int pixel_x, pixel_y; // pixel width and height iterators | |
202 int block_x, block_y; // block width and height iterators | |
203 int blocks_wide, blocks_high; // width and height in 4x4 blocks | |
204 int block_inc; | |
205 int row_dec; | |
206 | |
207 // decoding parameters | |
208 int stream_ptr; | |
209 unsigned char byte_a, byte_b; | |
210 unsigned short flags; | |
211 int skip_blocks; | |
212 | |
213 stream_ptr = 0; | |
214 skip_blocks = 0; | |
215 blocks_wide = width / 4; | |
216 blocks_high = height / 4; | |
217 block_inc = 4 * bytes_per_pixel; | |
218 row_dec = (width + 4) * bytes_per_pixel; | |
219 | |
220 for (block_y = blocks_high; block_y > 0; block_y--) | |
221 { | |
222 block_ptr = ((block_y * 4) - 1) * (width * bytes_per_pixel); | |
223 for (block_x = blocks_wide; block_x > 0; block_x--) | |
224 { | |
225 // check if this block should be skipped | |
226 if (skip_blocks) | |
227 { | |
228 block_ptr += block_inc; | |
229 skip_blocks--; | |
230 continue; | |
231 } | |
232 | |
233 pixel_ptr = block_ptr; | |
234 | |
235 // get the next two bytes in the encoded data stream | |
236 byte_a = encoded[stream_ptr++]; | |
237 byte_b = encoded[stream_ptr++]; | |
238 | |
239 // check if the decode is finished | |
240 if ((byte_a == 0) && (byte_b == 0)) | |
241 return; | |
242 | |
243 // check if this is a skip code | |
244 else if ((byte_b & 0xFC) == 0x84) | |
245 { | |
246 // but don't count the current block | |
247 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1; | |
248 } | |
249 | |
250 // check if this is a 2-color block | |
251 else if (byte_b < 0x80) | |
252 { | |
253 flags = (byte_b << 8) | byte_a; | |
254 | |
255 quad[0][0].c1 = (unsigned char)encoded[stream_ptr++]; | |
256 quad[0][0].c2 = (unsigned char)encoded[stream_ptr++]; | |
257 | |
258 DECODE_PALETTE_TO_BGR888(quad[0][0]); | |
259 | |
260 // 2-color encoding | |
261 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
262 { | |
263 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
264 { | |
265 if (flags & 1) | |
266 { | |
267 decoded[pixel_ptr++] = quad[0][0].c1_r; | |
268 decoded[pixel_ptr++] = quad[0][0].c1_g; | |
269 decoded[pixel_ptr++] = quad[0][0].c1_b; | |
270 } | |
271 else | |
272 { | |
273 decoded[pixel_ptr++] = quad[0][0].c2_r; | |
274 decoded[pixel_ptr++] = quad[0][0].c2_g; | |
275 decoded[pixel_ptr++] = quad[0][0].c2_b; | |
276 } | |
277 | |
278 // get the next flag ready to go | |
279 flags >>= 1; | |
280 } | |
281 pixel_ptr -= row_dec; | |
282 } | |
283 } | |
284 | |
285 // check if it's an 8-color block | |
286 else if (byte_b >= 0x90) | |
287 { | |
288 // 8-color encoding | |
289 quad[0][0].c1 = (unsigned char)encoded[stream_ptr++]; | |
290 quad[0][0].c2 = (unsigned char)encoded[stream_ptr++]; | |
291 quad[1][0].c1 = (unsigned char)encoded[stream_ptr++]; | |
292 quad[1][0].c2 = (unsigned char)encoded[stream_ptr++]; | |
293 | |
294 quad[0][1].c1 = (unsigned char)encoded[stream_ptr++]; | |
295 quad[0][1].c2 = (unsigned char)encoded[stream_ptr++]; | |
296 quad[1][1].c1 = (unsigned char)encoded[stream_ptr++]; | |
297 quad[1][1].c2 = (unsigned char)encoded[stream_ptr++]; | |
298 | |
299 DECODE_PALETTE_TO_BGR888(quad[0][0]); | |
300 DECODE_PALETTE_TO_BGR888(quad[0][1]); | |
301 DECODE_PALETTE_TO_BGR888(quad[1][0]); | |
302 DECODE_PALETTE_TO_BGR888(quad[1][1]); | |
303 | |
304 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
305 { | |
306 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
307 { | |
308 if (flags & 1) | |
309 { | |
310 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_r; | |
311 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_g; | |
312 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c1_b; | |
313 } | |
314 else | |
315 { | |
316 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_r; | |
317 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_g; | |
318 decoded[pixel_ptr++] = quad[pixel_x >> 1][pixel_y >> 1].c2_b; | |
319 } | |
320 | |
321 // get the next flag ready to go | |
322 flags >>= 1; | |
323 } | |
324 pixel_ptr -= row_dec; | |
325 } | |
326 } | |
327 | |
328 // otherwise, it's a 1-color block | |
329 else | |
330 { | |
331 // init c2 along with c1 just so c2 is a known value for macro | |
332 quad[0][0].c1 = quad[0][0].c2 = byte_a; | |
333 DECODE_PALETTE_TO_BGR888(quad[0][0]); | |
334 | |
335 for (pixel_y = 0; pixel_y < 4; pixel_y++) | |
336 { | |
337 for (pixel_x = 0; pixel_x < 4; pixel_x++) | |
338 { | |
339 decoded[pixel_ptr++] = quad[0][0].c1_r; | |
340 decoded[pixel_ptr++] = quad[0][0].c1_g; | |
341 decoded[pixel_ptr++] = quad[0][0].c1_b; | |
342 } | |
343 pixel_ptr -= row_dec; | |
344 } | |
345 } | |
346 | |
347 block_ptr += block_inc; | |
348 } | |
349 } | |
350 } | |
351 |