1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 /* $Id: gdev8bcm.c 8022 2007-06-05 22:23:38Z giles $ */
14 /* Dynamic color mapping for 8-bit displays */
15 #include "gx.h"
16 #include "gxdevice.h"
17 #include "gdev8bcm.h"
18
19 /* Initialize an 8-bit color map. */
20 void
gx_8bit_map_init(gx_8bit_color_map * pcm,int max_count)21 gx_8bit_map_init(gx_8bit_color_map * pcm, int max_count)
22 {
23 int i;
24
25 pcm->count = 0;
26 pcm->max_count = max_count;
27 for (i = 0; i < gx_8bit_map_size; i++)
28 pcm->map[i].rgb = gx_8bit_no_rgb;
29 }
30
31 /* Look up a color in an 8-bit color map. */
32 /* Return <0 if not found. */
33 int
gx_8bit_map_rgb_color(const gx_8bit_color_map * pcm,gx_color_value r,gx_color_value g,gx_color_value b)34 gx_8bit_map_rgb_color(const gx_8bit_color_map * pcm, gx_color_value r,
35 gx_color_value g, gx_color_value b)
36 {
37 ushort rgb = gx_8bit_rgb_key(r, g, b);
38 const gx_8bit_map_entry *pme =
39 &pcm->map[(rgb * gx_8bit_map_spreader) % gx_8bit_map_size];
40
41 for (;; pme++) {
42 if (pme->rgb == rgb)
43 return pme->index;
44 else if (pme->rgb == gx_8bit_no_rgb)
45 break;
46 }
47 if (pme != &pcm->map[gx_8bit_map_size])
48 return pme - &pcm->map[gx_8bit_map_size];
49 /* We ran off the end; wrap around and continue. */
50 pme = &pcm->map[0];
51 for (;; pme++) {
52 if (pme->rgb == rgb)
53 return pme->index;
54 else if (pme->rgb == gx_8bit_no_rgb)
55 return pme - &pcm->map[gx_8bit_map_size];
56 }
57 }
58
59 /* Add a color to an 8-bit color map after an unsuccessful lookup, */
60 /* and return its index. Return <0 if the map is full. */
61 int
gx_8bit_add_rgb_color(gx_8bit_color_map * pcm,gx_color_value r,gx_color_value g,gx_color_value b)62 gx_8bit_add_rgb_color(gx_8bit_color_map * pcm, gx_color_value r,
63 gx_color_value g, gx_color_value b)
64 {
65 int index;
66 gx_8bit_map_entry *pme;
67
68 if (gx_8bit_map_is_full(pcm))
69 return -1;
70 index = gx_8bit_map_rgb_color(pcm, r, g, b);
71 if (index >= 0) /* shouldn't happen */
72 return index;
73 pme = &pcm->map[-index];
74 pme->rgb = gx_8bit_rgb_key(r, g, b);
75 return (pme->index = pcm->count++);
76 }
77