Using new TightPalette helper class instead of std::map, in Hextile
encoder. This improves performance of the encoder, and provides more
space for optimizations. The palette implementation was extracted from
the Tight encoder.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@324 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/rfb/hextileEncodeBetter.h b/rfb/hextileEncodeBetter.h
index 9e03792..7a0e168 100644
--- a/rfb/hextileEncodeBetter.h
+++ b/rfb/hextileEncodeBetter.h
@@ -24,10 +24,9 @@
// EXTRA_ARGS - optional extra arguments
// GET_IMAGE_INTO_BUF - gets a rectangle of pixel data into a buffer
-#include <map>
-
#include <rdr/OutStream.h>
#include <rfb/hextileConstants.h>
+#include <rfb/TightPalette.h>
#include <assert.h>
@@ -56,21 +55,25 @@
HEXTILE_TILE ();
//
- // Initialize the object with new tile data.
+ // Initialize existing object instance with new tile data.
//
void newTile(const PIXEL_T *src, int w, int h);
//
- // Returns the size of encoded subrects data, including subrects count.
- //
- int getSize() const { return m_size; }
-
- //
- // Flags can include: hextileAnySubrects, hextileSubrectsColoured.
+ // Flags can include: hextileRaw, hextileAnySubrects and
+ // hextileSubrectsColoured. Note that if hextileRaw is set, other
+ // flags make no sense. Also, hextileSubrectsColoured is meaningful
+ // only when hextileAnySubrects is set as well.
//
int getFlags() const { return m_flags; }
//
+ // Returns the size of encoded subrects data, including subrect count.
+ // The size is zero if flags do not include hextileAnySubrects.
+ //
+ int getSize() const { return m_size; }
+
+ //
// Return optimal background.
//
int getBackground() const { return m_background; }
@@ -91,7 +94,7 @@
protected:
//
- // Fill in m_coords[], m_colors[], m_counts[] and set m_numSubrects.
+ // Fill in m_coords[], m_colors[], m_pal and set m_numSubrects.
//
void buildTables();
@@ -116,12 +119,8 @@
private:
- // DEBUG: Check performance for: (1) U8[] and (2) dyn.allocated.
bool m_processed[16][16];
-
- // FIXME: Use array for (BPP == 8)?
- // DEBUG: Use own hashing like in ZRLE?
- std::map<PIXEL_T,short> m_counts;
+ TightPalette m_pal;
};
HEXTILE_TILE::HEXTILE_TILE()
@@ -137,6 +136,8 @@
m_width = w;
m_height = h;
+ // NOTE: These two methods should always be called from this place
+ // only, and exactly in this order.
buildTables();
computeSize();
}
@@ -147,7 +148,7 @@
m_numSubrects = 0;
memset(m_processed, 0, 16 * 16 * sizeof(bool));
- m_counts.clear();
+ m_pal.reset();
int x, y, sx, sy, sw, sh, max_x;
PIXEL_T color;
@@ -181,7 +182,9 @@
*colorsPtr++ = color;
*coordsPtr++ = (rdr::U8)((x << 4) | (y & 0x0F));
*coordsPtr++ = (rdr::U8)(((sw - 1) << 4) | ((sh - 1) & 0x0F));
- m_counts[color] += 1;
+
+ if (m_pal.insert(color, 1, BPP) == 0)
+ return; // palette overflow
m_numSubrects++;
@@ -200,7 +203,7 @@
void HEXTILE_TILE::computeSize()
{
// Save the number of colors
- int numColors = m_counts.size();
+ int numColors = m_pal.getNumColors();
// Handle solid tile
if (numColors == 1) {
@@ -210,39 +213,28 @@
return;
}
- std::map<PIXEL_T,short>::iterator i;
-
// Handle monochrome tile - choose background and foreground
if (numColors == 2) {
- i = m_counts.begin();
- m_background = i->first;
- int bgCount = i->second;
- i++;
- if (i->second <= bgCount) {
- m_foreground = i->first;
- } else {
- m_foreground = m_background;
- m_background = i->first;
- bgCount = i->second;;
- }
+ int bgCount = m_pal.getCount(0);
+ m_background = (PIXEL_T)m_pal.getEntry(0);
+ m_foreground = (PIXEL_T)m_pal.getEntry(1);
m_flags = hextileAnySubrects;
m_size = 1 + 2 * (m_numSubrects - bgCount);
return;
}
- // Handle colored tile - choose the best background color
- int bgCount = 0, count;
- PIXEL_T color;
- for (i = m_counts.begin(); i != m_counts.end(); i++) {
- color = i->first;
- count = i->second;
- if (count > bgCount) {
- bgCount = count;
- m_background = color;
- }
+ // Handle raw-encoded tile (there was palette overflow)
+ if (numColors == 0) {
+ m_flags = hextileRaw;
+ m_size = 0;
+ return;
}
+ // Handle colored tile - choose the best background color
+ int bgCount = m_pal.getCount(0);
+ m_background = (PIXEL_T)m_pal.getEntry(0);
+
m_flags = hextileAnySubrects | hextileSubrectsColoured;
m_size = 1 + (2 + (BPP/8)) * (m_numSubrects - bgCount);
}
@@ -311,16 +303,17 @@
GET_IMAGE_INTO_BUF(t,buf);
tile.newTile(buf, t.width(), t.height());
+ int tileType = tile.getFlags();
int encodedLen = tile.getSize();
- if (encodedLen >= t.width() * t.height() * (BPP/8)) {
+ if ( (tileType & hextileRaw) != 0 ||
+ encodedLen >= t.width() * t.height() * (BPP/8)) {
os->writeU8(hextileRaw);
os->writeBytes(buf, t.width() * t.height() * (BPP/8));
oldBgValid = oldFgValid = false;
continue;
}
- int tileType = tile.getFlags();
PIXEL_T bg = tile.getBackground();
PIXEL_T fg = 0;