kopia lustrzana https://gitlab.com/sane-project/backends
* Added support for Canon LiDE 35/40/50
* Reworked data conversion process to convert CIS datamerge-requests/1/head
rodzic
0b1279193f
commit
02b1a07b5d
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2005-11-19 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
* backend/genesys_gl841.c backend/genesys_devices.c:
|
||||
Added support for Canon LiDE 35/40/50
|
||||
* backend/genesys.c backend/genesys_low.h
|
||||
backend/genesys_gl646.c: Reworked data conversion
|
||||
process to convert CIS data, added new slope
|
||||
generation variant
|
||||
* backend/genesys_conv.c backend/genesys_conv_hlp.c:
|
||||
Moved conversion filter functions out of
|
||||
backend/genesys.c
|
||||
|
||||
2005-11-18 Oliver Schwartz <Oliver.Schwartz@gmx.de>
|
||||
|
||||
* backend/snapscan-options.c: Disable 2400 DPI for
|
||||
|
|
2120
backend/genesys.c
2120
backend/genesys.c
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,151 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Conversion filters for genesys backend
|
||||
*/
|
||||
|
||||
|
||||
/*8 bit*/
|
||||
#define SINGLE_BYTE
|
||||
#define BYTES_PER_COMPONENT 1
|
||||
#define COMPONENT_TYPE u_int8_t
|
||||
|
||||
#define FUNC_NAME(f) f ## _8
|
||||
|
||||
#include "genesys_conv_hlp.c"
|
||||
|
||||
#undef FUNC_NAME
|
||||
|
||||
#undef COMPONENT_TYPE
|
||||
#undef BYTES_PER_COMPONENT
|
||||
#undef SINGLE_BYTE
|
||||
|
||||
/*16 bit*/
|
||||
#define DOUBLE_BYTE
|
||||
#define BYTES_PER_COMPONENT 2
|
||||
#define COMPONENT_TYPE u_int16_t
|
||||
|
||||
#define FUNC_NAME(f) f ## _16
|
||||
|
||||
#include "genesys_conv_hlp.c"
|
||||
|
||||
#undef FUNC_NAME
|
||||
|
||||
#undef COMPONENT_TYPE
|
||||
#undef BYTES_PER_COMPONENT
|
||||
#undef DOUBLE_BYTE
|
||||
|
||||
static SANE_Status
|
||||
genesys_reverse_bits(
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
size_t bytes)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < bytes; i++) {
|
||||
*dst_data++ = ~ *src_data++;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
genesys_shrink_lines_1 (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int src_pixels,
|
||||
unsigned int dst_pixels,
|
||||
unsigned int channels)
|
||||
{
|
||||
/*in search for a correct implementation*/
|
||||
unsigned int dst_x, src_x, y, c, cnt;
|
||||
unsigned int avg[3];
|
||||
u_int8_t *src = (u_int8_t *)src_data;
|
||||
u_int8_t *dst = (u_int8_t *)dst_data;
|
||||
|
||||
src_pixels /= 8;
|
||||
dst_pixels /= 8;
|
||||
|
||||
if (src_pixels > dst_pixels) {
|
||||
/*take first _byte_*/
|
||||
for(y = 0; y < lines; y++) {
|
||||
cnt = src_pixels / 2;
|
||||
src_x = 0;
|
||||
for (dst_x = 0; dst_x < dst_pixels; dst_x++) {
|
||||
while (cnt < src_pixels && src_x < src_pixels) {
|
||||
cnt += dst_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
avg[c] = *src++;
|
||||
src_x++;
|
||||
}
|
||||
cnt -= src_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*interpolate. copy pixels*/
|
||||
for(y = 0; y < lines; y++) {
|
||||
cnt = dst_pixels / 2;
|
||||
dst_x = 0;
|
||||
for (src_x = 0; src_x < src_pixels; src_x++) {
|
||||
for (c = 0; c < channels; c++)
|
||||
avg[c] = *src++;
|
||||
while (cnt < dst_pixels && dst_x < dst_pixels) {
|
||||
cnt += src_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c];
|
||||
dst_x++;
|
||||
}
|
||||
cnt -= dst_pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Conversion filters for genesys backend
|
||||
*/
|
||||
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_reorder_components_cis) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int pixels)
|
||||
{
|
||||
unsigned int x, y;
|
||||
u_int8_t *src[3];
|
||||
u_int8_t *dst = dst_data;
|
||||
unsigned int rest = pixels * 2 * BYTES_PER_COMPONENT;
|
||||
|
||||
src[0] = src_data + pixels * BYTES_PER_COMPONENT * 0;
|
||||
src[1] = src_data + pixels * BYTES_PER_COMPONENT * 1;
|
||||
src[2] = src_data + pixels * BYTES_PER_COMPONENT * 2;
|
||||
|
||||
for(y = 0; y < lines; y++) {
|
||||
for(x = 0; x < pixels; x++) {
|
||||
|
||||
#ifndef DOUBLE_BYTE
|
||||
*dst++ = *src[0]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[2]++;
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
*dst++ = *src[0]++;
|
||||
*dst++ = *src[0]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[2]++;
|
||||
*dst++ = *src[2]++;
|
||||
# else
|
||||
*dst++ = src[0][1];
|
||||
*dst++ = src[0][0];
|
||||
*dst++ = src[1][1];
|
||||
*dst++ = src[1][0];
|
||||
*dst++ = src[2][1];
|
||||
*dst++ = src[2][0];
|
||||
src[0] += 2;
|
||||
src[1] += 2;
|
||||
src[2] += 2;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
src[0] += rest;
|
||||
src[1] += rest;
|
||||
src[2] += rest;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_reorder_components_cis_bgr) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int pixels)
|
||||
{
|
||||
unsigned int x, y;
|
||||
u_int8_t *src[3];
|
||||
u_int8_t *dst = dst_data;
|
||||
unsigned int rest = pixels * 2 * BYTES_PER_COMPONENT;
|
||||
|
||||
src[0] = src_data + pixels * BYTES_PER_COMPONENT * 0;
|
||||
src[1] = src_data + pixels * BYTES_PER_COMPONENT * 1;
|
||||
src[2] = src_data + pixels * BYTES_PER_COMPONENT * 2;
|
||||
|
||||
for(y = 0; y < lines; y++) {
|
||||
for(x = 0; x < pixels; x++) {
|
||||
#ifndef DOUBLE_BYTE
|
||||
*dst++ = *src[2]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[0]++;
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
*dst++ = *src[2]++;
|
||||
*dst++ = *src[2]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[1]++;
|
||||
*dst++ = *src[0]++;
|
||||
*dst++ = *src[0]++;
|
||||
# else
|
||||
*dst++ = src[2][1];
|
||||
*dst++ = src[2][0];
|
||||
*dst++ = src[1][1];
|
||||
*dst++ = src[1][0];
|
||||
*dst++ = src[0][1];
|
||||
*dst++ = src[0][0];
|
||||
src[0] += 2;
|
||||
src[1] += 2;
|
||||
src[2] += 2;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
src[0] += rest;
|
||||
src[1] += rest;
|
||||
src[2] += rest;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_reorder_components_bgr) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int pixels)
|
||||
{
|
||||
unsigned int c;
|
||||
u_int8_t *src = src_data;
|
||||
u_int8_t *dst = dst_data;
|
||||
|
||||
for(c = 0; c < lines * pixels; c++) {
|
||||
|
||||
#ifndef DOUBLE_BYTE
|
||||
*dst++ = src[2];
|
||||
*dst++ = src[1];
|
||||
*dst++ = src[0];
|
||||
src += 3;
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
*dst++ = src[2 * 2 + 0];
|
||||
*dst++ = src[2 * 2 + 1];
|
||||
*dst++ = src[1 * 2 + 0];
|
||||
*dst++ = src[1 * 2 + 1];
|
||||
*dst++ = src[0 * 2 + 0];
|
||||
*dst++ = src[0 * 2 + 1];
|
||||
# else
|
||||
*dst++ = src[2 * 2 + 1];
|
||||
*dst++ = src[2 * 2 + 0];
|
||||
*dst++ = src[1 * 2 + 1];
|
||||
*dst++ = src[1 * 2 + 0];
|
||||
*dst++ = src[0 * 2 + 1];
|
||||
*dst++ = src[0 * 2 + 0];
|
||||
# endif
|
||||
src += 3 * 2;
|
||||
#endif
|
||||
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
#if defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN)
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_reorder_components_endian) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int pixels,
|
||||
unsigned int channels)
|
||||
{
|
||||
unsigned int c;
|
||||
u_int8_t *src = src_data;
|
||||
u_int8_t *dst = dst_data;
|
||||
|
||||
for(c = 0; c < lines * pixels * channels; c++) {
|
||||
*dst++ = src[1];
|
||||
*dst++ = src[0];
|
||||
src += 2;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
#endif /*defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN)*/
|
||||
|
||||
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_reverse_ccd) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int pixels,
|
||||
unsigned int channels,
|
||||
unsigned int *ccd_shift,
|
||||
unsigned int component_count)
|
||||
{
|
||||
unsigned int x, y, c;
|
||||
COMPONENT_TYPE *src = (COMPONENT_TYPE *)src_data;
|
||||
COMPONENT_TYPE *dst = (COMPONENT_TYPE *)dst_data;
|
||||
COMPONENT_TYPE *srcp;
|
||||
COMPONENT_TYPE *dstp;
|
||||
unsigned int pitch = pixels * channels;
|
||||
unsigned int ccd_shift_pitch[12];
|
||||
unsigned int *csp;
|
||||
|
||||
for (c = 0; c < component_count; c++)
|
||||
ccd_shift_pitch[c] = ccd_shift[c] * pitch;
|
||||
|
||||
/*
|
||||
* cache efficiency:
|
||||
we are processing a single line component_count times, so it should fit
|
||||
into the cpu cache for maximum efficiency. our lines take
|
||||
maximum 252kb(3 channels, 16bit, 2400dpi, full gl841 shading range)
|
||||
* instruction efficiency:
|
||||
the innermost loop runs long and consists of 3 adds, one compare,
|
||||
2 derefences.
|
||||
*/
|
||||
/*
|
||||
for (y = 0; y < lines; y++) {
|
||||
csp = ccd_shift_pitch;
|
||||
for (c = 0; c < component_count; c++) {
|
||||
srcp = src + c + *csp++;
|
||||
dstp = dst + c;
|
||||
for (x = 0; x < pitch; x += component_count) {
|
||||
*dstp = *srcp;
|
||||
srcp += component_count;
|
||||
dstp += component_count;
|
||||
}
|
||||
}
|
||||
dst += pitch;
|
||||
src += pitch;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
* cache efficency:
|
||||
here only line_dist_pitch needs to stay in cache. 12*4 = 48 bytes
|
||||
* instruction efficiency:
|
||||
we have a short running inner loop, consisting of 4 incs, 2 compare, 1 add,
|
||||
2 dereference and 1 indexed dereference.
|
||||
the enclosing loop is long running, consisting of 1 add, 1 compare.
|
||||
*/
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
for (y = 0; y < lines; y++) {
|
||||
for (x = 0; x < pitch; x += component_count) {
|
||||
csp = ccd_shift_pitch;
|
||||
for (c = 0; c < component_count && c + x < pitch; c++) {
|
||||
*dstp = srcp[*csp++];
|
||||
dstp++;
|
||||
srcp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
FUNC_NAME(genesys_shrink_lines) (
|
||||
u_int8_t *src_data,
|
||||
u_int8_t *dst_data,
|
||||
unsigned int lines,
|
||||
unsigned int src_pixels,
|
||||
unsigned int dst_pixels,
|
||||
unsigned int channels)
|
||||
{
|
||||
unsigned int dst_x, src_x, y, c, cnt;
|
||||
unsigned int avg[3];
|
||||
unsigned int count;
|
||||
COMPONENT_TYPE *src = (COMPONENT_TYPE *)src_data;
|
||||
COMPONENT_TYPE *dst = (COMPONENT_TYPE *)dst_data;
|
||||
|
||||
if (src_pixels > dst_pixels) {
|
||||
/*average*/
|
||||
for(y = 0; y < lines; y++) {
|
||||
cnt = src_pixels / 2;
|
||||
src_x = 0;
|
||||
for (dst_x = 0; dst_x < dst_pixels; dst_x++) {
|
||||
count = 0;
|
||||
while (cnt < src_pixels && src_x < src_pixels) {
|
||||
cnt += dst_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
avg[c] += *src++;
|
||||
src_x++;
|
||||
count++;
|
||||
}
|
||||
cnt -= src_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c] / count;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*interpolate. copy pixels*/
|
||||
for(y = 0; y < lines; y++) {
|
||||
cnt = dst_pixels / 2;
|
||||
dst_x = 0;
|
||||
for (src_x = 0; src_x < src_pixels; src_x++) {
|
||||
for (c = 0; c < channels; c++)
|
||||
avg[c] = *src++;
|
||||
while (cnt < dst_pixels && dst_x < dst_pixels) {
|
||||
cnt += src_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c];
|
||||
dst_x++;
|
||||
}
|
||||
cnt -= dst_pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
Copyright (C) 2004, 2005 Stephane Voltz <svoltz@numericable.fr>
|
||||
Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -55,38 +56,51 @@ static Genesys_Frontend Wolfson[] = {
|
|||
, {0x00, 0x00, 0x00}
|
||||
, {0x80, 0x80, 0x80}
|
||||
, {0x02, 0x02, 0x02}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* UMAX */
|
||||
{{0x00, 0x03, 0x05, 0x03}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xc8, 0xc8, 0xc8}
|
||||
, {0x04, 0x04, 0x04}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* ST12 */
|
||||
{{0x00, 0x03, 0x05, 0x21}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xc8, 0xc8, 0xc8}
|
||||
, {0x06, 0x06, 0x06}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* ST24 */
|
||||
{{0x00, 0x03, 0x05, 0x12}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xc8, 0xc8, 0xc8}
|
||||
, {0x04, 0x04, 0x04}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* MD6228/MD6471 */
|
||||
{{0x00, 0x03, 0x05, 0x02}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xc0, 0xc0, 0xc0}
|
||||
, {0x07, 0x07, 0x07}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* HP2400c */
|
||||
{{0x00, 0x03, 0x04, 0x02}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xb0, 0xb0, 0xb0}
|
||||
, {0x04, 0x04, 0x04}
|
||||
, {0x00, 0x00, 0x00}
|
||||
}
|
||||
, /* HP2300c */
|
||||
{{0x00, 0x3d, 0x08, 0x00}
|
||||
, {0x00, 0x00, 0x00}
|
||||
, {0xe1, 0xe1, 0xe1}
|
||||
, {0x93, 0x93, 0x93}
|
||||
, {0x00, 0x19, 0x06}
|
||||
}
|
||||
, /* CANONLIDE35 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -180,11 +194,34 @@ static Genesys_Sensor Sensor[] = {
|
|||
,
|
||||
2.1, 2.1, 2.1,
|
||||
NULL, NULL, NULL}
|
||||
,
|
||||
/* CANOLIDE35 */
|
||||
{1200,
|
||||
/*TODO: find a good reason for keeping all three following variables*/
|
||||
87, /*(black)*/
|
||||
87, /* (dummy)*/
|
||||
0, /* (startxoffset)*/
|
||||
10400, /*sensor_pixels*/
|
||||
210,
|
||||
200,
|
||||
{0x00, 0x00, 0x00, 0x00},
|
||||
{0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x50,
|
||||
0x00, 0x00, 0x00, 0x00 /* TODO(these do no harm, but may be neccessery for CCD)*/
|
||||
},
|
||||
{0x05, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, /*[GB](HI|LOW) not needed for cis*/
|
||||
0x3a, 0x03,
|
||||
0x40, /*TODO: bit7*/
|
||||
0x00, 0x00, 0x00, 0x00 /*TODO (these do no harm, but may be neccessery for CCD)*/
|
||||
}
|
||||
,
|
||||
0.45, 0.45, 0.45,
|
||||
NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
/** for General Purpose Output specific settings:
|
||||
* initial GPO value (registers 0x66-0x67)
|
||||
* GPO enable mask (registers 0x68-0x69)
|
||||
* initial GPO value (registers 0x66-0x67/0x6c-0x6d)
|
||||
* GPO enable mask (registers 0x68-0x69/0x6e-0x6f)
|
||||
*/
|
||||
static Genesys_Gpo Gpo[] = {
|
||||
/* UMAX */
|
||||
|
@ -234,6 +271,14 @@ static Genesys_Gpo Gpo[] = {
|
|||
{0x00, 0x00}
|
||||
,
|
||||
}
|
||||
,
|
||||
/* CANONLIDE35 */
|
||||
{
|
||||
{0x81, 0x80}
|
||||
,
|
||||
{0xef, 0x80}
|
||||
,
|
||||
}
|
||||
};
|
||||
|
||||
#define MOTOR_ST24 2
|
||||
|
@ -241,24 +286,112 @@ static Genesys_Motor Motor[] = {
|
|||
/* UMAX */
|
||||
{
|
||||
1200, /* motor base steps */
|
||||
2400 /* maximum motor resolution */
|
||||
}
|
||||
,
|
||||
2400, /* maximum motor resolution */
|
||||
1, /* maximum step mode*/
|
||||
{{
|
||||
11000, /* maximum start speed */
|
||||
3000, /* maximum end speed */
|
||||
128, /* step count */
|
||||
1.0, /* nonlinearity */
|
||||
},
|
||||
{
|
||||
11000,
|
||||
3000,
|
||||
128,
|
||||
1.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ /* MD5345/6228/6471 */
|
||||
1200,
|
||||
2400}
|
||||
,
|
||||
2400,
|
||||
1,
|
||||
{{
|
||||
2000,
|
||||
1375,
|
||||
128,
|
||||
0.5,
|
||||
},
|
||||
{
|
||||
2000,
|
||||
1375,
|
||||
128,
|
||||
0.5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ /* ST24 */
|
||||
2400,
|
||||
2400}
|
||||
,
|
||||
2400,
|
||||
1,
|
||||
{{
|
||||
2289,
|
||||
2100,
|
||||
128,
|
||||
0.3,
|
||||
},
|
||||
{
|
||||
2289,
|
||||
2100,
|
||||
128,
|
||||
0.3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ /* HP 2400c */
|
||||
1200,
|
||||
2400}
|
||||
,
|
||||
2400,
|
||||
1,
|
||||
{{
|
||||
11000,
|
||||
3000,
|
||||
128,
|
||||
1.0,
|
||||
},
|
||||
{
|
||||
11000,
|
||||
3000,
|
||||
128,
|
||||
1.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ /* HP 2300c */
|
||||
600,
|
||||
1200}
|
||||
1200,
|
||||
1,
|
||||
{{
|
||||
3200,
|
||||
1200,
|
||||
128,
|
||||
0.5,
|
||||
},
|
||||
{
|
||||
3200,
|
||||
1200,
|
||||
128,
|
||||
0.5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ /* Canon LiDE 35 */
|
||||
1200,
|
||||
2400,
|
||||
1,
|
||||
{{
|
||||
3000,
|
||||
1300,
|
||||
50,
|
||||
0.8,
|
||||
},
|
||||
{
|
||||
3000,
|
||||
1400,
|
||||
50,
|
||||
0.8,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* here we have the various device settings...
|
||||
|
@ -309,7 +442,7 @@ static Genesys_Model canon_lide_50_model = {
|
|||
"canon-lide-50", /* Name */
|
||||
"Canon", /* Device vendor string */
|
||||
"LiDE 35/50", /* Device model name */
|
||||
GENESYS_GL646,
|
||||
GENESYS_GL841,
|
||||
NULL,
|
||||
|
||||
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
|
||||
|
@ -317,13 +450,13 @@ static Genesys_Model canon_lide_50_model = {
|
|||
{16, 8, 0}, /* possible depths in gray mode */
|
||||
{16, 8, 0}, /* possible depths in color mode */
|
||||
|
||||
SANE_FIX (3.5), /* Start of scan area in mm (x) */
|
||||
SANE_FIX (7.5), /* Start of scan area in mm (y) */
|
||||
SANE_FIX (0.42), /* Start of scan area in mm (x) */
|
||||
SANE_FIX (7.9), /* Start of scan area in mm (y) */
|
||||
SANE_FIX (218.0), /* Size of scan area in mm (x) */
|
||||
SANE_FIX (299.0), /* Size of scan area in mm (y) */
|
||||
|
||||
SANE_FIX (0.0), /* Start of white strip in mm (y) */
|
||||
SANE_FIX (1.0), /* Start of black mark in mm (x) */
|
||||
SANE_FIX (3.0), /* Start of white strip in mm (y) */
|
||||
SANE_FIX (0.0), /* Start of black mark in mm (x) */
|
||||
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */
|
||||
|
@ -334,17 +467,20 @@ static Genesys_Model canon_lide_50_model = {
|
|||
|
||||
0, 0, 0, /* RGB CCD Line-distance correction in pixel */
|
||||
|
||||
COLOR_ORDER_BGR, /* Order of the CCD/CIS colors */
|
||||
COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */
|
||||
|
||||
SANE_TRUE, /* Is this a CIS scanner? */
|
||||
CCD_UMAX,
|
||||
DAC_WOLFSON_UMAX,
|
||||
GPO_UMAX,
|
||||
MOTOR_UMAX,
|
||||
GENESYS_FLAG_UNTESTED, /* Which flags are needed for this scanner? */
|
||||
/* untested, values set by hmg */
|
||||
20,
|
||||
200
|
||||
CCD_CANONLIDE35,
|
||||
DAC_CANONLIDE35,
|
||||
GPO_CANONLIDE35,
|
||||
MOTOR_CANONLIDE35,
|
||||
GENESYS_FLAG_UNTESTED
|
||||
| GENESYS_FLAG_LAZY_INIT
|
||||
| GENESYS_FLAG_SKIP_WARMUP
|
||||
| GENESYS_FLAG_OFFSET_CALIBRATION
|
||||
| GENESYS_FLAG_DARK_WHITE_CALIBRATION, /* Which flags are needed for this scanner? */
|
||||
300,
|
||||
400
|
||||
};
|
||||
|
||||
static Genesys_Model hp2300c_model = {
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
Copyright (C) 2003 Oliver Rauch
|
||||
Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
Copyright (C) 2004 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
Copyright (C) 2004, 2005 Stephane Voltz <svoltz@numericable.fr>
|
||||
Copyright (C) 2004, 2005 Stephane Voltz <stefdev@modulonet.fr>
|
||||
Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -249,6 +250,209 @@ enum
|
|||
GENESYS_GL646_MAX_REGS
|
||||
};
|
||||
|
||||
/* Write to many registers */
|
||||
static SANE_Status
|
||||
gl646_bulk_write_register (Genesys_Device * dev,
|
||||
Genesys_Register_Set * reg, size_t size)
|
||||
{
|
||||
SANE_Status status;
|
||||
u_int8_t outdata[8];
|
||||
unsigned int i;
|
||||
|
||||
/* handle differently sized register sets, reg[0x00] is the last one */
|
||||
i = 0;
|
||||
while ((i < size / 2) && (reg[i].address != 0))
|
||||
i++;
|
||||
size = i * 2;
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_write_register (size = %lu)\n",
|
||||
(u_long) size);
|
||||
|
||||
|
||||
outdata[0] = BULK_OUT;
|
||||
outdata[1] = BULK_REGISTER;
|
||||
outdata[2] = 0x00;
|
||||
outdata[3] = 0x00;
|
||||
outdata[4] = (size & 0xff);
|
||||
outdata[5] = ((size >> 8) & 0xff);
|
||||
outdata[6] = ((size >> 16) & 0xff);
|
||||
outdata[7] = ((size >> 24) & 0xff);
|
||||
|
||||
status =
|
||||
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
|
||||
VALUE_BUFFER, INDEX, sizeof (outdata), outdata);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_write_register: failed while writing command: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
status = sanei_usb_write_bulk (dev->dn, (u_int8_t *) reg, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_write_register: failed while writing bulk data: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
for (i = 0; i < size / 2; i++)
|
||||
DBG (DBG_io2, "reg[0x%02x] = 0x%02x\n", ((u_int8_t *) reg)[2 * i],
|
||||
((u_int8_t *) reg)[2 * i + 1]);
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_write_register: wrote %d bytes\n", size);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Write bulk data (e.g. shading, gamma) */
|
||||
static SANE_Status
|
||||
gl646_bulk_write_data (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len)
|
||||
{
|
||||
SANE_Status status;
|
||||
size_t size;
|
||||
u_int8_t outdata[8];
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_write_data writing %lu bytes\n",
|
||||
(u_long) len);
|
||||
|
||||
status =
|
||||
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
|
||||
VALUE_SET_REGISTER, INDEX, 1, &addr);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_write_data failed while setting register: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (len > BULKOUT_MAXSIZE)
|
||||
size = BULKOUT_MAXSIZE;
|
||||
else
|
||||
size = len;
|
||||
|
||||
outdata[0] = BULK_OUT;
|
||||
outdata[1] = BULK_RAM;
|
||||
outdata[2] = 0x00;
|
||||
outdata[3] = 0x00;
|
||||
outdata[4] = (size & 0xff);
|
||||
outdata[5] = ((size >> 8) & 0xff);
|
||||
outdata[6] = ((size >> 16) & 0xff);
|
||||
outdata[7] = ((size >> 24) & 0xff);
|
||||
|
||||
status =
|
||||
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
|
||||
VALUE_BUFFER, INDEX, sizeof (outdata),
|
||||
outdata);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_write_data failed while writing command: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
status = sanei_usb_write_bulk (dev->dn, data, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_write_data failed while writing bulk data: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
DBG (DBG_io2,
|
||||
"gl646_bulk_write_data wrote %lu bytes, %lu remaining\n",
|
||||
(u_long) size, (u_long) (len - size));
|
||||
|
||||
len -= size;
|
||||
data += size;
|
||||
}
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_write_data: completed\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Read bulk data (e.g. scanned data) */
|
||||
static SANE_Status
|
||||
gl646_bulk_read_data (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len)
|
||||
{
|
||||
SANE_Status status;
|
||||
size_t size;
|
||||
u_int8_t outdata[8];
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_read_data: requesting %lu bytes\n",
|
||||
(u_long) len);
|
||||
|
||||
status =
|
||||
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
|
||||
VALUE_SET_REGISTER, INDEX, 1, &addr);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_read_data failed while setting register: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
outdata[0] = BULK_IN;
|
||||
outdata[1] = BULK_RAM;
|
||||
outdata[2] = 0x00;
|
||||
outdata[3] = 0x00;
|
||||
outdata[4] = (len & 0xff);
|
||||
outdata[5] = ((len >> 8) & 0xff);
|
||||
outdata[6] = ((len >> 16) & 0xff);
|
||||
outdata[7] = ((len >> 24) & 0xff);
|
||||
|
||||
status =
|
||||
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
|
||||
VALUE_BUFFER, INDEX, sizeof (outdata), outdata);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_read_data failed while writing command: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (len > BULKIN_MAXSIZE)
|
||||
size = BULKIN_MAXSIZE;
|
||||
else
|
||||
size = len;
|
||||
|
||||
DBG (DBG_io2,
|
||||
"gl646_bulk_read_data: trying to read %lu bytes of data\n",
|
||||
(u_long) size);
|
||||
status = sanei_usb_read_bulk (dev->dn, data, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_bulk_read_data failed while reading bulk data: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
DBG (DBG_io2,
|
||||
"gl646_bulk_read_data read %lu bytes, %lu remaining\n",
|
||||
(u_long) size, (u_long) (len - size));
|
||||
|
||||
len -= size;
|
||||
data += size;
|
||||
}
|
||||
|
||||
DBG (DBG_io, "gl646_bulk_read_data: completed\n");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static SANE_Bool
|
||||
gl646_get_fast_feed_bit (Genesys_Register_Set * regs)
|
||||
|
@ -606,7 +810,7 @@ gl646_asic_test (Genesys_Device * dev)
|
|||
return status;
|
||||
}
|
||||
|
||||
status = sanei_genesys_bulk_write_data (dev, 0x3c, data, size);
|
||||
status = gl646_bulk_write_data (dev, 0x3c, data, size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "gl646_asic_test: failed to bulk write data: %s\n",
|
||||
|
@ -627,7 +831,7 @@ gl646_asic_test (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_read_data (dev, 0x45, (u_int8_t *) verify_data,
|
||||
gl646_bulk_read_data (dev, 0x45, (u_int8_t *) verify_data,
|
||||
verify_size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -881,7 +1085,7 @@ gl646_send_slope_table (Genesys_Device * dev, int table_nr,
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_data (dev, 0x3c, (u_int8_t *) slope_table,
|
||||
gl646_bulk_write_data (dev, 0x3c, (u_int8_t *) slope_table,
|
||||
steps * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -1064,6 +1268,24 @@ gl646_set_lamp_power (Genesys_Register_Set * regs, SANE_Bool set)
|
|||
}
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
gl646_save_power(Genesys_Device * dev, SANE_Bool enable) {
|
||||
|
||||
DBG(DBG_proc, "gl646_save_power: enable = %d\n", enable);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
|
||||
gl646_set_fe (dev, AFE_POWER_SAVE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
gl646_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
|
||||
{
|
||||
|
@ -1139,7 +1361,7 @@ gl646_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
|
|||
local_reg[5].value = exposure_time & 255; /* lowbyte */
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, local_reg, sizeof (local_reg));
|
||||
gl646_bulk_write_register (dev, local_reg, sizeof (local_reg));
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
DBG (DBG_error,
|
||||
"gl646_set_powersaving: Failed to bulk write registers: %s\n",
|
||||
|
@ -1173,7 +1395,7 @@ gl646_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
|
|||
local_reg[2].value = 0x00; /* do not start motor yet */
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, local_reg, sizeof (local_reg));
|
||||
gl646_bulk_write_register (dev, local_reg, sizeof (local_reg));
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
|
@ -1239,7 +1461,7 @@ gl646_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
|
|||
static SANE_Status
|
||||
gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
|
||||
{
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS];
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS+1];
|
||||
SANE_Status status;
|
||||
u_int8_t val = 0;
|
||||
u_int8_t prepare_steps;
|
||||
|
@ -1284,7 +1506,7 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
|
|||
usleep (200000UL);
|
||||
}
|
||||
|
||||
memcpy (local_reg, dev->reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
|
||||
prepare_steps = 4;
|
||||
exposure_time = 6 * MOTOR_SPEED_MAX;
|
||||
|
@ -1388,7 +1610,7 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, local_reg,
|
||||
gl646_bulk_write_register (dev, local_reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -1405,7 +1627,7 @@ gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
|
|||
sane_strstatus (status));
|
||||
sanei_genesys_stop_motor (dev);
|
||||
/* send original registers */
|
||||
sanei_genesys_bulk_write_register (dev, dev->reg,
|
||||
gl646_bulk_write_register (dev, dev->reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
return status;
|
||||
}
|
||||
|
@ -1541,7 +1763,7 @@ gl646_park_head (Genesys_Device * dev, Genesys_Register_Set * reg,
|
|||
local_reg[i++].value = LOBYTE (exposure_time);
|
||||
|
||||
/* writes register */
|
||||
status = sanei_genesys_bulk_write_register (dev, local_reg, i * 2);
|
||||
status = gl646_bulk_write_register (dev, local_reg, i * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
|
@ -1569,7 +1791,7 @@ gl646_park_head (Genesys_Device * dev, Genesys_Register_Set * reg,
|
|||
sane_strstatus (status));
|
||||
sanei_genesys_stop_motor (dev);
|
||||
/* restore original registers */
|
||||
sanei_genesys_bulk_write_register (dev, reg,
|
||||
gl646_bulk_write_register (dev, reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
return status;
|
||||
}
|
||||
|
@ -1631,7 +1853,7 @@ gl646_search_start_position (Genesys_Device * dev)
|
|||
SANE_Status status;
|
||||
u_int8_t *data;
|
||||
u_int16_t slope_table0[256];
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS];
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS + 1];
|
||||
int i, steps;
|
||||
int exposure_time, half_ccd = 0;
|
||||
struct timeval tv;
|
||||
|
@ -1642,7 +1864,7 @@ gl646_search_start_position (Genesys_Device * dev)
|
|||
|
||||
DBG (DBG_proc, "gl646_search_start_position\n");
|
||||
memset (local_reg, 0, sizeof (local_reg));
|
||||
memcpy (local_reg, dev->reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
|
||||
gettimeofday (&tv, NULL);
|
||||
/* is scanner warm enough ? */
|
||||
|
@ -1770,7 +1992,7 @@ gl646_search_start_position (Genesys_Device * dev)
|
|||
|
||||
/* send to scanner */
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, local_reg,
|
||||
gl646_bulk_write_register (dev, local_reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -1890,7 +2112,7 @@ gl646_search_start_position (Genesys_Device * dev)
|
|||
/* update regs to copy ASIC internal state */
|
||||
dev->reg[reg_0x01].value = local_reg[reg_0x01].value;
|
||||
dev->reg[reg_0x02].value = local_reg[reg_0x02].value;
|
||||
memcpy (dev->reg, local_reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (dev->reg, local_reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
|
||||
status =
|
||||
sanei_genesys_search_reference_point (dev, data, start_pixel, dpi, pixels,
|
||||
|
@ -2058,7 +2280,7 @@ gl646_init_regs_for_coarse_calibration (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, dev->calib_reg,
|
||||
gl646_bulk_write_register (dev, dev->calib_reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -2341,7 +2563,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, dev->calib_reg,
|
||||
gl646_bulk_write_register (dev, dev->calib_reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -2389,9 +2611,15 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
int dummy;
|
||||
u_int32_t steps_sum, z1, z2;
|
||||
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
|
||||
SANE_Status status;
|
||||
unsigned int stagger;
|
||||
unsigned int max_shift;
|
||||
float read_factor;
|
||||
size_t requested_buffer_size;
|
||||
size_t read_buffer_size;
|
||||
|
||||
DBG (DBG_info,
|
||||
"gl646_init_register_for_scan settings:\nResolution: %ux%uDPI\n"
|
||||
"gl646_init_regs_for_scan settings:\nResolution: %ux%uDPI\n"
|
||||
"Lines : %u\nPPL : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n",
|
||||
dev->settings.xres, dev->settings.yres, dev->settings.lines,
|
||||
dev->settings.pixels, dev->settings.tl_x, dev->settings.tl_y,
|
||||
|
@ -2421,16 +2649,16 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
else if (i <= 24)
|
||||
dpiset = dev->sensor.optical_res / 12;
|
||||
DBG (DBG_info,
|
||||
"gl646_init_register_for_scan : i=%d, dpiset=%d, half_ccd=%d\n", i,
|
||||
"gl646_init_regs_for_scan : i=%d, dpiset=%d, half_ccd=%d\n", i,
|
||||
dpiset, half_ccd);
|
||||
|
||||
/* sigh ... MD6471 motor's provide vertically shifted columns at hi res ... */
|
||||
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
|
||||
dev->stagger = (4 * dev->settings.yres) / dev->motor.base_ydpi;
|
||||
stagger = (4 * dev->settings.yres) / dev->motor.base_ydpi;
|
||||
else
|
||||
dev->stagger = 0;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan : stagger=%d lines\n",
|
||||
dev->stagger);
|
||||
stagger = 0;
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan : stagger=%d lines\n",
|
||||
stagger);
|
||||
|
||||
/* compute scan parameters values */
|
||||
/* pixels are allways given at half or full CCD optical resolution */
|
||||
|
@ -2444,11 +2672,11 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
start += (dev->settings.tl_x * dev->sensor.optical_res) / MM_PER_INCH;
|
||||
if (half_ccd)
|
||||
start = start / 2;
|
||||
if (dev->stagger > 0)
|
||||
if (stagger > 0)
|
||||
start = start | 1;
|
||||
|
||||
/* compute correct pixels number */
|
||||
dev->read_factor = 0.0;
|
||||
read_factor = 0.0;
|
||||
pixels =
|
||||
(dev->settings.pixels * dev->sensor.optical_res) / dev->settings.xres;
|
||||
if (half_ccd)
|
||||
|
@ -2462,10 +2690,10 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
pixels = ((pixels + i - 1) / i) * i;
|
||||
/* sets flag for reading */
|
||||
/* the 2 factor is due to the fact that dpiset = 2 desired ccd dpi */
|
||||
dev->read_factor = (float) pixels / (float) (dev->settings.pixels * 2);
|
||||
read_factor = (float) pixels / (float) (dev->settings.pixels * 2);
|
||||
DBG (DBG_info,
|
||||
"gl646_init_register_for_scan : rounding up pixels, factor=%f\n",
|
||||
dev->read_factor);
|
||||
"gl646_init_regs_for_scan : rounding up pixels, factor=%f\n",
|
||||
read_factor);
|
||||
}
|
||||
|
||||
end = start + pixels;
|
||||
|
@ -2480,17 +2708,17 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
/* all values are assumed >= 0 */
|
||||
if (channels > 1)
|
||||
{
|
||||
dev->max_shift = dev->model->ld_shift_r;
|
||||
if (dev->model->ld_shift_b > dev->max_shift)
|
||||
dev->max_shift = dev->model->ld_shift_b;
|
||||
if (dev->model->ld_shift_g > dev->max_shift)
|
||||
dev->max_shift = dev->model->ld_shift_g;
|
||||
dev->max_shift =
|
||||
(dev->max_shift * dev->settings.yres) / dev->motor.base_ydpi;
|
||||
max_shift = dev->model->ld_shift_r;
|
||||
if (dev->model->ld_shift_b > max_shift)
|
||||
max_shift = dev->model->ld_shift_b;
|
||||
if (dev->model->ld_shift_g > max_shift)
|
||||
max_shift = dev->model->ld_shift_g;
|
||||
max_shift =
|
||||
(max_shift * dev->settings.yres) / dev->motor.base_ydpi;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->max_shift = 0;
|
||||
max_shift = 0;
|
||||
}
|
||||
|
||||
/* enable shading */
|
||||
|
@ -2597,7 +2825,7 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
slope_dpi = 100;
|
||||
slope_dpi = slope_dpi * (1 + dummy);
|
||||
|
||||
lincnt = dev->settings.lines - 1 + dev->max_shift + dev->stagger;
|
||||
lincnt = dev->settings.lines - 1 + max_shift + stagger;
|
||||
|
||||
dev->reg[reg_0x25].value = LOBYTE (HIWORD (lincnt)); /* scan line numbers - here one line */
|
||||
dev->reg[reg_0x26].value = HIBYTE (LOWORD (lincnt));
|
||||
|
@ -2696,30 +2924,30 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
move = (SANE_UNFIX (dev->model->y_offset_calib) * move_dpi) / MM_PER_INCH;
|
||||
else
|
||||
move = 0;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
|
||||
move += (SANE_UNFIX (dev->model->y_offset) * move_dpi) / MM_PER_INCH;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
|
||||
/* add tl_y to base movement */
|
||||
/* move += (dev->settings.tl_y * dev->motor.optical_ydpi) / MM_PER_INCH; */
|
||||
move += (dev->settings.tl_y * move_dpi) / MM_PER_INCH;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
|
||||
/* substract current head position */
|
||||
move -= dev->scanhead_position_in_steps - dev->stagger;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
move -= dev->scanhead_position_in_steps - stagger;
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
|
||||
if ((dev->reg[reg_0x02].value & REG02_FASTFED)
|
||||
&& (dev->model->motor_type == MOTOR_HP2300))
|
||||
{
|
||||
move *= 2;
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
}
|
||||
|
||||
/* round it */
|
||||
move = ((move + dummy) / (dummy + 1)) * (dummy + 1);
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: move=%d steps\n", move);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: move=%d steps\n", move);
|
||||
|
||||
/* set feed steps number of motor move */
|
||||
dev->reg[reg_0x3d].value = LOBYTE (HIWORD (move));
|
||||
|
@ -2731,8 +2959,8 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
dev->slope_table0,
|
||||
dev->reg[reg_0x21].value,
|
||||
move, dev->reg[reg_0x22].value, &z1, &z2);
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: z1 = %d\n", z1);
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: z2 = %d\n", z2);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: z1 = %d\n", z1);
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: z2 = %d\n", z2);
|
||||
dev->reg[reg_0x60].value = HIBYTE (z1);
|
||||
dev->reg[reg_0x61].value = LOBYTE (z1);
|
||||
dev->reg[reg_0x62].value = HIBYTE (z2);
|
||||
|
@ -2752,64 +2980,113 @@ gl646_init_regs_for_scan (Genesys_Device * dev)
|
|||
dev->reg[reg_0x67].value = dev->gpo.enable[1];
|
||||
|
||||
/* prepares data reordering */
|
||||
dev->words_per_line = words_per_line;
|
||||
|
||||
/* we must use a round number of words_per_line */
|
||||
dev->requested_buffer_size =
|
||||
(BULKIN_MAXSIZE / dev->words_per_line) * dev->words_per_line;
|
||||
requested_buffer_size =
|
||||
(BULKIN_MAXSIZE / words_per_line) * words_per_line;
|
||||
|
||||
dev->read_buffer_size =
|
||||
2 * dev->requested_buffer_size +
|
||||
((dev->max_shift + dev->stagger) * pixels * channels * depth) / 8;
|
||||
if (dev->read_buffer != NULL)
|
||||
{
|
||||
free (dev->read_buffer);
|
||||
free (dev->resize_buffer);
|
||||
}
|
||||
dev->read_buffer = (SANE_Byte *) malloc (dev->read_buffer_size);
|
||||
if (dev->read_buffer == NULL)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
dev->resize_buffer = (SANE_Byte *) malloc (dev->requested_buffer_size);
|
||||
if (dev->resize_buffer == NULL)
|
||||
{
|
||||
free (dev->read_buffer);
|
||||
dev->read_buffer = NULL;
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
read_buffer_size =
|
||||
2 * requested_buffer_size +
|
||||
((max_shift + stagger) * pixels * channels * depth) / 8;
|
||||
|
||||
RIE(sanei_genesys_buffer_free(&(dev->read_buffer)));
|
||||
RIE(sanei_genesys_buffer_alloc(&(dev->read_buffer), read_buffer_size));
|
||||
|
||||
RIE(sanei_genesys_buffer_free(&(dev->lines_buffer)));
|
||||
RIE(sanei_genesys_buffer_alloc(&(dev->lines_buffer), read_buffer_size));
|
||||
|
||||
RIE(sanei_genesys_buffer_free(&(dev->shrink_buffer)));
|
||||
RIE(sanei_genesys_buffer_alloc(&(dev->shrink_buffer),
|
||||
requested_buffer_size));
|
||||
|
||||
RIE(sanei_genesys_buffer_free(&(dev->out_buffer)));
|
||||
RIE(sanei_genesys_buffer_alloc(&(dev->out_buffer),
|
||||
(8 * dev->settings.pixels * channels * depth) / 8));
|
||||
|
||||
dev->read_pos = 0;
|
||||
dev->total_bytes_read = 0;
|
||||
dev->read_bytes_in_buffer = 0;
|
||||
/* scan bytes to read */
|
||||
dev->read_bytes_left = dev->words_per_line * (lincnt + 1);
|
||||
dev->read_bytes_left = words_per_line * (lincnt + 1);
|
||||
|
||||
|
||||
DBG (DBG_info,
|
||||
"gl646_init_regs_for_scan: physical bytes to read = %lu\n",
|
||||
(u_long) dev->read_bytes_left);
|
||||
dev->read_active = SANE_TRUE;
|
||||
|
||||
|
||||
dev->current_setup.pixels = (pixels * dpiset) / dev->sensor.optical_res;
|
||||
if (half_ccd)
|
||||
dev->current_setup.pixels &= ~1;
|
||||
dev->current_setup.lines = lincnt + 1;
|
||||
dev->current_setup.depth = depth;
|
||||
dev->current_setup.channels = channels;
|
||||
dev->current_setup.exposure_time = exposure_time;
|
||||
if (half_ccd)
|
||||
dev->current_setup.xres = dpiset / 2;
|
||||
else
|
||||
dev->current_setup.xres = dpiset ;
|
||||
dev->current_setup.yres = dev->settings.yres;
|
||||
dev->current_setup.half_ccd = half_ccd;
|
||||
dev->current_setup.stagger = stagger;
|
||||
dev->current_setup.max_shift = max_shift + stagger;
|
||||
|
||||
|
||||
/* TODO: should this be done elsewhere? */
|
||||
/* scan bytes to send to the frontend */
|
||||
/* theory :
|
||||
target_size =
|
||||
(dev->settings.pixels * dev->settings.lines * channels * depth) / 8;
|
||||
but it suffers from integer overflow so we do the following: */
|
||||
switch (depth)
|
||||
{
|
||||
case 1:
|
||||
dev->bytes_to_read =
|
||||
(size_t) (dev->settings.pixels * dev->settings.lines * channels) / 8;
|
||||
break;
|
||||
case 8:
|
||||
dev->bytes_to_read =
|
||||
(size_t) (dev->settings.pixels * dev->settings.lines * channels);
|
||||
break;
|
||||
case 16:
|
||||
dev->bytes_to_read =
|
||||
(size_t) (dev->settings.pixels * dev->settings.lines * channels * 2);
|
||||
break;
|
||||
}
|
||||
DBG (DBG_info,
|
||||
"gl646_init_register_for_scan: physical bytes to read = %lu\n",
|
||||
(u_long) dev->read_bytes_left);
|
||||
DBG (DBG_info, "gl646_init_register_for_scan: total bytes to send = %lu\n",
|
||||
(u_long) dev->bytes_to_read);
|
||||
dev->read_active = SANE_TRUE;
|
||||
but it suffers from integer overflow so we do the following:
|
||||
|
||||
DBG (DBG_proc, "gl646_init_register_for_scan: completed\n");
|
||||
1 bit color images store color data byte-wise, eg byte 0 contains
|
||||
8 bits of red data, byte 1 contains 8 bits of green, byte 2 contains
|
||||
8 bits of blue.
|
||||
This does not fix the overflow, though.
|
||||
644mp*16 = 10gp, leading to an overflow
|
||||
-- pierre
|
||||
*/
|
||||
|
||||
dev->total_bytes_read = 0;
|
||||
if (depth == 1)
|
||||
dev->total_bytes_to_read =
|
||||
((dev->settings.pixels * dev->settings.lines) / 8) * channels;
|
||||
else
|
||||
dev->total_bytes_to_read =
|
||||
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
|
||||
|
||||
DBG (DBG_info, "gl646_init_regs_for_scan: total bytes to send = %lu\n",
|
||||
(u_long) dev->total_bytes_to_read);
|
||||
/* END TODO */
|
||||
|
||||
|
||||
|
||||
|
||||
status =
|
||||
gl646_send_slope_table (dev, 0, dev->slope_table0,
|
||||
sanei_genesys_read_reg_from_set
|
||||
(dev->reg, 0x21));
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_init_regs_for_scan: failed to send slope table 0: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
status =
|
||||
gl646_send_slope_table (dev, 1, dev->slope_table1,
|
||||
sanei_genesys_read_reg_from_set
|
||||
(dev->reg, 0x6b));
|
||||
|
||||
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"gl646_init_regs_for_scan: failed to send slope table 1: %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
DBG (DBG_proc, "gl646_init_regs_for_scan: completed\n");
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -2898,7 +3175,7 @@ gl646_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
|
|||
|
||||
/* send data */
|
||||
status =
|
||||
sanei_genesys_bulk_write_data (dev, 0x3c, (u_int8_t *) gamma,
|
||||
gl646_bulk_write_data (dev, 0x3c, (u_int8_t *) gamma,
|
||||
size * 2 * 3);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -2914,6 +3191,14 @@ gl646_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/* this function does the led calibration.
|
||||
*/
|
||||
static SANE_Status
|
||||
gl646_led_calibration (Genesys_Device * dev)
|
||||
{
|
||||
DBG(DBG_error,"Implementation for led calibration missing\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
/* this function does the offset calibration by scanning one line of the calibration
|
||||
area below scanner's top. There is a black margin and the remaining is white.
|
||||
|
@ -3129,7 +3414,7 @@ ST12: 0x60 0x00 0x61 0x00 0x62 0x00 0x63 0x00 0x64 0x00 0x65 0x3f 0x66 0x00 0x67
|
|||
|
||||
RIE (gl646_set_fe (dev, AFE_SET));
|
||||
|
||||
RIE (sanei_genesys_bulk_write_register
|
||||
RIE (gl646_bulk_write_register
|
||||
(dev, dev->calib_reg, GENESYS_GL646_MAX_REGS * 2));
|
||||
|
||||
first_line = malloc (total_size);
|
||||
|
@ -3480,7 +3765,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
|
|||
|
||||
DBG (DBG_proc, "gl646_warmup_lamp\n");
|
||||
|
||||
memcpy (local_reg, dev->reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
*total_size = num_pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */
|
||||
|
||||
/* ST12: 0x01 0x00 0x02 0x41 0x03 0x1f 0x04 0x53 0x05 0x10 0x06 0x10 0x08 0x02 0x09 0x00 0x0a 0x06 0x0b 0x04 */
|
||||
|
@ -3567,9 +3852,9 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
|
|||
local_reg[reg_0x24].value = local_reg[reg_0x21].value; /* table one steps number backward slope curve of the acc/dec */
|
||||
|
||||
|
||||
local_reg[reg_0x25].value = HIWORD (LOBYTE (lincnt)); /* scan line numbers - here one line */
|
||||
local_reg[reg_0x26].value = LOWORD (HIBYTE (lincnt));
|
||||
local_reg[reg_0x27].value = LOWORD (LOBYTE (lincnt));
|
||||
local_reg[reg_0x25].value = LOBYTE (HIWORD (lincnt)); /* scan line numbers - here one line */
|
||||
local_reg[reg_0x26].value = HIBYTE (LOWORD (lincnt));
|
||||
local_reg[reg_0x27].value = LOBYTE (LOWORD (lincnt));
|
||||
|
||||
local_reg[reg_0x2c].value = HIBYTE (dpi);
|
||||
local_reg[reg_0x2d].value = LOBYTE (dpi);
|
||||
|
@ -3593,7 +3878,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
|
|||
local_reg[reg_0x37].value = LOBYTE (LOWORD (words_per_line));
|
||||
|
||||
exposure_time = sanei_genesys_exposure_time (dev, local_reg, dpi),
|
||||
local_reg[reg_0x38].value = HIBYTE (exposure_time);
|
||||
local_reg[reg_0x38].value = HIBYTE (exposure_time);
|
||||
local_reg[reg_0x39].value = LOBYTE (exposure_time);
|
||||
|
||||
/* monochrome scan */
|
||||
|
@ -3648,7 +3933,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
|
|||
|
||||
RIE (gl646_set_fe (dev, AFE_INIT));
|
||||
|
||||
RIE (sanei_genesys_bulk_write_register
|
||||
RIE (gl646_bulk_write_register
|
||||
(dev, local_reg, GENESYS_GL646_MAX_REGS * 2));
|
||||
|
||||
return status;
|
||||
|
@ -3663,7 +3948,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev,
|
|||
static SANE_Status
|
||||
gl646_repark_head (Genesys_Device * dev)
|
||||
{
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS];
|
||||
Genesys_Register_Set local_reg[GENESYS_GL646_MAX_REGS + 1];
|
||||
u_int16_t slope_table[256];
|
||||
int exposure_time; /* todo : modify sanei_genesys_exposure_time() */
|
||||
SANE_Status status;
|
||||
|
@ -3675,7 +3960,7 @@ gl646_repark_head (Genesys_Device * dev)
|
|||
DBG (DBG_proc, "gl646_repark_head\n");
|
||||
|
||||
memset (local_reg, 0, sizeof (local_reg));
|
||||
memcpy (local_reg, dev->reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (local_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
|
||||
local_reg[reg_0x01].value =
|
||||
local_reg[reg_0x01].value & ~REG01_DVDSET & ~REG01_FASTMOD & ~REG01_SCAN;
|
||||
|
@ -3786,7 +4071,7 @@ gl646_repark_head (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
status =
|
||||
sanei_genesys_bulk_write_register (dev, local_reg,
|
||||
gl646_bulk_write_register (dev, local_reg,
|
||||
GENESYS_GL646_MAX_REGS * 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -3852,7 +4137,6 @@ gl646_init (Genesys_Device * dev)
|
|||
}
|
||||
}
|
||||
|
||||
sanei_genesys_init_structs (dev);
|
||||
|
||||
dev->dark_average_data = NULL;
|
||||
dev->white_average_data = NULL;
|
||||
|
@ -3981,7 +4265,7 @@ gl646_init (Genesys_Device * dev)
|
|||
usleep (10000UL); /* sleep 100 ms */
|
||||
|
||||
/* Write initial registers */
|
||||
RIE (sanei_genesys_bulk_write_register
|
||||
RIE (gl646_bulk_write_register
|
||||
(dev, dev->reg, GENESYS_GL646_MAX_REGS * 2));
|
||||
|
||||
/* Test ASIC and RAM */
|
||||
|
@ -4027,7 +4311,7 @@ gl646_init (Genesys_Device * dev)
|
|||
}
|
||||
|
||||
/* initial calibration reg values */
|
||||
memcpy (dev->calib_reg, dev->reg, GENESYS_GL646_MAX_REGS * 2);
|
||||
memcpy (dev->calib_reg, dev->reg, (GENESYS_GL646_MAX_REGS + 1) * 2);
|
||||
|
||||
/* Set powersaving (default = 15 minutes) */
|
||||
RIE (gl646_set_powersaving (dev, 15));
|
||||
|
@ -4059,6 +4343,7 @@ static Genesys_Command_Set gl646_cmd_set = {
|
|||
|
||||
gl646_set_fe,
|
||||
gl646_set_powersaving,
|
||||
gl646_save_power,
|
||||
gl646_set_motor_power,
|
||||
gl646_set_lamp_power,
|
||||
|
||||
|
@ -4066,14 +4351,19 @@ static Genesys_Command_Set gl646_cmd_set = {
|
|||
gl646_end_scan,
|
||||
|
||||
gl646_send_gamma_table,
|
||||
gl646_send_slope_table,
|
||||
|
||||
gl646_search_start_position,
|
||||
|
||||
gl646_offset_calibration,
|
||||
gl646_coarse_gain_calibration,
|
||||
gl646_led_calibration,
|
||||
|
||||
gl646_slow_back_home,
|
||||
gl646_park_head,
|
||||
|
||||
gl646_bulk_write_register,
|
||||
gl646_bulk_write_data,
|
||||
gl646_bulk_read_data,
|
||||
};
|
||||
|
||||
SANE_Status
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -3,7 +3,8 @@
|
|||
Copyright (C) 2003 Oliver Rauch
|
||||
Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
Copyright (C) 2004, 2005 Stephane Voltz <stephane.voltz@numericable.fr>
|
||||
Copyright (C) 2004, 2005 Stephane Voltz <stefdev@modulonet.fr>
|
||||
Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||
Parts of the structs have been taken from the gt68xx backend by
|
||||
Sergey Vlasov <vsu@altlinux.ru> et al.
|
||||
|
||||
|
@ -83,8 +84,16 @@
|
|||
#define GENESYS_FLAG_DARK_CALIBRATION (1 << 8) /* do dark calibration */
|
||||
#define GENESYS_FLAG_STAGGERED_LINE (1 << 9) /* pixel columns are shifted vertically for hi-res modes */
|
||||
|
||||
#define GENESYS_FLAG_MUST_WAIT (1 << 10) /* tells wether the scanner should wait 1 minute after init
|
||||
before doing anything */
|
||||
#define GENESYS_FLAG_MUST_WAIT (1 << 10) /* tells wether the scanner
|
||||
should wait 1 minute after
|
||||
init before doing anything
|
||||
*/
|
||||
|
||||
|
||||
#define GENESYS_FLAG_ALT_SLOPE_CREATE (1 << 11) /* use alternative slope
|
||||
creation function */
|
||||
|
||||
#define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /*yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/
|
||||
|
||||
/* USB control message values */
|
||||
#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN)
|
||||
|
@ -112,7 +121,7 @@
|
|||
#define BULK_RAM 0x00
|
||||
#define BULK_REGISTER 0x11
|
||||
|
||||
#define BULKIN_MAXSIZE 0xFFC0
|
||||
#define BULKIN_MAXSIZE 0xFE00
|
||||
#define BULKOUT_MAXSIZE 0xF000
|
||||
|
||||
/* AFE values */
|
||||
|
@ -146,13 +155,14 @@ typedef struct
|
|||
u_int8_t sign[3];
|
||||
u_int8_t offset[3];
|
||||
u_int8_t gain[3];
|
||||
u_int8_t reg2[3];
|
||||
} Genesys_Frontend;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int optical_res;
|
||||
int black_pixels;
|
||||
int dummy_pixel;
|
||||
int dummy_pixel; /* value of dummy register. */
|
||||
int CCD_start_xoffset; /* last pixel of CCD margin at optical resolution */
|
||||
int sensor_pixels; /* total pixels used by the sensor */
|
||||
int fau_gain_white_ref; /* TA CCD target code (reference gain) */
|
||||
|
@ -176,8 +186,22 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
SANE_Int base_ydpi; /* motor base steps */
|
||||
SANE_Int optical_ydpi; /* maximum resolution in y-direction */
|
||||
SANE_Int maximum_start_speed; /* maximum speed allowed when accelerating from standstill. Unit: pixeltime/step */
|
||||
SANE_Int maximum_speed; /* maximum speed allowed. Unit: pixeltime/step */
|
||||
SANE_Int minimum_steps; /* number of steps used for default curve */
|
||||
float g; /* power for non-linear acceleration curves. */
|
||||
/* vs*(1-i^g)+ve*(i^g) where
|
||||
vs = start speed, ve = end speed,
|
||||
i = 0.0 for first entry and i = 1.0 for last entry in default table*/
|
||||
} Genesys_Motor_Slope;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SANE_Int base_ydpi; /* motor base steps. Unit: 1/" */
|
||||
SANE_Int optical_ydpi; /* maximum resolution in y-direction. Unit: 1/" */
|
||||
SANE_Int max_step_type; /* maximum step type. 0-2 */
|
||||
Genesys_Motor_Slope slopes[3]; /* slopes to derive individual slopes from */
|
||||
} Genesys_Motor;
|
||||
|
||||
typedef enum Genesys_Color_Order
|
||||
|
@ -195,7 +219,8 @@ Genesys_Color_Order;
|
|||
#define GENESYS_GL646 646
|
||||
#define GENESYS_GL841 841
|
||||
|
||||
#define GENESYS_MAX_REGS 135
|
||||
/*135 registers for gl841 + 1 null-reg*/
|
||||
#define GENESYS_MAX_REGS 136
|
||||
|
||||
#define DAC_WOLFSON_UMAX 0
|
||||
#define DAC_WOLFSON_ST12 1
|
||||
|
@ -203,6 +228,7 @@ Genesys_Color_Order;
|
|||
#define DAC_WOLFSON_5345 3
|
||||
#define DAC_WOLFSON_HP2400 4
|
||||
#define DAC_WOLFSON_HP2300 5
|
||||
#define DAC_CANONLIDE35 6
|
||||
|
||||
#define CCD_UMAX 0
|
||||
#define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */
|
||||
|
@ -210,6 +236,7 @@ Genesys_Color_Order;
|
|||
#define CCD_5345 3
|
||||
#define CCD_HP2400 4
|
||||
#define CCD_HP2300 5
|
||||
#define CCD_CANONLIDE35 6
|
||||
|
||||
#define GPO_UMAX 0
|
||||
#define GPO_ST12 1
|
||||
|
@ -217,12 +244,14 @@ Genesys_Color_Order;
|
|||
#define GPO_5345 3
|
||||
#define GPO_HP2400 4
|
||||
#define GPO_HP2300 5
|
||||
#define GPO_CANONLIDE35 6
|
||||
|
||||
#define MOTOR_UMAX 0
|
||||
#define MOTOR_5345 1
|
||||
#define MOTOR_ST24 2
|
||||
#define MOTOR_HP2400 3
|
||||
#define MOTOR_HP2300 4
|
||||
#define MOTOR_CANONLIDE35 5
|
||||
|
||||
|
||||
/* Forward typedefs */
|
||||
|
@ -268,6 +297,7 @@ typedef struct Genesys_Command_Set
|
|||
|
||||
SANE_Status (*set_fe) (Genesys_Device * dev, u_int8_t set);
|
||||
SANE_Status (*set_powersaving) (Genesys_Device * dev, int delay);
|
||||
SANE_Status (*save_power) (Genesys_Device * dev, SANE_Bool enable);
|
||||
|
||||
void (*set_motor_power) (Genesys_Register_Set * regs, SANE_Bool set);
|
||||
void (*set_lamp_power) (Genesys_Register_Set * regs, SANE_Bool set);
|
||||
|
@ -280,18 +310,25 @@ typedef struct Genesys_Command_Set
|
|||
SANE_Bool check_stop);
|
||||
|
||||
SANE_Status (*send_gamma_table) (Genesys_Device * dev, SANE_Bool generic);
|
||||
SANE_Status (*send_slope_table) (Genesys_Device * dev, int table_nr,
|
||||
u_int16_t * slope_table, int steps);
|
||||
|
||||
SANE_Status (*search_start_position) (Genesys_Device * dev);
|
||||
SANE_Status (*offset_calibration) (Genesys_Device * dev);
|
||||
SANE_Status (*coarse_gain_calibration) (Genesys_Device * dev, int dpi);
|
||||
SANE_Status (*led_calibration) (Genesys_Device * dev);
|
||||
|
||||
SANE_Status (*slow_back_home) (Genesys_Device * dev,
|
||||
SANE_Bool wait_until_home);
|
||||
SANE_Status (*park_head) (Genesys_Device * dev,
|
||||
Genesys_Register_Set * reg,
|
||||
SANE_Bool wait_until_home);
|
||||
SANE_Status (*bulk_write_register) (Genesys_Device * dev,
|
||||
Genesys_Register_Set * reg,
|
||||
size_t size);
|
||||
SANE_Status (*bulk_write_data) (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len);
|
||||
|
||||
SANE_Status (*bulk_read_data) (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len);
|
||||
|
||||
} Genesys_Command_Set;
|
||||
|
||||
|
@ -354,17 +391,38 @@ typedef struct
|
|||
double tl_x; /* x start on scan table in mm */
|
||||
double tl_y; /* y start on scan table in mm */
|
||||
|
||||
int lines; /* number of lines at scan resolution */
|
||||
int pixels; /* number of pixels at scan resolution */
|
||||
unsigned int lines; /* number of lines at scan resolution */
|
||||
unsigned int pixels; /* number of pixels at scan resolution */
|
||||
|
||||
int depth; /* bit depth of the scan */
|
||||
unsigned int depth;/* bit depth of the scan */
|
||||
|
||||
/* todo : remove these fields ? */
|
||||
int exposure_time;
|
||||
|
||||
int color_filter; /* todo: check, may be make it an advanced option */
|
||||
unsigned int color_filter; /* todo: check, may be make it an advanced option */
|
||||
} Genesys_Settings;
|
||||
|
||||
typedef struct Genesys_Current_Setup
|
||||
{
|
||||
int pixels; /* pixel count expected from scanner */
|
||||
int lines; /* line count expected from scanner */
|
||||
int depth; /* depth expected from scanner */
|
||||
int channels; /* channel count expected from scanner */
|
||||
int exposure_time; /* used exposure time */
|
||||
float xres; /* used xres */
|
||||
float yres; /* used yres*/
|
||||
SANE_Bool half_ccd; /* half ccd mode */
|
||||
SANE_Int stagger;
|
||||
SANE_Int max_shift; /* max shift of any ccd component, including staggered pixels*/
|
||||
} Genesys_Current_Setup;
|
||||
|
||||
typedef struct Genesys_Buffer
|
||||
{
|
||||
SANE_Byte *buffer;
|
||||
size_t size;
|
||||
size_t pos; /* current position in read buffer */
|
||||
size_t avail; /* data bytes currently in buffer */
|
||||
} Genesys_Buffer;
|
||||
|
||||
struct Genesys_Device
|
||||
{
|
||||
|
@ -392,22 +450,18 @@ struct Genesys_Device
|
|||
SANE_Int lamp_off_time;
|
||||
|
||||
SANE_Bool read_active;
|
||||
SANE_Byte *read_buffer;
|
||||
SANE_Byte *resize_buffer;
|
||||
size_t words_per_line;
|
||||
float read_factor; /* line shrinking factor */
|
||||
size_t requested_buffer_size;
|
||||
size_t read_buffer_size;
|
||||
size_t read_pos; /* current position in data buffer */
|
||||
size_t read_bytes_in_buffer; /* data bytes currently in buffer */
|
||||
size_t read_bytes_left; /* bytes to read from scanner */
|
||||
size_t total_bytes_read; /* total bytes read sent to frontend */
|
||||
size_t bytes_to_read; /* total bytes read to be sent to frontend */
|
||||
SANE_Int max_shift; /* maximum line number that has to be read
|
||||
to enable data reordering */
|
||||
SANE_Int stagger; /* numbre of scan lines needed to process
|
||||
staggering effect */
|
||||
|
||||
Genesys_Buffer read_buffer;
|
||||
Genesys_Buffer lines_buffer;
|
||||
Genesys_Buffer shrink_buffer;
|
||||
Genesys_Buffer out_buffer;
|
||||
|
||||
size_t read_bytes_left; /* bytes to read from scanner */
|
||||
|
||||
size_t total_bytes_read; /* total bytes read sent to frontend */
|
||||
size_t total_bytes_to_read; /* total bytes read to be sent to frontend */
|
||||
|
||||
Genesys_Current_Setup current_setup; /* contains the real used values */
|
||||
|
||||
struct Genesys_Device *next;
|
||||
};
|
||||
|
@ -453,7 +507,7 @@ extern SANE_Status
|
|||
sanei_genesys_init_shading_data (Genesys_Device * dev, int pixels_per_line);
|
||||
|
||||
extern SANE_Status sanei_genesys_read_feed_steps (Genesys_Device * dev,
|
||||
int *steps);
|
||||
unsigned int *steps);
|
||||
|
||||
extern void
|
||||
sanei_genesys_calculate_zmode2 (SANE_Bool two_table,
|
||||
|
@ -472,14 +526,6 @@ sanei_genesys_calculate_zmode (Genesys_Device * dev,
|
|||
u_int8_t fwdstep, u_int8_t tgtime,
|
||||
u_int32_t * z1, u_int32_t * z2);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_bulk_write_data (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_bulk_read_data (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int8_t * data, size_t len);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_set_buffer_address (Genesys_Device * dev, u_int32_t addr);
|
||||
|
||||
|
@ -487,6 +533,11 @@ extern SANE_Status
|
|||
sanei_genesys_fe_write_data (Genesys_Device * dev, u_int8_t addr,
|
||||
u_int16_t data);
|
||||
|
||||
extern SANE_Int
|
||||
sanei_genesys_exposure_time2 (Genesys_Device * dev,
|
||||
float ydpi, int step_type, int endpixel,
|
||||
int led_exposure);
|
||||
|
||||
extern SANE_Int
|
||||
sanei_genesys_exposure_time (Genesys_Device * dev, Genesys_Register_Set * reg,
|
||||
int xdpi);
|
||||
|
@ -497,15 +548,20 @@ sanei_genesys_create_slope_table (Genesys_Device * dev,
|
|||
int step_type, int exposure_time,
|
||||
SANE_Bool same_speed, double yres);
|
||||
|
||||
SANE_Int
|
||||
sanei_genesys_create_slope_table3 (Genesys_Device * dev,
|
||||
u_int8_t * slope_table, int max_step,
|
||||
unsigned int use_steps,
|
||||
int step_type, int exposure_time,
|
||||
double yres,
|
||||
unsigned int *used_steps,
|
||||
unsigned int *final_exposure);
|
||||
|
||||
extern void
|
||||
sanei_genesys_create_gamma_table (u_int16_t * gamma_table, float size,
|
||||
sanei_genesys_create_gamma_table (u_int16_t * gamma_table, int size,
|
||||
float maximum, float gamma_max,
|
||||
float gamma);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_bulk_write_register (Genesys_Device * dev,
|
||||
Genesys_Register_Set * reg, size_t size);
|
||||
|
||||
extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev);
|
||||
|
||||
extern SANE_Status sanei_genesys_stop_motor (Genesys_Device * dev);
|
||||
|
@ -526,6 +582,24 @@ extern SANE_Status
|
|||
sanei_genesys_read_data_from_scanner (Genesys_Device * dev, u_int8_t * data,
|
||||
size_t size);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_buffer_alloc(Genesys_Buffer * buf, size_t size);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_buffer_free(Genesys_Buffer * buf);
|
||||
|
||||
extern SANE_Byte *
|
||||
sanei_genesys_buffer_get_write_pos(Genesys_Buffer * buf, size_t size);
|
||||
|
||||
extern SANE_Byte *
|
||||
sanei_genesys_buffer_get_read_pos(Genesys_Buffer * buf);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_buffer_produce(Genesys_Buffer * buf, size_t size);
|
||||
|
||||
extern SANE_Status
|
||||
sanei_genesys_buffer_consume(Genesys_Buffer * buf, size_t size);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* ASIC specific functions declarations */
|
||||
|
|
Ładowanie…
Reference in New Issue