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