void test_nsc_decode(void) { int i; NSC_CONTEXT* context; context = nsc_context_new(); nsc_process_message(context, 32, 15, 10, (BYTE*) nsc_data, sizeof(nsc_data)); /*winpr_HexDump(context->bmpdata, 15 * 10 * 4);*/ for (i = 0; i < 30000; i++) { nsc_process_message(context, 32, 54, 44, (BYTE*) nsc_stress_data, sizeof(nsc_stress_data)); } nsc_context_free(context); }
void test_nsc_decode(void) { int i; NSC_CONTEXT* context; context = nsc_context_new(); nsc_context_set_cpu_opt(context, CPU_SSE2); nsc_process_message(context, 32, 15, 10, (uint8*) nsc_data, sizeof(nsc_data)); /*freerdp_hexdump(context->bmpdata, 15 * 10 * 4);*/ for (i = 0; i < 30000; i++) { nsc_process_message(context, 32, 54, 44, (uint8*) nsc_stress_data, sizeof(nsc_stress_data)); } nsc_context_free(context); }
void test_nsc_encode(void) { int i; uint8* rgb_data; STREAM* enc_stream; NSC_CONTEXT* context; rgb_data = (uint8 *) malloc(64 * 64 * 3); for (i = 0; i < 64; i++) memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3); context = nsc_context_new(); nsc_context_set_cpu_opt(context, CPU_SSE2); nsc_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8); enc_stream = stream_new(65536); stream_clear(enc_stream); for (i = 0; i < 30000; i++) { stream_set_pos(enc_stream, 0); nsc_compose_message(context, enc_stream, rgb_data, 64, 64, 64 * 3); } /*freerdp_hexdump(stream_get_head(enc_stream), stream_get_length(enc_stream));*/ nsc_process_message(context, 32, 64, 64, stream_get_head(enc_stream), stream_get_length(enc_stream)); /*freerdp_hexdump(context->bmpdata, 64 * 64 * 4);*/ stream_free(enc_stream); nsc_context_free(context); }
void test_nsc_encode(void) { int i; BYTE* rgb_data; wStream* enc_stream; NSC_CONTEXT* context; rgb_data = (BYTE *) malloc(64 * 64 * 3); for (i = 0; i < 64; i++) memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3); context = nsc_context_new(); nsc_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8); enc_stream = stream_new(65536); stream_clear(enc_stream); for (i = 0; i < 30000; i++) { Stream_SetPosition(enc_stream, 0); nsc_compose_message(context, enc_stream, rgb_data, 64, 64, 64 * 3); } /*winpr_HexDump(Stream_Buffer(enc_stream), Stream_GetPosition(enc_stream));*/ nsc_process_message(context, 32, 64, 64, Stream_Buffer(enc_stream), Stream_GetPosition(enc_stream)); /*winpr_HexDump(context->bmpdata, 64 * 64 * 4);*/ stream_free(enc_stream); nsc_context_free(context); }
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 wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_command) { int i, j; int tx, ty; char* tile_bitmap; RFX_MESSAGE* message; BITMAPINFO bitmap_info; RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context; NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context; tile_bitmap = (char*) malloc(32); ZeroMemory(tile_bitmap, 32); if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); /* blit each tile */ for (i = 0; i < message->numTiles; i++) { tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv); for (j = 0; j < message->numRects; j++) { wf_set_clip_rgn(wfc, surface_bits_command->destLeft + message->rects[j].x, surface_bits_command->destTop + message->rects[j].y, message->rects[j].width, message->rects[j].height); BitBlt(wfc->primary->hdc, tx, ty, 64, 64, wfc->tile->hdc, 0, 0, SRCCOPY); } } wf_set_null_clip_rgn(wfc); /* invalidate regions */ for (i = 0; i < message->numRects; i++) { tx = surface_bits_command->destLeft + message->rects[i].x; ty = surface_bits_command->destTop + message->rects[i].y; wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height); } rfx_message_free(rfx_context, message); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); ZeroMemory(&bitmap_info, sizeof(bitmap_info)); bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmap_info.bmiHeader.biWidth = surface_bits_command->width; bitmap_info.bmiHeader.biHeight = surface_bits_command->height; bitmap_info.bmiHeader.biPlanes = 1; bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp; bitmap_info.bmiHeader.biCompression = BI_RGB; SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height, nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS); wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) { ZeroMemory(&bitmap_info, sizeof(bitmap_info)); bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmap_info.bmiHeader.biWidth = surface_bits_command->width; bitmap_info.bmiHeader.biHeight = surface_bits_command->height; bitmap_info.bmiHeader.biPlanes = 1; bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp; bitmap_info.bmiHeader.biCompression = BI_RGB; SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height, surface_bits_command->bitmapData, &bitmap_info, DIB_RGB_COLORS); wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); } else { fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID); } if (tile_bitmap != NULL) free(tile_bitmap); }
void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command) { int i, tx, ty; XImage* image; RFX_MESSAGE* message; xfInfo* xfi = GET_XFI(update); RFX_CONTEXT* context = (RFX_CONTEXT*) xfi->rfx_context; NSC_CONTEXT* ncontext = (NSC_CONTEXT*) xfi->nsc_context; if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) { message = rfx_process_message(context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetClipRectangles(xfi->display, xfi->gc, surface_bits_command->destLeft, surface_bits_command->destTop, (XRectangle*) message->rects, message->num_rects, YXBanded); /* Draw the tiles to primary surface, each is 64x64. */ for (i = 0; i < message->num_tiles; i++) { image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) message->tiles[i]->data, 64, 64, 32, 0); tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64); XFree(image); } /* Copy the updated region from backstore to the window. */ for (i = 0; i < message->num_rects; i++) { tx = message->rects[i].x + surface_bits_command->destLeft; ty = message->rects[i].y + surface_bits_command->destTop; if (xfi->remote_app != True) { XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, tx, ty, message->rects[i].width, message->rects[i].height, tx, ty); } gdi_InvalidateRegion(xfi->hdc, tx, ty, message->rects[i].width, message->rects[i].height); } XSetClipMask(xfi->display, xfi->gc, None); rfx_message_free(context, message); } else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) { ncontext->width = surface_bits_command->width; ncontext->height = surface_bits_command->height; nsc_process_message(ncontext, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); xfi->bmp_codec_nsc = (uint8*) xrealloc(xfi->bmp_codec_nsc, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(ncontext->bmpdata, xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); if (xfi->remote_app != True) { XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, surface_bits_command->destLeft, surface_bits_command->destTop); } gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); nsc_context_destroy(ncontext); } else if (surface_bits_command->codecID == CODEC_ID_NONE) { XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); xfi->bmp_codec_none = (uint8*) xrealloc(xfi->bmp_codec_none, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); if (xfi->remote_app != True) { XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, surface_bits_command->destLeft, surface_bits_command->destTop); } gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); } else { printf("Unsupported codecID %d\n", surface_bits_command->codecID); } }
static BOOL gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd) { BOOL result = FALSE; DWORD format; rdpGdi* gdi; REGION16 region; RECTANGLE_16 cmdRect; UINT32 i, nbRects; const RECTANGLE_16* rects; if (!context || !cmd) return FALSE; gdi = context->gdi; WLog_Print(gdi->log, WLOG_DEBUG, "destLeft %"PRIu32" destTop %"PRIu32" destRight %"PRIu32" destBottom %"PRIu32" " "bpp %"PRIu32" codecID %"PRIu32" width %"PRIu32" height %"PRIu32" length %"PRIu32"", cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom, cmd->bpp, cmd->codecID, cmd->width, cmd->height, cmd->bitmapDataLength); region16_init(®ion); cmdRect.left = cmd->destLeft; cmdRect.top = cmd->destTop; cmdRect.right = cmdRect.left + cmd->width; cmdRect.bottom = cmdRect.top + cmd->height; switch (cmd->codecID) { case RDP_CODEC_ID_REMOTEFX: if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength, cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height, ®ion)) { WLog_ERR(TAG, "Failed to process RemoteFX message"); goto out; } break; case RDP_CODEC_ID_NSCODEC: format = gdi->dstFormat; if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, gdi->primary_buffer, format, gdi->stride, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, FREERDP_FLIP_VERTICAL)) { WLog_ERR(TAG, "Failed to process NSCodec message"); goto out; } region16_union_rect(®ion, ®ion, &cmdRect); break; case RDP_CODEC_ID_NONE: format = gdi_get_pixel_format(cmd->bpp); if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, cmd->bitmapData, format, 0, 0, 0, &gdi->palette, FREERDP_FLIP_VERTICAL)) { WLog_ERR(TAG, "Failed to process nocodec message"); goto out; } region16_union_rect(®ion, ®ion, &cmdRect); break; default: WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->codecID); break; } if (!(rects = region16_rects(®ion, &nbRects))) goto out; for (i = 0; i < nbRects; i++) { UINT32 left = rects[i].left; UINT32 top = rects[i].top; UINT32 width = rects[i].right - rects[i].left; UINT32 height = rects[i].bottom - rects[i].top; if (!gdi_InvalidateRegion(gdi->primary->hdc, left, top, width, height)) { WLog_ERR(TAG, "Failed to update invalid region"); goto out; } } result = TRUE; out: region16_uninit(®ion); return result; }
static BOOL xf_gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd) { BYTE* pSrcData; xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; DWORD format; rdpGdi* gdi; REGION16 region; RECTANGLE_16 cmdRect; if (!context || !cmd || !context->gdi) return FALSE; region16_init(®ion); cmdRect.left = cmd->destLeft; cmdRect.top = cmd->destTop; cmdRect.right = cmdRect.left + cmd->width; cmdRect.bottom = cmdRect.top + cmd->height; gdi = context->gdi; xf_lock_x11(xfc, FALSE); switch (cmd->codecID) { case RDP_CODEC_ID_REMOTEFX: if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength, cmd->destLeft, cmd->destTop, gdi->primary_buffer, gdi->dstFormat, gdi->stride, gdi->height, ®ion)) goto fail; break; case RDP_CODEC_ID_NSCODEC: if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, gdi->primary_buffer, gdi->dstFormat, gdi->stride, 0, 0, cmd->width, cmd->height, FREERDP_FLIP_VERTICAL)) goto fail; region16_union_rect(®ion, ®ion, &cmdRect); break; case RDP_CODEC_ID_NONE: pSrcData = cmd->bitmapData; format = gdi_get_pixel_format(cmd->bpp); if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride, 0, 0, cmd->width, cmd->height, pSrcData, format, 0, 0, 0, &xfc->context.gdi->palette, FREERDP_FLIP_VERTICAL)) goto fail; region16_union_rect(®ion, ®ion, &cmdRect); break; default: WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->codecID); ret = TRUE; goto fail; } ret = xf_gdi_update_screen(xfc, gdi->primary_buffer, gdi->stride, ®ion); fail: region16_uninit(®ion); xf_unlock_x11(xfc, FALSE); return ret; }
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codecId) { BOOL status; UINT16 size; BYTE* src; BYTE* dst; int yindex; int xindex; rdpGdi* gdi; RFX_MESSAGE* msg; size = width * height * ((bpp + 7) / 8); if (!bitmap->data) bitmap->data = (BYTE*) malloc(size); else bitmap->data = (BYTE*) realloc(bitmap->data, size); switch (codecId) { case RDP_CODEC_ID_NSCODEC: gdi = context->gdi; nsc_process_message(gdi->nsc_context, bpp, width, height, data, length); freerdp_image_flip(((NSC_CONTEXT*) gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp); break; case RDP_CODEC_ID_REMOTEFX: gdi = context->gdi; rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); msg = rfx_process_message(gdi->rfx_context, data, length); if (!msg) { fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n"); } else { for (yindex = 0; yindex < height; yindex++) { src = msg->tiles[0]->data + yindex * 64 * 4; dst = bitmap->data + yindex * width * 3; for (xindex = 0; xindex < width; xindex++) { *(dst++) = *(src++); *(dst++) = *(src++); *(dst++) = *(src++); src++; } } rfx_message_free(gdi->rfx_context, msg); } break; case RDP_CODEC_ID_JPEG: #ifdef WITH_JPEG if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp)) { fprintf(stderr, "gdi_Bitmap_Decompress: jpeg Decompression Failed\n"); } #endif break; default: if (compressed) { status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); if (!status) { fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n"); } } else { freerdp_image_flip(data, bitmap->data, width, height, bpp); } break; } bitmap->width = width; bitmap->height = height; bitmap->compressed = FALSE; bitmap->length = size; bitmap->bpp = bpp; }
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) { int i, tx, ty; XImage* image; RFX_MESSAGE* message; xfInfo* xfi = ((xfContext*) context)->xfi; RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context; NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context; if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetClipRectangles(xfi->display, xfi->gc, surface_bits_command->destLeft, surface_bits_command->destTop, (XRectangle*) message->rects, message->num_rects, YXBanded); /* Draw the tiles to primary surface, each is 64x64. */ for (i = 0; i < message->num_tiles; i++) { image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) message->tiles[i]->data, 64, 64, 32, 0); tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64); XFree(image); } /* Copy the updated region from backstore to the window. */ for (i = 0; i < message->num_rects; i++) { tx = message->rects[i].x + surface_bits_command->destLeft; ty = message->rects[i].y + surface_bits_command->destTop; xf_gdi_surface_update_frame(xfi, tx, ty, message->rects[i].width, message->rects[i].height); } XSetClipMask(xfi->display, xfi->gc, None); rfx_message_free(rfx_context, message); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); xfi->bmp_codec_nsc = (BYTE*) realloc(xfi->bmp_codec_nsc, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(nsc_context->bmpdata, xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); xf_gdi_surface_update_frame(xfi, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) { XSetFunction(xfi->display, xfi->gc, GXcopy); XSetFillStyle(xfi->display, xfi->gc, FillSolid); /* Validate that the data received is large enough */ if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength ) { xfi->bmp_codec_none = (BYTE*) realloc(xfi->bmp_codec_none, surface_bits_command->width * surface_bits_command->height * 4); freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32); image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, (char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0); XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XFree(image); xf_gdi_surface_update_frame(xfi, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); XSetClipMask(xfi->display, xfi->gc, None); } else { printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height); } } else { printf("Unsupported codecID %d\n", surface_bits_command->codecID); } }
void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) { int i, j; int tx, ty; char* tile_bitmap; RFX_MESSAGE* message; wfInfo* wfi = ((wfContext*) context)->wfi; RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context; NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context; tile_bitmap = (char*) xzalloc(32); if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) { RECTANGLE_16 dest_rect; dest_rect.left = surface_bits_command->destLeft; dest_rect.top = surface_bits_command->destTop; dest_rect.right = surface_bits_command->destRight; dest_rect.bottom = surface_bits_command->destBottom; message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength, &dest_rect); /* blit each tile */ for (i = 0; i < message->num_tiles; i++) { tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 32, wfi->clrconv); for (j = 0; j < message->num_rects; j++) { wf_set_clip_rgn(wfi, surface_bits_command->destLeft + message->rects[j].x, surface_bits_command->destTop + message->rects[j].y, message->rects[j].width, message->rects[j].height); BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY); } } wf_set_null_clip_rgn(wfi); /* invalidate regions */ for (i = 0; i < message->num_rects; i++) { tx = surface_bits_command->destLeft + message->rects[i].x; ty = surface_bits_command->destTop + message->rects[i].y; wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height); } rfx_message_free(rfx_context, message); } else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) { nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); wfi->image->_bitmap.width = surface_bits_command->width; wfi->image->_bitmap.height = surface_bits_command->height; wfi->image->_bitmap.bpp = surface_bits_command->bpp; wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); freerdp_image_flip(nsc_context->bmpdata, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, GDI_SRCCOPY); } else if (surface_bits_command->codecID == CODEC_ID_NONE) { wfi->image->_bitmap.width = surface_bits_command->width; wfi->image->_bitmap.height = surface_bits_command->height; wfi->image->_bitmap.bpp = surface_bits_command->bpp; wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); if ((surface_bits_command->bpp != 32) || (wfi->clrconv->alpha == true)) { uint8* temp_image; freerdp_image_convert(surface_bits_command->bitmapData, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, wfi->image->_bitmap.bpp, 32, wfi->clrconv); surface_bits_command->bpp = 32; surface_bits_command->bitmapData = wfi->image->_bitmap.data; temp_image = (uint8*) xmalloc(wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); freerdp_image_flip(wfi->image->_bitmap.data, temp_image, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); xfree(wfi->image->_bitmap.data); wfi->image->_bitmap.data = temp_image; } else { freerdp_image_flip(surface_bits_command->bitmapData, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); } BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, SRCCOPY); } else { printf("Unsupported codecID %d\n", surface_bits_command->codecID); } if (tile_bitmap != NULL) xfree(tile_bitmap); }
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); }
static BOOL xf_gdi_surface_bits(rdpContext* context, const SURFACE_BITS_COMMAND* cmd) { BYTE* pSrcData; xfContext* xfc = (xfContext*) context; BOOL ret = FALSE; DWORD format; DWORD stride; rdpGdi* gdi; if (!context || !cmd || !context->gdi) return FALSE; gdi = context->gdi; stride = cmd->width * GetBytesPerPixel(gdi->dstFormat); xf_lock_x11(xfc, FALSE); switch (cmd->codecID) { case RDP_CODEC_ID_REMOTEFX: format = PIXEL_FORMAT_BGRX32; if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData, format, cmd->bitmapDataLength, 0, 0, gdi->primary_buffer, gdi->dstFormat, stride, gdi->height, NULL)) goto fail; break; case RDP_CODEC_ID_NSCODEC: format = FREERDP_VFLIP_PIXEL_FORMAT(gdi->dstFormat); if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength, gdi->primary_buffer, format, stride, 0, 0, cmd->width, cmd->height)) goto fail; break; case RDP_CODEC_ID_NONE: pSrcData = cmd->bitmapData; format = PIXEL_FORMAT_BGRX32_VF; if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, stride, 0, 0, cmd->width, cmd->height, pSrcData, format, 0, 0, 0, &xfc->context.gdi->palette)) goto fail; break; default: WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID); ret = TRUE; goto fail; } ret = xf_gdi_update_screen(xfc, cmd, gdi->primary_buffer); fail: xf_unlock_x11(xfc, FALSE); return ret; }