⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prpclass.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
//------------------------------------------------------------------------------
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 + -