From: Pierre Ossman Date: Tue, 31 Mar 2009 14:06:53 +0000 (+0000) Subject: Optimise the common pixel format conversion RGB24 to RGB32. X-Git-Tag: v0.0.90~59 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=19501b8e23ec152bf883ef52bccfa978df4a245b;p=tigervnc.git Optimise the common pixel format conversion RGB24 to RGB32. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3730 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx index e8cb1a21..b00bc823 100644 --- a/common/rfb/PixelFormat.cxx +++ b/common/rfb/PixelFormat.cxx @@ -180,6 +180,44 @@ Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, } +void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, + int pixels, ColourMap* cm) const +{ + if (is888()) { + // Optimised common case + rdr::U8 *r, *g, *b; + + r = dst + redShift/8; + g = dst + greenShift/8; + b = dst + blueShift/8; + + while (pixels--) { + *r = *(src++); + *g = *(src++); + *b = *(src++); + r += 4; + g += 4; + b += 4; + } + } else { + // Generic code + Pixel p; + rdr::U8 r, g, b; + + while (pixels--) { + r = *(src++); + g = *(src++); + b = *(src++); + + p = pixelFromRGB(r, g, b, cm); + + bufferFromPixel(dst, p); + dst += bpp/8; + } + } +} + + void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, Colour* rgb) const { rdr::U16 r, g, b; diff --git a/common/rfb/PixelFormat.h b/common/rfb/PixelFormat.h index 7daa6e7d..8adbf911 100644 --- a/common/rfb/PixelFormat.h +++ b/common/rfb/PixelFormat.h @@ -46,10 +46,13 @@ namespace rfb { bool isLittleEndian(void) const; inline Pixel pixelFromBuffer(const rdr::U8* buffer) const; + inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const; Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue, ColourMap* cm=0) const; Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue, ColourMap* cm=0) const; + void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels, ColourMap* cm=0) const; + void rgbFromPixel(Pixel pix, ColourMap* cm, Colour* rgb) const; inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const; inline void rgbFromPixel(Pixel pix, ColourMap* cm, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const; diff --git a/common/rfb/PixelFormat.inl b/common/rfb/PixelFormat.inl index d5edfa55..90d8e6da 100644 --- a/common/rfb/PixelFormat.inl +++ b/common/rfb/PixelFormat.inl @@ -50,6 +50,31 @@ inline Pixel PixelFormat::pixelFromBuffer(const rdr::U8* buffer) const } +inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const +{ + if (bigEndian) { + switch (bpp) { + case 32: + *(buffer++) = (p >> 24) & 0xff; + *(buffer++) = (p >> 16) & 0xff; + case 16: + *(buffer++) = (p >> 8) & 0xff; + case 8: + *(buffer++) = (p >> 0) & 0xff; + } + } else { + buffer[0] = (p >> 0) & 0xff; + if (bpp >= 16) { + buffer[1] = (p >> 8) & 0xff; + if (bpp == 32) { + buffer[2] = (p >> 16) & 0xff; + buffer[3] = (p >> 24) & 0xff; + } + } + } +} + + inline void PixelFormat::rgbFromPixel(Pixel p, ColourMap* cm, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const { if (trueColour) { diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h index 9cf234d0..9679dd78 100644 --- a/common/rfb/tightDecode.h +++ b/common/rfb/tightDecode.h @@ -267,10 +267,8 @@ DecompressJpegRect(const Rect& r, rdr::InStream* is, break; } - for (int dx = 0; dx < r.width(); dx++) { - *pixelPtr++ = - myFormat.pixelFromRGB(scanline[dx*3], scanline[dx*3+1], scanline[dx*3+2]); - } + myFormat.bufferFromRGB((rdr::U8*)pixelPtr, (const rdr::U8*)scanline, r.width()); + pixelPtr += r.width(); } IMAGE_RECT(r, buf);