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 
72 extern const pixma_config_t pixma_mp150_devices[];
73 extern const pixma_config_t pixma_mp750_devices[];
74 extern const pixma_config_t pixma_mp730_devices[];
75 extern const pixma_config_t pixma_mp800_devices[];
76 extern const pixma_config_t pixma_iclass_devices[];
77 
78 static 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 
87 static pixma_t *first_pixma = NULL;
88 static time_t tstart_sec = 0;
89 static uint32_t tstart_usec = 0;
90 static int debug_level = 1;
91 
92 
93 #ifndef NDEBUG
94 
95 static void
u8tohex(uint8_t x, char *str)96 u8tohex (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 
107 static void
u32tohex(uint32_t x, char *str)108 u32tohex (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 
116 void
pixma_hexdump(int level, const void *d_, unsigned len)117 pixma_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 
175 static void
time2str(char *buf, unsigned size)176 time2str (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 
196 void
pixma_dump(int level, const char *type, const void *data, int len, int size, int max)197 pixma_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 */
228 const char *
pixma_strerror(int error)229 pixma_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 
269 void
pixma_set_debug_level(int level)270 pixma_set_debug_level (int level)
271 {
272   debug_level = level;
273 }
274 
275 void
pixma_set_be16(uint16_t x, uint8_t * buf)276 pixma_set_be16 (uint16_t x, uint8_t * buf)
277 {
278   buf[0] = x >> 8;
279   buf[1] = x;
280 }
281 
282 void
pixma_set_be32(uint32_t x, uint8_t * buf)283 pixma_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 
291 uint16_t
pixma_get_be16(const uint8_t * buf)292 pixma_get_be16 (const uint8_t * buf)
293 {
294   return ((uint16_t) buf[0] << 8) | buf[1];
295 }
296 
297 uint32_t
pixma_get_be32(const uint8_t * buf)298 pixma_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 
304 uint8_t
pixma_sum_bytes(const void *data, unsigned len)305 pixma_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 
314 void
pixma_sleep(unsigned long usec)315 pixma_sleep (unsigned long usec)
316 {
317   usleep (usec);
318 }
319 
320 void
pixma_get_time(time_t * sec, uint32_t * usec)321 pixma_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  */
341 uint8_t *
pixma_r_to_ir(uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)342 pixma_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  */
366 uint8_t *
pixma_rgb_to_gray(uint8_t * gptr, uint8_t * sptr, unsigned w, unsigned c)367 pixma_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  * */
408 uint8_t *
pixma_binarize_line(pixma_scan_param_t * sp, uint8_t * dst, uint8_t * src, unsigned width, unsigned c)409 pixma_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   * */
543 static SANE_Status
load_lut(unsigned char * lut, int in_bits, int out_bits, int out_min, int out_max, int slope, int offset)544 load_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 
594 int
pixma_map_status_errno(unsigned status)595 pixma_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 
610 int
pixma_check_result(pixma_cmdbuf_t * cb)611 pixma_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 
657 int
pixma_cmd_transaction(pixma_t * s, const void *cmd, unsigned cmdlen, void *data, unsigned expected_len)658 pixma_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 
713 uint8_t *
pixma_newcmd(pixma_cmdbuf_t * cb, unsigned cmd, unsigned dataout, unsigned datain)714 pixma_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 
733 int
pixma_exec(pixma_t * s, pixma_cmdbuf_t * cb)734 pixma_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 
745 int
pixma_exec_short_cmd(pixma_t * s, pixma_cmdbuf_t * cb, unsigned cmd)746 pixma_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 
752 int
pixma_check_dpi(unsigned dpi, unsigned max)753 pixma_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 
763 int
pixma_init(void)764 pixma_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 
774 void
pixma_cleanup(void)775 pixma_cleanup (void)
776 {
777   while (first_pixma)
778     pixma_close (first_pixma);
779   pixma_io_cleanup ();
780 }
781 
782 int
pixma_open(unsigned devnr, pixma_t ** handle)783 pixma_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 
823 rollback:
824   PDBG (pixma_dbg (2, "pixma_open() failed %s\n", pixma_strerror (error)));
825   pixma_close (s);
826   return error;
827 }
828 
829 void
pixma_close(pixma_t * s)830 pixma_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 
858 int
pixma_scan(pixma_t * s, pixma_scan_param_t * sp)859 pixma_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 
908 static uint8_t *
fill_pixels(pixma_t * s, uint8_t * ptr, uint8_t * end, uint8_t value)909 fill_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 
923 int
pixma_read_image(pixma_t * s, void *buf, unsigned len)924 pixma_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 
1010 cancel:
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 
1026 void
pixma_cancel(pixma_t * s)1027 pixma_cancel (pixma_t * s)
1028 {
1029   s->cancel = 1;
1030 }
1031 
1032 int
pixma_enable_background(pixma_t * s, int enabled)1033 pixma_enable_background (pixma_t * s, int enabled)
1034 {
1035   return pixma_set_interrupt_mode (s->io, enabled);
1036 }
1037 
1038 int
pixma_activate_connection(pixma_t * s)1039 pixma_activate_connection(pixma_t * s)
1040 {
1041   return pixma_activate (s->io);
1042 }
1043 
1044 int
pixma_deactivate_connection(pixma_t * s)1045 pixma_deactivate_connection(pixma_t * s)
1046 {
1047   return pixma_deactivate (s->io);
1048 }
1049 
1050 uint32_t
pixma_wait_event(pixma_t * s, int timeout )1051 pixma_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 
1069 int
pixma_check_scan_param(pixma_t * s, pixma_scan_param_t * sp)1070 pixma_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 
1167 const char *
pixma_get_string(pixma_t * s, pixma_string_index_t i)1168 pixma_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 
1182 const pixma_config_t *
pixma_get_config(pixma_t * s)1183 pixma_get_config (pixma_t * s)
1184 {
1185   return s->cfg;
1186 }
1187 
1188 void
pixma_fill_gamma_table(double gamma, uint8_t * table, unsigned n)1189 pixma_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 
1223 int
pixma_find_scanners(const char **conf_devices, SANE_Bool local_only)1224 pixma_find_scanners (const char **conf_devices, SANE_Bool local_only)
1225 {
1226   return pixma_collect_devices (conf_devices, pixma_devices, local_only);
1227 }
1228 
1229 const char *
pixma_get_device_model(unsigned devnr)1230 pixma_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 
1237 int
pixma_get_device_status(pixma_t * s, pixma_device_status_t * status)1238 pixma_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 
1246 unsigned
pixma_calc_calibrate(pixma_t * p)1247 pixma_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)
1262 static const char *
format_xml_response(const char *resp_details)1263 format_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 
1280 int
pixma_parse_xml_response(const char *xml_message)1281 pixma_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 
1351 clean:
1352   xmlFreeDoc(doc);
1353   return status;
1354 }
1355 #endif
1356