mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-18 16:45:51 +01:00
145 lines
2.7 KiB
C++
145 lines
2.7 KiB
C++
|
#include "Decoder.h"
|
||
|
#include "indices.h"
|
||
|
#include "vlc_table.h"
|
||
|
|
||
|
static unsigned char zig_zag_scan[64]={
|
||
|
0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,
|
||
|
12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,
|
||
|
35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,
|
||
|
58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63
|
||
|
};
|
||
|
|
||
|
#define ESCAPE 7167
|
||
|
// mode 1 = Inter (or Intra in advanced intra coding mode)
|
||
|
// mode 0 = Intra
|
||
|
void Decoder::getblock(int comp, int mode)
|
||
|
{
|
||
|
int val, i, j, sign;
|
||
|
unsigned int code;
|
||
|
VLCtab *tab;
|
||
|
short *bp;
|
||
|
int run, last, level, QP;
|
||
|
short *qval;
|
||
|
|
||
|
|
||
|
/* TODO: benski>
|
||
|
i think this whole function can get replaced with
|
||
|
ippiDecodeCoeffsIntra_H263_1u16s (mode==0)
|
||
|
or
|
||
|
ippiDecodeCoeffsInter_H263_1u16s (mode == 1)
|
||
|
with pCoef = bp
|
||
|
modQuantFlag = escapemode>=1
|
||
|
scan = IPPVC_SCAN_ZIGZAG
|
||
|
|
||
|
*/
|
||
|
bp = block[comp];
|
||
|
|
||
|
/* decode AC coefficients (or all coefficients in advanced intra coding
|
||
|
* mode) */
|
||
|
|
||
|
for (i = (mode == 0);; i++)
|
||
|
{
|
||
|
|
||
|
code = buffer.showbits(12);
|
||
|
|
||
|
|
||
|
if (code >= 512)
|
||
|
tab = &DCT3Dtab0[(code >> 5) - 16];
|
||
|
else if (code >= 128)
|
||
|
tab = &DCT3Dtab1[(code >> 2) - 32];
|
||
|
else if (code >= 8)
|
||
|
tab = &DCT3Dtab2[(code >> 0) - 8];
|
||
|
else
|
||
|
{
|
||
|
fault = 1;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
run = (tab->val >> 4) & 255;
|
||
|
level = tab->val & 15;
|
||
|
last = (tab->val >> 12) & 1;
|
||
|
|
||
|
buffer.flushbits(tab->len);
|
||
|
if (tab->val == ESCAPE)
|
||
|
{
|
||
|
/* escape */
|
||
|
if (escapemode >= 1)
|
||
|
{
|
||
|
int is11 = buffer.getbits1();
|
||
|
sign=0;
|
||
|
last = buffer.getbits1();
|
||
|
i+=run = buffer.getbits(6);
|
||
|
if (is11)
|
||
|
{
|
||
|
level = buffer.getbits(11);
|
||
|
if ((sign = (level>=1024)))
|
||
|
val = 2048 - level;
|
||
|
else
|
||
|
val = level;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
level = buffer.getbits(7);
|
||
|
if ((sign = (level>=64)))
|
||
|
val = 128 - level;
|
||
|
else
|
||
|
val = level;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
last = buffer.getbits1();
|
||
|
i += run = buffer.getbits(6);
|
||
|
level = buffer.getbits(8);
|
||
|
|
||
|
if ((sign = (level >= 128)))
|
||
|
val = 256 - level;
|
||
|
else
|
||
|
val = level;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
i += run;
|
||
|
val = level;
|
||
|
sign = buffer.getbits(1);
|
||
|
}
|
||
|
|
||
|
|
||
|
if (i >= 64)
|
||
|
{
|
||
|
fault = 1;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Descan in the proper order in advanced intra coding mode */
|
||
|
|
||
|
|
||
|
j = zig_zag_scan[i];
|
||
|
qval = &bp[j];
|
||
|
QP = quant;
|
||
|
|
||
|
|
||
|
|
||
|
/* TODO: benski>
|
||
|
ippiQuantInvIntra_H263_16s_C1I
|
||
|
or
|
||
|
ippiQuantInvInter_H263_16s_C1I (mode == 1)
|
||
|
but outside the loop
|
||
|
pSrcDst = bp
|
||
|
QP = quant
|
||
|
modQuantFlag = escapemode >= 1
|
||
|
*/
|
||
|
/* TMN3 dequantization */
|
||
|
if ((QP % 2) == 1)
|
||
|
*qval = (sign ? -(QP * (2 * val + 1)) : QP * (2 * val + 1));
|
||
|
else
|
||
|
*qval = (sign ? -(QP * (2 * val + 1) - 1) : QP * (2 * val + 1) - 1);
|
||
|
|
||
|
if (last)
|
||
|
{
|
||
|
/* That's it */
|
||
|
return;
|
||
|
}
|
||
|
}}
|