/* Copyright (C) 2000-2005 Constantin Kaplinsky. All Rights Reserved. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ // // TightPalette class is a container for ordered color values. Colors // are keys in a hash where values are frequency counts. Also, there // is a list where colors are always sorted by these counts (more // frequent first). // #ifndef __RFB_TIGHTPALETTE_H__ #define __RFB_TIGHTPALETTE_H__ #include #include namespace rfb { struct TightColorList { TightColorList *next; int idx; rdr::U32 rgb; }; struct TightPaletteEntry { TightColorList *listNode; int numPixels; }; class TightPalette { protected: // FIXME: Bigger hash table? Better hash function? inline static int hashFunc(rdr::U32 rgb) { return (rgb ^ (rgb >> 13)) & 0xFF; } public: TightPalette(int maxColors = 254); // // Re-initialize the object. This does not change maximum number // of colors. // void reset(); // // Set limit on the number of colors in the palette. Note that // this value cannot exceed 254. // void setMaxColors(int maxColors); // // Insert new color into the palette, or increment its counter if // the color is already there. Returns new number of colors, or // zero if the palette is full. If the palette becomes full, it // reports zero colors and cannot be used any more without calling // reset(). // int insert(rdr::U32 rgb, int numPixels); // // Return number of colors in the palette. // inline int getNumColors() const { return m_numColors; } // // Return the color specified by its index in the palette. // inline rdr::U32 getEntry(int i) const { return (i < m_numColors) ? m_entry[i].listNode->rgb : (rdr::U32)-1; } // // Return the pixel counter of the color specified by its index. // inline int getCount(int i) const { return (i < m_numColors) ? m_entry[i].numPixels : 0; } // // Return the index of a specified color. // inline rdr::U8 getIndex(rdr::U32 rgb) const { TightColorList *pnode = m_hash[hashFunc(rgb)]; while (pnode != NULL) { if (pnode->rgb == rgb) { return (rdr::U8)pnode->idx; } pnode = pnode->next; } return 0xFF; // no such color } protected: int m_maxColors; int m_numColors; TightPaletteEntry m_entry[256]; TightColorList *m_hash[256]; TightColorList m_list[256]; }; } // namespace rfb #endif // __RFB_TIGHTPALETTE_H__