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