📄 scan.c
字号:
CHLocalsPtr2 -= ppi->ChLocalsCircularBufferSize;
CHLocalsPtr2 -= 1;
/* The defining rule used here is as follows. */
/* An edge pixels has 3-5 changed locals. */
/* And one or more of these changed locals has itself got 7-8
changed locals. */
if ( RowType == NOT_EDGE_ROW ){
/* Loop for all pixels in the row. */
for ( i = 0; i < ppi->PlaneWidth; i += HFRAGPIXELS ){
/* Does the fragment contain anything interesting to work with. */
if ( *DispFragPtr == CANDIDATE_BLOCK ){
/* Reset the cumulative fragment score. */
FragScore = 0;
/* Pixels grouped along the row into fragments */
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* How many changed locals has the current pixel got. */
changed_locals = ChangedLocalsPtr[j];
/* Is the pixel a suitable candidate */
if ( (changed_locals > 2) && (changed_locals < 6) ){
/* The pixel may qualify... have a closer look. */
BodyNeighbours = 0;
/* Count the number of "BodyNeighbours" .. Pixels that
have 7 or more changed neighbours. */
if ( (i > 0) || (j > 0 ) ){
if ( CHLocalsPtr0[0] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr1[0] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr2[0] >= 7 )
BodyNeighbours++;
}
if ( CHLocalsPtr0[1] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr2[1] >= 7 )
BodyNeighbours++;
if ( (i + j) < LastRowIndex ){
if ( CHLocalsPtr0[2] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr1[2] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr2[2] >= 7 )
BodyNeighbours++;
}
if ( BodyNeighbours > 0 ){
AbsDiff = abs( YUVDiffsPtr[j] );
Score = (ogg_int32_t)
( (double)(BodyNeighbours *
BodyNeighbourScore) *
ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
if ( Score < 1 )
Score = 1;
/* Increment the score by a value determined by the
number of body neighbours. */
PixelNoiseScorePtr[j] += (unsigned char)Score;
FragScore += (ogg_uint32_t)Score;
}
}
/* Increment pointers into changed locals buffer */
CHLocalsPtr0 ++;
CHLocalsPtr1 ++;
CHLocalsPtr2 ++;
}
/* Add fragment score (with plane correction factor) into main
data structure */
*FragScorePtr += (ogg_int32_t)(FragScore *
ppi->YUVPlaneCorrectionFactor);
/* If score is greater than trip threshold then mark blcok for
update. */
if ( *FragScorePtr > ppi->BlockThreshold ){
*DispFragPtr = BLOCK_CODED_LOW;
}
}else{
/* Nothing to do for this fragment group */
/* Advance pointers into changed locals buffer */
CHLocalsPtr0 += HFRAGPIXELS;
CHLocalsPtr1 += HFRAGPIXELS;
CHLocalsPtr2 += HFRAGPIXELS;
}
/* Increment the various pointers */
FragScorePtr++;
DispFragPtr++;
PixelNoiseScorePtr += HFRAGPIXELS;
ChangedLocalsPtr += HFRAGPIXELS;
YUVDiffsPtr += HFRAGPIXELS;
}
}else{
/* This is either the top or bottom row of pixels in a plane. */
/* Loop for all pixels in the row. */
for ( i = 0; i < ppi->PlaneWidth; i += HFRAGPIXELS ){
/* Does the fragment contain anything interesting to work with. */
if ( *DispFragPtr == CANDIDATE_BLOCK ){
/* Reset the cumulative fragment score. */
FragScore = 0;
/* Pixels grouped along the row into fragments */
for ( j = 0; j < HFRAGPIXELS; j++ ){
/* How many changed locals has the current pixel got. */
changed_locals = ChangedLocalsPtr[j];
/* Is the pixel a suitable candidate */
if ( (changed_locals > 2) && (changed_locals < 6) ){
/* The pixel may qualify... have a closer look. */
BodyNeighbours = 0;
/* Count the number of "BodyNeighbours" .. Pixels
that have 7 or more changed neighbours. */
if ( RowType == LAST_ROW ){
/* Test for cases where it could be the first pixel on
the line */
if ( (i > 0) || (j > 0) ){
if ( CHLocalsPtr0[0] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr1[0] >= 7 )
BodyNeighbours++;
}
if ( CHLocalsPtr0[1] >= 7 )
BodyNeighbours++;
/* Test for the end of line case */
if ( (i + j) < LastRowIndex ){
if ( CHLocalsPtr0[2] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr1[2] >= 7 )
BodyNeighbours++;
}
}else{
/* First Row */
/* Test for cases where it could be the first pixel on
the line */
if ( (i > 0) || (j > 0) ){
if ( CHLocalsPtr1[0] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr2[0] >= 7 )
BodyNeighbours++;
}
/* Test for the end of line case */
if ( CHLocalsPtr2[1] >= 7 )
BodyNeighbours++;
if ( (i + j) < LastRowIndex ){
if ( CHLocalsPtr1[2] >= 7 )
BodyNeighbours++;
if ( CHLocalsPtr2[2] >= 7 )
BodyNeighbours++;
}
}
/* Allocate a score according to the number of Body neighbours. */
if ( BodyNeighbours > 0 ){
AbsDiff = abs( YUVDiffsPtr[j] );
Score = (ogg_int32_t)
( (double)(BodyNeighbours * BodyNeighbourScore) *
ppi->AbsDiff_ScoreMultiplierTable[AbsDiff] );
if ( Score < 1 )
Score = 1;
PixelNoiseScorePtr[j] += (unsigned char)Score;
FragScore += (ogg_uint32_t)Score;
}
}
/* Increment pointers into changed locals buffer */
CHLocalsPtr0 ++;
CHLocalsPtr1 ++;
CHLocalsPtr2 ++;
}
/* Add fragment score (with plane correction factor) into main
data structure */
*FragScorePtr +=
(ogg_int32_t)(FragScore * ppi->YUVPlaneCorrectionFactor);
/* If score is greater than trip threshold then mark blcok for
update. */
if ( *FragScorePtr > ppi->BlockThreshold ){
*DispFragPtr = BLOCK_CODED_LOW;
}
}else{
/* Nothing to do for this fragment group */
/* Advance pointers into changed locals buffer */
CHLocalsPtr0 += HFRAGPIXELS;
CHLocalsPtr1 += HFRAGPIXELS;
CHLocalsPtr2 += HFRAGPIXELS;
}
/* Increment the various pointers */
FragScorePtr++;
DispFragPtr++;
PixelNoiseScorePtr += HFRAGPIXELS;
ChangedLocalsPtr += HFRAGPIXELS;
YUVDiffsPtr += HFRAGPIXELS;
}
}
}
static void PixelLineSearch( PP_INSTANCE *ppi,
unsigned char * ChangedLocalsPtr,
ogg_int32_t RowNumber,
ogg_int32_t ColNumber,
unsigned char direction,
ogg_uint32_t * line_length ){
/* Exit if the pixel does not qualify or we have fallen off the edge
of either the image plane or the row. */
if ( ((*ChangedLocalsPtr) <= 1) ||
((*ChangedLocalsPtr) >= 6) ||
(RowNumber < 0) ||
(RowNumber >= ppi->PlaneHeight) ||
(ColNumber < 0) ||
(ColNumber >= ppi->PlaneWidth) ){
/* If not then it isn't part of any line. */
return;
}
if (*line_length < ppi->MaxLineSearchLen){
ogg_uint32_t TmpLineLength;
ogg_uint32_t BestLineLength;
unsigned char * search_ptr;
/* Increment the line length to include this pixel. */
*line_length += 1;
BestLineLength = *line_length;
/* Continue search */
/* up */
if ( direction == UP ){
TmpLineLength = *line_length;
search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
if ( search_ptr < ppi->ChLocals )
search_ptr += ppi->ChLocalsCircularBufferSize;
PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* up and left */
if ( (BestLineLength < ppi->MaxLineSearchLen) &&
((direction == UP) || (direction == LEFT)) ){
TmpLineLength = *line_length;
search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
if ( search_ptr < ppi->ChLocals )
search_ptr += ppi->ChLocalsCircularBufferSize;
search_ptr -= 1;
PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber - 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* up and right */
if ( (BestLineLength < ppi->MaxLineSearchLen) &&
((direction == UP) || (direction == RIGHT)) ){
TmpLineLength = *line_length;
search_ptr = ChangedLocalsPtr - ppi->PlaneWidth;
if ( search_ptr < ppi->ChLocals )
search_ptr += ppi->ChLocalsCircularBufferSize;
search_ptr += 1;
PixelLineSearch( ppi, search_ptr, RowNumber - 1, ColNumber + 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* left */
if ( (BestLineLength < ppi->MaxLineSearchLen) && ( direction == LEFT ) ){
TmpLineLength = *line_length;
PixelLineSearch( ppi, ChangedLocalsPtr - 1, RowNumber, ColNumber - 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* right */
if ( (BestLineLength < ppi->MaxLineSearchLen) && ( direction == RIGHT ) ){
TmpLineLength = *line_length;
PixelLineSearch( ppi, ChangedLocalsPtr + 1, RowNumber, ColNumber + 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* Down */
if ( BestLineLength < ppi->MaxLineSearchLen ){
TmpLineLength = *line_length;
if ( direction == DOWN ){
search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
search_ptr -= ppi->ChLocalsCircularBufferSize;
PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber, direction,
&TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* down and left */
if ( (BestLineLength < ppi->MaxLineSearchLen) &&
((direction == DOWN) || (direction == LEFT)) ){
TmpLineLength = *line_length;
search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
search_ptr -= ppi->ChLocalsCircularBufferSize;
search_ptr -= 1;
PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber - 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
/* down and right */
if ( (BestLineLength < ppi->MaxLineSearchLen) &&
((direction == DOWN) || (direction == RIGHT)) ){
TmpLineLength = *line_length;
search_ptr = ChangedLocalsPtr + ppi->PlaneWidth;
if ( search_ptr >= (ppi->ChLocals + ppi->ChLocalsCircularBufferSize) )
search_ptr -= ppi->ChLocalsCircularBufferSize;
search_ptr += 1;
PixelLineSearch( ppi, search_ptr, RowNumber + 1, ColNumber + 1,
direction, &TmpLineLength );
if ( TmpLineLength > BestLineLength )
BestLineLength = TmpLineLength;
}
}
/* Note the search value for this pixel. */
*line_length = BestLineLength;
}
}
static unsigned char LineSearchScorePixel( PP_INSTANCE *ppi,
unsigned char * ChangedLocalsPtr,
ogg_int32_t RowNumber,
ogg_int32_t ColNumber ){
ogg_uint32_t line_length = 0;
ogg_uint32_t line_length2 = 0;
ogg_uint32_t line_length_score = 0;
ogg_uint32_t tmp_line_length = 0;
ogg_uint32_t tmp_line_length2 = 0;
/* Look UP and Down */
PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber,
ColNumber, UP, &tmp_line_length );
if (tmp_line_length < ppi->MaxLineSearchLen) {
/* Look DOWN */
PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber,
ColNumber, DOWN, &tmp_line_length2 );
line_length = tmp_line_length + tmp_line_length2 - 1;
if ( line_length > ppi->MaxLineSearchLen )
line_length = ppi->MaxLineSearchLen;
}else
line_length = tmp_line_length;
/* If no max length line found then look left and right */
if ( line_length < ppi->MaxLineSearchLen ){
tmp_line_length = 0;
tmp_line_length2 = 0;
PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber,
ColNumber, LEFT, &tmp_line_length );
if (tmp_line_length < ppi->MaxLineSearchLen){
PixelLineSearch( ppi, ChangedLocalsPtr, RowNumber,
ColNumber, RIGHT, &tmp_line_length2 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -