xref: /openbmc/qemu/ui/vnc-palette.c (revision e33e66b1)
15136a052SCorentin Chary /*
25136a052SCorentin Chary  * QEMU VNC display driver: palette hash table
35136a052SCorentin Chary  *
45136a052SCorentin Chary  * From libvncserver/libvncserver/tight.c
55136a052SCorentin Chary  * Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved.
65136a052SCorentin Chary  * Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
75136a052SCorentin Chary  *
85136a052SCorentin Chary  * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
95136a052SCorentin Chary  *
105136a052SCorentin Chary  * Permission is hereby granted, free of charge, to any person obtaining a copy
115136a052SCorentin Chary  * of this software and associated documentation files (the "Software"), to deal
125136a052SCorentin Chary  * in the Software without restriction, including without limitation the rights
135136a052SCorentin Chary  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
145136a052SCorentin Chary  * copies of the Software, and to permit persons to whom the Software is
155136a052SCorentin Chary  * furnished to do so, subject to the following conditions:
165136a052SCorentin Chary  *
175136a052SCorentin Chary  * The above copyright notice and this permission notice shall be included in
185136a052SCorentin Chary  * all copies or substantial portions of the Software.
195136a052SCorentin Chary  *
205136a052SCorentin Chary  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
215136a052SCorentin Chary  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
225136a052SCorentin Chary  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
235136a052SCorentin Chary  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
245136a052SCorentin Chary  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
255136a052SCorentin Chary  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
265136a052SCorentin Chary  * THE SOFTWARE.
275136a052SCorentin Chary  */
285136a052SCorentin Chary 
29*e16f4c87SPeter Maydell #include "qemu/osdep.h"
305136a052SCorentin Chary #include "vnc-palette.h"
315136a052SCorentin Chary 
palette_find(const VncPalette * palette,uint32_t color,unsigned int hash)325136a052SCorentin Chary static VncPaletteEntry *palette_find(const VncPalette *palette,
335136a052SCorentin Chary                                      uint32_t color, unsigned int hash)
345136a052SCorentin Chary {
355136a052SCorentin Chary     VncPaletteEntry *entry;
365136a052SCorentin Chary 
375136a052SCorentin Chary     QLIST_FOREACH(entry, &palette->table[hash], next) {
385136a052SCorentin Chary         if (entry->color == color) {
395136a052SCorentin Chary             return entry;
405136a052SCorentin Chary         }
415136a052SCorentin Chary     }
425136a052SCorentin Chary 
435136a052SCorentin Chary     return NULL;
445136a052SCorentin Chary }
455136a052SCorentin Chary 
palette_hash(uint32_t rgb,int bpp)465136a052SCorentin Chary static unsigned int palette_hash(uint32_t rgb, int bpp)
475136a052SCorentin Chary {
485136a052SCorentin Chary     if (bpp == 16) {
495136a052SCorentin Chary         return ((unsigned int)(((rgb >> 8) + rgb) & 0xFF));
505136a052SCorentin Chary     } else {
515136a052SCorentin Chary         return ((unsigned int)(((rgb >> 16) + (rgb >> 8)) & 0xFF));
525136a052SCorentin Chary     }
535136a052SCorentin Chary }
545136a052SCorentin Chary 
palette_new(size_t max,int bpp)555136a052SCorentin Chary VncPalette *palette_new(size_t max, int bpp)
565136a052SCorentin Chary {
575136a052SCorentin Chary     VncPalette *palette;
585136a052SCorentin Chary 
597267c094SAnthony Liguori     palette = g_malloc0(sizeof(*palette));
6072aefb76SCorentin Chary     palette_init(palette, max, bpp);
6172aefb76SCorentin Chary     return palette;
6272aefb76SCorentin Chary }
6372aefb76SCorentin Chary 
palette_init(VncPalette * palette,size_t max,int bpp)6472aefb76SCorentin Chary void palette_init(VncPalette *palette, size_t max, int bpp)
6572aefb76SCorentin Chary {
6672aefb76SCorentin Chary     memset(palette, 0, sizeof (*palette));
675136a052SCorentin Chary     palette->max = max;
685136a052SCorentin Chary     palette->bpp = bpp;
695136a052SCorentin Chary }
705136a052SCorentin Chary 
palette_destroy(VncPalette * palette)715136a052SCorentin Chary void palette_destroy(VncPalette *palette)
725136a052SCorentin Chary {
737267c094SAnthony Liguori     g_free(palette);
745136a052SCorentin Chary }
755136a052SCorentin Chary 
palette_put(VncPalette * palette,uint32_t color)765136a052SCorentin Chary int palette_put(VncPalette *palette, uint32_t color)
775136a052SCorentin Chary {
785136a052SCorentin Chary     unsigned int hash;
795136a052SCorentin Chary     unsigned int idx = palette->size;
805136a052SCorentin Chary     VncPaletteEntry *entry;
815136a052SCorentin Chary 
825136a052SCorentin Chary     hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
835136a052SCorentin Chary     entry = palette_find(palette, color, hash);
845136a052SCorentin Chary 
855136a052SCorentin Chary     if (!entry && palette->size >= palette->max) {
865136a052SCorentin Chary         return 0;
875136a052SCorentin Chary     }
885136a052SCorentin Chary     if (!entry) {
89e31e3694SCorentin Chary         entry = &palette->pool[palette->size];
905136a052SCorentin Chary         entry->color = color;
915136a052SCorentin Chary         entry->idx = idx;
925136a052SCorentin Chary         QLIST_INSERT_HEAD(&palette->table[hash], entry, next);
935136a052SCorentin Chary         palette->size++;
945136a052SCorentin Chary     }
955136a052SCorentin Chary     return palette->size;
965136a052SCorentin Chary }
975136a052SCorentin Chary 
palette_idx(const VncPalette * palette,uint32_t color)985136a052SCorentin Chary int palette_idx(const VncPalette *palette, uint32_t color)
995136a052SCorentin Chary {
1005136a052SCorentin Chary     VncPaletteEntry *entry;
1015136a052SCorentin Chary     unsigned int hash;
1025136a052SCorentin Chary 
1035136a052SCorentin Chary     hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
1045136a052SCorentin Chary     entry = palette_find(palette, color, hash);
1055136a052SCorentin Chary     return (entry == NULL ? -1 : entry->idx);
1065136a052SCorentin Chary }
1075136a052SCorentin Chary 
palette_size(const VncPalette * palette)1085136a052SCorentin Chary size_t palette_size(const VncPalette *palette)
1095136a052SCorentin Chary {
1105136a052SCorentin Chary     return palette->size;
1115136a052SCorentin Chary }
1125136a052SCorentin Chary 
palette_iter(const VncPalette * palette,void (* iter)(int idx,uint32_t color,void * opaque),void * opaque)1135136a052SCorentin Chary void palette_iter(const VncPalette *palette,
1145136a052SCorentin Chary                   void (*iter)(int idx, uint32_t color, void *opaque),
1155136a052SCorentin Chary                   void *opaque)
1165136a052SCorentin Chary {
1175136a052SCorentin Chary     int i;
1185136a052SCorentin Chary     VncPaletteEntry *entry;
1195136a052SCorentin Chary 
1205136a052SCorentin Chary     for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) {
1215136a052SCorentin Chary         QLIST_FOREACH(entry, &palette->table[i], next) {
1225136a052SCorentin Chary             iter(entry->idx, entry->color, opaque);
1235136a052SCorentin Chary         }
1245136a052SCorentin Chary     }
1255136a052SCorentin Chary }
126f8562e32SCorentin Chary 
palette_color(const VncPalette * palette,int idx,bool * found)127f8562e32SCorentin Chary uint32_t palette_color(const VncPalette *palette, int idx, bool *found)
128f8562e32SCorentin Chary {
129f8562e32SCorentin Chary     int i;
130f8562e32SCorentin Chary     VncPaletteEntry *entry;
131f8562e32SCorentin Chary 
132f8562e32SCorentin Chary     for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) {
133f8562e32SCorentin Chary         QLIST_FOREACH(entry, &palette->table[i], next) {
134f8562e32SCorentin Chary             if (entry->idx == idx) {
135f8562e32SCorentin Chary                 *found = true;
136f8562e32SCorentin Chary                 return entry->color;
137f8562e32SCorentin Chary             }
138f8562e32SCorentin Chary         }
139f8562e32SCorentin Chary     }
140f8562e32SCorentin Chary 
141f8562e32SCorentin Chary     *found = false;
142f8562e32SCorentin Chary     return -1;
143f8562e32SCorentin Chary }
144f8562e32SCorentin Chary 
palette_fill_cb(int idx,uint32_t color,void * opaque)145f8562e32SCorentin Chary static void palette_fill_cb(int idx, uint32_t color, void *opaque)
146f8562e32SCorentin Chary {
147f8562e32SCorentin Chary     uint32_t *colors = opaque;
148f8562e32SCorentin Chary 
149f8562e32SCorentin Chary     colors[idx] = color;
150f8562e32SCorentin Chary }
151f8562e32SCorentin Chary 
palette_fill(const VncPalette * palette,uint32_t colors[VNC_PALETTE_MAX_SIZE])152f8562e32SCorentin Chary size_t palette_fill(const VncPalette *palette,
153f8562e32SCorentin Chary                     uint32_t colors[VNC_PALETTE_MAX_SIZE])
154f8562e32SCorentin Chary {
155f8562e32SCorentin Chary     palette_iter(palette, palette_fill_cb, colors);
156f8562e32SCorentin Chary     return palette_size(palette);
157f8562e32SCorentin Chary }
158