1 /*
2 * "$Id: print-canon.c,v 1.71.2.9 2003/10/19 23:48:19 rlk Exp $"
3 *
4 * Print plug-in CANON BJL driver for the GIMP.
5 *
6 * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
7 * Robert Krawitz (rlk@alum.mit.edu) and
8 * Andy Thaller (thaller@ph.tum.de)
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25 /*
26 * This file must include only standard C header files. The core code must
27 * compile on generic platforms that don't support glib, gimp, gtk, etc.
28 */
29
30 /*
31 * Large parts of this file (mainly the ink handling) is based on
32 * print-escp2.c -- refer to README.new-printer on how to adjust the colors
33 * for a certain model.
34 */
35
36 /* TODO-LIST
37 *
38 * * adjust the colors of all supported models
39 *
40 */
41
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
45 #include <gimp-print/gimp-print.h>
46 #include "gimp-print-internal.h"
47 #include <gimp-print/gimp-print-intl-internal.h>
48 #include <string.h>
49 #include <stdio.h>
50 #if defined(HAVE_VARARGS_H) && !defined(HAVE_STDARG_H)
51 #include <varargs.h>
52 #else
53 #include <stdarg.h>
54 #endif
55 #include <ctype.h>
56
57 #if (0)
58 #define EXPERIMENTAL_STUFF 0
59 #endif
60
61 #define MAX_CARRIAGE_WIDTH 13 /* This really needs to go away */
62
63 /*
64 * We really need to get away from this silly static nonsense...
65 */
66 #define MAX_PHYSICAL_BPI 1440
67 #define MAX_OVERSAMPLED 8
68 #define MAX_BPP 4
69 #define BITS_PER_BYTE 8
70 #define COMPBUFWIDTH (MAX_PHYSICAL_BPI * MAX_OVERSAMPLED * MAX_BPP * \
71 MAX_CARRIAGE_WIDTH / BITS_PER_BYTE)
72
73 #define USE_3BIT_FOLD_TYPE 323
74
75 /*
76 * For each printer, we can select from a variety of dot sizes.
77 * For single dot size printers, the available sizes are usually 0,
78 * which is the "default", and some subset of 1-4. For simple variable
79 * dot size printers (with only one kind of variable dot size), the
80 * variable dot size is specified as 0x10. For newer printers, there
81 * is a choice of variable dot sizes available, 0x10, 0x11, and 0x12 in
82 * order of increasing size.
83 *
84 * Normally, we want to specify the smallest dot size that lets us achieve
85 * a density of less than .8 or thereabouts (above that we start to get
86 * some dither artifacts). This needs to be tested for each printer and
87 * resolution.
88 *
89 * An entry of -1 in a slot means that this resolution is not available.
90 * 0 standard dot sizes are used.
91 * 1 drop modulation is used.
92 */
93
94 /* We know a per-model base resolution (like 180dpi or 150dpi)
95 * and multipliers for the base resolution in the dotsize-, densities-
96 * and inklist:
97 * for 180dpi base resolution we would have
98 * s_r11_4 for 4color ink @180dpi
99 * s_r22_4 for 4color ink @360dpi
100 * s_r33_4 for 4color ink @720dpi
101 * s_r43_4 for 4color ink @1440x720dpi
102 */
103
104 typedef struct canon_dot_sizes
105 {
106 int dot_r11; /* 180x180 or 150x150 */
107 int dot_r22; /* 360x360 or 300x300 */
108 int dot_r33; /* 720x720 or 600x600 */
109 int dot_r43; /* 1440x720 or 1200x600 */
110 int dot_r44; /* 1440x1440 or 1200x1200 */
111 int dot_r55; /* 2880x2880 or 2400x2400 */
112 } canon_dot_size_t;
113
114 /*
115 * Specify the base density for each available resolution.
116 *
117 */
118
119 typedef struct canon_densities
120 {
121 double d_r11; /* 180x180 or 150x150 */
122 double d_r22; /* 360x360 or 300x300 */
123 double d_r33; /* 720x720 or 600x600 */
124 double d_r43; /* 1440x720 or 1200x600 */
125 double d_r44; /* 1440x1440 or 1200x1200 */
126 double d_r55; /* 2880x2880 or 2400x2400 */
127 } canon_densities_t;
128
129
130
131 /*
132 * Definition of the multi-level inks available to a given printer.
133 * Each printer may use a different kind of ink droplet for variable
134 * and single drop size for each supported horizontal resolution and
135 * type of ink (4 or 6 color).
136 *
137 * Recall that 6 color ink is treated as simply another kind of
138 * multi-level ink, but the driver offers the user a choice of 4 and
139 * 6 color ink, so we need to define appropriate inksets for both
140 * kinds of ink.
141 *
142 * Stuff like the MIS 4 and 6 "color" monochrome inks doesn't fit into
143 * this model very nicely, so we'll either have to special case it
144 * or find some way of handling it in here.
145 */
146
147 typedef struct canon_variable_ink
148 {
149 const stp_simple_dither_range_t *range;
150 int count;
151 double density;
152 } canon_variable_ink_t;
153
154 typedef struct canon_variable_inkset
155 {
156 const canon_variable_ink_t *c;
157 const canon_variable_ink_t *m;
158 const canon_variable_ink_t *y;
159 const canon_variable_ink_t *k;
160 } canon_variable_inkset_t;
161
162 /*
163 * currenty unaccounted for are the 7color printers and the 3color ones
164 * (which use CMY only printheads)
165 *
166 */
167
168 typedef struct canon_variable_inklist
169 {
170 const int bits;
171 const int colors;
172 const canon_variable_inkset_t *r11; /* 180x180 or 150x150 */
173 const canon_variable_inkset_t *r22; /* 360x360 or 300x300 */
174 const canon_variable_inkset_t *r33; /* 720x720 or 600x600 */
175 const canon_variable_inkset_t *r43; /* 1440x720 or 1200x600 */
176 const canon_variable_inkset_t *r44; /* 1440x1440 or 1200x1200 */
177 const canon_variable_inkset_t *r55; /* 2880x2880 or 2400x2400 */
178 } canon_variable_inklist_t;
179
180
181 #ifdef EXPERIMENTAL_STUFF
182 /*
183 * A printmode is defined by its resolution (xdpi x ydpi), the bits per pixel
184 * and the installed printhead.
185 *
186 * For a hereby defined printmode we specify the density and gamma multipliers
187 * and the ink definition with optional adjustments for lum, hue and sat
188 *
189 */
190 typedef struct canon_variable_printmode
191 {
192 const int xdpi; /* horizontal resolution */
193 const int ydpi; /* vertical resolution */
194 const int bits; /* bits per pixel */
195 const int printhead; /* installed printhead */
196 const int quality; /* maximum init-quality */
197 const double density; /* density multiplier */
198 const double gamma; /* gamma multiplier */
199 const canon_variable_inkset_t *inks; /* ink definition */
200 const double *lum_adjustment; /* optional lum adj. */
201 const double *hue_adjustment; /* optional hue adj. */
202 const double *sat_adjustment; /* optional sat adj. */
203 } canon_variable_printmode_t;
204 #endif
205
206 /* NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
207 *
208 * The following dither ranges were taken from print-escp2.c and do NOT
209 * represent the requirements of canon inks. Feel free to play with them
210 * accoring to the escp2 part of doc/README.new-printer and send me a patch
211 * if you get better results. Please send mail to thaller@ph.tum.de
212 */
213
214 /*
215 * Dither ranges specifically for Cyan/LightCyan (see NOTE above)
216 *
217 */
218 static const stp_simple_dither_range_t canon_dither_ranges_Cc_1bit[] =
219 {
220 { 0.25, 0x1, 1, 1 },
221 { 1.0, 0x1, 0, 1 }
222 };
223
224 static const canon_variable_ink_t canon_ink_Cc_1bit =
225 {
226 canon_dither_ranges_Cc_1bit,
227 sizeof(canon_dither_ranges_Cc_1bit) / sizeof(stp_simple_dither_range_t),
228 .75
229 };
230
231 /*
232 * Dither ranges specifically for Magenta/LightMagenta (see NOTE above)
233 *
234 */
235 static const stp_simple_dither_range_t canon_dither_ranges_Mm_1bit[] =
236 {
237 { 0.26, 0x1, 1, 1 },
238 { 1.0, 0x1, 0, 1 }
239 };
240
241 static const canon_variable_ink_t canon_ink_Mm_1bit =
242 {
243 canon_dither_ranges_Mm_1bit,
244 sizeof(canon_dither_ranges_Mm_1bit) / sizeof(stp_simple_dither_range_t),
245 .75
246 };
247
248
249 /*
250 * Dither ranges specifically for any Color and 2bit/pixel (see NOTE above)
251 *
252 */
253 static const stp_simple_dither_range_t canon_dither_ranges_X_2bit[] =
254 {
255 { 0.45, 0x1, 0, 1 },
256 { 0.68, 0x2, 0, 2 },
257 { 1.0, 0x3, 0, 3 }
258 };
259
260 static const canon_variable_ink_t canon_ink_X_2bit =
261 {
262 canon_dither_ranges_X_2bit,
263 sizeof(canon_dither_ranges_X_2bit) / sizeof(stp_simple_dither_range_t),
264 1.0
265 };
266
267 /*
268 * Dither ranges specifically for any Color/LightColor and 2bit/pixel
269 * (see NOTE above)
270 */
271 static const stp_simple_dither_range_t canon_dither_ranges_Xx_2bit[] =
272 {
273 { 0.15, 0x1, 1, 1 },
274 { 0.227, 0x2, 1, 2 },
275 /*{ 0.333, 0x3, 1, 3 }, */
276 { 0.45, 0x1, 0, 1 },
277 { 0.68, 0x2, 0, 2 },
278 { 1.0, 0x3, 0, 3 }
279 };
280
281 static const canon_variable_ink_t canon_ink_Xx_2bit =
282 {
283 canon_dither_ranges_Xx_2bit,
284 sizeof(canon_dither_ranges_Xx_2bit) / sizeof(stp_simple_dither_range_t),
285 1.0
286 };
287
288 /*
289 * Dither ranges specifically for any Color and 3bit/pixel
290 * (see NOTE above)
291 *
292 * BIG NOTE: The bjc8200 has this kind of ink. One Byte seems to hold
293 * drop sizes for 3 pixels in a 3/2/2 bit fashion.
294 * Size values for 3bit-sized pixels range from 1 to 7,
295 * size values for 2bit-sized picels from 1 to 3 (kill msb).
296 *
297 *
298 */
299 static const stp_simple_dither_range_t canon_dither_ranges_X_3bit[] =
300 {
301 { 0.45, 0x1, 0, 1 },
302 { 0.55, 0x2, 0, 2 },
303 { 0.66, 0x3, 0, 3 },
304 { 0.77, 0x4, 0, 4 },
305 { 0.88, 0x5, 0, 5 },
306 { 1.0, 0x6, 0, 6 }
307 };
308
309 static const canon_variable_ink_t canon_ink_X_3bit =
310 {
311 canon_dither_ranges_X_3bit,
312 sizeof(canon_dither_ranges_X_3bit) / sizeof(stp_simple_dither_range_t),
313 1.0
314 };
315
316 /*
317 * Dither ranges specifically for any Color/LightColor and 3bit/pixel
318 * (see NOTE above)
319 */
320 static const stp_simple_dither_range_t canon_dither_ranges_Xx_3bit[] =
321 {
322 { 0.15, 0x1, 1, 1 },
323 { 0.227, 0x2, 1, 2 },
324 { 0.333, 0x3, 1, 3 },
325 /* { 0.333, 0x3, 1, 3 }, */
326 { 0.45, 0x1, 0, 1 },
327 { 0.55, 0x2, 0, 2 },
328 { 0.66, 0x3, 0, 3 },
329 { 0.77, 0x4, 0, 4 },
330 { 0.88, 0x5, 0, 5 },
331 { 1.0, 0x6, 0, 6 }
332 };
333
334 static const canon_variable_ink_t canon_ink_Xx_3bit =
335 {
336 canon_dither_ranges_Xx_3bit,
337 sizeof(canon_dither_ranges_Xx_3bit) / sizeof(stp_simple_dither_range_t),
338 1.0
339 };
340
341
342 /* Inkset for printing in CMY and 1bit/pixel */
343 static const canon_variable_inkset_t ci_CMY_1 =
344 {
345 NULL,
346 NULL,
347 NULL,
348 NULL
349 };
350
351 /* Inkset for printing in CMY and 2bit/pixel */
352 static const canon_variable_inkset_t ci_CMY_2 =
353 {
354 &canon_ink_X_2bit,
355 &canon_ink_X_2bit,
356 &canon_ink_X_2bit,
357 NULL
358 };
359
360 /* Inkset for printing in CMYK and 1bit/pixel */
361 static const canon_variable_inkset_t ci_CMYK_1 =
362 {
363 NULL,
364 NULL,
365 NULL,
366 NULL
367 };
368
369 /* Inkset for printing in CcMmYK and 1bit/pixel */
370 static const canon_variable_inkset_t ci_CcMmYK_1 =
371 {
372 &canon_ink_Cc_1bit,
373 &canon_ink_Mm_1bit,
374 NULL,
375 NULL
376 };
377
378 /* Inkset for printing in CMYK and 2bit/pixel */
379 static const canon_variable_inkset_t ci_CMYK_2 =
380 {
381 &canon_ink_X_2bit,
382 &canon_ink_X_2bit,
383 &canon_ink_X_2bit,
384 &canon_ink_X_2bit
385 };
386
387 /* Inkset for printing in CcMmYK and 2bit/pixel */
388 static const canon_variable_inkset_t ci_CcMmYK_2 =
389 {
390 &canon_ink_Xx_2bit,
391 &canon_ink_Xx_2bit,
392 &canon_ink_X_2bit,
393 &canon_ink_X_2bit
394 };
395
396 /* Inkset for printing in CMYK and 3bit/pixel */
397 static const canon_variable_inkset_t ci_CMYK_3 =
398 {
399 &canon_ink_X_3bit,
400 &canon_ink_X_3bit,
401 &canon_ink_X_3bit,
402 &canon_ink_X_3bit
403 };
404
405 /* Inkset for printing in CcMmYK and 3bit/pixel */
406 static const canon_variable_inkset_t ci_CcMmYK_3 =
407 {
408 &canon_ink_Xx_3bit,
409 &canon_ink_Xx_3bit,
410 &canon_ink_X_3bit,
411 &canon_ink_X_3bit,
412 };
413
414
415 typedef canon_variable_inklist_t* canon_variable_inklist_p;
416
417 /* Ink set should be applicable for any CMYK based model */
418 static const canon_variable_inklist_t canon_ink_standard[] =
419 {
420 {
421 1,4,
422 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
423 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
424 },
425 };
426
427 /* Ink set for printers using CMY and CMY photo printing, 1 or 2bit/pixel */
428 static const canon_variable_inklist_t canon_ink_oldphoto[] =
429 {
430 {
431 1,3,
432 &ci_CMY_1, &ci_CMY_1, &ci_CMY_1,
433 &ci_CMY_1, &ci_CMY_1, &ci_CMY_1,
434 },
435 {
436 2,3,
437 &ci_CMY_2, &ci_CMY_2,
438 &ci_CMY_2, &ci_CMY_2,
439 &ci_CMY_2, &ci_CMY_2,
440 },
441 };
442
443 /* Ink set for printers using CMYK and CcMmYK printing, 1 or 2bit/pixel */
444 static const canon_variable_inklist_t canon_ink_standardphoto[] =
445 {
446 {
447 1,4,
448 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
449 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
450 },
451 {
452 2,4,
453 &ci_CMYK_2, &ci_CMYK_2,
454 &ci_CMYK_2, &ci_CMYK_2,
455 &ci_CMYK_2, &ci_CMYK_2,
456 },
457 {
458 1,6,
459 &ci_CcMmYK_1, &ci_CcMmYK_1, &ci_CcMmYK_1,
460 &ci_CcMmYK_1, &ci_CcMmYK_1, &ci_CcMmYK_1,
461 },
462 {
463 2,6,
464 &ci_CcMmYK_2, &ci_CcMmYK_2, &ci_CcMmYK_2,
465 &ci_CcMmYK_2, &ci_CcMmYK_2, &ci_CcMmYK_2,
466 },
467 };
468
469 /* Ink set for printers using CMYK and CcMmYK printing, 1 or 3bit/pixel */
470 static const canon_variable_inklist_t canon_ink_superphoto[] =
471 {
472 {
473 1,4,
474 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
475 &ci_CMYK_1, &ci_CMYK_1, &ci_CMYK_1,
476 },
477 {
478 3,4,
479 &ci_CMYK_3, &ci_CMYK_3, &ci_CMYK_3,
480 &ci_CMYK_3, &ci_CMYK_3, &ci_CMYK_3,
481 },
482 {
483 3,6,
484 &ci_CcMmYK_3, &ci_CcMmYK_3, &ci_CcMmYK_3,
485 &ci_CcMmYK_3, &ci_CcMmYK_3, &ci_CcMmYK_3,
486 },
487 };
488
489 static const double standard_sat_adjustment[49] =
490 {
491 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, /* C */
492 1.8, 1.9, 1.9, 1.9, 1.7, 1.5, 1.3, 1.1, /* B */
493 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, /* M */
494 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, /* R */
495 1.0, 1.0, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, /* Y */
496 1.5, 1.4, 1.3, 1.2, 1.1, 1.0, 1.0, 1.0, /* G */
497 1.0 /* C */
498 };
499
500 static const double standard_lum_adjustment[49] =
501 {
502 0.50, 0.6, 0.7, 0.8, 0.9, 0.86, 0.82, 0.79, /* C */
503 0.78, 0.8, 0.83, 0.87, 0.9, 0.95, 1.05, 1.15, /* B */
504 1.3, 1.25, 1.2, 1.15, 1.12, 1.09, 1.06, 1.03, /* M */
505 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, /* R */
506 1.0, 0.9, 0.8, 0.7, 0.65, 0.6, 0.55, 0.52, /* Y */
507 0.48, 0.47, 0.47, 0.49, 0.49, 0.49, 0.52, 0.51, /* G */
508 0.50 /* C */
509 };
510
511 static const double standard_hue_adjustment[49] =
512 {
513 0.00, 0.05, 0.04, 0.01, -.03, -.10, -.18, -.26, /* C */
514 -.35, -.43, -.40, -.32, -.25, -.18, -.10, -.07, /* B */
515 0.00, -.04, -.09, -.13, -.18, -.23, -.27, -.31, /* M */
516 -.35, -.38, -.30, -.23, -.15, -.08, 0.00, -.02, /* R */
517 0.00, 0.08, 0.10, 0.08, 0.05, 0.03, -.03, -.12, /* Y */
518 -.20, 0.17, -.20, -.17, -.15, -.12, -.10, -.08, /* G */
519 0.00, /* C */
520 };
521
522 static const double plain_paper_lum_adjustment[49] =
523 {
524 1.2, 1.22, 1.28, 1.34, 1.39, 1.42, 1.45, 1.48, /* C */
525 1.5, 1.4, 1.3, 1.25, 1.2, 1.1, 1.05, 1.05, /* B */
526 1.05, 1.05, 1.05, 1.05, 1.05, 1.05, 1.05, 1.05, /* M */
527 1.05, 1.05, 1.05, 1.1, 1.1, 1.1, 1.1, 1.1, /* R */
528 1.1, 1.15, 1.3, 1.45, 1.6, 1.75, 1.9, 2.0, /* Y */
529 2.1, 2.0, 1.8, 1.7, 1.6, 1.5, 1.4, 1.3, /* G */
530 1.2 /* C */
531 };
532
533
534 typedef enum {
535 COLOR_MONOCHROME = 1,
536 COLOR_CMY = 3,
537 COLOR_CMYK = 4,
538 COLOR_CCMMYK= 6,
539 COLOR_CCMMYYK= 7
540 } colormode_t;
541
542 typedef struct canon_caps {
543 int model; /* model number as used in printers.xml */
544 int model_id; /* model ID code for use in commands */
545 int max_width; /* maximum printable paper size */
546 int max_height;
547 int base_res; /* base resolution - shall be 150 or 180 */
548 int max_xdpi; /* maximum horizontal resolution */
549 int max_ydpi; /* maximum vertical resolution */
550 int max_quality;
551 int border_left; /* left margin, points */
552 int border_right; /* right margin, points */
553 int border_top; /* absolute top margin, points */
554 int border_bottom; /* absolute bottom margin, points */
555 int inks; /* installable cartridges (CANON_INK_*) */
556 int slots; /* available paperslots */
557 unsigned long features; /* special bjl settings */
558 #ifdef EXPERIMENTAL_STUFF
559 const canon_variable_printmode_t *printmodes;
560 int printmodes_cnt;
561 #else
562 int dummy;
563 const canon_dot_size_t dot_sizes; /* Vector of dot sizes for resolutions */
564 const canon_densities_t densities; /* List of densities for each printer */
565 const canon_variable_inklist_t *inxs; /* Choices of inks for this printer */
566 int inxs_cnt; /* number of ink definitions in inxs */
567 #endif
568 const double *lum_adjustment;
569 const double *hue_adjustment;
570 const double *sat_adjustment;
571 } canon_cap_t;
572
573 typedef struct canon_privdata_weave {
574 int bidirectional; /* tells us if we are allowed to print bidirectional */
575 int direction; /* stores the last direction of the print head */
576 } canon_privdata_weave;
577
578
579 static void canon_write_line(const stp_vars_t, const canon_cap_t *, int,
580 unsigned char *, int,
581 unsigned char *, int,
582 unsigned char *, int,
583 unsigned char *, int,
584 unsigned char *, int,
585 unsigned char *, int,
586 unsigned char *, int,
587 int, int, int, int *,int);
588
589
590 /* Codes for possible ink-tank combinations.
591 * Each combo is represented by the colors that can be used with
592 * the installed ink-tank(s)
593 * Combinations of the codes represent the combinations allowed for a model
594 * Note that only preferrable combinations should be used
595 */
596 #define CANON_INK_K 1
597 #define CANON_INK_CMY 2
598 #define CANON_INK_CMYK 4
599 #define CANON_INK_CcMmYK 8
600 #define CANON_INK_CcMmYyK 16
601
602 #define CANON_INK_BLACK_MASK (CANON_INK_K|CANON_INK_CMYK|CANON_INK_CcMmYK)
603
604 #define CANON_INK_PHOTO_MASK (CANON_INK_CcMmYK|CANON_INK_CcMmYyK)
605
606 /* document feeding */
607 #define CANON_SLOT_ASF1 1
608 #define CANON_SLOT_ASF2 2
609 #define CANON_SLOT_MAN1 4
610 #define CANON_SLOT_MAN2 8
611
612 /* model peculiarities */
613 #define CANON_CAP_DMT 0x01ul /* Drop Modulation Technology */
614 #define CANON_CAP_MSB_FIRST 0x02ul /* how to send data */
615 #define CANON_CAP_a 0x04ul
616 #define CANON_CAP_b 0x08ul
617 #define CANON_CAP_q 0x10ul
618 #define CANON_CAP_m 0x20ul
619 #define CANON_CAP_d 0x40ul
620 #define CANON_CAP_t 0x80ul
621 #define CANON_CAP_c 0x100ul
622 #define CANON_CAP_p 0x200ul
623 #define CANON_CAP_l 0x400ul
624 #define CANON_CAP_r 0x800ul
625 #define CANON_CAP_g 0x1000ul
626 #define CANON_CAP_ACKSHORT 0x2000ul
627 #define CANON_CAP_rr 0x4000ul
628 #define CANON_CAP_WEAVE 0x8000ul /* S200 has to be fed with weaved data */
629 /* for Resolutions above 360dpi */
630
631 #define CANON_CAP_STD0 (CANON_CAP_b|CANON_CAP_c|CANON_CAP_d|\
632 CANON_CAP_l|CANON_CAP_q|CANON_CAP_t)
633
634 #define CANON_CAP_STD1 (CANON_CAP_b|CANON_CAP_c|CANON_CAP_d|CANON_CAP_l|\
635 CANON_CAP_m|CANON_CAP_p|CANON_CAP_q|CANON_CAP_t)
636
637 #ifdef EXPERIMENTAL_STUFF
638 #define CANON_MODES(A) A,sizeof(A)/sizeof(canon_variable_printmode_t*)
639 #else
640 #define CANON_MODES(A) 0
641 #endif
642
643 #define CANON_INK(A) A,sizeof(A)/sizeof(canon_variable_inklist_t*)
644
645
646 #ifdef EXPERIMENTAL_STUFF
647
648 #define BC_10 CANON_INK_K /* b/w */
649 #define BC_11 CANON_INK_CMYK /* color */
650 #define BC_12 CANON_INK_CMYK /* photo */
651 #define BC_20 CANON_INK_K /* b/w */
652 #define BC_21 CANON_INK_CMYK /* color */
653 #define BC_22 CANON_INK_CMYK /* photo */
654 #define BC_29 0 /* neon! */
655 #define BC_3031 CANON_INK_CMYK /* color */
656 #define BC_3231 CANON_INK_CcMmYK /* photo */
657
658
659 static const canon_variable_printmode_t canon_nomodes[] =
660 {
661 {0,0,0,0,0,0,0,0,0,0}
662 };
663
664 static const canon_variable_printmode_t canon_modes_30[] = {
665 { 180, 180, 1, BC_10, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
666 { 360, 360, 1, BC_10, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
667 { 720, 360, 1, BC_10, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
668 };
669
670 static const canon_variable_printmode_t canon_modes_85[] = {
671 { 360, 360, 1, BC_10, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
672 { 360, 360, 1, BC_11, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
673 { 360, 360, 2, BC_11, 2, 1.0, 1.0, &ci_CMYK_2, 0,0,0 },
674 { 360, 360, 1, BC_21, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
675 { 360, 360, 2, BC_21, 2, 1.0, 1.0, &ci_CMYK_2, 0,0,0 },
676 };
677
678 static const canon_variable_printmode_t canon_modes_2x00[] = {
679 { 360, 360, 1, BC_20, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
680 { 360, 360, 1, BC_21, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
681 { 360, 360, 1, BC_22, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
682 };
683
684 static const canon_variable_printmode_t canon_modes_6x00[] = {
685 { 360, 360, 1, BC_3031, 2, 1.8, 1.0, &ci_CMYK_1, 0,0,0 },
686 { 360, 360, 2, BC_3031, 2, 1.8, 1.0, &ci_CMYK_2, 0,0,0 },
687 { 720, 720, 1, BC_3031, 2, 1.0, 1.0, &ci_CMYK_1, 0,0,0 },
688 { 1440, 720, 1, BC_3031, 2, 0.5, 1.0, &ci_CMYK_1, 0,0,0 },
689 { 360, 360, 1, BC_3231, 2, 1.8, 1.0, &ci_CcMmYK_1, 0,0,0 },
690 { 360, 360, 2, BC_3231, 2, 1.8, 1.0, &ci_CcMmYK_2, 0,0,0 },
691 { 720, 720, 1, BC_3231, 2, 1.0, 1.0, &ci_CcMmYK_1, 0,0,0 },
692 { 1440, 720, 1, BC_3231, 2, 0.5, 1.0, &ci_CcMmYK_1, 0,0,0 },
693 };
694 #endif
695
696 static const canon_cap_t canon_model_capabilities[] =
697 {
698 /* default settings for unkown models */
699
700 { -1, 8*72,11*72,180,180,20,20,20,20, CANON_INK_K, CANON_SLOT_ASF1, 0 },
701
702 /* ******************************** */
703 /* */
704 /* tested and color-adjusted models */
705 /* */
706 /* ******************************** */
707
708
709
710
711 /* ************************************ */
712 /* */
713 /* tested models w/out color-adjustment */
714 /* */
715 /* ************************************ */
716
717 { /* Canon S200x *//* heads: BC-24 */
718 4202, 3,
719 618, 936, /* 8.58" x 13 " */
720 180, 2880, 2880, 4,
721 10, 10, 9, 20,
722 CANON_INK_CMYK | CANON_INK_CMY | CANON_INK_K,
723 CANON_SLOT_ASF1,
724 CANON_CAP_STD1 | CANON_CAP_rr | CANON_CAP_WEAVE,
725 CANON_MODES(canon_nomodes),
726 #ifndef EXPERIMENTAL_STUFF
727 /* 2880dpi Resolutions: TBD */
728 /* 180x180 360x360 720x720 1440x720 1440x1440 2880x2880 */
729 {-1, 0, 0, 0, 0, -1},
730 /*------- 360x360 720x720 1440x720 1440x1440 ---------*/
731 { 1, 2, 1, 0.5, 0.3, 0.2},
732 CANON_INK(canon_ink_standard),
733 #endif
734 standard_lum_adjustment,
735 standard_hue_adjustment,
736 standard_sat_adjustment
737 },
738
739 { /* Canon BJ 30 *//* heads: BC-10 */
740 30, 1,
741 9.5*72, 14*72,
742 90, 360, 360, 2,
743 11, 9, 10, 18,
744 CANON_INK_K,
745 CANON_SLOT_ASF1,
746 CANON_CAP_STD0 | CANON_CAP_a,
747 CANON_MODES(canon_modes_30),
748 #ifndef EXPERIMENTAL_STUFF
749 {-1,0,0,0,-1,-1}, /*090x090 180x180 360x360 720x360 720x720 1440x1440*/
750 {1,1,1,1,1,1}, /*------- 180x180 360x360 720x360 ------- ---------*/
751 CANON_INK(canon_ink_standard),
752 #endif
753 standard_lum_adjustment,
754 standard_hue_adjustment,
755 standard_sat_adjustment
756 },
757
758 { /* Canon BJC 85 *//* heads: BC-20 BC-21 BC-22 */
759 85, 1,
760 9.5*72, 14*72,
761 90, 720, 360, 2,
762 11, 9, 10, 18,
763 CANON_INK_K | CANON_INK_CMYK | CANON_INK_CcMmYK,
764 CANON_SLOT_ASF1,
765 CANON_CAP_STD0 | CANON_CAP_a | CANON_CAP_DMT,
766 CANON_MODES(canon_modes_85),
767 #ifndef EXPERIMENTAL_STUFF
768 {-1,-1,1,0,-1,-1},/*090x090 180x180 360x360 720x360 720x720 1440x1440*/
769 {1,1,1,1,1,1}, /*------- ------- 360x360 720x360 ------- ---------*/
770 CANON_INK(canon_ink_standard),
771 #endif
772 standard_lum_adjustment,
773 standard_hue_adjustment,
774 standard_sat_adjustment
775 },
776
777 { /* Canon BJC 4300 *//* heads: BC-20 BC-21 BC-22 BC-29 */
778 4300, 1,
779 618, 936, /* 8.58" x 13 " */
780 180, 1440, 720, 2,
781 11, 9, 10, 18,
782 CANON_INK_CMYK | CANON_INK_CcMmYK,
783 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
784 CANON_CAP_STD0 | CANON_CAP_DMT,
785 CANON_MODES(canon_nomodes),
786 #ifndef EXPERIMENTAL_STUFF
787 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
788 {1,1,1,1,1,1}, /*------- 360x360 720x720 1440x720 --------- ---------*/
789 CANON_INK(canon_ink_standard),
790 #endif
791 standard_lum_adjustment,
792 standard_hue_adjustment,
793 standard_sat_adjustment
794 },
795
796 { /* Canon BJC 4400 *//* heads: BC-20 BC-21 BC-22 BC-29 */
797 4400, 1,
798 9.5*72, 14*72,
799 90, 720, 360, 2,
800 11, 9, 10, 18,
801 CANON_INK_K | CANON_INK_CMYK | CANON_INK_CcMmYK,
802 CANON_SLOT_ASF1,
803 CANON_CAP_STD0 | CANON_CAP_a | CANON_CAP_DMT,
804 CANON_MODES(canon_nomodes),
805 #ifndef EXPERIMENTAL_STUFF
806 {-1,-1,0,0,-1,-1},/*090x090 180x180 360x360 720x360 720x720 1440x1440*/
807 {1,1,1,1,1,1}, /*------- ------- 360x360 720x360 ------- ---------*/
808 CANON_INK(canon_ink_standard),
809 #endif
810 standard_lum_adjustment,
811 standard_hue_adjustment,
812 standard_sat_adjustment
813 },
814
815 { /* Canon BJC 6000 *//* heads: BC-30/BC-31 BC-32/BC-31 */
816 6000, 3,
817 618, 936, /* 8.58" x 13 " */
818 180, 1440, 720, 2,
819 11, 9, 10, 18,
820 CANON_INK_CMYK | CANON_INK_CcMmYK,
821 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
822 CANON_CAP_STD1 | CANON_CAP_DMT | CANON_CAP_ACKSHORT,
823 CANON_MODES(canon_modes_6x00),
824 #ifndef EXPERIMENTAL_STUFF
825 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
826 {1,1.8,1,0.5,1,1},/*------- 360x360 720x720 1440x720 --------- ---------*/
827 CANON_INK(canon_ink_standardphoto),
828 #endif
829 standard_lum_adjustment,
830 standard_hue_adjustment,
831 standard_sat_adjustment
832 },
833
834 { /* Canon BJC 6200 *//* heads: BC-30/BC-31 BC-32/BC-31 */
835 6200, 3,
836 618, 936, /* 8.58" x 13 " */
837 180, 1440, 720, 2,
838 11, 9, 10, 18,
839 CANON_INK_CMYK | CANON_INK_CcMmYK,
840 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
841 CANON_CAP_STD1 | CANON_CAP_DMT | CANON_CAP_ACKSHORT,
842 CANON_MODES(canon_modes_6x00),
843 #ifndef EXPERIMENTAL_STUFF
844 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
845 {0,1.8,1,.5,0,0}, /*------- 360x360 720x720 1440x720 --------- ---------*/
846 CANON_INK(canon_ink_standardphoto),
847 #endif
848 standard_lum_adjustment,
849 standard_hue_adjustment,
850 standard_sat_adjustment
851 },
852
853 { /* Canon BJC 6500 *//* heads: BC-30/BC-31 BC-32/BC-31 */
854 6500, 3,
855 842, 17*72,
856 180, 1440, 720, 2,
857 11, 9, 10, 18,
858 CANON_INK_CMYK | CANON_INK_CcMmYK,
859 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
860 CANON_CAP_STD1 | CANON_CAP_DMT,
861 CANON_MODES(canon_modes_6x00),
862 #ifndef EXPERIMENTAL_STUFF
863 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
864 {0,1.8,1,.5,0,0}, /*------- 360x360 720x720 1440x720 --------- ---------*/
865 CANON_INK(canon_ink_standardphoto),
866 #endif
867 standard_lum_adjustment,
868 standard_hue_adjustment,
869 standard_sat_adjustment
870 },
871
872 { /* Canon BJC 8200 *//* heads: BC-50 */
873 8200, 3,
874 842, 17*72,
875 150, 1200,1200, 4,
876 11, 9, 10, 18,
877 CANON_INK_CMYK, /* | CANON_INK_CcMmYK */
878 CANON_SLOT_ASF1,
879 CANON_CAP_STD1 | CANON_CAP_r | CANON_CAP_DMT | CANON_CAP_ACKSHORT,
880 CANON_MODES(canon_nomodes),
881 #ifndef EXPERIMENTAL_STUFF
882 {-1,0,0,-1,0,-1}, /*150x150 300x300 600x600 1200x600 1200x1200 2400x2400*/
883 {1,1,1,1,1,1}, /*------- 300x300 600x600 -------- 1200x1200 ---------*/
884 CANON_INK(canon_ink_superphoto),
885 #endif
886 standard_lum_adjustment,
887 standard_hue_adjustment,
888 standard_sat_adjustment
889 },
890
891
892 /* *************** */
893 /* */
894 /* untested models */
895 /* */
896 /* *************** */
897
898
899 { /* Canon BJC 210 *//* heads: BC-02 BC-05 BC-06 */
900 210, 1,
901 618, 936, /* 8.58" x 13 " */
902 90, 720, 360, 2,
903 11, 9, 10, 18,
904 CANON_INK_K | CANON_INK_CMY,
905 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
906 CANON_CAP_STD0,
907 CANON_MODES(canon_nomodes),
908 #ifndef EXPERIMENTAL_STUFF
909 {0,0,0,0,-1,-1},/*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
910 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
911 CANON_INK(canon_ink_standard),
912 #endif
913 standard_lum_adjustment,
914 standard_hue_adjustment,
915 standard_sat_adjustment
916 },
917 { /* Canon BJC 240 *//* heads: BC-02 BC-05 BC-06 */
918 240, 1,
919 618, 936, /* 8.58" x 13 " */
920 90, 720, 360, 2,
921 11, 9, 10, 18,
922 CANON_INK_K | CANON_INK_CMY,
923 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
924 CANON_CAP_STD0 | CANON_CAP_DMT,
925 CANON_MODES(canon_nomodes),
926 #ifndef EXPERIMENTAL_STUFF
927 {0,0,1,0,-1,-1},/*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
928 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
929 CANON_INK(canon_ink_oldphoto),
930 #endif
931 standard_lum_adjustment,
932 standard_hue_adjustment,
933 standard_sat_adjustment
934 },
935 { /* Canon BJC 250 *//* heads: BC-02 BC-05 BC-06 */
936 250, 1,
937 618, 936, /* 8.58" x 13 " */
938 90, 720, 360, 2,
939 11, 9, 10, 18,
940 CANON_INK_K | CANON_INK_CMY,
941 CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
942 CANON_CAP_STD0 | CANON_CAP_DMT,
943 CANON_MODES(canon_nomodes),
944 #ifndef EXPERIMENTAL_STUFF
945 {0,0,1,0,-1,-1},/*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
946 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
947 CANON_INK(canon_ink_oldphoto),
948 #endif
949 standard_lum_adjustment,
950 standard_hue_adjustment,
951 standard_sat_adjustment
952 },
953 { /* Canon BJC 1000 *//* heads: BC-02 BC-05 BC-06 */
954 1000, 1,
955 842, 17*72,
956 90, 720, 360, 2,
957 11, 9, 10, 18,
958 CANON_INK_K | CANON_INK_CMY,
959 CANON_SLOT_ASF1,
960 CANON_CAP_STD0 | CANON_CAP_DMT | CANON_CAP_a,
961 CANON_MODES(canon_nomodes),
962 #ifndef EXPERIMENTAL_STUFF
963 {0,0,1,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
964 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
965 CANON_INK(canon_ink_oldphoto),
966 #endif
967 standard_lum_adjustment,
968 standard_hue_adjustment,
969 standard_sat_adjustment
970 },
971 { /* Canon BJC 2000 *//* heads: BC-20 BC-21 BC-22 BC-29 */
972 2000, 1,
973 842, 17*72,
974 180, 720, 360, 2,
975 11, 9, 10, 18,
976 CANON_INK_CMYK,
977 CANON_SLOT_ASF1,
978 CANON_CAP_STD0 | CANON_CAP_a,
979 CANON_MODES(canon_nomodes),
980 #ifndef EXPERIMENTAL_STUFF
981 {0,0,-1,-1,-1,-1},/*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
982 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
983 CANON_INK(canon_ink_standard),
984 #endif
985 standard_lum_adjustment,
986 standard_hue_adjustment,
987 standard_sat_adjustment
988 },
989 { /* Canon BJC 3000 *//* heads: BC-30 BC-33 BC-34 */
990 3000, 3,
991 842, 17*72,
992 180, 1440, 720, 2,
993 11, 9, 10, 18,
994 CANON_INK_CMYK | CANON_INK_CcMmYK,
995 CANON_SLOT_ASF1,
996 CANON_CAP_STD0 | CANON_CAP_a | CANON_CAP_DMT, /*FIX? should have _r? */
997 CANON_MODES(canon_nomodes),
998 #ifndef EXPERIMENTAL_STUFF
999 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
1000 {1,1,1,1,1,1}, /*------- 360x360 720x720 1440x720 --------- ---------*/
1001 CANON_INK(canon_ink_standard),
1002 #endif
1003 standard_lum_adjustment,
1004 standard_hue_adjustment,
1005 standard_sat_adjustment
1006 },
1007 { /* Canon BJC 6100 *//* heads: BC-30/BC-31 BC-32/BC-31 */
1008 6100, 3,
1009 842, 17*72,
1010 180, 1440, 720, 2,
1011 11, 9, 10, 18,
1012 CANON_INK_CMYK | CANON_INK_CcMmYK,
1013 CANON_SLOT_ASF1,
1014 CANON_CAP_STD1 | CANON_CAP_a | CANON_CAP_r | CANON_CAP_DMT,
1015 CANON_MODES(canon_modes_6x00),
1016 #ifndef EXPERIMENTAL_STUFF
1017 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
1018 {1,1,1,1,1,1}, /*------- 360x360 720x720 1440x720 --------- ---------*/
1019 CANON_INK(canon_ink_standard),
1020 #endif
1021 standard_lum_adjustment,
1022 standard_hue_adjustment,
1023 standard_sat_adjustment
1024 },
1025 { /* Canon BJC 7000 *//* heads: BC-60/BC-61 BC-60/BC-62 ??????? */
1026 7000, 3,
1027 842, 17*72,
1028 150, 1200, 600, 2,
1029 11, 9, 10, 18,
1030 CANON_INK_CMYK | CANON_INK_CcMmYyK,
1031 CANON_SLOT_ASF1,
1032 CANON_CAP_STD1,
1033 CANON_MODES(canon_nomodes),
1034 #ifndef EXPERIMENTAL_STUFF
1035 {-1,0,0,0,-1,-1}, /*150x150 300x300 600x600 1200x600 1200x1200 2400x2400*/
1036 {1,3.5,1.8,1,1,1},/*------- 300x300 600x600 1200x600 --------- ---------*/
1037 CANON_INK(canon_ink_standard),
1038 #endif
1039 standard_lum_adjustment,
1040 standard_hue_adjustment,
1041 standard_sat_adjustment
1042 },
1043 { /* Canon BJC 7100 *//* heads: BC-60/BC-61 BC-60/BC-62 ??????? */
1044 7100, 3,
1045 842, 17*72,
1046 150, 1200, 600, 2,
1047 11, 9, 10, 18,
1048 CANON_INK_CMYK | CANON_INK_CcMmYyK,
1049 CANON_SLOT_ASF1,
1050 CANON_CAP_STD0,
1051 CANON_MODES(canon_nomodes),
1052 #ifndef EXPERIMENTAL_STUFF
1053 {-1,0,0,0,-1,-1}, /*150x150 300x300 600x600 1200x600 1200x1200 2400x2400*/
1054 {1,1,1,1,1,1}, /*------- 300x300 600x600 1200x600 --------- ---------*/
1055 CANON_INK(canon_ink_standard),
1056 #endif
1057 standard_lum_adjustment,
1058 standard_hue_adjustment,
1059 standard_sat_adjustment
1060 },
1061
1062 /*****************************/
1063 /* */
1064 /* extremely fuzzy models */
1065 /* (might never work at all) */
1066 /* */
1067 /*****************************/
1068
1069 { /* Canon BJC 5100 *//* heads: BC-20 BC-21 BC-22 BC-23 BC-29 */
1070 5100, 1,
1071 17*72, 22*72,
1072 180, 1440, 720, 2,
1073 11, 9, 10, 18,
1074 CANON_INK_CMYK | CANON_INK_CcMmYK,
1075 CANON_SLOT_ASF1,
1076 CANON_CAP_STD0 | CANON_CAP_DMT,
1077 CANON_MODES(canon_nomodes),
1078 #ifndef EXPERIMENTAL_STUFF
1079 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
1080 {1,1,1,1,1,1}, /*------- 360x360 720x720 1440x720 --------- ---------*/
1081 CANON_INK(canon_ink_standard),
1082 #endif
1083 standard_lum_adjustment,
1084 standard_hue_adjustment,
1085 standard_sat_adjustment
1086 },
1087 { /* Canon BJC 5500 *//* heads: BC-20 BC-21 BC-29 */
1088 5500, 1,
1089 22*72, 34*72,
1090 180, 720, 360, 2,
1091 11, 9, 10, 18,
1092 CANON_INK_CMYK | CANON_INK_CcMmYK,
1093 CANON_SLOT_ASF1,
1094 CANON_CAP_STD0 | CANON_CAP_a,
1095 CANON_MODES(canon_nomodes),
1096 #ifndef EXPERIMENTAL_STUFF
1097 {0,0,-1,-1,-1,-1},/*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
1098 {1,1,1,1,1,1}, /*180x180 360x360 ------- -------- --------- ---------*/
1099 CANON_INK(canon_ink_standard),
1100 #endif
1101 standard_lum_adjustment,
1102 standard_hue_adjustment,
1103 standard_sat_adjustment
1104 },
1105 { /* Canon BJC 6500 *//* heads: BC-30/BC-31 BC-32/BC-31 */
1106 6500, 3,
1107 17*72, 22*72,
1108 180, 1440, 720, 2,
1109 11, 9, 10, 18,
1110 CANON_INK_CMYK | CANON_INK_CcMmYK,
1111 CANON_SLOT_ASF1,
1112 CANON_CAP_STD1 | CANON_CAP_a | CANON_CAP_DMT,
1113 CANON_MODES(canon_nomodes),
1114 #ifndef EXPERIMENTAL_STUFF
1115 {-1,1,0,0,-1,-1}, /*180x180 360x360 720x720 1440x720 1440x1440 2880x2880*/
1116 {1,1,1,1,1,1}, /*------- 360x360 720x720 1440x720 --------- ---------*/
1117 CANON_INK(canon_ink_standard),
1118 #endif
1119 standard_lum_adjustment,
1120 standard_hue_adjustment,
1121 standard_sat_adjustment
1122 },
1123 { /* Canon BJC 8500 *//* heads: BC-80/BC-81 BC-82/BC-81 */
1124 8500, 3,
1125 17*72, 22*72,
1126 150, 1200,1200, 2,
1127 11, 9, 10, 18,
1128 CANON_INK_CMYK | CANON_INK_CcMmYK,
1129 CANON_SLOT_ASF1,
1130 CANON_CAP_STD0,
1131 CANON_MODES(canon_nomodes),
1132 #ifndef EXPERIMENTAL_STUFF
1133 {-1,0,0,-1,0,-1}, /*150x150 300x300 600x600 1200x600 1200x1200 2400x2400*/
1134 {1,1,1,1,1,1}, /*------- 300x300 600x600 -------- 1200x1200 ---------*/
1135 CANON_INK(canon_ink_standard),
1136 #endif
1137 standard_lum_adjustment,
1138 standard_hue_adjustment,
1139 standard_sat_adjustment
1140 },
1141 };
1142
1143 typedef struct {
1144 const char *name;
1145 const char *text;
1146 int media_code;
1147 double base_density;
1148 double k_lower_scale;
1149 double k_upper;
1150 const double *hue_adjustment;
1151 const double *lum_adjustment;
1152 const double *sat_adjustment;
1153 } paper_t;
1154
1155 typedef struct {
1156 const canon_cap_t *caps;
1157 int output_type;
1158 const paper_t *pt;
1159 int print_head;
1160 int colormode;
1161 const char *source_str;
1162 int xdpi;
1163 int ydpi;
1164 int page_width;
1165 int page_height;
1166 int top;
1167 int left;
1168 int bits;
1169 } canon_init_t;
1170
1171 static const paper_t canon_paper_list[] = {
1172 { "Plain", N_ ("Plain Paper"), 0x00, 0.50, 0.25, 0.500, 0, 0, 0 },
1173 { "Transparency", N_ ("Transparencies"), 0x02, 1.00, 1.00, 0.900, 0, 0, 0 },
1174 { "BackPrint", N_ ("Back Print Film"), 0x03, 1.00, 1.00, 0.900, 0, 0, 0 },
1175 { "Fabric", N_ ("Fabric Sheets"), 0x04, 0.50, 0.25, 0.500, 0, 0, 0 },
1176 { "Envelope", N_ ("Envelope"), 0x08, 0.50, 0.25, 0.500, 0, 0, 0 },
1177 { "Coated", N_ ("High Resolution Paper"), 0x07, 0.78, 0.25, 0.500, 0, 0, 0 },
1178 { "TShirt", N_ ("T-Shirt Transfers"), 0x03, 0.50, 0.25, 0.500, 0, 0, 0 },
1179 { "GlossyFilm", N_ ("High Gloss Film"), 0x06, 1.00, 1.00, 0.999, 0, 0, 0 },
1180 { "GlossyPaper", N_ ("Glossy Photo Paper"), 0x05, 1.00, 1.00, 0.999, 0, 0, 0 },
1181 { "GlossyCard", N_ ("Glossy Photo Cards"), 0x0a, 1.00, 1.00, 0.999, 0, 0, 0 },
1182 { "GlossyPro", N_ ("Photo Paper Pro"), 0x09, 1.00, 1.00, 0.999, 0, 0, 0 },
1183 { "Other", N_ ("Other"), 0x00, 0.50, 0.25, .5, 0, 0, 0 },
1184 };
1185
1186 /* ---- Function prototypes ----*/
1187
1188 static void canon_advance_paper(stp_vars_t, int);
1189
1190 static const int paper_type_count = sizeof(canon_paper_list) / sizeof(paper_t);
1191
1192 static void canon_flush_pass(stp_softweave_t *sw, int passno, int model, int width,
1193 int hoffset, int ydpi, int xdpi, int physical_xdpi,
1194 int vertical_subpass);
1195
1196 static const paper_t *
get_media_type(const char * name)1197 get_media_type(const char *name)
1198 {
1199 int i;
1200 for (i = 0; i < paper_type_count; i++)
1201 {
1202 /* translate paper_t.name */
1203 if (!strcmp(name, canon_paper_list[i].name))
1204 return &(canon_paper_list[i]);
1205 }
1206 return NULL;
1207 }
1208
1209 static const canon_cap_t *
canon_get_model_capabilities(int model)1210 canon_get_model_capabilities(int model)
1211 {
1212 int i;
1213 int models= sizeof(canon_model_capabilities) / sizeof(canon_cap_t);
1214 for (i=0; i<models; i++) {
1215 if (canon_model_capabilities[i].model == model) {
1216 return &(canon_model_capabilities[i]);
1217 }
1218 }
1219 stp_deprintf(STP_DBG_CANON,"canon: model %d not found in capabilities list.\n",model);
1220 return &(canon_model_capabilities[0]);
1221 }
1222
1223 static int
canon_source_type(const char * name,const canon_cap_t * caps)1224 canon_source_type(const char *name, const canon_cap_t * caps)
1225 {
1226 /* used internally: do not translate */
1227 if (!strcmp(name,"Auto")) return 4;
1228 if (!strcmp(name,"Manual")) return 0;
1229 if (!strcmp(name,"ManualNP")) return 1;
1230
1231 stp_deprintf(STP_DBG_CANON,"canon: Unknown source type '%s' - reverting to auto\n",name);
1232 return 4;
1233 }
1234
1235 static int
canon_printhead_type(const char * name,const canon_cap_t * caps)1236 canon_printhead_type(const char *name, const canon_cap_t * caps)
1237 {
1238 /* used internally: do not translate */
1239 if (!strcmp(name,"Gray")) return 0;
1240 if (!strcmp(name,"RGB")) return 1;
1241 if (!strcmp(name,"CMYK")) return 2;
1242 if (!strcmp(name,"PhotoCMY")) return 3;
1243 if (!strcmp(name,"Photo")) return 4;
1244 if (!strcmp(name,"PhotoCMYK")) return 5;
1245
1246 if (*name == 0) {
1247 if (caps->inks & CANON_INK_CMYK) return 2;
1248 if (caps->inks & CANON_INK_CMY) return 1;
1249 if (caps->inks & CANON_INK_K) return 0;
1250 }
1251
1252 stp_deprintf(STP_DBG_CANON,"canon: Unknown head combo '%s' - reverting to black",name);
1253 return 0;
1254 }
1255
1256 static colormode_t
canon_printhead_colors(const char * name,const canon_cap_t * caps)1257 canon_printhead_colors(const char *name, const canon_cap_t * caps)
1258 {
1259 /* used internally: do not translate */
1260 if (!strcmp(name,"Gray")) return COLOR_MONOCHROME;
1261 if (!strcmp(name,"RGB")) return COLOR_CMY;
1262 if (!strcmp(name,"CMYK")) return COLOR_CMYK;
1263 if (!strcmp(name,"PhotoCMY")) return COLOR_CCMMYK;
1264 if (!strcmp(name,"PhotoCMYK")) return COLOR_CCMMYYK;
1265
1266 if (*name == 0) {
1267 if (caps->inks & CANON_INK_CMYK) return COLOR_CMYK;
1268 if (caps->inks & CANON_INK_CMY) return COLOR_CMY;
1269 if (caps->inks & CANON_INK_K) return COLOR_MONOCHROME;
1270 }
1271
1272 stp_deprintf(STP_DBG_CANON,"canon: Unknown head combo '%s' - reverting to black",name);
1273 return COLOR_MONOCHROME;
1274 }
1275
1276 static unsigned char
canon_size_type(const stp_vars_t v,const canon_cap_t * caps)1277 canon_size_type(const stp_vars_t v, const canon_cap_t * caps)
1278 {
1279 const stp_papersize_t pp = stp_get_papersize_by_size(stp_get_page_height(v),
1280 stp_get_page_width(v));
1281 if (pp)
1282 {
1283 const char *name = stp_papersize_get_name(pp);
1284 /* used internally: do not translate */
1285 /* built ins: */
1286 if (!strcmp(name,"A5")) return 0x01;
1287 if (!strcmp(name,"A4")) return 0x03;
1288 if (!strcmp(name,"B5")) return 0x08;
1289 if (!strcmp(name,"Letter")) return 0x0d;
1290 if (!strcmp(name,"Legal")) return 0x0f;
1291 if (!strcmp(name,"COM10")) return 0x16;
1292 if (!strcmp(name,"DL")) return 0x17;
1293 if (!strcmp(name,"LetterExtra")) return 0x2a;
1294 if (!strcmp(name,"A4Extra")) return 0x2b;
1295 if (!strcmp(name,"w288h144")) return 0x2d;
1296 /* custom */
1297
1298 stp_deprintf(STP_DBG_CANON,"canon: Unknown paper size '%s' - using custom\n",name);
1299 } else {
1300 stp_deprintf(STP_DBG_CANON,"canon: Couldn't look up paper size %dx%d - "
1301 "using custom\n",stp_get_page_height(v), stp_get_page_width(v));
1302 }
1303 return 0;
1304 }
1305
1306 static char *
c_strdup(const char * s)1307 c_strdup(const char *s)
1308 {
1309 char *ret = stp_malloc(strlen(s) + 1);
1310 strcpy(ret, s);
1311 return ret;
1312 }
1313
1314 #ifndef EXPERIMENTAL_STUFF
canon_res_code(const canon_cap_t * caps,int xdpi,int ydpi)1315 static int canon_res_code(const canon_cap_t * caps, int xdpi, int ydpi)
1316 {
1317 int x, y, res= 0;
1318
1319 for (x=1; x<6; x++) if ((xdpi/caps->base_res) == (1<<(x-1))) res= (x<<4);
1320 for (y=1; y<6; y++) if ((ydpi/caps->base_res) == (1<<(y-1))) res|= y;
1321
1322 return res;
1323 }
1324 #else
canon_printmode(const canon_cap_t * caps,int xdpi,int ydpi,int bpp,int head)1325 static const canon_variable_printmode_t *canon_printmode(const canon_cap_t * caps,
1326 int xdpi, int ydpi,
1327 int bpp, int head)
1328 {
1329 const canon_variable_printmode_t *modes;
1330 int modes_cnt;
1331 int i;
1332 if (!caps) return 0;
1333 modes= caps->printmodes;
1334 modes_cnt= caps->printmodes_cnt;
1335 /* search for the right printmode: */
1336 for (i=0; i<modes_cnt; i++) {
1337 if ((modes[i].xdpi== xdpi) && (modes[i].ydpi== ydpi) &&
1338 (modes[i].bits== bpp) && (modes[i].printhead== head))
1339 {
1340 return &(modes[i]);
1341 }
1342 }
1343 /* nothing found -> either return 0 or apply some policy to
1344 * get a fallback printmode
1345 */
1346 if (modes[0].xdpi) return modes;
1347 return 0;
1348 }
1349 #endif
1350
1351 static int
canon_ink_type(const canon_cap_t * caps,int res_code)1352 canon_ink_type(const canon_cap_t * caps, int res_code)
1353 {
1354 #ifndef EXPERIMENTAL_STUFF
1355 switch (res_code)
1356 {
1357 case 0x11: return caps->dot_sizes.dot_r11;
1358 case 0x22: return caps->dot_sizes.dot_r22;
1359 case 0x33: return caps->dot_sizes.dot_r33;
1360 case 0x43: return caps->dot_sizes.dot_r43;
1361 case 0x44: return caps->dot_sizes.dot_r44;
1362 case 0x55: return caps->dot_sizes.dot_r55;
1363 }
1364 return -1;
1365 #else
1366 return -1;
1367 #endif
1368 }
1369
1370 static const double *
canon_lum_adjustment(const stp_printer_t printer)1371 canon_lum_adjustment(const stp_printer_t printer)
1372 {
1373 const canon_cap_t * caps=
1374 canon_get_model_capabilities(stp_printer_get_model(printer));
1375 return (caps->lum_adjustment);
1376 }
1377
1378 static const double *
canon_hue_adjustment(const stp_printer_t printer)1379 canon_hue_adjustment(const stp_printer_t printer)
1380 {
1381 const canon_cap_t * caps=
1382 canon_get_model_capabilities(stp_printer_get_model(printer));
1383 return (caps->hue_adjustment);
1384 }
1385
1386 static const double *
canon_sat_adjustment(const stp_printer_t printer)1387 canon_sat_adjustment(const stp_printer_t printer)
1388 {
1389 const canon_cap_t * caps=
1390 canon_get_model_capabilities(stp_printer_get_model(printer));
1391 return (caps->sat_adjustment);
1392 }
1393
1394 static double
canon_density(const canon_cap_t * caps,int res_code)1395 canon_density(const canon_cap_t * caps, int res_code)
1396 {
1397 #ifndef EXPERIMENTAL_STUFF
1398 switch (res_code)
1399 {
1400 case 0x11: return caps->densities.d_r11;
1401 case 0x22: return caps->densities.d_r22;
1402 case 0x33: return caps->densities.d_r33;
1403 case 0x43: return caps->densities.d_r43;
1404 case 0x44: return caps->densities.d_r44;
1405 case 0x55: return caps->densities.d_r55;
1406 default:
1407 stp_deprintf(STP_DBG_CANON,"no such res_code 0x%x in density of model %d\n",
1408 res_code,caps->model);
1409 return 0.2;
1410 }
1411 #else
1412 return 0.2;
1413 #endif
1414 }
1415
1416 static const canon_variable_inkset_t *
canon_inks(const canon_cap_t * caps,int res_code,int colors,int bits)1417 canon_inks(const canon_cap_t * caps, int res_code, int colors, int bits)
1418 {
1419 #ifndef EXPERIMENTAL_STUFF
1420 const canon_variable_inklist_t *inks = caps->inxs;
1421 int i;
1422
1423 if (!inks)
1424 return NULL;
1425
1426 for (i=0; i<caps->inxs_cnt; i++) {
1427 stp_deprintf(STP_DBG_CANON,"hmm, trying ink for resolution code "
1428 "%x, %d bits, %d colors\n",res_code,inks[i].bits,inks[i].colors);
1429 if ((inks[i].bits==bits) && (inks[i].colors==colors)) {
1430 stp_deprintf(STP_DBG_CANON,"wow, found ink for resolution code "
1431 "%x, %d bits, %d colors\n",res_code,bits,colors);
1432 switch (res_code)
1433 {
1434 case 0x11: return inks[i].r11;
1435 case 0x22: return inks[i].r22;
1436 case 0x33: return inks[i].r33;
1437 case 0x43: return inks[i].r43;
1438 case 0x44: return inks[i].r44;
1439 case 0x55: return inks[i].r55;
1440 }
1441 }
1442 }
1443 stp_deprintf(STP_DBG_CANON,"ooo, found no ink for resolution code "
1444 "%x, %d bits, %d colors in all %d defs!\n",
1445 res_code,bits,colors,caps->inxs_cnt);
1446 return NULL;
1447 #else
1448 return NULL;
1449 #endif
1450 }
1451
1452 static void
canon_describe_resolution(const stp_printer_t printer,const char * resolution,int * x,int * y)1453 canon_describe_resolution(const stp_printer_t printer,
1454 const char *resolution, int *x, int *y)
1455 {
1456 *x = -1;
1457 *y = -1;
1458 sscanf(resolution, "%dx%d", x, y);
1459 return;
1460 }
1461
1462 static const stp_param_t media_sources[] =
1463 {
1464 { "Auto", N_ ("Auto Sheet Feeder") },
1465 { "Manual", N_ ("Manual with Pause") },
1466 { "ManualNP", N_ ("Manual without Pause") }
1467 };
1468
1469
1470 /*
1471 * 'canon_parameters()' - Return the parameter values for the given parameter.
1472 */
1473
1474 static stp_param_t * /* O - Parameter values */
canon_parameters(const stp_printer_t printer,const char * ppd_file,const char * name,int * count)1475 canon_parameters(const stp_printer_t printer, /* I - Printer model */
1476 const char *ppd_file, /* I - PPD file (not used) */
1477 const char *name, /* I - Name of parameter */
1478 int *count) /* O - Number of values */
1479 {
1480 int i;
1481 stp_param_t *valptrs= 0;
1482
1483 const canon_cap_t * caps=
1484 canon_get_model_capabilities(stp_printer_get_model(printer));
1485
1486 if (count == NULL)
1487 return (NULL);
1488
1489 *count = 0;
1490
1491 if (name == NULL)
1492 return (NULL);
1493
1494 if (strcmp(name, "PageSize") == 0)
1495 {
1496 int height_limit, width_limit;
1497 int papersizes = stp_known_papersizes();
1498 valptrs = stp_zalloc(sizeof(stp_param_t) * papersizes);
1499 *count = 0;
1500
1501 width_limit = caps->max_width;
1502 height_limit = caps->max_height;
1503
1504 for (i = 0; i < papersizes; i++) {
1505 const stp_papersize_t pt = stp_get_papersize_by_index(i);
1506 if (strlen(stp_papersize_get_name(pt)) > 0 &&
1507 stp_papersize_get_width(pt) <= width_limit &&
1508 stp_papersize_get_height(pt) <= height_limit)
1509 {
1510 valptrs[*count].name = c_strdup(stp_papersize_get_name(pt));
1511 valptrs[*count].text = c_strdup(stp_papersize_get_text(pt));
1512 (*count)++;
1513 }
1514 }
1515 }
1516 else if (strcmp(name, "Resolution") == 0)
1517 {
1518 char tmp[100];
1519 int x,y;
1520 int c= 0;
1521 int t;
1522 valptrs = stp_zalloc(sizeof(stp_param_t) * 10);
1523
1524 for (x=1; x<6; x++) {
1525 for (y=x-1; y<x+1; y++) {
1526 if ((t= canon_ink_type(caps,(x<<4)|y)) > -1) {
1527 sprintf(tmp,"%dx%ddpi",
1528 (1<<x)/2*caps->base_res,(1<<y)/2*caps->base_res);
1529 valptrs[c].name= c_strdup(tmp);
1530
1531 sprintf(tmp,"%dx%d DPI",
1532 (1<<x)/2*caps->base_res,(1<<y)/2*caps->base_res);
1533 stp_deprintf(STP_DBG_CANON,"supports mode '%s'\n",tmp);
1534 valptrs[c++].text= c_strdup(tmp);
1535
1536 if (t==1) {
1537 sprintf(tmp,"%dx%ddmt",
1538 (1<<x)/2*caps->base_res,(1<<y)/2*caps->base_res);
1539 valptrs[c].name= c_strdup(tmp);
1540 sprintf(tmp,"%dx%d DPI DMT",
1541 (1<<x)/2*caps->base_res,(1<<y)/2*caps->base_res);
1542 stp_deprintf(STP_DBG_CANON,"supports mode '%s'\n",tmp);
1543 valptrs[c++].text = c_strdup(tmp);
1544 }
1545 }
1546 }
1547 }
1548 *count= c;
1549 }
1550 else if (strcmp(name, "InkType") == 0)
1551 {
1552 int c= 0;
1553 valptrs = stp_zalloc(sizeof(stp_param_t) * 5);
1554 /* used internally: do not translate */
1555 if ((caps->inks & CANON_INK_K))
1556 {
1557 valptrs[c].name = c_strdup("Gray");
1558 valptrs[c++].text = c_strdup(_("Black"));
1559 }
1560 if ((caps->inks & CANON_INK_CMY))
1561 {
1562 valptrs[c].name = c_strdup("RGB");
1563 valptrs[c++].text = c_strdup(_("CMY Color"));
1564 }
1565 if ((caps->inks & CANON_INK_CMYK))
1566 {
1567 valptrs[c].name = c_strdup("CMYK");
1568 valptrs[c++].text = c_strdup(_("CMYK Color"));
1569 }
1570 if ((caps->inks & CANON_INK_CcMmYK))
1571 {
1572 valptrs[c].name = c_strdup("PhotoCMY");
1573 valptrs[c++].text = c_strdup(_("Photo CcMmY Color"));
1574 }
1575 if ((caps->inks & CANON_INK_CcMmYyK))
1576 {
1577 valptrs[c].name = c_strdup("PhotoCMYK");
1578 valptrs[c++].text = c_strdup(_("Photo CcMmYK Color"));
1579 }
1580
1581 *count = c;
1582 }
1583 else if (strcmp(name, "MediaType") == 0)
1584 {
1585 *count = sizeof(canon_paper_list) / sizeof(canon_paper_list[0]);
1586
1587 valptrs = stp_zalloc(*count * sizeof(stp_param_t));
1588
1589 for (i = 0; i < *count; i ++)
1590 {
1591 valptrs[i].name = c_strdup(canon_paper_list[i].name);
1592 valptrs[i].text = c_strdup(_(canon_paper_list[i].text));
1593 }
1594 }
1595 else if (strcmp(name, "InputSlot") == 0)
1596 {
1597 *count = sizeof(media_sources) / sizeof(media_sources[0]);
1598
1599 valptrs = stp_zalloc(*count * sizeof(stp_param_t));
1600 for (i = 0; i < *count; i ++)
1601 {
1602 /* translate media_sources */
1603 valptrs[i].name = c_strdup(media_sources[i].name);
1604 valptrs[i].text = c_strdup(_(media_sources[i].text));
1605 }
1606 }
1607 else
1608 return (NULL);
1609
1610 return (valptrs);
1611 }
1612
1613 static const char *
canon_default_parameters(const stp_printer_t printer,const char * ppd_file,const char * name)1614 canon_default_parameters(const stp_printer_t printer,
1615 const char *ppd_file,
1616 const char *name)
1617 {
1618 int i;
1619 const canon_cap_t * caps=
1620 canon_get_model_capabilities(stp_printer_get_model(printer));
1621
1622 if (name == NULL)
1623 return (NULL);
1624
1625 if (strcmp(name, "PageSize") == 0)
1626 {
1627 int height_limit, width_limit;
1628 int papersizes = stp_known_papersizes();
1629
1630 width_limit = caps->max_width;
1631 height_limit = caps->max_height;
1632
1633 for (i = 0; i < papersizes; i++) {
1634 const stp_papersize_t pt = stp_get_papersize_by_index(i);
1635 if (strlen(stp_papersize_get_name(pt)) > 0 &&
1636 stp_papersize_get_width(pt) <= width_limit &&
1637 stp_papersize_get_height(pt) <= height_limit)
1638 return (stp_papersize_get_name(pt));
1639 }
1640 return NULL;
1641 }
1642 else if (strcmp(name, "Resolution") == 0)
1643 {
1644 char tmp[100];
1645 int x,y;
1646 int t;
1647 int min_res = caps->base_res;
1648 while (min_res < 300)
1649 min_res *= 2;
1650
1651 for (x=1; x<6; x++)
1652 {
1653 for (y=x-1; y<x+1; y++)
1654 {
1655 if ((t= canon_ink_type(caps,(x<<4)|y)) > -1)
1656 {
1657 if (t == 1)
1658 sprintf(tmp, "%dx%ddmt", min_res, min_res);
1659 else
1660 sprintf(tmp,"%dx%ddpi", min_res, min_res);
1661
1662 stp_deprintf(STP_DBG_CANON,"supports mode '%s'\n",tmp);
1663 return (c_strdup(tmp));
1664 }
1665 }
1666 }
1667 return NULL;
1668 }
1669 else if (strcmp(name, "InkType") == 0)
1670 {
1671 /* used internally: do not translate */
1672 if ((caps->inks & CANON_INK_K))
1673 return ("Gray");
1674 if ((caps->inks & CANON_INK_CMY))
1675 return ("RGB");
1676 if ((caps->inks & CANON_INK_CMYK))
1677 return ("CMYK");
1678 if ((caps->inks & CANON_INK_CcMmYK))
1679 return ("PhotoCMY");
1680 if ((caps->inks & CANON_INK_CcMmYyK))
1681 return ("PhotoCMYK");
1682 return NULL;
1683 }
1684 else if (strcmp(name, "MediaType") == 0)
1685 {
1686 return (canon_paper_list[0].name);
1687 }
1688 else if (strcmp(name, "InputSlot") == 0)
1689 {
1690 return (media_sources[0].name);
1691 }
1692 else
1693 return (NULL);
1694 }
1695
1696
1697 /*
1698 * 'canon_imageable_area()' - Return the imageable area of the page.
1699 */
1700
1701 static void
canon_imageable_area(const stp_printer_t printer,const stp_vars_t v,int * left,int * right,int * bottom,int * top)1702 canon_imageable_area(const stp_printer_t printer, /* I - Printer model */
1703 const stp_vars_t v, /* I */
1704 int *left, /* O - Left position in points */
1705 int *right, /* O - Right position in points */
1706 int *bottom, /* O - Bottom position in points */
1707 int *top) /* O - Top position in points */
1708 {
1709 int width, length; /* Size of page */
1710
1711 const canon_cap_t * caps=
1712 canon_get_model_capabilities(stp_printer_get_model(printer));
1713
1714 stp_default_media_size(printer, v, &width, &length);
1715
1716 *left = caps->border_left;
1717 *right = width - caps->border_right;
1718 *top = length - caps->border_top;
1719 *bottom = caps->border_bottom;
1720 }
1721
1722 static void
canon_limit(const stp_printer_t printer,const stp_vars_t v,int * width,int * height,int * min_width,int * min_height)1723 canon_limit(const stp_printer_t printer, /* I - Printer model */
1724 const stp_vars_t v, /* I */
1725 int *width,
1726 int *height,
1727 int *min_width,
1728 int *min_height)
1729 {
1730 const canon_cap_t * caps=
1731 canon_get_model_capabilities(stp_printer_get_model(printer));
1732 *width = caps->max_width;
1733 *height = caps->max_height;
1734 *min_width = 1;
1735 *min_height = 1;
1736 }
1737
1738 /*
1739 * 'canon_cmd()' - Sends a command with variable args
1740 */
1741 static void
canon_cmd(const stp_vars_t v,const char * ini,const char cmd,int num,...)1742 canon_cmd(const stp_vars_t v, /* I - the printer */
1743 const char *ini, /* I - 2 bytes start code */
1744 const char cmd, /* I - command code */
1745 int num, /* I - number of arguments */
1746 ... /* I - the args themselves */
1747 )
1748 {
1749 unsigned char *buffer = stp_zalloc(num + 1);
1750 int i;
1751 va_list ap;
1752
1753 if (num)
1754 {
1755 va_start(ap, num);
1756 for (i=0; i<num; i++)
1757 buffer[i]= (unsigned char) va_arg(ap, int);
1758 va_end(ap);
1759 }
1760
1761 stp_zfwrite(ini,2,1,v);
1762 if (cmd)
1763 {
1764 stp_putc(cmd,v);
1765 stp_putc((num & 255),v);
1766 stp_putc((num >> 8 ),v);
1767 if (num)
1768 stp_zfwrite((const char *)buffer,num,1,v);
1769 }
1770 stp_free(buffer);
1771 }
1772
1773 #define PUT(WHAT,VAL,RES) stp_deprintf(STP_DBG_CANON,"canon: "WHAT\
1774 " is %04x =% 5d = %f\" = %f mm\n",(VAL),(VAL),(VAL)/(1.*RES),(VAL)/(RES/25.4))
1775
1776 #define ESC28 "\033\050"
1777 #define ESC5b "\033\133"
1778 #define ESC40 "\033\100"
1779
1780 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
1781 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
1782
1783 /* ESC [K -- -- reset printer:
1784 */
1785 static void
canon_init_resetPrinter(const stp_vars_t v,canon_init_t * init)1786 canon_init_resetPrinter(const stp_vars_t v, canon_init_t *init)
1787 {
1788 unsigned long f=init->caps->features;
1789 if (f & (CANON_CAP_ACKSHORT))
1790 {
1791 canon_cmd(v,ESC5b,0x4b, 2, 0x00,0x1f);
1792 stp_puts("BJLSTART\nControlMode=Common\n",v);
1793 if (f & CANON_CAP_ACKSHORT) stp_puts("AckTime=Short\n",v);
1794 stp_puts("BJLEND\n",v);
1795 }
1796 canon_cmd(v,ESC5b,0x4b, 2, 0x00,0x0f);
1797 }
1798
1799 /* ESC (a -- 0x61 -- cmdSetPageMode --:
1800 */
1801 static void
canon_init_setPageMode(const stp_vars_t v,canon_init_t * init)1802 canon_init_setPageMode(const stp_vars_t v, canon_init_t *init)
1803 {
1804 if (!(init->caps->features & CANON_CAP_a))
1805 return;
1806
1807 if (init->caps->features & CANON_CAP_a)
1808 canon_cmd(v,ESC28,0x61, 1, 0x01);
1809 }
1810
1811 /* ESC (b -- 0x62 -- -- set data compression:
1812 */
1813 static void
canon_init_setDataCompression(const stp_vars_t v,canon_init_t * init)1814 canon_init_setDataCompression(const stp_vars_t v, canon_init_t *init)
1815 {
1816 if (!(init->caps->features & CANON_CAP_b))
1817 return;
1818
1819 canon_cmd(v,ESC28,0x62, 1, 0x01);
1820 }
1821
1822 /* ESC (c -- 0x63 -- cmdSetColor --:
1823 */
1824 static void
canon_init_setColor(const stp_vars_t v,canon_init_t * init)1825 canon_init_setColor(const stp_vars_t v, canon_init_t *init)
1826 {
1827 unsigned char
1828 numargs, arg_63[6];
1829
1830
1831 if (!(init->caps->features & CANON_CAP_c))
1832 return;
1833
1834 numargs = 3;
1835 arg_63[0] = init->caps->model_id << 4; /* MODEL_ID */
1836
1837 switch ( init->caps->model_id ) {
1838
1839 case 0: /* very old 360 dpi series: BJC-800/820 */
1840 break; /* tbd */
1841
1842 case 1: /* 360 dpi series - BJC-4000, BJC-210, BJC-70 and their descendants */
1843 if (init->output_type==OUTPUT_GRAY || init->output_type == OUTPUT_MONOCHROME)
1844 arg_63[0]|= 0x01; /* PRINT_COLOUR */
1845
1846 arg_63[1] = ((init->pt ? init->pt->media_code : 0) << 4) /* PRINT_MEDIA */
1847 + 1; /* hardcode to High quality for now */ /* PRINT_QUALITY */
1848
1849 canon_cmd(v,ESC28,0x63, 2, arg_63[0], arg_63[1]);
1850 break;
1851
1852 case 2: /* are any models using this? */
1853 break;
1854
1855 case 3: /* 720 dpi series - BJC-3000 and descendants */
1856 if (init->output_type==OUTPUT_GRAY || init->output_type == OUTPUT_MONOCHROME)
1857 arg_63[0]|= 0x01; /* colour mode */
1858
1859 arg_63[1] = (init->pt) ? init->pt->media_code : 0; /* print media type */
1860 if (init->caps->model == 4202) /* S200 */
1861 {
1862 if ((init->xdpi == 720) && (init->ydpi == 720 ))
1863 arg_63[2] = 1;
1864 else
1865 arg_63[2] = 4; /* hardcoded: quality 3 (may be 0...4) */
1866 /* bidirectional is controlled via quality: 0..2 is bidi, 3 and 4 uni */
1867 /* not every combination works, no idea about the principle */
1868 if ( (init->xdpi > 360) || (init->ydpi > 360) )
1869 {
1870 numargs = 6;
1871 arg_63[3] = 0x10; arg_63[4] = 6; arg_63[5] = 8; /* arg5 makes a vert. offset for K */
1872 if (init->output_type==OUTPUT_GRAY || init->output_type == OUTPUT_MONOCHROME)
1873 arg_63[4] = 1;
1874 }
1875 }
1876 else
1877 arg_63[2] = 2; /* hardcode to whatever this means for now; quality, apparently */
1878
1879 stp_zprintf(v, "\033\050\143");
1880 stp_putc((numargs & 255),v);
1881 stp_putc((numargs >> 8 ),v);
1882 stp_zfwrite((const char *)arg_63, numargs, 1, v);
1883 break;
1884 }
1885
1886 return;
1887 }
1888
1889 /* ESC (d -- 0x64 -- -- set raster resolution:
1890 */
1891 static void
canon_init_setResolution(const stp_vars_t v,canon_init_t * init)1892 canon_init_setResolution(const stp_vars_t v, canon_init_t *init)
1893 {
1894 if (!(init->caps->features & CANON_CAP_d))
1895 return;
1896 if (init->caps->model != 4202 || (init->xdpi < 360))
1897 canon_cmd(v,ESC28,0x64, 4,
1898 (init->ydpi >> 8 ), (init->ydpi & 255),
1899 (init->xdpi >> 8 ), (init->xdpi & 255));
1900 else
1901 if (init->xdpi < 2880)
1902 canon_cmd(v,ESC28,0x64, 4,
1903 (720 >> 8), (720 & 255),
1904 (720 >> 8), (720 & 255));
1905 else
1906 canon_cmd(v,ESC28,0x64, 4,
1907 (720 >> 8), (720 & 255),
1908 (2880 >> 8), (2880 & 255));
1909 }
1910
1911 /* ESC (g -- 0x67 -- cmdSetPageMargins --:
1912 */
1913 static void
canon_init_setPageMargins(const stp_vars_t v,canon_init_t * init)1914 canon_init_setPageMargins(const stp_vars_t v, canon_init_t *init)
1915 {
1916 /* TOFIX: what exactly is to be sent?
1917 * Is it the printable length or the bottom border?
1918 * Is is the printable width or the right border?
1919 */
1920
1921 int minlength= 0;
1922 int minwidth= 0;
1923 int length= init->page_height*5/36;
1924 int width= init->page_width*5/36;
1925
1926 if (!(init->caps->features & CANON_CAP_g))
1927 return;
1928
1929 if (minlength>length) length= minlength;
1930 if (minwidth>width) width= minwidth;
1931
1932 canon_cmd(v,ESC28,0x67, 4, 0,
1933 (unsigned char)(length),1,
1934 (unsigned char)(width));
1935
1936 }
1937
1938 /* ESC (l -- 0x6c -- cmdSetTray --:
1939 */
1940 static void
canon_init_setTray(const stp_vars_t v,canon_init_t * init)1941 canon_init_setTray(const stp_vars_t v, canon_init_t *init)
1942 {
1943 unsigned char
1944 arg_6c_1 = 0x00,
1945 arg_6c_2 = 0x00; /* plain paper */
1946
1947 /* int media= canon_media_type(media_str,caps); */
1948 int source= canon_source_type(init->source_str,init->caps);
1949
1950 if (!(init->caps->features & CANON_CAP_l))
1951 return;
1952
1953 arg_6c_1 = init->caps->model_id << 4;
1954
1955 arg_6c_1|= (source & 0x0f);
1956
1957 if (init->pt)
1958 arg_6c_2 = init->pt->media_code;
1959
1960 canon_cmd(v,ESC28,0x6c, 2, arg_6c_1, arg_6c_2);
1961 }
1962
1963 /* ESC (m -- 0x6d -- cmdSetPrintMode -- :
1964 */
1965 static void
canon_init_setPrintMode(const stp_vars_t v,canon_init_t * init)1966 canon_init_setPrintMode(const stp_vars_t v, canon_init_t *init)
1967 {
1968 unsigned char
1969 arg_6d_1 = 0x03, /* color printhead? */
1970 arg_6d_2 = 0x00, /* 00=color 02=b/w */
1971 arg_6d_3 = 0x00, /* only 01 for bjc8200 and S200*/
1972 /* S200:for envelope and t-shirt transfer = 03 */
1973 arg_6d_a = 0x03, /* A4 paper */
1974 arg_6d_b = 0x00;
1975
1976 if (!(init->caps->features & CANON_CAP_m))
1977 return;
1978
1979 arg_6d_a= canon_size_type(v,init->caps);
1980 if (!arg_6d_a)
1981 arg_6d_b= 1;
1982
1983 if (init->print_head==0)
1984 arg_6d_1= 0x03;
1985 else if (init->print_head<=2)
1986 arg_6d_1= 0x02;
1987 else if (init->print_head<=4)
1988 arg_6d_1= 0x04;
1989 if (init->output_type==OUTPUT_GRAY || init->output_type == OUTPUT_MONOCHROME)
1990 arg_6d_2= 0x02;
1991
1992 if (init->caps->model==8200 || init->caps->model==4202)
1993 arg_6d_3= 0x01;
1994
1995 canon_cmd(v,ESC28,0x6d,12, arg_6d_1,
1996 0xff,0xff,0x00,0x00,0x07,0x00,
1997 arg_6d_a,arg_6d_b,arg_6d_2,0x00,arg_6d_3);
1998 }
1999
2000 /* ESC (p -- 0x70 -- cmdSetPageMargins2 --:
2001 */
2002 static void
canon_init_setPageMargins2(const stp_vars_t v,canon_init_t * init)2003 canon_init_setPageMargins2(const stp_vars_t v, canon_init_t *init)
2004 {
2005 /* TOFIX: what exactly is to be sent?
2006 * Is it the printable length or the bottom border?
2007 * Is is the printable width or the right border?
2008 * [KF] I think the printable width/length in units of 1/60 inch
2009 */
2010
2011 int printable_width= init->page_width*5/6;
2012 int printable_length= init->page_height*5/6;
2013
2014 unsigned char arg_70_1= (printable_length >> 8) & 0xff;
2015 unsigned char arg_70_2= (printable_length) & 0xff;
2016 unsigned char arg_70_3= (printable_width >> 8) & 0xff;
2017 unsigned char arg_70_4= (printable_width) & 0xff;
2018
2019 if (!(init->caps->features & CANON_CAP_p))
2020 return;
2021
2022 canon_cmd(v,ESC28,0x70, 8,
2023 arg_70_1, arg_70_2, 0x00, 0x00,
2024 arg_70_3, arg_70_4, 0x00, 0x00);
2025 }
2026
2027 /* ESC (q -- 0x71 -- setPageID -- :
2028 */
2029 static void
canon_init_setPageID(const stp_vars_t v,canon_init_t * init)2030 canon_init_setPageID(const stp_vars_t v, canon_init_t *init)
2031 {
2032 if (!(init->caps->features & CANON_CAP_q))
2033 return;
2034
2035 canon_cmd(v,ESC28,0x71, 1, 0x01);
2036 }
2037
2038 /* ESC (r -- 0x72 -- ??? set direction ??? -- :
2039 */
2040 static void
canon_init_setX72(const stp_vars_t v,canon_init_t * init)2041 canon_init_setX72(const stp_vars_t v, canon_init_t *init)
2042 {
2043 if ( !( (init->caps->features & CANON_CAP_r)
2044 || (init->caps->features & CANON_CAP_rr) ) )
2045 return;
2046
2047 if ( (init->caps->features & CANON_CAP_r)
2048 || (init->caps->features & CANON_CAP_rr) )
2049 canon_cmd(v,ESC28,0x72, 1, 0x61); /* whatever for - 8200/S200 need it */
2050 if (init->caps->features & CANON_CAP_rr)
2051 canon_cmd(v,ESC28,0x72, 3, 0x63, 1, 0); /* whatever for - S200 needs it */
2052 /* probably to set the print direction of the head */
2053 }
2054
2055 /* ESC (r -- 0x72 -- ??? set direction ??? -- :
2056 only works if quality = 01 (S200) */
2057 static void
canon_set_X72(const stp_vars_t v,int x72arg)2058 canon_set_X72(const stp_vars_t v, int x72arg)
2059 {
2060 canon_cmd(v,ESC28,0x72, 3, 0x63, x72arg, 0);
2061 }
2062
2063 /* ESC (t -- 0x74 -- cmdSetImage --:
2064 */
2065 static void
canon_init_setImage(const stp_vars_t v,canon_init_t * init)2066 canon_init_setImage(const stp_vars_t v, canon_init_t *init)
2067 {
2068 unsigned char
2069 arg_74_1 = 0x01, /* 1 bit per pixel */
2070 arg_74_2 = 0x00, /* */
2071 arg_74_3 = 0x01; /* 01 <= 360 dpi 09 >= 720 dpi */
2072
2073 if (!(init->caps->features & CANON_CAP_t))
2074 return;
2075
2076
2077 if (init->caps->model==4202) /* 1 bit per pixel (arg 4,7,10,13); */
2078 /* 2 level per pixel (arg 6,9,12,15) for each color */
2079 /* though we print only 1bit/pixel - but this is how */
2080 /* the windows driver works */
2081 {
2082 canon_cmd(v,ESC28,0x74, 30, 0x80, 4, 1, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2,\
2083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2084 return;
2085 }
2086
2087 if (init->xdpi==1440) arg_74_2= 0x04;
2088 if (init->ydpi>=720) arg_74_3= 0x09;
2089
2090 if (init->bits>1) {
2091 arg_74_1= 0x02;
2092 arg_74_2= 0x80;
2093 arg_74_3= 0x09;
2094 if (init->colormode == COLOR_CMY) arg_74_3= 0x02; /* for BC-06 cartridge!!! */
2095 }
2096
2097 /* workaround for the bjc8200 in 6color mode - not really understood */
2098 if (init->caps->model==8200) {
2099 if (init->colormode==COLOR_CCMMYK) {
2100 arg_74_1= 0xff;
2101 arg_74_2= 0x90;
2102 arg_74_3= 0x04;
2103 init->bits=3;
2104 if (init->ydpi>600) arg_74_3= 0x09;
2105 } else {
2106 arg_74_1= 0x01;
2107 arg_74_2= 0x00;
2108 arg_74_3= 0x01;
2109 if (init->ydpi>600) arg_74_3= 0x09;
2110 }
2111 }
2112
2113 canon_cmd(v,ESC28,0x74, 3, arg_74_1, arg_74_2, arg_74_3);
2114 }
2115
2116 static void
canon_init_printer(const stp_vars_t v,canon_init_t * init)2117 canon_init_printer(const stp_vars_t v, canon_init_t *init)
2118 {
2119 int mytop;
2120 /* init printer */
2121
2122 canon_init_resetPrinter(v,init); /* ESC [K */
2123 canon_init_setPageMode(v,init); /* ESC (a */
2124 canon_init_setDataCompression(v,init); /* ESC (b */
2125 canon_init_setPageID(v,init); /* ESC (q */
2126 canon_init_setPrintMode(v,init); /* ESC (m */
2127 canon_init_setResolution(v,init); /* ESC (d */
2128 canon_init_setImage(v,init); /* ESC (t */
2129 canon_init_setColor(v,init); /* ESC (c */
2130 canon_init_setPageMargins(v,init); /* ESC (g */
2131 canon_init_setPageMargins2(v,init); /* ESC (p */
2132 canon_init_setTray(v,init); /* ESC (l */
2133 canon_init_setX72(v,init); /* ESC (r */
2134
2135 /* some linefeeds */
2136
2137 mytop= (init->top*init->ydpi)/72;
2138 canon_cmd(v,ESC28,0x65, 2, (mytop >> 8 ),(mytop & 255));
2139 }
2140
2141 static void
canon_deinit_printer(const stp_vars_t v,canon_init_t * init)2142 canon_deinit_printer(const stp_vars_t v, canon_init_t *init)
2143 {
2144 /* eject page */
2145 stp_putc(0x0c,v);
2146
2147 /* say goodbye */
2148 canon_cmd(v,ESC28,0x62,1,0);
2149 if (init->caps->features & CANON_CAP_a)
2150 canon_cmd(v,ESC28,0x61, 1, 0);
2151 }
2152
2153 static int
canon_end_job(const stp_printer_t printer,stp_image_t * image,const stp_vars_t v)2154 canon_end_job(const stp_printer_t printer, /* I - Model */
2155 stp_image_t *image, /* I - Image to print */
2156 const stp_vars_t v)
2157 {
2158 if (!stp_get_verified(v))
2159 return 0;
2160 if (stp_get_job_mode(v) != STP_JOB_MODE_JOB)
2161 return 0;
2162 canon_cmd(v,ESC40,0,0);
2163 return 1;
2164 }
2165
2166 /*
2167 * 'advance_buffer()' - Move (num) lines of length (len) down one line
2168 * and sets first line to 0s
2169 * accepts NULL pointers as buf
2170 * !!! buf must contain more than (num) lines !!!
2171 * also sets first line to 0s if num<1
2172 */
2173 static void
canon_advance_buffer(unsigned char * buf,int len,int num)2174 canon_advance_buffer(unsigned char *buf, int len, int num)
2175 {
2176 if (!buf || !len) return;
2177 if (num>0) memmove(buf+len,buf,len*num);
2178 memset(buf,0,len);
2179 }
2180
2181 /*
2182 * 'canon_print()' - Print an image to a CANON printer.
2183 */
2184 static void
canon_print(const stp_printer_t printer,stp_image_t * image,const stp_vars_t v)2185 canon_print(const stp_printer_t printer, /* I - Model */
2186 stp_image_t *image, /* I - Image to print */
2187 const stp_vars_t v)
2188 {
2189 int i;
2190 const unsigned char *cmap = stp_get_cmap(v);
2191 int model = stp_printer_get_model(printer);
2192 const char *resolution = stp_get_resolution(v);
2193 const char *media_source = stp_get_media_source(v);
2194 int output_type = stp_get_output_type(v);
2195 int orientation = stp_get_orientation(v);
2196 const char *ink_type = stp_get_ink_type(v);
2197 double scaling = stp_get_scaling(v);
2198 int top = stp_get_top(v);
2199 int left = stp_get_left(v);
2200 int y; /* Looping vars */
2201 int xdpi, ydpi; /* Resolution */
2202 int n; /* Output number */
2203 unsigned short *out; /* Output pixels (16-bit) */
2204 unsigned char *in; /* Input pixels */
2205 unsigned char *cols[7]; /* Bitmap data: cols[0]=black ... */
2206 /* ... cols[6]=lyellow */
2207
2208 int delay_k,
2209 delay_c,
2210 delay_m,
2211 delay_y,
2212 delay_lc,
2213 delay_lm,
2214 delay_ly,
2215 delay_max;
2216 int page_left, /* Left margin of page */
2217 page_right, /* Right margin of page */
2218 page_top, /* Top of page */
2219 page_bottom, /* Bottom of page */
2220 page_width, /* Width of page */
2221 page_height, /* Length of page */
2222 page_true_height,/* True length of page */
2223 out_width, /* Width of image on page */
2224 out_length, /* Length of image on page */
2225 out_bpp, /* Output bytes per pixel */
2226 length, /* Length of raster data */
2227 buf_length, /* Length of raster data buffer (dmt) */
2228 errdiv, /* Error dividend */
2229 errmod, /* Error modulus */
2230 errval, /* Current error value */
2231 errline, /* Current raster line */
2232 errlast; /* Last raster line loaded */
2233 stp_convert_t colorfunc = 0; /* Color conversion function... */
2234 int zero_mask;
2235 int bits= 1;
2236 int image_height,
2237 image_width,
2238 image_bpp;
2239 int ink_spread;
2240 void * dither;
2241 int res_code;
2242 int use_6color= 0;
2243 double k_upper, k_lower;
2244 int emptylines= 0;
2245 stp_vars_t nv = stp_allocate_copy(v);
2246 double lum_adjustment[49], sat_adjustment[49], hue_adjustment[49];
2247 int have_lum_adjustment= 0;
2248 int have_sat_adjustment= 0;
2249 int have_hue_adjustment= 0;
2250
2251 canon_init_t init;
2252 const canon_cap_t * caps = canon_get_model_capabilities(model);
2253 int printhead = canon_printhead_type(ink_type,caps);
2254 colormode_t colormode = canon_printhead_colors(ink_type,caps);
2255 const paper_t *pt;
2256 const canon_variable_inkset_t *inks;
2257
2258 stp_dither_data_t *dt;
2259 void * weave = NULL;
2260 int total_channels; /* number of colors to print with */
2261 int physical_xdpi = 720, nozzle_ydpi = 360, stepper_ydpi = 720;
2262 int nozzles = 24; /* count of inkjets for one pass */
2263 int nozzle_separation, horizontal_passes;
2264 int vertical_passes, vertical_oversample;
2265 int * head_offset = NULL;
2266 canon_privdata_weave privdata;
2267
2268 if (!stp_get_verified(nv))
2269 {
2270 stp_eprintf(nv, "Print options not verified; cannot print.\n");
2271 return;
2272 }
2273
2274 PUT("top ",top,72);
2275 PUT("left ",left,72);
2276
2277 /*
2278 * Setup a read-only pixel region for the entire image...
2279 */
2280
2281 image->init(image);
2282 image_height = image->height(image);
2283 image_width = image->width(image);
2284 image_bpp = image->bpp(image);
2285
2286 /* force grayscale if image is grayscale
2287 * or single black cartridge installed
2288 */
2289
2290 if ((printhead == 0 || caps->inks == CANON_INK_K) &&
2291 output_type != OUTPUT_MONOCHROME)
2292 {
2293 output_type = OUTPUT_GRAY;
2294 stp_set_output_type(nv, output_type);
2295 }
2296
2297 if (output_type == OUTPUT_GRAY || output_type == OUTPUT_MONOCHROME)
2298 colormode = COLOR_MONOCHROME;
2299
2300 stp_set_output_color_model(nv, COLOR_MODEL_CMY);
2301
2302 /*
2303 * Choose the correct color conversion function...
2304 */
2305
2306 colorfunc = stp_choose_colorfunc(output_type, image_bpp, cmap, &out_bpp, nv);
2307
2308 /*
2309 * Figure out the output resolution...
2310 */
2311
2312 switch (sscanf(resolution,"%dx%d",&xdpi,&ydpi)) {
2313 case 1: ydpi= xdpi; if (ydpi>caps->max_ydpi) ydpi/= 2; break;
2314 case 0: xdpi= caps->max_xdpi; ydpi= caps->max_ydpi; break;
2315 }
2316
2317 stp_deprintf(STP_DBG_CANON,"canon: resolution=%dx%d\n",xdpi,ydpi);
2318 #ifndef EXPERIMENTAL_STUFF
2319 stp_deprintf(STP_DBG_CANON," rescode =0x%x\n",canon_res_code(caps,xdpi,ydpi));
2320 res_code= canon_res_code(caps,xdpi,ydpi);
2321 #endif
2322
2323 if (((!strcmp(resolution+(strlen(resolution)-3),"DMT")) ||
2324 (!strcmp(resolution+(strlen(resolution)-3),"dmt"))) &&
2325 (caps->features & CANON_CAP_DMT) &&
2326 output_type != OUTPUT_MONOCHROME) {
2327 bits= 2;
2328 stp_deprintf(STP_DBG_CANON,"canon: using drop modulation technology\n");
2329 }
2330
2331 /*
2332 * Compute the output size...
2333 */
2334
2335 canon_imageable_area(printer, nv, &page_left, &page_right,
2336 &page_bottom, &page_top);
2337
2338 stp_compute_page_parameters(page_right, page_left, page_top, page_bottom,
2339 scaling, image_width, image_height, image,
2340 &orientation, &page_width, &page_height,
2341 &out_width, &out_length, &left, &top);
2342
2343 /*
2344 * Recompute the image length and width. If the image has been
2345 * rotated, these will change from previously.
2346 */
2347 image_height = image->height(image);
2348 image_width = image->width(image);
2349
2350 stp_default_media_size(printer, nv, &n, &page_true_height);
2351
2352 PUT("top ",top,72);
2353 PUT("left ",left,72);
2354 PUT("page_top ",page_top,72);
2355 PUT("page_bottom",page_bottom,72);
2356 PUT("page_left ",page_left,72);
2357 PUT("page_right ",page_right,72);
2358 PUT("page_width ",page_width,72);
2359 PUT("page_height",page_height,72);
2360 PUT("page_true_height",page_true_height,72);
2361 PUT("out_width ", out_width,xdpi);
2362 PUT("out_length", out_length,ydpi);
2363
2364 image->progress_init(image);
2365
2366 PUT("top ",top,72);
2367 PUT("left ",left,72);
2368
2369 pt = get_media_type(stp_get_media_type(nv));
2370
2371 init.caps = caps;
2372 init.output_type = output_type;
2373 init.pt = pt;
2374 init.print_head = printhead;
2375 init.colormode = colormode;
2376 init.source_str = media_source;
2377 init.xdpi = xdpi;
2378 init.ydpi = ydpi;
2379 init.page_width = page_width;
2380 init.page_height = page_height;
2381 init.top = top;
2382 init.left = left;
2383 init.bits = bits;
2384
2385 canon_init_printer(nv, &init);
2386
2387 /* possibly changed during initialitation
2388 * to enforce valid modes of operation:
2389 */
2390 bits= init.bits;
2391 xdpi= init.xdpi;
2392 ydpi= init.ydpi;
2393
2394 /*
2395 * Convert image size to printer resolution...
2396 */
2397
2398 out_width = xdpi * out_width / 72;
2399 out_length = ydpi * out_length / 72;
2400
2401 PUT("out_width ", out_width,xdpi);
2402 PUT("out_length", out_length,ydpi);
2403
2404 left = xdpi * left / 72;
2405
2406 PUT("leftskip",left,xdpi);
2407
2408 if((xdpi == 1440) && (model != 4202)){
2409 delay_k= 0;
2410 delay_c= 112;
2411 delay_m= 224;
2412 delay_y= 336;
2413 delay_lc= 112;
2414 delay_lm= 224;
2415 delay_ly= 336;
2416 delay_max= 336;
2417 stp_deprintf(STP_DBG_CANON,"canon: delay on!\n");
2418 } else if (model ==4202 ){
2419 delay_k= 0;
2420 delay_c= 0x30;
2421 delay_m= 0x50;
2422 delay_y= 0x70;
2423 delay_lc= 0;
2424 delay_lm= 0;
2425 delay_ly= 0;
2426 delay_max= 0x70;
2427 stp_deprintf(STP_DBG_CANON,"canon: delay for S200 on!\n");
2428 } else {
2429 delay_k= delay_c= delay_m= delay_y= delay_lc= delay_lm= delay_ly=0;
2430 delay_max=0;
2431 stp_deprintf(STP_DBG_CANON,"canon: delay off!\n");
2432 }
2433
2434 /*
2435 * Allocate memory for the raster data...
2436 */
2437
2438 length = (out_width + 7) / 8;
2439
2440 buf_length= length*bits;
2441
2442 stp_deprintf(STP_DBG_CANON,"canon: buflength is %d!\n",buf_length);
2443
2444 for (i=0; i<=6; i++)
2445 cols[i] = NULL;
2446
2447 if (colormode==COLOR_MONOCHROME)
2448 cols[0] = stp_zalloc(buf_length*(delay_k+1));
2449
2450 else { /* use Colors CMY */
2451 cols[1] = stp_zalloc(buf_length*(delay_c+1));
2452 cols[2] = stp_zalloc(buf_length*(delay_m+1));
2453 cols[3] = stp_zalloc(buf_length*(delay_y+1));
2454
2455 if (colormode!=COLOR_CMY) /* use also K */
2456 cols[0] = stp_zalloc(buf_length*(delay_k+1));
2457
2458 if (colormode==COLOR_CCMMYK || colormode==COLOR_CCMMYYK) {
2459 use_6color= 1;
2460 cols[4] = stp_zalloc(buf_length*(delay_lc+1));
2461 cols[5] = stp_zalloc(buf_length*(delay_lm+1));
2462 if (colormode==CANON_INK_CcMmYyK)
2463 cols[6] = stp_zalloc(buf_length*(delay_lc+1));
2464 }
2465 }
2466
2467 stp_deprintf(STP_DBG_CANON,"canon: driver will use colors %s%s%s%s%s%s\n",
2468 cols[1] ? "C" : "", cols[4] ? "c" : "", cols[2] ? "M" : "",
2469 cols[5] ? "m" : "", cols[3] ? "Y" : "", cols[0] ? "K" : "");
2470
2471 stp_deprintf(STP_DBG_CANON,"density is %f\n",stp_get_density(nv));
2472
2473 /*
2474 * Compute the LUT. For now, it's 8 bit, but that may eventually
2475 * sometimes change.
2476 */
2477 if (pt)
2478 stp_set_density(nv, stp_get_density(nv) * pt->base_density);
2479 else /* Can't find paper type? Assume plain */
2480 stp_set_density(nv, stp_get_density(nv) * .5);
2481 stp_set_density(nv, stp_get_density(nv) * canon_density(caps, res_code));
2482 if (stp_get_density(nv) > 1.0)
2483 stp_set_density(nv, 1.0);
2484 if (colormode == COLOR_MONOCHROME)
2485 stp_set_gamma(nv, stp_get_gamma(nv) / .8);
2486 stp_compute_lut(nv, 256);
2487
2488 stp_deprintf(STP_DBG_CANON,"density is %f\n",stp_get_density(nv));
2489
2490 /*
2491 * Output the page...
2492 */
2493
2494 if (xdpi > ydpi)
2495 dither = stp_init_dither(image_width, out_width, 1, xdpi / ydpi, nv);
2496 else
2497 dither = stp_init_dither(image_width, out_width, ydpi / xdpi, 1, nv);
2498
2499 for (i = 0; i <= NCOLORS; i++)
2500 stp_dither_set_black_level(dither, i, 1.0);
2501
2502 if (use_6color)
2503 k_lower = .4 / bits + .1;
2504 else
2505 k_lower = .25 / bits;
2506 if (pt)
2507 {
2508 k_lower *= pt->k_lower_scale;
2509 k_upper = pt->k_upper;
2510 }
2511 else
2512 {
2513 k_lower *= .5;
2514 k_upper = .5;
2515 }
2516 stp_dither_set_black_lower(dither, k_lower);
2517 stp_dither_set_black_upper(dither, k_upper);
2518
2519 if ((inks = canon_inks(caps, res_code, colormode, bits))!=0)
2520 {
2521 if (inks->c)
2522 stp_dither_set_ranges(dither, ECOLOR_C, inks->c->count, inks->c->range,
2523 inks->c->density * stp_get_density(nv));
2524 if (inks->m)
2525 stp_dither_set_ranges(dither, ECOLOR_M, inks->m->count, inks->m->range,
2526 inks->m->density * stp_get_density(nv));
2527 if (inks->y)
2528 stp_dither_set_ranges(dither, ECOLOR_Y, inks->y->count, inks->y->range,
2529 inks->y->density * stp_get_density(nv));
2530 if (inks->k)
2531 stp_dither_set_ranges(dither, ECOLOR_K, inks->k->count, inks->k->range,
2532 inks->k->density * stp_get_density(nv));
2533 }
2534
2535 switch (stp_get_image_type(nv))
2536 {
2537 case IMAGE_LINE_ART:
2538 stp_dither_set_ink_spread(dither, 19);
2539 break;
2540 case IMAGE_SOLID_TONE:
2541 stp_dither_set_ink_spread(dither, 15);
2542 break;
2543 case IMAGE_CONTINUOUS:
2544 ink_spread = 13;
2545 /*
2546 if (ydpi > canon_max_vres(model))
2547 ink_spread++;
2548 */
2549 if (bits > 1)
2550 ink_spread++;
2551 stp_dither_set_ink_spread(dither, ink_spread);
2552 break;
2553 }
2554 stp_dither_set_density(dither, stp_get_density(nv));
2555
2556 /* initialize weaving for S200 for resolutions > 360dpi */
2557 if (init.caps->features & CANON_CAP_WEAVE && xdpi > 360)
2558 {
2559 stepper_ydpi = 720;
2560 nozzle_ydpi = 360;
2561 if (xdpi == 2880)
2562 physical_xdpi = 2880;
2563 else
2564 physical_xdpi = 720;
2565
2566 total_channels = 4;
2567 head_offset = stp_zalloc(sizeof(int) * total_channels);
2568 memset(head_offset, 0, sizeof(head_offset));
2569
2570 if ( colormode == COLOR_MONOCHROME )
2571 nozzles = 64; /* black nozzles */
2572 else
2573 nozzles = 24; /* color nozzles */
2574 if (colormode == COLOR_MONOCHROME)
2575 {
2576 head_offset[0] = 0; /* K starts at 0 */
2577 head_offset[1] = 144 ;/* how far C starts after K */
2578 head_offset[2] = 144 + 64;/* how far M starts after K */
2579 head_offset[3] = 144 + 64 + 64;/* how far Y starts after K */
2580 top += 11;
2581 }
2582 else if (colormode == COLOR_CMYK)
2583 {
2584 head_offset[0] = 0; /* K starts at 0 */
2585 head_offset[1] = 144 ;/* how far C starts after K */
2586 head_offset[2] = 144 + 64;/* how far M starts after K */
2587 head_offset[3] = 144 + 64 + 64;/* how far Y starts after K */
2588 top += 5;
2589 }
2590 else /* colormode == CMY */
2591 {
2592 head_offset[0] = 0; /* K starts at 0 */
2593 head_offset[1] = 0 ;/* how far C starts after K */
2594 head_offset[2] = 64;/* how far M starts after K */
2595 head_offset[3] = 128;/* how far Y starts after K */
2596 top += 18;
2597 }
2598
2599 nozzle_separation = stepper_ydpi / nozzle_ydpi;
2600 horizontal_passes = xdpi / physical_xdpi;
2601 vertical_passes = 1;
2602 vertical_oversample = ydpi / stepper_ydpi;
2603
2604 privdata.bidirectional = 1; /* 1: bidirectional; 0: unidirectional printing */
2605 privdata.direction = 1;
2606 stp_set_driver_data(nv, &privdata);
2607
2608 stp_deprintf(STP_DBG_CANON,"canon: initializing weaving: nozzles=%d, nozzle_separation=%d, "
2609 "horizontal_passes=%d, vertical_passes=%d,vertical_oversample=%d, total_channels=%d \n",
2610 nozzles, nozzle_separation,
2611 horizontal_passes, vertical_passes,
2612 vertical_oversample, total_channels);
2613
2614 weave = stp_initialize_weave(nozzles, nozzle_separation,
2615 horizontal_passes, vertical_passes,
2616 vertical_oversample, total_channels,
2617 1,
2618 out_width, out_length,
2619 top * stepper_ydpi / 72,
2620 page_height * stepper_ydpi / 72,
2621 1, head_offset, nv,
2622 canon_flush_pass,
2623 stp_fill_uncompressed,
2624 stp_pack_uncompressed,
2625 stp_compute_uncompressed_linewidth);
2626 }
2627
2628 in = stp_zalloc(image_width * image_bpp);
2629 out = stp_zalloc(image_width * out_bpp * 2);
2630
2631 errdiv = image_height / out_length;
2632 errmod = image_height % out_length;
2633 errval = 0;
2634 errlast = -1;
2635 errline = 0;
2636 if (canon_lum_adjustment(printer)) {
2637 int k;
2638 for (k = 0; k < 49; k++) {
2639 have_lum_adjustment= 1;
2640 lum_adjustment[k] = canon_lum_adjustment(printer)[k];
2641 if(pt)
2642 if (pt->lum_adjustment)
2643 lum_adjustment[k] *= pt->lum_adjustment[k];
2644 }
2645 }
2646 if (canon_sat_adjustment(printer)) {
2647 int k;
2648 for (k = 0; k < 49; k++) {
2649 have_sat_adjustment= 1;
2650 sat_adjustment[k] = canon_sat_adjustment(printer)[k];
2651 if(pt)
2652 if (pt->sat_adjustment)
2653 sat_adjustment[k] *= pt->sat_adjustment[k];
2654 }
2655 }
2656 if (canon_hue_adjustment(printer)) {
2657 int k;
2658 for (k = 0; k < 49; k++) {
2659 have_hue_adjustment= 1;
2660 hue_adjustment[k] = canon_hue_adjustment(printer)[k];
2661 if(pt)
2662 if (pt->hue_adjustment)
2663 hue_adjustment[k] += pt->hue_adjustment[k];
2664 }
2665 }
2666
2667 dt = stp_create_dither_data();
2668 stp_add_channel(dt, cols[0], ECOLOR_K, 0);
2669 stp_add_channel(dt, cols[1], ECOLOR_C, 0);
2670 stp_add_channel(dt, cols[4], ECOLOR_C, 1);
2671 stp_add_channel(dt, cols[2], ECOLOR_M, 0);
2672 stp_add_channel(dt, cols[5], ECOLOR_M, 1);
2673 stp_add_channel(dt, cols[3], ECOLOR_Y, 0);
2674 stp_add_channel(dt, cols[6], ECOLOR_Y, 1);
2675
2676 /* ---- go through every image line (y) ---- */
2677
2678 for (y = 0; y < out_length; y ++)
2679 {
2680 int duplicate_line = 1;
2681
2682 /* stp_deprintf(STP_DBG_CANON,"\ny=%d\n",y); */
2683
2684 if ((y & 63) == 0)
2685 image->note_progress(image, y, out_length);
2686
2687 if (errline != errlast)
2688 {
2689 errlast = errline;
2690 duplicate_line = 0;
2691 if (image->get_row(image, in, errline) != STP_IMAGE_OK)
2692 break;
2693 (*colorfunc)(nv, in, out, &zero_mask, image_width, image_bpp, cmap,
2694 have_hue_adjustment ? hue_adjustment : NULL,
2695 have_lum_adjustment ? lum_adjustment : NULL,
2696 have_sat_adjustment ? sat_adjustment : NULL);
2697 }
2698
2699 stp_dither(out, y, dither, dt, duplicate_line, zero_mask);
2700
2701 #if 0 /* excessive debugging */
2702 stp_deprintf(STP_DBG_CANON,"dithering done, length=%d, out_width=%d \n"
2703 "black=%p; cyan=%p; magenta=%p; yellow=%p \n",
2704 length, out_width, cols[0], cols[1], cols[2], cols[3]);
2705 dump_area(cols[0], length, "black:");
2706 dump_area(cols[1], length, "cyan:");
2707 dump_area(cols[2], length, "magenta:");
2708 dump_area(cols[3], length, "yellow:");
2709 #endif
2710
2711 if (init.caps->features & CANON_CAP_WEAVE && xdpi > 360)
2712 {
2713 stp_write_weave(weave, length, stepper_ydpi, model, out_width,
2714 left * physical_xdpi / xdpi,
2715 xdpi, physical_xdpi, cols);
2716 }
2717
2718 else
2719 {
2720 canon_write_line(nv, caps, ydpi, cols[0], delay_k,
2721 cols[1], delay_c,
2722 cols[2], delay_m,
2723 cols[3], delay_y,
2724 cols[4], delay_lc,
2725 cols[5], delay_lm,
2726 cols[6], delay_ly,
2727 length, out_width, left, &emptylines, bits);
2728
2729 canon_advance_buffer(cols[0], buf_length,delay_k);
2730 canon_advance_buffer(cols[1], buf_length,delay_c);
2731 canon_advance_buffer(cols[2], buf_length,delay_m);
2732 canon_advance_buffer(cols[3], buf_length,delay_y);
2733 canon_advance_buffer(cols[4], buf_length,delay_lc);
2734 canon_advance_buffer(cols[5], buf_length,delay_lm);
2735 canon_advance_buffer(cols[6], buf_length,delay_ly);
2736 }
2737
2738 errval += errmod;
2739 errline += errdiv;
2740 if (errval >= out_length)
2741 {
2742 errval -= out_length;
2743 errline ++;
2744 }
2745 }
2746
2747 if (init.caps->features & CANON_CAP_WEAVE && xdpi > 360)
2748 {
2749 stp_flush_all(weave, model, out_width,
2750 left * physical_xdpi / xdpi,
2751 ydpi, xdpi, physical_xdpi);
2752 canon_advance_paper(nv, 5);
2753 }
2754 else
2755 {
2756 /*
2757 * Flush delayed buffers...
2758 */
2759
2760 if (delay_max) {
2761 stp_deprintf(STP_DBG_CANON,"\ncanon: flushing %d possibly delayed buffers\n",
2762 delay_max);
2763 for (y= 0; y<delay_max; y++) {
2764
2765 canon_write_line(nv, caps, ydpi, cols[0], delay_k,
2766 cols[1], delay_c,
2767 cols[2], delay_m,
2768 cols[3], delay_y,
2769 cols[4], delay_lc,
2770 cols[5], delay_lm,
2771 cols[6], delay_ly,
2772 length, out_width, left, &emptylines, bits);
2773
2774 canon_advance_buffer(cols[0], buf_length,delay_k);
2775 canon_advance_buffer(cols[1], buf_length,delay_c);
2776 canon_advance_buffer(cols[2], buf_length,delay_m);
2777 canon_advance_buffer(cols[3], buf_length,delay_y);
2778 canon_advance_buffer(cols[4], buf_length,delay_lc);
2779 canon_advance_buffer(cols[5], buf_length,delay_lm);
2780 canon_advance_buffer(cols[6], buf_length,delay_ly);
2781 }
2782 }
2783 }
2784
2785 image->progress_conclude(image);
2786
2787 /*
2788 * Cleanup...
2789 */
2790
2791 stp_free_dither_data(dt);
2792 stp_free_dither(dither);
2793 stp_free_lut(nv);
2794 stp_free(in);
2795 stp_free(out);
2796 if (weave != NULL) stp_destroy_weave(weave);
2797 for (y = 0; y < 6; y++)
2798 if ( cols[y] != NULL ) stp_free(cols[y]);
2799
2800 canon_deinit_printer(nv, &init);
2801 stp_free_vars(nv);
2802 }
2803
2804 const stp_printfuncs_t stp_canon_printfuncs =
2805 {
2806 canon_parameters,
2807 stp_default_media_size,
2808 canon_imageable_area,
2809 canon_limit,
2810 canon_print,
2811 canon_default_parameters,
2812 canon_describe_resolution,
2813 stp_verify_printer_params,
2814 stp_start_job,
2815 canon_end_job
2816 };
2817
2818 /*
2819 * 'canon_fold_lsb_msb()' fold 2 lines in order lsb/msb
2820 */
2821
2822 static void
canon_fold_2bit(const unsigned char * line,int single_length,unsigned char * outbuf)2823 canon_fold_2bit(const unsigned char *line,
2824 int single_length,
2825 unsigned char *outbuf)
2826 {
2827 int i;
2828 for (i = 0; i < single_length; i++) {
2829 outbuf[0] =
2830 ((line[0] & (1 << 7)) >> 1) |
2831 ((line[0] & (1 << 6)) >> 2) |
2832 ((line[0] & (1 << 5)) >> 3) |
2833 ((line[0] & (1 << 4)) >> 4) |
2834 ((line[single_length] & (1 << 7)) >> 0) |
2835 ((line[single_length] & (1 << 6)) >> 1) |
2836 ((line[single_length] & (1 << 5)) >> 2) |
2837 ((line[single_length] & (1 << 4)) >> 3);
2838 outbuf[1] =
2839 ((line[0] & (1 << 3)) << 3) |
2840 ((line[0] & (1 << 2)) << 2) |
2841 ((line[0] & (1 << 1)) << 1) |
2842 ((line[0] & (1 << 0)) << 0) |
2843 ((line[single_length] & (1 << 3)) << 4) |
2844 ((line[single_length] & (1 << 2)) << 3) |
2845 ((line[single_length] & (1 << 1)) << 2) |
2846 ((line[single_length] & (1 << 0)) << 1);
2847 line++;
2848 outbuf += 2;
2849 }
2850 }
2851
2852 #ifndef USE_3BIT_FOLD_TYPE
2853 #error YOU MUST CHOOSE A VALUE FOR USE_3BIT_FOLD_TYPE
2854 #endif
2855
2856 #if USE_3BIT_FOLD_TYPE == 333
2857
2858 static void
canon_fold_3bit(const unsigned char * line,int single_length,unsigned char * outbuf)2859 canon_fold_3bit(const unsigned char *line,
2860 int single_length,
2861 unsigned char *outbuf)
2862 {
2863 int i;
2864 for (i = 0; i < single_length; i++) {
2865 outbuf[0] =
2866 ((line[0] & (1 << 7)) >> 2) |
2867 ((line[0] & (1 << 6)) >> 4) |
2868 ((line[single_length] & (1 << 7)) >> 1) |
2869 ((line[single_length] & (1 << 6)) >> 3) |
2870 ((line[single_length] & (1 << 5)) >> 5) |
2871 ((line[2*single_length] & (1 << 7)) << 0) |
2872 ((line[2*single_length] & (1 << 6)) >> 2) |
2873 ((line[2*single_length] & (1 << 5)) >> 4);
2874 outbuf[1] =
2875 ((line[0] & (1 << 5)) << 2) |
2876 ((line[0] & (1 << 4)) << 0) |
2877 ((line[0] & (1 << 3)) >> 2) |
2878 ((line[single_length] & (1 << 4)) << 1) |
2879 ((line[single_length] & (1 << 3)) >> 1) |
2880 ((line[2*single_length] & (1 << 4)) << 2) |
2881 ((line[2*single_length] & (1 << 3)) << 0) |
2882 ((line[2*single_length] & (1 << 2)) >> 2);
2883 outbuf[2] =
2884 ((line[0] & (1 << 2)) << 4) |
2885 ((line[0] & (1 << 1)) << 2) |
2886 ((line[0] & (1 << 0)) << 0) |
2887 ((line[single_length] & (1 << 2)) << 5) |
2888 ((line[single_length] & (1 << 1)) << 3) |
2889 ((line[single_length] & (1 << 0)) << 1) |
2890 ((line[2*single_length] & (1 << 1)) << 4) |
2891 ((line[2*single_length] & (1 << 0)) << 2);
2892 line++;
2893 outbuf += 3;
2894 }
2895 }
2896
2897 #elif USE_3BIT_FOLD_TYPE == 323
2898
2899 static void
canon_fold_3bit(const unsigned char * line,int single_length,unsigned char * outbuf)2900 canon_fold_3bit(const unsigned char *line,
2901 int single_length,
2902 unsigned char *outbuf)
2903 {
2904 unsigned char A0,A1,A2,B0,B1,B2,C0,C1,C2;
2905 const unsigned char *last= line+single_length;
2906
2907 for (; line < last; line+=3, outbuf+=8) {
2908
2909 A0= line[0]; B0= line[single_length]; C0= line[2*single_length];
2910
2911 if (line<last-2) {
2912 A1= line[1]; B1= line[single_length+1]; C1= line[2*single_length+1];
2913 } else {
2914 A1= 0; B1= 0; C1= 0;
2915 }
2916 if (line<last-1) {
2917 A2= line[2]; B2= line[single_length+2]; C2= line[2*single_length+2];
2918 } else {
2919 A2= 0; B2= 0; C2= 0;
2920 }
2921
2922 outbuf[0] =
2923 ((C0 & 0x80) >> 0) |
2924 ((B0 & 0x80) >> 1) |
2925 ((A0 & 0x80) >> 2) |
2926 ((B0 & 0x40) >> 2) |
2927 ((A0 & 0x40) >> 3) |
2928 ((C0 & 0x20) >> 3) |
2929 ((B0 & 0x20) >> 4) |
2930 ((A0 & 0x20) >> 5);
2931 outbuf[1] =
2932 ((C0 & 0x10) << 3) |
2933 ((B0 & 0x10) << 2) |
2934 ((A0 & 0x10) << 1) |
2935 ((B0 & 0x08) << 1) |
2936 ((A0 & 0x08) << 0) |
2937 ((C0 & 0x04) >> 0) |
2938 ((B0 & 0x04) >> 1) |
2939 ((A0 & 0x04) >> 2);
2940 outbuf[2] =
2941 ((C0 & 0x02) << 6) |
2942 ((B0 & 0x02) << 5) |
2943 ((A0 & 0x02) << 4) |
2944 ((B0 & 0x01) << 4) |
2945 ((A0 & 0x01) << 3) |
2946 ((C1 & 0x80) >> 5) |
2947 ((B1 & 0x80) >> 6) |
2948 ((A1 & 0x80) >> 7);
2949 outbuf[3] =
2950 ((C1 & 0x40) << 1) |
2951 ((B1 & 0x40) << 0) |
2952 ((A1 & 0x40) >> 1) |
2953 ((B1 & 0x20) >> 1) |
2954 ((A1 & 0x20) >> 2) |
2955 ((C1 & 0x10) >> 2) |
2956 ((B1 & 0x10) >> 3) |
2957 ((A1 & 0x10) >> 4);
2958 outbuf[4] =
2959 ((C1 & 0x08) << 4) |
2960 ((B1 & 0x08) << 3) |
2961 ((A1 & 0x08) << 2) |
2962 ((B1 & 0x04) << 2) |
2963 ((A1 & 0x04) << 1) |
2964 ((C1 & 0x02) << 1) |
2965 ((B1 & 0x02) >> 0) |
2966 ((A1 & 0x02) >> 1);
2967 outbuf[5] =
2968 ((C1 & 0x01) << 7) |
2969 ((B1 & 0x01) << 6) |
2970 ((A1 & 0x01) << 5) |
2971 ((B2 & 0x80) >> 3) |
2972 ((A2 & 0x80) >> 4) |
2973 ((C2 & 0x40) >> 4) |
2974 ((B2 & 0x40) >> 5) |
2975 ((A2 & 0x40) >> 6);
2976 outbuf[6] =
2977 ((C2 & 0x20) << 2) |
2978 ((B2 & 0x20) << 1) |
2979 ((A2 & 0x20) << 0) |
2980 ((B2 & 0x10) >> 0) |
2981 ((A2 & 0x10) >> 1) |
2982 ((C2 & 0x08) >> 1) |
2983 ((B2 & 0x08) >> 2) |
2984 ((A2 & 0x08) >> 3);
2985 outbuf[7] =
2986 ((C2 & 0x04) << 5) |
2987 ((B2 & 0x04) << 4) |
2988 ((A2 & 0x04) << 3) |
2989 ((B2 & 0x02) << 3) |
2990 ((A2 & 0x02) << 2) |
2991 ((C2 & 0x01) << 2) |
2992 ((B2 & 0x01) << 1) |
2993 ((A2 & 0x01) << 0);
2994 }
2995 }
2996
2997 #else
2998 #error 3BIT FOLD TYPE NOT IMPLEMENTED
2999 #endif
3000
3001 static void
canon_shift_buffer(unsigned char * line,int length,int bits)3002 canon_shift_buffer(unsigned char *line,int length,int bits)
3003 {
3004 int i,j;
3005 for (j=0; j<bits; j++) {
3006 for (i=length-1; i>0; i--) {
3007 line[i]= (line[i] >> 1) | (line[i-1] << 7);
3008 }
3009 line[0] = line[0] >> 1;
3010 }
3011 }
3012
3013 /*
3014 * 'canon_write()' - Send graphics using TIFF packbits compression.
3015 */
3016
3017 static int
canon_write(const stp_vars_t v,const canon_cap_t * caps,unsigned char * line,int length,int coloridx,int ydpi,int * empty,int width,int offset,int bits)3018 canon_write(const stp_vars_t v, /* I - Print file or command */
3019 const canon_cap_t *caps, /* I - Printer model; currently unused */
3020 unsigned char *line, /* I - Output bitmap data */
3021 int length, /* I - Length of bitmap data */
3022 int coloridx, /* I - Which color */
3023 int ydpi, /* I - Vertical resolution; currently unused */
3024 int *empty, /* IO- Preceeding empty lines */
3025 int width, /* I - Printed width; currently unused */
3026 int offset, /* I - Offset from left side */
3027 int bits)
3028 {
3029 unsigned char
3030 comp_buf[COMPBUFWIDTH], /* Compression buffer */
3031 in_fold[COMPBUFWIDTH],
3032 *in_ptr= line,
3033 *comp_ptr, *comp_data;
3034 int newlength;
3035 int offset2,bitoffset;
3036 unsigned char color;
3037
3038 /* Don't send blank lines... */
3039
3040 if (line[0] == 0 && memcmp(line, line + 1, length - 1) == 0)
3041 return 0;
3042
3043 /* fold lsb/msb pairs if drop modulation is active */
3044
3045
3046
3047 if (bits==2) {
3048 memset(in_fold,0,length*2);
3049 canon_fold_2bit(line,length,in_fold);
3050 in_ptr= in_fold;
3051 length= (length*8/4); /* 4 pixels in 8bit */
3052 offset= (offset*8/4); /* 4 pixels in 8bit */
3053 }
3054 if (bits==3) {
3055 memset(in_fold,0,length*3);
3056 canon_fold_3bit(line,length,in_fold);
3057 in_ptr= in_fold;
3058 length= (length*8)/3;
3059 offset= (offset/3)*8;
3060 #if 0
3061 switch(offset%3){
3062 case 0: offset= (offset/3)*8; break;
3063 case 1: offset= (offset/3)*8/*+3 CAREFUL! CANNOT SHIFT _AFTER_ RECODING!!*/; break;
3064 case 2: offset= (offset/3)*8/*+5 CAREFUL! CANNOT SHIFT _AFTER_ RECODING!!*/; break;
3065 }
3066 #endif
3067 }
3068
3069 /* pack left border rounded to multiples of 8 dots */
3070
3071 comp_data= comp_buf;
3072 offset2= offset/8;
3073 bitoffset= offset%8;
3074 while (offset2>0) {
3075 unsigned char toffset = offset2 > 128 ? 128 : offset2;
3076 comp_data[0] = 1 - toffset;
3077 comp_data[1] = 0;
3078 comp_data += 2;
3079 offset2-= toffset;
3080 }
3081 if (bitoffset) {
3082 if (bitoffset<8)
3083 canon_shift_buffer(in_ptr,length,bitoffset);
3084 else
3085 stp_deprintf(STP_DBG_CANON,"SEVERE BUG IN print-canon.c::canon_write() "
3086 "bitoffset=%d!!\n",bitoffset);
3087 }
3088
3089 stp_pack_tiff(in_ptr, length, comp_data, &comp_ptr);
3090 newlength = comp_ptr - comp_buf;
3091
3092 /* send packed empty lines if any */
3093
3094 if (*empty) {
3095 stp_zfwrite("\033\050\145\002\000", 5, 1, v);
3096 stp_putc((*empty) >> 8 , v);
3097 stp_putc((*empty) & 255, v);
3098 *empty= 0;
3099 }
3100
3101 /* Send a line of raster graphics... */
3102
3103 stp_zfwrite("\033\050\101", 3, 1, v);
3104 stp_putc((newlength+1) & 255, v);
3105 stp_putc((newlength+1) >> 8, v);
3106 color= "CMYKcmy"[coloridx];
3107 if (!color) color= 'K';
3108 stp_putc(color,v);
3109 stp_zfwrite((const char *)comp_buf, newlength, 1, v);
3110 stp_putc('\015', v);
3111 return 1;
3112 }
3113
3114
3115 static void
canon_write_line(const stp_vars_t v,const canon_cap_t * caps,int ydpi,unsigned char * k,int dk,unsigned char * c,int dc,unsigned char * m,int dm,unsigned char * y,int dy,unsigned char * lc,int dlc,unsigned char * lm,int dlm,unsigned char * ly,int dly,int l,int width,int offset,int * empty,int bits)3116 canon_write_line(const stp_vars_t v, /* I - Print file or command */
3117 const canon_cap_t * caps, /* I - Printer model */
3118 int ydpi, /* I - Vertical resolution */
3119 unsigned char *k, /* I - Output bitmap data */
3120 int dk, /* I - */
3121 unsigned char *c, /* I - Output bitmap data */
3122 int dc, /* I - */
3123 unsigned char *m, /* I - Output bitmap data */
3124 int dm, /* I - */
3125 unsigned char *y, /* I - Output bitmap data */
3126 int dy, /* I - */
3127 unsigned char *lc, /* I - Output bitmap data */
3128 int dlc, /* I - */
3129 unsigned char *lm, /* I - Output bitmap data */
3130 int dlm, /* I - */
3131 unsigned char *ly, /* I - Output bitmap data */
3132 int dly, /* I - */
3133 int l, /* I - Length of bitmap data */
3134 int width, /* I - Printed width */
3135 int offset, /* I - horizontal offset */
3136 int *empty, /* IO- unflushed empty lines */
3137 int bits)
3138 {
3139 int written= 0;
3140
3141 stp_deprintf(STP_DBG_CANON,"canon_write_line: length=%d, width=%d, (hor.)offset=%d\n",
3142 l, width, offset);
3143
3144 if (k) written+=
3145 canon_write(v, caps, k+ dk*l, l, 3, ydpi, empty, width, offset, bits);
3146 if (y) written+=
3147 canon_write(v, caps, y+ dy*l, l, 2, ydpi, empty, width, offset, bits);
3148 if (m) written+=
3149 canon_write(v, caps, m+ dm*l, l, 1, ydpi, empty, width, offset, bits);
3150 if (c) written+=
3151 canon_write(v, caps, c+ dc*l, l, 0, ydpi, empty, width, offset, bits);
3152 if (ly) written+=
3153 canon_write(v, caps, ly+dly*l, l, 6, ydpi, empty, width, offset, bits);
3154 if (lm) written+=
3155 canon_write(v, caps, lm+dlm*l, l, 5, ydpi, empty, width, offset, bits);
3156 if (lc) written+=
3157 canon_write(v, caps, lc+dlc*l, l, 4, ydpi, empty, width, offset, bits);
3158
3159 if (written||(empty==0))
3160 stp_zfwrite("\033\050\145\002\000\000\001", 7, 1, v);
3161 else
3162 (*empty)+= 1;
3163 }
3164
3165 static void
canon_advance_paper(stp_vars_t v,int advance)3166 canon_advance_paper(stp_vars_t v, int advance)
3167 {
3168 if ( advance > 0 )
3169 {
3170 int a0, a1, a2, a3;
3171 stp_deprintf(STP_DBG_CANON,"canon_advance_paper: advance= %d\n", advance);
3172 a0 = advance & 0xff;
3173 a1 = (advance >> 8) & 0xff;
3174 a2 = (advance >> 16) & 0xff;
3175 a3 = (advance >> 24) & 0xff;
3176 stp_zprintf(v, "\033(e%c%c%c%c%c%c", 4, 0, a3, a2, a1, a0);
3177 }
3178 }
3179
3180 static void
canon_flush_pass(stp_softweave_t * sw,int passno,int model,int width,int hoffset,int ydpi,int xdpi,int physical_xdpi,int vertical_subpass)3181 canon_flush_pass(stp_softweave_t *sw, int passno, int model, int width,
3182 int hoffset, int ydpi, int xdpi, int physical_xdpi,
3183 int vertical_subpass)
3184 {
3185 const stp_vars_t nv = (sw->v);
3186 stp_lineoff_t *lineoffs = stp_get_lineoffsets_by_pass(sw, passno);
3187 stp_lineactive_t *lineactive = stp_get_lineactive_by_pass(sw, passno);
3188 const stp_linebufs_t *bufs = stp_get_linebases_by_pass(sw, passno);
3189 stp_pass_t *pass = stp_get_pass_by_pass(sw, passno);
3190 stp_linecount_t *linecount = stp_get_linecount_by_pass(sw, passno);
3191 canon_privdata_weave *privdata_weave = stp_get_driver_data(nv);
3192 int papershift = (pass->logicalpassstart - sw->last_pass_offset);
3193 int color, line, empty = 0, written = 0, linelength = 0, lines = 0;
3194 int idx[4]={3, 0, 1, 2}; /* color numbering is different between canon_write and weaving */
3195
3196 stp_deprintf(STP_DBG_CANON,"canon_flush_pass: pass=%d, papershift=%d\n", passno, papershift);
3197
3198 for ( color = 0; color < sw->ncolors; color++ ) /* find max. linecount */
3199 {
3200 if ( linecount[0].v[color] > lines ) lines = linecount[0].v[color];
3201 }
3202
3203 for ( line = 0; line < lines; line++ ) /* go through each nozzle of that pass */
3204 {
3205 stp_deprintf(STP_DBG_CANON,"canon_flush_pass: line=%d, written=%d, empty=%d \n",
3206 line, written, empty);
3207 if ( written > 0 )
3208 canon_cmd(nv,ESC28,0x65, 2, 0, 1); /* go to next nozzle if there was printed some data */
3209
3210 written = 0;
3211 for ( color = 0; color < sw->ncolors; color++ )
3212 {
3213 if ( line < linecount[0].v[color] ) /* try only existing lines */
3214 {
3215 if ( lineactive[0].v[color] > 0 )
3216 {
3217 linelength = lineoffs[0].v[color] / linecount[0].v[color];
3218 /* stp_deprintf(STP_DBG_CANON,"canon_flush_pass: linelength=%d, bufs[0].v[color]=%p,"
3219 "bufs[0].v[color]+line * linelength=%p, empty=%d \n", linelength, bufs[0].v[color], bufs[0].v[color] + line * linelength, empty);
3220 */
3221 if ( pass->logicalpassstart > sw->last_pass_offset)
3222 {
3223 canon_advance_paper(nv, papershift);
3224 sw->last_pass_offset = pass->logicalpassstart;
3225 if (privdata_weave->bidirectional)
3226 {
3227 privdata_weave->direction = (privdata_weave->direction +1) & 1;
3228 canon_set_X72(nv, privdata_weave->direction);
3229 }
3230 }
3231
3232 written += canon_write(nv, NULL,
3233 (unsigned char *)(bufs[0].v[color] + line * linelength),
3234 linelength, idx[color], 0, &empty, 0, hoffset, sw->bitwidth);
3235 }
3236 }
3237 }
3238
3239 if ( written == 0 ) /* count unused nozzles */
3240 empty += 1;
3241 }
3242
3243 for ( color = 0; color < sw->ncolors; color++ )
3244 {
3245 lineoffs[0].v[color] = 0;
3246 linecount[0].v[color] = 0;
3247 }
3248
3249 sw->last_pass = pass->pass;
3250 pass->pass = -1;
3251
3252 }
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270