]> icculus.org git repositories - taylor/freespace2.git/blob - src/movie/decoder16.cpp
Preliminary MVE code (Where's the soup now?!)
[taylor/freespace2.git] / src / movie / decoder16.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 extern int g_width, g_height;
6 extern void *g_vBackBuf1, *g_vBackBuf2;
7
8 /* 16 bit decoding routines */
9
10 static unsigned short *backBuf1, *backBuf2;
11 static int lookup_initialized;
12
13 static void dispatchDecoder16(unsigned short **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb);
14 static void genLoopkupTable();
15
16 void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
17 {
18     unsigned char *pOrig;
19     unsigned char *pOffData, *pEnd;
20     unsigned short offset;
21     int length;
22     int op;
23     int i, j;
24     int xb, yb;
25
26         if (!lookup_initialized) {
27                 genLoopkupTable();
28         }
29         
30     backBuf1 = (unsigned short *)g_vBackBuf1;
31     backBuf2 = (unsigned short *)g_vBackBuf2;
32         
33     xb = g_width >> 3;
34     yb = g_height >> 3;
35         
36     offset = pData[0]|(pData[1]<<8);
37     
38     pOffData = pData + offset;
39     pEnd = pData + offset;
40        
41     pData += 2;
42     
43     pOrig = pData;
44     length = offset - 2; /*dataRemain-2;*/
45     
46     for (j=0; j<yb; j++)
47     {
48         for (i=0; i<xb/2; i++)
49         {
50             op = (*pMap) & 0xf;
51             dispatchDecoder16((unsigned short **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
52
53 /*
54            if ((unsigned short *)pFrame < backBuf1)
55                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
56            else if ((unsigned short *)pFrame >= backBuf1 + g_width*g_height)
57                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
58 */
59
60             op = ((*pMap) >> 4) & 0xf;
61             dispatchDecoder16((unsigned short **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
62
63 /*
64             if ((unsigned short *)pFrame < backBuf1)
65                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
66             else if ((unsigned short *)pFrame >= backBuf1 + g_width*g_height)
67                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
68 */
69
70             ++pMap;
71             --mapRemain;
72         }
73
74         pFrame += 7*g_width*2;
75     }
76     
77     if ((length-(pData-pOrig)) != 0) {
78         fprintf(stderr, "DEBUG: junk left over: %d,%d,%d\n", (pData-pOrig), length, (length-(pData-pOrig)));
79     }
80 }
81
82 static unsigned short GETPIXEL(unsigned char **buf, int off)
83 {
84         unsigned short val = (*buf)[0+off] | ((*buf)[1+off] << 8);
85         return val;
86 }
87
88 static unsigned short GETPIXELI(unsigned char **buf, int off)
89 {
90         unsigned short val = (*buf)[0+off] | ((*buf)[1+off] << 8);
91         (*buf) += 2;
92         return val;
93 }
94
95 static void relClose(int i, int *x, int *y)
96 {
97     int ma, mi;
98
99     ma = i >> 4;
100     mi = i & 0xf;
101
102     *x = mi - 8;
103     *y = ma - 8;
104 }
105
106 static void relFar(int i, int sign, int *x, int *y)
107 {
108     if (i < 56)
109     {
110         *x = sign * (8 + (i % 7));
111         *y = sign *      (i / 7);
112     }
113     else
114     {
115         *x = sign * (-14 + (i - 56) % 29);
116         *y = sign *   (8 + (i - 56) / 29);
117     }
118 }
119
120 static int close_table[512];
121 static int far_p_table[512];
122 static int far_n_table[512];
123
124 static void genLoopkupTable()
125 {
126         int i;
127         int x, y;
128         
129         for (i = 0; i < 256; i++) {
130                 relClose(i, &x, &y);
131                 
132                 close_table[i*2+0] = x;
133                 close_table[i*2+1] = y;
134                 
135                 relFar(i, 1, &x, &y);
136                 
137                 far_p_table[i*2+0] = x;
138                 far_p_table[i*2+1] = y;
139                 
140                 relFar(i, -1, &x, &y);
141                 
142                 far_n_table[i*2+0] = x;
143                 far_n_table[i*2+1] = y;
144         }
145         
146         lookup_initialized = 1;
147 }
148
149 static void copyFrame(unsigned short *pDest, unsigned short *pSrc)
150 {
151     int i;
152
153     for (i=0; i<8; i++)
154     {
155         memcpy(pDest, pSrc, 16);
156         pDest += g_width;
157         pSrc += g_width;
158     }
159 }
160
161 static void patternRow4Pixels(unsigned short *pFrame,
162                               unsigned char pat0, unsigned char pat1,
163                               unsigned short *p)
164 {
165     unsigned short mask=0x0003;
166     unsigned short shift=0;
167     unsigned short pattern = (pat1 << 8) | pat0;
168
169     while (mask != 0)
170     {
171         *pFrame++ = p[(mask & pattern) >> shift];
172         mask <<= 2;
173         shift += 2;
174     }
175 }
176
177 static void patternRow4Pixels2(unsigned short *pFrame,
178                                unsigned char pat0,
179                                unsigned short *p)
180 {
181     unsigned char mask=0x03;
182     unsigned char shift=0;
183     unsigned short pel;
184 /* ORIGINAL VERSION IS BUGGY
185     int skip=1;
186
187     while (mask != 0)
188     {
189         pel = p[(mask & pat0) >> shift];
190         pFrame[0] = pel;
191         pFrame[2] = pel;
192         pFrame[g_width + 0] = pel;
193         pFrame[g_width + 2] = pel;
194         pFrame += skip;
195         skip = 4 - skip;
196         mask <<= 2;
197         shift += 2;
198     }
199 */
200     while (mask != 0)
201     {
202         pel = p[(mask & pat0) >> shift];
203         pFrame[0] = pel;
204         pFrame[1] = pel;
205         pFrame[g_width + 0] = pel;
206         pFrame[g_width + 1] = pel;
207         pFrame += 2;
208         mask <<= 2;
209         shift += 2;
210     }
211 }
212
213 static void patternRow4Pixels2x1(unsigned short *pFrame, unsigned char pat, 
214         unsigned short *p)
215 {
216     unsigned char mask=0x03;
217     unsigned char shift=0;
218     unsigned short pel;
219
220     while (mask != 0)
221     {
222         pel = p[(mask & pat) >> shift];
223         pFrame[0] = pel;
224         pFrame[1] = pel;
225         pFrame += 2;
226         mask <<= 2;
227         shift += 2;
228     }
229 }
230
231 static void patternQuadrant4Pixels(unsigned short *pFrame, 
232         unsigned char pat0, unsigned char pat1, unsigned char pat2, 
233         unsigned char pat3, unsigned short *p)
234 {
235     unsigned long mask = 0x00000003UL;
236     int shift=0;
237     int i;
238     unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
239
240     for (i=0; i<16; i++)
241     {
242         pFrame[i&3] = p[(pat & mask) >> shift];
243
244         if ((i&3) == 3)
245             pFrame += g_width;
246
247         mask <<= 2;
248         shift += 2;
249     }
250 }
251
252
253 static void patternRow2Pixels(unsigned short *pFrame, unsigned char pat, 
254         unsigned short *p)
255 {
256     unsigned char mask=0x01;
257
258     while (mask != 0)
259     {
260         *pFrame++ = p[(mask & pat) ? 1 : 0];
261         mask <<= 1;
262     }
263 }
264
265 static void patternRow2Pixels2(unsigned short *pFrame, unsigned char pat, 
266         unsigned short *p)
267 {
268     unsigned short pel;
269     unsigned char mask=0x1;
270
271 /* ORIGINAL VERSION IS BUGGY   
272     int skip=1;
273     while (mask != 0x10)
274     {
275         pel = p[(mask & pat) ? 1 : 0];
276         pFrame[0] = pel;
277         pFrame[2] = pel;
278         pFrame[g_width + 0] = pel;
279         pFrame[g_width + 2] = pel;
280         pFrame += skip;
281         skip = 4 - skip;
282         mask <<= 1;
283     }
284 */
285         while (mask != 0x10) {
286                 pel = p[(mask & pat) ? 1 : 0];
287                 
288                 pFrame[0] = pel;
289                 pFrame[1] = pel;
290                 pFrame[g_width + 0] = pel;
291                 pFrame[g_width + 1] = pel;
292                 pFrame += 2;
293                 
294                 mask <<= 1;
295         }
296 }
297
298 static void patternQuadrant2Pixels(unsigned short *pFrame, unsigned char pat0,
299          unsigned char pat1, unsigned short *p)
300 {
301     unsigned short mask = 0x0001;
302     int i;
303     unsigned short pat = (pat1 << 8) | pat0;
304
305     for (i=0; i<16; i++)
306     {
307         pFrame[i&3] = p[(pat & mask) ? 1 : 0];
308
309         if ((i&3) == 3)
310             pFrame += g_width;
311
312         mask <<= 1;
313     }
314 }
315
316 static void dispatchDecoder16(unsigned short **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb)
317 {
318     unsigned short p[4];
319     unsigned char pat[16];
320     int i, j, k;
321     int x, y;
322     unsigned short *pDstBak;
323
324     pDstBak = *pFrame;
325
326     switch(codeType)
327     {
328         case 0x0:
329                   copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
330         case 0x1:
331                   break;
332         case 0x2: /*    
333                   relFar(*(*pOffData)++, 1, &x, &y);
334                   */
335                   
336                   k = *(*pOffData)++;
337                   x = far_p_table[k*2+0];
338                   y = far_p_table[k*2+1];
339                   
340                   copyFrame(*pFrame, *pFrame + x + y*g_width);
341                   --*pDataRemain;
342                   break;
343         case 0x3: /*
344                   relFar(*(*pOffData)++, -1, &x, &y);
345                   */
346                   
347                   k = *(*pOffData)++;
348                   x = far_n_table[k*2+0];
349                   y = far_n_table[k*2+1];
350                   
351                   copyFrame(*pFrame, *pFrame + x + y*g_width);
352                   --*pDataRemain;                  
353                   break;
354         case 0x4: /*
355                   relClose(*(*pOffData)++, &x, &y);
356                   */
357                   
358                   k = *(*pOffData)++;
359                   x = close_table[k*2+0];
360                   y = close_table[k*2+1];
361                   
362                   copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
363                   --*pDataRemain;
364                   break;
365         case 0x5:
366                   x = (char)*(*pData)++;
367                   y = (char)*(*pData)++;
368                   copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
369                   *pDataRemain -= 2;
370                   break;
371         case 0x6:
372                 fprintf(stderr, "STUB: encoding 6 not tested\n");
373                   for (i=0; i<2; i++)
374                   {
375                       *pFrame += 16;
376                       if (++*curXb == (g_width >> 3))
377                       {
378                           *pFrame += 7*g_width;
379                           *curXb = 0;
380                           if (++*curYb == (g_height >> 3))
381                               return;
382                       }
383                   }
384                   break;
385
386         case 0x7:
387                   p[0] = GETPIXELI(pData, 0);
388                   p[1] = GETPIXELI(pData, 0);
389      
390                   if (!((p[0]/*|p[1]*/)&0x8000))
391                   {
392                       for (i=0; i<8; i++)
393                       {
394                           patternRow2Pixels(*pFrame, *(*pData), p);
395                           (*pData)++;
396                           
397                           *pFrame += g_width;
398                       }
399                   }
400                   else
401                   {
402                       for (i=0; i<2; i++)
403                       {
404                           patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
405                           *pFrame += 2*g_width;
406                           patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
407                           (*pData)++;
408
409                           *pFrame += 2*g_width;
410                       }
411                   }
412                   break;
413                   
414         case 0x8:
415                   p[0] = GETPIXEL(pData, 0);
416                   
417                   if (!(p[0] & 0x8000))
418                   {
419                       for (i=0; i<4; i++)
420                       {
421                           p[0] = GETPIXELI(pData, 0);
422                           p[1] = GETPIXELI(pData, 0);
423                           
424                           pat[0] = (*pData)[0];
425                           pat[1] = (*pData)[1];
426                           (*pData) += 2;
427                                                                            
428                           patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
429
430                           if (i & 1)
431                               *pFrame -= (4*g_width - 4);
432                           else
433                               *pFrame += 4*g_width;
434                       }
435                       
436                       
437                   } else {
438                          p[2] = GETPIXEL(pData, 8);
439
440                          if (!(p[2]&0x8000)) {
441                               for (i=0; i<4; i++)
442                               {
443                                   if ((i & 1) == 0)
444                                   {
445                                       p[0] = GETPIXELI(pData, 0);
446                                       p[1] = GETPIXELI(pData, 0);
447                                   }
448                                   pat[0] = *(*pData)++;
449                                   pat[1] = *(*pData)++;
450                                   patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
451
452                                   if (i & 1)
453                                       *pFrame -= (4*g_width - 4);
454                                   else
455                                       *pFrame += 4*g_width;
456                               }
457                           } else {
458                               for (i=0; i<8; i++)
459                               {
460                                   if ((i & 3) == 0)
461                                   {
462                                       p[0] = GETPIXELI(pData, 0);
463                                       p[1] = GETPIXELI(pData, 0);
464                                   }
465                                   patternRow2Pixels(*pFrame, *(*pData), p);
466                                   (*pData)++;
467                                   
468                                   *pFrame += g_width;
469                               }
470                           }
471                   }
472                   break;
473
474         case 0x9:
475                   p[0] = GETPIXELI(pData, 0);
476                   p[1] = GETPIXELI(pData, 0);
477                   p[2] = GETPIXELI(pData, 0);
478                   p[3] = GETPIXELI(pData, 0);
479                   
480                   *pDataRemain -= 8;
481
482                   if (!(p[0] & 0x8000))
483                   {
484                       if (!(p[2] & 0x8000))
485                       {
486
487                           for (i=0; i<8; i++)
488                           {
489                               pat[0] = (*pData)[0];
490                               pat[1] = (*pData)[1];
491                               (*pData) += 2;
492                               patternRow4Pixels(*pFrame, pat[0], pat[1], p);
493                               *pFrame += g_width;                              
494                           }
495                           *pDataRemain -= 16;
496
497                       }
498                       else
499                       {  
500                           patternRow4Pixels2(*pFrame, (*pData)[0], p);
501                           *pFrame += 2*g_width;
502                           patternRow4Pixels2(*pFrame, (*pData)[1], p);
503                           *pFrame += 2*g_width;
504                           patternRow4Pixels2(*pFrame, (*pData)[2], p);
505                           *pFrame += 2*g_width;
506                           patternRow4Pixels2(*pFrame, (*pData)[3], p);
507                           
508                           (*pData) += 4;
509                           *pDataRemain -= 4;
510
511                         }
512                   }
513                   else
514                   {
515                       if (!(p[2] & 0x8000)) 
516                       {
517                           for (i=0; i<8; i++)
518                           {
519                               pat[0] = (*pData)[0];
520                               (*pData) += 1;
521                               patternRow4Pixels2x1(*pFrame, pat[0], p);
522                               *pFrame += g_width;
523                           }
524                           *pDataRemain -= 8;
525                       }
526                       else
527                       { 
528                           for (i=0; i<4; i++)
529                           {
530                               pat[0] = (*pData)[0];
531                               pat[1] = (*pData)[1];
532                               
533                               (*pData) += 2;
534                               
535                               patternRow4Pixels(*pFrame, pat[0], pat[1], p);
536                               *pFrame += g_width;
537                               patternRow4Pixels(*pFrame, pat[0], pat[1], p);
538                               *pFrame += g_width;
539                           }
540                           *pDataRemain -= 8;
541                       }
542                   }
543                   break;
544
545         case 0xa:
546                   p[0] = GETPIXEL(pData, 0);
547                   
548                   if (!(p[0] & 0x8000))
549                   {
550                       for (i=0; i<4; i++)
551                       {
552                           p[0] = GETPIXELI(pData, 0);
553                           p[1] = GETPIXELI(pData, 0);
554                           p[2] = GETPIXELI(pData, 0);
555                           p[3] = GETPIXELI(pData, 0);
556                           pat[0] = (*pData)[0];
557                           pat[1] = (*pData)[1];
558                           pat[2] = (*pData)[2];
559                           pat[3] = (*pData)[3];
560
561                           (*pData) += 4;
562                         
563                           patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
564
565                           if (i & 1)
566                               *pFrame -= (4*g_width - 4);
567                           else
568                               *pFrame += 4*g_width;
569                       }                      
570                   }
571                   else
572                   {
573                       p[0] = GETPIXEL(pData, 16);
574                       
575                       if (!(p[0] & 0x8000))
576                       {
577                           for (i=0; i<4; i++)
578                           {
579                               if ((i&1) == 0)
580                               {
581                                   p[0] = GETPIXELI(pData, 0); 
582                                   p[1] = GETPIXELI(pData, 0);
583                                   p[2] = GETPIXELI(pData, 0);
584                                   p[3] = GETPIXELI(pData, 0);
585                               }
586
587                               pat[0] = (*pData)[0];
588                               pat[1] = (*pData)[1];
589                               pat[2] = (*pData)[2];
590                               pat[3] = (*pData)[3];
591
592                                 (*pData) += 4;
593                                 
594                               patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
595
596                               if (i & 1)
597                                   *pFrame -= (4*g_width - 4);
598                               else
599                                   *pFrame += 4*g_width;
600                           }
601                       }
602                       else
603                       {
604                           for (i=0; i<8; i++)
605                           {
606                               if ((i&3) == 0)
607                               {
608                                   p[0] = GETPIXELI(pData, 0);
609                                   p[1] = GETPIXELI(pData, 0);
610                                   p[2] = GETPIXELI(pData, 0);
611                                   p[3] = GETPIXELI(pData, 0);
612                               }
613
614                               pat[0] = (*pData)[0];
615                               pat[1] = (*pData)[1];
616                               patternRow4Pixels(*pFrame, pat[0], pat[1], p);
617                               *pFrame += g_width;
618                               
619                               (*pData) += 2;
620                           }
621                       }
622                   }                  
623                   break;
624
625         case 0xb:
626                   for (i=0; i<8; i++)
627                   {
628                       memcpy(*pFrame, *pData, 16);
629                       *pFrame += g_width;
630                       *pData += 16;
631                       *pDataRemain -= 16;
632                   }
633                   break;
634
635         case 0xc:
636                   for (i=0; i<4; i++)
637                   {
638                       p[0] = GETPIXEL(pData, 0);
639                       p[1] = GETPIXEL(pData, 2);
640                       p[2] = GETPIXEL(pData, 4);
641                       p[3] = GETPIXEL(pData, 6);
642
643                       for (j=0; j<2; j++)
644                       {
645                           for (k=0; k<4; k++)
646                           {
647                               (*pFrame)[j+2*k] = p[k];
648                               (*pFrame)[g_width+j+2*k] = p[k];
649                           }
650                           *pFrame += g_width;
651                       }
652                       *pData += 8;
653                       *pDataRemain -= 8;
654                   }
655                   break;
656
657         case 0xd:
658                   for (i=0; i<2; i++)
659                   {
660                      p[0] = GETPIXEL(pData, 0);
661                      p[1] = GETPIXEL(pData, 2);
662
663                       for (j=0; j<4; j++)
664                       {
665                           for (k=0; k<4; k++)
666                           {
667                               (*pFrame)[k*g_width+j] = p[0];
668                               (*pFrame)[k*g_width+j+4] = p[1];
669                           }
670                       }                    
671                       
672                       *pFrame += 4*g_width;
673                       
674                       *pData += 4;
675                       *pDataRemain -= 4;
676                   }
677                   break;
678
679         case 0xe:                 
680                   p[0] = GETPIXEL(pData, 0);
681                   
682                   for (i = 0; i < 8; i++) {
683                         for (j = 0; j < 8; j++) {
684                                 (*pFrame)[j] = p[0];
685                         }
686                                 
687                         *pFrame += g_width;
688                   }
689                                   
690                   *pData += 2;
691                   *pDataRemain -= 2;
692                    
693                   break;
694
695         case 0xf:
696                   p[0] = GETPIXEL(pData, 0);
697                   p[1] = GETPIXEL(pData, 1);
698                   
699                   for (i=0; i<8; i++)
700                   {
701                       for (j=0; j<8; j++)
702                       {
703                           (*pFrame)[j] = p[(i+j)&1];
704                       }
705                       *pFrame += g_width;
706                   }
707                   
708                   *pData += 4;
709                   *pDataRemain -= 4;
710                   break;
711
712         default:
713             break;
714     }
715     
716     *pFrame = pDstBak+8;
717 }