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;
}
}
精彩评论