2 |
- |
1 |
/*
|
|
|
2 |
Copyright (C) 1996-1998 <Uli Wortmann uliw@erdw.ethz.ch>
|
|
|
3 |
Portions Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
|
|
|
4 |
|
|
|
5 |
This program is free software; you can redistribute it and/or modify
|
|
|
6 |
it under the terms of the GNU General Public License as published by
|
|
|
7 |
the Free Software Foundation; either version 2 of the License, or
|
|
|
8 |
(at your option) any later version.
|
|
|
9 |
|
|
|
10 |
This program is distributed in the hope that it will be useful,
|
|
|
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
13 |
GNU General Public License for more details.
|
|
|
14 |
|
|
|
15 |
You should have received a copy of the GNU General Public License
|
|
|
16 |
along with this program; if not, write to the Free Software
|
|
|
17 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 U.S.A.
|
|
|
18 |
|
|
|
19 |
This program may also be distributed as part of Aladdin Ghostscript,
|
|
|
20 |
under the terms of the Aladdin Free Public License (the "License").
|
|
|
21 |
|
|
|
22 |
Every copy of Aladdin Ghostscript must include a copy of the
|
|
|
23 |
License, normally in a plain ASCII text file named PUBLIC. The
|
|
|
24 |
License grants you the right to copy, modify and redistribute
|
|
|
25 |
Aladdin Ghostscript, but only under certain conditions described in
|
|
|
26 |
the License. Among other things, the License requires that the
|
|
|
27 |
copyright notice and this notice be preserved on all copies.
|
|
|
28 |
*/
|
|
|
29 |
|
|
|
30 |
/*$Id: gdevcd8.c,v 1.1 2000/03/09 08:40:40 lpd Exp $*/
|
|
|
31 |
|
|
|
32 |
/*
|
|
|
33 |
A printer driver for the HP670, HP690, HP850, HP855
|
|
|
34 |
HP870, HP890, HP1100 and HP1600 color printers.
|
|
|
35 |
|
|
|
36 |
To be used with the Ghostscript printing system.
|
|
|
37 |
Please report all problems to uliw@erdw.ethz.ch
|
|
|
38 |
|
|
|
39 |
CREDITS: Much of the driver is based on ideas derived
|
|
|
40 |
from the cdj550 driver of George Cameron.
|
|
|
41 |
|
|
|
42 |
The support for the hp670, hp690, hp890
|
|
|
43 |
and hp1600 was added by Martin Gerbershagen.
|
|
|
44 |
*/
|
|
|
45 |
|
|
|
46 |
/* Note: Depending on how you transfered the files,
|
|
|
47 |
you might need to remove some CR-codes used on intel-based machines:
|
|
|
48 |
|
|
|
49 |
simply type: unzip -a hp850.zip
|
|
|
50 |
|
|
|
51 |
to compile with gs5.x, simply add
|
|
|
52 |
|
|
|
53 |
DEVICE_DEVS4=cdj850.dev cdj670.dev cdj890.dev cdj1600.dev
|
|
|
54 |
|
|
|
55 |
to your makefile.
|
|
|
56 |
|
|
|
57 |
BTW, it is always a good idea to read Make.htm found in the
|
|
|
58 |
gs-distrib before attempting to recompile.....
|
|
|
59 |
|
|
|
60 |
*/
|
|
|
61 |
|
|
|
62 |
/* 1999-01-07 edited by L. Peter Deutsch <ghost@aladdin.com> to eliminate
|
|
|
63 |
non-const statics and otherwise bring up to date with Ghostscript coding
|
|
|
64 |
style guidelines. */
|
|
|
65 |
|
|
|
66 |
/* 01.06.98 Version 1.3 Due to the most welcome contribution
|
|
|
67 |
of Martin Gerbershagen (ger@ulm.temic.de),
|
|
|
68 |
support for the hp670, hp690 and hp890
|
|
|
69 |
and hp1600 has been added. Martin has also
|
|
|
70 |
resolved all known bugs.
|
|
|
71 |
|
|
|
72 |
Problems : Dark colors are still pale.
|
|
|
73 |
|
|
|
74 |
|
|
|
75 |
The driver no longer needs special switches to be invoked
|
|
|
76 |
except -sDEVICE=cdj850, or -sDEVICE=CDJ890, or sDEVICE=CDJ670
|
|
|
77 |
or -sDEVICE=CDJ1600
|
|
|
78 |
|
|
|
79 |
The hp690 is supported through the hp670 device, the hp855, hp870
|
|
|
80 |
and the hp1100 through the hp850 device.
|
|
|
81 |
|
|
|
82 |
The driver implements the following switches:
|
|
|
83 |
|
|
|
84 |
-dPapertype= 0 plain paper [default]
|
|
|
85 |
1 bond paper
|
|
|
86 |
2 special paper
|
|
|
87 |
3 glossy film
|
|
|
88 |
4 transparency film
|
|
|
89 |
|
|
|
90 |
Note, currently the lookuptables are not suited
|
|
|
91 |
for printing on special paper or transperencies.
|
|
|
92 |
Please revert to the gamma functions in this case.
|
|
|
93 |
|
|
|
94 |
-dQuality= -1 draft
|
|
|
95 |
|
|
|
96 |
1 presentation
|
|
|
97 |
|
|
|
98 |
-dRetStatus= 0 C-RET off
|
|
|
99 |
1 C-RET on [default]
|
|
|
100 |
|
|
|
101 |
-dMasterGamma= 3.0 [default = 1.0]
|
|
|
102 |
__Note__: To take advantage of the calibrated color-transfer
|
|
|
103 |
functions, be sure not to have any Gamma-Statements
|
|
|
104 |
left! If you need to (i.e. overhead sheets),
|
|
|
105 |
you still can use the gamma-functions, but they will
|
|
|
106 |
override the built-in calibration. To use gamma in the
|
|
|
107 |
traditional way, set MasterGamma to any value greater
|
|
|
108 |
1.0 and less 10.0. To adjust individual gamma-values,
|
|
|
109 |
you have to additionally set MasterGamma to a value
|
|
|
110 |
greater 1.0 and less 10.0
|
|
|
111 |
|
|
|
112 |
With the next release, gamma functions will be dropped.
|
|
|
113 |
|
|
|
114 |
When using the driver, be aware that printing in 600dpi involves
|
|
|
115 |
processing of large amounts of data (> 188MB !). Therefore, the
|
|
|
116 |
driver is not what you would expect to be a fast driver ;-)
|
|
|
117 |
This is no problem when printing a full sized color page (because
|
|
|
118 |
printing itself is slow), but it's really annoying if yoy print only
|
|
|
119 |
text pages. Maybe I can optimize the code for text-only pages in a
|
|
|
120 |
later release. Right now, it is recommended to use the highest
|
|
|
121 |
possible optimisation level your compiler offers....
|
|
|
122 |
For the time beeing, use the cdj550 device with -sBitsPerPixel=3
|
|
|
123 |
for fast proof-prints. If you simply want to print 600dpi b/w data,
|
|
|
124 |
use the cdj550 device with -sBitsPerPixel=8 (or 1).
|
|
|
125 |
|
|
|
126 |
Since the printer itself is slow, it may help to set the
|
|
|
127 |
process-priority of the gs-process to regular or even less. On a
|
|
|
128 |
486/100MHZ this is still sufficient to maintain a continuos
|
|
|
129 |
data-flow.
|
|
|
130 |
Note to OS/2 users: Simply put the gs-window into the background,
|
|
|
131 |
or minimize it. Also make sure, that print01.sys is invoked without
|
|
|
132 |
the /irq switch (great speed improvement under warp4).
|
|
|
133 |
|
|
|
134 |
The printer default settings compensate for dot-gain by a
|
|
|
135 |
calibrated color-transfer function. If this appears to be to light
|
|
|
136 |
for your business-graphs, or for overhead-sheets, feel free to set
|
|
|
137 |
-dMasterGamma=1.7.
|
|
|
138 |
|
|
|
139 |
Furthermore, you may tweak the gammavalues independently by setting
|
|
|
140 |
-dGammaValC, -dGammaValM, -dGammaValY or -dGammaValK (if not set,
|
|
|
141 |
the values default to MasterGamma). This will only work, when
|
|
|
142 |
-dMasterGamma is set to a value greater than 1.0.
|
|
|
143 |
|
|
|
144 |
If you want to learn more about gamma, see:
|
|
|
145 |
|
|
|
146 |
http://www.erdw.ethz.ch/~bonk/ftp/misc/gammafaq.pdf
|
|
|
147 |
http://www.erdw.ethz.ch/~bonk/ftp/misc/colorfaq.pdf
|
|
|
148 |
|
|
|
149 |
Further information, bugs, tips etc, can be found
|
|
|
150 |
at my website.
|
|
|
151 |
|
|
|
152 |
Have fun!
|
|
|
153 |
|
|
|
154 |
Uli
|
|
|
155 |
|
|
|
156 |
uliw@erdw.ethz.ch
|
|
|
157 |
http://www.erdw.ethz.ch/~bonk/bonk.html
|
|
|
158 |
|
|
|
159 |
*/
|
|
|
160 |
|
|
|
161 |
/* 25.08.97 Version 1.2. Resolved all but one of the
|
|
|
162 |
known bugs, introduced a couple
|
|
|
163 |
of perfomance improvements. Complete
|
|
|
164 |
new color-transfer-function handling.
|
|
|
165 |
(see gamma). */
|
|
|
166 |
|
|
|
167 |
/* 04.05.97 Version 1.1. For added features, */
|
|
|
168 |
/* resolved bugs and so forth, please see */
|
|
|
169 |
/* http://bonk.ethz.ch */
|
|
|
170 |
|
|
|
171 |
/* 11.11.96. Initial release of the driver */
|
|
|
172 |
|
|
|
173 |
#include "math_.h"
|
|
|
174 |
#include <stdlib.h> /* for rand() */
|
|
|
175 |
#include <assert.h>
|
|
|
176 |
#include "gdevprn.h"
|
|
|
177 |
#include "gdevpcl.h"
|
|
|
178 |
#include "gsparam.h"
|
|
|
179 |
|
|
|
180 |
/* Conversion stuff. */
|
|
|
181 |
#include "gxlum.h"
|
|
|
182 |
|
|
|
183 |
#define P1(x) x
|
|
|
184 |
#define P2(x,y) x,y
|
|
|
185 |
#define P3(x,y,z) x,y,z
|
|
|
186 |
#define P4(x,y,z,a) x,y,z,a
|
|
|
187 |
#define P5(x,y,z,a,b) x,y,z,a,b
|
|
|
188 |
#define P6(x,y,z,a,b,c) x,y,z,a,b,c
|
|
|
189 |
#define P7(x,y,z,a,b,c,d) x,y,z,a,b,c,d
|
|
|
190 |
#define P8(x,y,z,a,b,c,d,e) x,y,z,a,b,c,d,e
|
|
|
191 |
#define P9(x,y,z,a,b,c,d,e,f) x,y,z,a,b,c,d,e,f
|
|
|
192 |
#define P10(x,y,z,a,b,c,d,e,f,g) x,y,z,a,b,c,d,e,f,g
|
|
|
193 |
#define P11(x,y,z,a,b,c,d,e,f,g,h) x,y,z,a,b,c,d,e,f,g,h
|
|
|
194 |
#define P12(x,y,z,a,b,c,d,e,f,g,h,i) x,y,z,a,b,c,d,e,f,g,h,i
|
|
|
195 |
|
|
|
196 |
/* this holds the initialisation data of the hp850 */
|
|
|
197 |
typedef struct hp850_cmyk_init_s {
|
|
|
198 |
byte a[26];
|
|
|
199 |
} hp850_cmyk_init_t;
|
|
|
200 |
private const hp850_cmyk_init_t hp850_cmyk_init =
|
|
|
201 |
{
|
|
|
202 |
{
|
|
|
203 |
0x02, /* format */
|
|
|
204 |
0x04, /* number of components */
|
|
|
205 |
/* black */
|
|
|
206 |
0x01, /* MSB x resolution */
|
|
|
207 |
0x2c, /* LSB x resolution */
|
|
|
208 |
0x01, /* MSB y resolution */
|
|
|
209 |
0x2c, /* LSB y resolution */
|
|
|
210 |
0x00, /* MSB intensity levels */
|
|
|
211 |
0x02, /* LSB intensity levels */
|
|
|
212 |
|
|
|
213 |
/* cyan */
|
|
|
214 |
0x01, /* MSB x resolution */
|
|
|
215 |
0x2c, /* LSB x resolution */
|
|
|
216 |
0x01, /* MSB y resolution */
|
|
|
217 |
0x2c, /* LSB y resolution */
|
|
|
218 |
0x00, /* MSB intensity levels */
|
|
|
219 |
0x02, /* LSB intensity levels */
|
|
|
220 |
|
|
|
221 |
/* magenta */
|
|
|
222 |
0x01, /* MSB x resolution */
|
|
|
223 |
0x2c, /* LSB x resolution */
|
|
|
224 |
0x01, /* MSB y resolution */
|
|
|
225 |
0x2c, /* LSB y resolution */
|
|
|
226 |
0x00, /* MSB intensity levels */
|
|
|
227 |
0x02, /* LSB intensity levels */
|
|
|
228 |
|
|
|
229 |
/* yellow */
|
|
|
230 |
0x01, /* MSB x resolution */
|
|
|
231 |
0x2c, /* LSB x resolution */
|
|
|
232 |
0x01, /* MSB y resolution */
|
|
|
233 |
0x2c, /* LSB y resolution */
|
|
|
234 |
0x00, /* MSB intensity levels */
|
|
|
235 |
0x02 /* LSB intensity levels */
|
|
|
236 |
}
|
|
|
237 |
};
|
|
|
238 |
|
|
|
239 |
/* this holds the color lookuptable data of the hp850 */
|
|
|
240 |
typedef struct {
|
|
|
241 |
byte c[256]; /* Lookuptable for cyan */
|
|
|
242 |
byte m[256]; /* dito for magenta */
|
|
|
243 |
byte y[256]; /* dito for yellow */
|
|
|
244 |
byte k[256]; /* dito for black */
|
|
|
245 |
int correct[256]; /* potential undercolor black correction */
|
|
|
246 |
} Gamma;
|
|
|
247 |
|
|
|
248 |
private const Gamma gammat850 =
|
|
|
249 |
{
|
|
|
250 |
/* Lookup values for cyan */
|
|
|
251 |
{0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
|
|
|
252 |
8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 12, 12, 12,
|
|
|
253 |
12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 16, 16, 17, 17,
|
|
|
254 |
17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 22,
|
|
|
255 |
22, 23, 23, 23, 23, 23, 24, 24, 25, 25, 26, 26, 26, 26, 26, 27, 27,
|
|
|
256 |
27, 27, 28, 28, 29, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 34,
|
|
|
257 |
35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 42,
|
|
|
258 |
43, 43, 43, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 51,
|
|
|
259 |
52, 52, 53, 54, 54, 54, 55, 55, 56, 57, 58, 58, 59, 60, 60, 61, 62,
|
|
|
260 |
62, 63, 65, 65, 66, 67, 67, 68, 69, 69, 70, 72, 73, 73, 74, 75, 75,
|
|
|
261 |
76, 77, 79, 79, 80, 81, 82, 83, 83, 84, 86, 87, 88, 88, 89, 90, 91,
|
|
|
262 |
92, 93, 94, 95, 96, 97, 97, 99, 100, 101, 102, 103, 104, 105, 106,
|
|
|
263 |
108, 109, 110, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125, 127,
|
|
|
264 |
129, 131, 132, 135, 136, 138, 140, 142, 144, 146, 147, 150, 152, 154,
|
|
|
265 |
157, 159, 162, 164, 166, 168, 171, 174, 176, 180, 182, 187, 192, 197,
|
|
|
266 |
204, 215, 255},
|
|
|
267 |
/* Lookup values for magenta */
|
|
|
268 |
{0, 0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7,
|
|
|
269 |
7, 8, 8, 8, 9, 9, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12,
|
|
|
270 |
12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17,
|
|
|
271 |
17, 17, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22,
|
|
|
272 |
23, 23, 24, 24, 25, 25, 25, 26, 26, 27, 27, 28, 29, 29, 29, 29, 30,
|
|
|
273 |
30, 31, 30, 31, 31, 32, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36,
|
|
|
274 |
36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44,
|
|
|
275 |
45, 45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54,
|
|
|
276 |
54, 55, 55, 56, 57, 57, 58, 58, 59, 60, 60, 61, 61, 62, 63, 64, 65,
|
|
|
277 |
66, 66, 67, 68, 68, 70, 71, 71, 72, 73, 73, 74, 76, 77, 77, 78, 79,
|
|
|
278 |
79, 80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 92, 93,
|
|
|
279 |
94, 95, 96, 97, 98, 99, 100, 100, 101, 102, 103, 105, 106, 107, 108,
|
|
|
280 |
109, 112, 113, 114, 115, 116, 118, 119, 121, 123, 124, 125, 128, 129,
|
|
|
281 |
130, 133, 134, 135, 138, 139, 142, 144, 145, 148, 150, 152, 154, 157,
|
|
|
282 |
159, 162, 164, 168, 169, 170, 172, 175, 177, 179, 182, 185, 189, 193,
|
|
|
283 |
198, 204, 215, 255},
|
|
|
284 |
/* Lookup values for yellow */
|
|
|
285 |
{0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8,
|
|
|
286 |
8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11,
|
|
|
287 |
12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 17, 17, 18, 18,
|
|
|
288 |
18, 19, 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 22, 22, 23,
|
|
|
289 |
23, 24, 24, 25, 25, 25, 26, 27, 28, 28, 29, 29, 29, 30, 30, 30, 30,
|
|
|
290 |
31, 31, 32, 32, 33, 33, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37,
|
|
|
291 |
38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 45,
|
|
|
292 |
45, 46, 46, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 53, 53, 54, 54,
|
|
|
293 |
55, 55, 56, 57, 58, 59, 59, 60, 61, 61, 62, 62, 63, 64, 65, 66, 67,
|
|
|
294 |
67, 68, 69, 69, 70, 71, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79,
|
|
|
295 |
80, 81, 82, 83, 84, 85, 86, 87, 87, 88, 89, 90, 91, 91, 93, 94, 95,
|
|
|
296 |
96, 97, 98, 100, 101, 102, 102, 103, 104, 106, 107, 108, 109, 110,
|
|
|
297 |
111, 113, 114, 115, 116, 117, 118, 119, 121, 123, 124, 126, 128, 130,
|
|
|
298 |
131, 134, 135, 137, 139, 140, 143, 145, 146, 148, 150, 152, 154, 156,
|
|
|
299 |
158, 160, 163, 166, 167, 169, 171, 173, 176, 178, 181, 184, 188, 192,
|
|
|
300 |
198, 204, 215, 255},
|
|
|
301 |
/* Lookup values for black */
|
|
|
302 |
{0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
|
|
|
303 |
4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
|
|
|
304 |
8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
|
|
|
305 |
12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
|
|
|
306 |
16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
|
|
|
307 |
21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
|
|
|
308 |
26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
|
|
|
309 |
32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
|
|
|
310 |
41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
|
|
|
311 |
52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
|
|
|
312 |
65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
|
|
|
313 |
82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
|
|
|
314 |
103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
|
|
|
315 |
127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
|
|
|
316 |
166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
|
|
|
317 |
};
|
|
|
318 |
|
|
|
319 |
private const Gamma gammat890 =
|
|
|
320 |
{
|
|
|
321 |
/* Lookup values for cyan */
|
|
|
322 |
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
|
323 |
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
|
324 |
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
|
|
325 |
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
|
|
326 |
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
|
|
327 |
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
|
|
328 |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
|
|
329 |
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
|
|
|
330 |
126, 127,
|
|
|
331 |
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
|
|
332 |
142, 143,
|
|
|
333 |
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
|
|
|
334 |
158, 159,
|
|
|
335 |
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
|
|
|
336 |
174, 175,
|
|
|
337 |
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
|
|
338 |
190, 191,
|
|
|
339 |
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
|
|
|
340 |
206, 207,
|
|
|
341 |
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
|
|
|
342 |
222, 223,
|
|
|
343 |
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
|
|
|
344 |
238, 239,
|
|
|
345 |
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
|
|
|
346 |
254, 255},
|
|
|
347 |
|
|
|
348 |
/* Lookup values for magenta */
|
|
|
349 |
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
|
350 |
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
|
351 |
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
|
|
352 |
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
|
|
353 |
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
|
|
354 |
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
|
|
355 |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
|
|
356 |
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
|
|
|
357 |
126, 127,
|
|
|
358 |
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
|
|
359 |
142, 143,
|
|
|
360 |
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
|
|
|
361 |
158, 159,
|
|
|
362 |
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
|
|
|
363 |
174, 175,
|
|
|
364 |
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
|
|
365 |
190, 191,
|
|
|
366 |
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
|
|
|
367 |
206, 207,
|
|
|
368 |
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
|
|
|
369 |
222, 223,
|
|
|
370 |
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
|
|
|
371 |
238, 239,
|
|
|
372 |
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
|
|
|
373 |
254, 255},
|
|
|
374 |
|
|
|
375 |
/* Lookup values for yellow */
|
|
|
376 |
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
|
377 |
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
|
378 |
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
|
|
379 |
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
|
|
380 |
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
|
|
381 |
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
|
|
382 |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
|
|
383 |
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
|
|
|
384 |
126, 127,
|
|
|
385 |
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
|
|
|
386 |
142, 143,
|
|
|
387 |
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
|
|
|
388 |
158, 159,
|
|
|
389 |
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
|
|
|
390 |
174, 175,
|
|
|
391 |
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
|
|
392 |
190, 191,
|
|
|
393 |
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
|
|
|
394 |
206, 207,
|
|
|
395 |
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
|
|
|
396 |
222, 223,
|
|
|
397 |
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
|
|
|
398 |
238, 239,
|
|
|
399 |
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
|
|
|
400 |
254, 255},
|
|
|
401 |
|
|
|
402 |
/* Lookup values for black */
|
|
|
403 |
{0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4,
|
|
|
404 |
4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8,
|
|
|
405 |
8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13,
|
|
|
406 |
12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 16, 16,
|
|
|
407 |
16, 17, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 20, 20, 20, 21, 21,
|
|
|
408 |
21, 21, 22, 22, 22, 22, 23, 22, 23, 23, 24, 24, 24, 24, 25, 25, 26,
|
|
|
409 |
26, 26, 26, 27, 27, 28, 28, 28, 28, 29, 29, 30, 30, 31, 31, 31, 32,
|
|
|
410 |
32, 33, 33, 34, 34, 35, 36, 36, 36, 37, 37, 37, 38, 38, 40, 40, 40,
|
|
|
411 |
41, 41, 42, 43, 43, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 49, 50,
|
|
|
412 |
52, 52, 53, 54, 54, 56, 56, 57, 58, 59, 60, 60, 61, 62, 63, 63, 64,
|
|
|
413 |
65, 66, 67, 68, 69, 70, 71, 72, 72, 73, 75, 75, 76, 77, 78, 80, 81,
|
|
|
414 |
82, 82, 83, 84, 85, 86, 88, 89, 90, 91, 94, 95, 96, 98, 99, 100, 101,
|
|
|
415 |
103, 105, 106, 107, 110, 111, 112, 115, 116, 118, 120, 121, 124, 126,
|
|
|
416 |
127, 131, 133, 134, 138, 140, 141, 146, 148, 151, 154, 156, 160, 163,
|
|
|
417 |
166, 169, 174, 177, 182, 187, 194, 203, 215, 255}
|
|
|
418 |
};
|
|
|
419 |
|
|
|
420 |
private const Gamma * const gammat[] =
|
|
|
421 |
{
|
|
|
422 |
&gammat850, /* CDJ670 */
|
|
|
423 |
&gammat850, /* CDJ850 */
|
|
|
424 |
&gammat890, /* CDJ890 */
|
|
|
425 |
&gammat850 /* CDJ1600 */
|
|
|
426 |
};
|
|
|
427 |
|
|
|
428 |
private int
|
|
|
429 |
rescale_byte_wise1x1(P4(int bytecount, const byte * inbytea,
|
|
|
430 |
const byte * inbyteb, byte * outbyte));
|
|
|
431 |
private int
|
|
|
432 |
rescale_byte_wise2x1(P4(int bytecount, const byte * inbytea,
|
|
|
433 |
const byte * inbyteb, byte * outbyte));
|
|
|
434 |
private int
|
|
|
435 |
rescale_byte_wise1x2(P4(int bytecount, const byte * inbytea,
|
|
|
436 |
const byte * inbyteb, byte * outbyte));
|
|
|
437 |
private int
|
|
|
438 |
rescale_byte_wise2x2(P4(int bytecount, const byte * inbytea,
|
|
|
439 |
const byte * inbyteb, byte * outbyte));
|
|
|
440 |
|
|
|
441 |
private int (* const rescale_color_plane[2][2]) (P4(int, const byte *, const byte *, byte *)) = {
|
|
|
442 |
{
|
|
|
443 |
rescale_byte_wise1x1, rescale_byte_wise1x2
|
|
|
444 |
},
|
|
|
445 |
{
|
|
|
446 |
rescale_byte_wise2x1, rescale_byte_wise2x2
|
|
|
447 |
}
|
|
|
448 |
};
|
|
|
449 |
|
|
|
450 |
/*
|
|
|
451 |
* Drivers stuff.
|
|
|
452 |
*
|
|
|
453 |
*/
|
|
|
454 |
#define DESKJET_PRINT_LIMIT 0.04 /* 'real' top margin? */
|
|
|
455 |
/* Margins are left, bottom, right, top. */
|
|
|
456 |
#define DESKJET_MARGINS_LETTER 0.25, 0.50, 0.25, 0.167
|
|
|
457 |
#define DESKJET_MARGINS_A4 0.13, 0.46, 0.13, 0.04
|
|
|
458 |
/* Define bits-per-pixel - default is 32-bit cmyk-mode */
|
|
|
459 |
#ifndef BITSPERPIXEL
|
|
|
460 |
# define BITSPERPIXEL 32
|
|
|
461 |
#endif
|
|
|
462 |
#define DOFFSET (dev_t_margin(pdev) - DESKJET_PRINT_LIMIT) /* Print position */
|
|
|
463 |
|
|
|
464 |
|
|
|
465 |
#define W sizeof(word)
|
|
|
466 |
#define I sizeof(int)
|
|
|
467 |
|
|
|
468 |
/* paper types */
|
|
|
469 |
typedef enum {
|
|
|
470 |
PLAIN_PAPER, BOND_PAPER, SPECIAL_PAPER, GLOSSY_FILM, TRANSPARENCY_FILM
|
|
|
471 |
} cdj_paper_type_t;
|
|
|
472 |
|
|
|
473 |
/* quality */
|
|
|
474 |
typedef enum {
|
|
|
475 |
DRAFT = -1, NORMAL = 0, PRESENTATION = 1
|
|
|
476 |
} cdj_quality_t;
|
|
|
477 |
|
|
|
478 |
/* Printer types */
|
|
|
479 |
typedef enum {
|
|
|
480 |
DJ670C, DJ850C, DJ890C, DJ1600C
|
|
|
481 |
} cdj_printer_type_t;
|
|
|
482 |
|
|
|
483 |
/* No. of ink jets (used to minimise head movements) */
|
|
|
484 |
#define HEAD_ROWS_MONO 50
|
|
|
485 |
#define HEAD_ROWS_COLOUR 16
|
|
|
486 |
|
|
|
487 |
/* Colour mapping procedures */
|
|
|
488 |
private dev_proc_map_cmyk_color(gdev_cmyk_map_cmyk_color);
|
|
|
489 |
private dev_proc_map_rgb_color(gdev_cmyk_map_rgb_color);
|
|
|
490 |
private dev_proc_map_color_rgb(gdev_cmyk_map_color_rgb);
|
|
|
491 |
|
|
|
492 |
private dev_proc_map_rgb_color(gdev_pcl_map_rgb_color);
|
|
|
493 |
private dev_proc_map_color_rgb(gdev_pcl_map_color_rgb);
|
|
|
494 |
|
|
|
495 |
/* Print-page, parameters and miscellaneous procedures */
|
|
|
496 |
private dev_proc_open_device(hp_colour_open);
|
|
|
497 |
|
|
|
498 |
private dev_proc_get_params(cdj850_get_params);
|
|
|
499 |
private dev_proc_put_params(cdj850_put_params);
|
|
|
500 |
|
|
|
501 |
private dev_proc_print_page(cdj850_print_page);
|
|
|
502 |
|
|
|
503 |
/* The device descriptors */
|
|
|
504 |
|
|
|
505 |
/* The basic structure for all printers. Note the presence of the cmyk, depth
|
|
|
506 |
and correct fields even if some are not used by all printers. */
|
|
|
507 |
|
|
|
508 |
#define prn_colour_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page, cmyk, correct)\
|
|
|
509 |
prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page), cmyk, depth /* default */, correct
|
|
|
510 |
|
|
|
511 |
|
|
|
512 |
|
|
|
513 |
#define gx_prn_colour_device_common \
|
|
|
514 |
gx_prn_device_common; \
|
|
|
515 |
int cmyk; /* 0: not CMYK-capable, > 0: printing CMYK, */ \
|
|
|
516 |
/* < 0 : CMYK-capable, not printing CMYK */ \
|
|
|
517 |
uint default_depth; /* Used only for CMYK-capable printers now. */ \
|
|
|
518 |
uint correction
|
|
|
519 |
|
|
|
520 |
|
|
|
521 |
/* some definitions needed later */
|
|
|
522 |
struct error_val_field {
|
|
|
523 |
int c; /* Current value of Cyan error during dithering */
|
|
|
524 |
int m; /* Current value of Magenta error during dithering */
|
|
|
525 |
int y; /* Current value of Yellow error during dithering */
|
|
|
526 |
int k; /* Current value of Black error during dithering */
|
|
|
527 |
};
|
|
|
528 |
|
|
|
529 |
/* this structure holds all the pointers to the different values
|
|
|
530 |
in all those data fields */
|
|
|
531 |
/*
|
|
|
532 |
* The principal data pointers are stored as pairs of values, with
|
|
|
533 |
* the selection being made by the 'scan' variable. The function of the
|
|
|
534 |
* scan variable is overloaded, as it controls both the alternating
|
|
|
535 |
* raster scan direction used in the Floyd-Steinberg dithering and also
|
|
|
536 |
* the buffer alternation required for line-difference compression.
|
|
|
537 |
*
|
|
|
538 |
* Thus, the number of pointers required is as follows:
|
|
|
539 |
*/
|
|
|
540 |
|
|
|
541 |
struct ptr_arrays {
|
|
|
542 |
byte *data[4]; /* 4 600dpi data, scan direction and alternating buffers */
|
|
|
543 |
byte *data_c[4]; /* 4 300dpi data, as above, */
|
|
|
544 |
byte *plane_data[4][4]; /*4 b/w-planes, scan direction and alternating buffers */
|
|
|
545 |
byte *plane_data_c[4][8]; /* as above, but for 8 planes */
|
|
|
546 |
byte *out_data; /* output buffer for the b/w data, one 600dpi plane */
|
|
|
547 |
byte *test_data[4]; /* holds a copy of the last plane */
|
|
|
548 |
int *errors[2]; /* 2 b/w dithering erros (scan direction only) */
|
|
|
549 |
int *errors_c[2]; /* 2 color dithering errors (scan direction only) */
|
|
|
550 |
word *storage; /* pointer to the beginning of the b/w-buffer */
|
|
|
551 |
word *storage_start; /* used for debugging */
|
|
|
552 |
word *storage_end; /* used for debugging */
|
|
|
553 |
word *storage_size; /* used for debugging */
|
|
|
554 |
};
|
|
|
555 |
|
|
|
556 |
/* Some miscellaneous variables */
|
|
|
557 |
struct misc_struct {
|
|
|
558 |
int line_size; /* size of scan_line */
|
|
|
559 |
int line_size_c; /* size of rescaled scan_line */
|
|
|
560 |
int line_size_words; /* size of scan_line in words */
|
|
|
561 |
int paper_size; /* size of paper */
|
|
|
562 |
int num_comps; /* number of color components (1 - 4) */
|
|
|
563 |
int bits_per_pixel; /* bits per pixel 1,4,8,16,24,32 */
|
|
|
564 |
int storage_bpp; /* = bits_per_pixel */
|
|
|
565 |
int expanded_bpp; /* = bits_per_pixel */
|
|
|
566 |
int plane_size; /* size of b/w bit plane */
|
|
|
567 |
int plane_size_c; /* size of color bit plane */
|
|
|
568 |
int databuff_size; /* size of databuffer for b/w data */
|
|
|
569 |
int databuff_size_c; /* size of databuffer for color data */
|
|
|
570 |
int errbuff_size; /* size of error buffer b/w -data */
|
|
|
571 |
int errbuff_size_c; /* size of error buffer color -data */
|
|
|
572 |
int outbuff_size; /* size of output buffer for b/w data */
|
|
|
573 |
int scan; /* scan-line variable [0,1] */
|
|
|
574 |
int cscan; /* dito for the color-planes */
|
|
|
575 |
int is_two_pass; /* checks if b/w data has already been printed */
|
|
|
576 |
int zero_row_count; /* How many empty lines */
|
|
|
577 |
uint storage_size_words; /* size of storage in words for b/w data */
|
|
|
578 |
uint storage_size_words_c; /* size of storage in words for c-data */
|
|
|
579 |
int is_color_data; /* indicates whether there is color data */
|
|
|
580 |
};
|
|
|
581 |
|
|
|
582 |
/* function pointer typedefs for device driver struct */
|
|
|
583 |
typedef void (*StartRasterMode) (P3(gx_device_printer * pdev, int paper_size,
|
|
|
584 |
FILE * prn_stream));
|
|
|
585 |
typedef void (*PrintNonBlankLines) (P6(gx_device_printer * pdev,
|
|
|
586 |
struct ptr_arrays *data_ptrs,
|
|
|
587 |
struct misc_struct *misc_vars,
|
|
|
588 |
struct error_val_field *error_values,
|
|
|
589 |
const Gamma *gamma,
|
|
|
590 |
FILE * prn_stream));
|
|
|
591 |
|
|
|
592 |
typedef void (*TerminatePage) (P2(gx_device_printer * pdev, FILE * prn_stream));
|
|
|
593 |
|
|
|
594 |
typedef struct gx_device_cdj850_s {
|
|
|
595 |
gx_device_common;
|
|
|
596 |
gx_prn_colour_device_common;
|
|
|
597 |
int /*cdj_quality_t*/ quality; /* -1 draft, 0 normal, 1 best */
|
|
|
598 |
int /*cdj_paper_type_t*/ papertype; /* papertype [0,4] */
|
|
|
599 |
int intensities; /* intensity values per pixel [2,4] */
|
|
|
600 |
int xscal; /* boolean to indicate x scaling by 2 */
|
|
|
601 |
int yscal; /* boolean to indicate y scaling by 2 */
|
|
|
602 |
int /*cdj_printer_type_t*/ ptype; /* printer type, one of DJ670C, DJ850C, DJ890C, DJ1600C */
|
|
|
603 |
int compression; /* compression level */
|
|
|
604 |
float mastergamma; /* Gammavalue applied to all colors */
|
|
|
605 |
float gammavalc; /* range to which gamma-correction is
|
|
|
606 |
applied to bw values */
|
|
|
607 |
float gammavalm; /* amount of gamma correction for bw */
|
|
|
608 |
float gammavaly; /* range to which gamma-correction i
|
|
|
609 |
applied to color values */
|
|
|
610 |
float gammavalk; /* amount of gamma correction for color */
|
|
|
611 |
float blackcorrect; /* amount of gamma correction for color */
|
|
|
612 |
StartRasterMode start_raster_mode; /* output function to start raster mode */
|
|
|
613 |
PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */
|
|
|
614 |
TerminatePage terminate_page; /* page termination output function */
|
|
|
615 |
} gx_device_cdj850;
|
|
|
616 |
|
|
|
617 |
typedef struct {
|
|
|
618 |
gx_device_common;
|
|
|
619 |
gx_prn_colour_device_common;
|
|
|
620 |
} gx_device_colour_prn;
|
|
|
621 |
|
|
|
622 |
|
|
|
623 |
/* Use the cprn_device macro to access generic fields (like cmyk,
|
|
|
624 |
default_depth and correction), and specific macros for specific
|
|
|
625 |
devices. */
|
|
|
626 |
|
|
|
627 |
#define cprn_device ((gx_device_colour_prn*) pdev)
|
|
|
628 |
#define cdj850 ((gx_device_cdj850 *)pdev)
|
|
|
629 |
|
|
|
630 |
#define prn_cmyk_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
|
|
|
631 |
prn_colour_device_body(dtype, procs, dev_name,\
|
|
|
632 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
|
|
|
633 |
((bpp == 1 || bpp == 4) ? 1 : 4), bpp,\
|
|
|
634 |
(bpp > 8 ? 255 : 1), (1 << (bpp >> 2)) - 1, /* max_gray, max_color */\
|
|
|
635 |
(bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
|
|
|
636 |
print_page, 1 /* cmyk */, correct)
|
|
|
637 |
|
|
|
638 |
|
|
|
639 |
#define prn_cmy_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\
|
|
|
640 |
prn_colour_device_body(dtype, procs, dev_name,\
|
|
|
641 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, x_dpi, y_dpi, 0, 0, 0, 0,\
|
|
|
642 |
((bpp == 1 || bpp == 4) ? 1 : 3), bpp,\
|
|
|
643 |
(bpp > 8 ? 255 : 1), (bpp > 8 ? 255 : 1), /* max_gray, max_color */\
|
|
|
644 |
(bpp > 8 ? 5 : 2), (bpp > 8 ? 5 : bpp > 1 ? 2 : 0),\
|
|
|
645 |
print_page, -1 /* cmyk */, correct)
|
|
|
646 |
|
|
|
647 |
|
|
|
648 |
#define cdj_850_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
|
|
|
649 |
{ prn_cmyk_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
|
|
|
650 |
quality,\
|
|
|
651 |
papertype,\
|
|
|
652 |
intensities,\
|
|
|
653 |
0, 0, /* xscal, yscal */\
|
|
|
654 |
ptype,\
|
|
|
655 |
compression,\
|
|
|
656 |
mastergamma,\
|
|
|
657 |
gammavalc,\
|
|
|
658 |
gammavalm,\
|
|
|
659 |
gammavaly,\
|
|
|
660 |
gammavalk,\
|
|
|
661 |
blackcorrect,\
|
|
|
662 |
start_raster_mode,\
|
|
|
663 |
print_non_blank_line,\
|
|
|
664 |
terminate_page\
|
|
|
665 |
}
|
|
|
666 |
|
|
|
667 |
#define cdj_1600_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\
|
|
|
668 |
{ prn_cmy_colour_device(gx_device_cdj850, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction),\
|
|
|
669 |
quality,\
|
|
|
670 |
papertype,\
|
|
|
671 |
intensities,\
|
|
|
672 |
0, 0, /* xscal, yscal */\
|
|
|
673 |
ptype,\
|
|
|
674 |
compression,\
|
|
|
675 |
mastergamma,\
|
|
|
676 |
gammavalc,\
|
|
|
677 |
gammavalm,\
|
|
|
678 |
gammavaly,\
|
|
|
679 |
gammavalk,\
|
|
|
680 |
blackcorrect,\
|
|
|
681 |
start_raster_mode,\
|
|
|
682 |
print_non_blank_line,\
|
|
|
683 |
terminate_page\
|
|
|
684 |
}
|
|
|
685 |
|
|
|
686 |
#define cmyk_colour_procs(proc_colour_open, proc_get_params, proc_put_params, \
|
|
|
687 |
map_rgb_color, map_color_rgb, map_cmyk_color) {\
|
|
|
688 |
proc_colour_open,\
|
|
|
689 |
gx_default_get_initial_matrix,\
|
|
|
690 |
gx_default_sync_output,\
|
|
|
691 |
gdev_prn_output_page,\
|
|
|
692 |
gdev_prn_close,\
|
|
|
693 |
map_rgb_color,\
|
|
|
694 |
map_color_rgb,\
|
|
|
695 |
NULL /* fill_rectangle */,\
|
|
|
696 |
NULL /* tile_rectangle */,\
|
|
|
697 |
NULL /* copy_mono */,\
|
|
|
698 |
NULL /* copy_color */,\
|
|
|
699 |
NULL /* draw_line */,\
|
|
|
700 |
gx_default_get_bits,\
|
|
|
701 |
proc_get_params,\
|
|
|
702 |
proc_put_params,\
|
|
|
703 |
map_cmyk_color\
|
|
|
704 |
}
|
|
|
705 |
|
|
|
706 |
private void
|
|
|
707 |
cdj850_start_raster_mode(P3(gx_device_printer * pdev,
|
|
|
708 |
int papersize, FILE * prn_stream));
|
|
|
709 |
|
|
|
710 |
private void
|
|
|
711 |
cdj850_print_non_blank_lines(P6(gx_device_printer * pdev,
|
|
|
712 |
struct ptr_arrays *data_ptrs,
|
|
|
713 |
struct misc_struct *misc_vars,
|
|
|
714 |
struct error_val_field *error_values,
|
|
|
715 |
const Gamma *gamma,
|
|
|
716 |
FILE * prn_stream));
|
|
|
717 |
private void
|
|
|
718 |
cdj850_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
|
|
|
719 |
|
|
|
720 |
private void
|
|
|
721 |
cdj1600_start_raster_mode(P3(gx_device_printer * pdev,
|
|
|
722 |
int papersize, FILE * prn_stream));
|
|
|
723 |
private void
|
|
|
724 |
cdj1600_print_non_blank_lines(P6(gx_device_printer * pdev,
|
|
|
725 |
struct ptr_arrays *data_ptrs,
|
|
|
726 |
struct misc_struct *misc_vars,
|
|
|
727 |
struct error_val_field *error_values,
|
|
|
728 |
const Gamma *gamma,
|
|
|
729 |
FILE * prn_stream));
|
|
|
730 |
private void
|
|
|
731 |
cdj1600_terminate_page(P2(gx_device_printer * pdev, FILE * prn_stream));
|
|
|
732 |
|
|
|
733 |
|
|
|
734 |
|
|
|
735 |
private const gx_device_procs cdj670_procs =
|
|
|
736 |
cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
|
|
|
737 |
NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
|
|
|
738 |
|
|
|
739 |
private const gx_device_procs cdj850_procs =
|
|
|
740 |
cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
|
|
|
741 |
NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
|
|
|
742 |
|
|
|
743 |
private const gx_device_procs cdj890_procs =
|
|
|
744 |
cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
|
|
|
745 |
NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color);
|
|
|
746 |
|
|
|
747 |
private const gx_device_procs cdj1600_procs =
|
|
|
748 |
cmyk_colour_procs(hp_colour_open, cdj850_get_params, cdj850_put_params,
|
|
|
749 |
gdev_pcl_map_rgb_color, gdev_pcl_map_color_rgb, NULL);
|
|
|
750 |
|
|
|
751 |
const gx_device_cdj850 gs_cdj670_device =
|
|
|
752 |
cdj_850_device(cdj670_procs, "cdj670", 600, 600, 32, cdj850_print_page, 0,
|
|
|
753 |
PRESENTATION, PLAIN_PAPER, 2, DJ670C, 9,
|
|
|
754 |
1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
|
|
755 |
cdj850_start_raster_mode, cdj850_print_non_blank_lines,
|
|
|
756 |
cdj850_terminate_page);
|
|
|
757 |
|
|
|
758 |
const gx_device_cdj850 gs_cdj850_device =
|
|
|
759 |
cdj_850_device(cdj850_procs, "cdj850", 600, 600, 32, cdj850_print_page, 0,
|
|
|
760 |
PRESENTATION, PLAIN_PAPER, 4, DJ850C, 9,
|
|
|
761 |
1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
|
|
762 |
cdj850_start_raster_mode, cdj850_print_non_blank_lines,
|
|
|
763 |
cdj850_terminate_page);
|
|
|
764 |
|
|
|
765 |
const gx_device_cdj850 gs_cdj890_device =
|
|
|
766 |
cdj_850_device(cdj890_procs, "cdj890", 600, 600, 32, cdj850_print_page, 0,
|
|
|
767 |
PRESENTATION, PLAIN_PAPER, 4, DJ890C, 9,
|
|
|
768 |
1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
|
|
769 |
cdj850_start_raster_mode, cdj850_print_non_blank_lines,
|
|
|
770 |
cdj850_terminate_page);
|
|
|
771 |
|
|
|
772 |
const gx_device_cdj850 gs_cdj1600_device =
|
|
|
773 |
cdj_1600_device(cdj1600_procs, "cdj1600", 300, 300, 24, cdj850_print_page, 0,
|
|
|
774 |
PRESENTATION, PLAIN_PAPER, 2, DJ1600C, 3,
|
|
|
775 |
1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
|
|
|
776 |
cdj1600_start_raster_mode, cdj1600_print_non_blank_lines,
|
|
|
777 |
cdj1600_terminate_page);
|
|
|
778 |
|
|
|
779 |
/* Forward references */
|
|
|
780 |
private int cdj_put_param_int(P6(gs_param_list *, gs_param_name,
|
|
|
781 |
int *, int, int, int));
|
|
|
782 |
private int cdj_put_param_float(P6(gs_param_list *, gs_param_name, float
|
|
|
783 |
*, float, float, int));
|
|
|
784 |
private int cdj_put_param_bpp(P5(gx_device *, gs_param_list *, int, int, int));
|
|
|
785 |
private int cdj_set_bpp(P3(gx_device *, int, int));
|
|
|
786 |
|
|
|
787 |
|
|
|
788 |
/* Open the printer and set up the margins. */
|
|
|
789 |
private int
|
|
|
790 |
hp_colour_open(gx_device * pdev)
|
|
|
791 |
{ /* Change the margins if necessary. */
|
|
|
792 |
static const float dj_a4[4] = {
|
|
|
793 |
DESKJET_MARGINS_A4
|
|
|
794 |
};
|
|
|
795 |
static const float dj_letter[4] = {
|
|
|
796 |
DESKJET_MARGINS_LETTER
|
|
|
797 |
};
|
|
|
798 |
|
|
|
799 |
/* margins for DJ1600C from manual */
|
|
|
800 |
static const float m_cdj1600[4] = {
|
|
|
801 |
0.25, 0.5, 0.25, 0.5
|
|
|
802 |
};
|
|
|
803 |
|
|
|
804 |
const float *m = (float *)0;
|
|
|
805 |
|
|
|
806 |
/* Set up colour params if put_params has not already done so */
|
|
|
807 |
if (pdev->color_info.num_components == 0) {
|
|
|
808 |
int code = cdj_set_bpp(pdev, pdev->color_info.depth,
|
|
|
809 |
pdev->color_info.num_components);
|
|
|
810 |
|
|
|
811 |
if (code < 0)
|
|
|
812 |
return code;
|
|
|
813 |
}
|
|
|
814 |
/* assign printer type and set resolution dependent on printer type */
|
|
|
815 |
switch (cdj850->ptype) {
|
|
|
816 |
case DJ670C:
|
|
|
817 |
if (cdj850->papertype <= SPECIAL_PAPER) { /* paper */
|
|
|
818 |
if (cdj850->quality == DRAFT) {
|
|
|
819 |
gx_device_set_resolution(pdev, 300.0, 300.0);
|
|
|
820 |
cdj850->xscal = 0;
|
|
|
821 |
cdj850->yscal = 0;
|
|
|
822 |
} else if (cdj850->quality == NORMAL) {
|
|
|
823 |
gx_device_set_resolution(pdev, 600.0, 300.0);
|
|
|
824 |
cdj850->xscal = 1;
|
|
|
825 |
cdj850->yscal = 0;
|
|
|
826 |
} else { /* quality == PRESENTATION */
|
|
|
827 |
gx_device_set_resolution(pdev, 600.0, 600.0);
|
|
|
828 |
cdj850->xscal = 1;
|
|
|
829 |
cdj850->yscal = 1;
|
|
|
830 |
}
|
|
|
831 |
} else { /* film */
|
|
|
832 |
gx_device_set_resolution(pdev, 600.0, 300.0);
|
|
|
833 |
cdj850->xscal = 0;
|
|
|
834 |
cdj850->yscal = 0;
|
|
|
835 |
}
|
|
|
836 |
m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
|
|
|
837 |
break;
|
|
|
838 |
case DJ850C:
|
|
|
839 |
case DJ890C:
|
|
|
840 |
if (cdj850->quality == DRAFT) {
|
|
|
841 |
gx_device_set_resolution(pdev, 300.0, 300.0);
|
|
|
842 |
cdj850->xscal = 0;
|
|
|
843 |
cdj850->yscal = 0;
|
|
|
844 |
cdj850->intensities = 2;
|
|
|
845 |
} else if (cdj850->quality == NORMAL) {
|
|
|
846 |
gx_device_set_resolution(pdev, 600.0, 300.0);
|
|
|
847 |
cdj850->xscal = 1;
|
|
|
848 |
cdj850->yscal = 0;
|
|
|
849 |
/* only 3 intensities for normal paper */
|
|
|
850 |
if (cdj850->papertype <= PLAIN_PAPER) {
|
|
|
851 |
cdj850->intensities = 3;
|
|
|
852 |
} /* else cdj850->intensities = 4 from initialization */
|
|
|
853 |
} else { /* quality == PRESENTATION */
|
|
|
854 |
gx_device_set_resolution(pdev, 600.0, 600.0);
|
|
|
855 |
cdj850->xscal = 1;
|
|
|
856 |
cdj850->yscal = 1;
|
|
|
857 |
/* intensities = 4 from initialization */
|
|
|
858 |
}
|
|
|
859 |
m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter);
|
|
|
860 |
break;
|
|
|
861 |
case DJ1600C:
|
|
|
862 |
gx_device_set_resolution(pdev, 300.0, 300.0);
|
|
|
863 |
m = m_cdj1600;
|
|
|
864 |
break;
|
|
|
865 |
default:
|
|
|
866 |
assert(0);
|
|
|
867 |
}
|
|
|
868 |
gx_device_set_margins(pdev, m, true);
|
|
|
869 |
return gdev_prn_open(pdev);
|
|
|
870 |
}
|
|
|
871 |
|
|
|
872 |
/* Added parameters for DeskJet 850C */
|
|
|
873 |
private int
|
|
|
874 |
cdj850_get_params(gx_device * pdev, gs_param_list * plist)
|
|
|
875 |
{
|
|
|
876 |
int code = gdev_prn_get_params(pdev, plist);
|
|
|
877 |
|
|
|
878 |
if (code < 0 ||
|
|
|
879 |
(code = param_write_int(plist, "Quality", &cdj850->quality)) < 0 ||
|
|
|
880 |
(code = param_write_int(plist, "Papertype", &cdj850->papertype)) < 0 ||
|
|
|
881 |
(code = param_write_float(plist, "MasterGamma", &cdj850->gammavalc))
|
|
|
882 |
< 0 ||
|
|
|
883 |
(code = param_write_float(plist, "GammaValC", &cdj850->gammavalc)) <
|
|
|
884 |
|
|
|
885 |
(code = param_write_float(plist, "GammaValM", &cdj850->gammavalm)) <
|
|
|
886 |
|
|
|
887 |
(code = param_write_float(plist, "GammaValY", &cdj850->gammavaly)) <
|
|
|
888 |
|
|
|
889 |
(code = param_write_float(plist, "GammaValK", &cdj850->gammavalk)) <
|
|
|
890 |
|
|
|
891 |
(code = param_write_float(plist, "BlackCorrect",
|
|
|
892 |
&cdj850->blackcorrect)) < 0
|
|
|
893 |
)
|
|
|
894 |
return code;
|
|
|
895 |
|
|
|
896 |
return code;
|
|
|
897 |
}
|
|
|
898 |
|
|
|
899 |
private int
|
|
|
900 |
cdj850_put_params(gx_device * pdev, gs_param_list * plist)
|
|
|
901 |
{
|
|
|
902 |
int quality = cdj850->quality;
|
|
|
903 |
int papertype = cdj850->papertype;
|
|
|
904 |
float mastergamma = cdj850->mastergamma;
|
|
|
905 |
float gammavalc = cdj850->gammavalc;
|
|
|
906 |
float gammavalm = cdj850->gammavalm;
|
|
|
907 |
float gammavaly = cdj850->gammavaly;
|
|
|
908 |
float gammavalk = cdj850->gammavalk;
|
|
|
909 |
float blackcorrect = cdj850->blackcorrect;
|
|
|
910 |
int bpp = 0;
|
|
|
911 |
int code = 0;
|
|
|
912 |
|
|
|
913 |
code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code);
|
|
|
914 |
code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code);
|
|
|
915 |
code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code);
|
|
|
916 |
code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code);
|
|
|
917 |
code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code);
|
|
|
918 |
code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code);
|
|
|
919 |
code = cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code);
|
|
|
920 |
code = cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code);
|
|
|
921 |
code = cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0,
|
|
|
922 |
9.0, code);
|
|
|
923 |
|
|
|
924 |
|
|
|
925 |
if (code < 0)
|
|
|
926 |
return code;
|
|
|
927 |
code = cdj_put_param_bpp(pdev, plist, bpp, bpp, 0);
|
|
|
928 |
if (code < 0)
|
|
|
929 |
return code;
|
|
|
930 |
|
|
|
931 |
cdj850->quality = quality;
|
|
|
932 |
cdj850->papertype = papertype;
|
|
|
933 |
cdj850->mastergamma = mastergamma;
|
|
|
934 |
cdj850->gammavalc = gammavalc;
|
|
|
935 |
cdj850->gammavalm = gammavalm;
|
|
|
936 |
cdj850->gammavaly = gammavaly;
|
|
|
937 |
cdj850->gammavalk = gammavalk;
|
|
|
938 |
cdj850->blackcorrect = blackcorrect;
|
|
|
939 |
return 0;
|
|
|
940 |
}
|
|
|
941 |
|
|
|
942 |
/* ------ Internal routines ------ */
|
|
|
943 |
/* The DeskJet850C can compress (mode 9) */
|
|
|
944 |
|
|
|
945 |
|
|
|
946 |
/* Some convenient shorthand .. */
|
|
|
947 |
#define x_dpi (pdev->x_pixels_per_inch)
|
|
|
948 |
#define y_dpi (pdev->y_pixels_per_inch)
|
|
|
949 |
|
|
|
950 |
/* To calculate buffer size as next greater multiple of both parameter and W */
|
|
|
951 |
#define calc_buffsize(a, b) (((((a) + ((b) * W) - 1) / ((b) * W))) * W)
|
|
|
952 |
|
|
|
953 |
/* internal functions */
|
|
|
954 |
private void
|
|
|
955 |
FSDlinebw(P7(int scan, int plane_size,
|
|
|
956 |
struct error_val_field *error_values,
|
|
|
957 |
byte * kP,
|
|
|
958 |
int n, int *ep, byte * dp));
|
|
|
959 |
private void
|
|
|
960 |
FSDlinec2(P9(int scan, int plane_size,
|
|
|
961 |
struct error_val_field *error_values,
|
|
|
962 |
byte * cPa, byte * mPa, byte * yPa, int n,
|
|
|
963 |
byte * dp, int *ep));
|
|
|
964 |
private void
|
|
|
965 |
FSDlinec3(P12(int scan, int plane_size,
|
|
|
966 |
struct error_val_field *error_values,
|
|
|
967 |
byte * cPa, byte * mPa, byte * yPa,
|
|
|
968 |
byte * cPb, byte * mPb, byte * yPb,
|
|
|
969 |
int n, byte * dp, int *ep));
|
|
|
970 |
private void
|
|
|
971 |
FSDlinec4(P12(int scan, int plane_size,
|
|
|
972 |
struct error_val_field *error_values,
|
|
|
973 |
byte * cPa, byte * mPa, byte * yPa,
|
|
|
974 |
byte * cPb, byte * mPb, byte * yPb,
|
|
|
975 |
int n, byte * dp, int *ep));
|
|
|
976 |
private void
|
|
|
977 |
init_error_buffer(struct misc_struct *misc_vars,
|
|
|
978 |
struct ptr_arrays *data_ptrs);
|
|
|
979 |
private void
|
|
|
980 |
do_floyd_steinberg(P8(int scan, int cscan, int plane_size,
|
|
|
981 |
int plane_size_c, int n,
|
|
|
982 |
struct ptr_arrays *data_ptrs,
|
|
|
983 |
gx_device_printer * pdev,
|
|
|
984 |
struct error_val_field *error_values));
|
|
|
985 |
private int
|
|
|
986 |
do_gcr(P7(int bytecount, byte * inbyte, const byte * kvalues,
|
|
|
987 |
const byte * cvalues, const byte * mvalues,
|
|
|
988 |
const byte * yvalues, const int *kcorrect));
|
|
|
989 |
|
|
|
990 |
/* UNUSED
|
|
|
991 |
*private int
|
|
|
992 |
*test_scan (P4(int size,
|
|
|
993 |
* byte * current,
|
|
|
994 |
* byte * last,
|
|
|
995 |
* byte * control));
|
|
|
996 |
*private void
|
|
|
997 |
*save_color_data(P3(int size,
|
|
|
998 |
* byte * current,
|
|
|
999 |
* byte * saved));
|
|
|
1000 |
*
|
|
|
1001 |
*/
|
|
|
1002 |
private void
|
|
|
1003 |
send_scan_lines(P6(gx_device_printer * pdev,
|
|
|
1004 |
struct ptr_arrays *data_ptrs,
|
|
|
1005 |
struct misc_struct *misc_vars,
|
|
|
1006 |
struct error_val_field *error_values,
|
|
|
1007 |
const Gamma *gamma,
|
|
|
1008 |
FILE * prn_stream));
|
|
|
1009 |
private void
|
|
|
1010 |
do_gamma(P3(float mastergamma, float gammaval, byte * values));
|
|
|
1011 |
private void
|
|
|
1012 |
do_black_correction(P2(float kvalue, int *kcorrect));
|
|
|
1013 |
|
|
|
1014 |
private void
|
|
|
1015 |
init_data_structure(P3(gx_device_printer * pdev,
|
|
|
1016 |
struct ptr_arrays *data_ptrs,
|
|
|
1017 |
struct misc_struct *misc_vars));
|
|
|
1018 |
private void
|
|
|
1019 |
calculate_memory_size(P2(gx_device_printer * pdev,
|
|
|
1020 |
struct misc_struct *misc_vars));
|
|
|
1021 |
|
|
|
1022 |
|
|
|
1023 |
private void
|
|
|
1024 |
assign_dpi(int dpi, byte * msb)
|
|
|
1025 |
{
|
|
|
1026 |
if (dpi == 600) {
|
|
|
1027 |
msb[0] = 0x02;
|
|
|
1028 |
msb[1] = 0x58;
|
|
|
1029 |
} else {
|
|
|
1030 |
msb[0] = 0x01;
|
|
|
1031 |
msb[1] = 0x2c;
|
|
|
1032 |
}
|
|
|
1033 |
}
|
|
|
1034 |
|
|
|
1035 |
private void
|
|
|
1036 |
cdj850_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
|
|
|
1037 |
{
|
|
|
1038 |
fputs("0M", prn_stream); /* Reset compression */
|
|
|
1039 |
fputs("\033*rC\033E", prn_stream); /* End Graphics, Reset */
|
|
|
1040 |
fputs("\033&l0H", prn_stream); /* eject page */
|
|
|
1041 |
}
|
|
|
1042 |
|
|
|
1043 |
/* Here comes the hp850 output routine -------------------- */
|
|
|
1044 |
private int
|
|
|
1045 |
cdj850_print_page(gx_device_printer * pdev, FILE * prn_stream)
|
|
|
1046 |
{
|
|
|
1047 |
|
|
|
1048 |
struct error_val_field error_values;
|
|
|
1049 |
struct ptr_arrays data_ptrs;
|
|
|
1050 |
struct misc_struct misc_vars;
|
|
|
1051 |
|
|
|
1052 |
Gamma gamma;
|
|
|
1053 |
|
|
|
1054 |
/* make a local writable copy of the Gamma tables */
|
|
|
1055 |
memcpy(&gamma, gammat[cdj850->ptype], sizeof(Gamma));
|
|
|
1056 |
/* if mastergamma, don't use the built in functions */
|
|
|
1057 |
if (cdj850->mastergamma > 1.0) {
|
|
|
1058 |
/* prepare the bw lookup table */
|
|
|
1059 |
do_gamma(cdj850->mastergamma, cdj850->gammavalk, gamma.k);
|
|
|
1060 |
/* prepare the color lookup table */
|
|
|
1061 |
do_gamma(cdj850->mastergamma, cdj850->gammavalc, gamma.c);
|
|
|
1062 |
do_gamma(cdj850->mastergamma, cdj850->gammavalm, gamma.m);
|
|
|
1063 |
do_gamma(cdj850->mastergamma, cdj850->gammavaly, gamma.y);
|
|
|
1064 |
}
|
|
|
1065 |
/* prepare the black correction table for the unbunt mask */
|
|
|
1066 |
do_black_correction(cdj850->blackcorrect, gamma.correct);
|
|
|
1067 |
|
|
|
1068 |
/* Calculate the needed memory */
|
|
|
1069 |
calculate_memory_size(pdev, &misc_vars);
|
|
|
1070 |
|
|
|
1071 |
/* and allocate the memory */
|
|
|
1072 |
|
|
|
1073 |
/* Since we need 600 and 300 dpi, we set up several buffers:
|
|
|
1074 |
storage contains the data as copied from gs, as well as the
|
|
|
1075 |
plane-data and the out_row buffer.
|
|
|
1076 |
storagec will contain the rescaled color data. It also contains the
|
|
|
1077 |
plane_data for the color-planes - these are needed by the
|
|
|
1078 |
compression routine, but would be overwritten by the
|
|
|
1079 |
b/w-dithering. The color planes allow for overwriting the
|
|
|
1080 |
color-data by the error-data. Since we might use the
|
|
|
1081 |
2bpp feature of the hp850 someday, it is sized like storage.
|
|
|
1082 |
storagee contains the errors from b/w fs-ditherng */
|
|
|
1083 |
|
|
|
1084 |
data_ptrs.storage = (ulong *) gs_malloc(pdev->memory, misc_vars.storage_size_words, W,
|
|
|
1085 |
"cdj850_print_page");
|
|
|
1086 |
|
|
|
1087 |
/* if we can't allocate working area */
|
|
|
1088 |
if (data_ptrs.storage == 0) {
|
|
|
1089 |
return_error(gs_error_VMerror);
|
|
|
1090 |
}
|
|
|
1091 |
/* Initialise the needed pointers */
|
|
|
1092 |
init_data_structure(pdev, &data_ptrs, &misc_vars);
|
|
|
1093 |
|
|
|
1094 |
/* Start Raster mode */
|
|
|
1095 |
(*cdj850->start_raster_mode) (pdev, misc_vars.paper_size, prn_stream);
|
|
|
1096 |
|
|
|
1097 |
/* Send each scan line in turn */
|
|
|
1098 |
send_scan_lines(pdev, &data_ptrs, &misc_vars,
|
|
|
1099 |
&error_values, &gamma, prn_stream);
|
|
|
1100 |
|
|
|
1101 |
/* terminate page and eject paper */
|
|
|
1102 |
(*cdj850->terminate_page) (pdev, prn_stream);
|
|
|
1103 |
|
|
|
1104 |
/* Free Memory */
|
|
|
1105 |
gs_free(pdev->memory, (char *)data_ptrs.storage, misc_vars.storage_size_words, W,
|
|
|
1106 |
"hp850_print_page");
|
|
|
1107 |
|
|
|
1108 |
return 0;
|
|
|
1109 |
}
|
|
|
1110 |
|
|
|
1111 |
#define odd(i) ((i & 01) != 0)
|
|
|
1112 |
|
|
|
1113 |
private int
|
|
|
1114 |
GetScanLine(gx_device_printer * pdev, int *lnum,
|
|
|
1115 |
struct ptr_arrays *data_ptrs,
|
|
|
1116 |
struct misc_struct *misc_vars,
|
|
|
1117 |
word rmask)
|
|
|
1118 |
{
|
|
|
1119 |
word *data_words = (word *) data_ptrs->data[misc_vars->scan];
|
|
|
1120 |
register word *end_data = data_words + misc_vars->line_size_words;
|
|
|
1121 |
|
|
|
1122 |
++(*lnum);
|
|
|
1123 |
gdev_prn_copy_scan_lines(pdev, *lnum, (byte *) data_words, misc_vars->line_size);
|
|
|
1124 |
|
|
|
1125 |
misc_vars->scan = 1 - misc_vars->scan; /* toggle scan direction */
|
|
|
1126 |
misc_vars->is_two_pass = odd(*lnum); /* color output for odd lines */
|
|
|
1127 |
|
|
|
1128 |
/* Mask off 1-bits beyond the line width. */
|
|
|
1129 |
end_data[-1] &= rmask;
|
|
|
1130 |
|
|
|
1131 |
/* Remove trailing 0s. */
|
|
|
1132 |
while (end_data > data_words && end_data[-1] == 0)
|
|
|
1133 |
end_data--;
|
|
|
1134 |
|
|
|
1135 |
return end_data - data_words;
|
|
|
1136 |
}
|
|
|
1137 |
|
|
|
1138 |
/* Send the scan lines to the printer */
|
|
|
1139 |
private void
|
|
|
1140 |
send_scan_lines(gx_device_printer * pdev,
|
|
|
1141 |
struct ptr_arrays *data_ptrs,
|
|
|
1142 |
struct misc_struct *misc_vars,
|
|
|
1143 |
struct error_val_field *error_values,
|
|
|
1144 |
const Gamma *gamma,
|
|
|
1145 |
FILE * prn_stream)
|
|
|
1146 |
{
|
|
|
1147 |
int lnum, lend, llen;
|
|
|
1148 |
int num_blank_lines = 0;
|
|
|
1149 |
|
|
|
1150 |
word rmask =
|
|
|
1151 |
~(word) 0 << ((-pdev->width * misc_vars->storage_bpp) & (W * 8 - 1));
|
|
|
1152 |
|
|
|
1153 |
lend = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * y_dpi;
|
|
|
1154 |
|
|
|
1155 |
error_values->c = error_values->m = error_values->y =
|
|
|
1156 |
error_values->k = 0;
|
|
|
1157 |
|
|
|
1158 |
/* init the error buffer */
|
|
|
1159 |
init_error_buffer(misc_vars, data_ptrs);
|
|
|
1160 |
|
|
|
1161 |
misc_vars->zero_row_count = 0;
|
|
|
1162 |
lnum = -1;
|
|
|
1163 |
llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
|
|
|
1164 |
while (lnum < lend) {
|
|
|
1165 |
num_blank_lines = 0;
|
|
|
1166 |
while (lnum < lend && llen == 0) {
|
|
|
1167 |
++num_blank_lines;
|
|
|
1168 |
llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
|
|
|
1169 |
}
|
|
|
1170 |
if (lnum >= lend) {
|
|
|
1171 |
break;
|
|
|
1172 |
}
|
|
|
1173 |
/* Skip blank lines if any */
|
|
|
1174 |
if (num_blank_lines > 0) {
|
|
|
1175 |
fprintf(prn_stream, "%dy", num_blank_lines / (cdj850->yscal + 1));
|
|
|
1176 |
memset(data_ptrs->plane_data[0][0], 0,
|
|
|
1177 |
(misc_vars->plane_size * 2 * misc_vars->num_comps));
|
|
|
1178 |
memset(data_ptrs->plane_data_c[0][0], 0,
|
|
|
1179 |
(misc_vars->plane_size_c * 2 * misc_vars->num_comps));
|
|
|
1180 |
|
|
|
1181 |
}
|
|
|
1182 |
/* all blank lines printed, now for the non-blank lines */
|
|
|
1183 |
if (cdj850->yscal && odd(lnum)) {
|
|
|
1184 |
/* output a blank black plane for odd lines */
|
|
|
1185 |
putc('v', prn_stream);
|
|
|
1186 |
}
|
|
|
1187 |
/* now output all non blank lines */
|
|
|
1188 |
while (lnum < lend && llen != 0) {
|
|
|
1189 |
misc_vars->is_color_data = 0; /* maybe we have color ? */
|
|
|
1190 |
(*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
|
|
|
1191 |
error_values, gamma, prn_stream);
|
|
|
1192 |
llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask);
|
|
|
1193 |
}
|
|
|
1194 |
if (cdj850->yscal && odd(lnum)) { /* output empty line for odd lines */
|
|
|
1195 |
(*cdj850->print_non_blank_lines) (pdev, data_ptrs, misc_vars,
|
|
|
1196 |
error_values, gamma, prn_stream);
|
|
|
1197 |
}
|
|
|
1198 |
/* the current line is empty => run the next iteration */
|
|
|
1199 |
}
|
|
|
1200 |
}
|
|
|
1201 |
|
|
|
1202 |
/* print_line compresses (mode 9) and outputs one plane */
|
|
|
1203 |
private void
|
|
|
1204 |
print_c9plane(FILE * prn_stream, char plane_code, int plane_size,
|
|
|
1205 |
const byte * curr, const byte * prev, byte * out_data)
|
|
|
1206 |
{
|
|
|
1207 |
/* Compress the output data */
|
|
|
1208 |
int out_count = gdev_pcl_mode9compress(plane_size, curr, prev, out_data);
|
|
|
1209 |
|
|
|
1210 |
/* and output the data */
|
|
|
1211 |
if (out_count > 0) {
|
|
|
1212 |
fprintf(prn_stream, "%d%c", out_count, plane_code);
|
|
|
1213 |
fwrite(out_data, sizeof(byte), out_count, prn_stream);
|
|
|
1214 |
} else {
|
|
|
1215 |
putc(plane_code, prn_stream);
|
|
|
1216 |
}
|
|
|
1217 |
}
|
|
|
1218 |
|
|
|
1219 |
/* Printing non-blank lines */
|
|
|
1220 |
private void
|
|
|
1221 |
cdj850_print_non_blank_lines(gx_device_printer * pdev,
|
|
|
1222 |
struct ptr_arrays *data_ptrs,
|
|
|
1223 |
struct misc_struct *misc_vars,
|
|
|
1224 |
struct error_val_field *error_values,
|
|
|
1225 |
const Gamma *gamma,
|
|
|
1226 |
FILE * prn_stream)
|
|
|
1227 |
{
|
|
|
1228 |
static const char *const plane_code[2] =
|
|
|
1229 |
{"wvvv", "vvvv"};
|
|
|
1230 |
|
|
|
1231 |
int i;
|
|
|
1232 |
byte *kP = data_ptrs->plane_data[misc_vars->scan + 2][3];
|
|
|
1233 |
byte *dp = data_ptrs->data[misc_vars->scan + 2];
|
|
|
1234 |
int *ep = data_ptrs->errors[misc_vars->scan];
|
|
|
1235 |
|
|
|
1236 |
/* we need cmyk color separation befor all the rest, since
|
|
|
1237 |
black may be contained in the color fields. This needs to
|
|
|
1238 |
be done on all pixel-rows, since even unused color-bytes
|
|
|
1239 |
might generate black */
|
|
|
1240 |
|
|
|
1241 |
misc_vars->is_color_data =
|
|
|
1242 |
do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan],
|
|
|
1243 |
gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct);
|
|
|
1244 |
|
|
|
1245 |
/* dithering the black-plane */
|
|
|
1246 |
FSDlinebw(misc_vars->scan, misc_vars->plane_size,
|
|
|
1247 |
error_values, kP, misc_vars->num_comps, ep, dp);
|
|
|
1248 |
|
|
|
1249 |
/* output the black plane */
|
|
|
1250 |
print_c9plane(prn_stream, 'v', misc_vars->plane_size,
|
|
|
1251 |
data_ptrs->plane_data[misc_vars->scan][3],
|
|
|
1252 |
data_ptrs->plane_data[1 - misc_vars->scan][3],
|
|
|
1253 |
data_ptrs->out_data);
|
|
|
1254 |
|
|
|
1255 |
/* since color resolution is only half of the b/w-resolution,
|
|
|
1256 |
we only output every second row */
|
|
|
1257 |
if (!cdj850->yscal || misc_vars->is_two_pass) {
|
|
|
1258 |
|
|
|
1259 |
int plane_size_c = (*rescale_color_plane[cdj850->xscal][cdj850->yscal])
|
|
|
1260 |
(misc_vars->databuff_size,
|
|
|
1261 |
data_ptrs->data[misc_vars->scan],
|
|
|
1262 |
data_ptrs->data[1 - misc_vars->scan],
|
|
|
1263 |
data_ptrs->data_c[misc_vars->cscan]) / misc_vars->storage_bpp;
|
|
|
1264 |
|
|
|
1265 |
/* dither the color planes */
|
|
|
1266 |
do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
|
|
|
1267 |
misc_vars->plane_size, plane_size_c,
|
|
|
1268 |
misc_vars->num_comps, data_ptrs, pdev, error_values);
|
|
|
1269 |
|
|
|
1270 |
/* Transfer raster graphics in the order C, M, Y, that is
|
|
|
1271 |
planes 2,1,0 */
|
|
|
1272 |
for (i = misc_vars->num_comps - 2; i >= 0; i--) {
|
|
|
1273 |
|
|
|
1274 |
/* output the lower color planes */
|
|
|
1275 |
print_c9plane(prn_stream, plane_code[cdj850->intensities > 2][i],
|
|
|
1276 |
plane_size_c,
|
|
|
1277 |
data_ptrs->plane_data_c[misc_vars->cscan][i],
|
|
|
1278 |
data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
|
|
|
1279 |
data_ptrs->out_data);
|
|
|
1280 |
|
|
|
1281 |
/* output the upper color planes */
|
|
|
1282 |
if (cdj850->intensities > 2) {
|
|
|
1283 |
print_c9plane(prn_stream, plane_code[0][i], plane_size_c,
|
|
|
1284 |
data_ptrs->plane_data_c[misc_vars->cscan][i + 4],
|
|
|
1285 |
data_ptrs->plane_data_c[1 -
|
|
|
1286 |
misc_vars->cscan][i
|
|
|
1287 |
+ 4],
|
|
|
1288 |
data_ptrs->out_data);
|
|
|
1289 |
} /* end cdj850->intensities > 2 */
|
|
|
1290 |
} /* End For i = num_comps */
|
|
|
1291 |
misc_vars->cscan = 1 - misc_vars->cscan;
|
|
|
1292 |
} /* End of is_two_pass */
|
|
|
1293 |
return;
|
|
|
1294 |
}
|
|
|
1295 |
|
|
|
1296 |
/* moved that code into his own subroutine, otherwise things get
|
|
|
1297 |
somewhat clumsy */
|
|
|
1298 |
private void
|
|
|
1299 |
do_floyd_steinberg(int scan, int cscan, int plane_size,
|
|
|
1300 |
int plane_size_c, int n,
|
|
|
1301 |
struct ptr_arrays *data_ptrs,
|
|
|
1302 |
gx_device_printer * pdev,
|
|
|
1303 |
struct error_val_field *error_values)
|
|
|
1304 |
{
|
|
|
1305 |
/* the color pointers */
|
|
|
1306 |
byte *cPa, *mPa, *yPa, *cPb, *mPb, *yPb;
|
|
|
1307 |
byte *dpc;
|
|
|
1308 |
int *epc;
|
|
|
1309 |
|
|
|
1310 |
/* the b/w pointers */
|
|
|
1311 |
byte *kP, *dp;
|
|
|
1312 |
int *ep;
|
|
|
1313 |
|
|
|
1314 |
/* the color pointers, lower byte */
|
|
|
1315 |
cPa = data_ptrs->plane_data_c[cscan + 2][2];
|
|
|
1316 |
mPa = data_ptrs->plane_data_c[cscan + 2][1];
|
|
|
1317 |
yPa = data_ptrs->plane_data_c[cscan + 2][0];
|
|
|
1318 |
/* upper byte */
|
|
|
1319 |
cPb = data_ptrs->plane_data_c[cscan + 2][6];
|
|
|
1320 |
mPb = data_ptrs->plane_data_c[cscan + 2][5];
|
|
|
1321 |
yPb = data_ptrs->plane_data_c[cscan + 2][4];
|
|
|
1322 |
/* data and error */
|
|
|
1323 |
dpc = data_ptrs->data_c[cscan + 2];
|
|
|
1324 |
epc = data_ptrs->errors_c[cscan];
|
|
|
1325 |
/* the b/w pointers */
|
|
|
1326 |
kP = data_ptrs->plane_data[scan + 2][3];
|
|
|
1327 |
dp = data_ptrs->data[scan + 2];
|
|
|
1328 |
ep = data_ptrs->errors[scan];
|
|
|
1329 |
|
|
|
1330 |
switch (cdj850->intensities) {
|
|
|
1331 |
case 2:
|
|
|
1332 |
FSDlinec2(cscan, plane_size_c, error_values,
|
|
|
1333 |
cPa, mPa, yPa, n, dpc, epc);
|
|
|
1334 |
break;
|
|
|
1335 |
case 3:
|
|
|
1336 |
FSDlinec3(cscan, plane_size_c, error_values,
|
|
|
1337 |
cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
|
|
|
1338 |
break;
|
|
|
1339 |
case 4:
|
|
|
1340 |
FSDlinec4(cscan, plane_size_c, error_values,
|
|
|
1341 |
cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc);
|
|
|
1342 |
break;
|
|
|
1343 |
default:
|
|
|
1344 |
assert(0);
|
|
|
1345 |
}
|
|
|
1346 |
return;
|
|
|
1347 |
}
|
|
|
1348 |
|
|
|
1349 |
/* here we do our own gamma-correction */
|
|
|
1350 |
private void
|
|
|
1351 |
do_gamma(float mastergamma, float gammaval, byte values[256])
|
|
|
1352 |
{
|
|
|
1353 |
int i;
|
|
|
1354 |
float gamma;
|
|
|
1355 |
|
|
|
1356 |
if (gammaval > 0.0) {
|
|
|
1357 |
gamma = gammaval;
|
|
|
1358 |
} else {
|
|
|
1359 |
gamma = mastergamma;
|
|
|
1360 |
}
|
|
|
1361 |
|
|
|
1362 |
for (i = 0; i < 256; i++) {
|
|
|
1363 |
values[i] = (byte) (255.0 *
|
|
|
1364 |
(1.0 - pow(((double)(255.0 - (float)i) / 255.0),
|
|
|
1365 |
(double)(1.0 / gamma))));
|
|
|
1366 |
}
|
|
|
1367 |
|
|
|
1368 |
return;
|
|
|
1369 |
}
|
|
|
1370 |
|
|
|
1371 |
/* here we calculate a lookup-table which is used to compensate the
|
|
|
1372 |
relativ loss of color due to undercolor-removal */
|
|
|
1373 |
private void
|
|
|
1374 |
do_black_correction(float kvalue, int kcorrect[256])
|
|
|
1375 |
{
|
|
|
1376 |
int i;
|
|
|
1377 |
|
|
|
1378 |
for (i = 0; i < 256; i++) {
|
|
|
1379 |
kcorrect[i] = (int)
|
|
|
1380 |
(100.0 * kvalue * (
|
|
|
1381 |
pow(10.0,
|
|
|
1382 |
pow((i / 255.0), 3.0)
|
|
|
1383 |
)
|
|
|
1384 |
- 1.0
|
|
|
1385 |
)
|
|
|
1386 |
);
|
|
|
1387 |
}
|
|
|
1388 |
|
|
|
1389 |
return;
|
|
|
1390 |
}
|
|
|
1391 |
|
|
|
1392 |
/* For Better Performance we use a macro here */
|
|
|
1393 |
#define DOUCR(col1, col2, col3, col4)\
|
|
|
1394 |
{\
|
|
|
1395 |
/* determine how far we are from the grey axis. This is */\
|
|
|
1396 |
/* traditionally done by computing MAX(CMY)-MIN(CMY). */\
|
|
|
1397 |
/* However, if two colors are very similar, we could */\
|
|
|
1398 |
/* as either CMYRGB and K. Therefore we calculate the */\
|
|
|
1399 |
/* the distance col1-col2 and col2-col3, and use the */\
|
|
|
1400 |
/* smaller one. */\
|
|
|
1401 |
a = *col1 - *col2;\
|
|
|
1402 |
b = *col2 - *col3;\
|
|
|
1403 |
if (a >= b) {\
|
|
|
1404 |
grey_distance = 1.0 - (b/255.0);\
|
|
|
1405 |
} else {\
|
|
|
1406 |
grey_distance = 1.0 - (a/255.0);\
|
|
|
1407 |
}\
|
|
|
1408 |
ucr = (byte) (*col3 * grey_distance); \
|
|
|
1409 |
*col4 = *col4 + ucr; /* add removed black to black */\
|
|
|
1410 |
/* remove only as much color as black is surviving the */\
|
|
|
1411 |
/* gamma correction */\
|
|
|
1412 |
ucr = *(kvalues + ucr);\
|
|
|
1413 |
*col1 = *col1 - ucr ;\
|
|
|
1414 |
*col2 = *col2 - ucr ;\
|
|
|
1415 |
*col3 = *col3 - ucr ;\
|
|
|
1416 |
}
|
|
|
1417 |
|
|
|
1418 |
/* For Better Performance we use a macro here */
|
|
|
1419 |
#define DOGCR(col1, col2, col3, col4)\
|
|
|
1420 |
{\
|
|
|
1421 |
ucr = (int) *col3;\
|
|
|
1422 |
*col1 -= ucr ;\
|
|
|
1423 |
*col2 -= ucr ;\
|
|
|
1424 |
*col3 -= ucr ;\
|
|
|
1425 |
*col4 += ucr; /* add removed black to black */\
|
|
|
1426 |
kadd = ucr + *(kcorrect + ucr);\
|
|
|
1427 |
uca_fac = 1.0 + (kadd/255.0);\
|
|
|
1428 |
*col1 *= uca_fac;\
|
|
|
1429 |
*col2 *= uca_fac;\
|
|
|
1430 |
}
|
|
|
1431 |
|
|
|
1432 |
/* Since resolution can be different on different planes, we need to
|
|
|
1433 |
do real color separation, here we try a real grey component
|
|
|
1434 |
replacement */
|
|
|
1435 |
private int
|
|
|
1436 |
do_gcr(int bytecount, byte * inbyte, const byte kvalues[256],
|
|
|
1437 |
const byte cvalues[256], const byte mvalues[256],
|
|
|
1438 |
const byte yvalues[256], const int kcorrect[256])
|
|
|
1439 |
{
|
|
|
1440 |
int i, ucr, kadd, is_color = 0;
|
|
|
1441 |
byte *black, *cyan, *magenta, *yellow;
|
|
|
1442 |
float uca_fac;
|
|
|
1443 |
|
|
|
1444 |
/* Grey component replacement */
|
|
|
1445 |
for (i = 0; i < bytecount; i += 4) {
|
|
|
1446 |
black = inbyte++; /* Assign to black the current address of inbyte */
|
|
|
1447 |
cyan = inbyte++;
|
|
|
1448 |
magenta = inbyte++;
|
|
|
1449 |
yellow = inbyte++;
|
|
|
1450 |
|
|
|
1451 |
if (*magenta + *yellow + *cyan > 0) { /* if any color at all */
|
|
|
1452 |
|
|
|
1453 |
is_color = 1;
|
|
|
1454 |
|
|
|
1455 |
if ((*cyan >= *magenta)
|
|
|
1456 |
&& (*magenta >= *yellow)
|
|
|
1457 |
&& (*yellow > 0)) { /* if any grey component */
|
|
|
1458 |
DOGCR(cyan, magenta, yellow, black);
|
|
|
1459 |
} else if ((*cyan >= *yellow)
|
|
|
1460 |
&& (*yellow >= *magenta)
|
|
|
1461 |
&& (*magenta > 0)) {
|
|
|
1462 |
DOGCR(cyan, yellow, magenta, black);
|
|
|
1463 |
} else if ((*yellow >= *magenta)
|
|
|
1464 |
&& (*magenta >= *cyan)
|
|
|
1465 |
&& (*cyan > 0)) {
|
|
|
1466 |
DOGCR(yellow, magenta, cyan, black);
|
|
|
1467 |
} else if ((*yellow >= *cyan)
|
|
|
1468 |
&& (*cyan >= *magenta)
|
|
|
1469 |
&& (*magenta > 0)) {
|
|
|
1470 |
DOGCR(yellow, cyan, magenta, black);
|
|
|
1471 |
} else if ((*magenta >= *yellow)
|
|
|
1472 |
&& (*yellow >= *cyan)
|
|
|
1473 |
&& (*cyan > 0)) {
|
|
|
1474 |
DOGCR(magenta, yellow, cyan, black);
|
|
|
1475 |
} else if ((*magenta >= *cyan)
|
|
|
1476 |
&& (*cyan >= *yellow)
|
|
|
1477 |
&& (*yellow > 0)) {
|
|
|
1478 |
DOGCR(magenta, cyan, yellow, black);
|
|
|
1479 |
} else { /* do gamma only if no black */
|
|
|
1480 |
}
|
|
|
1481 |
*cyan = *(cvalues + *cyan);
|
|
|
1482 |
*magenta = *(mvalues + *magenta);
|
|
|
1483 |
*yellow = *(yvalues + *yellow);
|
|
|
1484 |
} /* end of if c+m+y > 0 */
|
|
|
1485 |
*black = *(kvalues + *black);
|
|
|
1486 |
} /* end of for bytecount */
|
|
|
1487 |
return is_color;
|
|
|
1488 |
}
|
|
|
1489 |
|
|
|
1490 |
/* Since resolution can be different on different planes, we need to
|
|
|
1491 |
rescale the data byte by byte */
|
|
|
1492 |
private int
|
|
|
1493 |
rescale_byte_wise2x2(int bytecount, const byte * inbytea, const byte * inbyteb,
|
|
|
1494 |
byte * outbyte)
|
|
|
1495 |
{
|
|
|
1496 |
register int i, j;
|
|
|
1497 |
int max = bytecount / 2;
|
|
|
1498 |
|
|
|
1499 |
for (i = 0; i < max; i += 4) {
|
|
|
1500 |
j = 2 * i;
|
|
|
1501 |
/* cyan */
|
|
|
1502 |
outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] +
|
|
|
1503 |
inbyteb[j + 5]) / 4;
|
|
|
1504 |
/* magenta */
|
|
|
1505 |
outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] +
|
|
|
1506 |
inbyteb[j + 6]) / 4;
|
|
|
1507 |
/* yellow */
|
|
|
1508 |
outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] +
|
|
|
1509 |
inbyteb[j + 7]) / 4;
|
|
|
1510 |
}
|
|
|
1511 |
return max;
|
|
|
1512 |
}
|
|
|
1513 |
|
|
|
1514 |
/* Since resolution can be different on different planes, we need to
|
|
|
1515 |
rescale the data byte by byte */
|
|
|
1516 |
private int
|
|
|
1517 |
rescale_byte_wise2x1(int bytecount, const byte * inbytea, const byte * inbyteb,
|
|
|
1518 |
byte * outbyte)
|
|
|
1519 |
{
|
|
|
1520 |
register int i, j;
|
|
|
1521 |
int max = bytecount / 2;
|
|
|
1522 |
|
|
|
1523 |
for (i = 0; i < max; i += 4) {
|
|
|
1524 |
j = 2 * i;
|
|
|
1525 |
/* cyan */
|
|
|
1526 |
outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2;
|
|
|
1527 |
/* magenta */
|
|
|
1528 |
outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2;
|
|
|
1529 |
/* yellow */
|
|
|
1530 |
outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2;
|
|
|
1531 |
}
|
|
|
1532 |
return max;
|
|
|
1533 |
}
|
|
|
1534 |
|
|
|
1535 |
/* Since resolution can be different on different planes, we need to
|
|
|
1536 |
rescale the data byte by byte */
|
|
|
1537 |
private int
|
|
|
1538 |
rescale_byte_wise1x2(int bytecount, const byte * inbytea, const byte * inbyteb,
|
|
|
1539 |
byte * outbyte)
|
|
|
1540 |
{
|
|
|
1541 |
register int i;
|
|
|
1542 |
|
|
|
1543 |
for (i = 0; i < bytecount; i += 4) {
|
|
|
1544 |
/* cyan */
|
|
|
1545 |
outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2;
|
|
|
1546 |
/* magenta */
|
|
|
1547 |
outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2;
|
|
|
1548 |
/* yellow */
|
|
|
1549 |
outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2;
|
|
|
1550 |
}
|
|
|
1551 |
return bytecount;
|
|
|
1552 |
}
|
|
|
1553 |
|
|
|
1554 |
/* Since resolution can be different on different planes, we need to
|
|
|
1555 |
rescale the data byte by byte */
|
|
|
1556 |
private int
|
|
|
1557 |
rescale_byte_wise1x1(int bytecount, const byte * inbytea, const byte * inbyteb,
|
|
|
1558 |
byte * outbyte)
|
|
|
1559 |
{
|
|
|
1560 |
register int i;
|
|
|
1561 |
|
|
|
1562 |
for (i = 0; i < bytecount; i += 4) {
|
|
|
1563 |
/* cyan */
|
|
|
1564 |
outbyte[i + 1] = inbytea[i + 1];
|
|
|
1565 |
/* magenta */
|
|
|
1566 |
outbyte[i + 2] = inbytea[i + 2];
|
|
|
1567 |
/* yellow */
|
|
|
1568 |
outbyte[i + 3] = inbytea[i + 3];
|
|
|
1569 |
}
|
|
|
1570 |
return bytecount;
|
|
|
1571 |
}
|
|
|
1572 |
|
|
|
1573 |
/* MACROS FOR DITHERING (we use macros for compact source and faster code) */
|
|
|
1574 |
/* Floyd-Steinberg dithering. Often results in a dramatic improvement in
|
|
|
1575 |
* subjective image quality, but can also produce dramatic increases in
|
|
|
1576 |
* amount of printer data generated and actual printing time!! Mode 9 2D
|
|
|
1577 |
* compression is still useful for fairly flat colour or blank areas but its
|
|
|
1578 |
* compression is much less effective in areas where the dithering has
|
|
|
1579 |
* effectively randomised the dot distribution. */
|
|
|
1580 |
|
|
|
1581 |
#define RSHIFT ((I * 8) - 16)
|
|
|
1582 |
#define SHIFT ((I * 8) - 13)
|
|
|
1583 |
#define MAXVALUE (255 << SHIFT)
|
|
|
1584 |
#define RANDOM (((rand() << RSHIFT) % (MAXVALUE / 2)) - MAXVALUE /4);
|
|
|
1585 |
#define MINVALUE 0
|
|
|
1586 |
#define C 8
|
|
|
1587 |
|
|
|
1588 |
#define THRESHOLD (128 << SHIFT)
|
|
|
1589 |
|
|
|
1590 |
/* --- needed for the hp850 -- */
|
|
|
1591 |
#define SHIFTS ((I * 8) - 14)
|
|
|
1592 |
#define SHIFTM ((I * 8) - 13)
|
|
|
1593 |
#define SHIFTL ((I * 8) - 12)
|
|
|
1594 |
|
|
|
1595 |
#define MAXVALUES (160 << SHIFTM)
|
|
|
1596 |
#define MAXVALUEM (226 << SHIFTM)
|
|
|
1597 |
#define MAXVALUEL (255 << SHIFTM)
|
|
|
1598 |
|
|
|
1599 |
#define THRESHOLDS (128 << SHIFTM)
|
|
|
1600 |
#define THRESHOLDM (192 << SHIFTM)
|
|
|
1601 |
#define THRESHOLDL (226 << SHIFTM)
|
|
|
1602 |
/* --------------------------- */
|
|
|
1603 |
|
|
|
1604 |
/* initialise the error_buffer */
|
|
|
1605 |
private void
|
|
|
1606 |
init_error_buffer(struct misc_struct *misc_vars,
|
|
|
1607 |
struct ptr_arrays *data_ptrs)
|
|
|
1608 |
{
|
|
|
1609 |
int i;
|
|
|
1610 |
int *ep;
|
|
|
1611 |
int *epc;
|
|
|
1612 |
|
|
|
1613 |
ep = data_ptrs->errors[0];
|
|
|
1614 |
epc = data_ptrs->errors_c[0];
|
|
|
1615 |
|
|
|
1616 |
if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error
|
|
|
1617 |
buffer */
|
|
|
1618 |
/* Otherwise, the first dithered rows would look rather uniform */
|
|
|
1619 |
for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */
|
|
|
1620 |
*ep++ = RANDOM;
|
|
|
1621 |
}
|
|
|
1622 |
|
|
|
1623 |
/* Now for the 2 * 300dpi color planes */
|
|
|
1624 |
for (i = 0; i < misc_vars->databuff_size_c; i++) {
|
|
|
1625 |
*epc++ = RANDOM;
|
|
|
1626 |
}
|
|
|
1627 |
}
|
|
|
1628 |
return;
|
|
|
1629 |
}
|
|
|
1630 |
|
|
|
1631 |
#define FSdither(inP, out, errP, Err, Bit, Offset, Element)\
|
|
|
1632 |
{\
|
|
|
1633 |
oldErr = Err;\
|
|
|
1634 |
Err = (*(errP + Element)\
|
|
|
1635 |
+ ((Err * 7 + C) >> 4)\
|
|
|
1636 |
+ ((int)*(inP + Element) << SHIFT));\
|
|
|
1637 |
if (Err > THRESHOLD) {\
|
|
|
1638 |
out |= Bit;\
|
|
|
1639 |
Err -= MAXVALUE;\
|
|
|
1640 |
}\
|
|
|
1641 |
*(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
|
|
|
1642 |
*(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
|
|
|
1643 |
}
|
|
|
1644 |
|
|
|
1645 |
/* The hp850c has 600dpi black and 300 dpi color. Therefore, we need
|
|
|
1646 |
an adapted dither algorythm */
|
|
|
1647 |
private void
|
|
|
1648 |
FSDlinebw(int scan, int plane_size,
|
|
|
1649 |
struct error_val_field *error_values,
|
|
|
1650 |
byte * kP, int n, int *ep, byte * dp)
|
|
|
1651 |
{
|
|
|
1652 |
if (scan == 0) { /* going_up */
|
|
|
1653 |
byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the
|
|
|
1654 |
|
|
|
1655 |
bit to be set within k */
|
|
|
1656 |
int oldErr, i;
|
|
|
1657 |
|
|
|
1658 |
for (i = 0; i < plane_size; i++) {
|
|
|
1659 |
bitmask = 0x80;
|
|
|
1660 |
for (k = 0; bitmask != 0; bitmask >>= 1) {
|
|
|
1661 |
/* dp points to the first word of the input data which is in
|
|
|
1662 |
kcmy-format */
|
|
|
1663 |
/* k points to the beginning of the first outbut byte, which
|
|
|
1664 |
is filled up, bit by bit while looping over bytemask */
|
|
|
1665 |
/* ep points to the first word of the error-plane which
|
|
|
1666 |
contains the errors kcmy format */
|
|
|
1667 |
/* err_values->k tempararily holds the error-value */
|
|
|
1668 |
/* bitmask selects the bit to be set in the outbyte */
|
|
|
1669 |
/* n gives the offset for the byte selection within
|
|
|
1670 |
words. With simple cmyk-printing, this should be 4 */
|
|
|
1671 |
/* 0 points to the active color within the input-word, i.e. 0
|
|
|
1672 |
= black, 1 = cyan, 2 = yellow, 3 = magenta */
|
|
|
1673 |
|
|
|
1674 |
FSdither(dp, k, ep, error_values->k, bitmask, -n, 0);
|
|
|
1675 |
dp += n, ep += n; /* increment the input and error pointer one
|
|
|
1676 |
word (=4 byte) further, in order to
|
|
|
1677 |
convert the next word into an bit */
|
|
|
1678 |
}
|
|
|
1679 |
*kP++ = k; /* fill the output-plane byte with the computet byte
|
|
|
1680 |
and increment the output plane pointer one byte */
|
|
|
1681 |
}
|
|
|
1682 |
|
|
|
1683 |
} else { /* going_down */
|
|
|
1684 |
byte k, bitmask;
|
|
|
1685 |
int oldErr, i;
|
|
|
1686 |
|
|
|
1687 |
for (i = 0; i < plane_size; i++) {
|
|
|
1688 |
bitmask = 0x01;
|
|
|
1689 |
for (k = 0; bitmask != 0; bitmask <<= 1) {
|
|
|
1690 |
dp -= n, ep -= n;
|
|
|
1691 |
FSdither(dp, k, ep, error_values->k, bitmask, n, 0);
|
|
|
1692 |
}
|
|
|
1693 |
*--kP = k;
|
|
|
1694 |
}
|
|
|
1695 |
}
|
|
|
1696 |
return;
|
|
|
1697 |
}
|
|
|
1698 |
|
|
|
1699 |
/* Since bw has already been dithered for the hp850c, we need
|
|
|
1700 |
an adapted dither algorythm */
|
|
|
1701 |
private void
|
|
|
1702 |
FSDlinec2(int scan, int plane_size,
|
|
|
1703 |
struct error_val_field *error_values,
|
|
|
1704 |
byte * cPa, byte * mPa, byte * yPa, int n,
|
|
|
1705 |
byte * dp, int *ep)
|
|
|
1706 |
{
|
|
|
1707 |
if (scan == 0) { /* going_up */
|
|
|
1708 |
int oldErr, i;
|
|
|
1709 |
byte ca, ya, ma, bitmask;
|
|
|
1710 |
|
|
|
1711 |
for (i = 0; i < plane_size; i++) {
|
|
|
1712 |
bitmask = 0x80;
|
|
|
1713 |
ca = ya = ma = 0;
|
|
|
1714 |
for (ca = 0; bitmask != 0; bitmask >>= 1) {
|
|
|
1715 |
FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3);
|
|
|
1716 |
FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2);
|
|
|
1717 |
FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1);
|
|
|
1718 |
dp += n, ep += n;
|
|
|
1719 |
}
|
|
|
1720 |
*cPa++ = ca;
|
|
|
1721 |
*mPa++ = ma;
|
|
|
1722 |
*yPa++ = ya;
|
|
|
1723 |
}
|
|
|
1724 |
|
|
|
1725 |
} else { /* going_down */
|
|
|
1726 |
byte ca, ya, ma, bitmask;
|
|
|
1727 |
int oldErr, i;
|
|
|
1728 |
|
|
|
1729 |
for (i = 0; i < plane_size; i++) {
|
|
|
1730 |
bitmask = 0x01;
|
|
|
1731 |
ca = ya = ma = 0;
|
|
|
1732 |
for (ca = 0; bitmask != 0; bitmask <<= 1) {
|
|
|
1733 |
dp -= n, ep -= n;
|
|
|
1734 |
FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1);
|
|
|
1735 |
FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2);
|
|
|
1736 |
FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3);
|
|
|
1737 |
}
|
|
|
1738 |
*--yPa = ya;
|
|
|
1739 |
*--mPa = ma;
|
|
|
1740 |
*--cPa = ca;
|
|
|
1741 |
}
|
|
|
1742 |
}
|
|
|
1743 |
return;
|
|
|
1744 |
}
|
|
|
1745 |
|
|
|
1746 |
/* while printing on paper, we only use 3 -intensities */
|
|
|
1747 |
#define FSdither8503(inP, outa, outb, errP, Err, Bit, Offset, Element)\
|
|
|
1748 |
{\
|
|
|
1749 |
oldErr = Err;\
|
|
|
1750 |
Err = (*(errP + Element)\
|
|
|
1751 |
+ ((Err * 7 + C) >> 4)\
|
|
|
1752 |
+ ((int) *(inP + Element) << SHIFT));\
|
|
|
1753 |
if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
|
|
|
1754 |
outa |= Bit;\
|
|
|
1755 |
Err -= MAXVALUES;\
|
|
|
1756 |
}\
|
|
|
1757 |
if (Err > THRESHOLDM) {\
|
|
|
1758 |
outb |= Bit;\
|
|
|
1759 |
Err -= MAXVALUEM;\
|
|
|
1760 |
}\
|
|
|
1761 |
*(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
|
|
|
1762 |
*(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
|
|
|
1763 |
}
|
|
|
1764 |
|
|
|
1765 |
/* On ordinary paper, we'll only use 3 intensities with the hp850 */
|
|
|
1766 |
private void
|
|
|
1767 |
FSDlinec3(int scan, int plane_size,
|
|
|
1768 |
struct error_val_field *error_values,
|
|
|
1769 |
byte * cPa, byte * mPa, byte * yPa,
|
|
|
1770 |
byte * cPb, byte * mPb, byte * yPb,
|
|
|
1771 |
int n, byte * dp, int *ep)
|
|
|
1772 |
{
|
|
|
1773 |
if (scan == 0) { /* going_up */
|
|
|
1774 |
byte ca, ya, ma, cb, yb, mb, bitmask;
|
|
|
1775 |
int oldErr, i;
|
|
|
1776 |
|
|
|
1777 |
for (i = 0; i < plane_size; i++) {
|
|
|
1778 |
bitmask = 0x80;
|
|
|
1779 |
ca = ya = ma = cb = yb = mb = 0;
|
|
|
1780 |
for (ca = 0; bitmask != 0; bitmask >>= 1) {
|
|
|
1781 |
FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, -n, n
|
|
|
1782 |
- 3);
|
|
|
1783 |
FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, -n, n
|
|
|
1784 |
- 2);
|
|
|
1785 |
FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, -n, n
|
|
|
1786 |
- 1);
|
|
|
1787 |
dp += n, ep += n;
|
|
|
1788 |
}
|
|
|
1789 |
*cPa++ = ca;
|
|
|
1790 |
*mPa++ = ma;
|
|
|
1791 |
*yPa++ = ya;
|
|
|
1792 |
*cPb++ = cb;
|
|
|
1793 |
*mPb++ = mb;
|
|
|
1794 |
*yPb++ = yb;
|
|
|
1795 |
}
|
|
|
1796 |
} else { /* going_down */
|
|
|
1797 |
byte ca, ya, ma, cb, yb, mb, bitmask;
|
|
|
1798 |
int oldErr, i;
|
|
|
1799 |
|
|
|
1800 |
for (i = 0; i < plane_size; i++) {
|
|
|
1801 |
bitmask = 0x01;
|
|
|
1802 |
ca = ya = ma = cb = yb = mb = 0;
|
|
|
1803 |
for (ca = 0; bitmask != 0; bitmask <<= 1) {
|
|
|
1804 |
dp -= n, ep -= n;
|
|
|
1805 |
FSdither8503(dp, ya, yb, ep, error_values->y, bitmask, n, n
|
|
|
1806 |
- 1);
|
|
|
1807 |
FSdither8503(dp, ma, mb, ep, error_values->m, bitmask, n, n
|
|
|
1808 |
- 2);
|
|
|
1809 |
FSdither8503(dp, ca, cb, ep, error_values->c, bitmask, n, n
|
|
|
1810 |
- 3);
|
|
|
1811 |
}
|
|
|
1812 |
*--yPa = ya;
|
|
|
1813 |
*--mPa = ma;
|
|
|
1814 |
*--cPa = ca;
|
|
|
1815 |
*--yPb = yb;
|
|
|
1816 |
*--mPb = mb;
|
|
|
1817 |
*--cPb = cb;
|
|
|
1818 |
}
|
|
|
1819 |
}
|
|
|
1820 |
return;
|
|
|
1821 |
}
|
|
|
1822 |
|
|
|
1823 |
|
|
|
1824 |
/* the hp850 knows about 4 different color intensities per color */
|
|
|
1825 |
#define FSdither8504(inP, outa, outb, errP, Err, Bit, Offset, Element)\
|
|
|
1826 |
{\
|
|
|
1827 |
oldErr = Err;\
|
|
|
1828 |
Err = (*(errP + Element)\
|
|
|
1829 |
+ ((Err * 7 + C) >> 4)\
|
|
|
1830 |
+ ((int) *(inP + Element) << SHIFT));\
|
|
|
1831 |
if ((Err > THRESHOLDS) && (Err <= THRESHOLDM)) {\
|
|
|
1832 |
outa |= Bit;\
|
|
|
1833 |
Err -= MAXVALUES;\
|
|
|
1834 |
}\
|
|
|
1835 |
if ((Err > THRESHOLDM) && (Err <= THRESHOLDL)) {\
|
|
|
1836 |
outb |= Bit;\
|
|
|
1837 |
Err -= MAXVALUEM;\
|
|
|
1838 |
}\
|
|
|
1839 |
if (Err > THRESHOLDL) {\
|
|
|
1840 |
outa |= Bit;\
|
|
|
1841 |
outb |= Bit;\
|
|
|
1842 |
Err -= MAXVALUEL;\
|
|
|
1843 |
}\
|
|
|
1844 |
*(errP + (Element + Offset)) += ((Err * 3 + C) >> 4);\
|
|
|
1845 |
*(errP + Element) = ((Err * 5 + oldErr + C) >> 4);\
|
|
|
1846 |
}
|
|
|
1847 |
|
|
|
1848 |
/* The hp850c knows about 4 intensity levels per color. Once more, we need
|
|
|
1849 |
an adapted dither algorythm */
|
|
|
1850 |
private void
|
|
|
1851 |
FSDlinec4(int scan, int plane_size,
|
|
|
1852 |
struct error_val_field *error_values,
|
|
|
1853 |
byte * cPa, byte * mPa, byte * yPa,
|
|
|
1854 |
byte * cPb, byte * mPb, byte * yPb,
|
|
|
1855 |
int n, byte * dp, int *ep)
|
|
|
1856 |
{
|
|
|
1857 |
if (scan == 0) { /* going_up */
|
|
|
1858 |
byte ca, ya, ma, cb, yb, mb, bitmask;
|
|
|
1859 |
int oldErr, i;
|
|
|
1860 |
|
|
|
1861 |
for (i = 0; i < plane_size; i++) {
|
|
|
1862 |
bitmask = 0x80;
|
|
|
1863 |
ca = ya = ma = cb = yb = mb = 0;
|
|
|
1864 |
for (ca = 0; bitmask != 0; bitmask >>= 1) {
|
|
|
1865 |
FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, -n, n
|
|
|
1866 |
- 3);
|
|
|
1867 |
FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, -n, n
|
|
|
1868 |
- 2);
|
|
|
1869 |
FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, -n, n
|
|
|
1870 |
- 1);
|
|
|
1871 |
dp += n, ep += n;
|
|
|
1872 |
}
|
|
|
1873 |
*cPa++ = ca;
|
|
|
1874 |
*mPa++ = ma;
|
|
|
1875 |
*yPa++ = ya;
|
|
|
1876 |
*cPb++ = cb;
|
|
|
1877 |
*mPb++ = mb;
|
|
|
1878 |
*yPb++ = yb;
|
|
|
1879 |
}
|
|
|
1880 |
} else { /* going_down */
|
|
|
1881 |
byte ca, ya, ma, cb, yb, mb, bitmask;
|
|
|
1882 |
int oldErr, i;
|
|
|
1883 |
|
|
|
1884 |
for (i = 0; i < plane_size; i++) {
|
|
|
1885 |
bitmask = 0x01;
|
|
|
1886 |
ca = ya = ma = cb = yb = mb = 0;
|
|
|
1887 |
for (ca = 0; bitmask != 0; bitmask <<= 1) {
|
|
|
1888 |
dp -= n, ep -= n;
|
|
|
1889 |
FSdither8504(dp, ya, yb, ep, error_values->y, bitmask, n, n
|
|
|
1890 |
- 1);
|
|
|
1891 |
FSdither8504(dp, ma, mb, ep, error_values->m, bitmask, n, n
|
|
|
1892 |
- 2);
|
|
|
1893 |
FSdither8504(dp, ca, cb, ep, error_values->c, bitmask, n, n
|
|
|
1894 |
- 3);
|
|
|
1895 |
}
|
|
|
1896 |
*--yPa = ya;
|
|
|
1897 |
*--mPa = ma;
|
|
|
1898 |
*--cPa = ca;
|
|
|
1899 |
*--yPb = yb;
|
|
|
1900 |
*--mPb = mb;
|
|
|
1901 |
*--cPb = cb;
|
|
|
1902 |
}
|
|
|
1903 |
}
|
|
|
1904 |
return;
|
|
|
1905 |
}
|
|
|
1906 |
|
|
|
1907 |
|
|
|
1908 |
/* calculate the needed memory */
|
|
|
1909 |
private void
|
|
|
1910 |
calculate_memory_size(gx_device_printer * pdev,
|
|
|
1911 |
struct misc_struct *misc_vars)
|
|
|
1912 |
{
|
|
|
1913 |
int xfac = cdj850->xscal ? 2 : 1;
|
|
|
1914 |
|
|
|
1915 |
misc_vars->line_size = gdev_prn_raster(pdev);
|
|
|
1916 |
misc_vars->line_size_c = misc_vars->line_size / xfac;
|
|
|
1917 |
misc_vars->line_size_words = (misc_vars->line_size + W - 1) / W;
|
|
|
1918 |
misc_vars->paper_size = gdev_pcl_paper_size((gx_device *) pdev);
|
|
|
1919 |
misc_vars->num_comps = pdev->color_info.num_components;
|
|
|
1920 |
misc_vars->bits_per_pixel = pdev->color_info.depth;
|
|
|
1921 |
misc_vars->storage_bpp = misc_vars->num_comps * 8;
|
|
|
1922 |
misc_vars->expanded_bpp = misc_vars->num_comps * 8;
|
|
|
1923 |
misc_vars->errbuff_size = 0;
|
|
|
1924 |
misc_vars->errbuff_size_c = 0;
|
|
|
1925 |
|
|
|
1926 |
misc_vars->plane_size = calc_buffsize(misc_vars->line_size, misc_vars->storage_bpp);
|
|
|
1927 |
|
|
|
1928 |
/* plane_size_c is dependedend on the bits used for
|
|
|
1929 |
dithering. Currently 2 bits are sufficient */
|
|
|
1930 |
misc_vars->plane_size_c = 2 * misc_vars->plane_size / xfac;
|
|
|
1931 |
|
|
|
1932 |
/* 4n extra values for line ends */
|
|
|
1933 |
/* might be wrong, see gdevcdj.c */
|
|
|
1934 |
misc_vars->errbuff_size =
|
|
|
1935 |
calc_buffsize((misc_vars->plane_size * misc_vars->expanded_bpp +
|
|
|
1936 |
misc_vars->num_comps * 4) * I, 1);
|
|
|
1937 |
|
|
|
1938 |
/* 4n extra values for line ends */
|
|
|
1939 |
misc_vars->errbuff_size_c =
|
|
|
1940 |
calc_buffsize((misc_vars->plane_size_c / 2 * misc_vars->expanded_bpp
|
|
|
1941 |
+ misc_vars->num_comps * 4) * I, 1);
|
|
|
1942 |
|
|
|
1943 |
misc_vars->databuff_size =
|
|
|
1944 |
misc_vars->plane_size * misc_vars->storage_bpp;
|
|
|
1945 |
|
|
|
1946 |
misc_vars->databuff_size_c =
|
|
|
1947 |
misc_vars->plane_size_c / 2 * misc_vars->storage_bpp;
|
|
|
1948 |
|
|
|
1949 |
|
|
|
1950 |
misc_vars->outbuff_size = misc_vars->plane_size * 4;
|
|
|
1951 |
|
|
|
1952 |
misc_vars->storage_size_words = (((misc_vars->plane_size)
|
|
|
1953 |
* 2
|
|
|
1954 |
* misc_vars->num_comps)
|
|
|
1955 |
+ misc_vars->databuff_size
|
|
|
1956 |
+ misc_vars->errbuff_size
|
|
|
1957 |
+ misc_vars->outbuff_size
|
|
|
1958 |
+ ((misc_vars->plane_size_c)
|
|
|
1959 |
* 2
|
|
|
1960 |
* misc_vars->num_comps)
|
|
|
1961 |
+ misc_vars->databuff_size_c
|
|
|
1962 |
+ misc_vars->errbuff_size_c
|
|
|
1963 |
+ (4 * misc_vars->plane_size_c))
|
|
|
1964 |
/ W;
|
|
|
1965 |
|
|
|
1966 |
return;
|
|
|
1967 |
}
|
|
|
1968 |
|
|
|
1969 |
|
|
|
1970 |
/* Initialise the needed pointers */
|
|
|
1971 |
private void
|
|
|
1972 |
init_data_structure(gx_device_printer * pdev,
|
|
|
1973 |
struct ptr_arrays *data_ptrs,
|
|
|
1974 |
struct misc_struct *misc_vars)
|
|
|
1975 |
{
|
|
|
1976 |
int i;
|
|
|
1977 |
byte *p = (byte *) data_ptrs->storage;
|
|
|
1978 |
|
|
|
1979 |
misc_vars->scan = 0;
|
|
|
1980 |
misc_vars->cscan = 0;
|
|
|
1981 |
misc_vars->is_two_pass = 1;
|
|
|
1982 |
|
|
|
1983 |
/* the b/w pointer */
|
|
|
1984 |
data_ptrs->data[0] = data_ptrs->data[1] = data_ptrs->data[2] = p;
|
|
|
1985 |
data_ptrs->data[3] = p + misc_vars->databuff_size;
|
|
|
1986 |
/* Note: The output data will overwrite part of the input-data */
|
|
|
1987 |
|
|
|
1988 |
if (misc_vars->bits_per_pixel > 1) {
|
|
|
1989 |
p += misc_vars->databuff_size;
|
|
|
1990 |
}
|
|
|
1991 |
if (misc_vars->bits_per_pixel > 4) {
|
|
|
1992 |
data_ptrs->errors[0] = (int *)p + misc_vars->num_comps * 2;
|
|
|
1993 |
data_ptrs->errors[1] = data_ptrs->errors[0] + misc_vars->databuff_size;
|
|
|
1994 |
p += misc_vars->errbuff_size;
|
|
|
1995 |
}
|
|
|
1996 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
1997 |
data_ptrs->plane_data[0][i] = data_ptrs->plane_data[2][i] = p;
|
|
|
1998 |
p += misc_vars->plane_size;
|
|
|
1999 |
}
|
|
|
2000 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2001 |
data_ptrs->plane_data[1][i] = p;
|
|
|
2002 |
data_ptrs->plane_data[3][i] = p + misc_vars->plane_size;
|
|
|
2003 |
p += misc_vars->plane_size;
|
|
|
2004 |
}
|
|
|
2005 |
data_ptrs->out_data = p;
|
|
|
2006 |
p += misc_vars->outbuff_size;
|
|
|
2007 |
|
|
|
2008 |
/* ---------------------------------------------------------
|
|
|
2009 |
now for the color pointers
|
|
|
2010 |
--------------------------------------------------------- */
|
|
|
2011 |
|
|
|
2012 |
data_ptrs->data_c[0] = data_ptrs->data_c[1] = data_ptrs->data_c[2] = p;
|
|
|
2013 |
data_ptrs->data_c[3] = p + misc_vars->databuff_size_c;
|
|
|
2014 |
/* Note: The output data will overwrite part of the input-data */
|
|
|
2015 |
|
|
|
2016 |
if (misc_vars->bits_per_pixel > 1) {
|
|
|
2017 |
p += misc_vars->databuff_size_c;
|
|
|
2018 |
}
|
|
|
2019 |
if (misc_vars->bits_per_pixel > 4) {
|
|
|
2020 |
data_ptrs->errors_c[0] = (int *)p + misc_vars->num_comps * 2;
|
|
|
2021 |
data_ptrs->errors_c[1] = data_ptrs->errors_c[0] + misc_vars->databuff_size_c;
|
|
|
2022 |
p += misc_vars->errbuff_size_c;
|
|
|
2023 |
}
|
|
|
2024 |
/* pointer for the lower bits of the output data */
|
|
|
2025 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2026 |
data_ptrs->plane_data_c[0][i] = data_ptrs->plane_data_c[2][i] = p;
|
|
|
2027 |
p += misc_vars->plane_size_c / 2;
|
|
|
2028 |
}
|
|
|
2029 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2030 |
data_ptrs->plane_data_c[1][i] = p;
|
|
|
2031 |
data_ptrs->plane_data_c[3][i] = p + misc_vars->plane_size_c / 2;
|
|
|
2032 |
p += misc_vars->plane_size_c / 2;
|
|
|
2033 |
}
|
|
|
2034 |
|
|
|
2035 |
/* pointer for the upper bits of the output data */
|
|
|
2036 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2037 |
data_ptrs->plane_data_c[0][i + 4] = data_ptrs->plane_data_c[2][i +
|
|
|
2038 |
4] = p;
|
|
|
2039 |
p += misc_vars->plane_size_c / 2;
|
|
|
2040 |
}
|
|
|
2041 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2042 |
data_ptrs->plane_data_c[1][i + 4] = p;
|
|
|
2043 |
data_ptrs->plane_data_c[3][i + 4] = p + misc_vars->plane_size_c / 2;
|
|
|
2044 |
p += misc_vars->plane_size_c / 2;
|
|
|
2045 |
}
|
|
|
2046 |
|
|
|
2047 |
for (i = 0; i < misc_vars->num_comps; i++) {
|
|
|
2048 |
data_ptrs->test_data[i] = p;
|
|
|
2049 |
p += misc_vars->plane_size_c / 2;
|
|
|
2050 |
}
|
|
|
2051 |
|
|
|
2052 |
/* Clear temp storage */
|
|
|
2053 |
memset(data_ptrs->storage, 0, misc_vars->storage_size_words * W);
|
|
|
2054 |
|
|
|
2055 |
return;
|
|
|
2056 |
} /* end init_data_structure */
|
|
|
2057 |
|
|
|
2058 |
/* Configure the printer and start Raster mode */
|
|
|
2059 |
private void
|
|
|
2060 |
cdj850_start_raster_mode(gx_device_printer * pdev, int paper_size,
|
|
|
2061 |
FILE * prn_stream)
|
|
|
2062 |
{
|
|
|
2063 |
int xres, yres; /* x,y resolution for color planes */
|
|
|
2064 |
hp850_cmyk_init_t init;
|
|
|
2065 |
|
|
|
2066 |
init = hp850_cmyk_init;
|
|
|
2067 |
init.a[13] = cdj850->intensities; /* Intensity levels cyan */
|
|
|
2068 |
init.a[19] = cdj850->intensities; /* Intensity levels magenta */
|
|
|
2069 |
init.a[25] = cdj850->intensities; /* Intensity levels yellow */
|
|
|
2070 |
|
|
|
2071 |
/* black plane resolution */
|
|
|
2072 |
assign_dpi(cdj850->x_pixels_per_inch, init.a + 2);
|
|
|
2073 |
assign_dpi(cdj850->y_pixels_per_inch, init.a + 4);
|
|
|
2074 |
/* color plane resolution */
|
|
|
2075 |
xres = cdj850->x_pixels_per_inch / (cdj850->xscal + 1);
|
|
|
2076 |
yres = cdj850->y_pixels_per_inch / (cdj850->yscal + 1);
|
|
|
2077 |
/* cyan */
|
|
|
2078 |
assign_dpi(xres, init.a + 8);
|
|
|
2079 |
assign_dpi(yres, init.a + 10);
|
|
|
2080 |
/* magenta */
|
|
|
2081 |
assign_dpi(xres, init.a + 14);
|
|
|
2082 |
assign_dpi(yres, init.a + 16);
|
|
|
2083 |
/* yellow */
|
|
|
2084 |
assign_dpi(xres, init.a + 20);
|
|
|
2085 |
assign_dpi(yres, init.a + 22);
|
|
|
2086 |
|
|
|
2087 |
fputs("\033*rbC", prn_stream); /* End raster graphics */
|
|
|
2088 |
fputs("\033E", prn_stream); /* Reset */
|
|
|
2089 |
/* Page size, orientation, top margin & perforation skip */
|
|
|
2090 |
fprintf(prn_stream, "\033&l%daolE", paper_size);
|
|
|
2091 |
|
|
|
2092 |
/* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
|
|
|
2093 |
fprintf(prn_stream, "\033*o%dM", cdj850->quality);
|
|
|
2094 |
/* Media Type,0 = plain paper, 1 = bond paper, 2 = special
|
|
|
2095 |
paper, 3 = glossy film, 4 = transparency film */
|
|
|
2096 |
fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
|
|
|
2097 |
|
|
|
2098 |
/* Move to top left of printed area */
|
|
|
2099 |
fprintf(prn_stream, "\033*p%dY", (int)(600 * DOFFSET));
|
|
|
2100 |
|
|
|
2101 |
/* This will start and configure the raster-mode */
|
|
|
2102 |
fprintf(prn_stream, "\033*g%dW", (int)sizeof(init.a)); /* The new configure
|
|
|
2103 |
raster data comand */
|
|
|
2104 |
fwrite(init.a, sizeof(byte), sizeof(init.a),
|
|
|
2105 |
prn_stream); /* Transmit config
|
|
|
2106 |
data */
|
|
|
2107 |
/* From now on, all escape commands start with \033*b, so we
|
|
|
2108 |
* combine them (if the printer supports this). */
|
|
|
2109 |
fputs("\033*b", prn_stream);
|
|
|
2110 |
/* Set compression if the mode has been defined. */
|
|
|
2111 |
if (cdj850->compression)
|
|
|
2112 |
fprintf(prn_stream, "%dm", cdj850->compression);
|
|
|
2113 |
|
|
|
2114 |
return;
|
|
|
2115 |
} /* end configure raster-mode */
|
|
|
2116 |
|
|
|
2117 |
private int
|
|
|
2118 |
cdj_put_param_int(gs_param_list * plist, gs_param_name pname, int *pvalue,
|
|
|
2119 |
int minval, int maxval, int ecode)
|
|
|
2120 |
{
|
|
|
2121 |
int code, value;
|
|
|
2122 |
|
|
|
2123 |
switch (code = param_read_int(plist, pname, &value)) {
|
|
|
2124 |
default:
|
|
|
2125 |
return code;
|
|
|
2126 |
case 1:
|
|
|
2127 |
return ecode;
|
|
|
2128 |
case 0:
|
|
|
2129 |
if (value < minval || value > maxval)
|
|
|
2130 |
param_signal_error(plist, pname, gs_error_rangecheck);
|
|
|
2131 |
*pvalue = value;
|
|
|
2132 |
return (ecode < 0 ? ecode : 1);
|
|
|
2133 |
}
|
|
|
2134 |
}
|
|
|
2135 |
|
|
|
2136 |
private int
|
|
|
2137 |
cdj_put_param_float(gs_param_list * plist, gs_param_name pname, float *pvalue,
|
|
|
2138 |
float minval, float maxval, int ecode)
|
|
|
2139 |
{
|
|
|
2140 |
int code;
|
|
|
2141 |
float value;
|
|
|
2142 |
|
|
|
2143 |
switch (code = param_read_float(plist, pname, &value)) {
|
|
|
2144 |
default:
|
|
|
2145 |
return code;
|
|
|
2146 |
case 1:
|
|
|
2147 |
return ecode;
|
|
|
2148 |
case 0:
|
|
|
2149 |
if (value < minval || value > maxval)
|
|
|
2150 |
param_signal_error(plist, pname, gs_error_rangecheck);
|
|
|
2151 |
*pvalue = value;
|
|
|
2152 |
return (ecode < 0 ? ecode : 1);
|
|
|
2153 |
}
|
|
|
2154 |
}
|
|
|
2155 |
|
|
|
2156 |
private int
|
|
|
2157 |
cdj_set_bpp(gx_device * pdev, int bpp, int ccomps)
|
|
|
2158 |
{
|
|
|
2159 |
gx_device_color_info *ci = &pdev->color_info;
|
|
|
2160 |
|
|
|
2161 |
if (ccomps && bpp == 0) {
|
|
|
2162 |
if (cprn_device->cmyk) {
|
|
|
2163 |
switch (ccomps) {
|
|
|
2164 |
default:
|
|
|
2165 |
return gs_error_rangecheck;
|
|
|
2166 |
/*NOTREACHED */
|
|
|
2167 |
break;
|
|
|
2168 |
|
|
|
2169 |
case 1:
|
|
|
2170 |
bpp = 1;
|
|
|
2171 |
break;
|
|
|
2172 |
|
|
|
2173 |
case 3:
|
|
|
2174 |
bpp = 24;
|
|
|
2175 |
break;
|
|
|
2176 |
|
|
|
2177 |
case 4:
|
|
|
2178 |
switch (ci->depth) {
|
|
|
2179 |
case 8:
|
|
|
2180 |
case 16:
|
|
|
2181 |
case 24:
|
|
|
2182 |
case 32:
|
|
|
2183 |
break;
|
|
|
2184 |
|
|
|
2185 |
default:
|
|
|
2186 |
bpp = cprn_device->default_depth;
|
|
|
2187 |
break;
|
|
|
2188 |
}
|
|
|
2189 |
break;
|
|
|
2190 |
}
|
|
|
2191 |
}
|
|
|
2192 |
}
|
|
|
2193 |
if (bpp == 0) {
|
|
|
2194 |
bpp = ci->depth; /* Use the current setting. */
|
|
|
2195 |
}
|
|
|
2196 |
if (cprn_device->cmyk < 0) {
|
|
|
2197 |
|
|
|
2198 |
/* Reset procedures because we may have been in another mode. */
|
|
|
2199 |
|
|
|
2200 |
dev_proc(pdev, map_cmyk_color) = gdev_cmyk_map_cmyk_color;
|
|
|
2201 |
dev_proc(pdev, map_rgb_color) = NULL;
|
|
|
2202 |
dev_proc(pdev, map_color_rgb) = gdev_cmyk_map_color_rgb;
|
|
|
2203 |
|
|
|
2204 |
if (pdev->is_open)
|
|
|
2205 |
gs_closedevice(pdev);
|
|
|
2206 |
}
|
|
|
2207 |
/* Check for valid bpp values */
|
|
|
2208 |
|
|
|
2209 |
switch (bpp) {
|
|
|
2210 |
case 16:
|
|
|
2211 |
case 32:
|
|
|
2212 |
if (cprn_device->cmyk && ccomps && ccomps != 4)
|
|
|
2213 |
goto bppe;
|
|
|
2214 |
break;
|
|
|
2215 |
|
|
|
2216 |
case 24:
|
|
|
2217 |
if (!cprn_device->cmyk || ccomps == 0 || ccomps == 4) {
|
|
|
2218 |
break;
|
|
|
2219 |
} else if (ccomps == 1) {
|
|
|
2220 |
goto bppe;
|
|
|
2221 |
} else {
|
|
|
2222 |
|
|
|
2223 |
/* 3 components 24 bpp printing for CMYK device. */
|
|
|
2224 |
|
|
|
2225 |
cprn_device->cmyk = -1;
|
|
|
2226 |
}
|
|
|
2227 |
break;
|
|
|
2228 |
|
|
|
2229 |
case 8:
|
|
|
2230 |
if (cprn_device->cmyk) {
|
|
|
2231 |
if (ccomps) {
|
|
|
2232 |
if (ccomps == 3) {
|
|
|
2233 |
cprn_device->cmyk = -1;
|
|
|
2234 |
bpp = 3;
|
|
|
2235 |
} else if (ccomps != 1 && ccomps != 4) {
|
|
|
2236 |
goto bppe;
|
|
|
2237 |
}
|
|
|
2238 |
}
|
|
|
2239 |
if (ccomps != 1)
|
|
|
2240 |
break;
|
|
|
2241 |
} else {
|
|
|
2242 |
break;
|
|
|
2243 |
}
|
|
|
2244 |
|
|
|
2245 |
case 1:
|
|
|
2246 |
if (ccomps != 1)
|
|
|
2247 |
goto bppe;
|
|
|
2248 |
|
|
|
2249 |
if (cprn_device->cmyk && bpp != pdev->color_info.depth) {
|
|
|
2250 |
dev_proc(pdev, map_cmyk_color) = NULL;
|
|
|
2251 |
dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color;
|
|
|
2252 |
|
|
|
2253 |
if (pdev->is_open) {
|
|
|
2254 |
gs_closedevice(pdev);
|
|
|
2255 |
}
|
|
|
2256 |
}
|
|
|
2257 |
break;
|
|
|
2258 |
|
|
|
2259 |
case 3:
|
|
|
2260 |
if (!cprn_device->cmyk) {
|
|
|
2261 |
break;
|
|
|
2262 |
}
|
|
|
2263 |
default:
|
|
|
2264 |
bppe:return gs_error_rangecheck;
|
|
|
2265 |
}
|
|
|
2266 |
|
|
|
2267 |
|
|
|
2268 |
if (cprn_device->cmyk == -1) {
|
|
|
2269 |
dev_proc(pdev, map_cmyk_color) = NULL;
|
|
|
2270 |
dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color;
|
|
|
2271 |
dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb;
|
|
|
2272 |
|
|
|
2273 |
if (pdev->is_open) {
|
|
|
2274 |
gs_closedevice(pdev);
|
|
|
2275 |
}
|
|
|
2276 |
}
|
|
|
2277 |
switch (ccomps) {
|
|
|
2278 |
case 0:
|
|
|
2279 |
break;
|
|
|
2280 |
|
|
|
2281 |
case 1:
|
|
|
2282 |
if (bpp != 1 && bpp != 8)
|
|
|
2283 |
goto cce;
|
|
|
2284 |
break;
|
|
|
2285 |
|
|
|
2286 |
case 4:
|
|
|
2287 |
if (cprn_device->cmyk) {
|
|
|
2288 |
if (bpp >= 8)
|
|
|
2289 |
break;
|
|
|
2290 |
}
|
|
|
2291 |
case 3:
|
|
|
2292 |
if (bpp == 1 || bpp == 3 || bpp == 8 || bpp == 16
|
|
|
2293 |
|| bpp == 24 || bpp == 32) {
|
|
|
2294 |
break;
|
|
|
2295 |
}
|
|
|
2296 |
cce: default:
|
|
|
2297 |
return gs_error_rangecheck;
|
|
|
2298 |
}
|
|
|
2299 |
|
|
|
2300 |
if (cprn_device->cmyk) {
|
|
|
2301 |
if (cprn_device->cmyk > 0) {
|
|
|
2302 |
ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4);
|
|
|
2303 |
} else {
|
|
|
2304 |
ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3);
|
|
|
2305 |
}
|
|
|
2306 |
if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */
|
|
|
2307 |
bpp = bpp < 8 ? 8 : bpp;
|
|
|
2308 |
}
|
|
|
2309 |
ci->max_color = (1 << (bpp >> 2)) - 1;
|
|
|
2310 |
ci->max_gray = (bpp >= 8 ? 255 : 1);
|
|
|
2311 |
|
|
|
2312 |
if (ci->num_components == 1) {
|
|
|
2313 |
ci->dither_grays = (bpp >= 8 ? 5 : 2);
|
|
|
2314 |
ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
|
|
|
2315 |
} else {
|
|
|
2316 |
ci->dither_grays = (bpp > 8 ? 5 : 2);
|
|
|
2317 |
ci->dither_colors = (bpp > 8 ? 5 : bpp > 1 ? 2 : 0);
|
|
|
2318 |
}
|
|
|
2319 |
} else {
|
|
|
2320 |
ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3);
|
|
|
2321 |
ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
|
|
|
2322 |
ci->max_gray = (bpp >= 8 ? 255 : 1);
|
|
|
2323 |
ci->dither_grays = (bpp >= 8 ? 5 : 2);
|
|
|
2324 |
ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
|
|
|
2325 |
}
|
|
|
2326 |
|
|
|
2327 |
ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp);
|
|
|
2328 |
|
|
|
2329 |
return 0;
|
|
|
2330 |
}
|
|
|
2331 |
|
|
|
2332 |
/*
|
|
|
2333 |
* Map a CMYK color to a color index. We just use depth / 4 bits per color
|
|
|
2334 |
* to produce the color index.
|
|
|
2335 |
*
|
|
|
2336 |
* Important note: CMYK values are stored in the order K, C, M, Y because of
|
|
|
2337 |
* the way the HP drivers work.
|
|
|
2338 |
*
|
|
|
2339 |
*/
|
|
|
2340 |
|
|
|
2341 |
#define gx_color_value_to_bits(cv, b) \
|
|
|
2342 |
((cv) >> (gx_color_value_bits - (b)))
|
|
|
2343 |
#define gx_bits_to_color_value(cv, b) \
|
|
|
2344 |
((cv) << (gx_color_value_bits - (b)))
|
|
|
2345 |
|
|
|
2346 |
#define gx_cmyk_value_bits(c, m, y, k, b) \
|
|
|
2347 |
((gx_color_value_to_bits((k), (b)) << (3 * (b))) | \
|
|
|
2348 |
(gx_color_value_to_bits((c), (b)) << (2 * (b))) | \
|
|
|
2349 |
(gx_color_value_to_bits((m), (b)) << (b)) | \
|
|
|
2350 |
(gx_color_value_to_bits((y), (b))))
|
|
|
2351 |
|
|
|
2352 |
#define gx_value_cmyk_bits(v, c, m, y, k, b) \
|
|
|
2353 |
(k) = gx_bits_to_color_value(((v) >> (3 * (b))) & ((1 << (b)) - 1), (b)), \
|
|
|
2354 |
(c) = gx_bits_to_color_value(((v) >> (2 * (b))) & ((1 << (b)) - 1), (b)), \
|
|
|
2355 |
(m) = gx_bits_to_color_value(((v) >> (b)) & ((1 << (b)) - 1), (b)), \
|
|
|
2356 |
(y) = gx_bits_to_color_value((v) & ((1 << (b)) - 1), (b))
|
|
|
2357 |
|
|
|
2358 |
private gx_color_index
|
|
|
2359 |
gdev_cmyk_map_cmyk_color(gx_device * pdev,
|
|
|
2360 |
gx_color_value *cmyk)
|
|
|
2361 |
{
|
|
|
2362 |
|
|
|
2363 |
gx_color_value cyan=cmyk[0], magenta=cmyk[1], yellow=cmyk[3], black=cmyk[4];
|
|
|
2364 |
|
|
|
2365 |
gx_color_index color;
|
|
|
2366 |
|
|
|
2367 |
switch (pdev->color_info.depth) {
|
|
|
2368 |
case 1:
|
|
|
2369 |
color = (cyan | magenta | yellow | black) > gx_max_color_value / 2 ?
|
|
|
2370 |
(gx_color_index) 1 : (gx_color_index) 0;
|
|
|
2371 |
break;
|
|
|
2372 |
|
|
|
2373 |
default:{
|
|
|
2374 |
int nbits = pdev->color_info.depth;
|
|
|
2375 |
|
|
|
2376 |
if (cyan == magenta && magenta == yellow) {
|
|
|
2377 |
/* Convert CMYK to gray -- Red Book 6.2.2 */
|
|
|
2378 |
float bpart = ((float)cyan) * (lum_red_weight / 100.) +
|
|
|
2379 |
((float)magenta) * (lum_green_weight / 100.) +
|
|
|
2380 |
((float)yellow) * (lum_blue_weight / 100.) +
|
|
|
2381 |
(float)black;
|
|
|
2382 |
|
|
|
2383 |
cyan = magenta = yellow = (gx_color_index) 0;
|
|
|
2384 |
black = (gx_color_index) (bpart > gx_max_color_value ?
|
|
|
2385 |
gx_max_color_value : bpart);
|
|
|
2386 |
}
|
|
|
2387 |
color = gx_cmyk_value_bits(cyan, magenta, yellow, black,
|
|
|
2388 |
nbits >> 2);
|
|
|
2389 |
}
|
|
|
2390 |
}
|
|
|
2391 |
|
|
|
2392 |
return color;
|
|
|
2393 |
}
|
|
|
2394 |
|
|
|
2395 |
/* Mapping of RGB colors to gray values. */
|
|
|
2396 |
|
|
|
2397 |
private gx_color_index
|
|
|
2398 |
gdev_cmyk_map_rgb_color(gx_device * pdev, gx_color_value rgb[3])
|
|
|
2399 |
{
|
|
|
2400 |
gx_color_value r=rgb[0], g=rgb[1], b=rgb[2];
|
|
|
2401 |
|
|
|
2402 |
if (gx_color_value_to_byte(r & g & b) == 0xff) {
|
|
|
2403 |
return (gx_color_index) 0; /* White */
|
|
|
2404 |
} else {
|
|
|
2405 |
gx_color_value c = gx_max_color_value - r;
|
|
|
2406 |
gx_color_value m = gx_max_color_value - g;
|
|
|
2407 |
gx_color_value y = gx_max_color_value - b;
|
|
|
2408 |
|
|
|
2409 |
switch (pdev->color_info.depth) {
|
|
|
2410 |
case 1:
|
|
|
2411 |
return (c | m | y) > gx_max_color_value / 2 ?
|
|
|
2412 |
(gx_color_index) 1 : (gx_color_index) 0;
|
|
|
2413 |
/*NOTREACHED */
|
|
|
2414 |
break;
|
|
|
2415 |
|
|
|
2416 |
case 8:
|
|
|
2417 |
return ((ulong) c * lum_red_weight * 10
|
|
|
2418 |
+ (ulong) m * lum_green_weight * 10
|
|
|
2419 |
+ (ulong) y * lum_blue_weight * 10)
|
|
|
2420 |
>> (gx_color_value_bits + 2);
|
|
|
2421 |
/*NOTREACHED */
|
|
|
2422 |
break;
|
|
|
2423 |
}
|
|
|
2424 |
}
|
|
|
2425 |
|
|
|
2426 |
return (gx_color_index) 0; /* This should never happen. */
|
|
|
2427 |
}
|
|
|
2428 |
|
|
|
2429 |
/* Mapping of CMYK colors. */
|
|
|
2430 |
private int
|
|
|
2431 |
gdev_cmyk_map_color_rgb(gx_device * pdev, gx_color_index color,
|
|
|
2432 |
gx_color_value prgb[3])
|
|
|
2433 |
{
|
|
|
2434 |
switch (pdev->color_info.depth) {
|
|
|
2435 |
case 1:
|
|
|
2436 |
prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color);
|
|
|
2437 |
break;
|
|
|
2438 |
|
|
|
2439 |
case 8:
|
|
|
2440 |
if (pdev->color_info.num_components == 1) {
|
|
|
2441 |
gx_color_value value = (gx_color_value) color ^ 0xff;
|
|
|
2442 |
|
|
|
2443 |
prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
|
|
|
2444 |
|
|
|
2445 |
break;
|
|
|
2446 |
}
|
|
|
2447 |
default:{
|
|
|
2448 |
unsigned long bcyan, bmagenta, byellow, black;
|
|
|
2449 |
int nbits = pdev->color_info.depth;
|
|
|
2450 |
|
|
|
2451 |
gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black,
|
|
|
2452 |
nbits >> 2);
|
|
|
2453 |
|
|
|
2454 |
#ifdef USE_ADOBE_CMYK_RGB
|
|
|
2455 |
|
|
|
2456 |
/* R = 1.0 - min(1.0, C + K), etc. */
|
|
|
2457 |
|
|
|
2458 |
bcyan += black, bmagenta += black, byellow += black;
|
|
|
2459 |
prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 :
|
|
|
2460 |
gx_max_color_value - bcyan);
|
|
|
2461 |
prgb[1] = (bmagenta > gx_max_color_value ? (gx_color_value) 0 :
|
|
|
2462 |
gx_max_color_value - bmagenta);
|
|
|
2463 |
prgb[2] = (byellow > gx_max_color_value ? (gx_color_value) 0 :
|
|
|
2464 |
gx_max_color_value - byellow);
|
|
|
2465 |
|
|
|
2466 |
#else
|
|
|
2467 |
|
|
|
2468 |
/* R = (1.0 - C) * (1.0 - K), etc. */
|
|
|
2469 |
|
|
|
2470 |
prgb[0] = (gx_color_value)
|
|
|
2471 |
((ulong) (gx_max_color_value - bcyan) *
|
|
|
2472 |
(gx_max_color_value - black) / gx_max_color_value);
|
|
|
2473 |
prgb[1] = (gx_color_value)
|
|
|
2474 |
((ulong) (gx_max_color_value - bmagenta) *
|
|
|
2475 |
(gx_max_color_value - black) / gx_max_color_value);
|
|
|
2476 |
prgb[2] = (gx_color_value)
|
|
|
2477 |
((ulong) (gx_max_color_value - byellow) *
|
|
|
2478 |
(gx_max_color_value - black) / gx_max_color_value);
|
|
|
2479 |
|
|
|
2480 |
#endif
|
|
|
2481 |
|
|
|
2482 |
}
|
|
|
2483 |
}
|
|
|
2484 |
|
|
|
2485 |
return 0;
|
|
|
2486 |
}
|
|
|
2487 |
|
|
|
2488 |
private gx_color_index
|
|
|
2489 |
gdev_pcl_map_rgb_color(gx_device * pdev, gx_color_value *rgb)
|
|
|
2490 |
{
|
|
|
2491 |
gx_color_value r=rgb[0], g=rgb[1], b=rgb[2];
|
|
|
2492 |
|
|
|
2493 |
if (gx_color_value_to_byte(r & g & b) == 0xff)
|
|
|
2494 |
return (gx_color_index) 0; /* white */
|
|
|
2495 |
else {
|
|
|
2496 |
gx_color_value c = gx_max_color_value - r;
|
|
|
2497 |
gx_color_value m = gx_max_color_value - g;
|
|
|
2498 |
gx_color_value y = gx_max_color_value - b;
|
|
|
2499 |
|
|
|
2500 |
switch (pdev->color_info.depth) {
|
|
|
2501 |
case 1:
|
|
|
2502 |
return ((c | m | y) > gx_max_color_value / 2 ?
|
|
|
2503 |
(gx_color_index) 1 : (gx_color_index) 0);
|
|
|
2504 |
case 8:
|
|
|
2505 |
if (pdev->color_info.num_components >= 3)
|
|
|
2506 |
#define gx_color_value_to_1bit(cv) ((cv) >> (gx_color_value_bits - 1))
|
|
|
2507 |
return (gx_color_value_to_1bit(c) +
|
|
|
2508 |
(gx_color_value_to_1bit(m) << 1) +
|
|
|
2509 |
(gx_color_value_to_1bit(y) << 2));
|
|
|
2510 |
else
|
|
|
2511 |
#define red_weight 306
|
|
|
2512 |
#define green_weight 601
|
|
|
2513 |
#define blue_weight 117
|
|
|
2514 |
return ((((ulong) c * red_weight +
|
|
|
2515 |
(ulong) m * green_weight +
|
|
|
2516 |
(ulong) y * blue_weight)
|
|
|
2517 |
>> (gx_color_value_bits + 2)));
|
|
|
2518 |
case 16:
|
|
|
2519 |
#define gx_color_value_to_5bits(cv) ((cv) >> (gx_color_value_bits - 5))
|
|
|
2520 |
#define gx_color_value_to_6bits(cv) ((cv) >> (gx_color_value_bits - 6))
|
|
|
2521 |
return (gx_color_value_to_5bits(y) +
|
|
|
2522 |
(gx_color_value_to_6bits(m) << 5) +
|
|
|
2523 |
(gx_color_value_to_5bits(c) << 11));
|
|
|
2524 |
case 24:
|
|
|
2525 |
return (gx_color_value_to_byte(y) +
|
|
|
2526 |
(gx_color_value_to_byte(m) << 8) +
|
|
|
2527 |
((ulong) gx_color_value_to_byte(c) << 16));
|
|
|
2528 |
case 32:
|
|
|
2529 |
{
|
|
|
2530 |
return ((c == m && c == y) ? ((ulong)
|
|
|
2531 |
gx_color_value_to_byte(c) << 24)
|
|
|
2532 |
: (gx_color_value_to_byte(y) +
|
|
|
2533 |
(gx_color_value_to_byte(m) << 8) +
|
|
|
2534 |
((ulong) gx_color_value_to_byte(c) << 16)));
|
|
|
2535 |
}
|
|
|
2536 |
}
|
|
|
2537 |
}
|
|
|
2538 |
return (gx_color_index) 0; /* This never happens */
|
|
|
2539 |
}
|
|
|
2540 |
|
|
|
2541 |
/* Map a color index to a r-g-b color. */
|
|
|
2542 |
private int
|
|
|
2543 |
gdev_pcl_map_color_rgb(gx_device * pdev, gx_color_index color,
|
|
|
2544 |
gx_color_value prgb[3])
|
|
|
2545 |
{
|
|
|
2546 |
/* For the moment, we simply ignore any black correction */
|
|
|
2547 |
switch (pdev->color_info.depth) {
|
|
|
2548 |
case 1:
|
|
|
2549 |
prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
|
|
|
2550 |
break;
|
|
|
2551 |
case 8:
|
|
|
2552 |
if (pdev->color_info.num_components >= 3) {
|
|
|
2553 |
gx_color_value c = (gx_color_value) color ^ 7;
|
|
|
2554 |
|
|
|
2555 |
prgb[0] = -(c & 1);
|
|
|
2556 |
prgb[1] = -((c >> 1) & 1);
|
|
|
2557 |
prgb[2] = -(c >> 2);
|
|
|
2558 |
} else {
|
|
|
2559 |
gx_color_value value = (gx_color_value) color ^ 0xff;
|
|
|
2560 |
|
|
|
2561 |
prgb[0] = prgb[1] = prgb[2] = (value << 8) + value;
|
|
|
2562 |
}
|
|
|
2563 |
break;
|
|
|
2564 |
case 16:
|
|
|
2565 |
{
|
|
|
2566 |
gx_color_value c = (gx_color_value) color ^ 0xffff;
|
|
|
2567 |
ushort value = c >> 11;
|
|
|
2568 |
|
|
|
2569 |
prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
|
|
|
2570 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
2571 |
value = (c >> 6) & 0x3f;
|
|
|
2572 |
prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
|
|
|
2573 |
>> (16 - gx_color_value_bits);
|
|
|
2574 |
value = c & 0x1f;
|
|
|
2575 |
prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
|
|
|
2576 |
(value >> 4)) >> (16 - gx_color_value_bits);
|
|
|
2577 |
}
|
|
|
2578 |
break;
|
|
|
2579 |
case 24:
|
|
|
2580 |
{
|
|
|
2581 |
gx_color_value c = (gx_color_value) color ^ 0xffffff;
|
|
|
2582 |
|
|
|
2583 |
prgb[0] = gx_color_value_from_byte(c >> 16);
|
|
|
2584 |
prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff);
|
|
|
2585 |
prgb[2] = gx_color_value_from_byte(c & 0xff);
|
|
|
2586 |
}
|
|
|
2587 |
break;
|
|
|
2588 |
case 32:
|
|
|
2589 |
#define gx_maxcol gx_color_value_from_byte(gx_color_value_to_byte(gx_max_color_value))
|
|
|
2590 |
{
|
|
|
2591 |
gx_color_value w = gx_maxcol - gx_color_value_from_byte(color >> 24);
|
|
|
2592 |
|
|
|
2593 |
prgb[0] = w - gx_color_value_from_byte((color >> 16) & 0xff);
|
|
|
2594 |
prgb[1] = w - gx_color_value_from_byte((color >> 8) & 0xff);
|
|
|
2595 |
prgb[2] = w - gx_color_value_from_byte(color & 0xff);
|
|
|
2596 |
}
|
|
|
2597 |
break;
|
|
|
2598 |
}
|
|
|
2599 |
return 0;
|
|
|
2600 |
}
|
|
|
2601 |
|
|
|
2602 |
/* new_bpp == save_bpp or new_bpp == 0 means don't change bpp.
|
|
|
2603 |
ccomps == 0 means don't change number of color comps.
|
|
|
2604 |
If new_bpp != 0, it must be the value of the BitsPerPixel element of
|
|
|
2605 |
the plist; real_bpp may differ from new_bpp.
|
|
|
2606 |
*/
|
|
|
2607 |
private int
|
|
|
2608 |
cdj_put_param_bpp(gx_device * pdev, gs_param_list * plist, int new_bpp,
|
|
|
2609 |
int real_bpp, int ccomps)
|
|
|
2610 |
{
|
|
|
2611 |
if (new_bpp == 0 && ccomps == 0)
|
|
|
2612 |
return gdev_prn_put_params(pdev, plist);
|
|
|
2613 |
else {
|
|
|
2614 |
gx_device_color_info save_info;
|
|
|
2615 |
int save_bpp;
|
|
|
2616 |
int code;
|
|
|
2617 |
|
|
|
2618 |
save_info = pdev->color_info;
|
|
|
2619 |
save_bpp = save_info.depth;
|
|
|
2620 |
#define save_ccomps save_info.num_components
|
|
|
2621 |
if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk)
|
|
|
2622 |
save_bpp = 3;
|
|
|
2623 |
code = cdj_set_bpp(pdev, real_bpp, ccomps);
|
|
|
2624 |
if (code < 0) {
|
|
|
2625 |
param_signal_error(plist, "BitsPerPixel", code);
|
|
|
2626 |
param_signal_error(plist, "ProcessColorModel", code);
|
|
|
2627 |
return code;
|
|
|
2628 |
}
|
|
|
2629 |
pdev->color_info.depth = new_bpp; /* cdj_set_bpp maps 3/6 to 8 */
|
|
|
2630 |
code = gdev_prn_put_params(pdev, plist);
|
|
|
2631 |
if (code < 0) {
|
|
|
2632 |
cdj_set_bpp(pdev, save_bpp, save_ccomps);
|
|
|
2633 |
return code;
|
|
|
2634 |
}
|
|
|
2635 |
cdj_set_bpp(pdev, real_bpp, ccomps); /* reset depth if needed */
|
|
|
2636 |
if ((cdj850->color_info.depth != save_bpp ||
|
|
|
2637 |
(ccomps != 0 && ccomps != save_ccomps))
|
|
|
2638 |
&& pdev->is_open)
|
|
|
2639 |
return gs_closedevice(pdev);
|
|
|
2640 |
return 0;
|
|
|
2641 |
#undef save_ccomps
|
|
|
2642 |
}
|
|
|
2643 |
}
|
|
|
2644 |
|
|
|
2645 |
/* the following code was in the original driver but is unused
|
|
|
2646 |
|
|
|
2647 |
* private int
|
|
|
2648 |
* x_mul_div (int a, int b, int c)
|
|
|
2649 |
* {
|
|
|
2650 |
* int result;
|
|
|
2651 |
*
|
|
|
2652 |
* result = (int) ((a * b) / c) ;
|
|
|
2653 |
* return result;
|
|
|
2654 |
* }
|
|
|
2655 |
*
|
|
|
2656 |
* private void
|
|
|
2657 |
* save_color_data(int size,
|
|
|
2658 |
* byte * current,
|
|
|
2659 |
* byte * saved)
|
|
|
2660 |
* {
|
|
|
2661 |
* int i;
|
|
|
2662 |
* for (i=0;i<size;i++){
|
|
|
2663 |
* *saved++ = *current++;
|
|
|
2664 |
* }
|
|
|
2665 |
* return;
|
|
|
2666 |
* }
|
|
|
2667 |
*
|
|
|
2668 |
* private int
|
|
|
2669 |
* test_scan (int size,
|
|
|
2670 |
* byte * current,
|
|
|
2671 |
* byte * last,
|
|
|
2672 |
* byte * control)
|
|
|
2673 |
* {
|
|
|
2674 |
* int error = 0;
|
|
|
2675 |
* int i;
|
|
|
2676 |
*
|
|
|
2677 |
* for (i=0;i<size;i++){
|
|
|
2678 |
* if (*control != *last){
|
|
|
2679 |
* error = 1;
|
|
|
2680 |
* }
|
|
|
2681 |
* *control = *current;
|
|
|
2682 |
*
|
|
|
2683 |
* control++;
|
|
|
2684 |
* last++;
|
|
|
2685 |
* current++;
|
|
|
2686 |
* }
|
|
|
2687 |
* return error;
|
|
|
2688 |
* }
|
|
|
2689 |
*
|
|
|
2690 |
* * Transform from cmy into hsv
|
|
|
2691 |
* private void
|
|
|
2692 |
* cmy2hsv(int *c, int *m, int *y, int *h, int *s, int *v)
|
|
|
2693 |
* {
|
|
|
2694 |
* int hue;
|
|
|
2695 |
* int r, g, b;
|
|
|
2696 |
* int r1, g1, b1;
|
|
|
2697 |
* int maxValue, minValue, diff;
|
|
|
2698 |
*
|
|
|
2699 |
* r = 255 - *c;
|
|
|
2700 |
* g = 255 - *m;
|
|
|
2701 |
* b = 255 - *y;
|
|
|
2702 |
*
|
|
|
2703 |
* maxValue = max(r, max(g,b));
|
|
|
2704 |
* minValue = min(r,min(g,b));
|
|
|
2705 |
* diff = maxValue - minValue;
|
|
|
2706 |
* *v = maxValue;
|
|
|
2707 |
*
|
|
|
2708 |
* if (maxValue != 0)
|
|
|
2709 |
* *s = x_mul_div(diff,255,maxValue);
|
|
|
2710 |
* else
|
|
|
2711 |
* *s = 0;
|
|
|
2712 |
*
|
|
|
2713 |
* if (*s == 0)
|
|
|
2714 |
* {
|
|
|
2715 |
* hue = 0;
|
|
|
2716 |
* }
|
|
|
2717 |
* else
|
|
|
2718 |
* {
|
|
|
2719 |
* r1 = x_mul_div(maxValue - r,255,diff);
|
|
|
2720 |
* g1 = x_mul_div(maxValue - g,255,diff);
|
|
|
2721 |
* b1 = x_mul_div(maxValue - b,255,diff);
|
|
|
2722 |
*
|
|
|
2723 |
* if (r == maxValue)
|
|
|
2724 |
* hue = b1 - g1;
|
|
|
2725 |
* else if (g == maxValue)
|
|
|
2726 |
* hue = 510 + r1 - b1;
|
|
|
2727 |
* else
|
|
|
2728 |
* hue = 1020 + g1 - r1;
|
|
|
2729 |
*
|
|
|
2730 |
* if (hue < 0)
|
|
|
2731 |
* hue += 1530;
|
|
|
2732 |
* }
|
|
|
2733 |
*
|
|
|
2734 |
* *h = (hue + 3) / 6;
|
|
|
2735 |
*
|
|
|
2736 |
* return;
|
|
|
2737 |
* }
|
|
|
2738 |
* end of unused code */
|
|
|
2739 |
|
|
|
2740 |
|
|
|
2741 |
/************************ the routines for the cdj1600 printer ***************/
|
|
|
2742 |
|
|
|
2743 |
/* Configure the printer and start Raster mode */
|
|
|
2744 |
private void
|
|
|
2745 |
cdj1600_start_raster_mode(gx_device_printer * pdev, int paper_size,
|
|
|
2746 |
FILE * prn_stream)
|
|
|
2747 |
{
|
|
|
2748 |
uint raster_width = pdev->width -
|
|
|
2749 |
pdev->x_pixels_per_inch * (dev_l_margin(pdev) + dev_r_margin(pdev));
|
|
|
2750 |
|
|
|
2751 |
/* switch to PCL control language */
|
|
|
2752 |
fputs("\033%-12345X@PJL enter language = PCL\n", prn_stream);
|
|
|
2753 |
|
|
|
2754 |
fputs("\033*rbC", prn_stream); /* End raster graphics */
|
|
|
2755 |
fputs("\033E", prn_stream); /* Reset */
|
|
|
2756 |
|
|
|
2757 |
/* resolution */
|
|
|
2758 |
fprintf(prn_stream, "\033*t%dR", (int)cdj850->x_pixels_per_inch);
|
|
|
2759 |
|
|
|
2760 |
/* Page size, orientation, top margin & perforation skip */
|
|
|
2761 |
fprintf(prn_stream, "\033&l%daolE", paper_size);
|
|
|
2762 |
|
|
|
2763 |
/* no negative motion */
|
|
|
2764 |
fputs("\033&a1N", prn_stream);
|
|
|
2765 |
|
|
|
2766 |
/* Print Quality, -1 = draft, 0 = normal, 1 = presentation */
|
|
|
2767 |
fprintf(prn_stream, "\033*o%dQ", cdj850->quality);
|
|
|
2768 |
|
|
|
2769 |
/* Media Type,0 = plain paper, 1 = bond paper, 2 = special
|
|
|
2770 |
paper, 3 = glossy film, 4 = transparency film */
|
|
|
2771 |
fprintf(prn_stream, "\033&l%dM", cdj850->papertype);
|
|
|
2772 |
|
|
|
2773 |
/* Move to top left of printed area */
|
|
|
2774 |
fprintf(prn_stream, "\033*p%dY", (int)(300.0 * DOFFSET));
|
|
|
2775 |
|
|
|
2776 |
/* raster width and number of planes */
|
|
|
2777 |
fprintf(prn_stream, "\033*r%ds-%du0A",
|
|
|
2778 |
raster_width, pdev->color_info.num_components);
|
|
|
2779 |
|
|
|
2780 |
/* start raster graphics */
|
|
|
2781 |
fputs("\033*r1A", prn_stream);
|
|
|
2782 |
|
|
|
2783 |
/* From now on, all escape commands start with \033*b, so we
|
|
|
2784 |
* combine them (if the printer supports this). */
|
|
|
2785 |
fputs("\033*b", prn_stream);
|
|
|
2786 |
|
|
|
2787 |
/* Set compression if the mode has been defined. */
|
|
|
2788 |
if (cdj850->compression)
|
|
|
2789 |
fprintf(prn_stream, "%dm", cdj850->compression);
|
|
|
2790 |
|
|
|
2791 |
return;
|
|
|
2792 |
} /* end configure raster-mode */
|
|
|
2793 |
|
|
|
2794 |
/* print_plane compresses (mode 3) and outputs one plane */
|
|
|
2795 |
private void
|
|
|
2796 |
print_c3plane(FILE * prn_stream, char plane_code, int plane_size,
|
|
|
2797 |
const byte * curr, byte * prev, byte * out_data)
|
|
|
2798 |
{
|
|
|
2799 |
/* Compress the output data */
|
|
|
2800 |
int out_count = gdev_pcl_mode3compress(plane_size, curr, prev, out_data);
|
|
|
2801 |
|
|
|
2802 |
/* and output the data */
|
|
|
2803 |
if (out_count > 0) {
|
|
|
2804 |
fprintf(prn_stream, "%d%c", out_count, plane_code);
|
|
|
2805 |
fwrite(out_data, sizeof(byte), out_count, prn_stream);
|
|
|
2806 |
} else {
|
|
|
2807 |
putc(plane_code, prn_stream);
|
|
|
2808 |
}
|
|
|
2809 |
}
|
|
|
2810 |
|
|
|
2811 |
private int
|
|
|
2812 |
copy_color_data(byte * dest, const byte * src, int n)
|
|
|
2813 |
{
|
|
|
2814 |
/* copy word by word */
|
|
|
2815 |
register int i = n / 4;
|
|
|
2816 |
register word *d = (word *) dest;
|
|
|
2817 |
register const word *s = (const word *)src;
|
|
|
2818 |
|
|
|
2819 |
while (i-- > 0) {
|
|
|
2820 |
*d++ = *s++;
|
|
|
2821 |
}
|
|
|
2822 |
return n;
|
|
|
2823 |
}
|
|
|
2824 |
|
|
|
2825 |
/* Printing non-blank lines */
|
|
|
2826 |
private void
|
|
|
2827 |
cdj1600_print_non_blank_lines(gx_device_printer * pdev,
|
|
|
2828 |
struct ptr_arrays *data_ptrs,
|
|
|
2829 |
struct misc_struct *misc_vars,
|
|
|
2830 |
struct error_val_field *error_values,
|
|
|
2831 |
const Gamma *gamma,
|
|
|
2832 |
FILE * prn_stream)
|
|
|
2833 |
{
|
|
|
2834 |
int i, plane_size_c;
|
|
|
2835 |
|
|
|
2836 |
/* copy data to data_c in order to make do_floyd_steinberg work */
|
|
|
2837 |
plane_size_c = copy_color_data
|
|
|
2838 |
(data_ptrs->data_c[misc_vars->cscan],
|
|
|
2839 |
data_ptrs->data[misc_vars->scan],
|
|
|
2840 |
misc_vars->databuff_size) / misc_vars->storage_bpp;
|
|
|
2841 |
|
|
|
2842 |
/* dither the color planes */
|
|
|
2843 |
do_floyd_steinberg(misc_vars->scan, misc_vars->cscan,
|
|
|
2844 |
misc_vars->plane_size, plane_size_c,
|
|
|
2845 |
misc_vars->num_comps, data_ptrs, pdev, error_values);
|
|
|
2846 |
|
|
|
2847 |
/* Transfer raster graphics in the order C, M, Y, that is
|
|
|
2848 |
planes 2,1,0 */
|
|
|
2849 |
for (i = misc_vars->num_comps - 1; i >= 0; i--) {
|
|
|
2850 |
|
|
|
2851 |
/* output the lower color planes */
|
|
|
2852 |
print_c3plane(prn_stream, "wvv"[i], plane_size_c,
|
|
|
2853 |
data_ptrs->plane_data_c[misc_vars->cscan][i],
|
|
|
2854 |
data_ptrs->plane_data_c[1 - misc_vars->cscan][i],
|
|
|
2855 |
data_ptrs->out_data);
|
|
|
2856 |
} /* End For i = num_comps */
|
|
|
2857 |
misc_vars->cscan = 1 - misc_vars->cscan;
|
|
|
2858 |
}
|
|
|
2859 |
|
|
|
2860 |
private void
|
|
|
2861 |
cdj1600_terminate_page(gx_device_printer * pdev, FILE * prn_stream)
|
|
|
2862 |
{
|
|
|
2863 |
cdj850_terminate_page(pdev, prn_stream);
|
|
|
2864 |
fputs("\033%-12345X", prn_stream);
|
|
|
2865 |
}
|