blob: 2f6448ea66cb4fd8f87f582386808aed1e980584 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2000-2005 Constantin Kaplinsky. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19//
20// TightPalette class is a container for ordered color values. Colors
21// are keys in a hash where values are frequency counts. Also, there
22// is a list where colors are always sorted by these counts (more
23// frequent first).
24//
25
26#ifndef __RFB_TIGHTPALETTE_H__
27#define __RFB_TIGHTPALETTE_H__
28
29#include <string.h>
30#include <rdr/types.h>
31
32namespace rfb {
33
34 struct TightColorList {
35 TightColorList *next;
36 int idx;
37 rdr::U32 rgb;
38 };
39
40 struct TightPaletteEntry {
41 TightColorList *listNode;
42 int numPixels;
43 };
44
45 class TightPalette {
46
47 protected:
48
49 // FIXME: Bigger hash table? Better hash function?
50 inline static int hashFunc(rdr::U32 rgb) {
51 return (rgb ^ (rgb >> 13)) & 0xFF;
52 }
53
54 public:
55
56 TightPalette(int maxColors = 254);
57
58 //
59 // Re-initialize the object. This does not change maximum number
60 // of colors.
61 //
62 void reset();
63
64 //
65 // Set limit on the number of colors in the palette. Note that
66 // this value cannot exceed 254.
67 //
68 void setMaxColors(int maxColors);
69
70 //
71 // Insert new color into the palette, or increment its counter if
72 // the color is already there. Returns new number of colors, or
73 // zero if the palette is full. If the palette becomes full, it
74 // reports zero colors and cannot be used any more without calling
75 // reset().
76 //
77 int insert(rdr::U32 rgb, int numPixels);
78
79 //
80 // Return number of colors in the palette.
81 //
82 inline int getNumColors() const {
83 return m_numColors;
84 }
85
86 //
87 // Return the color specified by its index in the palette.
88 //
89 inline rdr::U32 getEntry(int i) const {
90 return (i < m_numColors) ? m_entry[i].listNode->rgb : (rdr::U32)-1;
91 }
92
93 //
94 // Return the pixel counter of the color specified by its index.
95 //
96 inline int getCount(int i) const {
97 return (i < m_numColors) ? m_entry[i].numPixels : 0;
98 }
99
100 //
101 // Return the index of a specified color.
102 //
103 inline rdr::U8 getIndex(rdr::U32 rgb) const {
104 TightColorList *pnode = m_hash[hashFunc(rgb)];
105 while (pnode != NULL) {
106 if (pnode->rgb == rgb) {
107 return (rdr::U8)pnode->idx;
108 }
109 pnode = pnode->next;
110 }
111 return 0xFF; // no such color
112 }
113
114 protected:
115
116 int m_maxColors;
117 int m_numColors;
118
119 TightPaletteEntry m_entry[256];
120 TightColorList *m_hash[256];
121 TightColorList m_list[256];
122
123 };
124
125} // namespace rfb
126
127#endif // __RFB_TIGHTPALETTE_H__