libfreerdp-codec: add freerdp_image_copy_from_monochrome replacement function for...
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 22 Oct 2014 01:56:10 +0000 (21:56 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 22 Oct 2014 01:56:10 +0000 (21:56 -0400)
client/X11/xf_gdi.c
include/freerdp/codec/color.h
libfreerdp/codec/color.c
libfreerdp/gdi/gdi.c

index fcf4db5..acb3d7a 100644 (file)
@@ -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);
index a52a254..9f8aca6 100644 (file)
@@ -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);
 
index 6227e29..09c1038 100644 (file)
@@ -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;
index 72720da..3122746 100644 (file)
@@ -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);