diff options
author | Pierre Ossman <ossman@cendio.se> | 2009-03-31 14:06:53 +0000 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2009-03-31 14:06:53 +0000 |
commit | 19501b8e23ec152bf883ef52bccfa978df4a245b (patch) | |
tree | afe9de9dce72d80b23d59617ddac9879e6206b38 | |
parent | eed5d1f7f11628f8656320adae8f3c38b45ee74f (diff) | |
download | tigervnc-19501b8e23ec152bf883ef52bccfa978df4a245b.tar.gz tigervnc-19501b8e23ec152bf883ef52bccfa978df4a245b.zip |
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
-rw-r--r-- | common/rfb/PixelFormat.cxx | 38 | ||||
-rw-r--r-- | common/rfb/PixelFormat.h | 3 | ||||
-rw-r--r-- | common/rfb/PixelFormat.inl | 25 | ||||
-rw-r--r-- | common/rfb/tightDecode.h | 6 |
4 files changed, 68 insertions, 4 deletions
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); |