From 5f95f0776fa775f1b363c15ee527eaa5872e5545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 21 Oct 2014 21:56:10 -0400 Subject: [PATCH] libfreerdp-codec: add freerdp_image_copy_from_monochrome replacement function for deprecated freerdp_mono_image_convert --- client/X11/xf_gdi.c | 11 ++- include/freerdp/codec/color.h | 3 + libfreerdp/codec/color.c | 157 +++++++++++++++++++++++++++++++++- libfreerdp/gdi/gdi.c | 37 ++++++-- 4 files changed, 196 insertions(+), 12 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index fcf4db5e2..acb3d7a8a 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -241,20 +241,25 @@ unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color) Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data) { + GC gc; Pixmap bitmap; BYTE* cdata; XImage* image; + UINT32 brushFormat; bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth); if (data) { - GC gc; + brushFormat = gdi_get_pixel_format(bpp, FALSE); - cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfc->bpp, xfc->clrconv); + cdata = (BYTE*) _aligned_malloc(width * height * 4, 16); + + freerdp_image_copy(cdata, xfc->format, -1, 0, 0, + width, height, data, brushFormat, -1, 0, 0, xfc->palette); image = XCreateImage(xfc->display, xfc->visual, xfc->depth, - ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0); + ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0); gc = XCreateGC(xfc->display, xfc->drawable, 0, NULL); XPutImage(xfc->display, bitmap, gc, image, 0, 0, 0, 0, width, height); diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index a52a25472..9f8aca695 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -449,6 +449,9 @@ FREERDP_API UINT32 freerdp_convert_gdi_order_color(UINT32 color, int bpp, UINT32 FREERDP_API HCLRCONV freerdp_clrconv_new(UINT32 flags); FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv); +FREERDP_API int freerdp_image_copy_from_monochrome(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst, + int nWidth, int nHeight, BYTE* pSrcData, UINT32 backColor, UINT32 foreColor, BYTE* palette); + FREERDP_API int freerdp_image_copy_from_pointer_data(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, BYTE* xorMask, BYTE* andMask, UINT32 xorBpp, BYTE* palette); diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 6227e2904..09c1038e4 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1131,7 +1131,7 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp int bitIndex; BYTE redBg, greenBg, blueBg; BYTE redFg, greenFg, blueFg; - + GetRGB32(redBg, greenBg, blueBg, bgcolor); GetRGB32(redFg, greenFg, blueFg, fgcolor); @@ -1223,6 +1223,161 @@ BYTE* freerdp_mono_image_convert(BYTE* srcData, int width, int height, int srcBp return srcData; } +int freerdp_image_copy_from_monochrome(BYTE* pDstData, UINT32 DstFormat, int nDstStep, int nXDst, int nYDst, + int nWidth, int nHeight, BYTE* pSrcData, UINT32 backColor, UINT32 foreColor, BYTE* palette) +{ + int x, y; + BOOL vFlip; + BOOL invert; + int srcFlip; + int dstFlip; + int nDstPad; + int monoStep; + UINT32 monoBit; + BYTE* monoBits; + UINT32 monoPixel; + BYTE a, r, g, b; + int dstBitsPerPixel; + int dstBytesPerPixel; + + dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(DstFormat); + dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(DstFormat) / 8); + dstFlip = FREERDP_PIXEL_FORMAT_FLIP(DstFormat); + + if (nDstStep < 0) + nDstStep = dstBytesPerPixel * nWidth; + + nDstPad = (nDstStep - (nWidth * dstBytesPerPixel)); + + srcFlip = FREERDP_PIXEL_FLIP_NONE; + vFlip = (srcFlip != dstFlip) ? TRUE : FALSE; + + invert = (FREERDP_PIXEL_FORMAT_IS_ABGR(DstFormat)) ? TRUE : FALSE; + + backColor |= 0xFF000000; + foreColor |= 0xFF000000; + + monoStep = (nWidth + 7) / 8; + + if (dstBytesPerPixel == 4) + { + UINT32* pDstPixel; + + if (invert) + { + GetARGB32(a, r, g, b, backColor); + backColor = ABGR32(a, r, g, b); + + GetARGB32(a, r, g, b, foreColor); + foreColor = ABGR32(a, r, g, b); + } + + pDstPixel = (UINT32*) &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; + + for (y = 0; y < nHeight; y++) + { + monoBit = 0x80; + + if (!vFlip) + monoBits = &pSrcData[monoStep * y]; + else + monoBits = &pSrcData[monoStep * (nHeight - y - 1)]; + + for (x = 0; x < nWidth; x++) + { + monoPixel = (*monoBits & monoBit) ? 1 : 0; + if (!(monoBit >>= 1)) { monoBits++; monoBit = 0x80; } + + if (monoPixel) + *pDstPixel++ = backColor; + else + *pDstPixel++ = foreColor; + } + + pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[nDstPad]; + } + + return 1; + } + else if (dstBytesPerPixel == 2) + { + UINT16* pDstPixel; + UINT16 backColor16; + UINT16 foreColor16; + + if (!invert) + { + if (dstBitsPerPixel == 15) + { + GetRGB32(r, g, b, backColor); + backColor16 = RGB15(r, g, b); + + GetRGB32(r, g, b, foreColor); + foreColor16 = RGB15(r, g, b); + } + else + { + GetRGB32(r, g, b, backColor); + backColor16 = RGB16(r, g, b); + + GetRGB32(r, g, b, foreColor); + foreColor16 = RGB16(r, g, b); + } + } + else + { + if (dstBitsPerPixel == 15) + { + GetRGB32(r, g, b, backColor); + backColor16 = BGR15(r, g, b); + + GetRGB32(r, g, b, foreColor); + foreColor16 = BGR15(r, g, b); + } + else + { + GetRGB32(r, g, b, backColor); + backColor16 = BGR16(r, g, b); + + GetRGB32(r, g, b, foreColor); + foreColor16 = BGR16(r, g, b); + } + } + + pDstPixel = (UINT16*) &pDstData[(nYDst * nDstStep) + (nXDst * 2)]; + + for (y = 0; y < nHeight; y++) + { + monoBit = 0x80; + + if (!vFlip) + monoBits = &pSrcData[monoStep * y]; + else + monoBits = &pSrcData[monoStep * (nHeight - y - 1)]; + + for (x = 0; x < nWidth; x++) + { + monoPixel = (*monoBits & monoBit) ? 1 : 0; + if (!(monoBit >>= 1)) { monoBits++; monoBit = 0x80; } + + if (monoPixel) + *pDstPixel++ = backColor16; + else + *pDstPixel++ = foreColor16; + } + + pDstPixel = (UINT16*) &((BYTE*) pDstPixel)[nDstPad]; + } + + return 1; + } + + fprintf(stderr, "freerdp_image_copy_from_monochrome failure: dstBytesPerPixel: %d dstBitsPerPixel: %d\n", + dstBytesPerPixel, dstBitsPerPixel); + + return -1; +} + void freerdp_alpha_cursor_convert(BYTE* alphaData, BYTE* xorMask, BYTE* andMask, int width, int height, int bpp, HCLRCONV clrconv) { UINT32 xorPixel; diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 72720daf1..312274627 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -615,10 +615,15 @@ static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) } else if (brush->style == GDI_BS_HATCHED) { + BYTE* hatched; HGDI_BITMAP hBmp; - data = freerdp_mono_image_convert(GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch, 8, 8, 1, - gdi->dstBpp, backColor, foreColor, gdi->clrconv); + data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); + + hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch); + + 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); @@ -634,15 +639,23 @@ static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) else if (brush->style == GDI_BS_PATTERN) { HGDI_BITMAP hBmp; + UINT32 brushFormat; if (brush->bpp > 1) { - data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv); + brushFormat = gdi_get_pixel_format(brush->bpp, FALSE); + + data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); + + freerdp_image_copy(data, gdi->format, -1, 0, 0, + 8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette); } else { - data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - backColor, foreColor, gdi->clrconv); + data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); + + freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8, + brush->data, backColor, foreColor, gdi->palette); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -810,15 +823,23 @@ static void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) else if (brush->style == GDI_BS_PATTERN) { HGDI_BITMAP hBmp; + UINT32 brushFormat; if (brush->bpp > 1) { - data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv); + brushFormat = gdi_get_pixel_format(brush->bpp, FALSE); + + data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); + + freerdp_image_copy(data, gdi->format, -1, 0, 0, + 8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette); } else { - data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, - backColor, foreColor, gdi->clrconv); + data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16); + + freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8, + brush->data, backColor, foreColor, gdi->palette); } hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);