📄 vlc.c
字号:
{ 0, 0, 0, 1, 1, 9, 8, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0}},
//YUV444
{{ 1, 5, 7, 7, 7, 7,15,11, 8,15,11,15,11,15,11, 7, 4},
{ 0, 1, 4, 6, 6, 6, 6,14,10,14,10,14,10, 1,14,10, 6},
{ 0, 0, 1, 5, 5, 5, 5, 5,13, 9,13, 9,13, 9,13, 9, 5},
{ 0, 0, 0, 3, 3, 4, 4, 4, 4, 4,12,12, 8,12, 8,12, 8}}
};
int yuv = img->yuv_format - 1;
// se->value1 : numcoeff
// se->value2 : numtrailingones
se->len = lentab[yuv][se->value2][se->value1];
se->inf = codtab[yuv][se->value2][se->value1];
if (se->len == 0)
{
printf("ERROR: (numcoeff,trailingones) not valid: (%d, %d)\n",
se->value1, se->value2);
exit(-1);
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for TotalZeros
************************************************************************
*/
int writeSyntaxElement_TotalZeros(SyntaxElement *se, DataPartition *this_dataPart)
{
int lentab[TOTRUN_NUM][16] =
{
{ 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
{ 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
{ 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
{ 5,3,4,4,3,3,3,4,3,4,5,5,5},
{ 4,4,4,3,3,3,3,3,4,5,4,5},
{ 6,5,3,3,3,3,3,3,4,3,6},
{ 6,5,3,3,3,2,3,4,3,6},
{ 6,4,5,3,2,2,3,3,6},
{ 6,6,4,2,2,3,2,5},
{ 5,5,3,2,2,2,4},
{ 4,4,3,3,1,3},
{ 4,4,2,1,3},
{ 3,3,1,2},
{ 2,2,1},
{ 1,1},
};
int codtab[TOTRUN_NUM][16] =
{
{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
{7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
{5,7,6,5,4,3,4,3,2,3,2,1,1,0},
{3,7,5,4,6,5,4,3,3,2,2,1,0},
{5,4,3,7,6,5,4,3,2,1,1,0},
{1,1,7,6,5,4,3,2,1,1,0},
{1,1,5,4,3,3,2,1,1,0},
{1,1,1,3,3,2,2,1,0},
{1,0,1,3,2,1,1,1,},
{1,0,1,3,2,1,1,},
{0,1,1,2,1,3},
{0,1,1,1,1},
{0,1,1,1},
{0,1,1},
{0,1},
};
int vlcnum;
vlcnum = se->len;
// se->value1 : TotalZeros
se->len = lentab[vlcnum][se->value1];
se->inf = codtab[vlcnum][se->value1];
if (se->len == 0)
{
printf("ERROR: (TotalZeros) not valid: (%d)\n",se->value1);
exit(-1);
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for TotalZeros for Chroma DC
************************************************************************
*/
int writeSyntaxElement_TotalZerosChromaDC(SyntaxElement *se, DataPartition *this_dataPart)
{
int lentab[3][TOTRUN_NUM][16] =
{
//YUV420
{{ 1,2,3,3},
{ 1,2,2},
{ 1,1}},
//YUV422
{{ 1,3,3,4,4,4,5,5},
{ 3,2,3,3,3,3,3},
{ 3,3,2,2,3,3},
{ 3,2,2,2,3},
{ 2,2,2,2},
{ 2,2,1},
{ 1,1}},
//YUV444
{{ 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
{ 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
{ 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
{ 5,3,4,4,3,3,3,4,3,4,5,5,5},
{ 4,4,4,3,3,3,3,3,4,5,4,5},
{ 6,5,3,3,3,3,3,3,4,3,6},
{ 6,5,3,3,3,2,3,4,3,6},
{ 6,4,5,3,2,2,3,3,6},
{ 6,6,4,2,2,3,2,5},
{ 5,5,3,2,2,2,4},
{ 4,4,3,3,1,3},
{ 4,4,2,1,3},
{ 3,3,1,2},
{ 2,2,1},
{ 1,1}}
};
int codtab[3][TOTRUN_NUM][16] =
{
//YUV420
{{ 1,1,1,0},
{ 1,1,0},
{ 1,0}},
//YUV422
{{ 1,2,3,2,3,1,1,0},
{ 0,1,1,4,5,6,7},
{ 0,1,1,2,6,7},
{ 6,0,1,2,7},
{ 0,1,2,3},
{ 0,1,1},
{ 0,1}},
//YUV444
{{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
{7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
{5,7,6,5,4,3,4,3,2,3,2,1,1,0},
{3,7,5,4,6,5,4,3,3,2,2,1,0},
{5,4,3,7,6,5,4,3,2,1,1,0},
{1,1,7,6,5,4,3,2,1,1,0},
{1,1,5,4,3,3,2,1,1,0},
{1,1,1,3,3,2,2,1,0},
{1,0,1,3,2,1,1,1,},
{1,0,1,3,2,1,1,},
{0,1,1,2,1,3},
{0,1,1,1,1},
{0,1,1,1},
{0,1,1},
{0,1}}
};
int vlcnum;
int yuv = img->yuv_format - 1;
vlcnum = se->len;
// se->value1 : TotalZeros
se->len = lentab[yuv][vlcnum][se->value1];
se->inf = codtab[yuv][vlcnum][se->value1];
if (se->len == 0)
{
printf("ERROR: (TotalZeros) not valid: (%d)\n",se->value1);
exit(-1);
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for Run Before Next Coefficient, VLC0
************************************************************************
*/
int writeSyntaxElement_Run(SyntaxElement *se, DataPartition *this_dataPart)
{
int lentab[TOTRUN_NUM][16] =
{
{1,1},
{1,2,2},
{2,2,2,2},
{2,2,2,3,3},
{2,2,3,3,3,3},
{2,3,3,3,3,3,3},
{3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
};
int codtab[TOTRUN_NUM][16] =
{
{1,0},
{1,1,0},
{3,2,1,0},
{3,2,1,1,0},
{3,2,3,2,1,0},
{3,0,1,3,2,5,4},
{7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
};
int vlcnum;
vlcnum = se->len;
// se->value1 : run
se->len = lentab[vlcnum][se->value1];
se->inf = codtab[vlcnum][se->value1];
if (se->len == 0)
{
printf("ERROR: (run) not valid: (%d)\n",se->value1);
exit(-1);
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for Coeff Level (VLC1)
************************************************************************
*/
int writeSyntaxElement_Level_VLC1(SyntaxElement *se, DataPartition *this_dataPart)
{
int level, levabs, sign;
level = se->value1;
levabs = abs(level);
sign = (level < 0 ? 1 : 0);
if (levabs < 8)
{
se->len = levabs * 2 + sign - 1;
se->inf = 1;
}
else if (levabs < 8+8)
{
// escape code1
se->len = 14 + 1 + 4;
se->inf = (1 << 4) | ((levabs - 8) << 1) | sign;
}
else
{
// escape code2
se->len = 14 + 2 + 12;
se->inf = (0x1 << 12) | ((levabs - 16)<< 1) | sign;
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for Coeff Level
************************************************************************
*/
int writeSyntaxElement_Level_VLCN(SyntaxElement *se, int vlc, DataPartition *this_dataPart)
{
int iCodeword;
int iLength;
int level = se->value1;
int levabs = abs(level);
int sign = (level < 0 ? 1 : 0);
int shift = vlc-1;
int escape = (15<<shift)+1;
int numPrefix = (levabs-1)>>shift;
int sufmask = ~((0xffffffff)<<shift);
int suffix = (levabs-1)&sufmask;
if (levabs < escape)
{
iLength = numPrefix + vlc + 1;
iCodeword = (1<<(shift+1))|(suffix<<1)|sign;
}
else
{
iLength = 28;
iCodeword = (1<<12)|((levabs-escape)<<1)|sign;
}
se->len = iLength;
se->inf = iCodeword;
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* Write out a trace string on the trace file
************************************************************************
*/
#if TRACE
void trace2out(SyntaxElement *sym)
{
static int bitcounter = 0;
int i, chars;
if (p_trace != NULL)
{
putc('@', p_trace);
chars = fprintf(p_trace, "%i", bitcounter);
while(chars++ < 6)
putc(' ',p_trace);
chars += fprintf(p_trace, "%s", sym->tracestring);
while(chars++ < 55)
putc(' ',p_trace);
// Align bitpattern
if(sym->len<15)
{
for(i=0 ; i<15-sym->len ; i++)
fputc(' ', p_trace);
}
// Print bitpattern
bitcounter += sym->len;
for(i=1 ; i<=sym->len ; i++)
{
if((sym->bitpattern >> (sym->len-i)) & 0x1)
fputc('1', p_trace);
else
fputc('0', p_trace);
}
fprintf(p_trace, " (%3d) \n",sym->value1);
}
fflush (p_trace);
}
#endif
/*!
************************************************************************
* \brief
* puts the less than 8 bits in the byte buffer of the Bitstream into
* the streamBuffer.
*
* \param
* currStream: the Bitstream the alignment should be established
*
************************************************************************
*/
void writeVlcByteAlign(Bitstream* currStream)
{
if (currStream->bits_to_go < 8)
{ // trailing bits to process
currStream->byte_buf = (currStream->byte_buf <<currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go));
stat->bit_use_stuffingBits[img->type]+=currStream->bits_to_go;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
currStream->bits_to_go = 8;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -