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[] = {
