[codec,progressive] fix segfault and optimize updated tiles
The number of updated tiles was not reset at the end of a progressive block treatment leading to possibly overflow the updatedTiles array. This patch also introduces a dirty bit on tiles, so that a tile updated multiple times is just mark once as modified.
This commit is contained in:
parent
6ec762fdec
commit
4e24b966c8
@ -418,23 +418,24 @@ static INLINE RFX_PROGRESSIVE_TILE* progressive_tile_new(void)
|
|||||||
tile->height = 64;
|
tile->height = 64;
|
||||||
tile->stride = 4 * tile->width;
|
tile->stride = 4 * tile->width;
|
||||||
|
|
||||||
size_t dataLen = tile->stride * tile->height * 1ULL;
|
size_t dataLen = tile->stride * tile->height * 1ULL;
|
||||||
tile->data = (BYTE*)winpr_aligned_malloc(dataLen, 16);
|
tile->data = (BYTE*)winpr_aligned_malloc(dataLen, 16);
|
||||||
if (!tile->data)
|
if (!tile->data)
|
||||||
goto fail;
|
goto fail;
|
||||||
memset(tile->data, 0xFF, dataLen);
|
memset(tile->data, 0xFF, dataLen);
|
||||||
|
|
||||||
size_t signLen = (8192 + 32) * 3;
|
size_t signLen = (8192 + 32) * 3;
|
||||||
tile->sign = (BYTE*)winpr_aligned_calloc(signLen, sizeof(BYTE), 16);
|
tile->sign = (BYTE*)winpr_aligned_calloc(signLen, sizeof(BYTE), 16);
|
||||||
if (!tile->sign)
|
if (!tile->sign)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
size_t currentLen = (8192 + 32) * 3;
|
size_t currentLen = (8192 + 32) * 3;
|
||||||
tile->current = (BYTE*)winpr_aligned_calloc(currentLen, sizeof(BYTE), 16);
|
tile->current = (BYTE*)winpr_aligned_calloc(currentLen, sizeof(BYTE), 16);
|
||||||
if (!tile->current)
|
if (!tile->current)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
return tile;
|
||||||
|
|
||||||
return tile;
|
|
||||||
fail:
|
fail:
|
||||||
progressive_tile_free(tile);
|
progressive_tile_free(tile);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -466,7 +467,7 @@ static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* surface
|
|||||||
{
|
{
|
||||||
surface->tiles[x] = progressive_tile_new();
|
surface->tiles[x] = progressive_tile_new();
|
||||||
if (!surface->tiles[x])
|
if (!surface->tiles[x])
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp =
|
tmp =
|
||||||
@ -569,14 +570,20 @@ static BOOL progressive_surface_tile_replace(PROGRESSIVE_SURFACE_CONTEXT* surfac
|
|||||||
region->numTiles, region->usedTiles);
|
region->numTiles, region->usedTiles);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (surface->numUpdatedTiles >= surface->tilesSize)
|
|
||||||
{
|
|
||||||
if (!progressive_allocate_tile_cache(surface, surface->numUpdatedTiles))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
region->tiles[region->usedTiles++] = t;
|
region->tiles[region->usedTiles++] = t;
|
||||||
surface->updatedTileIndices[surface->numUpdatedTiles++] = (UINT32)zIdx;
|
if (!t->dirty)
|
||||||
|
{
|
||||||
|
if (surface->numUpdatedTiles >= surface->gridSize)
|
||||||
|
{
|
||||||
|
if (!progressive_allocate_tile_cache(surface, surface->numUpdatedTiles + 1))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->updatedTileIndices[surface->numUpdatedTiles++] = (UINT32)zIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->dirty = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2609,10 +2616,11 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD
|
|||||||
}
|
}
|
||||||
|
|
||||||
region16_uninit(&updateRegion);
|
region16_uninit(&updateRegion);
|
||||||
|
tile->dirty = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
region16_uninit(&clippingRects);
|
region16_uninit(&clippingRects);
|
||||||
|
surface->numUpdatedTiles = 0;
|
||||||
fail:
|
fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,7 @@ typedef struct
|
|||||||
|
|
||||||
BYTE flags;
|
BYTE flags;
|
||||||
BYTE quality;
|
BYTE quality;
|
||||||
|
BOOL dirty;
|
||||||
|
|
||||||
UINT16 yLen;
|
UINT16 yLen;
|
||||||
UINT16 cbLen;
|
UINT16 cbLen;
|
||||||
|
Loading…
Reference in New Issue
Block a user