1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/*$Id: gxdevndi.c 8250 2007-09-25 13:31:24Z giles $ */
27
* Binary halftoning algorithms.
29
* The procedures in this file use halftoning (if necessary)
30
* to implement a given device color that has already gone through
31
* the transfer function. There are two major cases: gray and color.
32
* Gray halftoning always uses a binary screen. Color halftoning
33
* uses either a fast algorithm with a binary screen that produces
34
* relatively poor approximations, or a very slow algorithm with a
35
* general colored screen (or screens) that faithfully implements
36
* the Adobe specifications.
39
/* Tables for fast computation of fractional color levels. */
40
/* We have to put the table before any uses of it because of a bug */
41
/* in the VAX C compiler. */
42
/* We have to split up the definition of the table itself because of a bug */
43
/* in the IBM AIX 3.2 C compiler. */
44
static const gx_color_value q0[] = {
47
static const gx_color_value q1[] = {
50
static const gx_color_value q2[] = {
51
0, frac_color_(1, 2), frac_color_(2, 2)
53
static const gx_color_value q3[] = {
54
0, frac_color_(1, 3), frac_color_(2, 3), frac_color_(3, 3)
56
static const gx_color_value q4[] = {
57
0, frac_color_(1, 4), frac_color_(2, 4), frac_color_(3, 4),
60
static const gx_color_value q5[] = {
61
0, frac_color_(1, 5), frac_color_(2, 5), frac_color_(3, 5),
62
frac_color_(4, 5), frac_color_(5, 5)
64
static const gx_color_value q6[] = {
65
0, frac_color_(1, 6), frac_color_(2, 6), frac_color_(3, 6),
66
frac_color_(4, 6), frac_color_(5, 6), frac_color_(6, 6)
68
static const gx_color_value q7[] = {
69
0, frac_color_(1, 7), frac_color_(2, 7), frac_color_(3, 7),
70
frac_color_(4, 7), frac_color_(5, 7), frac_color_(6, 7), frac_color_(7, 7)
73
/* We export fc_color_quo for the fractional_color macro in gzht.h. */
74
const gx_color_value *const fc_color_quo[8] = {
75
q0, q1, q2, q3, q4, q5, q6, q7
78
/* Begin code for setting up WTS device color. This should probably
79
move into its own module. */
82
* gx_render_device_DevN_wts: Render DeviceN color by halftoning with WTS.
84
* This routine is the primary constructor for WTS device colors.
85
* Note that, in the WTS code path, we sample the plane_vector array
86
* during device color construction, while in the legacy code path,
87
* it is sampled in the set_ht_colors procedure, invoked from
88
* fill_rectangle. Does it affect correctness? I don't think so, but
89
* it needs to be tested.
92
gx_render_device_DeviceN_wts(frac * pcolor,
93
gx_device_color * pdevc, gx_device * dev,
94
gx_device_halftone * pdht,
95
const gs_int_point * ht_phase)
98
gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
99
int num_comp = pdht->num_comp;
101
for (i = 0; i < num_comp; i++) {
105
pdevc->type = gx_dc_type_wts;
106
pdevc->colors.wts.w_ht = pdht;
108
if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN) {
109
/* Monochrome case may be inverted. */
110
pdevc->colors.wts.plane_vector[1] =
111
dev_proc(dev, encode_color)(dev, cv);
113
for (i = 0; i < num_comp; i++) {
114
pdevc->colors.wts.levels[i] = pcolor[i];
115
cv[i] = gx_max_color_value;
116
pdevc->colors.wts.plane_vector[i] =
117
dev_proc(dev, encode_color)(dev, cv);
120
pdevc->colors.wts.num_components = num_comp;
121
pdevc->phase = *ht_phase;
126
* Render DeviceN possibly by halftoning.
127
* pcolors = pointer to an array color values (as fracs)
128
* pdevc - pointer to device color structure
129
* dev = pointer to device data structure
130
* pht = pointer to halftone data structure
131
* ht_phase = halftone phase
132
* gray_colorspace = true -> current color space is DeviceGray.
133
* This is part of a kludge to minimize differences in the
134
* regression testing.
137
gx_render_device_DeviceN(frac * pcolor,
138
gx_device_color * pdevc, gx_device * dev,
139
gx_device_halftone * pdht, const gs_int_point * ht_phase)
141
uint max_value[GS_CLIENT_COLOR_MAX_COMPONENTS];
142
frac dither_check = 0;
143
uint int_color[GS_CLIENT_COLOR_MAX_COMPONENTS];
144
gx_color_value vcolor[GS_CLIENT_COLOR_MAX_COMPONENTS];
146
int num_colors = dev->color_info.num_components;
147
uint l_color[GS_CLIENT_COLOR_MAX_COMPONENTS];
149
if (pdht && pdht->components && pdht->components[0].corder.wts)
150
return gx_render_device_DeviceN_wts(pcolor, pdevc, dev, pdht,
153
for (i=0; i<num_colors; i++) {
154
max_value[i] = (dev->color_info.gray_index == i) ?
155
dev->color_info.dither_grays - 1 :
156
dev->color_info.dither_colors - 1;
159
for (i = 0; i < num_colors; i++) {
160
unsigned long hsize = pdht ?
161
(unsigned) pdht->components[i].corder.num_levels
163
unsigned long nshades = hsize * max_value[i] + 1;
164
long shade = pcolor[i] * nshades / (frac_1_long + 1);
165
int_color[i] = shade / hsize;
166
l_color[i] = shade % hsize;
167
if (max_value[i] < MIN_CONTONE_LEVELS)
168
dither_check |= l_color[i];
172
if (gs_debug_c('c')) {
173
dlprintf1("[c]ncomp=%d ", num_colors);
174
for (i = 0; i < num_colors; i++)
175
dlprintf1("0x%x, ", pcolor[i]);
177
for (i = 0; i < num_colors; i++)
178
dlprintf2("%x+0x%x, ", int_color[i], l_color[i]);
183
/* Check for no dithering required */
185
for (i = 0; i < num_colors; i++)
186
vcolor[i] = fractional_color(int_color[i], max_value[i]);
187
color_set_pure(pdevc, dev_proc(dev, encode_color)(dev, vcolor));
191
/* Use the slow, general colored halftone algorithm. */
193
for (i = 0; i < num_colors; i++)
194
_color_set_c(pdevc, i, int_color[i], l_color[i]);
195
gx_complete_halftone(pdevc, num_colors, pdht);
197
color_set_phase_mod(pdevc, ht_phase->x, ht_phase->y,
198
pdht->lcm_width, pdht->lcm_height);
200
/* Determine if we are using only one component */
201
if (!(pdevc->colors.colored.plane_mask &
202
(pdevc->colors.colored.plane_mask - 1))) {
203
/* We can reduce this color to a binary halftone or pure color. */
204
return gx_devn_reduce_colored_halftone(pdevc, dev);
210
/* Reduce a colored halftone to a binary halftone or pure color. */
211
/* This routine is called when only one component is being halftoned. */
213
gx_devn_reduce_colored_halftone(gx_device_color *pdevc, gx_device *dev)
215
int planes = pdevc->colors.colored.plane_mask;
216
int num_colors = dev->color_info.num_components;
217
uint max_value[GS_CLIENT_COLOR_MAX_COMPONENTS];
218
uint b[GX_DEVICE_COLOR_MAX_COMPONENTS];
219
gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS];
220
gx_color_index c0, c1;
223
for (i = 0; i < num_colors; i++) {
224
max_value[i] = (dev->color_info.gray_index == i) ?
225
dev->color_info.dither_grays - 1 :
226
dev->color_info.dither_colors - 1;
227
b[i] = pdevc->colors.colored.c_base[i];
228
v[i] = fractional_color(b[i], max_value[i]);
230
c0 = dev_proc(dev, encode_color)(dev, v);
234
* Use a pure color. This case is unlikely, but it can occur if
235
* (and only if) the difference of each component from the nearest
236
* device color is less than one halftone level.
238
color_set_pure(pdevc, c0);
241
/* Use a binary color. */
244
const gx_device_halftone *pdht = pdevc->colors.colored.c_ht;
246
* NB: the halftone orders are all set up for an additive color
247
* space. To use these work with a subtractive color space, it is
248
* necessary to invert both the color level and the color
249
* pair. Note that if the original color was provided an
250
* additive space, this will reverse (in an approximate sense)
251
* the color conversion performed to express the color in
254
bool invert = dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE;
257
/* Convert plane mask bit position to component number */
258
/* Determine i = log2(planes); This works for powers of two */
263
i += planes >> 1; /* log2 for 1,2,4 */
266
v[i] = fractional_color(bi, max_value[i]);
267
level = pdevc->colors.colored.c_level[i];
268
c1 = dev_proc(dev, encode_color)(dev, v);
270
level = pdht->components[i].corder.num_levels - level;
271
color_set_binary_halftone_component(pdevc, pdht, i, c1, c0, level);
273
color_set_binary_halftone_component(pdevc, pdht, i, c0, c1, level);