kopia lustrzana https://gitlab.com/sane-project/backends
2001-01-17 Henning Meier-Geinitz <hmg@gmx.de>
* backend/mustek.c backend/mustek.desc backend/mustek.h backend/mustek.CHANGES doc/sane-mustek.man: Added 36 bit mode for Pro models. Removed support for "special" modes, used options instead. Code cleanup. Updated manpage concerning sane-find-scanner. New version: 1.0-104. * configure: regenerated from configure.in.DEVEL_2_0_BRANCH-1
rodzic
e0f9d69e93
commit
229c5f7dbe
373
backend/mustek.c
373
backend/mustek.c
|
@ -1,7 +1,7 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 1996, 1997 David Mosberger-Tang and Andreas Czechanowski,
|
||||
1998 Andreas Bolsch for extension to ScanExpress models version 0.6,
|
||||
2000 Henning Meier-Geinitz
|
||||
2000, 2001 Henning Meier-Geinitz.
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
/**************************************************************************/
|
||||
/* Mustek backend version */
|
||||
#define BUILD 103
|
||||
#define BUILD 104
|
||||
/**************************************************************************/
|
||||
|
||||
#include "sane/config.h"
|
||||
|
@ -116,26 +116,15 @@ static SANE_String_Const mode_list_paragon[] =
|
|||
"Lineart", "Halftone", "Gray", "Color",
|
||||
0
|
||||
};
|
||||
static SANE_String_Const mode_list_pro[] =
|
||||
{
|
||||
"Lineart", "Gray", "Gray fast", "Color",
|
||||
0
|
||||
};
|
||||
static SANE_String_Const mode_list_se[] =
|
||||
{
|
||||
"Lineart", "Gray", "Color",
|
||||
0
|
||||
};
|
||||
/*
|
||||
static SANE_String_Const mode_list_se_plus[] =
|
||||
|
||||
static SANE_String_Const bit_depth_list_pro[] =
|
||||
{
|
||||
"Lineart", "Gray", "Color", "Color 48 bit",
|
||||
0
|
||||
};
|
||||
*/
|
||||
static SANE_String_Const mode_list_se_plus[] =
|
||||
{
|
||||
"Lineart", "Gray", "Color",
|
||||
"8", "12",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -244,6 +233,17 @@ static const SANE_Byte scsi_lookup_table[] =
|
|||
static SANE_Status area_and_windows (Mustek_Scanner *s);
|
||||
static SANE_Status inquiry (Mustek_Scanner *s);
|
||||
|
||||
/* Test if this machine is little endian (from coolscan.c) */
|
||||
static SANE_Bool little_endian(void)
|
||||
{
|
||||
SANE_Int testvalue = 255;
|
||||
u_int8_t *firstbyte = (u_int8_t *) &testvalue;
|
||||
|
||||
if (*firstbyte == 255)
|
||||
return SANE_TRUE;
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/* Used for Pro series. First value seems to be always 85, second one varies.
|
||||
First bit of second value clear == device ready (?) */
|
||||
static SANE_Status
|
||||
|
@ -609,8 +609,6 @@ dev_read_req_enter (Mustek_Scanner *s, SANE_Byte *buf, SANE_Int lines,
|
|||
SANE_Byte readlines[10];
|
||||
if (s->mode & MUSTEK_MODE_COLOR)
|
||||
lines *= 3;
|
||||
else if (s->mode & MUSTEK_MODE_COLOR_48)
|
||||
lines *= 6;
|
||||
|
||||
memset (readlines, 0, sizeof (readlines));
|
||||
readlines[0] = MUSTEK_SCSI_READ_DATA;
|
||||
|
@ -1807,11 +1805,6 @@ set_window_se (Mustek_Scanner *s, SANE_Int lamp)
|
|||
*cp++ = 0x05; /* actually not used! */
|
||||
*cp++ = 24; /* 24 bits/pixel in color mode */
|
||||
}
|
||||
else if (s->mode & MUSTEK_MODE_COLOR_48)
|
||||
{
|
||||
*cp++ = 0x05; /* actually not used! */
|
||||
*cp++ = 48; /* 48 bits/pixel in color mode */
|
||||
}
|
||||
else if (s->mode & MUSTEK_MODE_GRAY)
|
||||
{
|
||||
*cp++ = 0x02; /* actually not used! */
|
||||
|
@ -1846,7 +1839,7 @@ set_window_pro (Mustek_Scanner *s)
|
|||
|
||||
memset (cmd, 0, sizeof (cmd));
|
||||
cmd[0] = MUSTEK_SCSI_SET_WINDOW;
|
||||
cmd[8] = 0x0a;
|
||||
cmd[8] = 0x09;
|
||||
cp = cmd + sizeof (scsi_set_window); /* skip command block */
|
||||
|
||||
*cp++ = 0; /* what's this? */
|
||||
|
@ -1857,7 +1850,8 @@ set_window_pro (Mustek_Scanner *s)
|
|||
STORE16L(cp, SANE_UNFIX (s->val[OPT_TL_Y].w) * pixels_per_mm + 0.5);
|
||||
STORE16L(cp, SANE_UNFIX (s->val[OPT_BR_X].w) * pixels_per_mm + 0.5);
|
||||
STORE16L(cp, SANE_UNFIX (s->val[OPT_BR_Y].w) * pixels_per_mm + 0.5);
|
||||
*cp++ = 0x14; /* what's this? */
|
||||
|
||||
/**cp++ = 0x14;*/ /* what's this? */
|
||||
DBG(5, "set_window_pro\n");
|
||||
|
||||
return dev_cmd (s, cmd, (cp - cmd), 0, 0);
|
||||
|
@ -1998,7 +1992,9 @@ calibration_pro (Mustek_Scanner *s)
|
|||
{
|
||||
SANE_Status status;
|
||||
|
||||
if (s->val[OPT_QUALITY_CAL].w)
|
||||
if (s->val[OPT_QUALITY_CAL].w && (!s->val[OPT_FAST_GRAY_MODE].w) &&
|
||||
!((s->mode & MUSTEK_MODE_COLOR) &&
|
||||
(strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)))
|
||||
DBG(4, "calibration_pro: doing calibration\n");
|
||||
else
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -2049,7 +2045,7 @@ get_calibration_lines_se (Mustek_Scanner *s)
|
|||
bytes_per_color = s->hw->cal.bytes;
|
||||
}
|
||||
|
||||
DBG(4, "read_calibration_lines_se: reading %d lines (% bytes per color)\n",
|
||||
DBG(4, "get_calibration_lines_se: reading %d lines (%d bytes per color)\n",
|
||||
lines, bytes_per_color);
|
||||
memset (cmd, 0, sizeof (cmd));
|
||||
cmd[0] = MUSTEK_SCSI_READ_DATA;
|
||||
|
@ -2162,6 +2158,7 @@ calibration_se (Mustek_Scanner *s)
|
|||
status = get_calibration_lines_se (s);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
|
||||
if (s->mode == MUSTEK_MODE_GRAY)
|
||||
status = send_calibration_lines_se (s, 0);
|
||||
else
|
||||
|
@ -2192,8 +2189,7 @@ send_gamma_table_se (Mustek_Scanner *s)
|
|||
gamma[0] = MUSTEK_SCSI_SEND_DATA;
|
||||
gamma[2] = 0x03; /* indicates gamma table */
|
||||
|
||||
if ((s->mode & MUSTEK_MODE_GRAY) || (s->mode & MUSTEK_MODE_COLOR)
|
||||
|| (s->mode & MUSTEK_MODE_COLOR_48))
|
||||
if ((s->mode & MUSTEK_MODE_GRAY) || (s->mode & MUSTEK_MODE_COLOR))
|
||||
{
|
||||
if (s->hw->gamma_length + sizeof (scsi_send_data) > sizeof (gamma))
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
@ -2201,8 +2197,7 @@ send_gamma_table_se (Mustek_Scanner *s)
|
|||
gamma[8] = (s->hw->gamma_length >> 0) & 0xff;
|
||||
|
||||
factor = s->hw->gamma_length / 256;
|
||||
color = (s->mode & MUSTEK_MODE_COLOR
|
||||
|| s->mode & MUSTEK_MODE_COLOR_48) ? 1 : 0;
|
||||
color = (s->mode & MUSTEK_MODE_COLOR) ? 1 : 0;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -2407,19 +2402,28 @@ mode_select_pro (Mustek_Scanner *s)
|
|||
mode[4] = 0x0d;
|
||||
|
||||
if (s->mode & MUSTEK_MODE_COLOR)
|
||||
mode[6] = 0x60;
|
||||
{
|
||||
if (strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)
|
||||
mode[6] = 0xE0;
|
||||
else
|
||||
mode[6] = 0x60;
|
||||
}
|
||||
else if (s->mode & MUSTEK_MODE_GRAY)
|
||||
mode[6] = 0x40;
|
||||
else if (s->mode & MUSTEK_MODE_GRAY_FAST)
|
||||
mode[6] = 0x20;
|
||||
{
|
||||
if (s->val[OPT_FAST_GRAY_MODE].w)
|
||||
mode[6] = 0x20;
|
||||
else
|
||||
mode[6] = 0x40;
|
||||
}
|
||||
else
|
||||
mode[6] = 0x00; /* lineart */
|
||||
|
||||
mode[11] = 0x00; /* what's this? */
|
||||
mode[16] = 0x41; /* what's this? */
|
||||
cp = mode + 17;
|
||||
STORE16L(cp, s->resolution_code);
|
||||
|
||||
DBG(5, "mode_select_pro: resolution_code=%d (0x%x), mode=0x%x\n",
|
||||
s->resolution_code, s->resolution_code, mode[6]);
|
||||
return dev_cmd (s, mode, 6 + mode[4], 0, 0);
|
||||
}
|
||||
|
||||
|
@ -2488,10 +2492,17 @@ gamma_correction (Mustek_Scanner *s, SANE_Int color_code)
|
|||
bytes_per_channel = 4096;
|
||||
len = bytes_per_channel;
|
||||
if (s->mode == MUSTEK_MODE_COLOR)
|
||||
gamma[9] = (color_code << 6); /* color */
|
||||
else if ((s->mode == MUSTEK_MODE_GRAY)
|
||||
|| (s->mode == MUSTEK_MODE_GRAY_FAST))
|
||||
gamma[9] = 0x80; /* grayscale */
|
||||
{
|
||||
gamma[9] = (color_code << 6); /* color */
|
||||
if (strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)
|
||||
gamma[2] = 0x7f; /* medium brightness */
|
||||
}
|
||||
else if (s->mode == MUSTEK_MODE_GRAY)
|
||||
{
|
||||
gamma[9] = 0x80; /* grayscale */
|
||||
if (s->val[OPT_FAST_GRAY_MODE].w)
|
||||
gamma[2] = 0x7f; /* medium brightness */
|
||||
}
|
||||
else /* lineart */
|
||||
{
|
||||
gamma[2] = 128 - 127 * SANE_UNFIX(s->val[OPT_BRIGHTNESS].w) / 100.0;
|
||||
|
@ -2919,6 +2930,9 @@ get_window (Mustek_Scanner *s, SANE_Int *bpl, SANE_Int *lines,
|
|||
res = s->resolution_code;
|
||||
half_res = SANE_UNFIX (s->hw->dpi_range.max) / 2;
|
||||
|
||||
DBG(5, "get_window: resolution: %d dpi (hardware: %d dpi)\n",
|
||||
res, s->ld.peak_res);
|
||||
|
||||
len = sizeof (result);
|
||||
status = dev_cmd (s, scsi_get_window, sizeof (scsi_get_window), result,
|
||||
&len);
|
||||
|
@ -2933,17 +2947,16 @@ get_window (Mustek_Scanner *s, SANE_Int *bpl, SANE_Int *lines,
|
|||
s->hw->cal.lines = (result[10] << 24) | (result[11] << 16) |
|
||||
(result[12] << 8) | (result[13] << 0);
|
||||
|
||||
DBG(4, "get_window: calib_bytes=%d, calib_lines=%d\n",
|
||||
DBG(4, "get_window: calibration bpl=%d, lines=%d\n",
|
||||
s->hw->cal.bytes, s->hw->cal.lines);
|
||||
|
||||
s->hw->bpl = (result[14] << 24) | (result[15] << 16) |
|
||||
(result[16] << 8) | result[17];
|
||||
if (s->mode & MUSTEK_MODE_COLOR_48)
|
||||
s->hw->bpl *= 2;
|
||||
|
||||
s->hw->lines = (result[18] << 24) | (result[19] << 16) |
|
||||
(result[20] << 8) | result[21];
|
||||
|
||||
DBG(4, "get_window: bytes_per_line=%d, lines=%d\n",
|
||||
DBG(4, "get_window: scan bpl=%d, lines=%d\n",
|
||||
s->hw->bpl, s->hw->lines);
|
||||
|
||||
if ((s->hw->cal.bytes == 0) || (s->hw->cal.lines == 0)
|
||||
|
@ -2957,7 +2970,7 @@ get_window (Mustek_Scanner *s, SANE_Int *bpl, SANE_Int *lines,
|
|||
s->hw->gamma_length = 1 << result[26];
|
||||
DBG(4, "get_window: gamma length=%d\n", s->hw->gamma_length);
|
||||
|
||||
if ((s->mode & MUSTEK_MODE_COLOR) || (s->mode & MUSTEK_MODE_COLOR_48))
|
||||
if (s->mode & MUSTEK_MODE_COLOR)
|
||||
{
|
||||
s->ld.buf[0] = NULL;
|
||||
for (color = 0; color < 3; ++color)
|
||||
|
@ -3482,32 +3495,105 @@ fix_line_distance_pro (Mustek_Scanner *s, SANE_Int num_lines, SANE_Int bpl,
|
|||
SANE_Byte *out_addr, *in_addr;
|
||||
SANE_Int res, half_res, y, x_out, x_in;
|
||||
|
||||
|
||||
res = SANE_UNFIX (s->val[OPT_RESOLUTION].w);
|
||||
half_res = SANE_UNFIX (s->hw->dpi_range.max) / 2;
|
||||
|
||||
DBG(5, "fix_line_distance_pro: res=%d; halfres=%d; num_lines=%d; bpl=%d\n",
|
||||
res, half_res, num_lines, bpl);
|
||||
|
||||
/* need to enlarge x-resolution? */
|
||||
if ((s->hw->flags & MUSTEK_FLAG_ENLARGE_X) && (res > half_res))
|
||||
if (strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)
|
||||
{
|
||||
DBG(5, "fix_line_distance_pro: res > half_res --> need to enlarge x\n");
|
||||
|
||||
for (y = 0; y < num_lines; y++)
|
||||
if ((s->hw->flags & MUSTEK_FLAG_ENLARGE_X) && (res > half_res))
|
||||
{
|
||||
for (x_out = 0; x_out < s->params.pixels_per_line; x_out++)
|
||||
{
|
||||
x_in = x_out * bpl / s->params.bytes_per_line;
|
||||
out_addr = out + y * s->params.bytes_per_line + x_out * 3;
|
||||
in_addr = raw + y * bpl + x_in * 3;
|
||||
*(out_addr) = *(in_addr);
|
||||
*(out_addr + 1) = *(in_addr + 1);
|
||||
*(out_addr + 2) = *(in_addr + 2);
|
||||
}
|
||||
/*12 bit, need to enlarge x-resolution */
|
||||
DBG(5, "fix_line_distance_pro: res > half_res --> need to "
|
||||
"enlarge x\n");
|
||||
if (little_endian ())
|
||||
for (y = 0; y < num_lines; y++)
|
||||
{
|
||||
for (x_out = 0; x_out < s->params.pixels_per_line; x_out++)
|
||||
{
|
||||
x_in = x_out * bpl / s->params.bytes_per_line / 2;
|
||||
x_in *= 2;
|
||||
out_addr = out + y * s->params.bytes_per_line + x_out * 6;
|
||||
in_addr = raw + y * bpl + x_in * 6;
|
||||
*(out_addr) = *(in_addr) << 4;
|
||||
*(out_addr + 1) = (*(in_addr) >> 4) +
|
||||
(*(in_addr + 1) << 4);
|
||||
*(out_addr + 2) = *(in_addr + 2) << 4;
|
||||
*(out_addr + 3) = (*(in_addr + 2) >> 4) +
|
||||
(*(in_addr + 3) << 4);
|
||||
*(out_addr + 4) = *(in_addr + 4) << 4;
|
||||
*(out_addr + 5) = (*(in_addr + 4) >> 4) +
|
||||
(*(in_addr + 5) << 4);
|
||||
}
|
||||
}
|
||||
else /* big endian */
|
||||
for (y = 0; y < num_lines; y++)
|
||||
{
|
||||
for (x_out = 0; x_out < s->params.pixels_per_line; x_out++)
|
||||
{
|
||||
x_in = x_out * bpl / s->params.bytes_per_line / 2;
|
||||
out_addr = out + y * s->params.bytes_per_line + x_out * 6;
|
||||
in_addr = raw + y * bpl + x_in * 6;
|
||||
*(out_addr) = (*(in_addr) >> 4) +
|
||||
(*(in_addr + 1) << 4);
|
||||
*(out_addr + 1) = *(in_addr) << 4;
|
||||
*(out_addr + 2) = (*(in_addr + 2) >> 4) +
|
||||
(*(in_addr + 3) << 4);
|
||||
*(out_addr + 3) = *(in_addr + 2) << 4;
|
||||
*(out_addr + 4) = (*(in_addr + 4) >> 4) +
|
||||
(*(in_addr + 5) << 4);
|
||||
*(out_addr + 5) = *(in_addr + 4) << 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* 12 bit, no need to enlarge x */
|
||||
{
|
||||
SANE_Word pixel;
|
||||
|
||||
if (little_endian ())
|
||||
for (pixel = 0; pixel < (num_lines * bpl / 2); pixel++)
|
||||
{
|
||||
*(out + pixel * 2) = *(raw + pixel * 2) << 4;
|
||||
*(out + pixel * 2 + 1) = (*(raw + pixel * 2) >> 4) +
|
||||
(*(raw + pixel * 2 + 1) << 4);
|
||||
}
|
||||
else /* big endian */
|
||||
for (pixel = 0; pixel < (num_lines * bpl / 2); pixel++)
|
||||
{
|
||||
*(out + pixel * 2) = (*(raw + pixel * 2) >> 4) +
|
||||
(*(raw + pixel * 2 + 1) << 4);
|
||||
*(out + pixel * 2 + 1) = *(raw + pixel * 2) << 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy (out, raw, num_lines * bpl);
|
||||
else /* 8 bit */
|
||||
{
|
||||
/* need to enlarge x-resolution? */
|
||||
if ((s->hw->flags & MUSTEK_FLAG_ENLARGE_X) && (res > half_res))
|
||||
{
|
||||
DBG(5, "fix_line_distance_pro: res > half_res --> need to "
|
||||
"enlarge x\n");
|
||||
|
||||
for (y = 0; y < num_lines; y++)
|
||||
{
|
||||
for (x_out = 0; x_out < s->params.pixels_per_line; x_out++)
|
||||
{
|
||||
x_in = x_out * bpl / s->params.bytes_per_line;
|
||||
out_addr = out + y * s->params.bytes_per_line + x_out * 3;
|
||||
in_addr = raw + y * bpl + x_in * 3;
|
||||
*(out_addr) = *(in_addr);
|
||||
*(out_addr + 1) = *(in_addr + 1);
|
||||
*(out_addr + 2) = *(in_addr + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy (out, raw, num_lines * bpl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3693,15 +3779,7 @@ init_options (Mustek_Scanner *s)
|
|||
s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
|
||||
s->opt[OPT_MODE].type = SANE_TYPE_STRING;
|
||||
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||
if (s->hw->flags & MUSTEK_FLAG_SE_PLUS)
|
||||
{
|
||||
s->opt[OPT_MODE].size = max_string_size (mode_list_se_plus);
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_list_se_plus;
|
||||
s->val[OPT_MODE].s = strdup (mode_list_se_plus[1]);
|
||||
if (!s->val[OPT_MODE].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else if (s->hw->flags & MUSTEK_FLAG_SE)
|
||||
if (s->hw->flags & MUSTEK_FLAG_SE)
|
||||
{
|
||||
s->opt[OPT_MODE].size = max_string_size (mode_list_se);
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_list_se;
|
||||
|
@ -3709,14 +3787,6 @@ init_options (Mustek_Scanner *s)
|
|||
if (!s->val[OPT_MODE].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else if (s->hw->flags & MUSTEK_FLAG_PRO)
|
||||
{
|
||||
s->opt[OPT_MODE].size = max_string_size (mode_list_pro);
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_list_pro;
|
||||
s->val[OPT_MODE].s = strdup (mode_list_pro[1]);
|
||||
if (!s->val[OPT_MODE].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->opt[OPT_MODE].size = max_string_size (mode_list_paragon);
|
||||
|
@ -3726,6 +3796,20 @@ init_options (Mustek_Scanner *s)
|
|||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
/* fast gray mode (pro models) */
|
||||
s->opt[OPT_FAST_GRAY_MODE].name = "fast-gray-mode";
|
||||
s->opt[OPT_FAST_GRAY_MODE].title = "Fast gray mode";
|
||||
s->opt[OPT_FAST_GRAY_MODE].desc = "Scan in fast gray mode (lower "
|
||||
"quality).";
|
||||
s->opt[OPT_FAST_GRAY_MODE].type = SANE_TYPE_BOOL;
|
||||
s->val[OPT_FAST_GRAY_MODE].w = SANE_FALSE;
|
||||
s->opt[OPT_FAST_GRAY_MODE].cap |= SANE_CAP_INACTIVE;
|
||||
if (s->hw->flags & MUSTEK_FLAG_PRO)
|
||||
{
|
||||
/* Only Pro models support fast gray mode */
|
||||
s->opt[OPT_FAST_GRAY_MODE].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/* resolution */
|
||||
s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
|
||||
s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
|
||||
|
@ -3736,6 +3820,19 @@ init_options (Mustek_Scanner *s)
|
|||
s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
|
||||
s->val[OPT_RESOLUTION].w = MAX(SANE_FIX(72), s->hw->dpi_range.min);
|
||||
|
||||
/* bit depth */
|
||||
s->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
|
||||
s->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
|
||||
s->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
|
||||
s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_STRING;
|
||||
s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_BIT_DEPTH].size = max_string_size (bit_depth_list_pro);
|
||||
s->opt[OPT_BIT_DEPTH].constraint.string_list = bit_depth_list_pro;
|
||||
s->val[OPT_BIT_DEPTH].s = strdup (bit_depth_list_pro[0]);
|
||||
if (!s->val[OPT_BIT_DEPTH].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
/* speed */
|
||||
s->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED;
|
||||
s->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED;
|
||||
|
@ -3747,6 +3844,11 @@ init_options (Mustek_Scanner *s)
|
|||
s->val[OPT_SPEED].s = strdup (speed_list[4]);
|
||||
if (!s->val[OPT_SPEED].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
if (!(s->hw->flags & MUSTEK_FLAG_THREE_PASS))
|
||||
{
|
||||
/* Speed only supported by 3-pass scanners */
|
||||
s->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/* source */
|
||||
s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
|
||||
|
@ -4020,6 +4122,11 @@ init_options (Mustek_Scanner *s)
|
|||
s->opt[OPT_QUALITY_CAL].type = SANE_TYPE_BOOL;
|
||||
s->val[OPT_QUALITY_CAL].w = SANE_FALSE;
|
||||
s->opt[OPT_QUALITY_CAL].cap |= SANE_CAP_INACTIVE;
|
||||
if ((s->hw->flags & MUSTEK_FLAG_PRO) || (s->hw->flags & MUSTEK_FLAG_SE_PLUS))
|
||||
{
|
||||
/* Only Pro and SE Plus models support calibration */
|
||||
s->opt[OPT_QUALITY_CAL].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/* halftone dimension */
|
||||
s->opt[OPT_HALFTONE_DIMENSION].name = SANE_NAME_HALFTONE_DIMENSION;
|
||||
|
@ -4045,17 +4152,7 @@ init_options (Mustek_Scanner *s)
|
|||
s->opt[OPT_HALFTONE_PATTERN].constraint.range = &u8_range;
|
||||
s->val[OPT_HALFTONE_PATTERN].wa = s->halftone_pattern;
|
||||
|
||||
if (!(s->hw->flags & MUSTEK_FLAG_THREE_PASS))
|
||||
{
|
||||
/* Speed only supported by 3-pass scanners */
|
||||
s->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
if ((s->hw->flags & MUSTEK_FLAG_PRO) || (s->hw->flags & MUSTEK_FLAG_SE_PLUS))
|
||||
{
|
||||
/* Pro and SE Plus models support calibration */
|
||||
s->opt[OPT_QUALITY_CAL].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -4087,7 +4184,7 @@ output_data (Mustek_Scanner *s, FILE *fp,
|
|||
data, lines_per_buffer, bpl, extra);
|
||||
|
||||
/* convert to pixel-interleaved format: */
|
||||
if (((s->mode & MUSTEK_MODE_COLOR) || (s->mode & MUSTEK_MODE_COLOR_48))
|
||||
if ((s->mode & MUSTEK_MODE_COLOR)
|
||||
&& !(s->hw->flags & MUSTEK_FLAG_THREE_PASS))
|
||||
{
|
||||
num_lines = lines_per_buffer;
|
||||
|
@ -4192,8 +4289,7 @@ output_data (Mustek_Scanner *s, FILE *fp,
|
|||
|
||||
while (enlarged_x < s->params.pixels_per_line)
|
||||
{
|
||||
if ((s->mode & MUSTEK_MODE_GRAY)
|
||||
|| (s->mode & MUSTEK_MODE_GRAY_FAST))
|
||||
if (s->mode & MUSTEK_MODE_GRAY)
|
||||
{
|
||||
fputc (*(data + y * bpl + x), fp);
|
||||
res_counter += half_res;
|
||||
|
@ -5087,6 +5183,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
case OPT_PREVIEW:
|
||||
case OPT_FAST_PREVIEW:
|
||||
case OPT_RESOLUTION:
|
||||
case OPT_FAST_GRAY_MODE:
|
||||
case OPT_TL_X:
|
||||
case OPT_TL_Y:
|
||||
case OPT_BR_X:
|
||||
|
@ -5118,6 +5215,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
case OPT_SPEED:
|
||||
case OPT_SOURCE:
|
||||
case OPT_MODE:
|
||||
case OPT_BIT_DEPTH:
|
||||
case OPT_HALFTONE_DIMENSION:
|
||||
strcpy (val, s->val[option].s);
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -5153,6 +5251,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
/* fall through */
|
||||
case OPT_PREVIEW:
|
||||
case OPT_FAST_PREVIEW:
|
||||
case OPT_FAST_GRAY_MODE:
|
||||
case OPT_BRIGHTNESS:
|
||||
case OPT_BRIGHTNESS_R:
|
||||
case OPT_BRIGHTNESS_G:
|
||||
|
@ -5184,8 +5283,24 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
/* options with side-effects: */
|
||||
/* side-effect-free string list options: */
|
||||
case OPT_BIT_DEPTH:
|
||||
{
|
||||
SANE_Char *old_val = s->val[option].s;
|
||||
|
||||
if (old_val)
|
||||
{
|
||||
if (strcmp (old_val, val) == 0)
|
||||
return SANE_STATUS_GOOD; /* no change */
|
||||
free (old_val);
|
||||
}
|
||||
s->val[option].s = strdup (val);
|
||||
if (!s->val[option].s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/* options with side-effects: */
|
||||
case OPT_CUSTOM_GAMMA:
|
||||
w = *(SANE_Word *) val;
|
||||
|
||||
|
@ -5200,11 +5315,9 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
{
|
||||
SANE_String_Const mode = s->val[OPT_MODE].s;
|
||||
|
||||
if ((strcmp (mode, "Gray") == 0)
|
||||
|| (strcmp (mode, "Gray fast") == 0))
|
||||
if (strcmp (mode, "Gray") == 0)
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
else if ((strcmp (mode, "Color") == 0)
|
||||
|| (strcmp (mode, "Color 48 bit") == 0))
|
||||
else if (strcmp (mode, "Color") == 0)
|
||||
{
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
|
||||
|
@ -5311,14 +5424,30 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
else if (s->hw->flags & MUSTEK_FLAG_PRO)
|
||||
{
|
||||
if (strcmp (s->val[OPT_MODE].s, "Gray") == 0)
|
||||
s->opt[OPT_FAST_GRAY_MODE].cap &= ~SANE_CAP_INACTIVE;
|
||||
else
|
||||
s->opt[OPT_FAST_GRAY_MODE].cap |= SANE_CAP_INACTIVE;
|
||||
if (strcmp (s->val[OPT_MODE].s, "Color") == 0)
|
||||
s->opt[OPT_BIT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
|
||||
else
|
||||
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
else if (s->hw->flags & MUSTEK_FLAG_SE_PLUS)
|
||||
{
|
||||
if (strcmp (s->val[OPT_MODE].s, "Color") == 0)
|
||||
s->opt[OPT_BIT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
|
||||
else
|
||||
s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
if (s->val[OPT_CUSTOM_GAMMA].w)
|
||||
{
|
||||
if ((strcmp (val, "Gray") == 0)
|
||||
|| (strcmp (val, "Gray fast") == 0))
|
||||
if (strcmp (val, "Gray") == 0)
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
else if ((strcmp (val, "Color") == 0)
|
||||
|| (strcmp (val, "Color 48 bit") == 0))
|
||||
else if (strcmp (val, "Color") == 0)
|
||||
{
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
|
||||
|
@ -5428,12 +5557,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
|
|||
s->params.bytes_per_line = s->params.pixels_per_line;
|
||||
s->params.depth = 8;
|
||||
}
|
||||
else if (strcmp (mode, "Gray fast") == 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... */
|
||||
|
@ -5446,17 +5569,17 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
|
|||
}
|
||||
else /* 1-pass */
|
||||
{
|
||||
s->params.format = SANE_FRAME_RGB;
|
||||
if (strcmp (mode, "Color") == 0)
|
||||
{
|
||||
s->params.bytes_per_line = 3 * s->params.pixels_per_line;
|
||||
s->params.depth = 8;
|
||||
}
|
||||
else
|
||||
if (strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)
|
||||
{
|
||||
s->params.bytes_per_line = 6 * s->params.pixels_per_line;
|
||||
s->params.depth = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->params.bytes_per_line = 3 * s->params.pixels_per_line;
|
||||
s->params.depth = 8;
|
||||
}
|
||||
s->params.format = SANE_FRAME_RGB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5513,15 +5636,16 @@ sane_start (SANE_Handle handle)
|
|||
s->mode = MUSTEK_MODE_HALFTONE;
|
||||
else if (strcmp (mode, "Gray") == 0)
|
||||
s->mode = MUSTEK_MODE_GRAY;
|
||||
else if (strcmp (mode, "Gray fast") == 0)
|
||||
s->mode = MUSTEK_MODE_GRAY_FAST;
|
||||
else if (strcmp (mode, "Color") == 0)
|
||||
s->mode = MUSTEK_MODE_COLOR;
|
||||
else if (strcmp (mode, "Color 48 bit") == 0)
|
||||
s->mode = MUSTEK_MODE_COLOR_48;
|
||||
|
||||
/* scanner dependant specials */
|
||||
if (s->hw->flags && MUSTEK_FLAG_PRO)
|
||||
{
|
||||
|
||||
}
|
||||
s->one_pass_color_scan = SANE_FALSE;
|
||||
if (((s->mode & MUSTEK_MODE_COLOR) || (s->mode & MUSTEK_MODE_COLOR_48))
|
||||
if ((s->mode & MUSTEK_MODE_COLOR)
|
||||
&& !(s->hw->flags & MUSTEK_FLAG_THREE_PASS))
|
||||
{
|
||||
s->one_pass_color_scan = SANE_TRUE;
|
||||
|
@ -5609,6 +5733,9 @@ sane_start (SANE_Handle handle)
|
|||
|
||||
s->scanning = SANE_TRUE;
|
||||
s->cancelled = SANE_FALSE;
|
||||
|
||||
dev_wait_ready (s);
|
||||
|
||||
status = get_window (s, &s->params.bytes_per_line,
|
||||
&s->params.lines, &s->params.pixels_per_line);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
|
@ -5631,7 +5758,6 @@ sane_start (SANE_Handle handle)
|
|||
goto stop_scanner_and_return;
|
||||
}
|
||||
|
||||
|
||||
else if (s->hw->flags & MUSTEK_FLAG_PRO)
|
||||
{
|
||||
|
||||
|
@ -5734,10 +5860,13 @@ sane_start (SANE_Handle handle)
|
|||
}
|
||||
|
||||
s->params.pixels_per_line = s->params.bytes_per_line;
|
||||
if (s->mode & MUSTEK_MODE_COLOR_48)
|
||||
s->params.pixels_per_line /= 2;
|
||||
if (s->one_pass_color_scan)
|
||||
s->params.pixels_per_line /= 3;
|
||||
{
|
||||
if (strcmp(s->val[OPT_BIT_DEPTH].s, "12") == 0)
|
||||
s->params.pixels_per_line /= 6;
|
||||
else
|
||||
s->params.pixels_per_line /= 3;
|
||||
}
|
||||
else if ((s->mode & MUSTEK_MODE_LINEART)
|
||||
|| (s->mode & MUSTEK_MODE_HALFTONE))
|
||||
s->params.pixels_per_line *= 8;
|
||||
|
|
Ładowanie…
Reference in New Issue