xref: /qemu/ui/vnc-palette.c (revision 72aefb76f9268bec6eeb60530fd523b60effe610)
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 
295136a052SCorentin Chary #include "vnc-palette.h"
305136a052SCorentin Chary 
315136a052SCorentin Chary static VncPaletteEntry *palette_find(const VncPalette *palette,
325136a052SCorentin Chary                                      uint32_t color, unsigned int hash)
335136a052SCorentin Chary {
345136a052SCorentin Chary     VncPaletteEntry *entry;
355136a052SCorentin Chary 
365136a052SCorentin Chary     QLIST_FOREACH(entry, &palette->table[hash], next) {
375136a052SCorentin Chary         if (entry->color == color) {
385136a052SCorentin Chary             return entry;
395136a052SCorentin Chary         }
405136a052SCorentin Chary     }
415136a052SCorentin Chary 
425136a052SCorentin Chary     return NULL;
435136a052SCorentin Chary }
445136a052SCorentin Chary 
455136a052SCorentin Chary static unsigned int palette_hash(uint32_t rgb, int bpp)
465136a052SCorentin Chary {
475136a052SCorentin Chary     if (bpp == 16) {
485136a052SCorentin Chary         return ((unsigned int)(((rgb >> 8) + rgb) & 0xFF));
495136a052SCorentin Chary     } else {
505136a052SCorentin Chary         return ((unsigned int)(((rgb >> 16) + (rgb >> 8)) & 0xFF));
515136a052SCorentin Chary     }
525136a052SCorentin Chary }
535136a052SCorentin Chary 
545136a052SCorentin Chary VncPalette *palette_new(size_t max, int bpp)
555136a052SCorentin Chary {
565136a052SCorentin Chary     VncPalette *palette;
575136a052SCorentin Chary 
585136a052SCorentin Chary     palette = qemu_mallocz(sizeof(*palette));
59*72aefb76SCorentin Chary     palette_init(palette, max, bpp);
60*72aefb76SCorentin Chary     return palette;
61*72aefb76SCorentin Chary }
62*72aefb76SCorentin Chary 
63*72aefb76SCorentin Chary void palette_init(VncPalette *palette, size_t max, int bpp)
64*72aefb76SCorentin Chary {
65*72aefb76SCorentin Chary     memset(palette, 0, sizeof (*palette));
665136a052SCorentin Chary     palette->max = max;
675136a052SCorentin Chary     palette->bpp = bpp;
685136a052SCorentin Chary }
695136a052SCorentin Chary 
705136a052SCorentin Chary void palette_destroy(VncPalette *palette)
715136a052SCorentin Chary {
725136a052SCorentin Chary     if (palette == NULL) {
735136a052SCorentin Chary         qemu_free(palette);
745136a052SCorentin Chary     }
75e31e3694SCorentin Chary }
765136a052SCorentin Chary 
775136a052SCorentin Chary int palette_put(VncPalette *palette, uint32_t color)
785136a052SCorentin Chary {
795136a052SCorentin Chary     unsigned int hash;
805136a052SCorentin Chary     unsigned int idx = palette->size;
815136a052SCorentin Chary     VncPaletteEntry *entry;
825136a052SCorentin Chary 
835136a052SCorentin Chary     hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
845136a052SCorentin Chary     entry = palette_find(palette, color, hash);
855136a052SCorentin Chary 
865136a052SCorentin Chary     if (!entry && palette->size >= palette->max) {
875136a052SCorentin Chary         return 0;
885136a052SCorentin Chary     }
895136a052SCorentin Chary     if (!entry) {
905136a052SCorentin Chary         VncPaletteEntry *entry;
915136a052SCorentin Chary 
92e31e3694SCorentin Chary         entry = &palette->pool[palette->size];
935136a052SCorentin Chary         entry->color = color;
945136a052SCorentin Chary         entry->idx = idx;
955136a052SCorentin Chary         QLIST_INSERT_HEAD(&palette->table[hash], entry, next);
965136a052SCorentin Chary         palette->size++;
975136a052SCorentin Chary     }
985136a052SCorentin Chary     return palette->size;
995136a052SCorentin Chary }
1005136a052SCorentin Chary 
1015136a052SCorentin Chary int palette_idx(const VncPalette *palette, uint32_t color)
1025136a052SCorentin Chary {
1035136a052SCorentin Chary     VncPaletteEntry *entry;
1045136a052SCorentin Chary     unsigned int hash;
1055136a052SCorentin Chary 
1065136a052SCorentin Chary     hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
1075136a052SCorentin Chary     entry = palette_find(palette, color, hash);
1085136a052SCorentin Chary     return (entry == NULL ? -1 : entry->idx);
1095136a052SCorentin Chary }
1105136a052SCorentin Chary 
1115136a052SCorentin Chary size_t palette_size(const VncPalette *palette)
1125136a052SCorentin Chary {
1135136a052SCorentin Chary     return palette->size;
1145136a052SCorentin Chary }
1155136a052SCorentin Chary 
1165136a052SCorentin Chary void palette_iter(const VncPalette *palette,
1175136a052SCorentin Chary                   void (*iter)(int idx, uint32_t color, void *opaque),
1185136a052SCorentin Chary                   void *opaque)
1195136a052SCorentin Chary {
1205136a052SCorentin Chary     int i;
1215136a052SCorentin Chary     VncPaletteEntry *entry;
1225136a052SCorentin Chary 
1235136a052SCorentin Chary     for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) {
1245136a052SCorentin Chary         QLIST_FOREACH(entry, &palette->table[i], next) {
1255136a052SCorentin Chary             iter(entry->idx, entry->color, opaque);
1265136a052SCorentin Chary         }
1275136a052SCorentin Chary     }
1285136a052SCorentin Chary }
129