Improved support for Scanmaker X12USL. Alpha support for Scanmaker

9800XL. Some bugfixes. (From Karsten Festag <karsten.festag@gmx.de>).
RELEASE_1_0_11_BRANCH
Henning Geinitz 2003-01-09 00:40:45 +00:00
rodzic d93ecd140f
commit a50e314cbe
3 zmienionych plików z 437 dodań i 257 usunięć

Wyświetl plik

@ -30,6 +30,10 @@
entry about po files.
* po/Makefile.in: Remove sane-backends.pot from list of distributed
files.
* backend/microtek2.c backend/microtek2.h: Improved support for
Scanmaker X12USL. Alpha support for Scanmaker 9800XL. Some bugfixes.
(From Karsten Festag <karsten.festag@gmx.de>).
2003-01-07 Peter Fales <peter@fales-lorenz.net>

Wyświetl plik

@ -50,7 +50,7 @@
SCSI-2 command set.
(feedback to: bernd@aquila.muc.de)
( karsten.festag@gmx.de)
( karsten.festag@t-online.de)
***************************************************************************/
@ -94,6 +94,9 @@
#define BACKEND_NAME microtek2_test
#endif
/* for testing*/
/*#define NO_PHANTOMTYPE_SHADING*/
#include "../include/sane/sanei_backend.h"
#include "microtek2.h"
@ -474,7 +477,8 @@ sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize)
while ( md_config_temp )
{
sanei_config_attach_matching_devices(md_config_temp->device, attach_one);
sanei_config_attach_matching_devices(md_config_temp->device,
attach_one);
if ( md_config_temp->next ) /* go to next device, if existent */
md_config_temp = md_config_temp->next;
else
@ -624,8 +628,8 @@ sane_read(SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len )
{
if ( errno == EAGAIN )
{
return SANE_STATUS_GOOD;
DBG(30, "sane_read: currently no data available\n");
return SANE_STATUS_GOOD;
}
else
{
@ -759,17 +763,26 @@ attach(Microtek2_Device *md)
SANE_String model_string;
SANE_Status status;
SANE_Byte source_info;
DBG(30, "attach: device='%s'\n", md->name);
status = scsi_inquiry(&(md->info[MD_SOURCE_FLATBED]), md->name);
status = scsi_inquiry( &md->info[MD_SOURCE_FLATBED], md->name );
if ( status != SANE_STATUS_GOOD )
{
DBG(1, "attach: '%s'\n", sane_strstatus(status));
return status;
}
/* We copy the inquiry info into the info structures for each scansource */
/* like ADF, TMA, STRIPE and SLIDE */
for ( source_info = 1; source_info < 5; ++source_info )
memcpy( &md->info[source_info],
&md->info[MD_SOURCE_FLATBED],
sizeof( Microtek2_Info ) );
/* Here we should insert a function, that stores all the relevant */
/* information in the info structure in a more conveniant format */
/* in the device structure, e.g. the model name with a trailing '\0'. */
@ -786,7 +799,8 @@ attach(Microtek2_Device *md)
md->sane.type = "flatbed scanner";
md->revision = strtod(md->info[MD_SOURCE_FLATBED].revision, NULL);
status = scsi_read_attributes(&md->info[0], md->name, MD_SOURCE_FLATBED);
status = scsi_read_attributes(&md->info[MD_SOURCE_FLATBED],
md->name, MD_SOURCE_FLATBED);
if ( status != SANE_STATUS_GOOD )
{
DBG(1, "attach: '%s'\n", sane_strstatus(status));
@ -800,7 +814,8 @@ attach(Microtek2_Device *md)
/* check whether the device supports transparency media adapters */
if ( md->info[MD_SOURCE_FLATBED].option_device & MI_OPTDEV_TMA )
{
status = scsi_read_attributes(&md->info[0], md->name, MD_SOURCE_TMA);
status = scsi_read_attributes(&md->info[MD_SOURCE_TMA],
md->name, MD_SOURCE_TMA);
if ( status != SANE_STATUS_GOOD )
return status;
}
@ -808,7 +823,8 @@ attach(Microtek2_Device *md)
/* check whether the device supports an ADF */
if ( md->info[MD_SOURCE_FLATBED].option_device & MI_OPTDEV_ADF )
{
status = scsi_read_attributes(&md->info[0], md->name, MD_SOURCE_ADF);
status = scsi_read_attributes(&md->info[MD_SOURCE_ADF],
md->name, MD_SOURCE_ADF);
if ( status != SANE_STATUS_GOOD )
return status;
}
@ -816,7 +832,8 @@ attach(Microtek2_Device *md)
/* check whether the device supports STRIPES */
if ( md->info[MD_SOURCE_FLATBED].option_device & MI_OPTDEV_STRIPE )
{
status = scsi_read_attributes(&md->info[0], md->name, MD_SOURCE_STRIPE);
status = scsi_read_attributes(&md->info[MD_SOURCE_STRIPE],
md->name, MD_SOURCE_STRIPE);
if ( status != SANE_STATUS_GOOD )
return status;
}
@ -829,9 +846,8 @@ attach(Microtek2_Device *md)
if ( ! (md->model_flags & MD_NO_SLIDE_MODE) )
{
status = scsi_read_attributes(&md->info[0],
md->name,
MD_SOURCE_SLIDE);
status = scsi_read_attributes(&md->info[MD_SOURCE_SLIDE],
md->name, MD_SOURCE_SLIDE);
if ( status != SANE_STATUS_GOOD )
return status;
}
@ -1197,14 +1213,15 @@ check_inquiry(Microtek2_Device *md, SANE_String *model_string)
case 0x71:
case 0x94:
case 0xa0:
case 0xaf:
*model_string = "Phantom 330cx / Phantom 336cx / SlimScan C3";
/* These models do not accept gamma tables. Apparently they */
/* read the control bits and do not accept shading tables */
/* They also don't support enhancements (contrast, brightness...)*/
md->model_flags |= MD_NO_SLIDE_MODE
| MD_NO_GAMMA
#ifndef NO_PHANTOMTYPE_SHADING
| MD_PHANTOM336CX_TYPE_SHADING
#endif
| MD_READ_CONTROL_BIT
| MD_NO_ENHANCEMENTS;
md->opt_backend_calib_default = SANE_TRUE;
@ -1264,9 +1281,22 @@ check_inquiry(Microtek2_Device *md, SANE_String *model_string)
/* The V6USL does not accept gamma tables, perhaps the V6UL also */
md->model_flags |= MD_NO_GAMMA;
break;
case 0xaf:
*model_string = "SlimScan C3";
md->model_flags |= MD_NO_SLIDE_MODE
| MD_NO_GAMMA
| MD_READ_CONTROL_BIT
| MD_NO_ENHANCEMENTS;
md->opt_backend_calib_default = SANE_TRUE;
md->opt_no_backtrack_default = SANE_TRUE;
md->n_control_bytes = 320;
md->controlbit_offset = 7;
/*md->shading_depth = 10;*/ /*don't know*/
break;
case 0xb0:
*model_string = "ScanMaker X12USL";
md->opt_backend_calib_default = SANE_TRUE;
md->model_flags |= MD_16BIT_TRANSFER;
break;
case 0xb3:
*model_string = "ScanMaker 3600";
@ -1282,6 +1312,13 @@ check_inquiry(Microtek2_Device *md, SANE_String *model_string)
case 0xb8:
*model_string = "ScanMaker 3700";
break;
case 0xde:
*model_string = "ScanMaker 9800XL";
md->model_flags |= MD_NO_GAMMA
| MD_16BIT_TRANSFER;
md->opt_backend_calib_default = SANE_TRUE;
md->opt_no_backtrack_default = SANE_TRUE;
break;
default:
DBG(1, "check_inquiry: Model 0x%02x not supported\n", mi->model_code);
return SANE_STATUS_IO_ERROR;
@ -1668,6 +1705,7 @@ dump_attributes(Microtek2_Info *mi)
case 0xb4: DBG(1, "ScanMaker 4700\n"); break;
case 0xb6: DBG(1, "ScanMaker V6UPL\n"); break;
case 0xb8: DBG(1, "ScanMaker 3700\n"); break;
case 0xde: DBG(1, "ScanMaker 9800XL\n"); break;
default: DBG(1, "Unknown\n"); break;
}
DBG(1, " Device Type Code%10s: 0x%02x (%s),\n", " ",
@ -1973,6 +2011,7 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
int i;
static int first_call = 1; /* indicates, whether option */
/* descriptors must be initialized */
/* cannot be used as after a sane_close the sod's must be initialized */
DBG(30, "init_options: handle=%p, source=%d\n", ms, current_scan_source);
@ -2264,8 +2303,6 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
if ( first_call )
{
first_call = 0;
/* initialize option descriptors and ranges */
/* Percentage range for brightness, contrast */
@ -2319,10 +2356,15 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
sod[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;
val[OPT_NUM_OPTS].w = NUM_OPTIONS; /* NUM_OPTIONS is no option */
DBG(255, "sod=%p\n", sod);
DBG(255, "OPT_NUM_OPTS=%d\n", OPT_NUM_OPTS);
DBG(255, "SANE_CAP_SOFT_DETECT=%d\n", SANE_CAP_SOFT_DETECT);
DBG(255, "OPT_NUM_OPTS.cap=%d\n", sod[0].cap);
/* The Scan Mode Group */
sod[OPT_MODE_GROUP].title = "Scan Mode";
sod[OPT_MODE_GROUP].title = M_TITLE_SCANMODEGRP;
sod[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
sod[OPT_MODE_GROUP].size = 0;
sod[OPT_MODE_GROUP].desc = "";
sod[OPT_MODE_GROUP].cap = 0;
sod[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
@ -2378,15 +2420,15 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
sod[OPT_RESOLUTION].constraint.range = &md->x_res_range_dpi;
sod[OPT_X_RESOLUTION].name = "x-" SANE_NAME_SCAN_RESOLUTION;
sod[OPT_X_RESOLUTION].title = "X-Resolution";
sod[OPT_X_RESOLUTION].name = SANE_NAME_SCAN_X_RESOLUTION;
sod[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_X_RESOLUTION;
sod[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
sod[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI;
sod[OPT_X_RESOLUTION].cap |= SANE_CAP_INACTIVE;
sod[OPT_X_RESOLUTION].constraint.range = &md->x_res_range_dpi;
sod[OPT_Y_RESOLUTION].name = "y-" SANE_NAME_SCAN_RESOLUTION;
sod[OPT_Y_RESOLUTION].title = "Y-Resolution";
sod[OPT_Y_RESOLUTION].name = SANE_NAME_SCAN_Y_RESOLUTION;
sod[OPT_Y_RESOLUTION].title = SANE_TITLE_SCAN_Y_RESOLUTION;
sod[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
sod[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI;
sod[OPT_Y_RESOLUTION].cap |= SANE_CAP_INACTIVE;
@ -2401,8 +2443,9 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_PREVIEW].constraint_type = SANE_CONSTRAINT_NONE;
/* Geometry group, for scan area selection */
sod[OPT_GEOMETRY_GROUP].title = "Geometry";
sod[OPT_GEOMETRY_GROUP].title = M_TITLE_GEOMGRP;
sod[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
sod[OPT_GEOMETRY_GROUP].size = 0;
sod[OPT_GEOMETRY_GROUP].desc = "";
sod[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
sod[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
@ -2432,9 +2475,10 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_BR_Y].constraint.range = &md->y_range_mm;
/* Enhancement group */
sod[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
sod[OPT_ENHANCEMENT_GROUP].title = M_TITLE_ENHANCEGRP;
sod[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
sod[OPT_ENHANCEMENT_GROUP].desc = "";
sod[OPT_ENHANCEMENT_GROUP].size = 0;
sod[OPT_ENHANCEMENT_GROUP].cap = 0;
sod[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
@ -2472,6 +2516,7 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_GAMMA_GROUP].title = "Gamma";
sod[OPT_GAMMA_GROUP].desc = "";
sod[OPT_GAMMA_GROUP].type = SANE_TYPE_GROUP;
sod[OPT_GAMMA_GROUP].size = 0;
sod[OPT_GAMMA_GROUP].cap = 0;
sod[OPT_GAMMA_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
@ -2548,9 +2593,10 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_GAMMA_CUSTOM_B].constraint.range = &md->custom_gamma_range;
/* Shadow, midtone, highlight */
sod[OPT_SMH_GROUP].title = "Shadow, midtone, highlight, exposure time";
sod[OPT_SMH_GROUP].title = M_TITLE_SMHGRP;
sod[OPT_SMH_GROUP].desc = "";
sod[OPT_SMH_GROUP].type = SANE_TYPE_GROUP;
sod[OPT_SMH_GROUP].size = 0;
sod[OPT_SMH_GROUP].cap = 0;
sod[OPT_SMH_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
@ -2648,7 +2694,7 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_EXPOSURE].name = SANE_NAME_SCAN_EXPOS_TIME;
sod[OPT_EXPOSURE].title = SANE_TITLE_SCAN_EXPOS_TIME;
sod[OPT_EXPOSURE].desc = "Allows to lengthen the exposure time";
sod[OPT_EXPOSURE].desc = SANE_DESC_SCAN_EXPOS_TIME;
sod[OPT_EXPOSURE].type = SANE_TYPE_INT;
sod[OPT_EXPOSURE].unit = SANE_UNIT_PERCENT;
sod[OPT_EXPOSURE].size = sizeof(SANE_Int);
@ -2656,8 +2702,7 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_EXPOSURE_R].name = SANE_NAME_SCAN_EXPOS_TIME_R;
sod[OPT_EXPOSURE_R].title = SANE_TITLE_SCAN_EXPOS_TIME_R;
sod[OPT_EXPOSURE_R].desc = "Allows to lengthen the exposure time "
"for the red channel";
sod[OPT_EXPOSURE_R].desc = SANE_DESC_SCAN_EXPOS_TIME_R;
sod[OPT_EXPOSURE_R].type = SANE_TYPE_INT;
sod[OPT_EXPOSURE_R].unit = SANE_UNIT_PERCENT;
sod[OPT_EXPOSURE_R].size = sizeof(SANE_Int);
@ -2665,8 +2710,7 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_EXPOSURE_G].name = SANE_NAME_SCAN_EXPOS_TIME_G;
sod[OPT_EXPOSURE_G].title = SANE_TITLE_SCAN_EXPOS_TIME_G;
sod[OPT_EXPOSURE_G].desc = "Allows to lengthen the exposure time "
"for the green channel";
sod[OPT_EXPOSURE_G].desc = SANE_DESC_SCAN_EXPOS_TIME_G;
sod[OPT_EXPOSURE_G].type = SANE_TYPE_INT;
sod[OPT_EXPOSURE_G].unit = SANE_UNIT_PERCENT;
sod[OPT_EXPOSURE_G].size = sizeof(SANE_Int);
@ -2674,16 +2718,16 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_EXPOSURE_B].name = SANE_NAME_SCAN_EXPOS_TIME_B;
sod[OPT_EXPOSURE_B].title = SANE_TITLE_SCAN_EXPOS_TIME_B;
sod[OPT_EXPOSURE_B].desc = "Allows to lengthen the exposure time "
"for the blue channel";
sod[OPT_EXPOSURE_B].desc = SANE_DESC_SCAN_EXPOS_TIME_B;
sod[OPT_EXPOSURE_B].type = SANE_TYPE_INT;
sod[OPT_EXPOSURE_B].unit = SANE_UNIT_PERCENT;
sod[OPT_EXPOSURE_B].size = sizeof(SANE_Int);
sod[OPT_EXPOSURE_B].constraint.range = &md->exposure_range;
/* The Special Options Group */
sod[OPT_SPECIAL].title = "Special options";
sod[OPT_SPECIAL].title = M_TITLE_SPECIALGRP;
sod[OPT_SPECIAL].type = SANE_TYPE_GROUP;
sod[OPT_SPECIAL].size = 0;
sod[OPT_SPECIAL].desc = "";
sod[OPT_SPECIAL].cap = SANE_CAP_ADVANCED;
sod[OPT_SPECIAL].constraint_type = SANE_CONSTRAINT_NONE;
@ -2741,8 +2785,9 @@ init_options(Microtek2_Scanner *ms, u_int8_t current_scan_source)
sod[OPT_TOGGLELAMP].cap |= SANE_CAP_INACTIVE;
/* color balance */
sod[OPT_COLORBALANCE].title = "Color balance";
sod[OPT_COLORBALANCE].title = M_TITLE_COLBALANCEGRP;
sod[OPT_COLORBALANCE].type = SANE_TYPE_GROUP;
sod[OPT_COLORBALANCE].size = 0;
sod[OPT_COLORBALANCE].desc = "";
sod[OPT_COLORBALANCE].cap = SANE_CAP_ADVANCED;
sod[OPT_COLORBALANCE].constraint_type = SANE_CONSTRAINT_NONE;
@ -2984,12 +3029,14 @@ sane_control_option(SANE_Handle handle, SANE_Int option,
if ( option < 0 || option >= NUM_OPTIONS )
{
DBG(100, "sane_control_option: option %d; action %d \n", option, action);
DBG(10, "sane_control_option: option %d invalid\n", option);
return SANE_STATUS_INVAL;
}
if ( ! SANE_OPTION_IS_ACTIVE(ms->sod[option].cap) )
{
DBG(100, "sane_control_option: option %d; action %d \n", option, action);
DBG(10, "sane_control_option: option %d not active\n", option);
return SANE_STATUS_INVAL;
}
@ -2999,7 +3046,7 @@ sane_control_option(SANE_Handle handle, SANE_Int option,
switch ( action )
{
case SANE_ACTION_GET_VALUE:
case SANE_ACTION_GET_VALUE: /* read out option values */
switch ( option )
{
/* word options */
@ -3097,30 +3144,38 @@ sane_control_option(SANE_Handle handle, SANE_Int option,
/* NOTREACHED */
/* break; */
case SANE_ACTION_SET_VALUE:
case SANE_ACTION_SET_VALUE: /* set option values */
if ( ! SANE_OPTION_IS_SETTABLE(sod[option].cap) )
{
DBG(100, "sane_control_option: option %d; action %d \n",
option, action);
DBG(10, "sane_control_option: trying to set unsettable option\n");
return SANE_STATUS_INVAL;
}
/* do not check OPT_BR_Y, xscanimage sometimes tries to set */
/* it to a too large value; bug in xscanimage ? */
if ( option != OPT_BR_Y )
{
/* if ( option != OPT_BR_Y )
{ */
status = sanei_constrain_value(ms->sod + option, value, info);
if (status != SANE_STATUS_GOOD)
{
DBG(10, "sane_control_option: invalid option value\n");
return status;
}
}
/* } */
switch ( sod[option].type )
{
case SANE_TYPE_BOOL:
DBG(50, "sane_control_option: option=%d, action=%d, value=%d\n",
option, action, *(SANE_Int *) value);
if ( ! ( ( *(SANE_Bool *) value == SANE_TRUE )
|| ( *(SANE_Bool *) value == SANE_FALSE ) ) )
{
DBG(10, "sane_control_option: invalid BOOL option value\n");
return SANE_STATUS_INVAL;
}
if ( val[option].w == *(SANE_Bool *) value ) /* no change */
return SANE_STATUS_GOOD;
val[option].w = *(SANE_Bool *) value;
@ -3503,7 +3558,8 @@ sane_get_option_descriptor(SANE_Handle handle, SANE_Int n)
{
Microtek2_Scanner *ms = handle;
DBG(255, "sane_get_option_descriptor: handle=%p, opt=%d\n", handle, n);
DBG(255, "sane_get_option_descriptor: handle=%p, sod=%p, opt=%d\n",
handle, ms->sod, n);
if ( n < 0 || n > NUM_OPTIONS )
{
@ -3706,7 +3762,7 @@ get_calib_params(Microtek2_Scanner *ms)
DBG(30, "get_calib_params: handle=%p\n", ms);
md = ms->dev;
mi = &md->info[0]; /* must be changed */
mi = &md->info[md->scan_source];
ms->x_resolution_dpi = mi->opt_resolution / mi->calib_divisor;
ms->y_resolution_dpi = mi->opt_resolution / 5; /* ignore dust particles */
@ -3737,6 +3793,7 @@ get_calib_params(Microtek2_Scanner *ms)
ms->rawdat = 1;
ms->quality = 1;
ms->fastscan = 0;
/* ms->scan_source = md->scan_source; */
ms->scan_source = 0;
ms->brightness_m = ms->brightness_r = ms->brightness_g =
ms->brightness_b = 128;
@ -3849,6 +3906,9 @@ get_scan_parameters(Microtek2_Scanner *ms)
if ( ms->height_dots < 10 )
ms->height_dots = 10;
/*test!!!*/
/* ms->y1_dots -= 50;*/
/* take scanning direction into account */
if ((mi->direction & MI_DATSEQ_RTOL) == 1)
ms->x1_dots = mi->geo_width - ms->x1_dots - ms->width_dots;
@ -3982,7 +4042,17 @@ get_scan_mode_and_depth(Microtek2_Scanner *ms,
if ( strcmp(ms->val[OPT_MODE].s, MD_MODESTRING_COLOR) == 0
|| strcmp(ms->val[OPT_MODE].s, MD_MODESTRING_GRAY) == 0 )
{
if ( ms->val[OPT_BITDEPTH].w == MD_DEPTHVAL_12 )
if ( ms->val[OPT_BITDEPTH].w == MD_DEPTHVAL_16 )
{
*depth = 16;
*bits_per_pixel_in = *bits_per_pixel_out = 16;
}
else if ( ms->val[OPT_BITDEPTH].w == MD_DEPTHVAL_14 )
{
*depth = 14;
*bits_per_pixel_in = *bits_per_pixel_out = 16;
}
else if ( ms->val[OPT_BITDEPTH].w == MD_DEPTHVAL_12 )
{
*depth = 12;
*bits_per_pixel_in = *bits_per_pixel_out = 16;
@ -4322,6 +4392,9 @@ scsi_read_attributes(Microtek2_Info *pmi, char *device, u_int8_t scan_source)
result[0] &= 0xfd;
/* calib_divisor is bit49 which isn't read yet */
mi->calib_divisor = 1;
/* 9600XL */
if ( (&pmi[0])->model_code == 0xde )
mi->calib_divisor = 2;
#if 0
result[13] &= 0xfe; /* simulate no lineart */
@ -4343,10 +4416,11 @@ scsi_read_attributes(Microtek2_Info *pmi, char *device, u_int8_t scan_source)
RSA_GEOHEIGHT(mi->geo_height, result);
RSA_OPTRESOLUTION(mi->opt_resolution, result);
RSA_DEPTH(mi->depth, result);
/* The X12USL doesn't say that it has 14bit and uses a calib divisor */
if ( mi->model_code == 0xb0 )
/* The X12USL doesn't say that it has 14bit */
if ( (&pmi[0])->model_code == 0xb0 )
{
mi->depth |= MI_HASDEPTH_14;
if ( scan_source == MD_SOURCE_FLATBED )
mi->calib_divisor = 2;
}
RSA_SCANMODE(mi->scanmode, result);
@ -4535,10 +4609,8 @@ scsi_read_image_info(Microtek2_Scanner *ms)
size_t size;
SANE_Status status;
Microtek2_Device *md;
Microtek2_Info *mi;
md = ms->dev;
mi = &md->info[MD_SOURCE_FLATBED];
DBG(30, "scsi_read_image_info: ms=%p\n", ms);
@ -4632,7 +4704,7 @@ scsi_read_image_status(Microtek2_Scanner *ms)
SANE_Bool endian_type;
md = ms->dev;
mi = &md->info[0];
mi = &md->info[md->scan_source];
DBG(30, "scsi_read_image_status: ms=%p\n", ms);
@ -4955,8 +5027,10 @@ scsi_send_system_status(Microtek2_Device *md, int fd)
SSS_BUTTONCOUNT(pos, md->status.buttoncount);
if ( md_dump >= 2)
{
dump_area2(cmd, SSS_CMD_L, "sendsystemstatus");
dump_area2(cmd + SSS_CMD_L, SSS_DATA_L, "sendsystemstatusdata");
}
status = sanei_scsi_cmd(sfd, cmd, sizeof(cmd), NULL, 0);
if ( status != SANE_STATUS_GOOD )
@ -5158,12 +5232,12 @@ scsi_test_unit_ready(Microtek2_Device *md)
SANE_Status
sane_start(SANE_Handle handle)
{
SANE_Status status;
SANE_Status status = SANE_STATUS_GOOD;
Microtek2_Scanner *ms = handle;
Microtek2_Device *md;
Microtek2_Info *mi;
u_int8_t *pos;
int color, rc;
int color, rc, retry;
DBG(30, "sane_start: handle=0x%p\n", handle);
@ -5188,8 +5262,15 @@ sane_start(SANE_Handle handle)
if (ms->sfd < 0) /* first or only pass of this scan */
{
/* open device */
for ( retry = 0; retry < 10; retry++ )
{
status = sanei_scsi_open (md->sane.name, &ms->sfd,
scsi_sense_handler, 0);
if ( status != SANE_STATUS_DEVICE_BUSY )
break;
DBG(30, "sane_start: Scanner busy, trying again\n");
sleep(1);
}
if ( status != SANE_STATUS_GOOD )
{
DBG(1, "sane_start: scsi_open: '%s'\n", sane_strstatus(status));
@ -5208,6 +5289,8 @@ sane_start(SANE_Handle handle)
if ( ( ms->val[OPT_CALIB_BACKEND].w == SANE_TRUE )
&& !( md->model_flags & MD_PHANTOM336CX_TYPE_SHADING ) )
{
/* Read shading only once - possible with CIS scanners */
/* assuming only CIS scanners use Controlbits */
if ( ( md->shading_table_w == NULL )
|| !( md->model_flags & MD_READ_CONTROL_BIT ) )
{
@ -5245,7 +5328,10 @@ sane_start(SANE_Handle handle)
}
if ( ms->lightlid35 )
{
md->status.flamp &= ~MD_FLAMP_ON;
md->status.tlamp |= MD_TLAMP_ON;
}
if ( ms->no_backtracking )
md->status.ntrack |= MD_NTRACK_ON;
@ -5518,10 +5604,10 @@ cleanup:
}
static void
write_shading_buf_pnm(Microtek2_Scanner *ms)
write_shading_buf_pnm(Microtek2_Scanner *ms, u_int32_t lines)
{
FILE *outfile;
u_int16_t pixel, color, line, factor;
u_int16_t pixel, color, linenr, factor;
unsigned char img_val_out;
float img_val = 0;
Microtek2_Device *md;
@ -5540,37 +5626,44 @@ write_shading_buf_pnm(Microtek2_Scanner *ms)
factor = 4;
else
factor = 1;
if ( md->model_flags & MD_16BIT_TRANSFER )
factor = 256;
outfile = fopen("shading_buf_w.pnm", "w");
fprintf(outfile, "P6\n#imagedata\n%d %d\n255\n",
mi->geo_width / mi->calib_divisor, md->shading_length);
for ( line=0; line < md->shading_length; ++line )
mi->geo_width / mi->calib_divisor, lines);
for ( linenr=0; linenr < lines; linenr++ )
{
if (mi->data_format == MI_DATAFMT_LPLSEGREG)
{
DBG(1, "Output of shading buffer unsupported for"
"Segreg Data format\n");
break;
}
for ( pixel=0;
pixel < (u_int16_t) (mi->geo_width / mi->calib_divisor);
++pixel)
pixel++)
{
for ( color=0; color < 3; ++color )
for ( color=0; color < 3; color++ )
{
switch( mi->data_format )
{
case MI_DATAFMT_LPLCONCAT:
img_val = *((u_int16_t *) ms->shading_image
+ line * ( ms->bpl / ms->lut_entry_size )
+ linenr * ( ms->bpl / ms->lut_entry_size )
+ mi->color_sequence[color]
* ( ms->bpl / ms->lut_entry_size / 3 )
+ pixel);
break;
case MI_DATAFMT_CHUNKY:
case MI_DATAFMT_9800:
img_val = *((u_int16_t *)ms->shading_image
+ line * 3 * mi->geo_width / mi->calib_divisor
+ linenr * 3 * ( mi->geo_width
/ mi->calib_divisor )
+ 3 * pixel
+ mi->color_sequence[color]);
break;
case MI_DATAFMT_LPLSEGREG:
DBG(1, "Output of shading buffer unsupported for"
"Segreg Data format\n");
break;
}
img_val /= factor;
img_val_out = (unsigned char)img_val;
@ -5609,6 +5702,8 @@ write_shading_pnm(Microtek2_Scanner *ms)
factor = 4;
else
factor = 1;
if ( md->model_flags & MD_16BIT_TRANSFER )
factor = 256;
if ( md->model_flags & MD_PHANTOM336CX_TYPE_SHADING )
num_shading_pixels = ms->n_control_bytes * 8;
@ -5690,6 +5785,8 @@ write_cshading_pnm(Microtek2_Scanner *ms)
factor = 4;
else
factor = 1;
if ( md->model_flags & MD_16BIT_TRANSFER )
factor = 256;
outfile = fopen("microtek2_cshading_w.pnm", "w");
if ( ms->mode == MS_MODE_COLOR )
@ -5912,7 +6009,7 @@ read_shading_image(Microtek2_Scanner *ms)
DBG(30, "read_shading_image: ms=%p\n", ms);
md = ms->dev;
mi = &md->info[0];
mi = &md->info[md->scan_source];
if ( ! MI_WHITE_SHADING_ONLY(mi->shtrnsferequ)
@ -6053,6 +6150,7 @@ read_shading_image(Microtek2_Scanner *ms)
md->status.ncalib &= ~MD_NCALIB_ON;
md->status.flamp |= MD_FLAMP_ON;
/* md->status.tlamp &= ~MD_TLAMP_ON; */
md->status.ntrack |= MD_NTRACK_ON;
if ( md->model_flags & MD_PHANTOM_C6 )
@ -6063,6 +6161,13 @@ read_shading_image(Microtek2_Scanner *ms)
get_calib_params(ms);
#ifdef NO_PHANTOMTYPE_SHADING
/* md->status.stick &= ~MD_STICK_ON; */
/* md->status.ncalib &= ~MD_NCALIB_ON; */
/* md->status.reserved17 &= ~MD_RESERVED17_ON; */
ms->rawdat = 0;
#endif
status = scsi_send_system_status(md, ms->sfd);
if ( status != SANE_STATUS_GOOD )
return status;
@ -6083,9 +6188,21 @@ read_shading_image(Microtek2_Scanner *ms)
if ( status != SANE_STATUS_GOOD )
return status;
#ifdef NO_PHANTOMTYPE_SHADING
if ( !( md->model_flags & MD_READ_CONTROL_BIT ) )
{
#endif
status = scsi_read_system_status(md, ms->sfd);
if ( status != SANE_STATUS_GOOD )
return status;
#ifdef NO_PHANTOMTYPE_SHADING
}
#endif
#ifdef NO_PHANTOMTYPE_SHADING
if ( mi->model_code == 0x94 )
status = scsi_read_control_bits(ms);
#endif
ms->shading_image = malloc(ms->bpl * ms->src_remaining_lines);
DBG(100, "read shading image: ms->shading_image=%p, malloc'd %d bytes\n",
@ -6132,7 +6249,7 @@ read_shading_image(Microtek2_Scanner *ms)
if ( md_dump >= 3 )
{
write_shading_buf_pnm(ms);
write_shading_buf_pnm(ms, lines);
write_shading_pnm(ms);
}
@ -6166,6 +6283,11 @@ read_shading_image(Microtek2_Scanner *ms)
md->status.reserved17 &= ~MD_RESERVED17_ON;
}
#ifdef NO_PHANTOMTYPE_SHADING
if (mi->model_code == 0x94)
md->status.ncalib &= ~MD_NCALIB_ON;
#endif
status = scsi_send_system_status(md, ms->sfd);
if ( status != SANE_STATUS_GOOD )
return status;
@ -6206,21 +6328,17 @@ prepare_shading_data(Microtek2_Scanner *ms, u_int32_t lines, u_int8_t **data)
ms, lines, *data);
md = ms->dev;
mi = &md->info[0];
mi = &md->info[md->scan_source];
status = SANE_STATUS_GOOD;
get_lut_size(mi, &ms->lut_size, &ms->lut_entry_size);
if ( ms->lut_entry_size == 1 )
{
DBG(1, "prepare_shading_data: wordsize == 1 unsupported\n");
return SANE_STATUS_UNSUPPORTED;
}
length = 3 * ms->lut_entry_size * mi->geo_width / mi->calib_divisor;
if ( *data == NULL )
{
*data = (u_int8_t *) malloc(length);
DBG(100, "prepare_shading_data: malloc'd %d bytes at %p\n", length, *data);
DBG(100, "prepare_shading_data: malloc'd %d bytes at %p\n",
length, *data);
if ( *data == NULL )
{
DBG(1, "prepare_shading_data: malloc for shading table failed\n");
@ -6242,6 +6360,11 @@ prepare_shading_data(Microtek2_Scanner *ms, u_int32_t lines, u_int8_t **data)
switch( mi->data_format )
{
case MI_DATAFMT_LPLCONCAT:
if ( ms->lut_entry_size == 1 )
{
DBG(1, "prepare_shading_data: wordsize == 1 unsupported\n");
return SANE_STATUS_UNSUPPORTED;
}
for ( color = 0; color < 3; color++ )
{
for ( i = 0; i < ( mi->geo_width / mi->calib_divisor ); i++ )
@ -6274,6 +6397,12 @@ prepare_shading_data(Microtek2_Scanner *ms, u_int32_t lines, u_int8_t **data)
break;
case MI_DATAFMT_CHUNKY:
case MI_DATAFMT_9800:
if ( ms->lut_entry_size == 1 )
{
DBG(1, "prepare_shading_data: wordsize == 1 unsupported\n");
return SANE_STATUS_UNSUPPORTED;
}
for ( color = 0; color < 3; color++ )
{
for ( i = 0; i < ( mi->geo_width / mi->calib_divisor ); i++ )
@ -6312,6 +6441,22 @@ prepare_shading_data(Microtek2_Scanner *ms, u_int32_t lines, u_int8_t **data)
for ( i = 0; i < ( mi->geo_width / mi->calib_divisor ); i++ )
{
value = 0;
if ( ms->lut_entry_size == 1 )
{
for ( line = 0; line < lines; line++ )
value += *((u_int8_t *) ms->shading_image
+ line * 3 * mi->geo_width / mi->calib_divisor
+ 3 * i
+ color);
value /= lines;
*((u_int8_t *) *data
+ color * ( mi->geo_width / mi->calib_divisor ) + i) =
MIN(0xff, (u_int8_t) value);
}
else
{
for ( line = 0; line < lines; line++ )
value += *((u_int16_t *) ms->shading_image
+ line * 3 * mi->geo_width / mi->calib_divisor
@ -6323,6 +6468,8 @@ prepare_shading_data(Microtek2_Scanner *ms, u_int32_t lines, u_int8_t **data)
+ color * ( mi->geo_width / mi->calib_divisor ) + i) =
MIN(0xffff, (u_int16_t) value);
}
}
}
break;
@ -6793,7 +6940,7 @@ shading_function(Microtek2_Scanner *ms, u_int8_t *data)
md = ms->dev;
mi = &md->info[md->scan_source];
/* mi = &md->info[MD_SOURCE_FLATBED]; */
if ( ms->lut_entry_size == 1 )
{
@ -6833,6 +6980,7 @@ shading_function(Microtek2_Scanner *ms, u_int8_t *data)
value = (u_int32_t) ( ( 1073741824 / (double) value )
* ( (double) mi->balance[color]
/ 256.0) );
value = MIN(value, (u_int32_t)65535);
*((u_int16_t *) data
+ color * ( mi->geo_width / mi->calib_divisor ) + i) =
MIN(0xffff, (u_int16_t) value);
@ -7006,6 +7154,7 @@ reader_process(Microtek2_Scanner *ms)
switch ( mi->data_format )
{
case MI_DATAFMT_CHUNKY:
case MI_DATAFMT_9800:
status = chunky_proc_data(ms);
if ( status != SANE_STATUS_GOOD )
return status;
@ -7113,6 +7262,7 @@ chunky_proc_data(Microtek2_Scanner *ms)
#endif
from = ms->buf.src_buf;
from += bpl_ppl_diff;
DBG(30, "chunky_proc_data: lines=%d, bpl=%d, ppl=%d, bpp=%d, depth=%d"
" junk=%d\n", ms->src_lines_to_read, ms->bpl, ms->ppl,
@ -7120,11 +7270,10 @@ chunky_proc_data(Microtek2_Scanner *ms)
for ( line = 0; line < (u_int32_t) ms->src_lines_to_read; line++ )
{
from += bpl_ppl_diff;
status = chunky_copy_pixels(from, ms->ppl, ms->depth, ms->fp);
status = chunky_copy_pixels(ms, from);
if ( status != SANE_STATUS_GOOD )
return status;
from += ms->bpl - bpl_ppl_diff;
from += ms->bpl;
}
return SANE_STATUS_GOOD;
@ -7133,38 +7282,48 @@ chunky_proc_data(Microtek2_Scanner *ms)
/*---------- chunky_copy_pixels() --------------------------------------------*/
static SANE_Status
chunky_copy_pixels(u_int8_t *from, u_int32_t pixels, int depth, FILE * fp)
chunky_copy_pixels(Microtek2_Scanner *ms, u_int8_t *from)
{
Microtek2_Device *md;
u_int32_t pixel;
int color;
DBG(30, "chunky_copy_pixels: from=%p, pixels=%d, fp=%p, depth=%d\n",
from, pixels, fp, depth);
from, ms->ppl, ms->fp, ms->depth);
if ( depth > 8 )
md = ms->dev;
if ( ms->depth > 8 )
{
if ( !( md->model_flags & MD_16BIT_TRANSFER ) )
{
int scale1;
int scale2;
u_int16_t val16;
scale1 = 16 - depth;
scale2 = 2 * depth - 16;
for ( pixel = 0; pixel < pixels; pixel++ )
scale1 = 16 - ms->depth;
scale2 = 2 * ms->depth - 16;
for ( pixel = 0; pixel < ms->ppl; pixel++ )
{
for ( color = 0; color < 3; color++ )
{
val16 = *(u_int16_t *) from;
val16 = *( (u_int16_t *) from + 3 * pixel + color );
val16 = ( val16 << scale1 ) | ( val16 >> scale2 );
fwrite((void *) &val16, 2, 1, fp);
from += 2;
fwrite((void *) &val16, 2, 1, ms->fp);
}
}
}
else if ( depth == 8 )
fwrite((void *) from, 3 * pixels, 1, fp);
else
{
DBG(1, "chunky_copy_pixels: Unknown depth %d\n", depth);
fwrite((void *) from, 2, 3 * ms->ppl, ms->fp);
}
}
else if ( ms->depth == 8 )
{
fwrite((void *) from, 1, 3 * ms->ppl, ms->fp);
}
else
{
DBG(1, "chunky_copy_pixels: Unknown depth %d\n", ms->depth);
return SANE_STATUS_IO_ERROR;
}
@ -7346,7 +7505,8 @@ segreg_copy_pixels(Microtek2_Scanner *ms)
maxval = (float) pow(2.0, (float) ms->depth) - 1.0;
s_w = maxval;
s_d = 0.0;
shading_factor = (float) pow(2.0, (double) (md->shading_depth - ms->depth) );
shading_factor = (float) pow(2.0, (double) (md->shading_depth
- ms->depth) );
}
if ( gamma_by_backend )
@ -7587,6 +7747,7 @@ lplconcat_copy_pixels(Microtek2_Scanner *ms,
DBG(1, "lplconcat_copy_pixels: Unknown depth %d\n", ms->depth);
return SANE_STATUS_IO_ERROR;
}
if ((md->model_flags & MD_READ_CONTROL_BIT) && ms->calib_backend
&& ( ms->condensed_shading_w != NULL ))
/* apply shading by backend */
@ -7747,7 +7908,7 @@ gray_proc_data(Microtek2_Scanner *ms)
ms->src_lines_to_read, ms->bpl, ms->ppl, ms->depth);
md = ms->dev;
mi = &md->info[0];
mi = &md->info[md->scan_source];
gamma_by_backend = md->model_flags & MD_NO_GAMMA ? 1 : 0;
right_to_left = mi->direction & MI_DATSEQ_RTOL;
@ -7841,6 +8002,7 @@ gray_copy_pixels(Microtek2_Scanner *ms,
val16 = (u_int16_t) val;
if ( gamma_by_backend )
val16 = *((u_int16_t *) ms->gamma_table + val16);
if ( !( md->model_flags & MD_16BIT_TRANSFER ) )
val16 = ( val16 << scale1 ) | ( val16 >> scale2 );
fwrite((void *) &val16, 2, 1, ms->fp);
}
@ -8157,7 +8319,7 @@ get_cshading_values(Microtek2_Scanner *ms,
else
csh_offset = color * ms->ppl + pixel;
if ( ! (md->model_flags & MD_PHANTOM336CX_TYPE_SHADING) )
if ( ms->lut_entry_size == 2 )
/* condensed shading is 2 byte color data */
{
if ( ms->condensed_shading_d != NULL )
@ -8171,11 +8333,15 @@ get_cshading_values(Microtek2_Scanner *ms,
*s_w /= shading_factor;
*s_d /= shading_factor;
}
else
/* condensed shading is 8 bit data */
{
*s_w = (float) *( ms->condensed_shading_w + csh_offset );
if ( ms->condensed_shading_d != NULL )
*s_d = (float) *( ms->condensed_shading_d + csh_offset );
else
*s_d = 0.0;
}
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -90,7 +90,7 @@
#define MICROTEK2_MAJOR 0
#define MICROTEK2_MINOR 95
#define MICROTEK2_BUILD "20020127"
#define MICROTEK2_BUILD "200301082330"
#define MICROTEK2_CONFIG_FILE "microtek2.conf"
@ -606,113 +606,120 @@ typedef union {
/* Description of options not included in saneopts.h */
/******************************************************************************/
#define M_TITLE_SCANMODEGRP SANE_I18N("Scan Mode")
#define M_TITLE_GEOMGRP SANE_I18N("Geometry")
#define M_TITLE_ENHANCEGRP SANE_I18N("Enhancement")
#define M_TITLE_SMHGRP SANE_I18N("Shadow, midtone, highlight,"\
" exposure time");
#define M_TITLE_SPECIALGRP SANE_I18N("Special options")
#define M_TITLE_COLBALANCEGRP SANE_I18N("Color balance")
#define M_NAME_NOBACKTRACK "no-backtracking"
#define M_TITLE_NOBACKTRACK "Disable backtracking"
#define M_DESC_NOBACKTRACK "If checked the scanner does not perform" \
" backtracking."
#define M_TITLE_NOBACKTRACK SANE_I18N("Disable backtracking")
#define M_DESC_NOBACKTRACK SANE_I18N("If checked the scanner does not" \
" perform backtracking")
#define M_NAME_TOGGLELAMP "toggle-lamp"
#define M_TITLE_TOGGLELAMP "Toggle lamp of flatbed"
#define M_DESC_TOGGLELAMP "Toggles the lamp of the flatbed"
#define M_TITLE_TOGGLELAMP SANE_I18N("Toggle lamp of flatbed")
#define M_DESC_TOGGLELAMP SANE_I18N("Toggles the lamp of the flatbed")
#define M_NAME_CALIBBACKEND "backend-calibration"
#define M_TITLE_CALIBBACKEND "Calibration by backend"
#define M_DESC_CALIBBACKEND "If checked the color calibration before" \
" a scan is done by the backend. Uncheck" \
" this option if you experience any problem."
#define M_TITLE_CALIBBACKEND SANE_I18N("Calibration by backend")
#define M_DESC_CALIBBACKEND SANE_I18N("If checked the color calibration" \
" before a scan is done by the backend")
#define M_NAME_LIGHTLID35 "lightlid35"
#define M_TITLE_LIGHTLID35 "Use the lightlid-35mm adapter"
#define M_DESC_LIGHTLID35 "This option turns off the lamp of the" \
" flatbed during a scan. Do not expect" \
" excellent results. Maybe this option will" \
" be removed in the future."
#define M_TITLE_LIGHTLID35 SANE_I18N("Use the lightlid-35mm adapter")
#define M_DESC_LIGHTLID35 SANE_I18N("This option turns off the lamp of" \
" the flatbed during a scan")
#define M_NAME_QUALITY_SCAN "quality_scan"
#define M_TITLE_QUALITY_SCAN "Quality scan"
#define M_DESC_QUALITY_SCAN "Highest quality but lower speed"
#define M_TITLE_QUALITY_SCAN SANE_I18N("Quality scan")
#define M_DESC_QUALITY_SCAN SANE_I18N("Highest quality but lower speed")
#define M_NAME_FAST_SCAN "fast_scan"
#define M_TITLE_FAST_SCAN "Fast scan"
#define M_DESC_FAST_SCAN "Highest speed but lower quality"
#define M_TITLE_FAST_SCAN SANE_I18N("Fast scan")
#define M_DESC_FAST_SCAN SANE_I18N("Highest speed but lower quality")
#define M_NAME_AUTOADJUST "lineart-auto-adjust"
#define M_TITLE_AUTOADJUST "Automatic adjustment of threshold value"
#define M_DESC_AUTOADJUST "If checked the backend automatically tries" \
" to determine an optimal value for the" \
" threshold."
#define M_TITLE_AUTOADJUST SANE_I18N("Automatic adjustment of threshold")
#define M_DESC_AUTOADJUST SANE_I18N("If checked the backend automatically"\
" tries to determine an optimal value for the" \
" threshold.")
#define M_NAME_GAMMA_MODE "gamma-correction"
#define M_TITLE_GAMMA_MODE "Gamma correction"
#define M_DESC_GAMMA_MODE "Selects the gamma correction mode."
#define M_TITLE_GAMMA_MODE SANE_I18N("Gamma correction")
#define M_DESC_GAMMA_MODE SANE_I18N("Selects the gamma correction mode.")
#define M_NAME_GAMMA_BIND "bind-gamma"
#define M_TITLE_GAMMA_BIND "Bind gamma"
#define M_DESC_GAMMA_BIND "Use same gamma values for all colour channels."
#define M_TITLE_GAMMA_BIND SANE_I18N("Bind gamma")
#define M_DESC_GAMMA_BIND SANE_I18N("Use same gamma values for all" \
" colour channels.")
#define M_NAME_GAMMA_SCALAR "scalar-gamma"
#define M_TITLE_GAMMA_SCALAR "Scalar gamma"
#define M_DESC_GAMMA_SCALAR "Selects a value for scalar gamma correction."
#define M_TITLE_GAMMA_SCALAR SANE_I18N("Scalar gamma")
#define M_DESC_GAMMA_SCALAR SANE_I18N("Selects a value for scalar" \
" gamma correction.")
#define M_NAME_GAMMA_SCALAR_R "scalar-gamma-r"
#define M_TITLE_GAMMA_SCALAR_R "Scalar gamma red"
#define M_DESC_GAMMA_SCALAR_R "Selects a value for scalar gamma correction" \
" (red channel)"
#define M_TITLE_GAMMA_SCALAR_R SANE_I18N("Scalar gamma red")
#define M_DESC_GAMMA_SCALAR_R SANE_I18N("Selects a value for scalar gamma" \
" correction (red channel)")
#define M_NAME_GAMMA_SCALAR_G "scalar-gamma-g"
#define M_TITLE_GAMMA_SCALAR_G "Scalar gamma green"
#define M_DESC_GAMMA_SCALAR_G "Selects a value for scalar gamma correction" \
" (green channel)"
#define M_TITLE_GAMMA_SCALAR_G SANE_I18N("Scalar gamma green")
#define M_DESC_GAMMA_SCALAR_G SANE_I18N("Selects a value for scalar gamma" \
" correction (green channel)")
#define M_NAME_GAMMA_SCALAR_B "scalar-gamma-b"
#define M_TITLE_GAMMA_SCALAR_B "Scalar gamma blue"
#define M_DESC_GAMMA_SCALAR_B "Selects a value for scalar gamma correction" \
" (blue channel)"
#define M_TITLE_GAMMA_SCALAR_B SANE_I18N("Scalar gamma blue")
#define M_DESC_GAMMA_SCALAR_B SANE_I18N("Selects a value for scalar gamma" \
" correction (blue channel)")
#define M_NAME_CHANNEL "channel"
#define M_TITLE_CHANNEL "Channel"
#define M_DESC_CHANNEL "Selects the colour band, \"Master\" means," \
" that all colours are affected."
#define M_TITLE_CHANNEL SANE_I18N("Channel")
#define M_DESC_CHANNEL SANE_I18N("Selects the colour band, \"Master\"" \
" means that all colours are affected.")
#define M_NAME_MIDTONE "midtone"
#define M_TITLE_MIDTONE "Midtone"
#define M_DESC_MIDTONE "Selects which radiance level should be" \
" considered \"50 % gray\"."
#define M_TITLE_MIDTONE SANE_I18N("Midtone")
#define M_DESC_MIDTONE SANE_I18N("Selects which radiance level should" \
" be considered \"50 % gray\".")
#define M_NAME_MIDTONE_R "midtone-r"
#define M_TITLE_MIDTONE_R "Midtone for red"
#define M_DESC_MIDTONE_R "Selects which radiance level should be" \
" considered \"50 % red\"."
#define M_TITLE_MIDTONE_R SANE_I18N("Midtone for red")
#define M_DESC_MIDTONE_R SANE_I18N("Selects which radiance level should " \
" be considered \"50 % red\".")
#define M_NAME_MIDTONE_G "midtone-g"
#define M_TITLE_MIDTONE_G "Midtone for green"
#define M_DESC_MIDTONE_G "Selects which radiance level should be" \
" considered \"50 % green\"."
#define M_TITLE_MIDTONE_G SANE_I18N("Midtone for green")
#define M_DESC_MIDTONE_G SANE_I18N("Selects which radiance level should" \
" be considered \"50 % green\".")
#define M_NAME_MIDTONE_B "midtone-b"
#define M_TITLE_MIDTONE_B "Midtone for blue"
#define M_DESC_MIDTONE_B "Selects which radiance level should be" \
" considered \"50 % blue\"."
#define M_TITLE_MIDTONE_B SANE_I18N("Midtone for blue")
#define M_DESC_MIDTONE_B SANE_I18N("Selects which radiance level should" \
" be considered \"50 % blue\".")
#define M_NAME_BALANCE_R "balance-r"
#define M_TITLE_BALANCE_R "Red balance"
#define M_DESC_BALANCE_R "Balance factor for red. A value of 100% means " \
"no correction."
#define M_TITLE_BALANCE_R SANE_I18N("Red balance")
#define M_DESC_BALANCE_R SANE_I18N("Balance factor for red. A value of" \
" 100% means no correction.")
#define M_NAME_BALANCE_G "balance-g"
#define M_TITLE_BALANCE_G "Green balance"
#define M_DESC_BALANCE_G "Balance factor for green. A value of 100% "\
"means no correction."
#define M_TITLE_BALANCE_G SANE_I18N("Green balance")
#define M_DESC_BALANCE_G SANE_I18N("Balance factor for green. A value of"\
" 100% means no correction.")
#define M_NAME_BALANCE_B "balance-b"
#define M_TITLE_BALANCE_B "Blue balance"
#define M_DESC_BALANCE_B "Balance factor for blue. A value of 100% means " \
"no correction. "
#define M_TITLE_BALANCE_B SANE_I18N("Blue balance")
#define M_DESC_BALANCE_B SANE_I18N("Balance factor for blue. A value of" \
" 100% means no correction.")
#define M_NAME_BALANCE_FW "balance-fw"
#define M_TITLE_BALANCE_FW "Firmware balance"
#define M_DESC_BALANCE_FW "Sets the color balance values to the "\
"firmware provided values. "\
#define M_TITLE_BALANCE_FW SANE_I18N("Firmware balance")
#define M_DESC_BALANCE_FW SANE_I18N("Sets the color balance values to"\
" the firmware provided values.")
/******************************************************************************/
/* Structure that contains global options */
@ -775,6 +782,7 @@ typedef struct Microtek2_Info {
#define MI_DATAFMT_CHUNKY 1
#define MI_DATAFMT_LPLCONCAT 2
#define MI_DATAFMT_LPLSEGREG 3
#define MI_DATAFMT_9800 4
#define MI_DATAFMT_WORDCHUNKY 5
SANE_Byte data_format;
#define MI_COLSEQ_RED 0
@ -929,8 +937,10 @@ typedef struct Microtek2_Device {
#define MD_X6_SHORT_TRANSFER 512 /* X6 USB crashes if you read
too much */
#define MD_NO_RIS_COMMAND 1024 /* doesn't like read_image_status */
#define MD_16BIT_TRANSFER 2048 /* transfers 10/12/14bit scans as */
/* 16bit data */
u_int32_t n_control_bytes; /* for read_control_bits; the */
size_t n_control_bytes; /* for read_control_bits; the */
/* number is model dependent */
/* and can not be inquired */
u_int32_t shading_length; /* length of the shading image */
@ -1095,7 +1105,7 @@ typedef struct Microtek2_Scanner {
int current_pass; /* current pass if 3-pass scan */
int lut_size; /* size of gamma lookup table */
int lut_entry_size; /* size of one entry in lookup table */
u_int16_t lut_size_bytes; /* size of LUT in bytes */
u_int32_t lut_size_bytes; /* size of LUT in bytes */
u_int8_t word; /* word transfer, used in some read cmds */
/* MS_COLOR_X must correspond to color field in READ IMAGE STATUS */
#define MS_COLOR_RED 0
@ -1135,7 +1145,7 @@ typedef struct Microtek2_Scanner {
SANE_Bool onepass;
u_int32_t n_control_bytes; /* for READ CONTROL BITS */
size_t n_control_bytes; /* for READ CONTROL BITS */
u_int8_t *control_bytes; /* pointer to the result */
int scanning; /* true == between sane_start & sane_read=EOF */
@ -1182,7 +1192,7 @@ static void
check_option(const char *, Config_Options *);
static SANE_Status
chunky_copy_pixels(u_int8_t *, u_int32_t, int, FILE *);
chunky_copy_pixels(Microtek2_Scanner *, u_int8_t *);
static SANE_Status
chunky_proc_data(Microtek2_Scanner *);