xref: /plan9/sys/src/cmd/gs/src/gdev8bcm.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1994 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gdev8bcm.c,v 1.4 2002/02/21 22:24:51 giles Exp $ */
18 /* Dynamic color mapping for 8-bit displays */
19 #include "gx.h"
20 #include "gxdevice.h"
21 #include "gdev8bcm.h"
22 
23 /* Initialize an 8-bit color map. */
24 void
gx_8bit_map_init(gx_8bit_color_map * pcm,int max_count)25 gx_8bit_map_init(gx_8bit_color_map * pcm, int max_count)
26 {
27     int i;
28 
29     pcm->count = 0;
30     pcm->max_count = max_count;
31     for (i = 0; i < gx_8bit_map_size; i++)
32 	pcm->map[i].rgb = gx_8bit_no_rgb;
33 }
34 
35 /* Look up a color in an 8-bit color map. */
36 /* Return <0 if not found. */
37 int
gx_8bit_map_rgb_color(const gx_8bit_color_map * pcm,gx_color_value r,gx_color_value g,gx_color_value b)38 gx_8bit_map_rgb_color(const gx_8bit_color_map * pcm, gx_color_value r,
39 		      gx_color_value g, gx_color_value b)
40 {
41     ushort rgb = gx_8bit_rgb_key(r, g, b);
42     const gx_8bit_map_entry *pme =
43     &pcm->map[(rgb * gx_8bit_map_spreader) % gx_8bit_map_size];
44 
45     for (;; pme++) {
46 	if (pme->rgb == rgb)
47 	    return pme->index;
48 	else if (pme->rgb == gx_8bit_no_rgb)
49 	    break;
50     }
51     if (pme != &pcm->map[gx_8bit_map_size])
52 	return pme - &pcm->map[gx_8bit_map_size];
53     /* We ran off the end; wrap around and continue. */
54     pme = &pcm->map[0];
55     for (;; pme++) {
56 	if (pme->rgb == rgb)
57 	    return pme->index;
58 	else if (pme->rgb == gx_8bit_no_rgb)
59 	    return pme - &pcm->map[gx_8bit_map_size];
60     }
61 }
62 
63 /* Add a color to an 8-bit color map after an unsuccessful lookup, */
64 /* and return its index.  Return <0 if the map is full. */
65 int
gx_8bit_add_rgb_color(gx_8bit_color_map * pcm,gx_color_value r,gx_color_value g,gx_color_value b)66 gx_8bit_add_rgb_color(gx_8bit_color_map * pcm, gx_color_value r,
67 		      gx_color_value g, gx_color_value b)
68 {
69     int index;
70     gx_8bit_map_entry *pme;
71 
72     if (gx_8bit_map_is_full(pcm))
73 	return -1;
74     index = gx_8bit_map_rgb_color(pcm, r, g, b);
75     if (index >= 0)		/* shouldn't happen */
76 	return index;
77     pme = &pcm->map[-index];
78     pme->rgb = gx_8bit_rgb_key(r, g, b);
79     return (pme->index = pcm->count++);
80 }
81