winamp/Src/f263/Block.cpp

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;
}
}}