int rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_TO_CACHE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 20) return -1; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.cacheKey); /* cacheKey (8 bytes) */ Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */ WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToCachePdu: surfaceId: %d cacheKey: 0x%08X cacheSlot: %d " "left: %d top: %d right: %d bottom: %d", pdu.surfaceId, (int) pdu.cacheKey, pdu.cacheSlot, pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom); if (context && context->SurfaceToCache) { context->SurfaceToCache(context, &pdu); } return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error; if (Stream_GetRemainingLength(s) < 17) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ if ((error = rdpgfx_read_rect16(s, &(pdu.destRect)))) /* destRect (8 bytes) */ { WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu", error); return error; } Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_DBG(TAG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if ((error = rdpgfx_decode(gfx, &cmd))) WLog_ERR(TAG, "rdpgfx_decode failed with error %lu!", error); return error; }
int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 17) return -1; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ rdpgfx_read_rect16(s, &(pdu.destRect)); /* destRect (8 bytes) */ Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) return -1; pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if (cmd.codecId == RDPGFX_CODECID_H264) { rdpgfx_decode(gfx, &cmd); } else { if (context && context->SurfaceCommand) { context->SurfaceCommand(context, &cmd); } } return 1; }
int rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta) { UINT32 index; RDPGFX_RECT16* regionRect; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; meta->regionRects = NULL; meta->quantQualityVals = NULL; if (Stream_GetRemainingLength(s) < 4) return -1; Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8)) return -1; meta->regionRects = (RDPGFX_RECT16*) malloc(meta->numRegionRects * sizeof(RDPGFX_RECT16)); if (!meta->regionRects) return -1; meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); if (!meta->quantQualityVals) return -1; WLog_DBG(TAG, "H264_METABLOCK: numRegionRects: %d", (int) meta->numRegionRects); for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); rdpgfx_read_rect16(s, regionRect); WLog_DBG(TAG, "regionRects[%d]: left: %d top: %d right: %d bottom: %d", index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) return -1; for (index = 0; index < meta->numRegionRects; index++) { quantQualityVal = &(meta->quantQualityVals[index]); Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ quantQualityVal->qp = quantQualityVal->qpVal & 0x3F; quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; WLog_DBG(TAG, "quantQualityVals[%d]: qp: %d r: %d p: %d qualityVal: %d", index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); } return 1; }
int rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { UINT16 index; RDPGFX_POINT16* destPt; RDPGFX_SURFACE_TO_SURFACE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 14) return -1; Stream_Read_UINT16(s, pdu.surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceIdDest); /* surfaceIdDest (2 bytes) */ rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4)) return -1; pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); if (!pdu.destPts) return -1; for (index = 0; index < pdu.destPtsCount; index++) { destPt = &(pdu.destPts[index]); rdpgfx_read_point16(s, destPt); } WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %d surfaceIdDest: %d " "left: %d top: %d right: %d bottom: %d destPtsCount: %d", pdu.surfaceIdSrc, pdu.surfaceIdDest, pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom, pdu.destPtsCount); if (context && context->SurfaceToSurface) { context->SurfaceToSurface(context, &pdu); } free(pdu.destPts); return 1; }
int rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { UINT16 index; RDPGFX_RECT16* fillRect; RDPGFX_SOLID_FILL_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 8) return -1; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ rdpgfx_read_color32(s, &(pdu.fillPixel)); /* fillPixel (4 bytes) */ Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ if (Stream_GetRemainingLength(s) < (size_t) (pdu.fillRectCount * 8)) return -1; pdu.fillRects = (RDPGFX_RECT16*) calloc(pdu.fillRectCount, sizeof(RDPGFX_RECT16)); if (!pdu.fillRects) return -1; for (index = 0; index < pdu.fillRectCount; index++) { fillRect = &(pdu.fillRects[index]); rdpgfx_read_rect16(s, fillRect); } WLog_Print(gfx->log, WLOG_DEBUG, "RecvSolidFillPdu: surfaceId: %d fillRectCount: %d", pdu.surfaceId, pdu.fillRectCount); if (context && context->SolidFill) { context->SolidFill(context, &pdu); } free(pdu.fillRects); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_surface_to_cache_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_TO_CACHE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error; if (Stream_GetRemainingLength(s) < 20) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT64(s, pdu.cacheKey); /* cacheKey (8 bytes) */ Stream_Read_UINT16(s, pdu.cacheSlot); /* cacheSlot (2 bytes) */ if ((error = rdpgfx_read_rect16(s, &(pdu.rectSrc)))) /* rectSrc (8 bytes ) */ { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_rect16 failed with error %"PRIu32"!", error); return error; } WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToCachePdu: surfaceId: %"PRIu16" cacheKey: 0x%016"PRIX64" cacheSlot: %"PRIu16" " "left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"", pdu.surfaceId, pdu.cacheKey, pdu.cacheSlot, pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom); if (context) { IFCALLRET(context->SurfaceToCache, error, context, &pdu); if (error) WLog_Print(gfx->log, WLOG_ERROR, "context->SurfaceToCache failed with error %"PRIu32"", error); } return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_read_h264_metablock(RDPGFX_PLUGIN* gfx, wStream* s, RDPGFX_H264_METABLOCK* meta) { UINT32 index; RECTANGLE_16* regionRect; RDPGFX_H264_QUANT_QUALITY* quantQualityVal; UINT error = ERROR_INVALID_DATA; meta->regionRects = NULL; meta->quantQualityVals = NULL; if (Stream_GetRemainingLength(s) < 4) { WLog_ERR(TAG, "not enough data!"); goto error_out; } Stream_Read_UINT32(s, meta->numRegionRects); /* numRegionRects (4 bytes) */ if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 8)) { WLog_ERR(TAG, "not enough data!"); goto error_out; } meta->regionRects = (RECTANGLE_16*) malloc(meta->numRegionRects * sizeof(RECTANGLE_16)); if (!meta->regionRects) { WLog_ERR(TAG, "malloc failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } meta->quantQualityVals = (RDPGFX_H264_QUANT_QUALITY*) malloc(meta->numRegionRects * sizeof(RDPGFX_H264_QUANT_QUALITY)); if (!meta->quantQualityVals) { WLog_ERR(TAG, "malloc failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } WLog_DBG(TAG, "H264_METABLOCK: numRegionRects: %"PRIu32"", meta->numRegionRects); for (index = 0; index < meta->numRegionRects; index++) { regionRect = &(meta->regionRects[index]); if ((error = rdpgfx_read_rect16(s, regionRect))) { WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %"PRIu32"!", error); goto error_out; } WLog_DBG(TAG, "regionRects[%"PRIu32"]: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16"", index, regionRect->left, regionRect->top, regionRect->right, regionRect->bottom); } if (Stream_GetRemainingLength(s) < (meta->numRegionRects * 2)) { WLog_ERR(TAG, "not enough data!"); error = ERROR_INVALID_DATA; goto error_out; } for (index = 0; index < meta->numRegionRects; index++) { quantQualityVal = &(meta->quantQualityVals[index]); Stream_Read_UINT8(s, quantQualityVal->qpVal); /* qpVal (1 byte) */ Stream_Read_UINT8(s, quantQualityVal->qualityVal); /* qualityVal (1 byte) */ quantQualityVal->qp = quantQualityVal->qpVal & 0x3F; quantQualityVal->r = (quantQualityVal->qpVal >> 6) & 1; quantQualityVal->p = (quantQualityVal->qpVal >> 7) & 1; WLog_DBG(TAG, "quantQualityVals[%"PRIu32"]: qp: %"PRIu8" r: %"PRIu8" p: %"PRIu8" qualityVal: %"PRIu8"", index, quantQualityVal->qp, quantQualityVal->r, quantQualityVal->p, quantQualityVal->qualityVal); } return CHANNEL_RC_OK; error_out: free(meta->regionRects); meta->regionRects = NULL; free(meta->quantQualityVals); meta->quantQualityVals = NULL; return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { UINT16 index; RDPGFX_POINT16* destPt; RDPGFX_SURFACE_TO_SURFACE_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error; if (Stream_GetRemainingLength(s) < 14) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceIdSrc); /* surfaceIdSrc (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceIdDest); /* surfaceIdDest (2 bytes) */ if ((error = rdpgfx_read_rect16(s, &(pdu.rectSrc)))) /* rectSrc (8 bytes ) */ { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_rect16 failed with error %"PRIu32"!", error); return error; } Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ if (Stream_GetRemainingLength(s) < (size_t)(pdu.destPtsCount * 4)) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); if (!pdu.destPts) { WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } for (index = 0; index < pdu.destPtsCount; index++) { destPt = &(pdu.destPts[index]); if ((error = rdpgfx_read_point16(s, destPt))) { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_point16 failed with error %"PRIu32"!", error); free(pdu.destPts); return error; } } WLog_Print(gfx->log, WLOG_DEBUG, "RecvSurfaceToSurfacePdu: surfaceIdSrc: %"PRIu16" surfaceIdDest: %"PRIu16" " "left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" destPtsCount: %"PRIu16"", pdu.surfaceIdSrc, pdu.surfaceIdDest, pdu.rectSrc.left, pdu.rectSrc.top, pdu.rectSrc.right, pdu.rectSrc.bottom, pdu.destPtsCount); if (context) { IFCALLRET(context->SurfaceToSurface, error, context, &pdu); if (error) WLog_Print(gfx->log, WLOG_ERROR, "context->SurfaceToSurface failed with error %"PRIu32"", error); } free(pdu.destPts); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { UINT16 index; RECTANGLE_16* fillRect; RDPGFX_SOLID_FILL_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error; if (Stream_GetRemainingLength(s) < 8) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ if ((error = rdpgfx_read_color32(s, &(pdu.fillPixel)))) /* fillPixel (4 bytes) */ { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_color32 failed with error %"PRIu32"!", error); return error; } Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ if (Stream_GetRemainingLength(s) < (size_t)(pdu.fillRectCount * 8)) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } pdu.fillRects = (RECTANGLE_16*) calloc(pdu.fillRectCount, sizeof(RECTANGLE_16)); if (!pdu.fillRects) { WLog_Print(gfx->log, WLOG_ERROR, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } for (index = 0; index < pdu.fillRectCount; index++) { fillRect = &(pdu.fillRects[index]); if ((error = rdpgfx_read_rect16(s, fillRect))) { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_rect16 failed with error %"PRIu32"!", error); free(pdu.fillRects); return error; } } WLog_Print(gfx->log, WLOG_DEBUG, "RecvSolidFillPdu: surfaceId: %"PRIu16" fillRectCount: %"PRIu16"", pdu.surfaceId, pdu.fillRectCount); if (context) { IFCALLRET(context->SolidFill, error, context, &pdu); if (error) WLog_Print(gfx->log, WLOG_ERROR, "context->SolidFill failed with error %"PRIu32"", error); } free(pdu.fillRects); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error; if (Stream_GetRemainingLength(s) < RDPGFX_WIRE_TO_SURFACE_PDU_1_SIZE) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ if ((error = rdpgfx_read_rect16(s, &(pdu.destRect)))) /* destRect (8 bytes) */ { WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_read_rect16 failed with error %"PRIu32"", error); return error; } Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface1Pdu: surfaceId: %"PRIu16" codecId: %s (0x%04"PRIX16") pixelFormat: 0x%02"PRIX8" " "destRect: left: %"PRIu16" top: %"PRIu16" right: %"PRIu16" bottom: %"PRIu16" bitmapDataLength: %"PRIu32"", pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; switch (pdu.pixelFormat) { case GFX_PIXEL_FORMAT_XRGB_8888: cmd.format = PIXEL_FORMAT_BGRX32; break; case GFX_PIXEL_FORMAT_ARGB_8888: cmd.format = PIXEL_FORMAT_BGRA32; break; default: return ERROR_INVALID_DATA; } cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; cmd.extra = NULL; if ((error = rdpgfx_decode(gfx, &cmd))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_decode failed with error %"PRIu32"!", error); return error; }