2 * QEMU VNC display driver: palette hash table
4 * From libvncserver/libvncserver/tight.c
5 * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
6 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
8 * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 #include "vnc-palette.h"
33 static VncPaletteEntry
*palette_find(const VncPalette
*palette
,
34 uint32_t color
, unsigned int hash
)
36 VncPaletteEntry
*entry
;
38 QLIST_FOREACH(entry
, &palette
->table
[hash
], next
) {
39 if (entry
->color
== color
) {
47 static unsigned int palette_hash(uint32_t rgb
, int bpp
)
50 return ((unsigned int)(((rgb
>> 8) + rgb
) & 0xFF));
52 return ((unsigned int)(((rgb
>> 16) + (rgb
>> 8)) & 0xFF));
56 VncPalette
*palette_new(size_t max
, int bpp
)
60 palette
= g_malloc0(sizeof(*palette
));
61 palette_init(palette
, max
, bpp
);
65 void palette_init(VncPalette
*palette
, size_t max
, int bpp
)
67 memset(palette
, 0, sizeof (*palette
));
72 void palette_destroy(VncPalette
*palette
)
77 int palette_put(VncPalette
*palette
, uint32_t color
)
80 unsigned int idx
= palette
->size
;
81 VncPaletteEntry
*entry
;
83 hash
= palette_hash(color
, palette
->bpp
) % VNC_PALETTE_HASH_SIZE
;
84 entry
= palette_find(palette
, color
, hash
);
86 if (!entry
&& palette
->size
>= palette
->max
) {
90 VncPaletteEntry
*entry
;
92 entry
= &palette
->pool
[palette
->size
];
95 QLIST_INSERT_HEAD(&palette
->table
[hash
], entry
, next
);
101 int palette_idx(const VncPalette
*palette
, uint32_t color
)
103 VncPaletteEntry
*entry
;
106 hash
= palette_hash(color
, palette
->bpp
) % VNC_PALETTE_HASH_SIZE
;
107 entry
= palette_find(palette
, color
, hash
);
108 return (entry
== NULL
? -1 : entry
->idx
);
111 size_t palette_size(const VncPalette
*palette
)
113 return palette
->size
;
116 void palette_iter(const VncPalette
*palette
,
117 void (*iter
)(int idx
, uint32_t color
, void *opaque
),
121 VncPaletteEntry
*entry
;
123 for (i
= 0; i
< VNC_PALETTE_HASH_SIZE
; i
++) {
124 QLIST_FOREACH(entry
, &palette
->table
[i
], next
) {
125 iter(entry
->idx
, entry
->color
, opaque
);
130 uint32_t palette_color(const VncPalette
*palette
, int idx
, bool *found
)
133 VncPaletteEntry
*entry
;
135 for (i
= 0; i
< VNC_PALETTE_HASH_SIZE
; i
++) {
136 QLIST_FOREACH(entry
, &palette
->table
[i
], next
) {
137 if (entry
->idx
== idx
) {
148 static void palette_fill_cb(int idx
, uint32_t color
, void *opaque
)
150 uint32_t *colors
= opaque
;
155 size_t palette_fill(const VncPalette
*palette
,
156 uint32_t colors
[VNC_PALETTE_MAX_SIZE
])
158 palette_iter(palette
, palette_fill_cb
, colors
);
159 return palette_size(palette
);