/* 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 implementation. // #include using namespace rfb; TightPalette::TightPalette(int maxColors) { setMaxColors(maxColors); reset(); } void TightPalette::reset() { m_numColors = 0; memset(m_hash, 0, 256 * sizeof(TightColorList *)); } void TightPalette::setMaxColors(int maxColors) { m_maxColors = maxColors; if (m_maxColors < 0) { m_maxColors = 0; } else if (m_maxColors > 254) { m_maxColors = 254; } } int TightPalette::insert(rdr::U32 rgb, int numPixels) { TightColorList *pnode; TightColorList *prev_pnode = NULL; int hash_key, idx, new_idx, count; hash_key = hashFunc(rgb); pnode = m_hash[hash_key]; while (pnode != NULL) { if (pnode->rgb == rgb) { // Such palette entry already exists. new_idx = idx = pnode->idx; count = m_entry[idx].numPixels + numPixels; if (new_idx && m_entry[new_idx-1].numPixels < count) { do { m_entry[new_idx] = m_entry[new_idx-1]; m_entry[new_idx].listNode->idx = new_idx; new_idx--; } while (new_idx && m_entry[new_idx-1].numPixels < count); m_entry[new_idx].listNode = pnode; pnode->idx = new_idx; } m_entry[new_idx].numPixels = count; return m_numColors; } prev_pnode = pnode; pnode = pnode->next; } // Check if the palette is full. if (m_numColors == 256 || m_numColors == m_maxColors) { m_numColors = 0; return 0; } // Move palette entries with lesser pixel counts. for ( idx = m_numColors; idx > 0 && m_entry[idx-1].numPixels < numPixels; idx-- ) { m_entry[idx] = m_entry[idx-1]; m_entry[idx].listNode->idx = idx; } // Add new palette entry into the freed slot. pnode = &m_list[m_numColors]; if (prev_pnode != NULL) { prev_pnode->next = pnode; } else { m_hash[hash_key] = pnode; } pnode->next = NULL; pnode->idx = idx; pnode->rgb = rgb; m_entry[idx].listNode = pnode; m_entry[idx].numPixels = numPixels; return ++m_numColors; }