[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