diff options
Diffstat (limited to '')
-rw-r--r-- | libfreerdp/codec/progressive.c | 144 |
1 files changed, 78 insertions, 66 deletions
diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index df98ad3..3ab84ef 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -2312,67 +2312,11 @@ static SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* progressive, wStream return rc; } -INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, - BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, - UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId, - UINT32 frameId) +static BOOL update_tiles(PROGRESSIVE_CONTEXT* progressive, PROGRESSIVE_SURFACE_CONTEXT* surface, + BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, + UINT32 nYDst, PROGRESSIVE_BLOCK_REGION* region, REGION16* invalidRegion) { - INT32 rc = 1; - - WINPR_ASSERT(progressive); - PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId); - - if (!surface) - { - WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16, - surfaceId); - return -1001; - } - - PROGRESSIVE_BLOCK_REGION* region = &progressive->region; - WINPR_ASSERT(region); - - if (surface->frameId != frameId) - { - surface->frameId = frameId; - surface->numUpdatedTiles = 0; - } - - wStream ss = { 0 }; - wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize); - WINPR_ASSERT(s); - - switch (DstFormat) - { - case PIXEL_FORMAT_RGBA32: - case PIXEL_FORMAT_RGBX32: - case PIXEL_FORMAT_BGRA32: - case PIXEL_FORMAT_BGRX32: - progressive->format = DstFormat; - break; - default: - progressive->format = PIXEL_FORMAT_XRGB32; - break; - } - - const size_t start = Stream_GetPosition(s); - progressive->state = 0; /* Set state to not initialized */ - while (Stream_GetRemainingLength(s) > 0) - { - if (progressive_parse_block(progressive, s, surface, region) < 0) - goto fail; - } - - const size_t end = Stream_GetPosition(s); - if ((end - start) != SrcSize) - { - WLog_Print(progressive->log, WLOG_ERROR, - "total block len %" PRIuz " does not match read data %" PRIu32, end - start, - SrcSize); - rc = -1041; - goto fail; - } - + BOOL rc = TRUE; REGION16 clippingRects = { 0 }; region16_init(&clippingRects); @@ -2425,13 +2369,11 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD goto fail; if (rect->top + height > surface->height) goto fail; - if (!freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width, + rc = freerdp_image_copy(pDstData, DstFormat, nDstStep, rect->left, rect->top, width, height, tile->data, progressive->format, tile->stride, nXSrc, - nYSrc, NULL, FREERDP_KEEP_DST_ALPHA)) - { - rc = -42; + nYSrc, NULL, FREERDP_KEEP_DST_ALPHA); + if (!rc) break; - } if (invalidRegion) region16_union_rect(invalidRegion, invalidRegion, rect); @@ -2441,8 +2383,75 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD tile->dirty = FALSE; } +fail: region16_uninit(&clippingRects); - surface->numUpdatedTiles = 0; + return rc; +} + +INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, + BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, + UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId, + UINT32 frameId) +{ + INT32 rc = 1; + + WINPR_ASSERT(progressive); + PROGRESSIVE_SURFACE_CONTEXT* surface = progressive_get_surface_data(progressive, surfaceId); + + if (!surface) + { + WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion no surface for %" PRIu16, + surfaceId); + return -1001; + } + + PROGRESSIVE_BLOCK_REGION* region = &progressive->region; + WINPR_ASSERT(region); + + if (surface->frameId != frameId) + { + surface->frameId = frameId; + surface->numUpdatedTiles = 0; + } + + wStream ss = { 0 }; + wStream* s = Stream_StaticConstInit(&ss, pSrcData, SrcSize); + WINPR_ASSERT(s); + + switch (DstFormat) + { + case PIXEL_FORMAT_RGBA32: + case PIXEL_FORMAT_RGBX32: + case PIXEL_FORMAT_BGRA32: + case PIXEL_FORMAT_BGRX32: + progressive->format = DstFormat; + break; + default: + progressive->format = PIXEL_FORMAT_XRGB32; + break; + } + + const size_t start = Stream_GetPosition(s); + progressive->state = 0; /* Set state to not initialized */ + while (Stream_GetRemainingLength(s) > 0) + { + if (progressive_parse_block(progressive, s, surface, region) < 0) + goto fail; + } + + const size_t end = Stream_GetPosition(s); + if ((end - start) != SrcSize) + { + WLog_Print(progressive->log, WLOG_ERROR, + "total block len %" PRIuz " does not match read data %" PRIu32, end - start, + SrcSize); + rc = -1041; + goto fail; + } + + if (!update_tiles(progressive, surface, pDstData, DstFormat, nDstStep, nXDst, nYDst, region, + invalidRegion)) + return -2002; fail: return rc; } @@ -2631,7 +2640,10 @@ PROGRESSIVE_CONTEXT* progressive_context_new_ex(BOOL Compressor, UINT32 Threadin } return progressive; fail: + WINPR_PRAGMA_DIAG_PUSH + WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC progressive_context_free(progressive); + WINPR_PRAGMA_DIAG_POP return NULL; } |