If you have a 3-pass Mustek scanner, could you please try this patch
and let me know if/how it works? If it works, could you send me the
following info so I can update the README file?
- Exact scanner type: label on front of scanner & the SCSI id string & firmware version
- the SCSI card you're using
The SCSI id and firmware rev can be obtained like this:
SANE_DEBUG_MUSTEK=128 scan -h -d mustek >/dev/null
Enjoy,
--david
--
--- sane-0.53/backend/mustek.c Fri Apr 11 22:23:38 1997
+++ sane-0.54/backend/mustek.c Thu Apr 17 09:03:49 1997
@@ -264,8 +264,9 @@
if (strncmp (model_name, "MFS-12000CX", 11) == 0)
{
dev->x_range.max = SANE_FIX (8.5 * MM_PER_INCH);
- dev->y_range.max = SANE_FIX (14.0 * MM_PER_INCH); /* is this correct? */
+ dev->y_range.max = SANE_FIX (14.0 * MM_PER_INCH);
dev->dpi_range.max = SANE_FIX (1200);
+ dev->flags |= MUSTEK_FLAG_USE_EIGHTS;
}
else if (strncmp (model_name, "MFS-06000CX", 11) == 0)
{
@@ -361,8 +362,11 @@
if (result[63] & (1 << 6))
dev->flags |= MUSTEK_FLAG_TA;
- DBG(3, "attach: found Mustek scanner model %s (%s)\n",
- dev->sane.model, dev->sane.type);
+ DBG(3, "attach: found Mustek scanner model %s (%s), %s%s%s\n",
+ dev->sane.model, dev->sane.type,
+ (dev->flags & MUSTEK_FLAG_SINGLE_PASS) ? "1-pass" : "3-pass",
+ (dev->flags & MUSTEK_FLAG_ADF) ? ", ADF" : "",
+ (dev->flags & MUSTEK_FLAG_TA) ? ", TA" : "");
++num_devices;
dev->next = first_dev;
@@ -552,15 +556,17 @@
if (s->hw->flags & MUSTEK_FLAG_USE_EIGHTS)
{
+ double eights_per_mm = 8 / MM_PER_INCH;
+
/*
* The MSF-06000CZ seems to lock-up if the pixel-unit is used.
* Using 1/8" works.
*/
*cp++ = ((s->mode & MUSTEK_MODE_HALFTONE) ? 0x01 : 0x00);
- STORE16(cp, SANE_UNFIX(s->val[OPT_TL_X].w) * 8 / MM_PER_INCH + 0.5);
- STORE16(cp, SANE_UNFIX(s->val[OPT_TL_Y].w) * 8 / MM_PER_INCH + 0.5);
- STORE16(cp, SANE_UNFIX(s->val[OPT_BR_X].w) * 8 / MM_PER_INCH + 0.5);
- STORE16(cp, SANE_UNFIX(s->val[OPT_BR_Y].w) * 8 / MM_PER_INCH + 0.5);
+ STORE16(cp, SANE_UNFIX(s->val[OPT_TL_X].w) * eights_per_mm + 0.5);
+ STORE16(cp, SANE_UNFIX(s->val[OPT_TL_Y].w) * eights_per_mm + 0.5);
+ STORE16(cp, SANE_UNFIX(s->val[OPT_BR_X].w) * eights_per_mm + 0.5);
+ STORE16(cp, SANE_UNFIX(s->val[OPT_BR_Y].w) * eights_per_mm + 0.5);
}
else
{
@@ -690,7 +696,7 @@
if (s->hw->flags & MUSTEK_FLAG_SINGLE_PASS)
start[4] |= 0x20;
else
- start[4] |= ((s->pass << 3) + 1);
+ start[4] |= ((s->pass + 1) << 3);
}
/* or in single/multi bit: */
start[4] |= (s->mode & MUSTEK_MODE_MULTIBIT) ? (1 << 6) : 0;
@@ -1315,55 +1321,53 @@
DBG(1, "reader_process: read_data failed with status=%d\n", status);
return 3;
}
+ DBG(3, "reader_process: read %d lines", lines_per_buffer);
/* convert to pixel-interleaved format: */
- if (s->mode & MUSTEK_MODE_COLOR)
+ if ((s->mode & MUSTEK_MODE_COLOR)
+ && (s->hw->flags & MUSTEK_FLAG_SINGLE_PASS))
{
- if (s->hw->flags & MUSTEK_FLAG_SINGLE_PASS)
- {
- SANE_Byte *src;
+ SANE_Byte *src;
- if (s->hw->flags & MUSTEK_FLAG_LD_MFS)
- fix_line_distance_mfs (s, lines_per_buffer, bpl, data, extra);
- else if (s->ld.max_value)
- /* need to correct for distance between r/g/b sensors: */
- fix_line_distance_normal (s, lines_per_buffer, bpl, data,
- extra);
- else
- memcpy (extra, data, lines_per_buffer * bpl);
+ if (s->hw->flags & MUSTEK_FLAG_LD_MFS)
+ fix_line_distance_mfs (s, lines_per_buffer, bpl, data, extra);
+ else if (s->ld.max_value)
+ /* need to correct for distance between r/g/b sensors: */
+ fix_line_distance_normal (s, lines_per_buffer, bpl, data, extra);
+ else
+ memcpy (extra, data, lines_per_buffer * bpl);
- src = extra;
- if (s->mode & MUSTEK_MODE_MULTIBIT)
+ src = extra;
+ if (s->mode & MUSTEK_MODE_MULTIBIT)
+ {
+ /* each r/g/b sample is 8 bits in line-interleaved format */
+ for (y = 0; y < lines_per_buffer; ++y)
{
- /* each r/g/b sample is 8 bits in line-interleaved format */
- for (y = 0; y < lines_per_buffer; ++y)
+ for (x = 0; x < bpl / 3; ++x)
{
- for (x = 0; x < bpl / 3; ++x)
- {
- fputc (src[0 * bpl / 3 + x], fp);
- fputc (src[1 * bpl / 3 + x], fp);
- fputc (src[2 * bpl / 3 + x], fp);
- }
- src += bpl;
+ fputc (src[0 * bpl / 3 + x], fp);
+ fputc (src[1 * bpl / 3 + x], fp);
+ fputc (src[2 * bpl / 3 + x], fp);
}
+ src += bpl;
}
- else
+ }
+ else
+ {
+ /* each r/g/b/ sample is 1 bit in line-interleaved format */
+# define EXPAND(b, v) (((v) & (1 << (bit))) ? 0xff : 0x00)
+ for (y = 0; y < lines_per_buffer; ++y)
{
- /* each r/g/b/ sample is 1 bit in line-interleaved format */
-# define EXPAND(b, v) (((v) & (1 << (bit))) ? 0xff : 0x00)
- for (y = 0; y < lines_per_buffer; ++y)
+ for (x = 0; x < bpl / 3; ++x)
{
- for (x = 0; x < bpl / 3; ++x)
+ for (bit = 7; bit >= 0; --bit)
{
- for (bit = 7; bit >= 0; --bit)
- {
- fputc (EXPAND (bit, src[0 * bpl / 3 + x]), fp);
- fputc (EXPAND (bit, src[1 * bpl / 3 + x]), fp);
- fputc (EXPAND (bit, src[2 * bpl / 3 + x]), fp);
- }
+ fputc (EXPAND (bit, src[0 * bpl / 3 + x]), fp);
+ fputc (EXPAND (bit, src[1 * bpl / 3 + x]), fp);
+ fputc (EXPAND (bit, src[2 * bpl / 3 + x]), fp);
}
- src += bpl;
}
+ src += bpl;
}
}
}
@@ -1757,11 +1761,11 @@
sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
{
Mustek_Scanner *s = handle;
+ const char *mode;
if (!s->scanning)
{
double width, height, dpi;
- const char *mode;
memset (&s->params, 0, sizeof (s->params));
@@ -1778,53 +1782,50 @@
s->params.pixels_per_line = width * dots_per_mm;
s->params.lines = height * dots_per_mm;
}
+ }
+ mode = s->val[OPT_MODE].s;
+ if (strcmp (mode, "Lineart") == 0 || strcmp (mode, "Halftone") == 0)
+ {
+ s->params.format = SANE_FRAME_GRAY;
+ s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
+ s->params.depth = 1;
+ }
+ else if (strcmp (mode, "Gray") == 0)
+ {
+ s->params.format = SANE_FRAME_GRAY;
+ s->params.bytes_per_line = s->params.pixels_per_line;
+ s->params.depth = 8;
+ }
+ else
+ {
+ /* it's one of the color modes... */
- mode = s->val[OPT_MODE].s;
- if (strcmp (mode, "Lineart") == 0 || strcmp (mode, "Halftone") == 0)
- {
- s->params.format = SANE_FRAME_GRAY;
- s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
- s->params.depth = 1;
- }
- else if (strcmp (mode, "Gray") == 0)
+ if (s->hw->flags & MUSTEK_FLAG_SINGLE_PASS)
{
- s->params.format = SANE_FRAME_GRAY;
- s->params.bytes_per_line = s->params.pixels_per_line;
+ /* all color modes are treated the same since lineart and
+ halftoning with 1 bit color pixels still results in 3
+ bytes/pixel. */
+ s->params.format = SANE_FRAME_RGB;
+ s->params.bytes_per_line = 3 * s->params.pixels_per_line;
s->params.depth = 8;
}
else
{
- /* all color modes are treated the same since lineart with 1
- bit color pixels still results in 3 bytes/pixel. */
- if (s->hw->flags & MUSTEK_FLAG_SINGLE_PASS)
+ s->params.format = SANE_FRAME_RED + s->pass;
+ if (strcmp (mode, "Color") == 0)
{
- s->params.format = SANE_FRAME_RGB;
- s->params.bytes_per_line = 3 * s->params.pixels_per_line;
+ s->params.bytes_per_line = s->params.pixels_per_line;
s->params.depth = 8;
}
else
{
- switch (s->pass)
- {
- case 0:
- s->params.format = SANE_FRAME_RED;
- break;
- case 1:
- s->params.format = SANE_FRAME_GREEN;
- break;
- case 2:
- s->params.format = SANE_FRAME_BLUE;
- break;
- default:
- break;
- }
- s->params.bytes_per_line = s->params.pixels_per_line;
- s->params.depth = 8;
+ s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
+ s->params.depth = 1;
}
}
- s->params.last_frame = (s->params.format != SANE_FRAME_RED
- && s->params.format != SANE_FRAME_GREEN);
}
+ s->params.last_frame = (s->params.format != SANE_FRAME_RED
+ && s->params.format != SANE_FRAME_GREEN);
if (params)
*params = s->params;
return SANE_STATUS_GOOD;
@@ -1843,18 +1844,9 @@
if (status != SANE_STATUS_GOOD)
return status;
- if (s->fd >= 0)
- {
- /* this is the second or third pass... */
- status = wait_ready (s->fd);
- if (status != SANE_STATUS_GOOD)
- {
- DBG(1, "open: wait_ready() failed: %s\n", sane_strstatus (status));
- goto stop_scanner_and_return;
- }
- }
- else
+ if (s->fd < 0)
{
+ /* this is the first (and maybe only) pass... */
const char *mode;
/* translate options into s->mode for convenient access: */
@@ -1883,34 +1875,34 @@
s->hw->sane.name, sane_strstatus (status));
return status;
}
+ }
- status = wait_ready (s->fd);
- if (status != SANE_STATUS_GOOD)
- {
- DBG(1, "open: wait_ready() failed: %s\n", sane_strstatus (status));
- goto stop_scanner_and_return;
- }
+ status = wait_ready (s->fd);
+ if (status != SANE_STATUS_GOOD)
+ {
+ DBG(1, "open: wait_ready() failed: %s\n", sane_strstatus (status));
+ goto stop_scanner_and_return;
+ }
- status = scan_area_and_windows (s);
- if (status != SANE_STATUS_GOOD)
- {
- DBG(1, "open: set scan area command failed: %s\n",
- sane_strstatus (status));
- goto stop_scanner_and_return;
- }
+ status = scan_area_and_windows (s);
+ if (status != SANE_STATUS_GOOD)
+ {
+ DBG(1, "open: set scan area command failed: %s\n",
+ sane_strstatus (status));
+ goto stop_scanner_and_return;
+ }
- status = request_sense (s);
- if (status != SANE_STATUS_GOOD)
- goto stop_scanner_and_return;
+ status = request_sense (s);
+ if (status != SANE_STATUS_GOOD)
+ goto stop_scanner_and_return;
- status = backtrack_and_adf (s);
- if (status != SANE_STATUS_GOOD)
- goto stop_scanner_and_return;
+ status = backtrack_and_adf (s);
+ if (status != SANE_STATUS_GOOD)
+ goto stop_scanner_and_return;
- status = request_sense (s);
- if (status != SANE_STATUS_GOOD)
- goto stop_scanner_and_return;
- }
+ status = request_sense (s);
+ if (status != SANE_STATUS_GOOD)
+ goto stop_scanner_and_return;
if (s->one_pass_color_scan)
{
@@ -2042,6 +2034,7 @@
*len = 0;
nread = read (s->pipe, buf, max_len);
+ DBG(3, "read %ld bytes\n", (long) nread);
if (!s->scanning)
return do_cancel (s);
--
Source code, list archive, and docs: http://www.azstarnet.com/~axplinux/sane/
To unsubscribe: mail -s unsubscribe sane-devel-request@listserv.azstarnet.com