home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / print / print-canon.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-08  |  40.9 KB  |  1,531 lines

  1. /*
  2.  * "$Id: print-canon.c,v 1.6 2000/11/07 23:23:02 mitch Exp $"
  3.  *
  4.  *   Print plug-in CANON BJL driver for the GIMP.
  5.  *
  6.  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
  7.  *    Robert Krawitz (rlk@alum.mit.edu)
  8.  *
  9.  *   This program is free software; you can redistribute it and/or modify it
  10.  *   under the terms of the GNU General Public License as published by the Free
  11.  *   Software Foundation; either version 2 of the License, or (at your option)
  12.  *   any later version.
  13.  *
  14.  *   This program is distributed in the hope that it will be useful, but
  15.  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16.  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17.  *   for more details.
  18.  *
  19.  *   You should have received a copy of the GNU General Public License
  20.  *   along with this program; if not, write to the Free Software
  21.  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22.  */
  23.  
  24. /*
  25.  * This file must include only standard C header files.  The core code must
  26.  * compile on generic platforms that don't support glib, gimp, gtk, etc.
  27.  */
  28.  
  29.  
  30. /* TODO-LIST
  31.  *
  32.  *   * implement the left border
  33.  *
  34.  */
  35.  
  36. #include <stdarg.h>
  37. #include "print.h"
  38.  
  39. /*
  40.  * Local functions...
  41.  */
  42.  
  43. typedef struct {
  44.   int model;
  45.   int max_width;      /* maximum printable paper size */
  46.   int max_height;
  47.   int max_xdpi;
  48.   int max_ydpi;
  49.   int max_quality;
  50.   int border_left;
  51.   int border_right;
  52.   int border_top;
  53.   int border_bottom;
  54.   int inks;           /* installable cartridges (CANON_INK_*) */
  55.   int slots;          /* available paperslots */
  56.   int features;       /* special bjl settings */
  57. } canon_cap_t;
  58.  
  59. static void canon_write_line(FILE *, canon_cap_t, int,
  60.                  unsigned char *, int,
  61.                  unsigned char *, int,
  62.                  unsigned char *, int,
  63.                  unsigned char *, int,
  64.                  unsigned char *, int,
  65.                  unsigned char *, int,
  66.                  unsigned char *, int,
  67.                  int, int, int, int);
  68.  
  69. #define PHYSICAL_BPI 1440
  70. #define MAX_OVERSAMPLED 4
  71. #define MAX_BPP 2
  72. #define BITS_PER_BYTE 8
  73. #define COMPBUFWIDTH (PHYSICAL_BPI * MAX_OVERSAMPLED * MAX_BPP * \
  74.     MAX_CARRIAGE_WIDTH / BITS_PER_BYTE)
  75.  
  76.  
  77. /* Codes for possible ink-tank combinations.
  78.  * Each combo is represented by the colors that can be used with
  79.  * the installed ink-tank(s)
  80.  * Combinations of the codes represent the combinations allowed for a model
  81.  * Note that only preferrable combinations should be used 
  82.  */
  83. #define CANON_INK_K           1
  84. #define CANON_INK_CMY         2
  85. #define CANON_INK_CMYK        4
  86. #define CANON_INK_CcMmYK      8
  87. #define CANON_INK_CcMmYy     16
  88. #define CANON_INK_CcMmYyK    32
  89.  
  90. #define CANON_INK_BLACK_MASK (CANON_INK_K|CANON_INK_CMYK|\
  91.                               CANON_INK_CcMmYK|CANON_INK_CcMmYyK)
  92.  
  93. #define CANON_INK_PHOTO_MASK (CANON_INK_CcMmYy|CANON_INK_CcMmYK|\
  94.                               CANON_INK_CcMmYyK)
  95.  
  96. /* document feeding */
  97. #define CANON_SLOT_ASF1    1
  98. #define CANON_SLOT_ASF2    2
  99. #define CANON_SLOT_MAN1    4
  100. #define CANON_SLOT_MAN2    8
  101.  
  102. /* model peculiarities */
  103. #define CANON_CAP_DMT       1<<0    /* Drop Modulation Technology */
  104. #define CANON_CAP_MSB_FIRST 1<<1    /* how to send data           */
  105. #define CANON_CAP_CMD61     1<<2    /* uses command #0x61         */
  106. #define CANON_CAP_CMD6d     1<<3    /* uses command #0x6d         */
  107. #define CANON_CAP_CMD70     1<<4    /* uses command #0x70         */
  108. #define CANON_CAP_CMD72     1<<5    /* uses command #0x72         */
  109.  
  110.  
  111. static canon_cap_t canon_model_capabilities[] =
  112. {
  113.   /* default settings for unkown models */
  114.  
  115.   {   -1, 8*72,11*72,180,180,20,20,20,20, CANON_INK_K, CANON_SLOT_ASF1, 0 },
  116.  
  117.   /* tested models */
  118.  
  119.   { /* Canon BJC 4300 */
  120.     4300,
  121.     618, 936,      /* 8.58" x 13 " */
  122.     1440, 720, 2,
  123.     11, 9, 10, 18,
  124.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  125.     CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
  126.     CANON_CAP_DMT
  127.   },
  128.  
  129.   { /* Canon BJC 4400 */
  130.     4400,
  131.     9.5*72, 14*72,
  132.     720, 360, 2,
  133.     11, 9, 10, 18,
  134.     CANON_INK_K | CANON_INK_CMYK | CANON_INK_CcMmYK,
  135.     CANON_SLOT_ASF1,
  136.     CANON_CAP_CMD61 | CANON_CAP_DMT
  137.   },
  138.  
  139.   { /* Canon BJC 6000 */
  140.     6000,
  141.     618, 936,      /* 8.58" x 13 " */
  142.     1440, 720, 2,
  143.     11, 9, 10, 18,
  144.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  145.     CANON_SLOT_ASF1 | CANON_SLOT_MAN1,
  146.     CANON_CAP_DMT
  147.   },
  148.  
  149.   { /* Canon BJC 8200 */
  150.     8200,
  151.     11*72, 17*72,
  152.     1200,1200, 4,
  153.     11, 9, 10, 18,
  154.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  155.     CANON_SLOT_ASF1,
  156.     CANON_CAP_DMT | CANON_CAP_CMD72
  157.   },
  158.  
  159.   /* untested models */
  160.  
  161.   { /* Canon BJC 1000 */
  162.     1000,
  163.     11*72, 17*72,
  164.     360, 360, 2,
  165.     11, 9, 10, 18,
  166.     CANON_INK_K | CANON_INK_CMY,
  167.     CANON_SLOT_ASF1,
  168.     CANON_CAP_CMD61
  169.   },
  170.   { /* Canon BJC 2000 */
  171.     2000,
  172.     11*72, 17*72,
  173.     720, 360, 2,
  174.     11, 9, 10, 18,
  175.     CANON_INK_CMYK,
  176.     CANON_SLOT_ASF1,
  177.     CANON_CAP_CMD61
  178.   },
  179.   { /* Canon BJC 3000 */
  180.     3000,
  181.     11*72, 17*72,
  182.     1440, 720, 2,
  183.     11, 9, 10, 18,
  184.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  185.     CANON_SLOT_ASF1,
  186.     CANON_CAP_CMD61 | CANON_CAP_DMT
  187.   },
  188.   { /* Canon BJC 6100 */
  189.     6100,
  190.     11*72, 17*72,
  191.     1440, 720, 2,
  192.     11, 9, 10, 18,
  193.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  194.     CANON_SLOT_ASF1,
  195.     CANON_CAP_CMD61
  196.   },
  197.   { /* Canon BJC 7000 */
  198.     7000,
  199.     11*72, 17*72,
  200.     1200, 600, 2,
  201.     11, 9, 10, 18,
  202.     CANON_INK_CMYK | CANON_INK_CcMmYyK,
  203.     CANON_SLOT_ASF1,
  204.     0
  205.   },
  206.   { /* Canon BJC 7100 */
  207.     7100,
  208.     11*72, 17*72,
  209.     1200, 600, 2,
  210.     11, 9, 10, 18,
  211.     CANON_INK_CMYK | CANON_INK_CcMmYyK,
  212.     CANON_SLOT_ASF1,
  213.     0
  214.   },
  215.  
  216.   /* extremely fuzzy models */
  217.  
  218.   { /* Canon BJC 5100 */
  219.     5100,
  220.     17*72, 22*72,
  221.     1440, 720, 2,
  222.     11, 9, 10, 18,
  223.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  224.     CANON_SLOT_ASF1,
  225.     CANON_CAP_DMT
  226.   },
  227.   { /* Canon BJC 5500 */
  228.     5500,
  229.     22*72, 34*72,
  230.     720, 360, 2,
  231.     11, 9, 10, 18,
  232.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  233.     CANON_SLOT_ASF1,
  234.     CANON_CAP_CMD61
  235.   },
  236.   { /* Canon BJC 6500 */
  237.     6500,
  238.     17*72, 22*72,
  239.     1440, 720, 2,
  240.     11, 9, 10, 18,
  241.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  242.     CANON_SLOT_ASF1,
  243.     CANON_CAP_CMD61 | CANON_CAP_DMT
  244.   },
  245.   { /* Canon BJC 8500 */
  246.     8500,
  247.     17*72, 22*72,
  248.     1200,1200, 2,
  249.     11, 9, 10, 18,
  250.     CANON_INK_CMYK | CANON_INK_CcMmYK,
  251.     CANON_SLOT_ASF1,
  252.     0
  253.   },
  254. };
  255.  
  256.  
  257.  
  258.  
  259. static canon_cap_t canon_get_model_capabilities(int model)
  260. {
  261.   int i;
  262.   int models= sizeof(canon_model_capabilities) / sizeof(canon_cap_t);
  263.   for (i=0; i<models; i++) {
  264.     if (canon_model_capabilities[i].model == model) {
  265.       return canon_model_capabilities[i];
  266.     }
  267.   }
  268. #ifdef DEBUG
  269.   fprintf(stderr,"canon: model %d not found in capabilities list.\n",model);
  270. #endif
  271.   return canon_model_capabilities[0];
  272. }
  273.  
  274. static int
  275. canon_media_type(const char *name, canon_cap_t caps)
  276. {
  277.   if (!strcmp(name,"Plain Paper"))           return  1;
  278.   if (!strcmp(name,"Transparencies"))        return  2;
  279.   if (!strcmp(name,"Back Print Film"))       return  3;
  280.   if (!strcmp(name,"Fabric Sheets"))         return  4;
  281.   if (!strcmp(name,"Envelope"))              return  5;
  282.   if (!strcmp(name,"High Resolution Paper")) return  6;
  283.   if (!strcmp(name,"T-Shirt Transfers"))     return  7;
  284.   if (!strcmp(name,"High Gloss Film"))       return  8;
  285.   if (!strcmp(name,"Glossy Photo Paper"))    return  9;
  286.   if (!strcmp(name,"Glossy Photo Cards"))    return 10;
  287.   if (!strcmp(name,"Photo Paper Pro"))       return 11;
  288.  
  289. #ifdef DEBUG
  290.   fprintf(stderr,"canon: Unknown media type '%s' - reverting to plain\n",name);
  291. #endif
  292.   return 1;
  293. }
  294.  
  295. static int
  296. canon_source_type(const char *name, canon_cap_t caps)
  297. {
  298.   if (!strcmp(name,"Auto Sheet Feeder"))    return 4;
  299.   if (!strcmp(name,"Manual with Pause"))    return 0;
  300.   if (!strcmp(name,"Manual without Pause")) return 1;
  301.  
  302. #ifdef DEBUG
  303.   fprintf(stderr,"canon: Unknown source type '%s' - reverting to auto\n",name);
  304. #endif
  305.   return 4;
  306. }
  307.  
  308. static int
  309. canon_printhead_type(const char *name, canon_cap_t caps)
  310. {
  311.   if (!strcmp(name,"Black"))             return 0;
  312.   if (!strcmp(name,"Color"))             return 1;
  313.   if (!strcmp(name,"Black/Color"))       return 2;
  314.   if (!strcmp(name,"Photo/Color"))       return 3;
  315.   if (!strcmp(name,"Photo"))             return 4;
  316.   if (!strcmp(name,"Black/Photo Color")) return 5;
  317.  
  318.   if (*name == 0) {
  319.     if (caps.inks & CANON_INK_CMYK) return 2;
  320.     if (caps.inks & CANON_INK_CMY)  return 1;
  321.     if (caps.inks & CANON_INK_K)    return 0;
  322.   }
  323.  
  324. #ifdef DEBUG
  325.   fprintf(stderr,"canon: Unknown head combo '%s' - reverting to black\n",name);
  326. #endif
  327.   return 0;
  328. }
  329.  
  330. static unsigned char
  331. canon_size_type(const vars_t *v, canon_cap_t caps)
  332. {
  333.   const papersize_t *pp = get_papersize_by_size(v->page_height, v->page_width);
  334.   if (pp)
  335.     {
  336.       const char *name = pp->name;
  337.       /* built ins: */
  338.       if (!strcmp(name,"A5"))          return 0x01;
  339.       if (!strcmp(name,"A4"))          return 0x03;
  340.       if (!strcmp(name,"B5"))          return 0x08;
  341.       if (!strcmp(name,"Letter"))      return 0x0d;
  342.       if (!strcmp(name,"Legal"))       return 0x0f;
  343.       if (!strcmp(name,"Envelope 10")) return 0x16;
  344.       if (!strcmp(name,"Envelope DL")) return 0x17;
  345.       if (!strcmp(name,"Letter+"))     return 0x2a;
  346.       if (!strcmp(name,"A4+"))         return 0x2b;
  347.       if (!strcmp(name,"Canon 4x2"))   return 0x2d;
  348.       /* custom */
  349.  
  350. #ifdef DEBUG
  351.       fprintf(stderr,"canon: Unknown paper size '%s' - using custom\n",name);
  352.     } else {
  353.       fprintf(stderr,"canon: Couldn't look up paper size %dx%d - "
  354.           "using custom\n",v->page_height, v->page_width);
  355. #endif
  356.     }
  357.   return 0;
  358. }
  359.  
  360. static char *
  361. c_strdup(const char *s)
  362. {
  363.   char *ret = malloc(strlen(s) + 1);
  364.   strcpy(ret, s);
  365.   return ret;
  366. }
  367.  
  368. const char *
  369. canon_default_resolution(const printer_t *printer)
  370. {
  371.   canon_cap_t caps= canon_get_model_capabilities(printer->model);
  372.   if (!(caps.max_xdpi%300))
  373.     return "300x300 DPI";
  374.   else
  375.     return "180x180 DPI";
  376. }
  377.  
  378. /*
  379.  * 'canon_parameters()' - Return the parameter values for the given parameter.
  380.  */
  381.  
  382. char **                    /* O - Parameter values */
  383. canon_parameters(const printer_t *printer,    /* I - Printer model */
  384.                  char *ppd_file,    /* I - PPD file (not used) */
  385.                  char *name,        /* I - Name of parameter */
  386.                  int  *count)        /* O - Number of values */
  387. {
  388.   int        i;
  389.   char        **p= 0,
  390.                 **valptrs= 0;
  391.  
  392.   static char   *media_types[] =
  393.                 {
  394.                   ("Plain Paper"),
  395.                   ("Transparencies"),
  396.                   ("Back Print Film"),
  397.                   ("Fabric Sheets"),
  398.                   ("Envelope"),
  399.                   ("High Resolution Paper"),
  400.                   ("T-Shirt Transfers"),
  401.                   ("High Gloss Film"),
  402.                   ("Glossy Photo Paper"),
  403.                   ("Glossy Photo Cards"),
  404.                   ("Photo Paper Pro")
  405.                 };
  406.   static char   *media_sources[] =
  407.                 {
  408.                   ("Auto Sheet Feeder"),
  409.                   ("Manual with Pause"),
  410.                   ("Manual without Pause"),
  411.                 };
  412.  
  413.   canon_cap_t caps= canon_get_model_capabilities(printer->model);
  414.  
  415.   if (count == NULL)
  416.     return (NULL);
  417.  
  418.   *count = 0;
  419.  
  420.   if (name == NULL)
  421.     return (NULL);
  422.  
  423.   if (strcmp(name, "PageSize") == 0) {
  424.     int length_limit, width_limit;
  425.     const papersize_t *papersizes = get_papersizes();
  426.     valptrs = malloc(sizeof(char *) * known_papersizes());
  427.     *count = 0;
  428.  
  429.     width_limit = caps.max_width;
  430.     length_limit = caps.max_height;
  431.  
  432.     for (i = 0; i < known_papersizes(); i++) {
  433.       if (strlen(papersizes[i].name) > 0 &&
  434.       papersizes[i].width <= width_limit &&
  435.       papersizes[i].length <= length_limit) {
  436.     valptrs[*count] = malloc(strlen(papersizes[i].name) + 1);
  437.     strcpy(valptrs[*count], papersizes[i].name);
  438.     (*count)++;
  439.       }
  440.     }
  441.     return (valptrs);
  442.   }
  443.   else if (strcmp(name, "Resolution") == 0)
  444.   {
  445.     int x= caps.max_xdpi, y= caps.max_ydpi;
  446.     int c= 0;
  447.     valptrs = malloc(sizeof(char *) * 10);
  448.     if (!(caps.max_xdpi%300)) {
  449.  
  450.       if ( 300<=x && 300<=y)
  451.     valptrs[c++]= c_strdup("300x300 DPI");
  452.       if ( 300<=x && 300<=y && (caps.features&CANON_CAP_DMT))
  453.     valptrs[c++]= c_strdup("300x300 DPI DMT");
  454.       if ( 600<=x && 600<=y)
  455.     valptrs[c++]= c_strdup("600x600 DPI");
  456.       if ( 600<=x && 600<=y && (caps.features&CANON_CAP_DMT))
  457.     valptrs[c++]= c_strdup("600x600 DPI DMT");
  458.       if (1200==x && 600==y)
  459.     valptrs[c++]= c_strdup("1200x600 DPI");
  460.       if (1200<=x && 1200<=y)
  461.     valptrs[c++]= c_strdup("1200x1200 DPI");
  462.  
  463.     } else if (!(caps.max_xdpi%180)) {
  464.  
  465.       if ( 180<=x && 180<=y)
  466.     valptrs[c++]= c_strdup("180x180 DPI");
  467.       if ( 360<=x && 360<=y)
  468.     valptrs[c++]= c_strdup("360x360 DPI");
  469.       if ( 360<=x && 360<=y && (caps.features&CANON_CAP_DMT))
  470.     valptrs[c++]= c_strdup("360x360 DPI DMT");
  471.       if ( 720==x && 360==y)
  472.     valptrs[c++]= c_strdup("720x360 DPI");
  473.       if ( 720<=x && 720<=y)
  474.     valptrs[c++]= c_strdup("720x720 DPI");
  475.       if (1440==x && 720==y)
  476.     valptrs[c++]= c_strdup("1440x720 DPI");
  477.       if (1440<=x &&1440<=y)
  478.     valptrs[c++]= c_strdup("1440x1440 DPI");
  479.  
  480.     } else {
  481. #ifdef DEBUG
  482.       fprintf(stderr,"canon: unknown resolution multiplier for model %d\n",
  483.           caps.model);
  484. #endif
  485.       return 0;
  486.     }
  487.     *count= c;
  488.     p= valptrs;
  489.   }
  490.   else if (strcmp(name, "InkType") == 0)
  491.   {
  492.     int c= 0;
  493.     valptrs = malloc(sizeof(char *) * 5);
  494.     if ((caps.inks & CANON_INK_K))
  495.       valptrs[c++]= c_strdup("Black");
  496.     if ((caps.inks & CANON_INK_CMY))
  497.       valptrs[c++]= c_strdup("Color");
  498.     if ((caps.inks & CANON_INK_CMYK))
  499.       valptrs[c++]= c_strdup("Black/Color");
  500.     if ((caps.inks & CANON_INK_CcMmYK))
  501.       valptrs[c++]= c_strdup("Photo/Color");
  502.     if ((caps.inks & CANON_INK_CcMmYy))
  503.       valptrs[c++]= c_strdup("Photo");
  504.     if ((caps.inks & CANON_INK_CcMmYyK))
  505.       valptrs[c++]= c_strdup("Black/Photo Color");
  506.     *count = c;
  507.     p = valptrs;
  508.   }
  509.   else if (strcmp(name, "MediaType") == 0)
  510.   {
  511.     *count = 11;
  512.     p = media_types;
  513.   }
  514.   else if (strcmp(name, "InputSlot") == 0)
  515.   {
  516.     *count = 3;
  517.     p = media_sources;
  518.   }
  519.   else
  520.     return (NULL);
  521.  
  522.   valptrs = malloc(*count * sizeof(char *));
  523.   for (i = 0; i < *count; i ++)
  524.     valptrs[i] = c_strdup(p[i]);
  525.  
  526.   return (valptrs);
  527. }
  528.  
  529.  
  530. /*
  531.  * 'canon_imageable_area()' - Return the imageable area of the page.
  532.  */
  533.  
  534. void
  535. canon_imageable_area(const printer_t *printer,    /* I - Printer model */
  536.              const vars_t *v,   /* I */
  537.                      int  *left,    /* O - Left position in points */
  538.                      int  *right,    /* O - Right position in points */
  539.                      int  *bottom,    /* O - Bottom position in points */
  540.                      int  *top)        /* O - Top position in points */
  541. {
  542.   int    width, length;            /* Size of page */
  543.  
  544.   canon_cap_t caps= canon_get_model_capabilities(printer->model);
  545.  
  546.   default_media_size(printer, v, &width, &length);
  547.  
  548.   *left   = caps.border_left;
  549.   *right  = width - caps.border_right;
  550.   *top    = length - caps.border_top;
  551.   *bottom = caps.border_bottom;
  552. }
  553.  
  554. void
  555. canon_limit(const printer_t *printer,    /* I - Printer model */
  556.         const vars_t *v,          /* I */
  557.         int  *width,        /* O - Left position in points */
  558.         int  *length)        /* O - Top position in points */
  559. {
  560.   canon_cap_t caps= canon_get_model_capabilities(printer->model);
  561.   *width =    caps.max_width;
  562.   *length =    caps.max_height;
  563. }
  564.  
  565. /*
  566.  * 'canon_cmd()' - Sends a command with variable args
  567.  */
  568. static void
  569. canon_cmd(FILE *prn, /* I - the printer         */
  570.       char *ini, /* I - 2 bytes start code  */
  571.       char cmd,  /* I - command code        */
  572.       int  num,  /* I - number of arguments */
  573.       ...        /* I - the args themselves */
  574.       )
  575. {
  576.   static int bufsize= 0;
  577.   static unsigned char *buffer;
  578.   int i;
  579.   va_list ap;
  580.  
  581.   if (!buffer || (num > bufsize)) {
  582.     if (buffer)
  583.       free(buffer);
  584.     buffer = malloc(num);
  585.     bufsize= num;
  586.     if (!buffer) {
  587. #ifdef DEBUG
  588.       fprintf(stderr,"\ncanon: *** buffer allocation failed...\n");
  589.       fprintf(stderr,"canon: *** command 0x%02x with %d args dropped\n\n",
  590.           cmd,num);
  591. #endif
  592.       return;
  593.     }
  594.   }
  595.   if (num) {
  596.     va_start(ap, num);
  597.     for (i=0; i<num; i++)
  598.       buffer[i]= (unsigned char) va_arg(ap, int);
  599.     va_end(ap);
  600.   }
  601.  
  602.   fwrite(ini,2,1,prn);
  603.   if (cmd) {
  604.     fputc(cmd,prn);
  605.     fputc((num & 255),prn);
  606.     fputc((num >> 8 ),prn);
  607.     fwrite(buffer,num,1,prn);
  608.   }
  609. }
  610.  
  611. #ifdef DEBUG
  612. #define PUT(WHAT,VAL,RES) fprintf(stderr,"canon: "WHAT" is %04x =% 5d = %f\" = %f mm\n",(VAL),(VAL),(VAL)/(1.*RES),(VAL)/(RES/25.4))
  613. #else
  614. #define PUT(WHAT,VAL,RES) do {} while (0)
  615. #endif
  616.  
  617. static void
  618. canon_init_printer(FILE *prn, canon_cap_t caps,
  619.            int output_type, const char *media_str,
  620.            const vars_t *v, int print_head,
  621.            const char *source_str,
  622.            int xdpi, int ydpi,
  623.            int page_width, int page_height,
  624.            int top, int left,
  625.            int use_dmt)
  626. {
  627. #define MEDIACODES 11
  628.   static unsigned char mediacode_63[] = {
  629.     0x00,0x00,0x02,0x03,0x04,0x08,0x07,0x03,0x06,0x05,0x05,0x09
  630.   };
  631.   static unsigned char mediacode_6c[] = {
  632.     0x00,0x00,0x02,0x03,0x04,0x08,0x07,0x03,0x06,0x05,0x0a,0x09
  633.   };
  634.  
  635.   #define ESC28 "\x1b\x28"
  636.   #define ESC5b "\x1b\x5b"
  637.   #define ESC40 "\x1b\x40"
  638.  
  639.   unsigned char
  640.     arg_63_1 = 0x00,
  641.     arg_63_2 = 0x00, /* plain paper */
  642.     arg_63_3 = caps.max_quality, /* output quality  */
  643.     arg_6c_1 = 0x00,
  644.     arg_6c_2 = 0x01, /* plain paper */
  645.     arg_6d_1 = 0x03, /* color printhead? */
  646.     arg_6d_2 = 0x00, /* 00=color  02=b/w */
  647.     arg_6d_3 = 0x00, /* only 01 for bjc8200 */
  648.     arg_6d_a = 0x03, /* A4 paper */
  649.     arg_6d_b = 0x00,
  650.     arg_70_1 = 0x02, /* A4 printable area */
  651.     arg_70_2 = 0xa6,
  652.     arg_70_3 = 0x01,
  653.     arg_70_4 = 0xe0,
  654.     arg_74_1 = 0x01, /* 1 bit per pixel */
  655.     arg_74_2 = 0x00, /*  */
  656.     arg_74_3 = 0x01; /* 01 <= 360 dpi    09 >= 720 dpi */
  657.  
  658.   int media= canon_media_type(media_str,caps);
  659.   int source= canon_source_type(source_str,caps);
  660.  
  661.   int printable_width=  page_width*10/12;
  662.   int printable_height= page_height*10/12;
  663.  
  664.   arg_6d_a= canon_size_type(v,caps);
  665.   if (!arg_6d_a) arg_6d_b= 1;
  666.  
  667.   if (caps.model<3000)
  668.     arg_63_1= arg_6c_1= 0x10;
  669.   else
  670.     arg_63_1= arg_6c_1= 0x30;
  671.  
  672.   if (output_type==OUTPUT_GRAY) arg_63_1|= 0x01;
  673.   arg_6c_1|= (source & 0x0f);
  674.  
  675.   if (print_head==0) arg_6d_1= 0x03;
  676.   else if (print_head<=2) arg_6d_1= 0x02;
  677.   else if (print_head<=4) arg_6d_1= 0x04;
  678.   if (output_type==OUTPUT_GRAY) arg_6d_2= 0x02;
  679.  
  680.   if (caps.model==8200) arg_6d_3= 0x01;
  681.  
  682.   arg_70_1= (printable_height >> 8) & 0xff;
  683.   arg_70_2= (printable_height) & 0xff;
  684.   arg_70_3= (printable_width >> 8) & 0xff;
  685.   arg_70_4= (printable_width) & 0xff;
  686.  
  687.   if (xdpi==1440) arg_74_2= 0x04;
  688.   if (ydpi>=720)  arg_74_3= 0x09;
  689.  
  690.   if (media<MEDIACODES) {
  691.     arg_63_2= mediacode_63[media];
  692.     arg_6c_2= mediacode_6c[media];
  693.   }
  694.  
  695.   if (use_dmt) {
  696.     arg_74_1= 0x02;
  697.     arg_74_2= 0x80;
  698.     arg_74_3= 0x09;
  699.   }
  700.  
  701.   /* workaround for the bjc8200 - not really understood */
  702.   if (caps.model==8200 && use_dmt) {
  703.     arg_74_1= 0xff;
  704.     arg_74_2= 0x90;
  705.     arg_74_3= 0x04;
  706.   }
  707.  
  708.   /*
  709. #ifdef DEBUG
  710.   fprintf(stderr,"canon: printable size = %dx%d (%dx%d) %02x%02x %02x%02x\n",
  711.       page_width,page_height,printable_width,printable_height,
  712.       arg_70_1,arg_70_2,arg_70_3,arg_70_4);
  713. #endif
  714.   */
  715.  
  716.   /* init printer */
  717.  
  718.   canon_cmd(prn,ESC5b,0x4b, 2, 0x00,0x0f);
  719.   if (caps.features & CANON_CAP_CMD61)
  720.     canon_cmd(prn,ESC28,0x61, 1, 0x01);
  721.   canon_cmd(prn,ESC28,0x62, 1, 0x01);
  722.   canon_cmd(prn,ESC28,0x71, 1, 0x01);
  723.  
  724.   if (caps.features & CANON_CAP_CMD6d)
  725.     canon_cmd(prn,ESC28,0x6d,12, arg_6d_1,
  726.           0xff,0xff,0x00,0x00,0x07,0x00,
  727.           arg_6d_a,arg_6d_b,arg_6d_2,0x00,arg_6d_3);
  728.  
  729.   /* set resolution */
  730.  
  731.   canon_cmd(prn,ESC28,0x64, 4, (ydpi >> 8 ), (ydpi & 255),
  732.                             (xdpi >> 8 ), (xdpi & 255));
  733.  
  734.   canon_cmd(prn,ESC28,0x74, 3, arg_74_1, arg_74_2, arg_74_3);
  735.  
  736.   canon_cmd(prn,ESC28,0x63, 3, arg_63_1, arg_63_2, arg_63_3);
  737.  
  738.   if (caps.features & CANON_CAP_CMD70)
  739.     canon_cmd(prn,ESC28,0x70, 8, arg_70_1, arg_70_2, 0x00, 0x00,
  740.                              arg_70_3, arg_70_4, 0x00, 0x00);
  741.  
  742.   canon_cmd(prn,ESC28,0x6c, 2, arg_6c_1, arg_6c_2);
  743.  
  744.   if (caps.features & CANON_CAP_CMD72)
  745.     canon_cmd(prn,ESC28,0x72, 1, 0x61); /* whatever for - 8200 might need it */
  746.  
  747.   /* some linefeeds */
  748.  
  749.   top= (top*ydpi)/72;
  750.   PUT("topskip ",top,ydpi);
  751.   canon_cmd(prn,ESC28,0x65, 2, (top >> 8 ),(top & 255));
  752. }
  753.  
  754. void canon_deinit_printer(FILE *prn, canon_cap_t caps)
  755. {
  756.   /* eject page */
  757.   fputc(0x0c,prn);
  758.  
  759.   /* say goodbye */
  760.   canon_cmd(prn,ESC28,0x62,1,0);
  761.   if (caps.features & CANON_CAP_CMD61)
  762.     canon_cmd(prn,ESC28,0x61, 1, 0x00);
  763.   canon_cmd(prn,ESC40,0,0);
  764.   fflush(prn);
  765. }
  766.  
  767.  
  768. /*
  769.  *  'alloc_buffer()' allocates buffer and fills it with 0
  770.  */
  771. static unsigned char *canon_alloc_buffer(int size)
  772. {
  773.   unsigned char *buf= malloc(size);
  774.   if (buf) memset(buf,0,size);
  775.   return buf;
  776. }
  777.  
  778. /*
  779.  * 'advance_buffer()' - Move (num) lines of length (len) down one line
  780.  *                      and sets first line to 0s
  781.  *                      accepts NULL pointers as buf
  782.  *                  !!! buf must contain more than (num) lines !!!
  783.  *                      also sets first line to 0s if num<1
  784.  */
  785. static void
  786. canon_advance_buffer(unsigned char *buf, int len, int num)
  787. {
  788.   if (!buf || !len) return;
  789.   if (num>0) memmove(buf+len,buf,len*num);
  790.   memset(buf,0,len);
  791. }
  792.  
  793. /*
  794.  * 'canon_print()' - Print an image to a CANON printer.
  795.  */
  796. void
  797. canon_print(const printer_t *printer,        /* I - Model */
  798.             int       copies,        /* I - Number of copies */
  799.             FILE      *prn,        /* I - File to print to */
  800.         Image     image,        /* I - Image to print */
  801.         const vars_t    *v)
  802. {
  803.   unsigned char *cmap = v->cmap;
  804.   int        model = printer->model;
  805.   const char    *resolution = v->resolution;
  806.   const char    *media_type = v->media_type;
  807.   const char    *media_source = v->media_source;
  808.   int         output_type = v->output_type;
  809.   int        orientation = v->orientation;
  810.   const char    *ink_type = v->ink_type;
  811.   double     scaling = v->scaling;
  812.   int        top = v->top;
  813.   int        left = v->left;
  814.   int        y;        /* Looping vars */
  815.   int        xdpi, ydpi;    /* Resolution */
  816.   int        n;        /* Output number */
  817.   unsigned short *out;    /* Output pixels (16-bit) */
  818.   unsigned char    *in,        /* Input pixels */
  819.         *black,        /* Black bitmap data */
  820.         *cyan,        /* Cyan bitmap data */
  821.         *magenta,    /* Magenta bitmap data */
  822.         *yellow,    /* Yellow bitmap data */
  823.         *lcyan,        /* Light cyan bitmap data */
  824.         *lmagenta,    /* Light magenta bitmap data */
  825.         *lyellow;    /* Light yellow bitmap data */
  826.   int           delay_k,
  827.                 delay_c,
  828.                 delay_m,
  829.                 delay_y,
  830.                 delay_lc,
  831.                 delay_lm,
  832.                 delay_ly,
  833.                 delay_max;
  834.   int        page_left,    /* Left margin of page */
  835.         page_right,    /* Right margin of page */
  836.         page_top,    /* Top of page */
  837.         page_bottom,    /* Bottom of page */
  838.         page_width,    /* Width of page */
  839.         page_height,    /* Height of page */
  840.         page_length,    /* True length of page */
  841.         out_width,    /* Width of image on page */
  842.         out_height,    /* Height of image on page */
  843.         out_bpp,    /* Output bytes per pixel */
  844.         length,        /* Length of raster data */
  845.                 buf_length,     /* Length of raster data buffer (dmt) */
  846.         errdiv,        /* Error dividend */
  847.         errmod,        /* Error modulus */
  848.         errval,        /* Current error value */
  849.         errline,    /* Current raster line */
  850.         errlast;    /* Last raster line loaded */
  851.   convert_t    colorfunc = 0;    /* Color conversion function... */
  852.   int           image_height,
  853.                 image_width,
  854.                 image_bpp;
  855.   int           use_dmt = 0;
  856.   void *    dither;
  857.   double        the_levels[] = { 0.5, 0.75, 1.0 };
  858.   vars_t    nv;
  859.  
  860.   canon_cap_t caps= canon_get_model_capabilities(model);
  861.   int printhead= canon_printhead_type(ink_type,caps);
  862.  
  863.   memcpy(&nv, v, sizeof(vars_t));
  864.   /*
  865.   PUT("top        ",top,72);
  866.   PUT("left       ",left,72);
  867.   */
  868.  
  869.   /*
  870.   * Setup a read-only pixel region for the entire image...
  871.   */
  872.  
  873.   Image_init(image);
  874.   image_height = Image_height(image);
  875.   image_width = Image_width(image);
  876.   image_bpp = Image_bpp(image);
  877.  
  878.   /* force grayscale if image is grayscale
  879.    *                 or single black cartridge installed
  880.    */
  881.  
  882.   if (nv.image_type == IMAGE_MONOCHROME)
  883.     {
  884.       output_type = OUTPUT_GRAY;
  885.     }
  886.  
  887.   if (printhead == 0 || caps.inks == CANON_INK_K)
  888.     output_type = OUTPUT_GRAY;
  889.  
  890.   /*
  891.    * Choose the correct color conversion function...
  892.    */
  893.  
  894.   colorfunc = choose_colorfunc(output_type, image_bpp, cmap, &out_bpp, &nv);
  895.  
  896.  /*
  897.   * Figure out the output resolution...
  898.   */
  899.  
  900.   sscanf(resolution,"%dx%d",&xdpi,&ydpi);
  901. #ifdef DEBUG
  902.   fprintf(stderr,"canon: resolution=%dx%d\n",xdpi,ydpi);
  903. #endif
  904.  
  905.   if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
  906.       (caps.features & CANON_CAP_DMT) &&
  907.       nv.image_type != IMAGE_MONOCHROME) {
  908.     use_dmt= 1;
  909. #ifdef DEBUG
  910.     fprintf(stderr,"canon: using drop modulation technology\n");
  911. #endif
  912.   }
  913.  
  914.  /*
  915.   * Compute the output size...
  916.   */
  917.  
  918.   canon_imageable_area(printer, &nv, &page_left, &page_right,
  919.                        &page_bottom, &page_top);
  920.  
  921.   compute_page_parameters(page_right, page_left, page_top, page_bottom,
  922.               scaling, image_width, image_height, image,
  923.               &orientation, &page_width, &page_height,
  924.               &out_width, &out_height, &left, &top);
  925.  
  926.   /*
  927.    * Recompute the image height and width.  If the image has been
  928.    * rotated, these will change from previously.
  929.    */
  930.   image_height = Image_height(image);
  931.   image_width = Image_width(image);
  932.  
  933.   default_media_size(printer, &nv, &n, &page_length);
  934.  
  935.   /*
  936.   PUT("top        ",top,72);
  937.   PUT("left       ",left,72);
  938.   PUT("page_top   ",page_top,72);
  939.   PUT("page_bottom",page_bottom,72);
  940.   PUT("page_left  ",page_left,72);
  941.   PUT("page_right ",page_right,72);
  942.   PUT("page_width ",page_width,72);
  943.   PUT("page_height",page_height,72);
  944.   PUT("page_length",page_length,72);
  945.   PUT("out_width ", out_width,xdpi);
  946.   PUT("out_height", out_height,ydpi);
  947.   */
  948.  
  949.   Image_progress_init(image);
  950.  
  951.   PUT("top     ",top,72);
  952.   PUT("left    ",left,72);
  953.  
  954.   canon_init_printer(prn, caps, output_type, media_type,
  955.              &nv, printhead, media_source,
  956.              xdpi, ydpi, page_width, page_height,
  957.              top,left,use_dmt);
  958.  
  959.  /*
  960.   * Convert image size to printer resolution...
  961.   */
  962.  
  963.   out_width  = xdpi * out_width / 72;
  964.   out_height = ydpi * out_height / 72;
  965.  
  966.   /*
  967.   PUT("out_width ", out_width,xdpi);
  968.   PUT("out_height", out_height,ydpi);
  969.   */
  970.  
  971.   left = xdpi * left / 72;
  972.  
  973.   PUT("leftskip",left,xdpi);
  974.  
  975.   if(xdpi==1440){
  976.     delay_k= 0;
  977.     delay_c= 112;
  978.     delay_m= 224;
  979.     delay_y= 336;
  980.     delay_lc= 112;
  981.     delay_lm= 224;
  982.     delay_ly= 0;
  983.     delay_max= 336;
  984. #ifdef DEBUG
  985.     fprintf(stderr,"canon: delay on!\n");
  986. #endif
  987.   } else {
  988.     delay_k= delay_c= delay_m= delay_y= delay_lc= delay_lm= delay_ly=0;
  989.     delay_max=0;
  990. #ifdef DEBUG
  991.     fprintf(stderr,"canon: delay off!\n");
  992. #endif
  993.   }
  994.  
  995.  /*
  996.   * Allocate memory for the raster data...
  997.   */
  998.  
  999.   length = (out_width + 7) / 8;
  1000.  
  1001.   if (use_dmt) {
  1002.     buf_length= length*2;
  1003.   } else {
  1004.     buf_length= length;
  1005.   }
  1006.  
  1007. #ifdef DEBUG
  1008.   fprintf(stderr,"canon: buflength is %d!\n",buf_length);
  1009. #endif
  1010.  
  1011.   if (output_type == OUTPUT_GRAY) {
  1012.     black   = canon_alloc_buffer(buf_length*(delay_k+1));
  1013.     cyan    = NULL;
  1014.     magenta = NULL;
  1015.     lcyan   = NULL;
  1016.     lmagenta= NULL;
  1017.     yellow  = NULL;
  1018.     lyellow = NULL;
  1019.   } else {
  1020.     cyan    = canon_alloc_buffer(buf_length*(delay_c+1));
  1021.     magenta = canon_alloc_buffer(buf_length*(delay_m+1));
  1022.     yellow  = canon_alloc_buffer(buf_length*(delay_y+1));
  1023.  
  1024.     if ((caps.inks & CANON_INK_BLACK_MASK))
  1025.       black = canon_alloc_buffer(buf_length*(delay_k+1));
  1026.     else
  1027.       black = NULL;
  1028.  
  1029.     if (printhead==3 && (caps.inks & (CANON_INK_PHOTO_MASK))) {
  1030.       lcyan = canon_alloc_buffer(buf_length*(delay_lc+1));
  1031.       lmagenta = canon_alloc_buffer(buf_length*(delay_lm+1));
  1032.       if ((caps.inks & CANON_INK_CcMmYy) || 
  1033.       (caps.inks & CANON_INK_CcMmYyK))
  1034.     lyellow = canon_alloc_buffer(buf_length*(delay_lc+1));
  1035.       else
  1036.     lyellow = NULL;
  1037.     } else {
  1038.       lcyan = NULL;
  1039.       lmagenta = NULL;
  1040.       lyellow = NULL;
  1041.     }
  1042.   }
  1043.  
  1044. #ifdef DEBUG
  1045.   fprintf(stderr,"canon: driver will use colors ");
  1046.   if (cyan)     fputc('C',stderr);
  1047.   if (lcyan)    fputc('c',stderr);
  1048.   if (magenta)  fputc('M',stderr);
  1049.   if (lmagenta) fputc('m',stderr);
  1050.   if (yellow)   fputc('Y',stderr);
  1051.   if (lyellow)  fputc('y',stderr);
  1052.   if (black)    fputc('K',stderr);
  1053.   fprintf(stderr,"\n");
  1054. #endif
  1055.  
  1056. #ifdef DEBUG
  1057.   fprintf(stderr,"density is %f\n",nv.density);
  1058. #endif
  1059.  
  1060.   nv.density = (nv.density * ydpi) / (xdpi * 1.0);
  1061.   if (nv.density > 1.0)
  1062.     nv.density = 1.0;
  1063.   compute_lut(256, &nv);
  1064.  
  1065. #ifdef DEBUG
  1066.   fprintf(stderr,"density is %f\n",nv.density);
  1067. #endif
  1068.  
  1069.   if (xdpi > ydpi)
  1070.     dither = init_dither(image_width, out_width, 1, xdpi / ydpi, &nv);
  1071.   else
  1072.     dither = init_dither(image_width, out_width, ydpi / xdpi, 1, &nv);
  1073.  
  1074.   dither_set_black_levels(dither, 1.0, 1.0, 1.0);
  1075.   dither_set_black_lower(dither, .8 / ((1 << (use_dmt+1)) - 1));
  1076.   /*
  1077.   if (use_glossy_film)
  1078.   */
  1079.   dither_set_black_upper(dither, .999);
  1080.   /*
  1081.   else
  1082.     dither_set_black_upper(dither, .999);
  1083.   */
  1084.  
  1085.   if (!use_dmt) {
  1086.     dither_set_light_inks(dither,
  1087.               (lcyan)   ? (0.3333) : (0.0),
  1088.               (lmagenta)? (0.3333) : (0.0),
  1089.               (lyellow) ? (0.3333) : (0.0), nv.density);
  1090.   }
  1091.  
  1092.   switch (nv.image_type)
  1093.     {
  1094.     case IMAGE_LINE_ART:
  1095.       dither_set_ink_spread(dither, 19);
  1096.       break;
  1097.     case IMAGE_SOLID_TONE:
  1098.       dither_set_ink_spread(dither, 15);
  1099.       break;
  1100.     case IMAGE_CONTINUOUS:
  1101.       dither_set_ink_spread(dither, 14);
  1102.       break;
  1103.     }
  1104.   dither_set_density(dither, nv.density);
  1105.  
  1106.   if (use_dmt)
  1107.     {
  1108.       dither_set_c_ranges_simple(dither, 3, the_levels, nv.density);
  1109.       dither_set_m_ranges_simple(dither, 3, the_levels, nv.density);
  1110.       dither_set_y_ranges_simple(dither, 3, the_levels, nv.density);
  1111.       dither_set_k_ranges_simple(dither, 3, the_levels, nv.density);
  1112.     }
  1113.  /*
  1114.   * Output the page...
  1115.   */
  1116.  
  1117.   in  = malloc(image_width * image_bpp);
  1118.   out = malloc(image_width * out_bpp * 2);
  1119.  
  1120.   errdiv  = image_height / out_height;
  1121.   errmod  = image_height % out_height;
  1122.   errval  = 0;
  1123.   errlast = -1;
  1124.   errline  = 0;
  1125.  
  1126.   for (y = 0; y < out_height; y ++)
  1127.   {
  1128.     int duplicate_line = 1;
  1129.     if ((y & 63) == 0)
  1130.       Image_note_progress(image, y, out_height);
  1131.  
  1132.     if (errline != errlast)
  1133.     {
  1134.       errlast = errline;
  1135.       duplicate_line = 0;
  1136.       Image_get_row(image, in, errline);
  1137.       (*colorfunc)(in, out, image_width, image_bpp, cmap, &nv);
  1138.     }
  1139.  
  1140.     if (nv.image_type == IMAGE_MONOCHROME)
  1141.       dither_monochrome(out, y, dither, black, duplicate_line);
  1142.     else if (output_type == OUTPUT_GRAY)
  1143.       dither_black(out, y, dither, black, duplicate_line);
  1144.     else
  1145.       dither_cmyk(out, y, dither, cyan, lcyan, magenta, lmagenta,
  1146.           yellow, 0, black, duplicate_line);
  1147.  
  1148. #ifdef DEBUG
  1149.     /* fprintf(stderr,","); */
  1150. #endif
  1151.  
  1152.     canon_write_line(prn, caps, ydpi,
  1153.              black,    delay_k,
  1154.              cyan,     delay_c,
  1155.              magenta,  delay_m,
  1156.              yellow,   delay_y,
  1157.              lcyan,    delay_lc,
  1158.              lmagenta, delay_lm,
  1159.              lyellow,  delay_ly,
  1160.              length, out_width, left, use_dmt);
  1161.  
  1162. #ifdef DEBUG
  1163.     /* fprintf(stderr,"!"); */
  1164. #endif
  1165.  
  1166.     canon_advance_buffer(black,   buf_length,delay_k);
  1167.     canon_advance_buffer(cyan,    buf_length,delay_c);
  1168.     canon_advance_buffer(magenta, buf_length,delay_m);
  1169.     canon_advance_buffer(yellow,  buf_length,delay_y);
  1170.     canon_advance_buffer(lcyan,   buf_length,delay_lc);
  1171.     canon_advance_buffer(lmagenta,buf_length,delay_lm);
  1172.     canon_advance_buffer(lyellow, buf_length,delay_ly);
  1173.  
  1174.     errval += errmod;
  1175.     errline += errdiv;
  1176.     if (errval >= out_height)
  1177.     {
  1178.       errval -= out_height;
  1179.       errline ++;
  1180.     }
  1181.   }
  1182.   Image_progress_conclude(image);
  1183.  
  1184.   free_dither(dither);
  1185.  
  1186.   /*
  1187.    * Flush delayed buffers...
  1188.    */
  1189.  
  1190.   if (delay_max) {
  1191. #ifdef DEBUG
  1192.     fprintf(stderr,"\ncanon: flushing %d possibly delayed buffers\n",
  1193.         delay_max);
  1194. #endif
  1195.     for (y= 0; y<delay_max; y++) {
  1196.  
  1197.       canon_write_line(prn, caps, ydpi,
  1198.                black,    delay_k,
  1199.                cyan,     delay_c,
  1200.                magenta,  delay_m,
  1201.                yellow,   delay_y,
  1202.                lcyan,    delay_lc,
  1203.                lmagenta, delay_lm,
  1204.                lyellow,  delay_ly,
  1205.                length, out_width, left, use_dmt);
  1206.  
  1207. #ifdef DEBUG
  1208.       /* fprintf(stderr,"-"); */
  1209. #endif
  1210.  
  1211.       canon_advance_buffer(black,   buf_length,delay_k);
  1212.       canon_advance_buffer(cyan,    buf_length,delay_c);
  1213.       canon_advance_buffer(magenta, buf_length,delay_m);
  1214.       canon_advance_buffer(yellow,  buf_length,delay_y);
  1215.       canon_advance_buffer(lcyan,   buf_length,delay_lc);
  1216.       canon_advance_buffer(lmagenta,buf_length,delay_lm);
  1217.       canon_advance_buffer(lyellow, buf_length,delay_ly);
  1218.     }
  1219.   }
  1220.  
  1221.  /*
  1222.   * Cleanup...
  1223.   */
  1224.  
  1225.   free_lut(&nv);
  1226.   free(in);
  1227.   free(out);
  1228.  
  1229.   if (black != NULL)    free(black);
  1230.   if (cyan != NULL)     free(cyan);
  1231.   if (magenta != NULL)  free(magenta);
  1232.   if (yellow != NULL)   free(yellow);
  1233.   if (lcyan != NULL)    free(lcyan);
  1234.   if (lmagenta != NULL) free(lmagenta);
  1235.   if (lyellow != NULL)  free(lyellow);
  1236.  
  1237.   canon_deinit_printer(prn, caps);
  1238. }
  1239.  
  1240. /*
  1241.  * 'canon_fold_lsb_msb()' fold 2 lines in order lsb/msb
  1242.  */
  1243.  
  1244. static void
  1245. canon_fold_lsb_msb(const unsigned char *line,
  1246.            int single_length,
  1247.            unsigned char *outbuf)
  1248. {
  1249.   int i;
  1250.   for (i = 0; i < single_length; i++) {
  1251.     outbuf[0] =
  1252.       ((line[0] & (1 << 7)) >> 1) |
  1253.       ((line[0] & (1 << 6)) >> 2) |
  1254.       ((line[0] & (1 << 5)) >> 3) |
  1255.       ((line[0] & (1 << 4)) >> 4) |
  1256.       ((line[single_length] & (1 << 7)) >> 0) |
  1257.       ((line[single_length] & (1 << 6)) >> 1) |
  1258.       ((line[single_length] & (1 << 5)) >> 2) |
  1259.       ((line[single_length] & (1 << 4)) >> 3);
  1260.     outbuf[1] =
  1261.       ((line[0] & (1 << 3)) << 3) |
  1262.       ((line[0] & (1 << 2)) << 2) |
  1263.       ((line[0] & (1 << 1)) << 1) |
  1264.       ((line[0] & (1 << 0)) << 0) |
  1265.       ((line[single_length] & (1 << 3)) << 4) |
  1266.       ((line[single_length] & (1 << 2)) << 3) |
  1267.       ((line[single_length] & (1 << 1)) << 2) |
  1268.       ((line[single_length] & (1 << 0)) << 1);
  1269.     line++;
  1270.     outbuf += 2;
  1271.   }
  1272. }
  1273.  
  1274. /*
  1275.  * 'canon_fold_msb_lsb()' fold 2 lines in order msb/lsb
  1276.  */
  1277.  
  1278. static void
  1279. canon_fold_msb_lsb(const unsigned char *line,
  1280.            int single_length,
  1281.            unsigned char *outbuf)
  1282. {
  1283.   int i;
  1284.   for (i = 0; i < single_length; i++) {
  1285.     outbuf[0] =
  1286.       ((line[0] & (1 << 7)) >> 0) |
  1287.       ((line[0] & (1 << 6)) >> 1) |
  1288.       ((line[0] & (1 << 5)) >> 2) |
  1289.       ((line[0] & (1 << 4)) >> 3) |
  1290.       ((line[single_length] & (1 << 7)) >> 1) |
  1291.       ((line[single_length] & (1 << 6)) >> 2) |
  1292.       ((line[single_length] & (1 << 5)) >> 3) |
  1293.       ((line[single_length] & (1 << 4)) >> 4);
  1294.     outbuf[1] =
  1295.       ((line[0] & (1 << 3)) << 4) |
  1296.       ((line[0] & (1 << 2)) << 3) |
  1297.       ((line[0] & (1 << 1)) << 2) |
  1298.       ((line[0] & (1 << 0)) << 1) |
  1299.       ((line[single_length] & (1 << 3)) << 3) |
  1300.       ((line[single_length] & (1 << 2)) << 2) |
  1301.       ((line[single_length] & (1 << 1)) << 1) |
  1302.       ((line[single_length] & (1 << 0)) << 0);
  1303.     line++;
  1304.     outbuf += 2;
  1305.   }
  1306. }
  1307.  
  1308. static void
  1309. canon_pack(unsigned char *line,
  1310.        int length,
  1311.        unsigned char *comp_buf,
  1312.        unsigned char **comp_ptr)
  1313. {
  1314.   unsigned char *start;            /* Start of compressed data */
  1315.   unsigned char repeat;            /* Repeating char */
  1316.   int count;            /* Count of compressed bytes */
  1317.   int tcount;            /* Temporary count < 128 */
  1318.  
  1319.   /*
  1320.    * Compress using TIFF "packbits" run-length encoding...
  1321.    */
  1322.  
  1323.   (*comp_ptr) = comp_buf;
  1324.  
  1325.   while (length > 0)
  1326.     {
  1327.       /*
  1328.        * Get a run of non-repeated chars...
  1329.        */
  1330.  
  1331.       start  = line;
  1332.       line   += 2;
  1333.       length -= 2;
  1334.  
  1335.       while (length > 0 && (line[-2] != line[-1] || line[-1] != line[0]))
  1336.     {
  1337.       line ++;
  1338.       length --;
  1339.     }
  1340.  
  1341.       line   -= 2;
  1342.       length += 2;
  1343.  
  1344.       /*
  1345.        * Output the non-repeated sequences (max 128 at a time).
  1346.        */
  1347.  
  1348.       count = line - start;
  1349.       while (count > 0)
  1350.     {
  1351.       tcount = count > 128 ? 128 : count;
  1352.  
  1353.       (*comp_ptr)[0] = tcount - 1;
  1354.       memcpy((*comp_ptr) + 1, start, tcount);
  1355.  
  1356.       (*comp_ptr) += tcount + 1;
  1357.       start    += tcount;
  1358.       count    -= tcount;
  1359.     }
  1360.  
  1361.       if (length <= 0)
  1362.     break;
  1363.  
  1364.       /*
  1365.        * Find the repeated sequences...
  1366.        */
  1367.  
  1368.       start  = line;
  1369.       repeat = line[0];
  1370.  
  1371.       line ++;
  1372.       length --;
  1373.  
  1374.       while (length > 0 && *line == repeat)
  1375.     {
  1376.       line ++;
  1377.       length --;
  1378.     }
  1379.  
  1380.       /*
  1381.        * Output the repeated sequences (max 128 at a time).
  1382.        */
  1383.  
  1384.       count = line - start;
  1385.       while (count > 0)
  1386.     {
  1387.       tcount = count > 128 ? 128 : count;
  1388.  
  1389.       (*comp_ptr)[0] = 1 - tcount;
  1390.       (*comp_ptr)[1] = repeat;
  1391.  
  1392.       (*comp_ptr) += 2;
  1393.       count    -= tcount;
  1394.     }
  1395.     }
  1396. }
  1397.  
  1398.  
  1399. /*
  1400.  * 'canon_write()' - Send graphics using TIFF packbits compression.
  1401.  */
  1402.  
  1403. static int
  1404. canon_write(FILE          *prn,        /* I - Print file or command */
  1405.         canon_cap_t   caps,            /* I - Printer model */
  1406.         unsigned char *line,    /* I - Output bitmap data */
  1407.         int           length,    /* I - Length of bitmap data */
  1408.         int           coloridx,    /* I - Which color */
  1409.         int           ydpi,        /* I - Vertical resolution */
  1410.         int           *empty,       /* IO- Preceeding empty lines */
  1411.         int           width,    /* I - Printed width */
  1412.         int           offset,     /* I - Offset from left side */
  1413.         int           dmt)
  1414. {
  1415.   unsigned char
  1416.     comp_buf[COMPBUFWIDTH],        /* Compression buffer */
  1417.     in_fold[COMPBUFWIDTH],
  1418.     *in_ptr= line,
  1419.     *comp_ptr, *comp_data;
  1420.   int newlength;
  1421.   unsigned char color;
  1422.  
  1423.  /* Don't send blank lines... */
  1424.  
  1425.   if (line[0] == 0 && memcmp(line, line + 1, length - 1) == 0)
  1426.     return 0;
  1427.  
  1428.   /* fold lsb/msb pairs if drop modulation is active */
  1429.  
  1430.   if (dmt) {
  1431.     if (1) {
  1432.       if (caps.features & CANON_CAP_MSB_FIRST)
  1433.     canon_fold_msb_lsb(line,length,in_fold);
  1434.       else
  1435.     canon_fold_lsb_msb(line,length,in_fold);
  1436.       in_ptr= in_fold;
  1437.     }
  1438.     length*= 2;
  1439.     offset*= 2;
  1440.   }
  1441.  
  1442.   /* pack left border rounded to multiples of 8 dots */
  1443.  
  1444.   comp_data= comp_buf;
  1445.   if (offset) {
  1446.     int offset2= (offset+4)/8;
  1447.     while (offset2>0) {
  1448.       unsigned char toffset = offset2 > 128 ? 128 : offset2;
  1449.       comp_data[0] = 1 - toffset;
  1450.       comp_data[1] = 0;
  1451.       comp_data += 2;
  1452.       offset2-= toffset;
  1453.     }
  1454.   }
  1455.  
  1456.   canon_pack(in_ptr, length, comp_data, &comp_ptr);
  1457.   newlength= comp_ptr - comp_buf;
  1458.  
  1459.   /* send packed empty lines if any */
  1460.  
  1461.   if (*empty) {
  1462. #ifdef DEBUG
  1463.     /* fprintf(stderr,"<%d%c>",*empty,("CMYKcmy"[coloridx])); */
  1464. #endif
  1465.     fwrite("\x1b\x28\x65\x02\x00", 5, 1, prn);
  1466.     fputc((*empty) >> 8 , prn);
  1467.     fputc((*empty) & 255, prn);
  1468.     *empty= 0;
  1469.   }
  1470.  
  1471.  /* Send a line of raster graphics... */
  1472.  
  1473.   fwrite("\x1b\x28\x41", 3, 1, prn);
  1474.   putc((newlength+1) & 255, prn);
  1475.   putc((newlength+1) >> 8, prn);
  1476.   color= "CMYKcmy"[coloridx];
  1477.   if (!color) color= 'K';
  1478.   putc(color,prn);
  1479.   fwrite(comp_buf, newlength, 1, prn);
  1480.   putc('\x0d', prn);
  1481.   return 1;
  1482. }
  1483.  
  1484.  
  1485. static void
  1486. canon_write_line(FILE          *prn,    /* I - Print file or command */
  1487.          canon_cap_t   caps,    /* I - Printer model */
  1488.          int           ydpi,    /* I - Vertical resolution */
  1489.          unsigned char *k,    /* I - Output bitmap data */
  1490.          int           dk,    /* I -  */
  1491.          unsigned char *c,    /* I - Output bitmap data */
  1492.          int           dc,    /* I -  */
  1493.          unsigned char *m,    /* I - Output bitmap data */
  1494.          int           dm,    /* I -  */
  1495.          unsigned char *y,    /* I - Output bitmap data */
  1496.          int           dy,    /* I -  */
  1497.          unsigned char *lc,    /* I - Output bitmap data */
  1498.          int           dlc,    /* I -  */
  1499.          unsigned char *lm,    /* I - Output bitmap data */
  1500.          int           dlm,    /* I -  */
  1501.          unsigned char *ly,    /* I - Output bitmap data */
  1502.          int           dly,    /* I -  */
  1503.          int           l,    /* I - Length of bitmap data */
  1504.          int           width,    /* I - Printed width */
  1505.          int           offset,  /* I - horizontal offset */
  1506.          int           dmt)
  1507. {
  1508.   static int empty= 0;
  1509.   int written= 0;
  1510.  
  1511.   if (k) written+=
  1512.     canon_write(prn, caps, k+ dk*l,  l, 3, ydpi, &empty, width, offset, dmt);
  1513.   if (y) written+=
  1514.     canon_write(prn, caps, y+ dy*l,  l, 2, ydpi, &empty, width, offset, dmt);
  1515.   if (m) written+=
  1516.     canon_write(prn, caps, m+ dm*l,  l, 1, ydpi, &empty, width, offset, dmt);
  1517.   if (c) written+=
  1518.     canon_write(prn, caps, c+ dc*l,  l, 0, ydpi, &empty, width, offset, dmt);
  1519.   if (ly) written+=
  1520.     canon_write(prn, caps, ly+dly*l, l, 6, ydpi, &empty, width, offset, dmt);
  1521.   if (lm) written+=
  1522.     canon_write(prn, caps, lm+dlm*l, l, 5, ydpi, &empty, width, offset, dmt);
  1523.   if (lc) written+=
  1524.     canon_write(prn, caps, lc+dlc*l, l, 4, ydpi, &empty, width, offset, dmt);
  1525.  
  1526.   if (written)
  1527.     fwrite("\x1b\x28\x65\x02\x00\x00\x01", 7, 1, prn);
  1528.   else
  1529.     empty++;
  1530. }
  1531.