diff --git a/include/freerdp/gdi/bitmap.h b/include/freerdp/gdi/bitmap.h index 42caf0b13..e9d327ae0 100644 --- a/include/freerdp/gdi/bitmap.h +++ b/include/freerdp/gdi/bitmap.h @@ -38,7 +38,8 @@ FREERDP_API UINT32* gdi_GetPointer_32bpp(HGDI_BITMAP hBmp, int X, int Y); FREERDP_API void gdi_SetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y, BYTE pixel); FREERDP_API void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, UINT16 pixel); FREERDP_API void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, UINT32 pixel); -FREERDP_API HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* data); +FREERDP_API HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, + BYTE* data, void (*fkt_free)(void*)); FREERDP_API HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight); FREERDP_API BOOL gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, DWORD rop); diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index 9736ba724..804fb802e 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -178,6 +178,7 @@ struct _GDI_BITMAP int height; int scanline; BYTE* data; + void (*free)(void *); }; typedef struct _GDI_BITMAP GDI_BITMAP; typedef GDI_BITMAP* HGDI_BITMAP; diff --git a/libfreerdp/gdi/bitmap.c b/libfreerdp/gdi/bitmap.c index cc3ee84ed..b5cd25b73 100644 --- a/libfreerdp/gdi/bitmap.c +++ b/libfreerdp/gdi/bitmap.c @@ -130,10 +130,12 @@ INLINE void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, UINT32 pixel) * @param nHeight height * @param cBitsPerPixel bits per pixel * @param data pixel buffer + * @param fkt_free The function used for deallocation of the buffer, NULL for none. * @return new bitmap */ -HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* data) +HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* data, + void (*fkt_free)(void*)) { HGDI_BITMAP hBitmap = (HGDI_BITMAP) calloc(1, sizeof(GDI_BITMAP)); @@ -147,6 +149,7 @@ HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* d hBitmap->width = nWidth; hBitmap->height = nHeight; hBitmap->data = data; + hBitmap->free = fkt_free; return hBitmap; } @@ -162,7 +165,7 @@ HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, BYTE* d HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight) { - HGDI_BITMAP hBitmap = (HGDI_BITMAP) malloc(sizeof(GDI_BITMAP)); + HGDI_BITMAP hBitmap = (HGDI_BITMAP) calloc(1, sizeof(GDI_BITMAP)); if (!hBitmap) return NULL; @@ -173,6 +176,7 @@ HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight) hBitmap->width = nWidth; hBitmap->height = nHeight; hBitmap->data = _aligned_malloc(nWidth * nHeight * hBitmap->bytesPerPixel, 16); + hBitmap->free = _aligned_free; if (!hBitmap->data) { free(hBitmap); diff --git a/libfreerdp/gdi/dc.c b/libfreerdp/gdi/dc.c index b816a77b5..f1032bef8 100644 --- a/libfreerdp/gdi/dc.c +++ b/libfreerdp/gdi/dc.c @@ -201,8 +201,11 @@ BOOL gdi_DeleteObject(HGDIOBJECT hgdiobject) { HGDI_BITMAP hBitmap = (HGDI_BITMAP) hgdiobject; - if (hBitmap->data) - _aligned_free(hBitmap->data); + if (hBitmap->data && hBitmap->free) + { + hBitmap->free(hBitmap->data); + hBitmap->data = NULL; + } free(hBitmap); } diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 271ecd7ef..5572ecafd 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -399,7 +399,7 @@ gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, BYTE* { gdiBitmap* bitmap; - bitmap = (gdiBitmap*) malloc(sizeof(gdiBitmap)); + bitmap = (gdiBitmap*) calloc(1, sizeof(gdiBitmap)); if (!bitmap) goto fail_bitmap; @@ -645,7 +645,7 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8, hatched, backColor, foreColor, gdi->palette); - hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); + hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data, _aligned_free); if (!hBmp) { _aligned_free(data); @@ -703,7 +703,7 @@ static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush->data, backColor, foreColor, gdi->palette); } - hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); + hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data, _aligned_free); if (!hBmp) { _aligned_free(data); @@ -937,7 +937,7 @@ static BOOL gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush->data, backColor, foreColor, gdi->palette); } - hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); + hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data, _aligned_free); if (!hBmp) { _aligned_free(data); @@ -1102,11 +1102,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) 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_DeleteObject(gdi->image->bitmap); + gdi->image->bitmap = gdi_CreateBitmap(cmd->width, cmd->height, cmd->bpp, gdi->bitmap_buffer, NULL); gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } @@ -1127,11 +1124,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) 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_DeleteObject(gdi->image->bitmap); + gdi->image->bitmap = gdi_CreateBitmap(cmd->width, cmd->height, cmd->bpp, gdi->bitmap_buffer, NULL); gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); } @@ -1197,7 +1191,8 @@ BOOL gdi_init_primary(rdpGdi* gdi) if (!gdi->primary_buffer) gdi->primary->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, gdi->width, gdi->height); else - gdi->primary->bitmap = gdi_CreateBitmap(gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer); + gdi->primary->bitmap = gdi_CreateBitmap(gdi->width, gdi->height, gdi->dstBpp, + gdi->primary_buffer, NULL); if (!gdi->primary->bitmap) goto fail_bitmap; diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 8e53c5280..8acb95394 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -92,7 +92,7 @@ HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int nWidth, int nHeight, int bpp, BYT freerdp_image_copy(pDstData, gdi->format, nDstStep, 0, 0, nWidth, nHeight, pSrcData, SrcFormat, nSrcStep, 0, 0, gdi->palette); - bitmap = gdi_CreateBitmap(nWidth, nHeight, gdi->dstBpp, pDstData); + bitmap = gdi_CreateBitmap(nWidth, nHeight, gdi->dstBpp, pDstData, _aligned_free); return bitmap; } @@ -241,7 +241,7 @@ BOOL gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph) gdi_DeleteDC(gdi_glyph->hdc); return FALSE; } - gdi_glyph->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, data); + gdi_glyph->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, data, _aligned_free); if (!gdi_glyph->bitmap) { gdi_DeleteDC(gdi_glyph->hdc);