From 711f4b2202bc866458fefa71c18ade80cf88ce61 Mon Sep 17 00:00:00 2001 From: Philippe Auphelle Date: Mon, 12 Dec 2011 14:41:31 +0100 Subject: [PATCH] Refactored bitmap_flip in bitmap.c to use freerdp_bitmap_flip in color.c. Added in place "bitmap flip" in freerdp_bitmap_flip, changed bitmap_decompress (in bitmap.c) to use it. --- include/freerdp/codec/color.h | 5 ++- libfreerdp-codec/bitmap.c | 41 +++++---------------- libfreerdp-codec/color.c | 69 ++++++++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 48 deletions(-) diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index ad4845da3..acb7fb2a6 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -30,7 +30,7 @@ extern "C" { /* Color Space Conversions: http://msdn.microsoft.com/en-us/library/ff566496/ */ /* Color Space Conversion */ - + #define RGB_555_565(_r, _g, _b) \ _r = _r; \ _g = (_g << 1 & ~0x1) | (_g >> 4); \ @@ -124,7 +124,7 @@ extern "C" { _b = (_p & 0xF800) >> 11; \ _g = (_p & 0x7E0) >> 5; \ _r = (_p & 0x1F); - + #define GetBGR16(_r, _g, _b, _p) \ GetBGR_565(_r, _g, _b, _p); \ RGB_565_888(_r, _g, _b); @@ -240,6 +240,7 @@ typedef uint8* (*p_freerdp_image_convert)(uint8* srcData, uint8* dstData, int wi FREERDP_API uint32 freerdp_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API uint8* freerdp_image_convert(uint8* srcData, uint8 *dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv); FREERDP_API uint8* freerdp_glyph_convert(int width, int height, uint8* data); +FREERDP_API void freerdp_bitmap_flip(uint8 * src, uint8 * dst, int scanLineSz, int height); FREERDP_API uint8* freerdp_image_flip(uint8* srcData, uint8* dstData, int width, int height, int bpp); FREERDP_API uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv); FREERDP_API uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv); diff --git a/libfreerdp-codec/bitmap.c b/libfreerdp-codec/bitmap.c index 08bebb49c..d68811a62 100644 --- a/libfreerdp-codec/bitmap.c +++ b/libfreerdp-codec/bitmap.c @@ -19,6 +19,7 @@ #include #include +#include #include @@ -392,22 +393,6 @@ static boolean bitmap_decompress4(uint8* srcData, uint8* dstData, int width, int return (size == total_pro) ? true : false; } -/** - * bitmap flip - */ -static int bitmap_flip(uint8* src, uint8* dst, int delta, int height) -{ - int index; - - dst = (dst + delta * height) - delta; - for (index = 0; index < height; index++) - { - memcpy(dst, src, delta); - src += delta; - dst -= delta; - } - return 0; -} /** * bitmap decompression routine @@ -418,10 +403,8 @@ boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, if (srcBpp == 16 && dstBpp == 16) { - data = (uint8*) xmalloc(width * height * 2); - RleDecompress16to16(srcData, size, data, width * 2, width, height); - bitmap_flip(data, dstData, width * 2, height); - xfree(data); + RleDecompress16to16(srcData, size, dstData, width * 2, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 2, height); } else if (srcBpp == 32 && dstBpp == 32) { @@ -430,24 +413,18 @@ boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, } else if (srcBpp == 15 && dstBpp == 15) { - data = (uint8*) xmalloc(width * height * 2); - RleDecompress16to16(srcData, size, data, width * 2, width, height); - bitmap_flip(data, dstData, width * 2, height); - xfree(data); + RleDecompress16to16(srcData, size, dstData, width * 2, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 2, height); } else if (srcBpp == 8 && dstBpp == 8) { - data = (uint8*) xmalloc(width * height); - RleDecompress8to8(srcData, size, data, width, width, height); - bitmap_flip(data, dstData, width, height); - xfree(data); + RleDecompress8to8(srcData, size, dstData, width, width, height); + freerdp_bitmap_flip(dstData, dstData, width, height); } else if (srcBpp == 24 && dstBpp == 24) { - data = (uint8*) xmalloc(width * height * 3); - RleDecompress24to24(srcData, size, data, width * 3, width, height); - bitmap_flip(data, dstData, width * 3, height); - xfree(data); + RleDecompress24to24(srcData, size, dstData, width * 3, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 3, height); } else { diff --git a/libfreerdp-codec/color.c b/libfreerdp-codec/color.c index 5a0efd04a..a47fc5d0d 100644 --- a/libfreerdp-codec/color.c +++ b/libfreerdp-codec/color.c @@ -22,6 +22,7 @@ #include #include #include +#include int freerdp_get_pixel(uint8 * data, int x, int y, int width, int height, int bpp) { @@ -632,28 +633,68 @@ uint8* freerdp_image_convert(uint8* srcData, uint8* dstData, int width, int heig return 0; } +void freerdp_bitmap_flip(uint8 * src, uint8 * dst, int scanLineSz, int height) +{ + int i; + + uint8 * bottomLine = dst + (scanLineSz * (height - 1)); + uint8 * topLine = src; + + /* Special processing if called for flip-in-place. */ + if (src == dst) + { + /* Allocate a scanline buffer. + * (FIXME: xmalloc / xfree below should be replaced by "get/put + * scanline buffer from a pool/Q of fixed buffers" to reuse + * fixed size buffers (of max scanline size (or adaptative?) ) + * -- would be much faster). + */ + uint8 * tmpBfr = xmalloc(scanLineSz); + int half = height / 2; + /* Flip buffer in place by line permutations through the temp + * scan line buffer. + * Not that if height has an odd number of line, we don't need + * to move the center scanline anyway. + * Also note that in place flipping takes three memcpy() calls + * to process two scanlines while src to distinct dest would + * only requires two memcpy() calls for two scanlines. + */ + height--; + for (i = 0; i < half ; i++) + { + memcpy(tmpBfr, topLine, scanLineSz); + memcpy(topLine, bottomLine, scanLineSz); + memcpy(bottomLine, tmpBfr, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + height--; + } + xfree(tmpBfr); + } + /* Flip from source buffer to destination buffer. */ + else + { + + for (i = 0; i < height; i++) + { + memcpy(bottomLine, topLine, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + } + } + +} + uint8* freerdp_image_flip(uint8* srcData, uint8* dstData, int width, int height, int bpp) { - int y; - uint8* srcp; - uint8* dstp; int scanline; scanline = width * (bpp / 8); if (dstData == NULL) - dstData = (uint8*) malloc(width * height * (bpp / 8)); - - dstp = dstData; - srcp = &srcData[scanline * (height - 1)]; - - for (y = height - 1; y >= 0; y--) - { - memcpy(dstp, srcp, scanline); - dstp += scanline; - srcp -= scanline; - } + dstData = (uint8*) xmalloc(width * height * (bpp / 8)); + freerdp_bitmap_flip(srcData, dstData, scanline, height); return dstData; }