From 01e4624ed72128102e7cd01588271374fce7a927 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 8 May 2023 09:23:01 +0200 Subject: [PATCH] [progressive] fix tile cache resize ensure that the new cache size is larger than required. --- libfreerdp/codec/progressive.c | 54 +++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index 6bdd313d8..49be2824c 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -440,7 +440,7 @@ fail: return NULL; } -static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* surface) +static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* surface, size_t min) { size_t x; size_t oldIndex = 0; @@ -451,7 +451,8 @@ static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* surface if (surface->tiles) { oldIndex = surface->gridSize; - surface->gridSize += 1024; + while (surface->gridSize < min) + surface->gridSize += 1024; } void* tmp = winpr_aligned_recalloc(surface->tiles, surface->gridSize, @@ -481,7 +482,6 @@ static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* surface static PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfaceId, UINT32 width, UINT32 height) { - UINT32 x; PROGRESSIVE_SURFACE_CONTEXT* surface = (PROGRESSIVE_SURFACE_CONTEXT*)winpr_aligned_calloc( 1, sizeof(PROGRESSIVE_SURFACE_CONTEXT), 32); @@ -495,7 +495,7 @@ static PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfa surface->gridHeight = (height + (64 - height % 64)) / 64; surface->gridSize = surface->gridWidth * surface->gridHeight; - if (!progressive_allocate_tile_cache(surface)) + if (!progressive_allocate_tile_cache(surface, surface->gridSize)) { progressive_surface_context_free(surface); return NULL; @@ -571,7 +571,7 @@ static BOOL progressive_surface_tile_replace(PROGRESSIVE_SURFACE_CONTEXT* surfac } if (surface->numUpdatedTiles >= surface->tilesSize) { - if (!progressive_allocate_tile_cache(surface)) + if (!progressive_allocate_tile_cache(surface, surface->numUpdatedTiles)) return FALSE; } @@ -2495,11 +2495,8 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD UINT32 frameId) { INT32 rc = 1; - UINT32 i; - wStream *s, ss; - size_t start, end; - REGION16 clippingRects, updateRegion; - PROGRESSIVE_BLOCK_REGION* region = &progressive->region; + + WINPR_ASSERT(progressive); PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId); if (!surface) @@ -2509,13 +2506,18 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD return -1001; } + PROGRESSIVE_BLOCK_REGION* region = &progressive->region; + WINPR_ASSERT(region); + if (surface->frameId != frameId) { surface->frameId = frameId; surface->numUpdatedTiles = 0; } - s = Stream_StaticConstInit(&ss, pSrcData, SrcSize); + wStream ss = { 0 }; + wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize); + WINPR_ASSERT(s); switch (DstFormat) { @@ -2530,7 +2532,7 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD break; } - start = Stream_GetPosition(s); + const size_t start = Stream_GetPosition(s); progressive->state = 0; /* Set state to not initialized */ while (Stream_GetRemainingLength(s) > 0) { @@ -2538,7 +2540,7 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD goto fail; } - end = Stream_GetPosition(s); + const size_t end = Stream_GetPosition(s); if ((end - start) != SrcSize) { WLog_Print(progressive->log, WLOG_ERROR, @@ -2548,12 +2550,14 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD goto fail; } + REGION16 clippingRects = { 0 }; region16_init(&clippingRects); - for (i = 0; i < region->numRects; i++) + for (UINT32 i = 0; i < region->numRects; i++) { - RECTANGLE_16 clippingRect; + RECTANGLE_16 clippingRect = { 0 }; const RFX_RECT* rect = &(region->rects[i]); + clippingRect.left = (UINT16)nXDst + rect->x; clippingRect.top = (UINT16)nYDst + rect->y; clippingRect.right = clippingRect.left + rect->width; @@ -2561,22 +2565,30 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } - for (i = 0; i < surface->numUpdatedTiles; i++) + for (UINT32 i = 0; i < surface->numUpdatedTiles; i++) { - UINT32 nbUpdateRects, j; - const RECTANGLE_16* updateRects; - RECTANGLE_16 updateRect; - RFX_PROGRESSIVE_TILE* tile = surface->tiles[surface->updatedTileIndices[i]]; + UINT32 nbUpdateRects = 0; + const RECTANGLE_16* updateRects = NULL; + RECTANGLE_16 updateRect = { 0 }; + + WINPR_ASSERT(surface->updatedTileIndices); + const UINT32 index = surface->updatedTileIndices[i]; + + WINPR_ASSERT(index < surface->tilesSize); + RFX_PROGRESSIVE_TILE* tile = surface->tiles[index]; + WINPR_ASSERT(tile); updateRect.left = nXDst + tile->x; updateRect.top = nYDst + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; + + REGION16 updateRegion = { 0 }; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = region16_rects(&updateRegion, &nbUpdateRects); - for (j = 0; j < nbUpdateRects; j++) + for (UINT32 j = 0; j < nbUpdateRects; j++) { const RECTANGLE_16* rect = &updateRects[j]; const UINT32 nXSrc = rect->left - (nXDst + tile->x);