我正在进行图像处理,并且一直使用class I pulled from CodeProject called CBitmapEx。
该类管理数据缓冲区,并具有转换位图图像的有用功能。它被设计为使用32位图像,但我稍微修改了它,因为我将描述使用24位图像。
仅在特定情况下,当CBitmapEx实例的析构函数尝试释放它在创建时设置了分辨率时分配的内存时,我收到堆损坏错误。
我怀疑问题的根源在于一个方法,其中包含一些内联汇编,它将对另一个CBitmapEx的内容进行缩放绘制。
导致错误的标准是:
我在Direct2D窗口中显示目标位图,并且没有可视指示缩放绘制以任何方式失败。
CodeProject类适用于32位位图,但我使用的是24位,因此我必须在'drawScaled'方法的程序集中修改两行,结果是视觉上正确复制的图像。
在列表中有两行:
add edi, 3
add ebx, 3
我从原来改变了这些:
add edi, 4
add ebx, 4
此更改导致该方法在处理24位图像时正常工作。我的怀疑是,程序集中可能还有其他东西仍然是32位并且是问题的根源。任何人都可以在代码中看到这样的东西吗?
void CBitmapEx::drawScaled(long dstX,
long dstY,
long dstWidth,
long dstHeight,
CBitmapEx& bitmapEx,
long srcX,
long srcY,
long srcWidth,
long srcHeight){
// Check for valid bitmap
if (isValid() && bitmapEx.isValid())
{
// Calculate destination params
long _dstStartX = max(0, min(_bih.biWidth-1, dstX));
if (srcX < 0)
_dstStartX = max(0, min(_bih.biWidth-1, dstX-srcX));
long _dstStartY = max(0, min(_bih.biHeight-1, dstY));
if (srcY < 0)
_dstStartY = max(0, min(_bih.biHeight-1, dstY-srcY));
long _dstEndX = max(0, min(dstX+dstWidth, _bih.biWidth-1));
long _dstEndY = max(0, min(dstY+dstHeight, _bih.biHeight-1));
long _dstWidth = _dstEndX - _dstStartX + 1;
long _dstHeight = _dstEndY - _dstStartY + 1;
// Calculate source params
long _srcStartX = max(0, min(bitmapEx.getWidth()-1, srcX));
if (dstX < 0)
_srcStartX = max(0, min(bitmapEx.getWidth()-1, srcX-dstX));
long _srcStartY = max(0, min(bitmapEx.getHeight()-1, srcY));
if (dstY < 0)
_srcStartY = max(0, min(bitmapEx.getHeight()-1, srcY-dstY));
long _srcEndX = max(0, min(srcX+srcWidth, bitmapEx.getWidth()-1));
long _srcEndY = max(0, min(srcY+srcHeight, bitmapEx.getHeight()-1));
long _srcWidth = _srcEndX - _srcStartX + 1;
long _srcHeight = _srcEndY - _srcStartY + 1;
// Check drawing region
if ((_dstWidth == 0) || (_dstHeight == 0) || (_srcWidth == 0) || (_srcHeight == 0))
return;
// Calculate scaling params
long _height = bitmapEx.getHeight();
long _pitch = bitmapEx.getPitch();
long _bpp = bitmapEx.getBpp() >> 3;
float dx = (float)_srcWidth / (float)_dstWidth;
float dy = (float)_srcHeight / (float)_dstHeight;
fixed f_dx = ftofx(dx);
fixed f_dy = ftofx(dy);
// Draw bitmap
DWORD dwDstHorizontalStartOffset = _dstStartX * _iBpp;
DWORD dwDstVerticalOffset = (_bih.biHeight-_dstStartY-1) * _iPitch;
LPDWORD lpDstData = (LPDWORD)_lpData;
LPDWORD lpSrcData = (LPDWORD)bitmapEx.getData();
DWORD dwDstPitch = _iPitch;
__asm {
mov edi, lpDstData
add edi, dwDstVerticalOffset
add edi, dwDstHorizontalStartOffset
xor edx, edx
outer_loop:
xor ecx, ecx
xor ebx, ebx
inner_loop:
push ebx
push edx
mov ebx, _height
sub ebx, _srcStartY
mov eax, edx
shl eax, 8
mul f_dy
shr eax, 16
sub ebx, eax
dec ebx
mov eax, ebx
mul _pitch
push eax
mov ebx, _srcStartX
mov eax, ecx
shl eax, 8
mul f_dx
shr eax, 16
add eax, ebx
mul _bpp
pop ebx
add eax, ebx
mov esi, lpSrcData
add esi, eax
mov eax, [esi]
mov [edi], eax
pop edx
pop ebx
add edi, 3
add ebx, 3
inc ecx
cmp ecx, _dstWidth
jl inner_loop
sub edi, ebx
sub edi, dwDstPitch
inc edx
cmp edx, _dstHeight
jl outer_loop
}
}
}