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