libfreerdp-gdi: fix SurfaceToSurface overlapping copies
This commit is contained in:
parent
1837c34e6e
commit
c40d8155a6
@ -628,6 +628,7 @@ int xf_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill)
|
||||
int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
|
||||
{
|
||||
UINT16 index;
|
||||
BOOL sameSurface;
|
||||
int nWidth, nHeight;
|
||||
RDPGFX_RECT16* rectSrc;
|
||||
RDPGFX_POINT16* destPt;
|
||||
@ -638,11 +639,12 @@ int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_
|
||||
|
||||
rectSrc = &(surfaceToSurface->rectSrc);
|
||||
destPt = &surfaceToSurface->destPts[0];
|
||||
/**not needed?*/
|
||||
|
||||
surfaceSrc = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
|
||||
|
||||
if (surfaceToSurface->surfaceIdSrc != surfaceToSurface->surfaceIdDest)
|
||||
sameSurface = (surfaceToSurface->surfaceIdSrc == surfaceToSurface->surfaceIdDest) ? TRUE : FALSE;
|
||||
|
||||
if (!sameSurface)
|
||||
surfaceDst = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest);
|
||||
else
|
||||
surfaceDst = surfaceSrc;
|
||||
@ -657,16 +659,22 @@ int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_
|
||||
{
|
||||
destPt = &surfaceToSurface->destPts[index];
|
||||
|
||||
freerdp_image_copy(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, PIXEL_FORMAT_XRGB32,
|
||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||
if (sameSurface)
|
||||
{
|
||||
freerdp_image_move(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, rectSrc->left, rectSrc->top);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_image_copy(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, PIXEL_FORMAT_XRGB32,
|
||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||
}
|
||||
|
||||
invalidRect.left = destPt->x;
|
||||
invalidRect.top = destPt->y;
|
||||
invalidRect.right = destPt->x + rectSrc->right;
|
||||
invalidRect.bottom = destPt->y + rectSrc->bottom;
|
||||
|
||||
/**width,height?*/
|
||||
|
||||
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
|
||||
}
|
||||
|
@ -454,6 +454,8 @@ FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv);
|
||||
|
||||
FREERDP_API int freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst,
|
||||
int nWidth, int nHeight, BYTE* pSrcData, DWORD SrcFormat, int nSrcStep, int nXSrc, int nYSrc);
|
||||
FREERDP_API int freerdp_image_move(BYTE* pData, DWORD Format, int nStep, int nXDst, int nYDst,
|
||||
int nWidth, int nHeight, int nXSrc, int nYSrc);
|
||||
FREERDP_API int freerdp_image_fill(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst,
|
||||
int nWidth, int nHeight, UINT32 color);
|
||||
|
||||
|
@ -1878,6 +1878,91 @@ int freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int freerdp_image_move(BYTE* pData, DWORD Format, int nStep, int nXDst, int nYDst, int nWidth, int nHeight, int nXSrc, int nYSrc)
|
||||
{
|
||||
int y;
|
||||
BOOL overlap;
|
||||
BYTE* pSrcPixel;
|
||||
BYTE* pDstPixel;
|
||||
|
||||
overlap = (((nXDst + nWidth) > nXSrc) && (nXDst < (nXSrc + nWidth)) &&
|
||||
((nYDst + nHeight) > nYSrc) && (nYDst < (nYSrc + nHeight))) ? TRUE : FALSE;
|
||||
|
||||
if (!overlap)
|
||||
{
|
||||
pSrcPixel = &pData[(nYSrc * nStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pData[(nYDst * nStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
CopyMemory(pDstPixel, pSrcPixel, nWidth * 4);
|
||||
pSrcPixel += nStep;
|
||||
pDstPixel += nStep;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (nYSrc < nYDst)
|
||||
{
|
||||
/* copy down */
|
||||
|
||||
pSrcPixel = &pData[((nYSrc + nHeight - 1) * nStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pData[((nYDst + nHeight - 1) * nStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
CopyMemory(pDstPixel, pSrcPixel, nWidth * 4);
|
||||
pSrcPixel -= nStep;
|
||||
pDstPixel -= nStep;
|
||||
}
|
||||
}
|
||||
else if (nYSrc > nYDst)
|
||||
{
|
||||
/* copy up */
|
||||
|
||||
pSrcPixel = &pData[(nYSrc * nStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pData[(nYDst * nStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
CopyMemory(pDstPixel, pSrcPixel, nWidth * 4);
|
||||
pSrcPixel += nStep;
|
||||
pDstPixel += nStep;
|
||||
}
|
||||
}
|
||||
else if (nXSrc > nXDst)
|
||||
{
|
||||
/* copy left */
|
||||
|
||||
pSrcPixel = &pData[(nYSrc * nStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pData[(nYDst * nStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
MoveMemory(pDstPixel, pSrcPixel, nWidth * 4);
|
||||
pSrcPixel += nStep;
|
||||
pDstPixel += nStep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* copy right */
|
||||
|
||||
pSrcPixel = &pData[(nYSrc * nStep) + (nXSrc * 4)];
|
||||
pDstPixel = &pData[(nYDst * nStep) + (nXDst * 4)];
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
MoveMemory(pDstPixel, pSrcPixel, nWidth * 4);
|
||||
pSrcPixel += nStep;
|
||||
pDstPixel += nStep;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* freerdp_image_memset32(UINT32* ptr, UINT32 fill, size_t length)
|
||||
{
|
||||
while (length--)
|
||||
|
@ -633,6 +633,7 @@ int gdi_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill
|
||||
int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
|
||||
{
|
||||
UINT16 index;
|
||||
BOOL sameSurface;
|
||||
int nWidth, nHeight;
|
||||
RDPGFX_RECT16* rectSrc;
|
||||
RDPGFX_POINT16* destPt;
|
||||
@ -646,7 +647,9 @@ int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE
|
||||
|
||||
surfaceSrc = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
|
||||
|
||||
if (surfaceToSurface->surfaceIdSrc != surfaceToSurface->surfaceIdDest)
|
||||
sameSurface = (surfaceToSurface->surfaceIdSrc == surfaceToSurface->surfaceIdDest) ? TRUE : FALSE;
|
||||
|
||||
if (!sameSurface)
|
||||
surfaceDst = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest);
|
||||
else
|
||||
surfaceDst = surfaceSrc;
|
||||
@ -661,9 +664,17 @@ int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE
|
||||
{
|
||||
destPt = &surfaceToSurface->destPts[index];
|
||||
|
||||
freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, surfaceSrc->format,
|
||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||
if (sameSurface)
|
||||
{
|
||||
freerdp_image_move(surfaceDst->data, surfaceDst->format, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, rectSrc->left, rectSrc->top);
|
||||
}
|
||||
else
|
||||
{
|
||||
freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline,
|
||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, surfaceSrc->format,
|
||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||
}
|
||||
|
||||
invalidRect.left = destPt->x;
|
||||
invalidRect.top = destPt->y;
|
||||
|
Loading…
Reference in New Issue
Block a user