📄 dct_decode.c
字号:
(HFRAGPIXELS - 1);
SrcPtr2 = &DestReconPtr[ PixelIndex ];
DestPtr2 = &DestReconPtr[ PixelIndex + 1 ];
/* Now copy the top and bottom source lines into each line of the
respective borders */
for ( i = 0; i < PlaneHeight; i++ ) {
memset( DestPtr1, SrcPtr1[0], PlaneBorderWidth );
memset( DestPtr2, SrcPtr2[0], PlaneBorderWidth );
SrcPtr1 += PlaneStride;
SrcPtr2 += PlaneStride;
DestPtr1 += PlaneStride;
DestPtr2 += PlaneStride;
}
}
void UpdateUMVBorder( PB_INSTANCE *pbi,
unsigned char * DestReconPtr ) {
ogg_uint32_t PlaneFragOffset;
/* Y plane */
PlaneFragOffset = 0;
UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
/* Then the U and V Planes */
PlaneFragOffset = pbi->YPlaneFragments;
UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
PlaneFragOffset = pbi->YPlaneFragments + pbi->UVPlaneFragments;
UpdateUMV_VBorders( pbi, DestReconPtr, PlaneFragOffset );
UpdateUMV_HBorders( pbi, DestReconPtr, PlaneFragOffset );
}
static void CopyRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
unsigned char * SrcReconPtr ) {
ogg_uint32_t i;
ogg_uint32_t PlaneLineStep; /* Pixels per line */
ogg_uint32_t PixelIndex;
unsigned char *SrcPtr; /* Pointer to line of source image data */
unsigned char *DestPtr; /* Pointer to line of destination image data */
/* Copy over only updated blocks.*/
/* First Y plane */
PlaneLineStep = pbi->YStride;
for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
if ( pbi->display_fragments[i] ) {
PixelIndex = pbi->recon_pixel_index_table[i];
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
/* Then U and V */
PlaneLineStep = pbi->UVStride;
for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
if ( pbi->display_fragments[i] ) {
PixelIndex = pbi->recon_pixel_index_table[i];
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
}
static void CopyNotRecon( PB_INSTANCE *pbi, unsigned char * DestReconPtr,
unsigned char * SrcReconPtr ) {
ogg_uint32_t i;
ogg_uint32_t PlaneLineStep; /* Pixels per line */
ogg_uint32_t PixelIndex;
unsigned char *SrcPtr; /* Pointer to line of source image data */
unsigned char *DestPtr; /* Pointer to line of destination image data*/
/* Copy over only updated blocks. */
/* First Y plane */
PlaneLineStep = pbi->YStride;
for ( i = 0; i < pbi->YPlaneFragments; i++ ) {
if ( !pbi->display_fragments[i] ) {
PixelIndex = pbi->recon_pixel_index_table[i];
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
/* Then U and V */
PlaneLineStep = pbi->UVStride;
for ( i = pbi->YPlaneFragments; i < pbi->UnitFragments; i++ ) {
if ( !pbi->display_fragments[i] ) {
PixelIndex = pbi->recon_pixel_index_table[i];
SrcPtr = &SrcReconPtr[ PixelIndex ];
DestPtr = &DestReconPtr[ PixelIndex ];
dsp_static_copy8x8 (SrcPtr, DestPtr, PlaneLineStep);
}
}
}
void ExpandToken( Q_LIST_ENTRY * ExpandedBlock,
unsigned char * CoeffIndex, ogg_uint32_t Token,
ogg_int32_t ExtraBits ){
/* Is the token is a combination run and value token. */
if ( Token >= DCT_RUN_CATEGORY1 ){
/* Expand the token and additional bits to a zero run length and
data value. */
if ( Token < DCT_RUN_CATEGORY2 ) {
/* Decoding method depends on token */
if ( Token < DCT_RUN_CATEGORY1B ) {
/* Step on by the zero run length */
*CoeffIndex += (unsigned char)((Token - DCT_RUN_CATEGORY1) + 1);
/* The extra bit determines the sign. */
if ( ExtraBits & 0x01 )
ExpandedBlock[*CoeffIndex] = -1;
else
ExpandedBlock[*CoeffIndex] = 1;
} else if ( Token == DCT_RUN_CATEGORY1B ) {
/* Bits 0-1 determines the zero run length */
*CoeffIndex += (6 + (ExtraBits & 0x03));
/* Bit 2 determines the sign */
if ( ExtraBits & 0x04 )
ExpandedBlock[*CoeffIndex] = -1;
else
ExpandedBlock[*CoeffIndex] = 1;
}else{
/* Bits 0-2 determines the zero run length */
*CoeffIndex += (10 + (ExtraBits & 0x07));
/* Bit 3 determines the sign */
if ( ExtraBits & 0x08 )
ExpandedBlock[*CoeffIndex] = -1;
else
ExpandedBlock[*CoeffIndex] = 1;
}
}else{
/* If token == DCT_RUN_CATEGORY2 we have a single 0 followed by
a value */
if ( Token == DCT_RUN_CATEGORY2 ){
/* Step on by the zero run length */
*CoeffIndex += 1;
/* Bit 1 determines sign, bit 0 the value */
if ( ExtraBits & 0x02 )
ExpandedBlock[*CoeffIndex] = -(2 + (ExtraBits & 0x01));
else
ExpandedBlock[*CoeffIndex] = 2 + (ExtraBits & 0x01);
}else{
/* else we have 2->3 zeros followed by a value */
/* Bit 0 determines the zero run length */
*CoeffIndex += 2 + (ExtraBits & 0x01);
/* Bit 2 determines the sign, bit 1 the value */
if ( ExtraBits & 0x04 )
ExpandedBlock[*CoeffIndex] = -(2 + ((ExtraBits & 0x02) >> 1));
else
ExpandedBlock[*CoeffIndex] = 2 + ((ExtraBits & 0x02) >> 1);
}
}
/* Step on over value */
*CoeffIndex += 1;
} else if ( Token == DCT_SHORT_ZRL_TOKEN ) {
/* Token is a ZRL token so step on by the appropriate number of zeros */
*CoeffIndex += ExtraBits + 1;
} else if ( Token == DCT_ZRL_TOKEN ) {
/* Token is a ZRL token so step on by the appropriate number of zeros */
*CoeffIndex += ExtraBits + 1;
} else if ( Token < LOW_VAL_TOKENS ) {
/* Token is a small single value token. */
switch ( Token ) {
case ONE_TOKEN:
ExpandedBlock[*CoeffIndex] = 1;
break;
case MINUS_ONE_TOKEN:
ExpandedBlock[*CoeffIndex] = -1;
break;
case TWO_TOKEN:
ExpandedBlock[*CoeffIndex] = 2;
break;
case MINUS_TWO_TOKEN:
ExpandedBlock[*CoeffIndex] = -2;
break;
}
/* Step on the coefficient index. */
*CoeffIndex += 1;
}else{
/* Token is a larger single value token */
/* Expand the token and additional bits to a data value. */
if ( Token < DCT_VAL_CATEGORY3 ) {
/* Offset from LOW_VAL_TOKENS determines value */
Token = Token - LOW_VAL_TOKENS;
/* Extra bit determines sign */
if ( ExtraBits )
ExpandedBlock[*CoeffIndex] =
-((Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN));
else
ExpandedBlock[*CoeffIndex] =
(Q_LIST_ENTRY)(Token + DCT_VAL_CAT2_MIN);
} else if ( Token == DCT_VAL_CATEGORY3 ) {
/* Bit 1 determines sign, Bit 0 the value */
if ( ExtraBits & 0x02 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT3_MIN + (ExtraBits & 0x01));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT3_MIN + (ExtraBits & 0x01);
} else if ( Token == DCT_VAL_CATEGORY4 ) {
/* Bit 2 determines sign, Bit 0-1 the value */
if ( ExtraBits & 0x04 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT4_MIN + (ExtraBits & 0x03));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT4_MIN + (ExtraBits & 0x03);
} else if ( Token == DCT_VAL_CATEGORY5 ) {
/* Bit 3 determines sign, Bit 0-2 the value */
if ( ExtraBits & 0x08 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT5_MIN + (ExtraBits & 0x07));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT5_MIN + (ExtraBits & 0x07);
} else if ( Token == DCT_VAL_CATEGORY6 ) {
/* Bit 4 determines sign, Bit 0-3 the value */
if ( ExtraBits & 0x10 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT6_MIN + (ExtraBits & 0x0F);
} else if ( Token == DCT_VAL_CATEGORY7 ) {
/* Bit 5 determines sign, Bit 0-4 the value */
if ( ExtraBits & 0x20 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT7_MIN + (ExtraBits & 0x1F);
} else if ( Token == DCT_VAL_CATEGORY8 ) {
/* Bit 9 determines sign, Bit 0-8 the value */
if ( ExtraBits & 0x200 )
ExpandedBlock[*CoeffIndex] = -(DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF));
else
ExpandedBlock[*CoeffIndex] = DCT_VAL_CAT8_MIN + (ExtraBits & 0x1FF);
}
/* Step on the coefficient index. */
*CoeffIndex += 1;
}
}
void ClearDownQFragData(PB_INSTANCE *pbi){
ogg_int32_t i,j;
Q_LIST_ENTRY * QFragPtr;
for ( i = 0; i < pbi->CodedBlockIndex; i++ ) {
/* Get the linear index for the current fragment. */
QFragPtr = pbi->QFragData[pbi->CodedBlockList[i]];
memset(QFragPtr, 0, 64*sizeof(Q_LIST_ENTRY));
}
}
void FilterHoriz(unsigned char * PixelPtr,
ogg_int32_t LineLength,
ogg_int32_t *BoundingValuePtr){
ogg_int32_t j;
ogg_int32_t FiltVal;
for ( j = 0; j < 8; j++ ){
FiltVal =
( PixelPtr[0] ) -
( PixelPtr[1] * 3 ) +
( PixelPtr[2] * 3 ) -
( PixelPtr[3] );
FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));
PixelPtr[1] = clamp255(PixelPtr[1] + FiltVal);
PixelPtr[2] = clamp255(PixelPtr[2] - FiltVal);
PixelPtr += LineLength;
}
}
void FilterVert(unsigned char * PixelPtr,
ogg_int32_t LineLength,
ogg_int32_t *BoundingValuePtr){
ogg_int32_t j;
ogg_int32_t FiltVal;
/* the math was correct, but negative array indicies are forbidden
by ANSI/C99 and will break optimization on several modern
compilers */
PixelPtr -= 2*LineLength;
for ( j = 0; j < 8; j++ ) {
FiltVal = ( (ogg_int32_t)PixelPtr[0] ) -
( (ogg_int32_t)PixelPtr[LineLength] * 3 ) +
( (ogg_int32_t)PixelPtr[2 * LineLength] * 3 ) -
( (ogg_int32_t)PixelPtr[3 * LineLength] );
FiltVal = *(BoundingValuePtr+((FiltVal + 4) >> 3));
PixelPtr[LineLength] = clamp255(PixelPtr[LineLength] + FiltVal);
PixelPtr[2 * LineLength] = clamp255(PixelPtr[2*LineLength] - FiltVal);
PixelPtr ++;
}
}
void LoopFilter(PB_INSTANCE *pbi){
ogg_int32_t i;
ogg_int32_t * BoundingValuePtr=pbi->BoundingValuePtr;//pbi->FiltBoundingValue+256;
int FragsAcross=pbi->HFragments;
int FromFragment,ToFragment;
int FragsDown = pbi->VFragments;
ogg_int32_t LineFragments;
ogg_int32_t LineLength;
ogg_int32_t FLimit;
int QIndex;
int j,m,n;
/* Set the limit value for the loop filter based upon the current
quantizer. */
QIndex = Q_TABLE_SIZE - 1;
while ( QIndex >= 0 ) {
if ( (QIndex == 0) ||
( pbi->QThreshTable[QIndex] >= pbi->ThisFrameQualityValue) )
break;
QIndex --;
}
FLimit = pbi->LoopFilterLimits[QIndex];
if ( FLimit == 0 ) return;
dsp_funcs.SetupBoundingValueArray(pbi, FLimit);
for ( j = 0; j < 3 ; j++){
switch(j) {
case 0: /* y */
FromFragment = 0;
ToFragment = pbi->YPlaneFragments;
FragsAcross = pbi->HFragments;
FragsDown = pbi->VFragments;
LineLength = pbi->YStride;
LineFragments = pbi->HFragments;
break;
case 1: /* u */
FromFragment = pbi->YPlaneFragments;
ToFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments ;
FragsAcross = pbi->HFragments >> 1;
FragsDown = pbi->VFragments >> 1;
LineLength = pbi->UVStride;
LineFragments = pbi->HFragments / 2;
break;
/*case 2: v */
default:
FromFragment = pbi->YPlaneFragments + pbi->UVPlaneFragments;
ToFragment = pbi->YPlaneFragments + (2 * pbi->UVPlaneFragments) ;
FragsAcross = pbi->HFragments >> 1;
FragsDown = pbi->VFragments >> 1;
LineLength = pbi->UVStride;
LineFragments = pbi->HFragments / 2;
break;
}
i=FromFragment;
/**************************************************************
First Row
**************************************************************/
/* first column conditions */
/* only do 2 prediction if fragment coded and on non intra or if
all fragments are intra */
if( pbi->display_fragments[i]){
/* Filter right hand border only if the block to the right is
not coded */
if ( !pbi->display_fragments[ i + 1 ] ){
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i]+6,
LineLength,BoundingValuePtr);
}
/* Bottom done if next row set */
if( !pbi->display_fragments[ i + LineFragments] ){
dsp_funcs.FilterVert(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i+LineFragments],
LineLength, BoundingValuePtr);
}
}
i++;
/***************************************************************/
/* middle columns */
for ( n = 1 ; n < FragsAcross - 1 ; n++, i++) {
if( pbi->display_fragments[i]){
/* Filter Left edge always */
dsp_funcs.FilterHoriz(pbi->LastFrameRecon+
pbi->recon_pixel_index_table[i]-2,
LineLength, BoundingValuePtr);
/* Filter right hand border only if the block to the right is
not coded */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -