📄 text_bits.c
字号:
#include "momusys.h"
#include "text_defs.h"
#include "bitstream.h"
#include "text_bits.h"
#include "putvlc.h"
#include "zigzag.h"
#include "max_level.h"
Int IntraDC_dpcm (Int val, Int lum, Image *bitstream);
Int CodeCoeff (Int j_start, Int Mode, Int qcoeff[],
Int block, Int ncoeffs, Image *bitstream);
Int CodeCoeff_RVLC (Int j_start, Int Mode, Int qcoeff[],
Int block, Int ncoeffs, Image *bitstream);
Void MB_CodeCoeff(Bits* bits, Int *qcoeff,
Int Mode, Int CBP, Int ncoeffs,
Int intra_dcpred_disable,
Image *DCbitstream,
Image *bitstream,
Int transp_pattern[], Int direction[],
Int error_res_disable,
Int reverse_vlc,
Int switched,
Int alternate_scan)
{
Int i, m, coeff[64];
Int *zz = alternate_scan ? zigzag_v : zigzag;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
if (intra_dcpred_disable == 0)
{
for (i = 0; i < 6; i++)
{
{
if (!alternate_scan)
{
switch (direction[i])
{
case 1: zz = zigzag_v; break;
case 2: zz = zigzag_h; break;
case 0: break;
default: fprintf(stderr, "MB_CodeCoeff(): Error in zigzag direction\n");
exit(-1);
}
}
for (m = 0; m < 64; m++)
{
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
}
if (switched==0)
{
if (error_res_disable)
{
if (i < 4)
bits->Y += IntraDC_dpcm(coeff[0],1,bitstream);
else
bits->C += IntraDC_dpcm(coeff[0],0,bitstream);
}
else
{
if (i < 4)
bits->Y += IntraDC_dpcm(coeff[0],1,DCbitstream);
else
bits->C += IntraDC_dpcm(coeff[0],0,DCbitstream);
}
}
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,bitstream);
else
bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
else
bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
}
}
}
}
}
else
{
for (i = 0; i < 6; i++)
{
{
for (m = 0; m < 64; m++)
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
if (switched==0)
{
if (error_res_disable)
{
if (coeff[0] != 128)
BitstreamPutBits(bitstream,(long)(coeff[0]),8L);
else
BitstreamPutBits(bitstream, 255L, 8L);
}
else
{
if (coeff[0] != 128)
BitstreamPutBits(DCbitstream,(long)(coeff[0]),8L);
else
BitstreamPutBits(DCbitstream,255L, 8L);
}
if (i < 4)
bits->Y += 8;
else
bits->C += 8;
}
if ((i==0 && CBP&32) || (i==1 && CBP&16) ||
(i==2 && CBP&8) || (i==3 && CBP&4) ||
(i==4 && CBP&2) || (i==5 && CBP&1))
{
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
else
bits->C += CodeCoeff(1-switched,Mode, coeff,i,ncoeffs,
bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
else
bits->C += CodeCoeff_RVLC(1-switched,Mode, coeff, i,
ncoeffs, bitstream);
}
}
}
}
}
}
else
{
for (i = 0; i < 6; i++)
{
for (m = 0; m < 64; m++)
*(coeff + zz[m]) = qcoeff[i*ncoeffs+m];
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
if (error_res_disable || ((!error_res_disable) && (!reverse_vlc)))
{
if (i < 4)
bits->Y += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
else
bits->C += CodeCoeff(0,Mode, coeff, i, ncoeffs, bitstream);
}
else
{
if (i < 4)
bits->Y += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
bitstream);
else
bits->C += CodeCoeff_RVLC(0,Mode, coeff, i, ncoeffs,
bitstream);
}
}
}
}
}
Int
IntraDC_dpcm(Int val, Int lum, Image *bitstream)
{
Int n_bits;
Int absval, size = 0;
absval = ( val <0)?-val:val;
size = 0;
while(absval)
{
absval>>=1;
size++;
}
if (lum)
{
n_bits = PutDCsize_lum (size, bitstream);
}
else
{
n_bits = PutDCsize_chrom (size, bitstream);
}
if ( size != 0 )
{
if (val>=0)
{
;
}
else
{
absval = -val;
val = (absval ^( (int)pow(2.0,(double)size)-1) );
}
BitstreamPutBits(bitstream, (long)(val), (long)(size));
n_bits += size;
if (size > 8)
BitstreamPutBits(bitstream, (long)1, (long)1);
}
return n_bits;
}
Int CodeCoeff(Int j_start, Int Mode, Int qcoeff[], Int block, Int ncoeffs, Image *bitstream)
{
Int j, bits;
Int prev_run, run, prev_level, level, first;
Int prev_ind, ind, prev_s, s, length;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
for (j = j_start; j< ncoeffs; j++)
{
{
s = 0;
if ((level = qcoeff[j]) == 0)
{
run++;
}
else
{
if (level < 0)
{
s = 1;
level = -level;
}
ind = level | run<<4;
ind = ind | 0<<12;
if (!first)
{
if ((prev_run < 64) &&
(((prev_level < 13) && (Mode != MODE_INTRA &&
Mode != MODE_INTRA_Q))
|| ((prev_level < 28) && (Mode == MODE_INTRA ||
Mode == MODE_INTRA_Q))))
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutCoeff_Intra(prev_run, prev_level,
0, bitstream);
}
else
{
length = PutCoeff_Inter(prev_run, prev_level,
0, bitstream);
}
}
else
length = 0;
if (length == 0)
{
if ( prev_run < 64 )
{
int level_minus_max;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
level_minus_max = prev_level -
intra_max_level[0][prev_run];
else
level_minus_max = prev_level -
inter_max_level[0][prev_run];
if ( ( (level_minus_max < 13) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q) ) ||
( (level_minus_max < 28) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) ) )
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutLevelCoeff_Intra(prev_run, level_minus_max, 0, bitstream);
}
else
{
length = PutLevelCoeff_Inter(prev_run, level_minus_max, 0, bitstream);
}
} else
length = 0;
}
else length = 0;
}
if (length == 0)
{
if ( ((prev_level < 13) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q)) ||
((prev_level < 28) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) )
{
int run_minus_max;
if (prev_level == 0)
{
fprintf (stdout, "ERROR(CodeCoeff-second esc): level is %d\n", prev_level);
exit(-1);
}
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
run_minus_max = prev_run - (intra_max_run0[prev_level]+1);
else
run_minus_max = prev_run - (inter_max_run0[prev_level]+1);
if (run_minus_max < 64)
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutRunCoeff_Intra(run_minus_max, prev_level, 0, bitstream);
}
else
{
length = PutRunCoeff_Inter(run_minus_max, prev_level, 0, bitstream);
}
} else
length = 0;
}
else length = 0;
}
if (length == 0)
{
if (prev_s == 1)
{
prev_level = (prev_level^0xfff)+1;
}
BitstreamPutBits(bitstream, 3L, 7L);
BitstreamPutBits(bitstream, 3L, 2L);
BitstreamPutBits(bitstream, 0L, 1L);
BitstreamPutBits(bitstream, (long)(prev_run), 6L);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
BitstreamPutBits(bitstream, (long)(prev_level), 12L);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
bits += 30;
}
else
{
BitstreamPutBits(bitstream, (long)(prev_s), 1L);
bits += length + 1;
}
}
prev_run = run; prev_s = s;
prev_level = level; prev_ind = ind;
run = first = 0;
}
}
}
if (!first)
{
prev_ind = prev_ind | 1<<12;
if ((prev_run < 64) &&
(((prev_level < 4) && (Mode != MODE_INTRA &&
Mode != MODE_INTRA_Q))
|| ((prev_level < 9) && ((Mode == MODE_INTRA) ||
(Mode == MODE_INTRA_Q)))))
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutCoeff_Intra(prev_run, prev_level, 1,
bitstream);
}
else
{
length = PutCoeff_Inter(prev_run, prev_level, 1,
bitstream);
}
}
else
length = 0;
if (length == 0)
{
if ( prev_run < 64 )
{
int level_minus_max;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
level_minus_max = prev_level - intra_max_level[1][prev_run];
else
level_minus_max = prev_level - inter_max_level[1][prev_run];
if ( ( (level_minus_max < 4) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q) ) ||
( (level_minus_max < 9) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) ) )
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutLevelCoeff_Intra(prev_run, level_minus_max, 1, bitstream);
}
else
{
length = PutLevelCoeff_Inter(prev_run, level_minus_max, 1, bitstream);
}
} else
length = 0;
}
else length = 0;
}
if (length == 0)
{
if (((prev_level < 4) && (Mode != MODE_INTRA && Mode != MODE_INTRA_Q))||
((prev_level < 9) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)) )
{
int run_minus_max;
if (prev_level == 0)
{
fprintf (stdout, "ERROR(CodeCoeff-second esc): level is %d\n", prev_level);
exit(-1);
}
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
run_minus_max = prev_run - (intra_max_run1[prev_level]+1);
else
run_minus_max = prev_run - (inter_max_run1[prev_level]+1);
if (run_minus_max < 64)
{
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutRunCoeff_Intra(run_minus_max, prev_level, 1, bitstream);
}
else
{
length = PutRunCoeff_Inter(run_minus_max, prev_level, 1, bitstream);
}
} else
length = 0;
}
else length = 0;
}
if (length == 0)
{
if (prev_s == 1)
{
prev_level = (prev_level^0xfff)+1;
}
BitstreamPutBits(bitstream, 3L, 7L);
BitstreamPutBits(bitstream, 3L, 2L);
BitstreamPutBits(bitstream, 1L, 1L);
BitstreamPutBits(bitstream, (long)(prev_run), 6L);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
BitstreamPutBits(bitstream, (long)(prev_level), 12L);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
bits += 30;
}
else
{
BitstreamPutBits(bitstream, (long)(prev_s), 1L);
bits += length + 1;
}
}
return bits;
}
Int CodeCoeff_RVLC(Int j_start, Int Mode, Int qcoeff[], Int block, Int ncoeffs, Image *bitstream)
{
Int j, bits;
Int prev_run, run, prev_level, level, first;
Int prev_ind, ind, prev_s, s, length;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
for (j = j_start; j< ncoeffs; j++)
{
{
s = 0;
if ((level = qcoeff[j]) == 0)
{
run++;
}
else
{
if (level < 0)
{
s = 1;
level = -level;
}
ind = level | run<<4;
ind = ind | 0<<12;
if (!first)
{
if (prev_level < 28 && prev_run < 39)
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutCoeff_Intra_RVLC(prev_run, prev_level, 0,
bitstream);
}
else
{
length = PutCoeff_Inter_RVLC(prev_run, prev_level, 0,
bitstream);
}
else
length = 0;
if (length == 0)
{
BitstreamPutBits(bitstream, 1L, 5L);
BitstreamPutBits(bitstream, 0L, 1L);
BitstreamPutBits(bitstream,
(long)(prev_run), 6L);
BitstreamPutBits( bitstream, MARKER_BIT, 1 );
BitstreamPutBits( bitstream, (long)(prev_level), 11L);
BitstreamPutBits( bitstream, MARKER_BIT, 1 );
BitstreamPutBits(bitstream, 0L, 4L);
BitstreamPutBits(bitstream,
(long)(prev_s),1L);
bits += 5 + 1 + 6 + 1 + 11 + 1 + 4 + 1;
}
else
{
BitstreamPutBits(bitstream,
(long)(prev_s), 1L);
bits += length + 1;
}
}
prev_run = run; prev_s = s;
prev_level = level; prev_ind = ind;
run = first = 0;
}
}
}
if (!first)
{
prev_ind = prev_ind | 1<<12;
if (prev_level < 5 && prev_run < 45)
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
length = PutCoeff_Intra_RVLC(prev_run, prev_level, 1,
bitstream);
}
else
{
length = PutCoeff_Inter_RVLC(prev_run, prev_level, 1,
bitstream);
}
else
length = 0;
if (length == 0)
{
BitstreamPutBits(bitstream, 1L, 5L);
BitstreamPutBits(bitstream, 1L, 1L);
BitstreamPutBits(bitstream, (long)(prev_run), 6L);
BitstreamPutBits( bitstream, MARKER_BIT, 1 );
BitstreamPutBits( bitstream, (long)(prev_level), 11L);
BitstreamPutBits( bitstream, MARKER_BIT, 1 );
BitstreamPutBits(bitstream, 0L, 4L);
BitstreamPutBits(bitstream, (long)(prev_s), 1L);
bits += 24;
}
else
{
BitstreamPutBits(bitstream, (long)(prev_s), 1L);
bits += length + 1;
}
}
return bits;
}
void
Bits_Reset (Bits *bits)
{
memset(bits, 0, sizeof(Bits));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -