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