2 * $Logfile: /Freespace2/src/movie/decoder16.cpp $
7 * 16-bit frame decoder for MVEs
10 * Revision 1.2 2005/03/29 07:50:34 taylor
11 * Update to newest movie code with much better video support and audio support from
12 * Pierre Willenbrock. Movies are enabled always now (no longer a build option)
13 * and but can be skipped with the "--nomovies" or "-n" cmdline options.
23 extern int g_width, g_height;
24 extern void *g_vBackBuf1, *g_vBackBuf2;
26 /* 16 bit decoding routines */
28 static ushort *backBuf1, *backBuf2;
29 static int lookup_initialized;
31 static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb);
32 static void genLoopkupTable();
34 void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
37 unsigned char *pOffData, *pEnd;
44 if (!lookup_initialized) {
48 backBuf1 = (ushort *)g_vBackBuf1;
49 backBuf2 = (ushort *)g_vBackBuf2;
54 offset = pData[0]|(pData[1]<<8);
56 pOffData = pData + offset;
57 pEnd = pData + offset;
62 length = offset - 2; /*dataRemain-2;*/
64 for (j=0; j<yb; j++) {
65 for (i=0; i<xb/2; i++) {
67 dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
70 if ((ushort *)pFrame < backBuf1)
71 fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
72 else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
73 fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
76 op = ((*pMap) >> 4) & 0xf;
77 dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
80 if ((ushort *)pFrame < backBuf1)
81 fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
82 else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
83 fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
90 pFrame += 7*g_width*2;
93 if ((length-(pData-pOrig)) != 0) {
94 nprintf(("MVE", "DEBUG: junk left over: %d,%d,%d\n", (pData-pOrig), length, (length-(pData-pOrig))));
98 static ushort GETPIXEL(unsigned char **buf, int off)
100 ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
104 static ushort GETPIXELI(unsigned char **buf, int off)
106 ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
111 static void relClose(int i, int *x, int *y)
122 static void relFar(int i, int sign, int *x, int *y)
125 *x = sign * (8 + (i % 7));
128 *x = sign * (-14 + (i - 56) % 29);
129 *y = sign * (8 + (i - 56) / 29);
133 static int close_table[512];
134 static int far_p_table[512];
135 static int far_n_table[512];
137 static void genLoopkupTable()
142 for (i = 0; i < 256; i++) {
145 close_table[i*2+0] = x;
146 close_table[i*2+1] = y;
148 relFar(i, 1, &x, &y);
150 far_p_table[i*2+0] = x;
151 far_p_table[i*2+1] = y;
153 relFar(i, -1, &x, &y);
155 far_n_table[i*2+0] = x;
156 far_n_table[i*2+1] = y;
159 lookup_initialized = 1;
162 static void copyFrame(ushort *pDest, ushort *pSrc)
166 for (i=0; i<8; i++) {
167 memcpy(pDest, pSrc, 16);
173 static void patternRow4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
177 ushort pattern = (pat1 << 8) | pat0;
180 *pFrame++ = p[(mask & pattern) >> shift];
186 static void patternRow4Pixels2(ushort *pFrame, unsigned char pat0, ushort *p)
188 unsigned char mask=0x03;
189 unsigned char shift=0;
191 /* ORIGINAL VERSION IS BUGGY
195 pel = p[(mask & pat0) >> shift];
198 pFrame[g_width + 0] = pel;
199 pFrame[g_width + 2] = pel;
207 pel = p[(mask & pat0) >> shift];
210 pFrame[g_width + 0] = pel;
211 pFrame[g_width + 1] = pel;
218 static void patternRow4Pixels2x1(ushort *pFrame, unsigned char pat, ushort *p)
220 unsigned char mask=0x03;
221 unsigned char shift=0;
225 pel = p[(mask & pat) >> shift];
234 static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, ushort *p)
236 unsigned long mask = 0x00000003UL;
239 unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
241 for (i=0; i<16; i++) {
242 pFrame[i&3] = p[(pat & mask) >> shift];
252 static void patternRow2Pixels(ushort *pFrame, unsigned char pat, ushort *p)
254 unsigned char mask=0x01;
257 *pFrame++ = p[(mask & pat) ? 1 : 0];
262 static void patternRow2Pixels2(ushort *pFrame, unsigned char pat, ushort *p)
265 unsigned char mask=0x1;
267 /* ORIGINAL VERSION IS BUGGY
269 while (mask != 0x10) {
270 pel = p[(mask & pat) ? 1 : 0];
273 pFrame[g_width + 0] = pel;
274 pFrame[g_width + 2] = pel;
280 while (mask != 0x10) {
281 pel = p[(mask & pat) ? 1 : 0];
285 pFrame[g_width + 0] = pel;
286 pFrame[g_width + 1] = pel;
293 static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
295 ushort mask = 0x0001;
297 ushort pat = (pat1 << 8) | pat0;
299 for (i=0; i<16; i++) {
300 pFrame[i&3] = p[(pat & mask) ? 1 : 0];
310 static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb)
313 unsigned char pat[16];
322 copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
329 /* relFar(*(*pOffData)++, 1, &x, &y); */
332 x = far_p_table[k*2+0];
333 y = far_p_table[k*2+1];
335 copyFrame(*pFrame, *pFrame + x + y*g_width);
340 /* relFar(*(*pOffData)++, -1, &x, &y); */
343 x = far_n_table[k*2+0];
344 y = far_n_table[k*2+1];
346 copyFrame(*pFrame, *pFrame + x + y*g_width);
351 /* relClose(*(*pOffData)++, &x, &y); */
354 x = close_table[k*2+0];
355 y = close_table[k*2+1];
357 copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
362 x = (char)*(*pData)++;
363 y = (char)*(*pData)++;
364 copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
369 nprintf(("MVE", "STUB: encoding 6 not tested\n"));
371 for (i=0; i<2; i++) {
374 if (++*curXb == (g_width >> 3)) {
375 *pFrame += 7*g_width;
378 if (++*curYb == (g_height >> 3))
385 p[0] = GETPIXELI(pData, 0);
386 p[1] = GETPIXELI(pData, 0);
388 if (!((p[0]/*|p[1]*/)&0x8000)) {
389 for (i=0; i<8; i++) {
390 patternRow2Pixels(*pFrame, *(*pData), p);
396 for (i=0; i<2; i++) {
397 patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
398 *pFrame += 2*g_width;
399 patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
402 *pFrame += 2*g_width;
408 p[0] = GETPIXEL(pData, 0);
410 if (!(p[0] & 0x8000)) {
411 for (i=0; i<4; i++) {
412 p[0] = GETPIXELI(pData, 0);
413 p[1] = GETPIXELI(pData, 0);
415 pat[0] = (*pData)[0];
416 pat[1] = (*pData)[1];
419 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
422 *pFrame -= (4*g_width - 4);
424 *pFrame += 4*g_width;
428 p[2] = GETPIXEL(pData, 8);
430 if (!(p[2]&0x8000)) {
431 for (i=0; i<4; i++) {
433 p[0] = GETPIXELI(pData, 0);
434 p[1] = GETPIXELI(pData, 0);
436 pat[0] = *(*pData)++;
437 pat[1] = *(*pData)++;
438 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
441 *pFrame -= (4*g_width - 4);
443 *pFrame += 4*g_width;
447 for (i=0; i<8; i++) {
449 p[0] = GETPIXELI(pData, 0);
450 p[1] = GETPIXELI(pData, 0);
452 patternRow2Pixels(*pFrame, *(*pData), p);
462 p[0] = GETPIXELI(pData, 0);
463 p[1] = GETPIXELI(pData, 0);
464 p[2] = GETPIXELI(pData, 0);
465 p[3] = GETPIXELI(pData, 0);
469 if (!(p[0] & 0x8000)) {
470 if (!(p[2] & 0x8000)) {
471 for (i=0; i<8; i++) {
472 pat[0] = (*pData)[0];
473 pat[1] = (*pData)[1];
475 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
480 patternRow4Pixels2(*pFrame, (*pData)[0], p);
481 *pFrame += 2*g_width;
482 patternRow4Pixels2(*pFrame, (*pData)[1], p);
483 *pFrame += 2*g_width;
484 patternRow4Pixels2(*pFrame, (*pData)[2], p);
485 *pFrame += 2*g_width;
486 patternRow4Pixels2(*pFrame, (*pData)[3], p);
492 if (!(p[2] & 0x8000)) {
493 for (i=0; i<8; i++) {
494 pat[0] = (*pData)[0];
496 patternRow4Pixels2x1(*pFrame, pat[0], p);
501 for (i=0; i<4; i++) {
502 pat[0] = (*pData)[0];
503 pat[1] = (*pData)[1];
507 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
509 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
518 p[0] = GETPIXEL(pData, 0);
520 if (!(p[0] & 0x8000)) {
521 for (i=0; i<4; i++) {
522 p[0] = GETPIXELI(pData, 0);
523 p[1] = GETPIXELI(pData, 0);
524 p[2] = GETPIXELI(pData, 0);
525 p[3] = GETPIXELI(pData, 0);
526 pat[0] = (*pData)[0];
527 pat[1] = (*pData)[1];
528 pat[2] = (*pData)[2];
529 pat[3] = (*pData)[3];
533 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
536 *pFrame -= (4*g_width - 4);
538 *pFrame += 4*g_width;
542 p[0] = GETPIXEL(pData, 16);
544 if (!(p[0] & 0x8000)) {
545 for (i=0; i<4; i++) {
547 p[0] = GETPIXELI(pData, 0);
548 p[1] = GETPIXELI(pData, 0);
549 p[2] = GETPIXELI(pData, 0);
550 p[3] = GETPIXELI(pData, 0);
553 pat[0] = (*pData)[0];
554 pat[1] = (*pData)[1];
555 pat[2] = (*pData)[2];
556 pat[3] = (*pData)[3];
560 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
563 *pFrame -= (4*g_width - 4);
565 *pFrame += 4*g_width;
569 for (i=0; i<8; i++) {
571 p[0] = GETPIXELI(pData, 0);
572 p[1] = GETPIXELI(pData, 0);
573 p[2] = GETPIXELI(pData, 0);
574 p[3] = GETPIXELI(pData, 0);
577 pat[0] = (*pData)[0];
578 pat[1] = (*pData)[1];
579 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
589 for (i=0; i<8; i++) {
590 memcpy(*pFrame, *pData, 16);
598 for (i=0; i<4; i++) {
599 p[0] = GETPIXEL(pData, 0);
600 p[1] = GETPIXEL(pData, 2);
601 p[2] = GETPIXEL(pData, 4);
602 p[3] = GETPIXEL(pData, 6);
604 /* for (j=0; j<2; j++) {
605 for (k=0; k<4; k++) {
606 (*pFrame)[2*k] = p[k];
607 (*pFrame)[2*k+1] = p[k];
612 for (k=0; k<4; k++) {
613 (*pFrame)[0+2*k] = p[k];
614 (*pFrame)[g_width+0+2*k] = p[k];
615 (*pFrame)[1+2*k] = p[k];
616 (*pFrame)[g_width+1+2*k] = p[k];
619 *pFrame += 2*g_width;
627 for (i=0; i<2; i++) {
628 p[0] = GETPIXEL(pData, 0);
629 p[1] = GETPIXEL(pData, 2);
631 for (j=0; j<4; j++) {
632 for (k=0; k<4; k++) {
633 (*pFrame)[k*g_width+j] = p[0];
634 (*pFrame)[k*g_width+j+4] = p[1];
638 *pFrame += 4*g_width;
646 p[0] = GETPIXEL(pData, 0);
648 for (i = 0; i < 8; i++) {
649 for (j = 0; j < 8; j++) {
662 p[0] = GETPIXEL(pData, 0);
663 p[1] = GETPIXEL(pData, 1);
665 for (i=0; i<8; i++) {
666 for (j=0; j<8; j++) {
667 (*pFrame)[j] = p[(i+j)&1];