Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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