📄 prpclass.cpp
字号:
//
//------------------------------------------------------------------------------
BOOL PrpClass::PrpResize(UINT32 in, UINT32 out, prpResizeChannel channel,
prpResizeDimension dimension)
{
pPrpResizeParams pParam = NULL;
UINT8 retry = 0;
BOOL bRet = TRUE;
pParam = (pPrpResizeParams) malloc(sizeof(prpResizeParams));
if (pParam == NULL) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Resize parameter object allocation failed! \r\n"),
__WFUNCTION__));
bRet = FALSE;
goto _exit;
}
memset(pParam, 0, sizeof(prpResizeParams));
if (in == out) {
bRet = PrpGetCoeff(pParam, 1, 1);
if (bRet == FALSE) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Resizing failed due to same input and output size. \r\n"),
__WFUNCTION__));
goto _exit;
}
} else {
UINT tmpOut = out;
while (retry <= MAX_RESIZE_RETRIES) {
UINT16 gcd = PrpGetGcd(in, tmpOut);
bRet = PrpGetCoeff(pParam, in/gcd, tmpOut/gcd);
if (bRet == TRUE) {
// Get it!! Quit loop
pParam->in = in / gcd;
pParam->out = tmpOut / gcd;
DEBUGMSG(ZONE_FUNCTION,
(TEXT("%s: Resize actual size, in (%d), out (%d) \r\n"),
__WFUNCTION__, pParam->in, pParam->out));
break;
} else {
retry++;
tmpOut++;
}
}
}
if (retry > MAX_RESIZE_RETRIES) {
// In this case, PrpGetCoeff() failed.
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Pre-processor gets coefficient failed! \r\n"),
__WFUNCTION__));
goto _exit;
}
PrpPackToRegister(pParam, channel, dimension);
_exit:
if (pParam) {
free(pParam);
pParam = NULL;
}
return bRet;
}
//------------------------------------------------------------------------------
//
// Function: PrpGetGcd
//
// This function is used to calculate the greatest common divider of the
// two passed in parameters. This code is reused from Symbian.
//
// Parameters:
// x
// [in] One number.
//
// y
// [in] The other one.
//
// Returns:
// The greatest common divider of x and y.
//
//------------------------------------------------------------------------------
UINT16 PrpClass::PrpGetGcd(UINT16 x, UINT16 y)
{
UINT16 temp;
if (x < y) {
temp = y;
y = x;
x = temp;
}
if ((x % y) == 0) return y;
while ((temp = (x % y)) != 0) {
x = y;
y = temp;
}
return y;
}
//------------------------------------------------------------------------------
//
// Function: PrpGetCoeff
//
// This function is used to calculate the resize coefficients.
//
// Parameters:
// pParam
// [in] Pre-processing resize parameters.
//
// in
// [in] input.
//
// out
// [in] output.
//
// Returns:
// TRUE if success; FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL PrpClass::PrpGetCoeff(pPrpResizeParams pParam, UINT16 in, UINT16 out)
{
if (in > MAX_RESIZE_COEFFS) {
// We support only 20 coefficients space
DEBUGMSG(ZONE_FUNCTION,
(TEXT("%s: No enough coefficient space! \r\n"),
__WFUNCTION__));
return FALSE;
}
if (in == out) {
//
// Averaging interpolation
//
pParam->tbl_len = 1;
pParam->algo = prpResize_Averaging;
pParam->resize_tbl[0] = MAX_COEFF_VALUE - 1;
pParam->output_bits = 1;
} else if (in < PRP_RESIZE_THRESHOLD * out) {
//
// Bilinear interpolation
//
pParam->tbl_len = in;
pParam->algo = prpResize_Bilinear;
// For downscaling from 1:1 to 2:1
UINT16 inPos1 = out;
UINT16 inPosInc = out << 1;
UINT16 inPos2 = inPos1 + inPosInc;
UINT16 outPos = in;
UINT16 outPosInc = in << 1;
UINT16 init_carry = in - out;
UINT16 carry = init_carry;
UINT8 index = 0;
do {
int w1 = inPos2 - outPos;
int n = 0;
outPos += outPosInc;
carry += outPosInc;
PrpStoreCoeff(pParam->resize_tbl, &pParam->output_bits,
index, (out<<1), w1, 1); // (w1,1)
index++;
while (inPos2 < outPos) {
inPos1 = inPos2;
inPos2 += inPosInc;
n++;
carry -= inPosInc;
if (n > 1) {
PrpStoreCoeff(pParam->resize_tbl, &pParam->output_bits,
index, (out<<1), 0, 0); //(X,0)
index++;
}
}
} while (carry != init_carry);
} else {
//
// Average algo for all the other downscaling > 2:1
//
pParam->tbl_len = in;
pParam->algo = prpResize_Averaging;
// Start algo
UINT8 piece_len = in/out;
UINT8 num_pieces_plus_1 = in % out;
UINT8 num_pieces_plus_0 = out - num_pieces_plus_1;
UINT8 cur_index = 0;
for (; num_pieces_plus_1 > 0; num_pieces_plus_1--) {
PrpStoreCoeff(pParam->resize_tbl, &pParam->output_bits,
cur_index, piece_len+1);
cur_index += (piece_len+1);
}
for (; num_pieces_plus_0 > 0; num_pieces_plus_0--) {
PrpStoreCoeff(pParam->resize_tbl, &pParam->output_bits,
cur_index, piece_len);
cur_index += (piece_len);
}
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: PrpStoreCoeff
//
// This function is to store the coefficients for bilinear resizing.
//
// Parameters:
// resize_tbl
// [out] Resizing table.
//
// output_bits
// [out] Number of bits to output.
//
// index
// [in] Index in the table.
//
// base
// [in] UINT8.
//
// w1
// [in] UINT8.
//
// output
// [in] UINT8.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void PrpClass::PrpStoreCoeff(UINT8 *resize_tbl, UINT32 *output_bits,
UINT8 index, UINT8 base, UINT8 w1, UINT8 output)
{
// w1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
// reg | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 |
w1 = ((w1 << RESIZE_COEFF_WIDTH) + (base >> 1)) / base;
if (w1 >= MAX_COEFF_VALUE - 1) {
// Coeff 7 is regarded as 8.
w1--;
} else if (w1 == 1) {
// Because 7 (8-1) is regarded as 8 (8-0),
// coeff 1 is regarded as 0.
w1--;
}
resize_tbl[index] = w1;
if (output == 1)
*output_bits |= (1UL << index);
else
*output_bits &= ~(1UL << index);
}
//------------------------------------------------------------------------------
//
// Function: PrpStoreCoeff
//
// This function is to store the coefficients for averaging resize.
//
// Parameters:
// resize_tbl
// [out] Resizing table.
//
// output_bits
// [out] Number of bits to output.
//
// startindex
// [in] The start index in resizing table.
//
// len
// [in] Length.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void PrpClass::PrpStoreCoeff(UINT8 *resize_tbl, UINT32 *output_bits,
UINT8 startindex, UINT8 len)
{
PrpFillAveragingCoeff(&resize_tbl[startindex], len);
// Don't output for 1st len-1 bits
*output_bits &= ~( (0xFFFFFFFFUL >> (32-len)) << startindex );
// Output for len bit
*output_bits |= 1UL << (startindex+len-1);
}
//------------------------------------------------------------------------------
//
// Function: PrpFillAveragingCoeff
//
// This function is to use Gaussian filter coefficients for averaging resize.
//
// Parameters:
// startptr
// [in] The start pointer.
//
// filter_width
// [in] The filter width.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
void PrpClass::PrpFillAveragingCoeff(UINT8 *startptr, UINT8 filter_width)
{
// This routine contains hardcoded convolution filter coeffs based on
// PrP's constraint that sum of each filter can only be max 8.
static const UINT8 filter_coeff_tbl[][9] = {
{8},
{4,4},
{2,4,2},
{2,2,2,2},
{1,2,2,2,1},
{1,1,2,2,1,1},
{1,1,1,2,1,1,1},
{1,1,1,1,1,1,1,1}, // similar to 6
{1,1,1,1,1,1,1,1,0} // similar to 7
};
if (filter_width >= 10) {
// Use equal distribution if filter width is 10 or more
int zeros = (filter_width - 8) / 2;
int i = zeros + (filter_width & 1); // if odd then add one
for(; i--; *(startptr++) = 0);
for(i=8; i--; *(startptr++) = 1);
for(i=zeros; i--; *(startptr++) = 0);
} else {
// Copy coeff from table
memcpy(startptr, filter_coeff_tbl[filter_width-1], filter_width);
}
}
//------------------------------------------------------------------------------
//
// Function: PrpPackToRegister
//
// This function is to load the calculated resize coeffients into resize
// registers. It is tightly dependent on hardware and hence not portable.
//
// Parameters:
// pParams
// [in] Resize parameters.
//
// channel
// [in] Channel selection.
//
// dimension
// [in] Dimension selection.
//
// Returns:
//
//------------------------------------------------------------------------------
void PrpClass::PrpPackToRegister(pPrpResizeParams pParams,
prpResizeChannel channel, prpResizeDimension dimension)
{
UINT16 len = pParams->tbl_len;
UINT8 *tblptr = pParams->resize_tbl + len - 1; // Set pointer to last valid elem
UINT32 rz_coef2 = 0;
UINT32 rz_coef1 = 0;
// Pack resize coef
switch (len) {
// rz_coef2
case 20: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 3;
case 19: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 3;
case 18: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 3;
case 17: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 3;
case 16: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 4;
case 15: rz_coef2 |= *(tblptr--) & 0x7; rz_coef2 <<= 3;
case 14: rz_coef2 |= *(tblptr--) & 0x7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -