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)
|
int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
|
||||||
{
|
{
|
||||||
UINT16 index;
|
UINT16 index;
|
||||||
|
BOOL sameSurface;
|
||||||
int nWidth, nHeight;
|
int nWidth, nHeight;
|
||||||
RDPGFX_RECT16* rectSrc;
|
RDPGFX_RECT16* rectSrc;
|
||||||
RDPGFX_POINT16* destPt;
|
RDPGFX_POINT16* destPt;
|
||||||
@ -638,11 +639,12 @@ int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_
|
|||||||
|
|
||||||
rectSrc = &(surfaceToSurface->rectSrc);
|
rectSrc = &(surfaceToSurface->rectSrc);
|
||||||
destPt = &surfaceToSurface->destPts[0];
|
destPt = &surfaceToSurface->destPts[0];
|
||||||
/**not needed?*/
|
|
||||||
|
|
||||||
surfaceSrc = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
|
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);
|
surfaceDst = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest);
|
||||||
else
|
else
|
||||||
surfaceDst = surfaceSrc;
|
surfaceDst = surfaceSrc;
|
||||||
@ -657,17 +659,23 @@ int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_
|
|||||||
{
|
{
|
||||||
destPt = &surfaceToSurface->destPts[index];
|
destPt = &surfaceToSurface->destPts[index];
|
||||||
|
|
||||||
|
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,
|
freerdp_image_copy(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline,
|
||||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, PIXEL_FORMAT_XRGB32,
|
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, PIXEL_FORMAT_XRGB32,
|
||||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||||
|
}
|
||||||
|
|
||||||
invalidRect.left = destPt->x;
|
invalidRect.left = destPt->x;
|
||||||
invalidRect.top = destPt->y;
|
invalidRect.top = destPt->y;
|
||||||
invalidRect.right = destPt->x + rectSrc->right;
|
invalidRect.right = destPt->x + rectSrc->right;
|
||||||
invalidRect.bottom = destPt->y + rectSrc->bottom;
|
invalidRect.bottom = destPt->y + rectSrc->bottom;
|
||||||
|
|
||||||
/**width,height?*/
|
|
||||||
|
|
||||||
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
|
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,
|
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);
|
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,
|
FREERDP_API int freerdp_image_fill(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst,
|
||||||
int nWidth, int nHeight, UINT32 color);
|
int nWidth, int nHeight, UINT32 color);
|
||||||
|
|
||||||
|
@ -1878,6 +1878,91 @@ int freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst,
|
|||||||
return -1;
|
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)
|
void* freerdp_image_memset32(UINT32* ptr, UINT32 fill, size_t length)
|
||||||
{
|
{
|
||||||
while (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)
|
int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface)
|
||||||
{
|
{
|
||||||
UINT16 index;
|
UINT16 index;
|
||||||
|
BOOL sameSurface;
|
||||||
int nWidth, nHeight;
|
int nWidth, nHeight;
|
||||||
RDPGFX_RECT16* rectSrc;
|
RDPGFX_RECT16* rectSrc;
|
||||||
RDPGFX_POINT16* destPt;
|
RDPGFX_POINT16* destPt;
|
||||||
@ -646,7 +647,9 @@ int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE
|
|||||||
|
|
||||||
surfaceSrc = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc);
|
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);
|
surfaceDst = (gdiGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest);
|
||||||
else
|
else
|
||||||
surfaceDst = surfaceSrc;
|
surfaceDst = surfaceSrc;
|
||||||
@ -661,9 +664,17 @@ int gdi_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE
|
|||||||
{
|
{
|
||||||
destPt = &surfaceToSurface->destPts[index];
|
destPt = &surfaceToSurface->destPts[index];
|
||||||
|
|
||||||
|
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,
|
freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline,
|
||||||
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, surfaceSrc->format,
|
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, surfaceSrc->format,
|
||||||
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
surfaceSrc->scanline, rectSrc->left, rectSrc->top);
|
||||||
|
}
|
||||||
|
|
||||||
invalidRect.left = destPt->x;
|
invalidRect.left = destPt->x;
|
||||||
invalidRect.top = destPt->y;
|
invalidRect.top = destPt->y;
|
||||||
|
Loading…
Reference in New Issue
Block a user