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 0 normal [default]
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
hp_colour_open(gx_device * pdev)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
cdj850_get_params(gx_device * pdev,gs_param_list * plist)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 0 ||
885 (code = param_write_float(plist, "GammaValM", &cdj850->gammavalm)) <
886 0 ||
887 (code = param_write_float(plist, "GammaValY", &cdj850->gammavaly)) <
888 0 ||
889 (code = param_write_float(plist, "GammaValK", &cdj850->gammavalk)) <
890 0 ||
891 (code = param_write_float(plist, "BlackCorrect",
892 &cdj850->blackcorrect)) < 0
893 )
894 return code;
895
896 return code;
897 }
898
899 private int
cdj850_put_params(gx_device * pdev,gs_param_list * plist)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
assign_dpi(int dpi,byte * msb)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
cdj850_terminate_page(gx_device_printer * pdev,FILE * prn_stream)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
cdj850_print_page(gx_device_printer * pdev,FILE * prn_stream)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
GetScanLine(gx_device_printer * pdev,int * lnum,struct ptr_arrays * data_ptrs,struct misc_struct * misc_vars,word rmask)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
send_scan_lines(gx_device_printer * pdev,struct ptr_arrays * data_ptrs,struct misc_struct * misc_vars,struct error_val_field * error_values,const Gamma * gamma,FILE * prn_stream)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
print_c9plane(FILE * prn_stream,char plane_code,int plane_size,const byte * curr,const byte * prev,byte * out_data)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
cdj850_print_non_blank_lines(gx_device_printer * pdev,struct ptr_arrays * data_ptrs,struct misc_struct * misc_vars,struct error_val_field * error_values,const Gamma * gamma,FILE * prn_stream)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
do_floyd_steinberg(int scan,int cscan,int plane_size,int plane_size_c,int n,struct ptr_arrays * data_ptrs,gx_device_printer * pdev,struct error_val_field * error_values)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
do_gamma(float mastergamma,float gammaval,byte values[256])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
do_black_correction(float kvalue,int kcorrect[256])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
do_gcr(int bytecount,byte * inbyte,const byte kvalues[256],const byte cvalues[256],const byte mvalues[256],const byte yvalues[256],const int kcorrect[256])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
rescale_byte_wise2x2(int bytecount,const byte * inbytea,const byte * inbyteb,byte * outbyte)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
rescale_byte_wise2x1(int bytecount,const byte * inbytea,const byte * inbyteb,byte * outbyte)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
rescale_byte_wise1x2(int bytecount,const byte * inbytea,const byte * inbyteb,byte * outbyte)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
rescale_byte_wise1x1(int bytecount,const byte * inbytea,const byte * inbyteb,byte * outbyte)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
init_error_buffer(struct misc_struct * misc_vars,struct ptr_arrays * data_ptrs)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
FSDlinebw(int scan,int plane_size,struct error_val_field * error_values,byte * kP,int n,int * ep,byte * dp)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
FSDlinec2(int scan,int plane_size,struct error_val_field * error_values,byte * cPa,byte * mPa,byte * yPa,int n,byte * dp,int * ep)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
FSDlinec3(int scan,int plane_size,struct error_val_field * error_values,byte * cPa,byte * mPa,byte * yPa,byte * cPb,byte * mPb,byte * yPb,int n,byte * dp,int * ep)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
FSDlinec4(int scan,int plane_size,struct error_val_field * error_values,byte * cPa,byte * mPa,byte * yPa,byte * cPb,byte * mPb,byte * yPb,int n,byte * dp,int * ep)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
calculate_memory_size(gx_device_printer * pdev,struct misc_struct * misc_vars)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
init_data_structure(gx_device_printer * pdev,struct ptr_arrays * data_ptrs,struct misc_struct * misc_vars)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
cdj850_start_raster_mode(gx_device_printer * pdev,int paper_size,FILE * prn_stream)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
cdj_put_param_int(gs_param_list * plist,gs_param_name pname,int * pvalue,int minval,int maxval,int ecode)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
cdj_put_param_float(gs_param_list * plist,gs_param_name pname,float * pvalue,float minval,float maxval,int ecode)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
cdj_set_bpp(gx_device * pdev,int bpp,int ccomps)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
gdev_cmyk_map_cmyk_color(gx_device * pdev,gx_color_value * cmyk)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
gdev_cmyk_map_rgb_color(gx_device * pdev,gx_color_value rgb[3])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
gdev_cmyk_map_color_rgb(gx_device * pdev,gx_color_index color,gx_color_value prgb[3])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
gdev_pcl_map_rgb_color(gx_device * pdev,gx_color_value * rgb)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
gdev_pcl_map_color_rgb(gx_device * pdev,gx_color_index color,gx_color_value prgb[3])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
cdj_put_param_bpp(gx_device * pdev,gs_param_list * plist,int new_bpp,int real_bpp,int ccomps)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
cdj1600_start_raster_mode(gx_device_printer * pdev,int paper_size,FILE * prn_stream)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
print_c3plane(FILE * prn_stream,char plane_code,int plane_size,const byte * curr,byte * prev,byte * out_data)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
copy_color_data(byte * dest,const byte * src,int n)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
cdj1600_print_non_blank_lines(gx_device_printer * pdev,struct ptr_arrays * data_ptrs,struct misc_struct * misc_vars,struct error_val_field * error_values,const Gamma * gamma,FILE * prn_stream)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
cdj1600_terminate_page(gx_device_printer * pdev,FILE * prn_stream)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 }
2866