Some "cast to pointer from integer of different size" warnings removed.
[AROS-Contrib.git] / MultiMedia / AMP2 / plugin / msvc / main.c
blob27e50a58856b8960fc1a81472b82d4dc00631d7e
1 /*
3 * main.c
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include <plugin.h>
14 Microsoft Video 1 Decoder
16 (C) 2001 Mike Melanson
18 The description of the algorithm you can read here:
19 http://www.pcisys.net/~melanson/codecs/
21 Heavily optimized by Mathias "AmiDog" Roslund
24 #define LE_16(val) ({ unsigned short x = *(unsigned short *)(val); x = (x << 8) | (x >> 8); x; })
26 #define RGB555_TO_RGB888(argb, c) \
27 argb = ((c & 0x7c00) << 9) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 3);
29 #define DECODE_RGB555_TO_RGB888(x) \
30 RGB555_TO_RGB888(x.argb[1], x.c1); \
31 RGB555_TO_RGB888(x.argb[0], x.c2);
33 #define CRAM16(x, y) \
34 *(unsigned long *)&decoded[pixel_ptr] = quad[x][y].argb[flags & 1]; \
35 pixel_ptr += 4; \
36 flags >>= 1;
38 #define CRAM8(x, y) \
39 decoded[pixel_ptr++] = quad[x][y].b[flags & 1]; \
40 flags >>= 1;
42 static struct {
43 unsigned short c1, c2;
44 unsigned long argb[2];
45 unsigned char b[2];
46 } quad[2][2];
48 void AVI_Decode_Video1_16(unsigned char *encoded, int encoded_size, unsigned char *decoded, int width, int height)
50 int block_ptr, pixel_ptr;
51 int total_blocks;
52 int pixel_y; // pixel height iterator
53 int block_x, block_y; // block width and height iterators
54 int blocks_wide, blocks_high; // width and height in 4x4 blocks
55 int block_inc;
56 int row_dec;
58 // decoding parameters
59 int stream_ptr;
60 unsigned char byte_a, byte_b;
61 unsigned short flags;
62 int skip_blocks;
64 stream_ptr = 0;
65 skip_blocks = 0;
66 blocks_wide = width / 4;
67 blocks_high = height / 4;
68 total_blocks = blocks_wide * blocks_high;
69 block_inc = 4 * 4;
70 row_dec = (width + 4) * 4;
72 for (block_y = blocks_high; block_y > 0; block_y--)
74 block_ptr = ((block_y * 4) - 1) * (width * 4);
75 for (block_x = blocks_wide; block_x > 0; block_x--)
77 // check if this block should be skipped
78 if (skip_blocks > 0)
80 block_ptr += block_inc;
81 skip_blocks--;
82 total_blocks--;
83 continue;
86 pixel_ptr = block_ptr;
88 // get the next two bytes in the encoded data stream
89 byte_a = encoded[stream_ptr++];
90 byte_b = encoded[stream_ptr++];
92 // check if the decode is finished
93 if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
94 return;
96 // check if this is a skip code
97 else if ((byte_b & 0xFC) == 0x84)
99 // but don't count the current block
100 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
103 // check if this is in the 2- or 8-color classes
104 else if (byte_b < 0x80)
106 flags = (byte_b << 8) | byte_a;
108 quad[0][0].c1 = LE_16(&encoded[stream_ptr]);
109 stream_ptr += 2;
110 quad[0][0].c2 = LE_16(&encoded[stream_ptr]);
111 stream_ptr += 2;
113 DECODE_RGB555_TO_RGB888(quad[0][0]);
115 if (quad[0][0].c1 & 0x8000)
117 // 8-color encoding
118 quad[1][0].c1 = LE_16(&encoded[stream_ptr]);
119 stream_ptr += 2;
120 quad[1][0].c2 = LE_16(&encoded[stream_ptr]);
121 stream_ptr += 2;
122 quad[0][1].c1 = LE_16(&encoded[stream_ptr]);
123 stream_ptr += 2;
124 quad[0][1].c2 = LE_16(&encoded[stream_ptr]);
125 stream_ptr += 2;
126 quad[1][1].c1 = LE_16(&encoded[stream_ptr]);
127 stream_ptr += 2;
128 quad[1][1].c2 = LE_16(&encoded[stream_ptr]);
129 stream_ptr += 2;
131 DECODE_RGB555_TO_RGB888(quad[0][1]);
132 DECODE_RGB555_TO_RGB888(quad[1][0]);
133 DECODE_RGB555_TO_RGB888(quad[1][1]);
135 for (pixel_y = 0; pixel_y < 4; pixel_y++)
137 CRAM16(0, pixel_y >> 1);
138 CRAM16(0, pixel_y >> 1);
139 CRAM16(1, pixel_y >> 1);
140 CRAM16(1, pixel_y >> 1);
141 pixel_ptr -= row_dec;
144 else
146 // 2-color encoding
147 for (pixel_y = 0; pixel_y < 4; pixel_y++)
149 CRAM16(0, 0);
150 CRAM16(0, 0);
151 CRAM16(0, 0);
152 CRAM16(0, 0);
153 pixel_ptr -= row_dec;
158 // otherwise, it's a 1-color block
159 else
161 unsigned long argb, c;
163 c = (byte_b << 8) | byte_a;
164 RGB555_TO_RGB888(argb, c);
166 for (pixel_y = 0; pixel_y < 4; pixel_y++)
168 *(unsigned long *)&decoded[pixel_ptr] = argb;
169 pixel_ptr += 4;
170 *(unsigned long *)&decoded[pixel_ptr] = argb;
171 pixel_ptr += 4;
172 *(unsigned long *)&decoded[pixel_ptr] = argb;
173 pixel_ptr += 4;
174 *(unsigned long *)&decoded[pixel_ptr] = argb;
175 pixel_ptr += 4;
176 pixel_ptr -= row_dec;
180 block_ptr += block_inc;
181 total_blocks--;
186 void AVI_Decode_Video1_8(unsigned char *encoded, int encoded_size, unsigned char *decoded, int width, int height)
188 int block_ptr, pixel_ptr;
189 int total_blocks;
190 int pixel_y; // pixel height iterator
191 int block_x, block_y; // block width and height iterators
192 int blocks_wide, blocks_high; // width and height in 4x4 blocks
193 int block_inc;
194 int row_dec;
196 // decoding parameters
197 int stream_ptr;
198 unsigned char byte_a, byte_b;
199 unsigned short flags;
200 int skip_blocks;
202 stream_ptr = 0;
203 skip_blocks = 0;
204 blocks_wide = width / 4;
205 blocks_high = height / 4;
206 total_blocks = blocks_wide * blocks_high;
207 block_inc = 4 * 1;
208 row_dec = (width + 4) * 1;
210 for (block_y = blocks_high; block_y > 0; block_y--)
212 block_ptr = ((block_y * 4) - 1) * (width * 1);
213 for (block_x = blocks_wide; block_x > 0; block_x--)
215 // check if this block should be skipped
216 if (skip_blocks > 0)
218 block_ptr += block_inc;
219 skip_blocks--;
220 total_blocks--;
221 continue;
224 pixel_ptr = block_ptr;
226 // get the next two bytes in the encoded data stream
227 byte_a = encoded[stream_ptr++];
228 byte_b = encoded[stream_ptr++];
230 // check if the decode is finished
231 if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
232 return;
234 // check if this is a skip code
235 else if ((byte_b & 0xFC) == 0x84)
237 // but don't count the current block
238 skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
241 // check if this is a 2-color block
242 else if (byte_b < 0x80)
244 flags = (byte_b << 8) | byte_a;
246 quad[0][0].b[1] = encoded[stream_ptr++];
247 quad[0][0].b[0] = encoded[stream_ptr++];
249 // 2-color encoding
250 for (pixel_y = 0; pixel_y < 4; pixel_y++)
252 CRAM8(0, 0);
253 CRAM8(0, 0);
254 CRAM8(0, 0);
255 CRAM8(0, 0);
256 pixel_ptr -= row_dec;
260 // check if it's an 8-color block
261 else if (byte_b >= 0x90)
263 flags = (byte_b << 8) | byte_a;
265 quad[0][0].b[1] = encoded[stream_ptr++];
266 quad[0][0].b[0] = encoded[stream_ptr++];
267 quad[1][0].b[1] = encoded[stream_ptr++];
268 quad[1][0].b[0] = encoded[stream_ptr++];
270 quad[0][1].b[1] = encoded[stream_ptr++];
271 quad[0][1].b[0] = encoded[stream_ptr++];
272 quad[1][1].b[1] = encoded[stream_ptr++];
273 quad[1][1].b[0] = encoded[stream_ptr++];
275 for (pixel_y = 0; pixel_y < 4; pixel_y++)
277 CRAM8(0, pixel_y >> 1);
278 CRAM8(0, pixel_y >> 1);
279 CRAM8(1, pixel_y >> 1);
280 CRAM8(1, pixel_y >> 1);
281 pixel_ptr -= row_dec;
285 // otherwise, it's a 1-color block
286 else
288 unsigned long c;
290 c = byte_a | (byte_a << 8);
291 c = c | (c << 16);
293 *(unsigned long *)&decoded[pixel_ptr] = c;
294 pixel_ptr += 4;
295 pixel_ptr -= row_dec;
297 *(unsigned long *)&decoded[pixel_ptr] = c;
298 pixel_ptr += 4;
299 pixel_ptr -= row_dec;
301 *(unsigned long *)&decoded[pixel_ptr] = c;
302 pixel_ptr += 4;
303 pixel_ptr -= row_dec;
305 *(unsigned long *)&decoded[pixel_ptr] = c;
306 pixel_ptr += 4;
307 pixel_ptr -= row_dec;
310 block_ptr += block_inc;
311 total_blocks--;
316 static unsigned char *buffer = NULL;
318 static int video_w, video_h;
319 static int msvc_error = 0;
321 static double current_time = 0.0;
322 static double current_frame_time = 0.0;
323 static double current_video_time = 0.0;
325 int decode_msvc(unsigned char *buf, unsigned long length, double sync_time)
327 if (msvc_error != 0) {
328 return PLUGIN_FAIL;
331 if (length > 0) {
332 if (amp->depth == 8) {
333 AVI_Decode_Video1_8(buf, length, buffer, video_w, video_h);
334 } else {
335 AVI_Decode_Video1_16(buf, length, buffer, video_w, video_h);
338 if (sync_time > 0.0) {
339 current_time = sync_time;
342 amp->video_refresh(&buffer, current_time, current_video_time);
343 amp->total_frames++;
345 current_time += current_frame_time;
346 current_video_time += current_frame_time;
349 return PLUGIN_OK;
352 int init_msvc(unsigned long type, unsigned long fourcc)
354 int width, height;
356 width = amp->width;
357 height = amp->height;
359 buffer = malloc(width * height * 4);
360 memset(buffer, 0, width * height * 4);
362 video_w = width;
363 video_h = height;
365 amp->total_frames = 0;
366 amp->skiped_frames = 0;
368 msvc_error = 0;
370 current_time = 0.0;
371 current_frame_time = 1.0 / amp->framerate;
372 current_video_time = 0.0;
374 if (amp->depth == 8) {
375 if (amp->video_init(width, height, width, CMODE_CHUNKY) != PLUGIN_OK) {
376 msvc_error = 1;
377 return PLUGIN_FAIL;
379 } else {
380 if (amp->video_init(width, height, width, CMODE_ARGB32) != PLUGIN_OK) {
381 msvc_error = 1;
382 return PLUGIN_FAIL;
386 return PLUGIN_OK;
389 int exit_msvc(void)
391 if (buffer != NULL) {
392 free(buffer);
393 buffer = NULL;
396 return PLUGIN_OK;
399 VERSION("MSVC v1.01 (020520)");
401 IDENT_INIT
402 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_MSVC, init_msvc, decode_msvc, exit_msvc)
403 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_msvc, init_msvc, decode_msvc, exit_msvc)
404 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_CRAM, init_msvc, decode_msvc, exit_msvc)
405 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_cram, init_msvc, decode_msvc, exit_msvc)
406 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_WHAM, init_msvc, decode_msvc, exit_msvc)
407 IDENT_ADD((TYPE_VIDEO | SUBTYPE_NONE), FOURCC_wham, init_msvc, decode_msvc, exit_msvc)
408 IDENT_EXIT