summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2009-03-31 14:06:53 +0000
committerPierre Ossman <ossman@cendio.se>2009-03-31 14:06:53 +0000
commit19501b8e23ec152bf883ef52bccfa978df4a245b (patch)
treeafe9de9dce72d80b23d59617ddac9879e6206b38
parenteed5d1f7f11628f8656320adae8f3c38b45ee74f (diff)
downloadtigervnc-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.cxx38
-rw-r--r--common/rfb/PixelFormat.h3
-rw-r--r--common/rfb/PixelFormat.inl25
-rw-r--r--common/rfb/tightDecode.h6
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);