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