xref: /plan9/sys/src/cmd/gs/src/gdevpccm.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1992, 1993, 1998 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: gdevpccm.c,v 1.7 2004/09/20 22:14:59 dan Exp $ */
18 /* Support routines for PC color mapping */
19 #include "gx.h"
20 #include "gsmatrix.h"		/* for gxdevice.h */
21 #include "gxdevice.h"
22 #include "gdevpccm.h"		/* interface */
23 
24 /* Color mapping routines for EGA/VGA-style color. */
25 
26 /* ------ EGA/VGA (4-bit) color mapping ------ */
27 
28 /*
29  * Colors are 4 bits: 8=intensity (always set except black), 4=R, 2=G, 1=B.
30  * Note: We only use eight colors.  The halftoning logic requires that we
31  * have the same number for shades for each component.
32  */
33 gx_color_index
pc_4bit_map_rgb_color(gx_device * dev,const gx_color_value cv[])34 pc_4bit_map_rgb_color(gx_device * dev, const gx_color_value cv[])
35 {
36     gx_color_index r, g, color;
37 
38     r = (cv[0] > (gx_max_color_value/2));
39     g = (cv[1] > (gx_max_color_value/2));
40     color = (cv[2] > (gx_max_color_value/2));
41     color += (r << 2) + (g << 1);
42     if (color > 0)		/* If the color is not black */
43 	color += 8;		/* Turn on intensity bit */
44     return color;
45 }
46 
47 int
pc_4bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])48 pc_4bit_map_color_rgb(gx_device * dev, gx_color_index color,
49 		      gx_color_value prgb[3])
50 {
51 #define icolor (int)color
52     prgb[0] = (icolor & 4 ? gx_max_color_value : 0);
53     prgb[1] = (icolor & 2 ? gx_max_color_value : 0);
54     prgb[2] = (icolor & 1 ? gx_max_color_value : 0);
55     return 0;
56 #undef icolor
57 }
58 
59 /* ------ SVGA 8-bit color mapping ------ */
60 /*
61  * For 8-bit color, we use a 6x6x6 "cube".  This only provides 216
62  * different colors.  The halftoning logic assumes that we have the same
63  * number of shades of each color.  Thus asymetric cubes like 8x8x4 or
64  * 7x7x5 do not work properly.
65  */
66 
67 gx_color_index
pc_8bit_map_rgb_color(gx_device * dev,const gx_color_value cv[])68 pc_8bit_map_rgb_color(gx_device * dev, const gx_color_value cv[])
69 {
70     gx_color_value r, g, b;
71     uint rv, gv;
72     r = cv[0]; g = cv[1]; b = cv[2];
73     rv = r / (gx_max_color_value / 6 + 1);
74     gv = g / (gx_max_color_value / 6 + 1);
75 
76     return (gx_color_index)
77 	 (rv * 6 + gv) * 6 + b / (gx_max_color_value / 6 + 1);
78 }
79 int
pc_8bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])80 pc_8bit_map_color_rgb(gx_device * dev, gx_color_index color,
81 		      gx_color_value prgb[3])
82 {
83     static const gx_color_value ramp6[6] =
84     {0,
85      gx_max_color_value / 5,
86      2 * gx_max_color_value / 5,
87      3 * gx_max_color_value / 5,
88      gx_max_color_value - (gx_max_color_value / 5),
89      gx_max_color_value
90     };
91 
92 #define icolor (uint)color
93     if (icolor >= 216) {
94 	prgb[0] = prgb[1] = prgb[2] = 0;
95     } else {
96 	prgb[0] = ramp6[icolor / 36];
97 	prgb[1] = ramp6[(icolor / 6) % 6];
98 	prgb[2] = ramp6[icolor % 6];
99     }
100 #undef icolor
101     return 0;
102 }
103 
104 /* Write a palette on a file. */
105 int
pc_write_palette(gx_device * dev,uint max_index,FILE * file)106 pc_write_palette(gx_device * dev, uint max_index, FILE * file)
107 {
108     uint i, c;
109     gx_color_value rgb[3];
110 
111     for (i = 0; i < max_index; i++) {
112 	(*dev_proc(dev, map_color_rgb)) (dev, (gx_color_index) i, rgb);
113 	for (c = 0; c < 3; c++) {
114 	    byte b = rgb[c] >> (gx_color_value_bits - 8);
115 
116 	    fputc(b, file);
117 	}
118     }
119     return 0;
120 }
121