开发者

C++: Optimizing a simple image clipping operation... too many if() statements

The code I have here is preliminary. I am focusing on the clipping procedures. There seems to be a lot of if() statements, and I'm hoping someone will have a clever way of optimizing this at least a little bit.

If you're wondering what m_nStride is, it's the number of elements to add to any given p开发者_C百科ixel pointer to reach the pixel directly below it (y + 1, x + 0). But either way, that is unimportant pertaining to my question.

The general idea is to fill a rectangular area of the image (32-bpp) using coordinates left, top, width and height. In cases where the coordinates would cause that area to cross the boundaries of the image, the area would be clipped to fit inside the image instead of being interpreted as an error.

void Image::Clear(int nLeft, int nTop, int nWidth, int nHeight, DWORD dwColor)
{
    if(nWidth <= 0) return;
    if(nHeight <= 0) return;
    if(nLeft >= m_nWidth) return;
    if(nTop >= m_nHeight) return;

    if(nLeft < 0)
    {
        nWidth += nLeft;
        if(nWidth <= 0)
            return;
        nLeft = 0;
    }

    if(nTop < 0)
    {
        nHeight += nTop;
        if(nHeight <= 0)
            return;
        nTop = 0;
    }

    if(nLeft + nWidth > m_nWidth)
    {
        nWidth -= ((nLeft + nWidth) - m_nWidth);
        if(nWidth <= 0) 
            return;
    }

    if(nTop + nHeight > m_nHeight)
    {
        nHeight -= ((nTop + nHeight) - m_nHeight);
        if(nHeight <= 0)
            return;
    }

    DWORD *p = m_pBuffer + (m_nStride * nTop) + nLeft;
    for(int y = 0; y < nHeight; y++)
    {
        for(int x = 0; x < nWidth; x++)
            p[x] = dwColor;
        p += m_nStride;
    }
}


For performance, the if overhead is virtually zero compared to the for loops. Nonetheless, as an exercise here's a version with fewer checks. It clips the bounds first and then only needs to check width and height being positive.

void Image::Clear(int nLeft, int nTop, int nWidth, int nHeight, DWORD dwColor)
{
    if(nLeft < 0)
    {
        nWidth += nLeft;
        nLeft = 0;
    }

    if(nTop < 0)
    {
        nHeight += nTop;
        nTop = 0;
    }

    if(nLeft + nWidth > m_nWidth)
    {
        nWidth = m_nWidth - nLeft;
    }

    if(nTop + nHeight > m_nHeight)
    {
        nHeight = m_nHeight - nTop;
    }

    if(nWidth <= 0) return;
    if(nHeight <= 0) return;

    DWORD *p = m_pBuffer + (m_nStride * nTop) + nLeft;
    for(int y = 0; y < nHeight; y++)
    {
        for(int x = 0; x < nWidth; x++)
            p[x] = dwColor;
        p += m_nStride;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜