kopia lustrzana https://gitlab.com/sane-project/backends
Extensive changes to reduce the amount of global variables in mustek_usb2_high.c.
Might have made MustScanner_SetupScan less readable, though.merge-requests/1/head
rodzic
9444bf1156
commit
c1dc16d709
|
@ -117,10 +117,123 @@ static const Scanner_Model mustek_A2nu2_model = {
|
||||||
SANE_FIX (1.46 * MM_PER_INCH), /* size of scan area in TA mode in mm (x) */
|
SANE_FIX (1.46 * MM_PER_INCH), /* size of scan area in TA mode in mm (x) */
|
||||||
SANE_FIX (6.45 * MM_PER_INCH), /* size of scan area in TA mode in mm (y) */
|
SANE_FIX (6.45 * MM_PER_INCH), /* size of scan area in TA mode in mm (y) */
|
||||||
|
|
||||||
RO_RGB /* order of the CCD/CIS colors */
|
SANE_FALSE /* invert order of the CCD/CIS colors? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_target_image (Mustek_Scanner * s, TARGETIMAGE * pTarget)
|
||||||
|
{
|
||||||
|
SANE_String val, val_source;
|
||||||
|
float x1, y1, x2, y2;
|
||||||
|
|
||||||
|
DBG (DBG_FUNC, "get_target_image: start\n");
|
||||||
|
|
||||||
|
if (s->val[OPT_PREVIEW].w)
|
||||||
|
pTarget->wXDpi = 75;
|
||||||
|
else
|
||||||
|
pTarget->wXDpi = s->val[OPT_RESOLUTION].w;
|
||||||
|
pTarget->wYDpi = pTarget->wXDpi;
|
||||||
|
|
||||||
|
x1 = SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
|
||||||
|
y1 = SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
|
||||||
|
x2 = SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH;
|
||||||
|
y2 = SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH;
|
||||||
|
|
||||||
|
pTarget->wX = (unsigned short) ((x1 * pTarget->wXDpi) + 0.5);
|
||||||
|
pTarget->wY = (unsigned short) ((y1 * pTarget->wYDpi) + 0.5);
|
||||||
|
pTarget->wWidth = (unsigned short) (((x2 - x1) * pTarget->wXDpi) + 0.5);
|
||||||
|
pTarget->wHeight = (unsigned short) (((y2 - y1) * pTarget->wYDpi) + 0.5);
|
||||||
|
|
||||||
|
pTarget->wLineartThreshold = s->val[OPT_THRESHOLD].w;
|
||||||
|
|
||||||
|
val_source = s->val[OPT_SOURCE].s;
|
||||||
|
DBG (DBG_DET, "get_target_image: scan source = %s\n", val_source);
|
||||||
|
if (strcmp (val_source, source_list[SS_POSITIVE]) == 0)
|
||||||
|
pTarget->ssScanSource = SS_POSITIVE;
|
||||||
|
else if (strcmp (val_source, source_list[SS_NEGATIVE]) == 0)
|
||||||
|
pTarget->ssScanSource = SS_NEGATIVE;
|
||||||
|
else
|
||||||
|
pTarget->ssScanSource = SS_REFLECTIVE;
|
||||||
|
|
||||||
|
val = s->val[OPT_MODE].s;
|
||||||
|
if (strcmp (val, mode_list[CM_RGB48]) == 0)
|
||||||
|
{
|
||||||
|
if (s->val[OPT_PREVIEW].w)
|
||||||
|
{
|
||||||
|
DBG (DBG_DET, "get_target_image: preview, set ColorMode CM_RGB24\n");
|
||||||
|
pTarget->cmColorMode = CM_RGB24;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pTarget->cmColorMode = CM_RGB48;
|
||||||
|
}
|
||||||
|
else if (strcmp (val, mode_list[CM_RGB24]) == 0)
|
||||||
|
{
|
||||||
|
pTarget->cmColorMode = CM_RGB24;
|
||||||
|
}
|
||||||
|
else if (strcmp (val, mode_list[CM_GRAY16]) == 0)
|
||||||
|
{
|
||||||
|
if (s->val[OPT_PREVIEW].w)
|
||||||
|
{
|
||||||
|
DBG (DBG_DET, "get_target_image: preview, set ColorMode CM_GRAY8\n");
|
||||||
|
pTarget->cmColorMode = CM_GRAY8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pTarget->cmColorMode = CM_GRAY16;
|
||||||
|
}
|
||||||
|
else if (strcmp (val, mode_list[CM_GRAY8]) == 0)
|
||||||
|
{
|
||||||
|
pTarget->cmColorMode = CM_GRAY8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pTarget->cmColorMode = CM_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (DBG_FUNC, "get_target_image: exit\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
calc_parameters (TARGETIMAGE * pTarget, SANE_Parameters * params)
|
||||||
|
{
|
||||||
|
DBG (DBG_FUNC, "calc_parameters: start\n");
|
||||||
|
|
||||||
|
params->pixels_per_line = pTarget->wWidth;
|
||||||
|
params->lines = pTarget->wHeight;
|
||||||
|
params->last_frame = SANE_TRUE;
|
||||||
|
|
||||||
|
switch (pTarget->cmColorMode)
|
||||||
|
{
|
||||||
|
case CM_RGB48:
|
||||||
|
params->format = SANE_FRAME_RGB;
|
||||||
|
params->depth = 16;
|
||||||
|
params->bytes_per_line = params->pixels_per_line * 6;
|
||||||
|
break;
|
||||||
|
case CM_RGB24:
|
||||||
|
params->format = SANE_FRAME_RGB;
|
||||||
|
params->depth = 8;
|
||||||
|
params->bytes_per_line = params->pixels_per_line * 3;
|
||||||
|
break;
|
||||||
|
case CM_GRAY16:
|
||||||
|
params->format = SANE_FRAME_GRAY;
|
||||||
|
params->depth = 16;
|
||||||
|
params->bytes_per_line = params->pixels_per_line * 2;
|
||||||
|
break;
|
||||||
|
case CM_GRAY8:
|
||||||
|
params->format = SANE_FRAME_GRAY;
|
||||||
|
params->depth = 8;
|
||||||
|
params->bytes_per_line = params->pixels_per_line;
|
||||||
|
break;
|
||||||
|
case CM_TEXT:
|
||||||
|
params->format = SANE_FRAME_GRAY;
|
||||||
|
params->depth = 1;
|
||||||
|
params->bytes_per_line = params->pixels_per_line / 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (DBG_FUNC, "calc_parameters: exit\n");
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
max_string_size (SANE_String_Const *strings)
|
max_string_size (SANE_String_Const *strings)
|
||||||
{
|
{
|
||||||
|
@ -136,120 +249,12 @@ max_string_size (SANE_String_Const *strings)
|
||||||
return max_size;
|
return max_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
calc_parameters (Mustek_Scanner * s)
|
|
||||||
{
|
|
||||||
SANE_String val, val_source;
|
|
||||||
float x1, y1, x2, y2;
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "calc_parameters: start\n");
|
|
||||||
|
|
||||||
if (s->val[OPT_PREVIEW].w)
|
|
||||||
s->setpara.wDpi = 75;
|
|
||||||
else
|
|
||||||
s->setpara.wDpi = s->val[OPT_RESOLUTION].w;
|
|
||||||
|
|
||||||
x1 = SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
|
|
||||||
y1 = SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
|
|
||||||
x2 = SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH;
|
|
||||||
y2 = SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH;
|
|
||||||
|
|
||||||
s->setpara.wX = (unsigned short) ((x1 * s->setpara.wDpi) + 0.5);
|
|
||||||
s->setpara.wY = (unsigned short) ((y1 * s->setpara.wDpi) + 0.5);
|
|
||||||
s->setpara.wWidth = (unsigned short) (((x2 - x1) * s->setpara.wDpi) + 0.5);
|
|
||||||
s->setpara.wHeight = (unsigned short) (((y2 - y1) * s->setpara.wDpi) + 0.5);
|
|
||||||
|
|
||||||
s->setpara.wLineartThreshold = s->val[OPT_THRESHOLD].w;
|
|
||||||
|
|
||||||
val_source = s->val[OPT_SOURCE].s;
|
|
||||||
DBG (DBG_DET, "calc_parameters: scan source = %s\n", val_source);
|
|
||||||
if (strcmp (val_source, source_list[SS_POSITIVE]) == 0)
|
|
||||||
s->setpara.ssScanSource = SS_POSITIVE;
|
|
||||||
else if (strcmp (val_source, source_list[SS_NEGATIVE]) == 0)
|
|
||||||
s->setpara.ssScanSource = SS_NEGATIVE;
|
|
||||||
else
|
|
||||||
s->setpara.ssScanSource = SS_REFLECTIVE;
|
|
||||||
|
|
||||||
val = s->val[OPT_MODE].s;
|
|
||||||
if (strcmp (val, mode_list[CM_RGB48]) == 0)
|
|
||||||
{
|
|
||||||
if (s->val[OPT_PREVIEW].w)
|
|
||||||
{
|
|
||||||
DBG (DBG_DET, "calc_parameters: preview, set ColorMode CM_RGB24\n");
|
|
||||||
s->setpara.cmColorMode = CM_RGB24;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s->setpara.cmColorMode = CM_RGB48;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp (val, mode_list[CM_RGB24]) == 0)
|
|
||||||
{
|
|
||||||
s->setpara.cmColorMode = CM_RGB24;
|
|
||||||
}
|
|
||||||
else if (strcmp (val, mode_list[CM_GRAY16]) == 0)
|
|
||||||
{
|
|
||||||
if (s->val[OPT_PREVIEW].w)
|
|
||||||
{
|
|
||||||
DBG (DBG_DET, "calc_parameters: preview, set ColorMode CM_GRAY8\n");
|
|
||||||
s->setpara.cmColorMode = CM_GRAY8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s->setpara.cmColorMode = CM_GRAY16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp (val, mode_list[CM_GRAY8]) == 0)
|
|
||||||
{
|
|
||||||
s->setpara.cmColorMode = CM_GRAY8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s->setpara.cmColorMode = CM_TEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* provide an estimate for scan parameters returned by sane_get_parameters */
|
|
||||||
s->params.pixels_per_line = s->setpara.wWidth;
|
|
||||||
s->params.lines = s->setpara.wHeight;
|
|
||||||
s->params.last_frame = SANE_TRUE;
|
|
||||||
|
|
||||||
switch (s->setpara.cmColorMode)
|
|
||||||
{
|
|
||||||
case CM_RGB48:
|
|
||||||
s->params.format = SANE_FRAME_RGB;
|
|
||||||
s->params.depth = 16;
|
|
||||||
s->params.bytes_per_line = s->params.pixels_per_line * 6;
|
|
||||||
break;
|
|
||||||
case CM_RGB24:
|
|
||||||
s->params.format = SANE_FRAME_RGB;
|
|
||||||
s->params.depth = 8;
|
|
||||||
s->params.bytes_per_line = s->params.pixels_per_line * 3;
|
|
||||||
break;
|
|
||||||
case CM_GRAY16:
|
|
||||||
s->params.format = SANE_FRAME_GRAY;
|
|
||||||
s->params.depth = 16;
|
|
||||||
s->params.bytes_per_line = s->params.pixels_per_line * 2;
|
|
||||||
break;
|
|
||||||
case CM_GRAY8:
|
|
||||||
s->params.format = SANE_FRAME_GRAY;
|
|
||||||
s->params.depth = 8;
|
|
||||||
s->params.bytes_per_line = s->params.pixels_per_line;
|
|
||||||
break;
|
|
||||||
case CM_TEXT:
|
|
||||||
s->params.format = SANE_FRAME_GRAY;
|
|
||||||
s->params.depth = 1;
|
|
||||||
s->params.bytes_per_line = s->params.pixels_per_line / 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "calc_parameters: exit\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
init_options (Mustek_Scanner * s)
|
init_options (Mustek_Scanner * s)
|
||||||
{
|
{
|
||||||
SANE_Int option, count = 0;
|
SANE_Int option, count = 0;
|
||||||
SANE_Word *dpi_list;
|
SANE_Word *dpi_list;
|
||||||
|
TARGETIMAGE target;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "init_options: start\n");
|
DBG (DBG_FUNC, "init_options: start\n");
|
||||||
|
|
||||||
|
@ -401,40 +406,13 @@ init_options (Mustek_Scanner * s)
|
||||||
s->opt[OPT_BR_Y].constraint.range = &y_range;
|
s->opt[OPT_BR_Y].constraint.range = &y_range;
|
||||||
s->val[OPT_BR_Y].w = y_range.max;
|
s->val[OPT_BR_Y].w = y_range.max;
|
||||||
|
|
||||||
calc_parameters (s);
|
get_target_image (s, &target);
|
||||||
|
calc_parameters (&target, &s->params);
|
||||||
|
|
||||||
DBG (DBG_FUNC, "init_options: exit\n");
|
DBG (DBG_FUNC, "init_options: exit\n");
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SANE_Bool
|
|
||||||
ReadScannedData (IMAGEROWS * pImageRows, TARGETIMAGE * pTarget)
|
|
||||||
{
|
|
||||||
SANE_Bool isRGBInvert;
|
|
||||||
unsigned short Rows;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "ReadScannedData: start\n");
|
|
||||||
|
|
||||||
isRGBInvert = (pImageRows->roRgbOrder == RO_RGB) ? SANE_FALSE : SANE_TRUE;
|
|
||||||
Rows = pImageRows->wWantedLineNum;
|
|
||||||
DBG (DBG_INFO, "ReadScannedData: wanted rows = %d\n", Rows);
|
|
||||||
|
|
||||||
if (!MustScanner_GetRows (pImageRows->pBuffer, &Rows, isRGBInvert))
|
|
||||||
return SANE_FALSE;
|
|
||||||
pImageRows->wXferedLineNum = Rows;
|
|
||||||
|
|
||||||
if ((pTarget->cmColorMode == CM_TEXT) ||
|
|
||||||
(pTarget->ssScanSource == SS_NEGATIVE))
|
|
||||||
{
|
|
||||||
for (i = 0; i < (Rows * pTarget->dwBytesPerRow); i++)
|
|
||||||
pImageRows->pBuffer[i] ^= 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "ReadScannedData: exit\n");
|
|
||||||
return SANE_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************** SANE API functions ****************************/
|
/****************************** SANE API functions ****************************/
|
||||||
|
|
||||||
|
@ -564,6 +542,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
SANE_Status status;
|
SANE_Status status;
|
||||||
SANE_Word cap;
|
SANE_Word cap;
|
||||||
SANE_Int myinfo = 0;
|
SANE_Int myinfo = 0;
|
||||||
|
TARGETIMAGE target;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "sane_control_option: start: action = %s, option = %s (%d)\n",
|
DBG (DBG_FUNC, "sane_control_option: start: action = %s, option = %s (%d)\n",
|
||||||
(action == SANE_ACTION_GET_VALUE) ? "get" :
|
(action == SANE_ACTION_GET_VALUE) ? "get" :
|
||||||
|
@ -645,7 +624,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
case OPT_BR_X:
|
case OPT_BR_X:
|
||||||
case OPT_BR_Y:
|
case OPT_BR_Y:
|
||||||
s->val[option].w = *(SANE_Word *) val;
|
s->val[option].w = *(SANE_Word *) val;
|
||||||
calc_parameters (s);
|
get_target_image (s, &target);
|
||||||
|
calc_parameters (&target, &s->params);
|
||||||
myinfo |= SANE_INFO_RELOAD_PARAMS;
|
myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||||
break;
|
break;
|
||||||
case OPT_THRESHOLD:
|
case OPT_THRESHOLD:
|
||||||
|
@ -660,7 +640,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
|
s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
|
||||||
else
|
else
|
||||||
s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
|
s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
|
||||||
calc_parameters (s);
|
get_target_image (s, &target);
|
||||||
|
calc_parameters (&target, &s->params);
|
||||||
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||||
break;
|
break;
|
||||||
case OPT_SOURCE:
|
case OPT_SOURCE:
|
||||||
|
@ -740,6 +721,7 @@ SANE_Status
|
||||||
sane_start (SANE_Handle handle)
|
sane_start (SANE_Handle handle)
|
||||||
{
|
{
|
||||||
Mustek_Scanner *s = handle;
|
Mustek_Scanner *s = handle;
|
||||||
|
TARGETIMAGE target;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "sane_start: start\n");
|
DBG (DBG_FUNC, "sane_start: start\n");
|
||||||
|
|
||||||
|
@ -750,29 +732,26 @@ sane_start (SANE_Handle handle)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_parameters (s);
|
get_target_image (s, &target);
|
||||||
|
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wX=%d\n", s->setpara.wX);
|
DBG (DBG_INFO, "sane_start: target.wX=%d\n", target.wX);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wY=%d\n", s->setpara.wY);
|
DBG (DBG_INFO, "sane_start: target.wY=%d\n", target.wY);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wWidth=%d\n", s->setpara.wWidth);
|
DBG (DBG_INFO, "sane_start: target.wWidth=%d\n", target.wWidth);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wHeight=%d\n", s->setpara.wHeight);
|
DBG (DBG_INFO, "sane_start: target.wHeight=%d\n", target.wHeight);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wLineartThreshold=%d\n",
|
DBG (DBG_INFO, "sane_start: target.wLineartThreshold=%d\n",
|
||||||
s->setpara.wLineartThreshold);
|
target.wLineartThreshold);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.wDpi=%d\n", s->setpara.wDpi);
|
DBG (DBG_INFO, "sane_start: target.wXDpi=%d\n", target.wXDpi);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.cmColorMode=%d\n",
|
DBG (DBG_INFO, "sane_start: target.wYDpi=%d\n", target.wYDpi);
|
||||||
s->setpara.cmColorMode);
|
DBG (DBG_INFO, "sane_start: target.cmColorMode=%d\n", target.cmColorMode);
|
||||||
DBG (DBG_INFO, "sane_start: setpara.ssScanSource=%d\n",
|
DBG (DBG_INFO, "sane_start: target.ssScanSource=%d\n", target.ssScanSource);
|
||||||
s->setpara.ssScanSource);
|
|
||||||
|
|
||||||
MustScanner_Reset ();
|
MustScanner_Reset ();
|
||||||
|
|
||||||
/* adjust parameters to the scanner's requirements */
|
/* adjust parameters to the scanner's requirements */
|
||||||
MustScanner_ScanSuggest (&s->setpara);
|
MustScanner_ScanSuggest (&target);
|
||||||
|
calc_parameters (&target, &s->params);
|
||||||
/* update the scan parameters to be returned by sane_get_parameters */
|
s->bInvertImage = ((target.cmColorMode == CM_TEXT) ^
|
||||||
s->params.pixels_per_line = s->setpara.wWidth;
|
(target.ssScanSource == SS_NEGATIVE));
|
||||||
s->params.lines = s->setpara.wHeight;
|
|
||||||
s->params.bytes_per_line = s->setpara.dwBytesPerRow;
|
|
||||||
|
|
||||||
s->read_rows = s->params.lines;
|
s->read_rows = s->params.lines;
|
||||||
DBG (DBG_INFO, "sane_start: read_rows = %d\n", s->read_rows);
|
DBG (DBG_INFO, "sane_start: read_rows = %d\n", s->read_rows);
|
||||||
|
@ -787,7 +766,7 @@ sane_start (SANE_Handle handle)
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
s->scan_buf_len = 0;
|
s->scan_buf_len = 0;
|
||||||
|
|
||||||
if (!MustScanner_SetupScan (&s->setpara))
|
if (!MustScanner_SetupScan (&target))
|
||||||
return SANE_STATUS_INVAL;
|
return SANE_STATUS_INVAL;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "sane_start: exit\n");
|
DBG (DBG_FUNC, "sane_start: exit\n");
|
||||||
|
@ -801,8 +780,9 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
Mustek_Scanner *s = handle;
|
Mustek_Scanner *s = handle;
|
||||||
SANE_Byte *tempbuf;
|
SANE_Byte *tempbuf;
|
||||||
long int tempbuf_size;
|
long int tempbuf_size;
|
||||||
SANE_Int lines_to_read, lines_read;
|
SANE_Int lines, lines_read;
|
||||||
IMAGEROWS image_row;
|
unsigned short lines_received;
|
||||||
|
int i;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "sane_read: start: max_len=%d\n", max_len);
|
DBG (DBG_FUNC, "sane_read: start: max_len=%d\n", max_len);
|
||||||
|
|
||||||
|
@ -826,33 +806,34 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
{
|
{
|
||||||
if (s->read_rows > 0)
|
if (s->read_rows > 0)
|
||||||
{
|
{
|
||||||
lines_to_read = SCAN_BUFFER_SIZE / s->setpara.dwBytesPerRow;
|
lines = SCAN_BUFFER_SIZE / s->params.bytes_per_line;
|
||||||
if (lines_to_read > s->read_rows)
|
lines = _MIN (lines, s->read_rows);
|
||||||
lines_to_read = s->read_rows;
|
|
||||||
|
|
||||||
tempbuf_size = lines_to_read * s->setpara.dwBytesPerRow +
|
tempbuf_size = lines * s->params.bytes_per_line + 3 * 1024 + 1;
|
||||||
3 * 1024 + 1;
|
|
||||||
tempbuf = malloc (tempbuf_size);
|
tempbuf = malloc (tempbuf_size);
|
||||||
if (!tempbuf)
|
if (!tempbuf)
|
||||||
return SANE_STATUS_NO_MEM;
|
return SANE_STATUS_NO_MEM;
|
||||||
memset (tempbuf, 0, tempbuf_size);
|
memset (tempbuf, 0, tempbuf_size);
|
||||||
DBG (DBG_INFO, "sane_read: buffer size is %ld\n", tempbuf_size);
|
DBG (DBG_INFO, "sane_read: buffer size is %ld\n", tempbuf_size);
|
||||||
|
|
||||||
image_row.roRgbOrder = s->model.line_mode_color_order;
|
|
||||||
image_row.wWantedLineNum = lines_to_read;
|
|
||||||
image_row.pBuffer = tempbuf;
|
|
||||||
s->bIsReading = SANE_TRUE;
|
s->bIsReading = SANE_TRUE;
|
||||||
|
lines_received = (unsigned short) lines;
|
||||||
if (!ReadScannedData (&image_row, &s->setpara))
|
if (!MustScanner_GetRows (tempbuf, &lines_received,
|
||||||
|
s->model.isRGBInvert))
|
||||||
{
|
{
|
||||||
DBG (DBG_ERR, "sane_read: ReadScannedData error\n");
|
DBG (DBG_ERR, "sane_read: MustScanner_GetRows error\n");
|
||||||
s->bIsReading = SANE_FALSE;
|
s->bIsReading = SANE_FALSE;
|
||||||
return SANE_STATUS_INVAL;
|
return SANE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->bInvertImage)
|
||||||
|
{
|
||||||
|
for (i = 0; i < (lines_received * s->params.bytes_per_line); i++)
|
||||||
|
tempbuf[i] ^= 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
DBG (DBG_DBG, "sane_read: Finish ReadScanedData\n");
|
DBG (DBG_DBG, "sane_read: Finish ReadScanedData\n");
|
||||||
s->scan_buf_len =
|
s->scan_buf_len = lines_received * s->params.bytes_per_line;
|
||||||
image_row.wXferedLineNum * s->setpara.dwBytesPerRow;
|
|
||||||
DBG (DBG_INFO, "sane_read : s->scan_buf_len = %ld\n",
|
DBG (DBG_INFO, "sane_read : s->scan_buf_len = %ld\n",
|
||||||
(long int) s->scan_buf_len);
|
(long int) s->scan_buf_len);
|
||||||
|
|
||||||
|
@ -866,7 +847,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
DBG (DBG_DBG, "sane_read: after memcpy\n");
|
DBG (DBG_DBG, "sane_read: after memcpy\n");
|
||||||
free (tempbuf);
|
free (tempbuf);
|
||||||
s->scan_buf_start = s->scan_buf;
|
s->scan_buf_start = s->scan_buf;
|
||||||
s->read_rows -= image_row.wXferedLineNum;
|
s->read_rows -= lines_received;
|
||||||
s->bIsReading = SANE_FALSE;
|
s->bIsReading = SANE_FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -882,17 +863,14 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lines_read = _MIN (max_len, (SANE_Int) s->scan_buf_len);
|
lines_read = _MIN (max_len, s->scan_buf_len);
|
||||||
DBG (DBG_DBG, "sane_read: after %d\n", lines_read);
|
DBG (DBG_DBG, "sane_read: after %d\n", lines_read);
|
||||||
|
*len = lines_read;
|
||||||
|
|
||||||
*len = (SANE_Int) lines_read;
|
|
||||||
|
|
||||||
DBG (DBG_INFO, "sane_read: get lines_read = %d\n", lines_read);
|
|
||||||
DBG (DBG_INFO, "sane_read: get *len = %d\n", *len);
|
|
||||||
memcpy (buf, s->scan_buf_start, lines_read);
|
memcpy (buf, s->scan_buf_start, lines_read);
|
||||||
|
|
||||||
s->scan_buf_len -= lines_read;
|
s->scan_buf_len -= lines_read;
|
||||||
s->scan_buf_start += lines_read;
|
s->scan_buf_start += lines_read;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "sane_read: exit\n");
|
DBG (DBG_FUNC, "sane_read: exit\n");
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
@ -932,7 +910,6 @@ sane_cancel (SANE_Handle handle)
|
||||||
|
|
||||||
s->read_rows = 0;
|
s->read_rows = 0;
|
||||||
s->scan_buf_len = 0;
|
s->scan_buf_len = 0;
|
||||||
memset (&s->setpara, 0, sizeof (s->setpara));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,20 +79,6 @@ enum
|
||||||
NUM_OPTIONS
|
NUM_OPTIONS
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
RO_RGB,
|
|
||||||
RO_BGR
|
|
||||||
} RGBORDER;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
RGBORDER roRgbOrder;
|
|
||||||
unsigned short wWantedLineNum;
|
|
||||||
unsigned short wXferedLineNum;
|
|
||||||
SANE_Byte * pBuffer;
|
|
||||||
} IMAGEROWS;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -113,7 +99,8 @@ typedef struct
|
||||||
SANE_Fixed x_size_ta; /* size of scan area in TA mode in mm */
|
SANE_Fixed x_size_ta; /* size of scan area in TA mode in mm */
|
||||||
SANE_Fixed y_size_ta;
|
SANE_Fixed y_size_ta;
|
||||||
|
|
||||||
RGBORDER line_mode_color_order; /* order of the CCD/CIS colors */
|
SANE_Bool isRGBInvert; /* order of the CCD/CIS colors:
|
||||||
|
RGB if SANE_False, BGR otherwise */
|
||||||
/*@} */
|
/*@} */
|
||||||
} Scanner_Model;
|
} Scanner_Model;
|
||||||
|
|
||||||
|
@ -125,13 +112,13 @@ typedef struct Mustek_Scanner
|
||||||
Option_Value val[NUM_OPTIONS];
|
Option_Value val[NUM_OPTIONS];
|
||||||
SANE_Parameters params;
|
SANE_Parameters params;
|
||||||
Scanner_Model model;
|
Scanner_Model model;
|
||||||
TARGETIMAGE setpara;
|
|
||||||
SANE_Bool bIsScanning;
|
SANE_Bool bIsScanning;
|
||||||
SANE_Bool bIsReading;
|
SANE_Bool bIsReading;
|
||||||
|
SANE_Bool bInvertImage;
|
||||||
SANE_Word read_rows; /* number of image lines left to read */
|
SANE_Word read_rows; /* number of image lines left to read */
|
||||||
SANE_Byte * scan_buf;
|
SANE_Byte * scan_buf;
|
||||||
SANE_Byte * scan_buf_start;
|
SANE_Byte * scan_buf_start;
|
||||||
size_t scan_buf_len;
|
SANE_Int scan_buf_len;
|
||||||
} Mustek_Scanner;
|
} Mustek_Scanner;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,55 +59,38 @@
|
||||||
|
|
||||||
#include "mustek_usb2_high.h"
|
#include "mustek_usb2_high.h"
|
||||||
|
|
||||||
|
|
||||||
/* HOLD: these global variables should go to scanner structure */
|
/* HOLD: these global variables should go to scanner structure */
|
||||||
|
|
||||||
static SANE_Bool g_bOpened;
|
static SANE_Bool g_bOpened;
|
||||||
static SANE_Bool g_bPrepared;
|
static SANE_Bool g_bPrepared;
|
||||||
static SANE_Bool g_isCanceled;
|
static SANE_Bool g_isCanceled;
|
||||||
static SANE_Bool g_bFirstReadImage;
|
static SANE_Bool g_bFirstReadImage;
|
||||||
|
|
||||||
static SANE_Byte * g_pReadImageHead;
|
static SANE_Byte * g_pReadImageHead;
|
||||||
|
|
||||||
static unsigned short g_X;
|
static TARGETIMAGE g_Target;
|
||||||
static unsigned short g_Y;
|
|
||||||
static unsigned short g_Width;
|
|
||||||
static unsigned short g_Height;
|
|
||||||
static unsigned short g_XDpi;
|
|
||||||
static unsigned short g_YDpi;
|
|
||||||
static unsigned short g_SWWidth;
|
static unsigned short g_SWWidth;
|
||||||
static unsigned short g_SWHeight;
|
static unsigned short g_SWHeight;
|
||||||
static unsigned short g_wPixelDistance; /* even & odd sensor problem */
|
|
||||||
|
/* even & odd sensor problem */
|
||||||
|
static unsigned short g_wPixelDistance;
|
||||||
static unsigned short g_wLineDistance;
|
static unsigned short g_wLineDistance;
|
||||||
static unsigned short g_wScanLinesPerBlock;
|
static unsigned short g_wScanLinesPerBlock;
|
||||||
static unsigned short g_wLineartThreshold;
|
|
||||||
|
|
||||||
static unsigned int g_wtheReadyLines;
|
static unsigned int g_wtheReadyLines;
|
||||||
static unsigned int g_wMaxScanLines;
|
static unsigned int g_wMaxScanLines;
|
||||||
static unsigned int g_dwScannedTotalLines;
|
static unsigned int g_dwScannedTotalLines;
|
||||||
static unsigned int g_BytesPerRow;
|
static unsigned int g_BytesPerRow;
|
||||||
static unsigned int g_SWBytesPerRow;
|
static unsigned int g_SWBytesPerRow;
|
||||||
|
|
||||||
static unsigned int g_dwTotalTotalXferLines;
|
static unsigned int g_dwTotalTotalXferLines;
|
||||||
|
|
||||||
static unsigned short * g_pGammaTable;
|
|
||||||
|
|
||||||
static pthread_t g_threadid_readimage;
|
static pthread_t g_threadid_readimage;
|
||||||
|
|
||||||
static COLORMODE g_ScanMode;
|
|
||||||
static SCANSOURCE g_ssScanSource;
|
|
||||||
|
|
||||||
static ASIC g_chip;
|
|
||||||
|
|
||||||
static int g_nSecLength, g_nDarkSecLength;
|
|
||||||
static int g_nSecNum, g_nDarkSecNum;
|
|
||||||
static unsigned short g_wCalWidth;
|
|
||||||
static unsigned short g_wDarkCalWidth;
|
|
||||||
static int g_nPowerNum;
|
|
||||||
static unsigned short g_wStartPosition;
|
|
||||||
|
|
||||||
static pthread_mutex_t g_scannedLinesMutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t g_scannedLinesMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t g_readyLinesMutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t g_readyLinesMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static unsigned short * g_pGammaTable;
|
||||||
|
static ASIC g_chip;
|
||||||
|
|
||||||
/* for modifying the last point */
|
/* for modifying the last point */
|
||||||
static SANE_Bool g_bIsFirstReadBefData = SANE_TRUE;
|
static SANE_Bool g_bIsFirstReadBefData = SANE_TRUE;
|
||||||
static SANE_Byte * g_pBefLineImageData;
|
static SANE_Byte * g_pBefLineImageData;
|
||||||
|
@ -129,8 +112,6 @@ MustScanner_Init (void)
|
||||||
|
|
||||||
g_pGammaTable = NULL;
|
g_pGammaTable = NULL;
|
||||||
|
|
||||||
g_ssScanSource = SS_REFLECTIVE;
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_Init: leave MustScanner_Init\n");
|
DBG (DBG_FUNC, "MustScanner_Init: leave MustScanner_Init\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +331,7 @@ GetRgb48BitLineFull (SANE_Byte * pLine, SANE_Bool isOrderInvert)
|
||||||
unsigned int dwRTempData, dwGTempData, dwBTempData;
|
unsigned int dwRTempData, dwGTempData, dwBTempData;
|
||||||
unsigned short i = 0;
|
unsigned short i = 0;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wRLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
wRLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
||||||
wGLinePosOdd = g_wtheReadyLines - g_wLineDistance - g_wPixelDistance;
|
wGLinePosOdd = g_wtheReadyLines - g_wLineDistance - g_wPixelDistance;
|
||||||
|
@ -490,7 +471,7 @@ GetRgb24BitLineFull (SANE_Byte * pLine, SANE_Bool isOrderInvert)
|
||||||
unsigned short tempR, tempG, tempB;
|
unsigned short tempR, tempG, tempB;
|
||||||
unsigned short i = 0;
|
unsigned short i = 0;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wRLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
wRLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
||||||
wGLinePosOdd = g_wtheReadyLines - g_wLineDistance - g_wPixelDistance;
|
wGLinePosOdd = g_wtheReadyLines - g_wLineDistance - g_wPixelDistance;
|
||||||
|
@ -588,7 +569,7 @@ GetMono16BitLineFull (SANE_Byte * pLine,
|
||||||
unsigned short wLinePosEven;
|
unsigned short wLinePosEven;
|
||||||
unsigned short i = 0;
|
unsigned short i = 0;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
wLinePosOdd = g_wtheReadyLines - g_wPixelDistance;
|
||||||
wLinePosEven = g_wtheReadyLines;
|
wLinePosEven = g_wtheReadyLines;
|
||||||
|
@ -660,7 +641,7 @@ GetMono8BitLineFull (SANE_Byte * pLine,
|
||||||
unsigned short wGray;
|
unsigned short wGray;
|
||||||
unsigned short i = 0;
|
unsigned short i = 0;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wLinePosOdd = (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
|
wLinePosOdd = (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
|
||||||
wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
|
wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
|
||||||
|
@ -705,7 +686,7 @@ GetMono1BitLineHalf (SANE_Byte * pLine,
|
||||||
|
|
||||||
for (i = 0; i < g_SWWidth; i++)
|
for (i = 0; i < g_SWWidth; i++)
|
||||||
{
|
{
|
||||||
if (g_pReadImageHead[wLinePos + i] > g_wLineartThreshold)
|
if (g_pReadImageHead[wLinePos + i] > g_Target.wLineartThreshold)
|
||||||
pLine[i / 8] |= 0x80 >> (i % 8);
|
pLine[i / 8] |= 0x80 >> (i % 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -718,7 +699,7 @@ GetMono1BitLineFull (SANE_Byte * pLine,
|
||||||
unsigned short wLinePosEven;
|
unsigned short wLinePosEven;
|
||||||
unsigned short i = 0;
|
unsigned short i = 0;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wLinePosOdd = (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
|
wLinePosOdd = (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
|
||||||
wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
|
wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
|
||||||
|
@ -736,11 +717,11 @@ GetMono1BitLineFull (SANE_Byte * pLine,
|
||||||
if ((i + 1) >= g_SWWidth)
|
if ((i + 1) >= g_SWWidth)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (g_pReadImageHead[wLinePosOdd + i] > g_wLineartThreshold)
|
if (g_pReadImageHead[wLinePosOdd + i] > g_Target.wLineartThreshold)
|
||||||
pLine[i / 8] |= 0x80 >> (i % 8);
|
pLine[i / 8] |= 0x80 >> (i % 8);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (g_pReadImageHead[wLinePosEven + i] > g_wLineartThreshold)
|
if (g_pReadImageHead[wLinePosEven + i] > g_Target.wLineartThreshold)
|
||||||
pLine[i / 8] |= 0x80 >> (i % 8);
|
pLine[i / 8] |= 0x80 >> (i % 8);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -822,7 +803,7 @@ static void *
|
||||||
MustScanner_ReadDataFromScanner (void __sane_unused__ * dummy)
|
MustScanner_ReadDataFromScanner (void __sane_unused__ * dummy)
|
||||||
{
|
{
|
||||||
unsigned short wTotalReadImageLines = 0;
|
unsigned short wTotalReadImageLines = 0;
|
||||||
unsigned short wWantedLines = g_Height;
|
unsigned short wWantedLines = g_Target.wHeight;
|
||||||
SANE_Byte * pReadImage = g_pReadImageHead;
|
SANE_Byte * pReadImage = g_pReadImageHead;
|
||||||
SANE_Bool isWaitImageLineDiff = SANE_FALSE;
|
SANE_Bool isWaitImageLineDiff = SANE_FALSE;
|
||||||
unsigned int wMaxScanLines = g_wMaxScanLines;
|
unsigned int wMaxScanLines = g_wMaxScanLines;
|
||||||
|
@ -996,24 +977,24 @@ MustScanner_GetRows (SANE_Byte * pBlock, unsigned short * Rows,
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (g_ScanMode)
|
switch (g_Target.cmColorMode)
|
||||||
{
|
{
|
||||||
case CM_RGB48:
|
case CM_RGB48:
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
pFunc = GetRgb48BitLineFull;
|
pFunc = GetRgb48BitLineFull;
|
||||||
else
|
else
|
||||||
pFunc = GetRgb48BitLineHalf;
|
pFunc = GetRgb48BitLineHalf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CM_RGB24:
|
case CM_RGB24:
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
pFunc = GetRgb24BitLineFull;
|
pFunc = GetRgb24BitLineFull;
|
||||||
else
|
else
|
||||||
pFunc = GetRgb24BitLineHalf;
|
pFunc = GetRgb24BitLineHalf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CM_GRAY16:
|
case CM_GRAY16:
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
{
|
{
|
||||||
fixEvenOdd = SANE_TRUE;
|
fixEvenOdd = SANE_TRUE;
|
||||||
pFunc = GetMono16BitLineFull;
|
pFunc = GetMono16BitLineFull;
|
||||||
|
@ -1025,7 +1006,7 @@ MustScanner_GetRows (SANE_Byte * pBlock, unsigned short * Rows,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CM_GRAY8:
|
case CM_GRAY8:
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
{
|
{
|
||||||
fixEvenOdd = SANE_TRUE;
|
fixEvenOdd = SANE_TRUE;
|
||||||
pFunc = GetMono8BitLineFull;
|
pFunc = GetMono8BitLineFull;
|
||||||
|
@ -1039,7 +1020,7 @@ MustScanner_GetRows (SANE_Byte * pBlock, unsigned short * Rows,
|
||||||
case CM_TEXT:
|
case CM_TEXT:
|
||||||
memset (pBlock, 0, *Rows * g_SWWidth / 8);
|
memset (pBlock, 0, *Rows * g_SWWidth / 8);
|
||||||
dwLineIncrement /= 8;
|
dwLineIncrement /= 8;
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
pFunc = GetMono1BitLineFull;
|
pFunc = GetMono1BitLineFull;
|
||||||
else
|
else
|
||||||
pFunc = GetMono1BitLineHalf;
|
pFunc = GetMono1BitLineHalf;
|
||||||
|
@ -1059,8 +1040,8 @@ MustScanner_ScanSuggest (TARGETIMAGE * pTarget)
|
||||||
DBG (DBG_FUNC, "MustScanner_ScanSuggest: call in\n");
|
DBG (DBG_FUNC, "MustScanner_ScanSuggest: call in\n");
|
||||||
|
|
||||||
/* check width and height */
|
/* check width and height */
|
||||||
wMaxWidth = (MAX_SCANNING_WIDTH * pTarget->wDpi) / 300;
|
wMaxWidth = (MAX_SCANNING_WIDTH * pTarget->wXDpi) / 300;
|
||||||
wMaxHeight = (MAX_SCANNING_HEIGHT * pTarget->wDpi) / 300;
|
wMaxHeight = (MAX_SCANNING_HEIGHT * pTarget->wYDpi) / 300;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_ScanSuggest: wMaxWidth = %d\n", wMaxWidth);
|
DBG (DBG_FUNC, "MustScanner_ScanSuggest: wMaxWidth = %d\n", wMaxWidth);
|
||||||
DBG (DBG_FUNC, "MustScanner_ScanSuggest: wMaxHeight = %d\n", wMaxHeight);
|
DBG (DBG_FUNC, "MustScanner_ScanSuggest: wMaxHeight = %d\n", wMaxHeight);
|
||||||
|
@ -1068,27 +1049,6 @@ MustScanner_ScanSuggest (TARGETIMAGE * pTarget)
|
||||||
pTarget->wWidth = _MIN (pTarget->wWidth, wMaxWidth);
|
pTarget->wWidth = _MIN (pTarget->wWidth, wMaxWidth);
|
||||||
pTarget->wHeight = _MIN (pTarget->wHeight, wMaxHeight);
|
pTarget->wHeight = _MIN (pTarget->wHeight, wMaxHeight);
|
||||||
|
|
||||||
switch (pTarget->cmColorMode)
|
|
||||||
{
|
|
||||||
case CM_RGB48:
|
|
||||||
pTarget->dwBytesPerRow = (unsigned int) pTarget->wWidth * 6;
|
|
||||||
break;
|
|
||||||
case CM_RGB24:
|
|
||||||
pTarget->dwBytesPerRow = (unsigned int) pTarget->wWidth * 3;
|
|
||||||
break;
|
|
||||||
case CM_GRAY16:
|
|
||||||
pTarget->dwBytesPerRow = (unsigned int) pTarget->wWidth * 2;
|
|
||||||
break;
|
|
||||||
case CM_GRAY8:
|
|
||||||
pTarget->dwBytesPerRow = (unsigned int) pTarget->wWidth;
|
|
||||||
break;
|
|
||||||
case CM_TEXT:
|
|
||||||
pTarget->dwBytesPerRow = (unsigned int) pTarget->wWidth / 8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DBG (DBG_FUNC, "MustScanner_ScanSuggest: pTarget->dwBytesPerRow = %d\n",
|
|
||||||
pTarget->dwBytesPerRow);
|
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_ScanSuggest: leave MustScanner_ScanSuggest\n");
|
DBG (DBG_FUNC, "MustScanner_ScanSuggest: leave MustScanner_ScanSuggest\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1106,7 @@ MustScanner_PrepareScan (void)
|
||||||
g_wScanLinesPerBlock) * g_wScanLinesPerBlock;
|
g_wScanLinesPerBlock) * g_wScanLinesPerBlock;
|
||||||
g_dwScannedTotalLines = 0;
|
g_dwScannedTotalLines = 0;
|
||||||
|
|
||||||
switch (g_ScanMode)
|
switch (g_Target.cmColorMode)
|
||||||
{
|
{
|
||||||
case CM_RGB48:
|
case CM_RGB48:
|
||||||
case CM_RGB24:
|
case CM_RGB24:
|
||||||
|
@ -1201,90 +1161,96 @@ MustScanner_Reset (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MustScanner_PrepareCalculateMaxMin (unsigned short wResolution)
|
MustScanner_PrepareCalculateMaxMin (unsigned short wResolution,
|
||||||
|
CALIBRATIONPARAM * pCalParam)
|
||||||
{
|
{
|
||||||
g_wDarkCalWidth = 52;
|
unsigned short wCalWidth, wDarkCalWidth;
|
||||||
|
|
||||||
|
wDarkCalWidth = 52;
|
||||||
if (wResolution <= (SENSOR_DPI / 2))
|
if (wResolution <= (SENSOR_DPI / 2))
|
||||||
{
|
{
|
||||||
g_wCalWidth = (5120 * wResolution / (SENSOR_DPI / 2) + 511) & ~511;
|
wCalWidth = (5120 * wResolution / (SENSOR_DPI / 2) + 511) & ~511;
|
||||||
g_wDarkCalWidth *= wResolution / SENSOR_DPI;
|
wDarkCalWidth *= wResolution / SENSOR_DPI;
|
||||||
|
|
||||||
if (wResolution < 200)
|
if (wResolution < 200)
|
||||||
{
|
{
|
||||||
g_nPowerNum = 3;
|
pCalParam->nPowerNum = 3;
|
||||||
g_nSecLength = 8; /* 2^nPowerNum */
|
pCalParam->nSecLength = 8; /* 2^nPowerNum */
|
||||||
/* dark has at least 2 sections */
|
/* dark has at least 2 sections */
|
||||||
g_nDarkSecLength = g_wDarkCalWidth / 2;
|
pCalParam->nDarkSecLength = wDarkCalWidth / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_nPowerNum = 6;
|
pCalParam->nPowerNum = 6;
|
||||||
g_nSecLength = 64; /* 2^nPowerNum */
|
pCalParam->nSecLength = 64; /* 2^nPowerNum */
|
||||||
g_nDarkSecLength = g_wDarkCalWidth / 3;
|
pCalParam->nDarkSecLength = wDarkCalWidth / 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_nPowerNum = 6;
|
pCalParam->nPowerNum = 6;
|
||||||
g_nSecLength = 64; /* 2^nPowerNum */
|
pCalParam->nSecLength = 64; /* 2^nPowerNum */
|
||||||
g_wCalWidth = 10240;
|
wCalWidth = 10240;
|
||||||
g_nDarkSecLength = g_wDarkCalWidth / 5;
|
pCalParam->nDarkSecLength = wDarkCalWidth / 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_nDarkSecLength <= 0)
|
if (pCalParam->nDarkSecLength <= 0)
|
||||||
g_nDarkSecLength = 1;
|
pCalParam->nDarkSecLength = 1;
|
||||||
|
|
||||||
g_wStartPosition = 13 * wResolution / SENSOR_DPI;
|
pCalParam->wStartPosition = 13 * wResolution / SENSOR_DPI;
|
||||||
g_wCalWidth -= g_wStartPosition;
|
wCalWidth -= pCalParam->wStartPosition;
|
||||||
|
|
||||||
/* start of find max value */
|
/* start of find max value */
|
||||||
g_nSecNum = (int) (g_wCalWidth / g_nSecLength);
|
pCalParam->nSecNum = wCalWidth / pCalParam->nSecLength;
|
||||||
|
|
||||||
/* start of find min value */
|
/* start of find min value */
|
||||||
g_nDarkSecNum = (int) (g_wDarkCalWidth / g_nDarkSecLength);
|
pCalParam->nDarkSecNum = wDarkCalWidth / pCalParam->nDarkSecLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SANE_Bool
|
static SANE_Bool
|
||||||
MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * pMaxValue,
|
MustScanner_CalculateMaxMin (CALIBRATIONPARAM * pCalParam, SANE_Byte * pBuffer,
|
||||||
|
unsigned short * pMaxValue,
|
||||||
unsigned short * pMinValue)
|
unsigned short * pMinValue)
|
||||||
{
|
{
|
||||||
unsigned short *wSecData, *wDarkSecData;
|
unsigned short *wSecData, *wDarkSecData;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
wSecData = malloc (g_nSecNum * sizeof (unsigned short));
|
wSecData = malloc (pCalParam->nSecNum * sizeof (unsigned short));
|
||||||
if (!wSecData)
|
if (!wSecData)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
memset (wSecData, 0, g_nSecNum * sizeof (unsigned short));
|
memset (wSecData, 0, pCalParam->nSecNum * sizeof (unsigned short));
|
||||||
|
|
||||||
for (i = 0; i < g_nSecNum; i++)
|
for (i = 0; i < pCalParam->nSecNum; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < g_nSecLength; j++)
|
for (j = 0; j < pCalParam->nSecLength; j++)
|
||||||
wSecData[i] += pBuffer[g_wStartPosition + i * g_nSecLength + j];
|
wSecData[i] += pBuffer[pCalParam->wStartPosition +
|
||||||
wSecData[i] >>= g_nPowerNum;
|
i * pCalParam->nSecLength + j];
|
||||||
|
wSecData[i] >>= pCalParam->nPowerNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pMaxValue = wSecData[0];
|
*pMaxValue = wSecData[0];
|
||||||
for (i = 0; i < g_nSecNum; i++)
|
for (i = 0; i < pCalParam->nSecNum; i++)
|
||||||
{
|
{
|
||||||
if (*pMaxValue < wSecData[i])
|
if (*pMaxValue < wSecData[i])
|
||||||
*pMaxValue = wSecData[i];
|
*pMaxValue = wSecData[i];
|
||||||
}
|
}
|
||||||
free (wSecData);
|
free (wSecData);
|
||||||
|
|
||||||
wDarkSecData = malloc (g_nDarkSecNum * sizeof (unsigned short));
|
wDarkSecData = malloc (pCalParam->nDarkSecNum * sizeof (unsigned short));
|
||||||
if (!wDarkSecData)
|
if (!wDarkSecData)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
memset (wDarkSecData, 0, g_nDarkSecNum * sizeof (unsigned short));
|
memset (wDarkSecData, 0, pCalParam->nDarkSecNum * sizeof (unsigned short));
|
||||||
|
|
||||||
for (i = 0; i < g_nDarkSecNum; i++)
|
for (i = 0; i < pCalParam->nDarkSecNum; i++)
|
||||||
{
|
{
|
||||||
for (j = 0; j < g_nDarkSecLength; j++)
|
for (j = 0; j < pCalParam->nDarkSecLength; j++)
|
||||||
wDarkSecData[i] += pBuffer[g_wStartPosition + i * g_nDarkSecLength + j];
|
wDarkSecData[i] += pBuffer[pCalParam->wStartPosition +
|
||||||
wDarkSecData[i] /= g_nDarkSecLength;
|
i * pCalParam->nDarkSecLength + j];
|
||||||
|
wDarkSecData[i] /= pCalParam->nDarkSecLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pMinValue = wDarkSecData[0];
|
*pMinValue = wDarkSecData[0];
|
||||||
for (i = 0; i < g_nDarkSecNum; i++)
|
for (i = 0; i < pCalParam->nDarkSecNum; i++)
|
||||||
{
|
{
|
||||||
if (*pMinValue > wDarkSecData[i])
|
if (*pMinValue > wDarkSecData[i])
|
||||||
*pMinValue = wDarkSecData[i];
|
*pMinValue = wDarkSecData[i];
|
||||||
|
@ -1297,6 +1263,7 @@ MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * pMaxValue,
|
||||||
static SANE_Bool
|
static SANE_Bool
|
||||||
MustScanner_AdjustAD (void)
|
MustScanner_AdjustAD (void)
|
||||||
{
|
{
|
||||||
|
CALIBRATIONPARAM calParam;
|
||||||
SANE_Byte * pCalData;
|
SANE_Byte * pCalData;
|
||||||
unsigned short wCalWidth;
|
unsigned short wCalWidth;
|
||||||
unsigned short wMaxValue[3], wMinValue[3];
|
unsigned short wMaxValue[3], wMinValue[3];
|
||||||
|
@ -1321,7 +1288,7 @@ MustScanner_AdjustAD (void)
|
||||||
g_chip.AD.Direction[i] = DIR_POSITIVE;
|
g_chip.AD.Direction[i] = DIR_POSITIVE;
|
||||||
g_chip.AD.Gain[i] = 0;
|
g_chip.AD.Gain[i] = 0;
|
||||||
}
|
}
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
g_chip.AD.Offset[0] = 152; /* red */
|
g_chip.AD.Offset[0] = 152; /* red */
|
||||||
g_chip.AD.Offset[1] = 56; /* green */
|
g_chip.AD.Offset[1] = 56; /* green */
|
||||||
|
@ -1334,7 +1301,7 @@ MustScanner_AdjustAD (void)
|
||||||
g_chip.AD.Offset[2] = 45;
|
g_chip.AD.Offset[2] = 45;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_XDpi <= (SENSOR_DPI / 2))
|
if (g_Target.wXDpi <= (SENSOR_DPI / 2))
|
||||||
wAdjustADResolution = SENSOR_DPI / 2;
|
wAdjustADResolution = SENSOR_DPI / 2;
|
||||||
else
|
else
|
||||||
wAdjustADResolution = SENSOR_DPI;
|
wAdjustADResolution = SENSOR_DPI;
|
||||||
|
@ -1347,11 +1314,11 @@ MustScanner_AdjustAD (void)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Asic_SetWindow (&g_chip, g_ssScanSource, SCAN_TYPE_CALIBRATE_DARK, 24,
|
if (Asic_SetWindow (&g_chip, g_Target.ssScanSource, SCAN_TYPE_CALIBRATE_DARK,
|
||||||
wAdjustADResolution, wAdjustADResolution, 0, 0,
|
24, wAdjustADResolution, wAdjustADResolution, 0, 0,
|
||||||
wCalWidth, 1) != SANE_STATUS_GOOD)
|
wCalWidth, 1) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
MustScanner_PrepareCalculateMaxMin (wAdjustADResolution);
|
MustScanner_PrepareCalculateMaxMin (wAdjustADResolution, &calParam);
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
|
@ -1378,7 +1345,8 @@ MustScanner_AdjustAD (void)
|
||||||
|
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
if (!MustScanner_CalculateMaxMin (pCalData + (wCalWidth * j),
|
if (!MustScanner_CalculateMaxMin (&calParam,
|
||||||
|
pCalData + (wCalWidth * j),
|
||||||
&wMaxValue[j], &wMinValue[j]))
|
&wMaxValue[j], &wMinValue[j]))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -1440,7 +1408,8 @@ MustScanner_AdjustAD (void)
|
||||||
|
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
if (!MustScanner_CalculateMaxMin (pCalData + (wCalWidth * j),
|
if (!MustScanner_CalculateMaxMin (&calParam,
|
||||||
|
pCalData + (wCalWidth * j),
|
||||||
&wMaxValue[j], &wMinValue[j]))
|
&wMaxValue[j], &wMinValue[j]))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -1507,7 +1476,8 @@ MustScanner_AdjustAD (void)
|
||||||
|
|
||||||
for (j = 0; j < 3; j++)
|
for (j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
if (!MustScanner_CalculateMaxMin (pCalData + (wCalWidth * j),
|
if (!MustScanner_CalculateMaxMin (&calParam,
|
||||||
|
pCalData + (wCalWidth * j),
|
||||||
&wMaxValue[j], &wMinValue[j]))
|
&wMaxValue[j], &wMinValue[j]))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -1579,7 +1549,7 @@ MustScanner_FindTopLeft (unsigned short * pwStartX, unsigned short * pwStartY)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
wCalWidth = FIND_LEFT_TOP_WIDTH_IN_DIP;
|
wCalWidth = FIND_LEFT_TOP_WIDTH_IN_DIP;
|
||||||
wCalHeight = FIND_LEFT_TOP_HEIGHT_IN_DIP;
|
wCalHeight = FIND_LEFT_TOP_HEIGHT_IN_DIP;
|
||||||
|
@ -1599,8 +1569,8 @@ MustScanner_FindTopLeft (unsigned short * pwStartX, unsigned short * pwStartY)
|
||||||
}
|
}
|
||||||
nScanBlock = dwTotalSize / CALIBRATION_BLOCK_SIZE;
|
nScanBlock = dwTotalSize / CALIBRATION_BLOCK_SIZE;
|
||||||
|
|
||||||
if (Asic_SetWindow (&g_chip, g_ssScanSource, SCAN_TYPE_CALIBRATE_LIGHT, 8,
|
if (Asic_SetWindow (&g_chip, g_Target.ssScanSource, SCAN_TYPE_CALIBRATE_LIGHT,
|
||||||
FIND_LEFT_TOP_CALIBRATE_RESOLUTION,
|
8, FIND_LEFT_TOP_CALIBRATE_RESOLUTION,
|
||||||
FIND_LEFT_TOP_CALIBRATE_RESOLUTION, 0, 0,
|
FIND_LEFT_TOP_CALIBRATE_RESOLUTION, 0, 0,
|
||||||
wCalWidth, wCalHeight) != SANE_STATUS_GOOD)
|
wCalWidth, wCalHeight) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1652,7 +1622,7 @@ MustScanner_FindTopLeft (unsigned short * pwStartX, unsigned short * pwStartY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
/* find top side, i = left side */
|
/* find top side, i = left side */
|
||||||
for (j = 0; j < wCalHeight; j++)
|
for (j = 0; j < wCalHeight; j++)
|
||||||
|
@ -1781,7 +1751,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wCalWidth = g_Width;
|
wCalWidth = g_Target.wWidth;
|
||||||
wCalHeight = LINE_CALIBRATION_HEIGHT;
|
wCalHeight = LINE_CALIBRATION_HEIGHT;
|
||||||
dwTotalSize = wCalWidth * wCalHeight * 3 * 2;
|
dwTotalSize = wCalWidth * wCalHeight * 3 * 2;
|
||||||
DBG (DBG_FUNC, "MustScanner_LineCalibration16Bits: wCalWidth = %d, " \
|
DBG (DBG_FUNC, "MustScanner_LineCalibration16Bits: wCalWidth = %d, " \
|
||||||
|
@ -1797,9 +1767,9 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
|
|
||||||
/* read white level data */
|
/* read white level data */
|
||||||
SetAFEGainOffset (&g_chip);
|
SetAFEGainOffset (&g_chip);
|
||||||
if (Asic_SetWindow (&g_chip, g_ssScanSource, SCAN_TYPE_CALIBRATE_LIGHT, 48,
|
if (Asic_SetWindow (&g_chip, g_Target.ssScanSource, SCAN_TYPE_CALIBRATE_LIGHT,
|
||||||
g_XDpi, 600, g_X, 0, wCalWidth, wCalHeight) !=
|
48, g_Target.wXDpi, 600, g_Target.wX, 0,
|
||||||
SANE_STATUS_GOOD)
|
wCalWidth, wCalHeight) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (Asic_ScanStart (&g_chip) != SANE_STATUS_GOOD)
|
if (Asic_ScanStart (&g_chip) != SANE_STATUS_GOOD)
|
||||||
|
@ -1814,12 +1784,12 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
|
|
||||||
/* read dark level data */
|
/* read dark level data */
|
||||||
SetAFEGainOffset (&g_chip);
|
SetAFEGainOffset (&g_chip);
|
||||||
if (Asic_SetWindow (&g_chip, g_ssScanSource, SCAN_TYPE_CALIBRATE_DARK, 48,
|
if (Asic_SetWindow (&g_chip, g_Target.ssScanSource, SCAN_TYPE_CALIBRATE_DARK,
|
||||||
g_XDpi, 600, g_X, 0, wCalWidth, wCalHeight) !=
|
48, g_Target.wXDpi, 600, g_Target.wX, 0, wCalWidth,
|
||||||
SANE_STATUS_GOOD)
|
wCalHeight) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
if (Asic_TurnLamp (&g_chip, SANE_FALSE) != SANE_STATUS_GOOD)
|
if (Asic_TurnLamp (&g_chip, SANE_FALSE) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1842,7 +1812,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
if (Asic_ScanStop (&g_chip) != SANE_STATUS_GOOD)
|
if (Asic_ScanStop (&g_chip) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
if (Asic_TurnLamp (&g_chip, SANE_TRUE) != SANE_STATUS_GOOD)
|
if (Asic_TurnLamp (&g_chip, SANE_TRUE) != SANE_STATUS_GOOD)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1903,7 +1873,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sum of dark level for all pixels */
|
/* sum of dark level for all pixels */
|
||||||
if ((g_XDpi == SENSOR_DPI) && ((i % 2) == 0))
|
if ((g_Target.wXDpi == SENSOR_DPI) && ((i % 2) == 0))
|
||||||
{
|
{
|
||||||
/* compute dark shading table with mean */
|
/* compute dark shading table with mean */
|
||||||
dwREvenDarkLevel += MustScanner_FiltLower (pRDarkSort, wCalHeight,
|
dwREvenDarkLevel += MustScanner_FiltLower (pRDarkSort, wCalHeight,
|
||||||
|
@ -1924,7 +1894,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
{
|
{
|
||||||
dwRDarkLevel /= wCalWidth / 2;
|
dwRDarkLevel /= wCalWidth / 2;
|
||||||
dwGDarkLevel /= wCalWidth / 2;
|
dwGDarkLevel /= wCalWidth / 2;
|
||||||
|
@ -1939,7 +1909,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
dwGDarkLevel /= wCalWidth;
|
dwGDarkLevel /= wCalWidth;
|
||||||
dwBDarkLevel /= wCalWidth;
|
dwBDarkLevel /= wCalWidth;
|
||||||
}
|
}
|
||||||
if (g_ssScanSource != SS_REFLECTIVE)
|
if (g_Target.ssScanSource != SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
dwRDarkLevel -= 512;
|
dwRDarkLevel -= 512;
|
||||||
dwGDarkLevel -= 512;
|
dwGDarkLevel -= 512;
|
||||||
|
@ -1964,11 +1934,11 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
pBWhiteSort[j] += pWhiteData[j * wCalWidth * 2 * 3 + i * 6 + 5] << 8;
|
pBWhiteSort[j] += pWhiteData[j * wCalWidth * 2 * 3 + i * 6 + 5] << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((g_XDpi == SENSOR_DPI) && ((i % 2) == 0))
|
if ((g_Target.wXDpi == SENSOR_DPI) && ((i % 2) == 0))
|
||||||
{
|
{
|
||||||
pDarkShading[i * 3] = dwREvenDarkLevel;
|
pDarkShading[i * 3] = dwREvenDarkLevel;
|
||||||
pDarkShading[i * 3 + 1] = dwGEvenDarkLevel;
|
pDarkShading[i * 3 + 1] = dwGEvenDarkLevel;
|
||||||
if (g_ssScanSource == SS_POSITIVE)
|
if (g_Target.ssScanSource == SS_POSITIVE)
|
||||||
pDarkShading[i * 3 + 1] *= 0.78;
|
pDarkShading[i * 3 + 1] *= 0.78;
|
||||||
pDarkShading[i * 3 + 2] = dwBEvenDarkLevel;
|
pDarkShading[i * 3 + 2] = dwBEvenDarkLevel;
|
||||||
}
|
}
|
||||||
|
@ -1976,7 +1946,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
{
|
{
|
||||||
pDarkShading[i * 3] = dwRDarkLevel;
|
pDarkShading[i * 3] = dwRDarkLevel;
|
||||||
pDarkShading[i * 3 + 1] = dwGDarkLevel;
|
pDarkShading[i * 3 + 1] = dwGDarkLevel;
|
||||||
if (g_ssScanSource == SS_POSITIVE)
|
if (g_Target.ssScanSource == SS_POSITIVE)
|
||||||
pDarkShading[i * 3 + 1] *= 0.78;
|
pDarkShading[i * 3 + 1] *= 0.78;
|
||||||
pDarkShading[i * 3 + 2] = dwBDarkLevel;
|
pDarkShading[i * 3 + 2] = dwBDarkLevel;
|
||||||
}
|
}
|
||||||
|
@ -1988,7 +1958,7 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
wBWhiteLevel = MustScanner_FiltLower (pBWhiteSort, wCalHeight, 20, 30) -
|
wBWhiteLevel = MustScanner_FiltLower (pBWhiteSort, wCalHeight, 20, 30) -
|
||||||
pDarkShading[i * 3 + 2];
|
pDarkShading[i * 3 + 2];
|
||||||
|
|
||||||
switch (g_ssScanSource)
|
switch (g_Target.ssScanSource)
|
||||||
{
|
{
|
||||||
case SS_REFLECTIVE:
|
case SS_REFLECTIVE:
|
||||||
if (wRWhiteLevel > 0)
|
if (wRWhiteLevel > 0)
|
||||||
|
@ -2059,8 +2029,8 @@ MustScanner_LineCalibration16Bits (void)
|
||||||
free (pGDarkSort);
|
free (pGDarkSort);
|
||||||
free (pBDarkSort);
|
free (pBDarkSort);
|
||||||
|
|
||||||
if (Asic_SetShadingTable (&g_chip, pWhiteShading, pDarkShading, g_XDpi,
|
if (Asic_SetShadingTable (&g_chip, pWhiteShading, pDarkShading,
|
||||||
wCalWidth) != SANE_STATUS_GOOD)
|
g_Target.wXDpi, wCalWidth) != SANE_STATUS_GOOD)
|
||||||
goto error; /* TODO: memory leak */
|
goto error; /* TODO: memory leak */
|
||||||
|
|
||||||
free (pWhiteShading);
|
free (pWhiteShading);
|
||||||
|
@ -2081,7 +2051,7 @@ error:
|
||||||
SANE_Bool
|
SANE_Bool
|
||||||
MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
{
|
{
|
||||||
unsigned short targetY;
|
unsigned short finalY;
|
||||||
SANE_Byte bScanBits;
|
SANE_Byte bScanBits;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: call in\n");
|
DBG (DBG_FUNC, "MustScanner_SetupScan: call in\n");
|
||||||
|
@ -2092,19 +2062,16 @@ MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ScanMode = pTarget->cmColorMode;
|
g_Target = *pTarget;
|
||||||
g_XDpi = pTarget->wDpi;
|
g_SWWidth = g_Target.wWidth;
|
||||||
g_YDpi = pTarget->wDpi;
|
g_SWHeight = g_Target.wHeight;
|
||||||
g_Width = (pTarget->wWidth + 15) & ~15; /* real scan width */
|
/* set real scan width according to ASIC limit: width must be 8x */
|
||||||
g_Height = pTarget->wHeight;
|
g_Target.wWidth = (g_Target.wWidth + 15) & ~15;
|
||||||
g_SWWidth = pTarget->wWidth;
|
|
||||||
g_SWHeight = pTarget->wHeight;
|
|
||||||
g_wLineartThreshold = pTarget->wLineartThreshold;
|
|
||||||
g_ssScanSource = pTarget->ssScanSource;
|
|
||||||
|
|
||||||
/* create gamma table */
|
/* create gamma table */
|
||||||
if ((pTarget->cmColorMode == CM_GRAY8) ||
|
/* TODO: move into separate function */
|
||||||
(pTarget->cmColorMode == CM_RGB24))
|
if ((g_Target.cmColorMode == CM_GRAY8) ||
|
||||||
|
(g_Target.cmColorMode == CM_RGB24))
|
||||||
{
|
{
|
||||||
unsigned short i;
|
unsigned short i;
|
||||||
SANE_Byte bGammaData;
|
SANE_Byte bGammaData;
|
||||||
|
@ -2124,8 +2091,8 @@ MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
g_pGammaTable[i + 8192] = bGammaData;
|
g_pGammaTable[i + 8192] = bGammaData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((pTarget->cmColorMode == CM_GRAY16) ||
|
else if ((g_Target.cmColorMode == CM_GRAY16) ||
|
||||||
(pTarget->cmColorMode == CM_RGB48))
|
(g_Target.cmColorMode == CM_RGB48))
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned short wGammaData;
|
unsigned short wGammaData;
|
||||||
|
@ -2152,12 +2119,12 @@ MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
g_pGammaTable = NULL;
|
g_pGammaTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (g_YDpi)
|
switch (g_Target.wYDpi)
|
||||||
{
|
{
|
||||||
case 1200:
|
case 1200:
|
||||||
g_wPixelDistance = 4; /* even & odd sensor problem */
|
g_wPixelDistance = 4; /* even & odd sensor problem */
|
||||||
g_wLineDistance = 24;
|
g_wLineDistance = 24;
|
||||||
g_Height += g_wPixelDistance;
|
g_Target.wHeight += g_wPixelDistance;
|
||||||
break;
|
break;
|
||||||
case 600:
|
case 600:
|
||||||
g_wPixelDistance = 0; /* no even & odd problem */
|
g_wPixelDistance = 0; /* no even & odd problem */
|
||||||
|
@ -2181,41 +2148,41 @@ MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
g_wLineDistance = 0;
|
g_wLineDistance = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: g_YDpi=%d\n", g_YDpi);
|
DBG (DBG_FUNC, "MustScanner_SetupScan: wYDpi=%d\n", g_Target.wYDpi);
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: g_wLineDistance=%d\n",
|
DBG (DBG_FUNC, "MustScanner_SetupScan: g_wLineDistance=%d\n",
|
||||||
g_wLineDistance);
|
g_wLineDistance);
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: g_wPixelDistance=%d\n",
|
DBG (DBG_FUNC, "MustScanner_SetupScan: g_wPixelDistance=%d\n",
|
||||||
g_wPixelDistance);
|
g_wPixelDistance);
|
||||||
|
|
||||||
switch (g_ScanMode)
|
switch (g_Target.cmColorMode)
|
||||||
{
|
{
|
||||||
case CM_RGB48:
|
case CM_RGB48:
|
||||||
g_BytesPerRow = 6 * g_Width; /* ASIC limit: width must be 8x */
|
g_BytesPerRow = 6 * g_Target.wWidth;
|
||||||
g_SWBytesPerRow = 6 * g_SWWidth; /* ASIC limit: width must be 8x */
|
g_SWBytesPerRow = 6 * g_SWWidth;
|
||||||
g_Height += g_wLineDistance * 2;
|
g_Target.wHeight += g_wLineDistance * 2;
|
||||||
bScanBits = 48;
|
bScanBits = 48;
|
||||||
break;
|
break;
|
||||||
case CM_RGB24:
|
case CM_RGB24:
|
||||||
g_BytesPerRow = 3 * g_Width;
|
g_BytesPerRow = 3 * g_Target.wWidth;
|
||||||
g_SWBytesPerRow = 3 * g_SWWidth;
|
g_SWBytesPerRow = 3 * g_SWWidth;
|
||||||
g_Height += g_wLineDistance * 2;
|
g_Target.wHeight += g_wLineDistance * 2;
|
||||||
bScanBits = 24;
|
bScanBits = 24;
|
||||||
break;
|
break;
|
||||||
case CM_GRAY16:
|
case CM_GRAY16:
|
||||||
g_BytesPerRow = 2 * g_Width;
|
g_BytesPerRow = 2 * g_Target.wWidth;
|
||||||
g_SWBytesPerRow = 2 * g_SWWidth;
|
g_SWBytesPerRow = 2 * g_SWWidth;
|
||||||
bScanBits = 16;
|
bScanBits = 16;
|
||||||
break;
|
break;
|
||||||
case CM_GRAY8:
|
case CM_GRAY8:
|
||||||
case CM_TEXT:
|
case CM_TEXT:
|
||||||
default:
|
default:
|
||||||
g_BytesPerRow = g_Width;
|
g_BytesPerRow = g_Target.wWidth;
|
||||||
g_SWBytesPerRow = g_SWWidth;
|
g_SWBytesPerRow = g_SWWidth;
|
||||||
bScanBits = 8;
|
bScanBits = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
if (!MustScanner_PowerControl (SANE_TRUE, SANE_FALSE))
|
if (!MustScanner_PowerControl (SANE_TRUE, SANE_FALSE))
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
|
@ -2232,97 +2199,103 @@ MustScanner_SetupScan (TARGETIMAGE * pTarget)
|
||||||
g_bOpened = SANE_TRUE;
|
g_bOpened = SANE_TRUE;
|
||||||
|
|
||||||
/* find left & top side */
|
/* find left & top side */
|
||||||
if (g_ssScanSource != SS_REFLECTIVE)
|
if (g_Target.ssScanSource != SS_REFLECTIVE)
|
||||||
if (Asic_MotorMove (&g_chip, SANE_TRUE, TRAN_START_POS) != SANE_STATUS_GOOD)
|
if (Asic_MotorMove (&g_chip, SANE_TRUE, TRAN_START_POS) != SANE_STATUS_GOOD)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
|
|
||||||
if (g_XDpi == SENSOR_DPI)
|
if (g_Target.wXDpi == SENSOR_DPI)
|
||||||
{
|
{
|
||||||
g_XDpi = SENSOR_DPI / 2;
|
g_Target.wXDpi = SENSOR_DPI / 2;
|
||||||
if (!MustScanner_AdjustAD ())
|
if (!MustScanner_AdjustAD ())
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
if (!MustScanner_FindTopLeft (&g_X, &g_Y))
|
if (!MustScanner_FindTopLeft (&g_Target.wX, &g_Target.wY))
|
||||||
{
|
{
|
||||||
g_X = 187;
|
g_Target.wX = 187;
|
||||||
g_Y = 43;
|
g_Target.wY = 43;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_XDpi = SENSOR_DPI;
|
g_Target.wXDpi = SENSOR_DPI;
|
||||||
if (!MustScanner_AdjustAD ())
|
if (!MustScanner_AdjustAD ())
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
|
|
||||||
g_X = g_X * SENSOR_DPI / FIND_LEFT_TOP_CALIBRATE_RESOLUTION + pTarget->wX;
|
g_Target.wX = g_Target.wX * SENSOR_DPI /
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
FIND_LEFT_TOP_CALIBRATE_RESOLUTION + pTarget->wX;
|
||||||
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
g_X += 47;
|
g_Target.wX += 47;
|
||||||
g_Y = g_Y * SENSOR_DPI / FIND_LEFT_TOP_CALIBRATE_RESOLUTION +
|
g_Target.wY = g_Target.wY * SENSOR_DPI /
|
||||||
pTarget->wY * SENSOR_DPI / g_YDpi + 47;
|
FIND_LEFT_TOP_CALIBRATE_RESOLUTION +
|
||||||
|
pTarget->wY * SENSOR_DPI / g_Target.wYDpi + 47;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!MustScanner_AdjustAD ())
|
if (!MustScanner_AdjustAD ())
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
if (!MustScanner_FindTopLeft (&g_X, &g_Y))
|
if (!MustScanner_FindTopLeft (&g_Target.wX, &g_Target.wY))
|
||||||
{
|
{
|
||||||
g_X = 187;
|
g_Target.wX = 187;
|
||||||
g_Y = 43;
|
g_Target.wY = 43;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_X += pTarget->wX * (SENSOR_DPI / 2) / g_XDpi;
|
g_Target.wX += pTarget->wX * (SENSOR_DPI / 2) / g_Target.wXDpi;
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
if (g_XDpi != 75)
|
if (g_Target.wXDpi != 75)
|
||||||
g_X += 23;
|
g_Target.wX += 23;
|
||||||
g_Y = g_Y * SENSOR_DPI / FIND_LEFT_TOP_CALIBRATE_RESOLUTION +
|
g_Target.wY = g_Target.wY * SENSOR_DPI /
|
||||||
pTarget->wY * SENSOR_DPI / g_YDpi + 47;
|
FIND_LEFT_TOP_CALIBRATE_RESOLUTION +
|
||||||
|
pTarget->wY * SENSOR_DPI / g_Target.wYDpi + 47;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_XDpi == 75)
|
if (g_Target.wXDpi == 75)
|
||||||
g_X -= 23;
|
g_Target.wX -= 23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: before line calibration g_X=%d," \
|
DBG (DBG_FUNC, "MustScanner_SetupScan: before line calibration wX=%d," \
|
||||||
"g_Y=%d\n", g_X, g_Y);
|
"wY=%d\n", g_Target.wX, g_Target.wY);
|
||||||
|
|
||||||
if (!MustScanner_LineCalibration16Bits ())
|
if (!MustScanner_LineCalibration16Bits ())
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: after " \
|
DBG (DBG_FUNC, "MustScanner_SetupScan: after " \
|
||||||
"MustScanner_LineCalibration16Bits g_X=%d,g_Y=%d\n", g_X, g_Y);
|
"MustScanner_LineCalibration16Bits wX=%d,wY=%d\n",
|
||||||
|
g_Target.wX, g_Target.wY);
|
||||||
|
|
||||||
DBG (DBG_FUNC, "MustScanner_SetupScan: bScanBits=%d, g_XDpi=%d, " \
|
DBG (DBG_FUNC, "MustScanner_SetupScan: bScanBits=%d, wXDpi=%d, " \
|
||||||
"g_YDpi=%d, g_X=%d, g_Y=%d, g_Width=%d, g_Height=%d\n",
|
"wYDpi=%d, wX=%d, wY=%d, wWidth=%d, wHeight=%d\n",
|
||||||
bScanBits, g_XDpi, g_YDpi, g_X, g_Y, g_Width, g_Height);
|
bScanBits, g_Target.wXDpi, g_Target.wYDpi, g_Target.wX, g_Target.wY,
|
||||||
|
g_Target.wWidth, g_Target.wHeight);
|
||||||
|
|
||||||
if (g_ssScanSource == SS_REFLECTIVE)
|
if (g_Target.ssScanSource == SS_REFLECTIVE)
|
||||||
{
|
{
|
||||||
targetY = 300;
|
finalY = 300;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_Y = pTarget->wY * SENSOR_DPI / g_YDpi + (300 - 40) + 189;
|
g_Target.wY = pTarget->wY * SENSOR_DPI / g_Target.wYDpi + (300 - 40) +189;
|
||||||
targetY = 360;
|
finalY = 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Y > targetY)
|
if (g_Target.wY > finalY)
|
||||||
{
|
{
|
||||||
if (Asic_MotorMove (&g_chip, SANE_TRUE, g_Y - targetY) !=
|
if (Asic_MotorMove (&g_chip, SANE_TRUE, g_Target.wY - finalY) !=
|
||||||
SANE_STATUS_GOOD)
|
SANE_STATUS_GOOD)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Asic_MotorMove (&g_chip, SANE_FALSE, targetY - g_Y) !=
|
if (Asic_MotorMove (&g_chip, SANE_FALSE, finalY - g_Target.wY) !=
|
||||||
SANE_STATUS_GOOD)
|
SANE_STATUS_GOOD)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
}
|
}
|
||||||
g_Y = targetY;
|
g_Target.wY = finalY;
|
||||||
|
|
||||||
if (Asic_SetWindow (&g_chip, g_ssScanSource, SCAN_TYPE_NORMAL, bScanBits,
|
if (Asic_SetWindow (&g_chip, g_Target.ssScanSource, SCAN_TYPE_NORMAL,
|
||||||
g_XDpi, g_YDpi, g_X, g_Y, g_Width, g_Height) !=
|
bScanBits, g_Target.wXDpi, g_Target.wYDpi, g_Target.wX,
|
||||||
|
g_Target.wY, g_Target.wWidth, g_Target.wHeight) !=
|
||||||
SANE_STATUS_GOOD)
|
SANE_STATUS_GOOD)
|
||||||
return SANE_FALSE;
|
return SANE_FALSE;
|
||||||
|
|
||||||
|
|
|
@ -65,15 +65,23 @@ typedef struct
|
||||||
{
|
{
|
||||||
COLORMODE cmColorMode;
|
COLORMODE cmColorMode;
|
||||||
SCANSOURCE ssScanSource;
|
SCANSOURCE ssScanSource;
|
||||||
unsigned short wDpi;
|
unsigned short wXDpi;
|
||||||
|
unsigned short wYDpi;
|
||||||
unsigned short wX;
|
unsigned short wX;
|
||||||
unsigned short wY;
|
unsigned short wY;
|
||||||
unsigned short wWidth;
|
unsigned short wWidth;
|
||||||
unsigned short wHeight;
|
unsigned short wHeight;
|
||||||
unsigned short wLineartThreshold;
|
unsigned short wLineartThreshold;
|
||||||
unsigned int dwBytesPerRow;
|
|
||||||
} TARGETIMAGE;
|
} TARGETIMAGE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int nSecLength, nDarkSecLength;
|
||||||
|
int nSecNum, nDarkSecNum;
|
||||||
|
int nPowerNum;
|
||||||
|
unsigned short wStartPosition;
|
||||||
|
} CALIBRATIONPARAM;
|
||||||
|
|
||||||
|
|
||||||
#define _MAX(a,b) ((a)>(b)?(a):(b))
|
#define _MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
#define _MIN(a,b) ((a)<(b)?(a):(b))
|
#define _MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
|
Ładowanie…
Reference in New Issue