void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap, BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codecId) { int status; UINT16 size; BYTE* pSrcData; BYTE* pDstData; UINT32 SrcSize; UINT32 SrcFormat; UINT32 bytesPerPixel; bytesPerPixel = (bpp + 7) / 8; size = width * height * 4; if (!bitmap->data) bitmap->data = (BYTE*) _aligned_malloc(size, 16); else bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16); pSrcData = data; SrcSize = (UINT32) length; pDstData = bitmap->data; if (compressed) { if (bpp < 32) { if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED)) return; status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp, &pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, NULL); } else { if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR)) return; status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, TRUE); } if (status < 0) { WLog_ERR(TAG, "Bitmap Decompression Failed"); return; } } else { SrcFormat = gdi_get_pixel_format(bpp, TRUE); status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0, NULL); } bitmap->compressed = FALSE; bitmap->length = size; bitmap->bpp = 32; }
BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codecId) { int status; UINT16 size; BYTE* pSrcData; BYTE* pDstData; UINT32 SrcSize; UINT32 SrcFormat; UINT32 bytesPerPixel; rdpGdi* gdi = context->gdi; bytesPerPixel = (bpp + 7) / 8; size = width * height * 4; bitmap->data = (BYTE*) _aligned_malloc(size, 16); pSrcData = data; SrcSize = (UINT32) length; pDstData = bitmap->data; if (compressed) { if (bpp < 32) { if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED)) return FALSE; status = interleaved_decompress(gdi->codecs->interleaved, pSrcData, SrcSize, bpp, &pDstData, gdi->format, -1, 0, 0, width, height, gdi->palette); } else { if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR)) return FALSE; status = planar_decompress(gdi->codecs->planar, pSrcData, SrcSize, &pDstData, gdi->format, -1, 0, 0, width, height, TRUE); } if (status < 0) { WLog_ERR(TAG, "Bitmap Decompression Failed"); return FALSE; } } else { SrcFormat = gdi_get_pixel_format(bpp, TRUE); status = freerdp_image_copy(pDstData, gdi->format, -1, 0, 0, width, height, pSrcData, SrcFormat, -1, 0, 0, gdi->palette); } bitmap->compressed = FALSE; bitmap->length = size; bitmap->bpp = gdi->dstBpp; return TRUE; }
void guac_rdp_bitmap_decompress(rdpContext* context, rdpBitmap* bitmap, UINT8* data, int width, int height, int bpp, int length, BOOL compressed) { #else void guac_rdp_bitmap_decompress(rdpContext* context, rdpBitmap* bitmap, UINT8* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id) { #endif int size = width * height * 4; #ifdef FREERDP_BITMAP_REQUIRES_ALIGNED_MALLOC bitmap->data = (UINT8*) _aligned_malloc(size, 16); #else bitmap->data = (UINT8*) malloc(size); #endif if (compressed) { #ifdef HAVE_RDPCONTEXT_CODECS rdpCodecs* codecs = context->codecs; UINT32* palette = ((rdp_freerdp_context*) context)->palette; /* Decode as interleaved if less than 32 bits per pixel */ if (bpp < 32) { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); interleaved_decompress(codecs->interleaved, data, length, bpp, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height, (BYTE*) palette); } /* Otherwise, decode as planar */ else { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); planar_decompress(codecs->planar, data, length, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height, TRUE); } bitmap->bpp = 32; #else bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); bitmap->bpp = bpp; #endif } else { freerdp_image_flip(data, bitmap->data, width, height, bpp); bitmap->bpp = bpp; } bitmap->compressed = FALSE; bitmap->length = size; }
int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status = 0; xfGfxSurface* surface; RECTANGLE_16 invalidRect; freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; printf("xf_SurfaceCommand_Alpha: status: %d\n", status); /* fill with green for now to distinguish from the rest */ freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, 0x00FF00); invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PLANAR)) return ERROR_INTERNAL_ERROR; DstData = surface->data; status = planar_decompress(surface->codecs->planar, cmd->data, cmd->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, FALSE); 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) gdi_UpdateSurfaces(gdi); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PLANAR, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; DstData = surface->data; status = planar_decompress(surface->codecs->planar, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, FALSE); 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 (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = planar_decompress(xfc->codecs->planar, cmd->data, cmd->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status = 0; xfGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALPHACODEC, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; WLog_DBG(TAG, "xf_SurfaceCommand_Alpha: status: %d", status); /* fill with green for now to distinguish from the rest */ freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, 0x00FF00); 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 (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { gdiGfxSurface* surface; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) calloc(1, sizeof(gdiGfxSurface)); if (!surface) return ERROR_INTERNAL_ERROR; surface->codecs = codecs_new(gdi->context); if (!surface->codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->surfaceId = createSurface->surfaceId; surface->width = (UINT32) createSurface->width; surface->height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->scanline = gfx_align_scanline(surface->width * 4, 16); surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) { free(surface); return ERROR_INTERNAL_ERROR; } surface->outputMapped = FALSE; region16_init(&surface->invalidRegion); context->SetSurfaceData(context, surface->surfaceId, (void*) surface); return CHANNEL_RC_OK; }
BOOL gdi_init_ex(freerdp* instance, UINT32 format, UINT32 stride, BYTE* buffer, void (*pfree)(void*)) { UINT32 SrcFormat = gdi_get_pixel_format(instance->settings->ColorDepth); rdpGdi* gdi = (rdpGdi*) calloc(1, sizeof(rdpGdi)); rdpContext* context = instance->context; if (!gdi) goto fail; instance->context->gdi = gdi; gdi->log = WLog_Get(TAG); if (!gdi->log) goto fail; gdi->context = instance->context; gdi->width = instance->settings->DesktopWidth; gdi->height = instance->settings->DesktopHeight; gdi->dstFormat = format; /* default internal buffer format */ WLog_Print(gdi->log, WLOG_INFO, "Local framebuffer format %s", GetColorFormatName(gdi->dstFormat)); WLog_Print(gdi->log, WLOG_INFO, "Remote framebuffer format %s", GetColorFormatName(SrcFormat)); if (!(gdi->hdc = gdi_GetDC())) goto fail; gdi->hdc->format = gdi->dstFormat; if (!gdi_init_primary(gdi, stride, gdi->dstFormat, buffer, pfree)) goto fail; if (!(context->cache = cache_new(instance->settings))) goto fail; if (!freerdp_client_codecs_prepare(context->codecs, FREERDP_CODEC_ALL, gdi->width, gdi->height)) goto fail; gdi_register_update_callbacks(instance->update); brush_cache_register_callbacks(instance->update); glyph_cache_register_callbacks(instance->update); bitmap_cache_register_callbacks(instance->update); offscreen_cache_register_callbacks(instance->update); palette_cache_register_callbacks(instance->update); if (!gdi_register_graphics(instance->context->graphics)) goto fail; return TRUE; fail: gdi_free(instance); WLog_ERR(TAG, "failed to initialize gdi"); return FALSE; }
int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; BYTE* DstData = NULL; H264_CONTEXT* h264; xfGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264)) return -1; h264 = xfc->codecs->h264; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; if (!bs) return -1; meta = &(bs->meta); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData, surface->format, surface->scanline , surface->width, surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { WLog_ERR(TAG, "h264_decompress failure: %d",status); return -1; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, (RECTANGLE_16*) &(meta->regionRects[i])); } if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_AVC420(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; xfGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_AVC420_BITMAP_STREAM* bs; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_AVC420, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; bs = (RDPGFX_AVC420_BITMAP_STREAM*) cmd->extra; if (!bs) return ERROR_INTERNAL_ERROR; meta = &(bs->meta); status = avc420_decompress(surface->codecs->h264, bs->data, bs->length, surface->data, surface->format, surface->scanline , surface->width, surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { WLog_WARN(TAG, "avc420_decompress failure: %d, ignoring update.", status); return CHANNEL_RC_OK; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &(meta->regionRects[i])); } if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; BYTE* DstData = NULL; H264_CONTEXT* h264; gdiGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264); h264 = gdi->codecs->h264; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; if (!bs) return -1; meta = &(bs->meta); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = h264_decompress(gdi->codecs->h264, bs->data, bs->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { WLog_ERR(TAG, "h264_decompress failure: %d",status); return -1; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), (RECTANGLE_16*) &(meta->regionRects[i])); } if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC, xfc->settings->DesktopWidth, xfc->settings->DesktopHeight)) return ERROR_INTERNAL_ERROR; DstData = surface->data; status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); if (status < 0) { WLog_ERR(TAG, "clear_decompress failure: %d", status); 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 (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = clear_decompress(gdi->codecs->clear, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); if (status < 0) { WLog_ERR(TAG, "clear_decompress failure: %d", status); return -1; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect); if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CreateSurface(RdpgfxClientContext* context, const RDPGFX_CREATE_SURFACE_PDU* createSurface) { size_t size; xfGfxSurface* surface; rdpGdi* gdi = (rdpGdi*)context->custom; xfContext* xfc = (xfContext*) gdi->context; surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface)); if (!surface) return CHANNEL_RC_NO_MEMORY; surface->gdi.codecs = codecs_new(gdi->context); if (!surface->gdi.codecs) { free(surface); return CHANNEL_RC_NO_MEMORY; } if (!freerdp_client_codecs_prepare(surface->gdi.codecs, FREERDP_CODEC_ALL, createSurface->width, createSurface->height)) { free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.surfaceId = createSurface->surfaceId; surface->gdi.width = (UINT32) createSurface->width; surface->gdi.height = (UINT32) createSurface->height; switch (createSurface->pixelFormat) { case GFX_PIXEL_FORMAT_ARGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRA32; break; case GFX_PIXEL_FORMAT_XRGB_8888: surface->gdi.format = PIXEL_FORMAT_BGRX32; break; default: free(surface); return ERROR_INTERNAL_ERROR; } surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel( surface->gdi.format); surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad); size = surface->gdi.scanline * surface->gdi.height; surface->gdi.data = (BYTE*) _aligned_malloc(size, 16); if (!surface->gdi.data) { free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->gdi.data, size); if (gdi->dstFormat == surface->gdi.format) { surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } else { UINT32 width = surface->gdi.width; UINT32 bytes = GetBytesPerPixel(gdi->dstFormat); surface->stageScanline = width * bytes; surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad); size = surface->stageScanline * surface->gdi.height; surface->stage = (BYTE*) _aligned_malloc(size, 16); if (!surface->stage) { _aligned_free(surface->gdi.data); free(surface); return CHANNEL_RC_NO_MEMORY; } ZeroMemory(surface->stage, size); surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) surface->stage, surface->gdi.width, surface->gdi.height, xfc->scanline_pad, surface->gdi.scanline); } surface->gdi.outputMapped = FALSE; region16_init(&surface->gdi.invalidRegion); context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface); return CHANNEL_RC_OK; }
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) { int i, tx, ty; XImage* image; BYTE* pSrcData; BYTE* pDstData; RFX_MESSAGE* message; xfContext* xfc = (xfContext*) context; xf_lock_x11(xfc, FALSE); if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) { freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX); message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetClipRectangles(xfc->display, xfc->gc, cmd->destLeft, cmd->destTop, (XRectangle*) message->rects, message->numRects, YXBanded); if (xfc->bitmap_size < (64 * 64 * 4)) { xfc->bitmap_size = 64 * 64 * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } /* Draw the tiles to primary surface, each is 64x64. */ for (i = 0; i < message->numTiles; i++) { pSrcData = message->tiles[i]->data; pDstData = pSrcData; if ((xfc->depth != 24) || (xfc->depth != 32)) { pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, 64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, xfc->palette); } image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, 64, 64, xfc->scanline_pad, 0); tx = message->tiles[i]->x + cmd->destLeft; ty = message->tiles[i]->y + cmd->destTop; XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64); XFree(image); } /* Copy the updated region from backstore to the window. */ for (i = 0; i < message->numRects; i++) { tx = message->rects[i].x + cmd->destLeft; ty = message->rects[i].y + cmd->destTop; if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc, tx, ty, message->rects[i].width, message->rects[i].height, tx, ty); } xf_gdi_surface_update_frame(xfc, tx, ty, message->rects[i].width, message->rects[i].height); } XSetClipMask(xfc->display, xfc->gc, None); rfx_message_free(xfc->codecs->rfx, message); } else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) { freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC); nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) { xfc->bitmap_size = cmd->width * cmd->height * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } pSrcData = xfc->codecs->nsc->BitmapData; pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XFree(image); if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, cmd->destLeft, cmd->destTop); } xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XSetClipMask(xfc->display, xfc->gc, None); } else if (cmd->codecID == RDP_CODEC_ID_NONE) { XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); if (xfc->bitmap_size < (cmd->width * cmd->height * 4)) { xfc->bitmap_size = cmd->width * cmd->height * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } pSrcData = cmd->bitmapData; pDstData = xfc->bitmap_buffer; freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0); XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XFree(image); if (!xfc->remote_app) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, cmd->destLeft, cmd->destTop); } xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height); XSetClipMask(xfc->display, xfc->gc, None); } else { WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); } xf_unlock_x11(xfc, FALSE); }
void xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) { int status; int nXDst; int nYDst; int nXSrc; int nYSrc; int nWidth; int nHeight; UINT32 index; XImage* image; BYTE* pSrcData; BYTE* pDstData; UINT32 SrcSize; BOOL compressed; UINT32 SrcFormat; UINT32 bitsPerPixel; UINT32 bytesPerPixel; BITMAP_DATA* bitmap; rdpCodecs* codecs = context->codecs; xfContext* xfc = (xfContext*) context; for (index = 0; index < bitmapUpdate->number; index++) { bitmap = &(bitmapUpdate->rectangles[index]); nXSrc = 0; nYSrc = 0; nXDst = bitmap->destLeft; nYDst = bitmap->destTop; nWidth = bitmap->width; nHeight = bitmap->height; pSrcData = bitmap->bitmapDataStream; SrcSize = bitmap->bitmapLength; compressed = bitmap->compressed; bitsPerPixel = bitmap->bitsPerPixel; bytesPerPixel = (bitsPerPixel + 7) / 8; SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE); if (xfc->bitmap_size < (nWidth * nHeight * 4)) { xfc->bitmap_size = nWidth * nHeight * 4; xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) return; } if (compressed) { pDstData = xfc->bitmap_buffer; if (bitsPerPixel < 32) { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, &pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, xfc->palette); } else { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, TRUE); } if (status < 0) { WLog_ERR(TAG, "bitmap decompression failure"); return; } pSrcData = xfc->bitmap_buffer; } else { pDstData = xfc->bitmap_buffer; status = freerdp_image_copy(pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, xfc->palette); pSrcData = xfc->bitmap_buffer; } xf_lock_x11(xfc, FALSE); XSetFunction(xfc->display, xfc->gc, GXcopy); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, (char*) pSrcData, nWidth, nHeight, xfc->scanline_pad, 0); nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */ nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */ XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, nXDst, nYDst, nWidth, nHeight); XFree(image); gdi_InvalidateRegion(xfc->hdc, nXDst, nYDst, nWidth, nHeight); xf_unlock_x11(xfc, FALSE); } }
/** * 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; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return ERROR_INTERNAL_ERROR; } region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->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 < message->numTiles; i++) { tile = message->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; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(surface->codecs->rfx, message); region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
static void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) { int status; int nXDst; int nYDst; int nXSrc; int nYSrc; int nWidth; int nHeight; int nSrcStep; int nDstStep; UINT32 index; BYTE* pSrcData; BYTE* pDstData; UINT32 SrcSize; BOOL compressed; UINT32 SrcFormat; UINT32 bitsPerPixel; BITMAP_DATA* bitmap; rdpGdi* gdi = context->gdi; rdpCodecs* codecs = context->codecs; for (index = 0; index < bitmapUpdate->number; index++) { bitmap = &(bitmapUpdate->rectangles[index]); nXSrc = 0; nYSrc = 0; nXDst = bitmap->destLeft; nYDst = bitmap->destTop; nWidth = bitmap->width; nHeight = bitmap->height; pSrcData = bitmap->bitmapDataStream; SrcSize = bitmap->bitmapLength; compressed = bitmap->compressed; bitsPerPixel = bitmap->bitsPerPixel; if (gdi->bitmap_size < (nWidth * nHeight * 4)) { gdi->bitmap_size = nWidth * nHeight * 4; gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16); if (!gdi->bitmap_buffer) return; } if (compressed) { pDstData = gdi->bitmap_buffer; if (bitsPerPixel < 32) { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, &pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, gdi->palette); } else { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, TRUE); } if (status < 0) { WLog_ERR(TAG, "bitmap decompression failure"); return; } pSrcData = gdi->bitmap_buffer; } else { pDstData = gdi->bitmap_buffer; SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE); status = freerdp_image_copy(pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, gdi->palette); pSrcData = gdi->bitmap_buffer; } nSrcStep = nWidth * gdi->bytesPerPixel; pDstData = gdi->primary_buffer; nDstStep = gdi->width * gdi->bytesPerPixel; nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */ nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */ status = freerdp_image_copy(pDstData, gdi->format, nDstStep, nXDst, nYDst, nWidth, nHeight, pSrcData, gdi->format, nSrcStep, nXSrc, nYSrc, gdi->palette); gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight); } }
BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags, UINT32 width, UINT32 height) { BOOL rc = TRUE; if (!freerdp_client_codecs_prepare(codecs, flags)) return FALSE; if (flags & FREERDP_CODEC_INTERLEAVED) { if (codecs->interleaved) { rc &= bitmap_interleaved_context_reset(codecs->interleaved); } } if (flags & FREERDP_CODEC_PLANAR) { if (codecs->planar) { rc &= freerdp_bitmap_planar_context_reset(codecs->planar); } } if (flags & FREERDP_CODEC_NSCODEC) { if (codecs->nsc) { rc &= nsc_context_reset(codecs->nsc, width, height); } } if (flags & FREERDP_CODEC_REMOTEFX) { if (codecs->rfx) { rc &= rfx_context_reset(codecs->rfx, width, height); } } if (flags & FREERDP_CODEC_CLEARCODEC) { if (codecs->clear) { rc &= clear_context_reset(codecs->clear); } } if (flags & FREERDP_CODEC_ALPHACODEC) { } if (flags & FREERDP_CODEC_PROGRESSIVE) { if (codecs->progressive) { rc &= progressive_context_reset(codecs->progressive); } } if (flags & (FREERDP_CODEC_AVC420 | FREERDP_CODEC_AVC444)) { if (codecs->h264) { rc &= h264_context_reset(codecs->h264, width, height); } } return rc; }
int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; gdiGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; message = rfx_process_message(gdi->codecs->rfx, cmd->data, cmd->length); if (!message) return -1; region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->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 < message->numTiles; i++) { tile = message->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; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(gdi->codecs->rfx, message); if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }
static void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) { int i, j; int tx, ty; BYTE* pSrcData; BYTE* pDstData; RFX_MESSAGE* message; rdpGdi* gdi = context->gdi; DEBUG_GDI("destLeft %d destTop %d destRight %d destBottom %d " "bpp %d codecID %d width %d height %d length %d", cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom, cmd->bpp, cmd->codecID, cmd->width, cmd->height, cmd->bitmapDataLength); if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) { freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); message = rfx_process_message(gdi->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength); /* blit each tile */ for (i = 0; i < message->numTiles; i++) { tx = message->tiles[i]->x + cmd->destLeft; ty = message->tiles[i]->y + cmd->destTop; pSrcData = message->tiles[i]->data; pDstData = gdi->tile->bitmap->data; if (!gdi->invert && (gdi->dstBpp == 32)) { gdi->tile->bitmap->data = pSrcData; } else { freerdp_image_copy(pDstData, gdi->format, -1, 0, 0, 64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, gdi->palette); } for (j = 0; j < message->numRects; j++) { gdi_SetClipRgn(gdi->primary->hdc, cmd->destLeft + message->rects[j].x, cmd->destTop + message->rects[j].y, message->rects[j].width, message->rects[j].height); gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY); } gdi->tile->bitmap->data = pDstData; } gdi_SetNullClipRgn(gdi->primary->hdc); rfx_message_free(gdi->codecs->rfx, message); } else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) { freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC); nsc_process_message(gdi->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); if (gdi->bitmap_size < (cmd->width * cmd->height * 4)) { gdi->bitmap_size = cmd->width * cmd->height * 4; gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16); if (!gdi->bitmap_buffer) return; } pDstData = gdi->bitmap_buffer; pSrcData = gdi->codecs->nsc->BitmapData; freerdp_image_copy(pDstData, gdi->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, gdi->palette); gdi->image->bitmap->width = cmd->width; gdi->image->bitmap->height = cmd->height; gdi->image->bitmap->bitsPerPixel = cmd->bpp; gdi->image->bitmap->bytesPerPixel = cmd->bpp / 8; gdi->image->bitmap->data = gdi->bitmap_buffer; gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } else if (cmd->codecID == RDP_CODEC_ID_NONE) { if (gdi->bitmap_size < (cmd->width * cmd->height * 4)) { gdi->bitmap_size = cmd->width * cmd->height * 4; gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16); if (!gdi->bitmap_buffer) return; } pDstData = gdi->bitmap_buffer; pSrcData = cmd->bitmapData; freerdp_image_copy(pDstData, gdi->format, -1, 0, 0, cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, gdi->palette); gdi->image->bitmap->width = cmd->width; gdi->image->bitmap->height = cmd->height; gdi->image->bitmap->bitsPerPixel = cmd->bpp; gdi->image->bitmap->bytesPerPixel = cmd->bpp / 8; gdi->image->bitmap->data = gdi->bitmap_buffer; gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } else { WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); } }
void guac_rdp_bitmap_decompress(rdpContext* context, rdpBitmap* bitmap, UINT8* data, int width, int height, int bpp, int length, BOOL compressed) { #else void guac_rdp_bitmap_decompress(rdpContext* context, rdpBitmap* bitmap, UINT8* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id) { #endif int size = width * height * 4; #ifdef FREERDP_BITMAP_REQUIRES_ALIGNED_MALLOC /* Free pre-existing data, if any (might be reused) */ if (bitmap->data != NULL) _aligned_free(bitmap->data); /* Allocate new data */ bitmap->data = (UINT8*) _aligned_malloc(size, 16); #else /* Free pre-existing data, if any (might be reused) */ free(bitmap->data); /* Allocate new data */ bitmap->data = (UINT8*) malloc(size); #endif if (compressed) { #ifdef HAVE_RDPCONTEXT_CODECS rdpCodecs* codecs = context->codecs; /* Decode as interleaved if less than 32 bits per pixel */ if (bpp < 32) { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); #ifdef INTERLEAVED_DECOMPRESS_TAKES_PALETTE interleaved_decompress(codecs->interleaved, data, length, bpp, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height, (BYTE*) ((rdp_freerdp_context*) context)->palette); bitmap->bpp = 32; #else interleaved_decompress(codecs->interleaved, data, length, bpp, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height); bitmap->bpp = bpp; #endif } /* Otherwise, decode as planar */ else { freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); #ifdef PLANAR_DECOMPRESS_CAN_FLIP planar_decompress(codecs->planar, data, length, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height, TRUE); bitmap->bpp = 32; #else planar_decompress(codecs->planar, data, length, &(bitmap->data), PIXEL_FORMAT_XRGB32, -1, 0, 0, width, height); bitmap->bpp = bpp; #endif } #else bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); bitmap->bpp = bpp; #endif } else { freerdp_image_flip(data, bitmap->data, width, height, bpp); bitmap->bpp = bpp; } bitmap->compressed = FALSE; bitmap->length = size; }