Fix rounding error in pixel down conversion
Simple shifting can give noticable rounding errors if there is a large
difference in the number of bits between the formats. Do the proper
thing via a lookup table, the same way things are done for up conversion.
diff --git a/common/rfb/PixelFormatBPP.cxx b/common/rfb/PixelFormatBPP.cxx
index 6b5ad6b..c8e432d 100644
--- a/common/rfb/PixelFormatBPP.cxx
+++ b/common/rfb/PixelFormatBPP.cxx
@@ -41,11 +41,11 @@
const rdr::U8 *r, *g, *b;
int dstPad, srcPad;
- int redTruncShift, greenTruncShift, blueTruncShift;
+ const rdr::U8 *redDownTable, *greenDownTable, *blueDownTable;
- redTruncShift = 8 - redBits;
- greenTruncShift = 8 - greenBits;
- blueTruncShift = 8 - blueBits;
+ redDownTable = &downconvTable[(redBits-1)*256];
+ greenDownTable = &downconvTable[(greenBits-1)*256];
+ blueDownTable = &downconvTable[(blueBits-1)*256];
if (srcPF.bigEndian) {
r = src + (24 - srcPF.redShift)/8;
@@ -64,9 +64,9 @@
while (w_--) {
rdr::UOUT d;
- d = (*r >> redTruncShift) << redShift;
- d |= (*g >> greenTruncShift) << greenShift;
- d |= (*b >> blueTruncShift) << blueShift;
+ d = redDownTable[*r] << redShift;
+ d |= greenDownTable[*g] << greenShift;
+ d |= blueDownTable[*b] << blueShift;
#if OUTBPP != 8
if (endianMismatch)