1/* SANE - Scanner Access Now Easy.
2
3   Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4   Copyright (C) 2007-2008 Nicolas Martin, <nicols-guest at alioth dot debian dot org>
5   Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
6
7   This file is part of the SANE package.
8
9   This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License as
11   published by the Free Software Foundation; either version 2 of the
12   License, or (at your option) 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
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
22   As a special exception, the authors of SANE give permission for
23   additional uses of the libraries contained in this release of SANE.
24
25   The exception is that, if you link a SANE library with other files
26   to produce an executable, this does not by itself cause the
27   resulting executable to be covered by the GNU General Public
28   License.  Your use of that executable is in no way restricted on
29   account of linking the SANE library code into it.
30
31   This exception does not, however, invalidate any other reasons why
32   the executable file might be covered by the GNU General Public
33   License.
34
35   If you submit changes to SANE to the maintainers to be included in
36   a subsequent release, you agree by submitting the changes that
37   those changes may be distributed with this exception intact.
38
39   If you write modifications of your own for SANE, it is your choice
40   whether to permit this exception to apply to your modifications.
41   If you do not wish that, delete this exception notice.
42 */
43#include "../include/sane/config.h"
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <stdarg.h>
49#include <ctype.h>
50#include <math.h>		/* pow(C90) */
51
52#include <sys/time.h>		/* gettimeofday(4.3BSD) */
53#include <unistd.h>		/* usleep */
54
55#if defined(HAVE_LIBXML2)
56# include <libxml/parser.h>
57#endif
58
59#include "pixma_rename.h"
60#include "pixma_common.h"
61#include "pixma_io.h"
62
63#include "../include/sane/sanei_usb.h"
64#include "../include/sane/sane.h"
65
66#ifdef __GNUC__
67# define UNUSED(v) (void) v
68#else
69# define UNUSED(v)
70#endif
71
72extern const pixma_config_t pixma_mp150_devices[];
73extern const pixma_config_t pixma_mp750_devices[];
74extern const pixma_config_t pixma_mp730_devices[];
75extern const pixma_config_t pixma_mp800_devices[];
76extern const pixma_config_t pixma_iclass_devices[];
77
78static const pixma_config_t *const pixma_devices[] = {
79  pixma_mp150_devices,
80  pixma_mp750_devices,
81  pixma_mp730_devices,
82  pixma_mp800_devices,
83  pixma_iclass_devices,
84  NULL
85};
86
87static pixma_t *first_pixma = NULL;
88static time_t tstart_sec = 0;
89static uint32_t tstart_usec = 0;
90static int debug_level = 1;
91
92
93#ifndef NDEBUG
94
95static void
96u8tohex (uint8_t x, char *str)
97{
98  static const char hdigit[16] =
99    { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
100    'e', 'f'
101    };
102  str[0] = hdigit[(x >> 4) & 0xf];
103  str[1] = hdigit[x & 0xf];
104  str[2] = '\0';
105}
106
107static void
108u32tohex (uint32_t x, char *str)
109{
110  u8tohex (x >> 24, str);
111  u8tohex (x >> 16, str + 2);
112  u8tohex (x >> 8, str + 4);
113  u8tohex (x, str + 6);
114}
115
116void
117pixma_hexdump (int level, const void *d_, unsigned len)
118{
119  const uint8_t *d = (const uint8_t *) (d_);
120  unsigned ofs, c, plen;
121  char line[100];		/* actually only 1+8+1+8*3+1+8*3+1 = 61 bytes needed */
122
123  if (level > debug_level)
124    return;
125  if (level == debug_level)
126    /* if debuglevel == exact match and buffer contains more than 3 lines, print 2 lines + .... */
127    plen = (len > 64) ? 32: len;
128  else
129    plen = len;
130  ofs = 0;
131  while (ofs < plen)
132    {
133      char *p;
134      line[0] = ' ';
135      u32tohex (ofs, line + 1);
136      line[9] = ':';
137      p = line + 10;
138      for (c = 0; c != 16 && (ofs + c) < plen; c++)
139        {
140          u8tohex (d[ofs + c], p);
141          p[2] = ' ';
142          p += 3;
143          if (c == 7)
144            {
145              p[0] = ' ';
146              p++;
147            }
148        }
149      for (c = 0; c < 4; c++)
150        {
151          p[0] = ' ';
152          p++;
153        }
154      for (c = 0; c != 16 && (ofs + c) < plen; c++)
155        {
156          if (isprint(d[ofs + c]))
157            p[0] = d[ofs + c];
158          else
159            p[0] = '.';
160          p++;
161          if (c == 7)
162            {
163              p[0] = ' ';
164              p++;
165            }
166        }
167      p[0] = '\0';
168      pixma_dbg (level, "%s\n", line);
169      ofs += c;
170    }
171  if (len > plen)
172    pixma_dbg(level, "......\n");
173}
174
175static void
176time2str (char *buf, unsigned size)
177{
178  time_t sec;
179  uint32_t usec;
180
181  pixma_get_time (&sec, &usec);
182  sec -= tstart_sec;
183  if (usec >= tstart_usec)
184    {
185      usec -= tstart_usec;
186    }
187  else
188    {
189      usec = 1000000 + usec - tstart_usec;
190      sec--;
191    }
192  snprintf (buf, size, "%lu.%03u", (unsigned long) sec,
193	    (unsigned) (usec / 1000));
194}
195
196void
197pixma_dump (int level, const char *type, const void *data, int len,
198	    int size, int max)
199{
200  int actual_len, print_len;
201  char buf[20];
202
203  if (level > debug_level)
204    return;
205  if (debug_level >= 20)
206    max = -1;			/* dump every bytes */
207
208  time2str (buf, sizeof (buf));
209  pixma_dbg (level, "%s T=%s len=%d\n", type, buf, len);
210
211  actual_len = (size >= 0) ? size : len;
212  print_len = (max >= 0 && max < actual_len) ? max : actual_len;
213  if (print_len >= 0)
214    {
215      pixma_hexdump (level, data, print_len);
216      if (print_len < actual_len)
217	pixma_dbg (level, " ...\n");
218    }
219  if (len < 0)
220    pixma_dbg (level, "  ERROR: %s\n", pixma_strerror (len));
221  pixma_dbg (level, "\n");
222}
223
224
225#endif /* NDEBUG */
226
227/* NOTE: non-reentrant */
228const char *
229pixma_strerror (int error)
230{
231  static char buf[50];
232
233  /* TODO: more human friendly messages */
234  switch (error)
235    {
236    case PIXMA_EIO:
237      return "EIO";
238    case PIXMA_ENODEV:
239      return "ENODEV";
240    case PIXMA_EACCES:
241      return "EACCES";
242    case PIXMA_ENOMEM:
243      return "ENOMEM";
244    case PIXMA_EINVAL:
245      return "EINVAL";
246    case PIXMA_EBUSY:
247      return "EBUSY";
248    case PIXMA_ECANCELED:
249      return "ECANCELED";
250    case PIXMA_ENOTSUP:
251      return "ENOTSUP";
252    case PIXMA_ETIMEDOUT:
253      return "ETIMEDOUT";
254    case PIXMA_EPROTO:
255      return "EPROTO";
256    case PIXMA_EPAPER_JAMMED:
257      return "EPAPER_JAMMED";
258    case PIXMA_ECOVER_OPEN:
259      return "ECOVER_OPEN";
260    case PIXMA_ENO_PAPER:
261      return "ENO_PAPER";
262    case PIXMA_EOF:
263      return "EEOF";
264    }
265  snprintf (buf, sizeof (buf), "EUNKNOWN:%d", error);
266  return buf;
267}
268
269void
270pixma_set_debug_level (int level)
271{
272  debug_level = level;
273}
274
275void
276pixma_set_be16 (uint16_t x, uint8_t * buf)
277{
278  buf[0] = x >> 8;
279  buf[1] = x;
280}
281
282void
283pixma_set_be32 (uint32_t x, uint8_t * buf)
284{
285  buf[0] = x >> 24;
286  buf[1] = x >> 16;
287  buf[2] = x >> 8;
288  buf[3] = x;
289}
290
291uint16_t
292pixma_get_be16 (const uint8_t * buf)
293{
294  return ((uint16_t) buf[0] << 8) | buf[1];
295}
296
297uint32_t
298pixma_get_be32 (const uint8_t * buf)
299{
300  return ((uint32_t) buf[0] << 24) + ((uint32_t) buf[1] << 16) +
301    ((uint32_t) buf[2] << 8) + buf[3];
302}
303
304uint8_t
305pixma_sum_bytes (const void *data, unsigned len)
306{
307  const uint8_t *d = (const uint8_t *) data;
308  unsigned i, sum = 0;
309  for (i = 0; i != len; i++)
310    sum += d[i];
311  return sum;
312}
313
314void
315pixma_sleep (unsigned long usec)
316{
317  usleep (usec);
318}
319
320void
321pixma_get_time (time_t * sec, uint32_t * usec)
322{
323  struct timeval tv;
324  gettimeofday (&tv, NULL);
325  if (sec)
326    *sec = tv.tv_sec;
327  if (usec)
328    *usec = tv.tv_usec;
329}
330
331/* convert 24/48 bit RGB to 8/16 bit ir
332 *
333 * Formular: g = R
334 *           drop G + B
335 *
336 * sptr: source color scale buffer
337 * gptr: destination gray scale buffer
338 * c == 3: 24 bit RGB -> 8 bit ir
339 * c == 6: 48 bit RGB -> 16 bit ir
340 */
341uint8_t *
342pixma_r_to_ir (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)
343{
344  unsigned i;
345
346  /* PDBG (pixma_dbg (4, "*pixma_rgb_to_ir*****\n")); */
347
348  for (i = 0; i < w; i++)
349    {
350      *gptr++ = *sptr++;
351      if (c == 6) *gptr++ = *sptr++;            /* 48 bit RGB: high byte */
352      sptr += (c == 6) ? 4 : 2;                 /* drop G + B */
353    }
354  return gptr;
355}
356
357/* convert 24/48 bit RGB to 8/16 bit grayscale
358 *
359 * Formular: Y' = 0,2126 R' + 0,7152 G' + 0,0722 B'
360 *
361 * sptr: source color scale buffer
362 * gptr: destination gray scale buffer
363 * c == 3: 24 bit RGB -> 8 bit gray
364 * c == 6: 48 bit RGB -> 16 bit gray
365 */
366uint8_t *
367pixma_rgb_to_gray (uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)
368{
369  unsigned i, g;
370
371  /* PDBG (pixma_dbg (4, "*pixma_rgb_to_gray*****\n")); */
372
373  for (i = 0; i < w; i++)
374    {
375      if (c == 6)
376        { /* 48 bit RGB */
377          unsigned r = sptr[0] + (sptr[1] << 8);
378          unsigned y = sptr[2] + (sptr[3] << 8);
379          unsigned b = sptr[4] + (sptr[5] << 8);
380
381          g = (r * 2126) + (y * 7152) + (b * 722);
382          sptr += 6;
383        }
384      else
385        { /* 24 bit RGB */
386          g = (sptr[0] * 2126) + (sptr[1] * 7152) + (sptr[2] * 722);
387          sptr += 3;
388        }
389      g /= 10000;                               /* 8 and 16 bit gray */
390
391      *gptr++ = g;
392      if (c == 6) *gptr++ = (g >> 8);           /* 16 bit gray: high byte */
393    }
394  return gptr;
395}
396
397/**
398 * This code was taken from the genesys backend
399 * uses threshold and threshold_curve to control software binarization
400 * @param sp    device set up for the scan
401 * @param dst   pointer where to store result
402 * @param src   pointer to raw data
403 * @param width width of the processed line
404 * @param c     1 for 1-channel single-byte data,
405 *              3 for 3-channel single-byte data,
406 *              6 for double-byte data
407 * */
408uint8_t *
409pixma_binarize_line(pixma_scan_param_t * sp, uint8_t * dst, uint8_t * src, unsigned width, unsigned c)
410{
411  unsigned j, x, windowX, sum = 0;
412  unsigned threshold;
413  unsigned offset, addCol;
414  int dropCol, offsetX;
415  unsigned char mask;
416  uint8_t min, max;
417
418  /* PDBG (pixma_dbg (4, "*pixma_binarize_line***** src = %u, dst = %u, width = %u, c = %u, threshold = %u, threshold_curve = %u *****\n",
419                      src, dst, width, c, sp->threshold, sp->threshold_curve)); */
420
421  /* 16 bit grayscale not supported */
422  if (c == 6)
423    {
424      PDBG (pixma_dbg (1, "*pixma_binarize_line***** Error: 16 bit grayscale not supported\n"));
425      return dst;
426    }
427
428  /* first, color convert to grayscale */
429    if (c != 1)
430      pixma_rgb_to_gray(dst, src, width, c);
431
432  /* second, normalize line */
433    min = 255;
434    max = 0;
435    for (x = 0; x < width; x++)
436      {
437        if (src[x] > max)
438          {
439            max = src[x];
440          }
441        if (src[x] < min)
442          {
443            min = src[x];
444          }
445      }
446
447    /* safeguard against dark or white areas */
448    if(min>80)
449        min=0;
450    if(max<80)
451        max=255;
452    for (x = 0; x < width; x++)
453      {
454        src[x] = ((src[x] - min) * 255) / (max - min);
455      }
456
457  /* third, create sliding window, prefill the sliding sum */
458    /* ~1mm works best, but the window needs to have odd # of pixels */
459    windowX = (6 * sp->xdpi) / 150;
460    if (!(windowX % 2))
461      windowX++;
462
463    /* to avoid conflicts with *dst start with offset */
464    offsetX = 1 + (windowX / 2) / 8;
465    for (j = offsetX; j <= windowX; j++)
466      sum += src[j];
467    /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** windowX = %u, startX = %u, sum = %u\n",
468                     windowX, startX, sum)); */
469
470  /* fourth, walk the input buffer, output bits */
471    for (j = 0; j < width; j++)
472      {
473        /* output image location */
474        offset = j % 8;
475        mask = 0x80 >> offset;
476        threshold = sp->threshold;
477
478        /* move sum/update threshold only if there is a curve */
479        if (sp->threshold_curve)
480          {
481            addCol = j + windowX / 2;
482            dropCol = addCol - windowX;
483
484            if (dropCol >= offsetX && addCol < width)
485              {
486                sum += src[addCol];
487                sum -= (sum < src[dropCol] ? sum : src[dropCol]);       /* no negative sum */
488              }
489            threshold = sp->lineart_lut[sum / windowX];
490            /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** addCol = %u, dropCol = %d, sum = %u, windowX = %u, lut-element = %d, threshold = %u\n",
491                             addCol, dropCol, sum, windowX, sum/windowX, threshold)); */
492          }
493
494        /* lookup threshold */
495        if (src[j] > threshold)
496            *dst &= ~mask;      /* white */
497        else
498            *dst |= mask;       /* black */
499
500        if (offset == 7)
501            dst++;
502      }
503
504  /* PDBG (pixma_dbg (4, " *pixma_binarize_line***** ready: src = %u, dst = %u *****\n", src, dst)); */
505
506  return dst;
507}
508
509/**
510   This code was taken from the genesys backend
511   Function to build a lookup table (LUT), often
512   used by scanners to implement brightness/contrast/gamma
513   or by backends to speed binarization/thresholding
514
515   offset and slope inputs are -127 to +127
516
517   slope rotates line around central input/output val,
518   0 makes horizontal line
519
520       pos           zero          neg
521       .       x     .             .  x
522       .      x      .             .   x
523   out .     x       .xxxxxxxxxxx  .    x
524       .    x        .             .     x
525       ....x.......  ............  .......x....
526            in            in            in
527
528   offset moves line vertically, and clamps to output range
529   0 keeps the line crossing the center of the table
530
531       high           low
532       .   xxxxxxxx   .
533       . x            .
534   out x              .          x
535       .              .        x
536       ............   xxxxxxxx....
537            in             in
538
539   out_min/max provide bounds on output values,
540   useful when building thresholding lut.
541   0 and 255 are good defaults otherwise.
542  * */
543static SANE_Status
544load_lut (unsigned char * lut,
545  int in_bits, int out_bits,
546  int out_min, int out_max,
547  int slope, int offset)
548{
549  int i, j;
550  double shift, rise;
551  int max_in_val = (1 << in_bits) - 1;
552  int max_out_val = (1 << out_bits) - 1;
553  unsigned char * lut_p = lut;
554
555  /* PDBG (pixma_dbg (4, "*load_lut***** start %d %d *****\n", slope, offset)); */
556
557  /* slope is converted to rise per unit run:
558   * first [-127,127] to [-1,1]
559   * then multiply by PI/2 to convert to radians
560   * then take the tangent (T.O.A)
561   * then multiply by the normal linear slope
562   * because the table may not be square, i.e. 1024x256*/
563  rise = tan((double)slope/127 * M_PI/2) * max_out_val / max_in_val;
564
565  /* line must stay vertically centered, so figure
566   * out vertical offset at central input value */
567  shift = (double)max_out_val/2 - (rise*max_in_val/2);
568
569  /* convert the user offset setting to scale of output
570   * first [-127,127] to [-1,1]
571   * then to [-max_out_val/2,max_out_val/2]*/
572  shift += (double)offset / 127 * max_out_val / 2;
573
574  for(i=0;i<=max_in_val;i++){
575    j = rise*i + shift;
576
577    if(j<out_min){
578      j=out_min;
579    }
580    else if(j>out_max){
581      j=out_max;
582    }
583
584    *lut_p=j;
585    lut_p++;
586  }
587
588  /* PDBG (pixma_dbg (4, "*load_lut***** finish *****\n")); */
589  /* PDBG (pixma_hexdump (4, lut, max_in_val+1)); */
590
591  return SANE_STATUS_GOOD;
592}
593
594int
595pixma_map_status_errno (unsigned status)
596{
597  switch (status)
598    {
599    case PIXMA_STATUS_OK:
600      return 0;
601    case PIXMA_STATUS_FAILED:
602      return PIXMA_ECANCELED;
603    case PIXMA_STATUS_BUSY:
604      return PIXMA_EBUSY;
605    default:
606      return PIXMA_EPROTO;
607    }
608}
609
610int
611pixma_check_result (pixma_cmdbuf_t * cb)
612{
613  const uint8_t *r = cb->buf;
614  unsigned header_len = cb->res_header_len;
615  unsigned expected_reslen = cb->expected_reslen;
616  int error;
617  unsigned len;
618
619  if (cb->reslen < 0)
620    return cb->reslen;
621
622  len = (unsigned) cb->reslen;
623  if (len >= header_len)
624    {
625      error = pixma_map_status_errno (pixma_get_be16 (r));
626      if (expected_reslen != 0)
627        {
628          if (len == expected_reslen)
629            {
630              if (pixma_sum_bytes (r + header_len, len - header_len) != 0)
631                 error = PIXMA_EPROTO;
632            }
633          else
634            {
635              /* This case will happen when a command cannot be completely
636                 executed, e.g. because you press the cancel button. The
637                 device will return only a header with PIXMA_STATUS_FAILED. */
638              if (len != header_len)
639                 error = PIXMA_EPROTO;
640            }
641        }
642    }
643  else
644    error = PIXMA_EPROTO;
645
646#ifndef NDEBUG
647  if (error == PIXMA_EPROTO)
648    {
649      pixma_dbg (1, "WARNING: result len=%d expected %d\n",
650		 len, cb->expected_reslen);
651      pixma_hexdump (1, r, MIN (len, 64));
652    }
653#endif
654  return error;
655}
656
657int
658pixma_cmd_transaction (pixma_t * s, const void *cmd, unsigned cmdlen,
659		       void *data, unsigned expected_len)
660{
661  int error, tmo;
662
663  error = pixma_write (s->io, cmd, cmdlen);
664  if (error != (int) cmdlen)
665    {
666      if (error >= 0)
667        {
668          /* Write timeout is too low? */
669          PDBG (pixma_dbg
670          (1, "ERROR: incomplete write, %u out of %u written\n",
671           (unsigned) error, cmdlen));
672          error = PIXMA_ETIMEDOUT;
673        }
674      return error;
675    }
676
677  /* When you send the start_session command while the scanner optic is
678     going back to the home position after the last scan session has been
679     cancelled, you won't get the response before it arrives home. This takes
680     about 5 seconds. If the last session was succeeded, the scanner will
681     immediately answer with PIXMA_STATUS_BUSY.
682
683     Is 8 seconds timeout enough? This affects ALL commands that use
684     pixma_cmd_transaction(). Default value set in pixma_open(). */
685  tmo = s->rec_tmo;
686  do
687    {
688      error = pixma_read (s->io, data, expected_len);
689      if (error == PIXMA_ETIMEDOUT)
690      {
691        PDBG (pixma_dbg (2, "No response yet. Timed out in %d sec.\n", tmo));
692
693#ifndef HAVE_SANEI_USB_SET_TIMEOUT
694        /* 1s timeout
695           Only needed, if sanei_usb_set_timeout() isn't available.
696           pixma_read() has an internal timeout of 1 sec. */
697        pixma_sleep (1000000);
698#endif
699      }
700    }
701  while (error == PIXMA_ETIMEDOUT && --tmo != 0);
702  if (error < 0)
703    {
704      PDBG (pixma_dbg (1, "WARNING: Error in response phase. cmd:%02x%02x\n",
705		       ((const uint8_t *) cmd)[0],
706		       ((const uint8_t *) cmd)[1]));
707      PDBG (pixma_dbg (1,"  If the scanner hangs, reset it and/or unplug the "
708	                       "USB cable.\n"));
709    }
710  return error;			/* length of the result packet or error */
711}
712
713uint8_t *
714pixma_newcmd (pixma_cmdbuf_t * cb, unsigned cmd,
715	      unsigned dataout, unsigned datain)
716{
717  unsigned cmdlen = cb->cmd_header_len + dataout;
718  unsigned reslen = cb->res_header_len + datain;
719
720  if (cmdlen > cb->size || reslen > cb->size)
721    return NULL;
722  memset (cb->buf, 0, cmdlen);
723  cb->cmdlen = cmdlen;
724  cb->expected_reslen = reslen;
725  pixma_set_be16 (cmd, cb->buf);
726  pixma_set_be16 (dataout + datain, cb->buf + cb->cmd_len_field_ofs);
727  if (dataout != 0)
728    return cb->buf + cb->cmd_header_len;
729  else
730    return cb->buf + cb->res_header_len;
731}
732
733int
734pixma_exec (pixma_t * s, pixma_cmdbuf_t * cb)
735{
736  if (cb->cmdlen > cb->cmd_header_len)
737    pixma_fill_checksum (cb->buf + cb->cmd_header_len,
738			 cb->buf + cb->cmdlen - 1);
739  cb->reslen =
740    pixma_cmd_transaction (s, cb->buf, cb->cmdlen, cb->buf,
741			   cb->expected_reslen);
742  return pixma_check_result (cb);
743}
744
745int
746pixma_exec_short_cmd (pixma_t * s, pixma_cmdbuf_t * cb, unsigned cmd)
747{
748  pixma_newcmd (cb, cmd, 0, 0);
749  return pixma_exec (s, cb);
750}
751
752int
753pixma_check_dpi (unsigned dpi, unsigned max)
754{
755  /* valid dpi = 75 * 2^n */
756  unsigned temp = dpi / 75;
757  if (dpi > max || dpi < 75 || 75 * temp != dpi || (temp & (temp - 1)) != 0)
758    return PIXMA_EINVAL;
759  return 0;
760}
761
762
763int
764pixma_init (void)
765{
766  PDBG (pixma_dbg (2, "pixma version %d.%d.%d\n", PIXMA_VERSION_MAJOR,
767		   PIXMA_VERSION_MINOR, PIXMA_VERSION_BUILD));
768  PASSERT (first_pixma == NULL);
769  if (tstart_sec == 0)
770    pixma_get_time (&tstart_sec, &tstart_usec);
771  return pixma_io_init ();
772}
773
774void
775pixma_cleanup (void)
776{
777  while (first_pixma)
778    pixma_close (first_pixma);
779  pixma_io_cleanup ();
780}
781
782int
783pixma_open (unsigned devnr, pixma_t ** handle)
784{
785  int error;
786  pixma_t *s;
787  const pixma_config_t *cfg;
788
789  *handle = NULL;
790  cfg = pixma_get_device_config (devnr);
791  if (!cfg)
792    return PIXMA_EINVAL;	/* invalid devnr */
793  PDBG (pixma_dbg (2, "pixma_open(): %s\n", cfg->name));
794
795  s = (pixma_t *) calloc (1, sizeof (s[0]));
796  if (!s)
797    return PIXMA_ENOMEM;
798  s->next = first_pixma;
799  first_pixma = s;
800
801  s->cfg = cfg;
802  s->rec_tmo = 8;               /* set receive timeout to 8 seconds */
803  error = pixma_connect (devnr, &s->io);
804  if (error < 0)
805    {
806      PDBG (pixma_dbg
807	    (2, "pixma_connect() failed %s\n", pixma_strerror (error)));
808      goto rollback;
809    }
810  strncpy (s->id, pixma_get_device_id (devnr), sizeof (s->id) - 1);
811  s->ops = s->cfg->ops;
812  s->scanning = 0;
813  s->last_source = PIXMA_SOURCE_NONE;
814  error = s->ops->open (s);
815  if (error < 0)
816    goto rollback;
817  error = pixma_deactivate (s->io);
818  if (error < 0)
819    goto rollback;
820  *handle = s;
821  return 0;
822
823rollback:
824  PDBG (pixma_dbg (2, "pixma_open() failed %s\n", pixma_strerror (error)));
825  pixma_close (s);
826  return error;
827}
828
829void
830pixma_close (pixma_t * s)
831{
832  pixma_t **p;
833
834  if (!s)
835    return;
836  for (p = &first_pixma; *p && *p != s; p = &((*p)->next))
837    {
838    }
839  PASSERT (*p);
840  if (!(*p))
841    return;
842  PDBG (pixma_dbg (2, "pixma_close(): %s\n", s->cfg->name));
843  if (s->io)
844    {
845      if (s->scanning)
846	{
847	  PDBG (pixma_dbg (3, "pixma_close(): scanning in progress, call"
848			   " finish_scan()\n"));
849	  s->ops->finish_scan (s);
850	}
851      s->ops->close (s);
852      pixma_disconnect (s->io);
853    }
854  *p = s->next;
855  free (s);
856}
857
858int
859pixma_scan (pixma_t * s, pixma_scan_param_t * sp)
860{
861  int error;
862
863  error = pixma_check_scan_param (s, sp);
864  if (error < 0)
865    return error;
866
867  if (sp->mode == PIXMA_SCAN_MODE_LINEART)
868    {
869      load_lut(sp->lineart_lut, 8, 8, 50, 205,
870               sp->threshold_curve, sp->threshold-127);
871    }
872
873#ifndef NDEBUG
874  pixma_dbg (3, "\n");
875  pixma_dbg (3, "pixma_scan(): start\n");
876  pixma_dbg (3, "  line_size=%"PRIu64" image_size=%"PRIu64" channels=%u depth=%u\n",
877	     sp->line_size, sp->image_size, sp->channels, sp->depth);
878  pixma_dbg (3, "  dpi=%ux%u offset=(%u,%u) dimension=%ux%u\n",
879	     sp->xdpi, sp->ydpi, sp->x, sp->y, sp->w, sp->h);
880  pixma_dbg (3, "  gamma=%f gamma_table=%p source=%d\n", sp->gamma, (void *) sp->gamma_table, sp->source);
881  pixma_dbg (3, "  threshold=%d threshold_curve=%d\n", sp->threshold, sp->threshold_curve);
882  pixma_dbg (3, "  adf-wait=%d\n", sp->adf_wait);
883  pixma_dbg (3, "  ADF page count: %d\n", sp->adf_pageid);
884#endif
885
886  s->param = sp;
887  s->cancel = 0;
888  s->cur_image_size = 0;
889  s->imagebuf.wptr = NULL;
890  s->imagebuf.wend = NULL;
891  s->imagebuf.rptr = NULL;
892  s->imagebuf.rend = NULL;
893  s->underrun = 0;
894  error = s->ops->scan (s);
895  if (error >= 0)
896    {
897      s->scanning = 1;
898    }
899  else
900    {
901      PDBG (pixma_dbg
902	    (3, "pixma_scan() failed %s\n", pixma_strerror (error)));
903    }
904
905  return error;
906}
907
908static uint8_t *
909fill_pixels (pixma_t * s, uint8_t * ptr, uint8_t * end, uint8_t value)
910{
911  if (s->cur_image_size < s->param->image_size)
912    {
913      long n = s->param->image_size - s->cur_image_size;
914      if (n > (end - ptr))
915	n = end - ptr;
916      memset (ptr, value, n);
917      s->cur_image_size += n;
918      ptr += n;
919    }
920  return ptr;
921}
922
923int
924pixma_read_image (pixma_t * s, void *buf, unsigned len)
925{
926  int result;
927  pixma_imagebuf_t ib;
928
929  if (!s->scanning)
930    return 0;
931  if (s->cancel)
932    {
933      result = PIXMA_ECANCELED;
934      goto cancel;
935    }
936
937  ib = s->imagebuf;		/* get rptr and rend */
938  ib.wptr = (uint8_t *) buf;
939  ib.wend = ib.wptr + len;
940
941  if (s->underrun)
942    {
943      if (s->cur_image_size < s->param->image_size)
944        {
945          ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
946        }
947      else
948        {
949          PDBG (pixma_dbg
950          (3, "pixma_read_image(): completed (underrun detected)\n"));
951          s->scanning = 0;
952        }
953      return ib.wptr - (uint8_t *) buf;
954    }
955
956  while (ib.wptr != ib.wend)
957    {
958      if (ib.rptr == ib.rend)
959        {
960          ib.rptr = ib.rend = NULL;
961          result = s->ops->fill_buffer (s, &ib);
962          if (result < 0)
963            goto cancel;
964          if (result == 0)
965            {			/* end of image? */
966              s->ops->finish_scan (s);
967              /* set last source after successful scan */
968              s->last_source = s->param->source;
969              if ((s->cur_image_size != s->param->image_size) && !s->param->mode_jpeg)
970                {
971                  PDBG (pixma_dbg (1, "WARNING:image size mismatches\n"));
972                  PDBG (pixma_dbg (1,
973                       "    %"PRIu64" expected (%d lines) but %"PRIu64" received (%"PRIu64" lines)\n",
974                       s->param->image_size, s->param->h,
975                       s->cur_image_size,
976                       s->cur_image_size / s->param->line_size));
977                  if ((s->cur_image_size % s->param->line_size) != 0)
978                    {
979                      PDBG (pixma_dbg (1,
980                           "BUG:received data not multiple of line_size\n"));
981                    }
982                }
983              if ((s->cur_image_size < s->param->image_size) && !s->param->mode_jpeg)
984                {
985                  s->underrun = 1;
986                  ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
987                }
988              else
989                {
990                  PDBG (pixma_dbg (3, "pixma_read_image():completed\n"));
991                  s->scanning = 0;
992                }
993              break;
994            }
995          s->cur_image_size += result;
996
997          PASSERT (s->cur_image_size <= s->param->image_size);
998        }
999      if (ib.rptr)
1000        {
1001          unsigned count = MIN (ib.rend - ib.rptr, ib.wend - ib.wptr);
1002          memcpy (ib.wptr, ib.rptr, count);
1003          ib.rptr += count;
1004          ib.wptr += count;
1005        }
1006    }
1007  s->imagebuf = ib;		/* store rptr and rend */
1008  return ib.wptr - (uint8_t *) buf;
1009
1010cancel:
1011  s->ops->finish_scan (s);
1012  s->scanning = 0;
1013  if (result == PIXMA_ECANCELED)
1014    {
1015      PDBG (pixma_dbg (3, "pixma_read_image(): cancelled by %sware\n",
1016		       (s->cancel) ? "soft" : "hard"));
1017    }
1018  else
1019    {
1020      PDBG (pixma_dbg (3, "pixma_read_image() failed %s\n",
1021		       pixma_strerror (result)));
1022    }
1023  return result;
1024}
1025
1026void
1027pixma_cancel (pixma_t * s)
1028{
1029  s->cancel = 1;
1030}
1031
1032int
1033pixma_enable_background (pixma_t * s, int enabled)
1034{
1035  return pixma_set_interrupt_mode (s->io, enabled);
1036}
1037
1038int
1039pixma_activate_connection(pixma_t * s)
1040{
1041  return pixma_activate (s->io);
1042}
1043
1044int
1045pixma_deactivate_connection(pixma_t * s)
1046{
1047  return pixma_deactivate (s->io);
1048}
1049
1050uint32_t
1051pixma_wait_event (pixma_t * s, int timeout /*ms */ )
1052{
1053  unsigned events;
1054
1055  if (s->events == PIXMA_EV_NONE && s->ops->wait_event)
1056    s->ops->wait_event (s, timeout);
1057  events = s->events;
1058  s->events = PIXMA_EV_NONE;
1059  return events;
1060}
1061
1062#define CLAMP2(x,w,min,max,dpi) do {		\
1063    unsigned m = (max) * (dpi) / 75;		\
1064    x = MIN(x, m - min);			\
1065    w = MIN(w, m - x);				\
1066    if (w < min)  w = min;			\
1067} while(0)
1068
1069int
1070pixma_check_scan_param (pixma_t * s, pixma_scan_param_t * sp)
1071{
1072  unsigned cfg_xdpi;
1073
1074  if (!(sp->channels == 3 ||
1075	(sp->channels == 1 && (s->cfg->cap & PIXMA_CAP_GRAY) != 0)))
1076    return PIXMA_EINVAL;
1077
1078  /* flatbed: use s->cfg->xdpi
1079   * TPU/ADF: use s->cfg->adftpu_max_dpi, if configured with dpi value */
1080  cfg_xdpi = ((sp->source == PIXMA_SOURCE_FLATBED
1081               || s->cfg->adftpu_max_dpi == 0) ? s->cfg->xdpi
1082                                               : s->cfg->adftpu_max_dpi);
1083
1084  if (pixma_check_dpi (sp->xdpi, cfg_xdpi) < 0 ||
1085      pixma_check_dpi (sp->ydpi, s->cfg->ydpi) < 0)
1086    return PIXMA_EINVAL;
1087
1088  /* xdpi must be equal to ydpi except that
1089     xdpi = max_xdpi and ydpi = max_ydpi. */
1090  if (!(sp->xdpi == sp->ydpi ||
1091	(sp->xdpi == cfg_xdpi && sp->ydpi == s->cfg->ydpi)))
1092    return PIXMA_EINVAL;
1093
1094  if (s->ops->check_param (s, sp) < 0)
1095    return PIXMA_EINVAL;
1096
1097  /* FIXME: I assume the same minimum width and height for every model.
1098   * new scanners need minimum 16 px height
1099   * minimum image size: 16 px x 16 px */
1100  CLAMP2 (sp->x, sp->w, 16, s->cfg->width, sp->xdpi);
1101  CLAMP2 (sp->y, sp->h, 16, s->cfg->height, sp->ydpi);
1102
1103  switch (sp->source)
1104    {
1105    case PIXMA_SOURCE_FLATBED:
1106      break;
1107
1108    case PIXMA_SOURCE_TPU:
1109      if ((s->cfg->cap & PIXMA_CAP_TPU) != PIXMA_CAP_TPU)
1110        {
1111          sp->source = PIXMA_SOURCE_FLATBED;
1112          PDBG (pixma_dbg
1113          (1, "WARNING: TPU unsupported, fallback to flatbed.\n"));
1114        }
1115      break;
1116
1117    case PIXMA_SOURCE_ADF:
1118      if ((s->cfg->cap & PIXMA_CAP_ADF) != PIXMA_CAP_ADF)
1119        {
1120          sp->source = PIXMA_SOURCE_FLATBED;
1121          PDBG (pixma_dbg
1122          (1, "WARNING: ADF unsupported, fallback to flatbed.\n"));
1123        }
1124      break;
1125
1126    case PIXMA_SOURCE_ADFDUP:
1127      if ((s->cfg->cap & PIXMA_CAP_ADFDUP) != PIXMA_CAP_ADFDUP)
1128        {
1129          if (s->cfg->cap & PIXMA_CAP_ADF)
1130            {
1131              sp->source = PIXMA_SOURCE_ADF;
1132            }
1133          else
1134            {
1135              sp->source = PIXMA_SOURCE_FLATBED;
1136            }
1137          PDBG (pixma_dbg
1138          (1, "WARNING: ADF duplex unsupported, fallback to %d.\n",
1139           sp->source));
1140        }
1141      break;
1142    case PIXMA_SOURCE_NONE:
1143      /* this source can not be selected */
1144      break;
1145    }
1146
1147  if (sp->depth == 0)
1148    sp->depth = 8;
1149  if ((sp->depth % 8) != 0 && sp->depth != 1)
1150    return PIXMA_EINVAL;
1151
1152  sp->line_size = 0;
1153
1154  if (s->ops->check_param (s, sp) < 0)
1155    return PIXMA_EINVAL;
1156
1157  if (sp->line_size == 0)
1158    sp->line_size = sp->depth / 8 * sp->channels * sp->w;
1159  sp->image_size = sp->line_size * sp->h;
1160
1161  /* image_size for software lineart is counted in bits */
1162  if (sp->software_lineart == 1)
1163    sp->image_size /= 8;
1164  return 0;
1165}
1166
1167const char *
1168pixma_get_string (pixma_t * s, pixma_string_index_t i)
1169{
1170  switch (i)
1171    {
1172    case PIXMA_STRING_MODEL:
1173      return s->cfg->name;
1174    case PIXMA_STRING_ID:
1175      return s->id;
1176    case PIXMA_STRING_LAST:
1177      return NULL;
1178    }
1179  return NULL;
1180}
1181
1182const pixma_config_t *
1183pixma_get_config (pixma_t * s)
1184{
1185  return s->cfg;
1186}
1187
1188void
1189pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n)
1190{
1191  unsigned i;
1192  double r_gamma = 1.0 / gamma;
1193  double in_scale = 1.0 / (n - 1);
1194
1195  /* 8-bits gamma table
1196   * for generation 1 scanners
1197   */
1198  if (n == 4096)
1199    {
1200      double out_scale = 255.0;
1201
1202      for (i = 0; (unsigned) i != n; i++)
1203        {
1204          table[i] = (int) (out_scale * pow (i * in_scale, r_gamma) + 0.5);
1205        }
1206    }
1207
1208  /* 16-bits gamma table */
1209  else
1210    {
1211      double out_scale = 65535.0;
1212      uint16_t value;
1213
1214      for (i = 0; i < n; i++)
1215        {
1216          value = (uint16_t) (out_scale * pow (i * in_scale, r_gamma) + 0.5);
1217          table[2 * i] = (uint8_t) (value & 0xff);
1218          table[2 * i + 1] = (uint8_t) (value >> 8);
1219        }
1220    }
1221}
1222
1223int
1224pixma_find_scanners (const char **conf_devices, SANE_Bool local_only)
1225{
1226  return pixma_collect_devices (conf_devices, pixma_devices, local_only);
1227}
1228
1229const char *
1230pixma_get_device_model (unsigned devnr)
1231{
1232  const pixma_config_t *cfg = pixma_get_device_config (devnr);
1233  return (cfg) ? cfg->name : NULL;
1234}
1235
1236
1237int
1238pixma_get_device_status (pixma_t * s, pixma_device_status_t * status)
1239{
1240  if (!status)
1241    return PIXMA_EINVAL;
1242  memset (status, 0, sizeof (*status));
1243  return s->ops->get_status (s, status);
1244}
1245
1246unsigned
1247pixma_calc_calibrate (pixma_t * p)
1248{
1249    pixma_scan_param_t * sp = p->param;
1250    if (sp->calibrate == PIXMA_CALIBRATE_ALWAYS)
1251        return 0x01;
1252    if (sp->calibrate == PIXMA_CALIBRATE_NEVER)
1253        return 0x00;
1254    /* sp->calibrate == PIXMA_CALIBRATE_ONCE */
1255    if (sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP)
1256        return sp->adf_pageid == 0 ? 0x01 : 0x00;
1257    /* sp->source == PIXMA_SOURCE_FLATBED | TPU */
1258    return sp->source == p->last_source ? 0x00 : 0x01;
1259}
1260
1261#if defined(HAVE_LIBXML2)
1262static const char *
1263format_xml_response(const char *resp_details)
1264{
1265  if (strcmp(resp_details, "DeviceBusy") == 0)
1266    /* https://cromwell-intl.com/open-source/canon-pixma-printer-scanner.html */
1267    return "DeviceBusy - Device not initialized (yet). " \
1268      "Please check the USB power, try a different port or install the Ink Cartridges if the device supports them.";
1269  else if (strcmp(resp_details, "ScannerCarriageLockError") == 0)
1270    return "ScannerCarriageLockError - Please consult the manual to unlock the Carriage Lock.";
1271  else if (strcmp(resp_details, "PCScanning") == 0)
1272    return "PCScanning - Previous scan attempt was not completed. Try disconnecting and reconnecting the scanner. " \
1273      "If the problem persists, consider reporting it as a bug at http://www.sane-project.org/bugs.html.";
1274  else if (strcmp(resp_details, "DeviceCheckError") == 0)
1275    return "DeviceCheckError - Device detected a fault. Contact the repair center.";
1276  else
1277    return resp_details;
1278}
1279
1280int
1281pixma_parse_xml_response(const char *xml_message)
1282{
1283  int status = PIXMA_EPROTO;
1284  xmlDoc *doc = NULL;
1285  xmlNode *node = NULL;
1286  xmlChar *content = NULL;
1287
1288  doc = xmlReadMemory(xml_message, strlen(xml_message), "mem:device-resp.xml", NULL, 0);
1289  if (doc == NULL) {
1290    PDBG(pixma_dbg(10, "unable to parse xml response\n"));
1291    status = PIXMA_EINVAL;
1292    goto clean;
1293  }
1294
1295  node = xmlDocGetRootElement(doc);
1296  if (node == NULL) {
1297    status = PIXMA_EPROTO;
1298    goto clean;
1299  }
1300
1301  /* /cmd */
1302  for (; node; node = node->next) {
1303    if (strcmp((const char*)node->name, "cmd") == 0)
1304      break;
1305  }
1306  if (!node) {
1307    status = PIXMA_EPROTO;
1308    goto clean;
1309  }
1310
1311  /* /cmd/contents */
1312  for (node = node->children; node; node = node->next) {
1313    if (strcmp((const char*)node->name, "contents") == 0)
1314      break;
1315  }
1316  if (!node) {
1317    status = PIXMA_EPROTO;
1318    goto clean;
1319  }
1320
1321  /* /cmd/contents/param_set */
1322  for (node = node->children; node; node = node->next) {
1323    if (strcmp((const char*)node->name, "param_set") == 0)
1324      break;
1325  }
1326  if (!node) {
1327    status = PIXMA_EPROTO;
1328    goto clean;
1329  }
1330
1331  /* /cmd/contents/param_set/response... */
1332  for (node = node->children; node; node = node->next)
1333  {
1334    if (strcmp((const char*)node->name, "response") == 0) {
1335      content = xmlNodeGetContent(node);
1336      if (strcmp((const char*)content, "OK") == 0)
1337        status = PIXMA_STATUS_OK;
1338      else
1339        status = PIXMA_EINVAL;
1340      xmlFree(content);
1341    } else if (strcmp((const char*)node->name, "response_detail") == 0) {
1342      content = xmlNodeGetContent(node);
1343      if (strlen((const char*)content) > 0) {
1344        PDBG(pixma_dbg(0, "device response: %s\n",
1345                      format_xml_response((const char*)content)));
1346      }
1347      xmlFree(content);
1348    }
1349  }
1350
1351clean:
1352  xmlFreeDoc(doc);
1353  return status;
1354}
1355#endif
1356