/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { INT32 rc; UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; rc = progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); if (rc < 0) { WLog_ERR(TAG, "progressive_create_surface_context failure: %d", rc); return ERROR_INTERNAL_ERROR; } rc = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, surface->data, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (rc < 0) { WLog_ERR(TAG, "progressive_decompress failure: %d", rc); return ERROR_INTERNAL_ERROR; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int i, j; int status; BYTE* DstData; RFX_RECT* rect; int nXDst, nYDst; int nXSrc, nYSrc; int nWidth, nHeight; int nbUpdateRects; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PROGRESSIVE, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); DstData = surface->data; status = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) { WLog_ERR(TAG, "progressive_decompress failure: %d", status); return ERROR_INTERNAL_ERROR; } region = &(surface->codecs->progressive->region); region16_init(&clippingRects); for (i = 0; i < region->numRects; i++) { rect = &(region->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < region->numTiles; i++) { tile = region->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; nXSrc = nXDst - (cmd->left + tile->x); nYSrc = nYDst - (cmd->top + tile->y); freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int test_progressive_ms_sample(char* ms_sample_path) { int count; int status; EGFX_SAMPLE_FILE files[3][4][4]; EGFX_SAMPLE_FILE bitmaps[3][4][4]; PROGRESSIVE_CONTEXT* progressive; g_Width = 1920; g_Height = 1080; g_DstStep = g_Width * 4; ZeroMemory(files, sizeof(files)); ZeroMemory(bitmaps, sizeof(bitmaps)); status = test_progressive_load_files(ms_sample_path, files); if (status < 0) return -1; status = test_progressive_load_bitmaps(ms_sample_path, bitmaps); if (status < 0) return -1; count = 4; progressive = progressive_context_new(FALSE); g_DstData = _aligned_malloc(g_DstStep * g_Height, 16); progressive_create_surface_context(progressive, 0, g_Width, g_Height); /* image 1 */ if (1) { printf("\nSample Image 1\n"); test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); test_progressive_decode(progressive, files[0][0], bitmaps[0][0], 0, count); test_progressive_decode(progressive, files[0][1], bitmaps[0][1], 1, count); test_progressive_decode(progressive, files[0][2], bitmaps[0][2], 2, count); test_progressive_decode(progressive, files[0][3], bitmaps[0][3], 3, count); } /* image 2 */ if (0) { printf("\nSample Image 2\n"); /* sample data is in incorrect order */ test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); test_progressive_decode(progressive, files[1][0], bitmaps[1][0], 0, count); test_progressive_decode(progressive, files[1][1], bitmaps[1][1], 1, count); test_progressive_decode(progressive, files[1][2], bitmaps[1][2], 2, count); test_progressive_decode(progressive, files[1][3], bitmaps[1][3], 3, count); } /* image 3 */ if (0) { printf("\nSample Image 3\n"); /* sample data is in incorrect order */ test_image_fill(g_DstData, g_DstStep, 0, 0, g_Width, g_Height, 0xFF000000); test_progressive_decode(progressive, files[2][0], bitmaps[2][0], 0, count); test_progressive_decode(progressive, files[2][1], bitmaps[2][1], 1, count); test_progressive_decode(progressive, files[2][2], bitmaps[2][2], 2, count); test_progressive_decode(progressive, files[2][3], bitmaps[2][3], 3, count); } progressive_context_free(progressive); _aligned_free(g_DstData); return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { INT32 rc; UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; REGION16 invalidRegion; const RECTANGLE_16* rects; UINT32 nrRects, x; /** * Note: Since this comes via a Wire-To-Surface-2 PDU the * cmd's top/left/right/bottom/width/height members are always zero! * The update region is determined during decompression. */ surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } rc = progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); if (rc < 0) { WLog_ERR(TAG, "progressive_create_surface_context failure: %"PRId32"", rc); return ERROR_INTERNAL_ERROR; } region16_init(&invalidRegion); rc = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, surface->data, surface->format, surface->scanline, cmd->left, cmd->top, &invalidRegion, cmd->surfaceId); if (rc < 0) { WLog_ERR(TAG, "progressive_decompress failure: %"PRId32"", rc); region16_uninit(&invalidRegion); return ERROR_INTERNAL_ERROR; } rects = region16_rects(&invalidRegion, &nrRects); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, nrRects, rects); for (x=0; x<nrRects; x++) region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &rects[x]); region16_uninit(&invalidRegion); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }