[sane-devel] [sane-pixma] Canon MF4150 v. PIXMA_CAP_LINEART

Rolf Bensch rolf at bensch-online.de
Wed Aug 21 20:10:32 UTC 2013


Hi Samuel,

I prepared a quick patch to implement lineart for imageclass scanners.

To use this patch you must install SANE from git, as described here:
http://www.sane-project.org/README.linux

and

patch pixma_imageclass.c with the attached file ('patch
pixma_imageclass.c pixma_imageclass.c.diff1').

If you only need the Pixma backend you can reduce compiling time with
'./configure BACKENDS=pixma'.

The patch can be buggy. If so, I need all debug output from scanimage
enabled with 'export SANE_DEBUG_PIXMA=4'.

Cheers,
Rolf


Am 20.08.2013 15:36, schrieb Samuel Adam:
> I know experientially that the Canon imageCLASS MF4150 is possessed of
> a 1-bpp lineart mode.  Pages fly through the automatic feeder, and
> text is accorded an OCR-friendly crispiness lacking in the greyscale
> mode.  The Canon-provided Windows-only software provides two modes it
> respectively terms "Black and White" (not too good) and "Black and
> White Text" (much better).[1]  I do not currently have a Windows
> machine available, and I need to make some scans *yesterday*.
>
> sane-pixma permits only --mode Color or --mode Gray with the MF4150,
> and `scanimage -A` shows only these options.
>
> What would happen if I simply ORed in PIXMA_CAP_LINEART at the
> appropriate line in pixma_imageclass.c?
>
> -   DEV ("Canon imageCLASS MF4150", "MF4100", MF4100_PID, 600, 640,
> 877, PIXMA_CAP_ADF),
> +   DEV ("Canon imageCLASS MF4150", "MF4100", MF4100_PID, 600, 640,
> 877, PIXMA_CAP_ADF | PIXMA_CAP_LINEART),
>
> I expect this would lead to Bad Things, what with all the moving parts
> I skimmed past.  But is any other way to make it work right quickly?
>
> Sorry to return ENOTIME on the project to actually familiarize myself
> with sane-pixma code, beyond a simple grep.  And thanks to the folks
> who reverse-engineered the Canon protocols, so I can use scanner at all.
>
> Samuel Adam
>
>
> [1] The idiot-friendly software has a checkbox captioned "Show Scanner
> Driver".  Check it, and options galore do arise.
>
>
>

-------------- next part --------------
--- ./pixma_imageclass.c	2013-08-21 21:58:41.000000000 +0200
+++ ../sane-backends/backend/pixma_imageclass.c	2013-08-21 21:58:46.000000000 +0200
@@ -247,7 +247,7 @@
   pixma_set_be32 (mf->raw_width, data + 0x10);
   pixma_set_be32 (s->param->h, data + 0x14);
   data[0x18] = (s->param->channels == 1) ? 0x04 : 0x08;
-  data[0x19] = s->param->channels * s->param->depth;	/* bits per pixel */
+  data[0x19] = s->param->channels * ((s->param->software_lineart) ? 8 : s->param->depth);	/* bits per pixel */
   data[0x1f] = 0x7f;
   data[0x20] = 0xff;
   data[0x23] = 0x81;
@@ -499,8 +499,36 @@
 {
   UNUSED (s);
 
+  PDBG (pixma_dbg (4, "*iclass_check_param***** Initially: channels=%u, depth=%u, x=%u, y=%u, w=%u, line_size=%u , h=%u*****\n",
+                   sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->line_size, sp->h));
+
   sp->depth = 8;
+  sp->software_lineart = 0;
+  if (s->param->mode == PIXMA_SCAN_MODE_LINEART)
+  {
+    sp->software_lineart = 1;
+    sp->channels = 1;
+    sp->depth = 1;
+  }
+
+  /* for software lineart w must be a multiple of 8 */
+  if (sp->software_lineart == 1 && sp->w % 8)
+  {
+    unsigned w_max;
+
+    sp->w += 8 - (sp->w % 8);
+
+    /* do not exceed the scanner capability */
+    w_max = s->cfg->width * s->cfg->xdpi / 75;
+    w_max -= w_max % 8;
+    if (sp->w > w_max)
+      sp->w = w_max;
+  }
   sp->line_size = ALIGN_SUP (sp->w, 32) * sp->channels;
+
+  PDBG (pixma_dbg (4, "*iclass_check_param***** Finally: channels=%u, depth=%u, x=%u, y=%u, w=%u, line_size=%u , h=%u*****\n",
+                   sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->line_size, sp->h));
+
   return 0;
 }
 
@@ -634,7 +662,23 @@
       n = mf->blk_len / s->param->line_size;
       if (n != 0)
         {
-          if (s->param->channels != 1 &&
+          PDBG (pixma_dbg (4, "*iclass_fill_buffer***** Processing with n=%u, w=%i, line_size=%u, raw_width=%u ***** \n",
+                           n, s->param->w, s->param->line_size, mf->raw_width));
+
+          /* gray to lineart convert */
+          if (s->param->mode == PIXMA_SCAN_MODE_LINEART)
+          {
+            int i;
+            uint8_t *sptr, *dptr;
+
+            sptr = mf->blkptr;
+            dptr = mf->lineptr;
+
+            /* process ALL lines */
+            for (i = 0; i < n; i++, sptr += s->param->line_size, dptr += (s->param->line_size / 8))
+              pixma_binarize_line (s->param, dptr, sptr, s->param->line_size, 1);
+          }
+          else if (s->param->channels != 1 &&
                   s->cfg->pid != MF3010_PID &&
                   s->cfg->pid != MF4410_PID &&
 	          s->cfg->pid != MF4550_PID &&
@@ -752,6 +796,7 @@
             0, 0,                     /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \
             0, 0,                     /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */   \
             w, h,                     /* width, height */	\
+            PIXMA_CAP_LINEART|        /* all scanners with software lineart */ \
             PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap             \
 }
 const pixma_config_t pixma_iclass_devices[] = {


More information about the sane-devel mailing list