kopia lustrzana https://gitlab.com/sane-project/backends
1070 wiersze
32 KiB
C
1070 wiersze
32 KiB
C
![]() |
/* sane - Scanner Access Now Easy.
|
||
|
|
||
|
Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
|
||
|
Copyright (C) 2002 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||
|
|
||
|
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.
|
||
|
*/
|
||
|
|
||
|
#include "gt68xx_mid.h"
|
||
|
#include "gt68xx_low.c"
|
||
|
|
||
|
/** @file
|
||
|
* @brief Image data unpacking.
|
||
|
*/
|
||
|
|
||
|
static SANE_Status
|
||
|
gt68xx_delay_buffer_init (GT68xx_Delay_Buffer * delay,
|
||
|
SANE_Int pixels_per_line, SANE_Int delay_count)
|
||
|
{
|
||
|
DECLARE_FUNCTION_NAME ("gt68xx_delay_buffer_init") SANE_Int bytes_per_line;
|
||
|
SANE_Int line_count, i;
|
||
|
|
||
|
if (pixels_per_line <= 0)
|
||
|
{
|
||
|
XDBG ((3, "%s: BUG: pixels_per_line=%d\n",
|
||
|
function_name, pixels_per_line));
|
||
|
return SANE_STATUS_INVAL;
|
||
|
}
|
||
|
|
||
|
if (delay_count < 0)
|
||
|
{
|
||
|
XDBG ((3, "%s: BUG: delay_count=%d\n", function_name, delay_count));
|
||
|
return SANE_STATUS_INVAL;
|
||
|
}
|
||
|
|
||
|
bytes_per_line = pixels_per_line * sizeof (unsigned int);
|
||
|
|
||
|
delay->line_count = line_count = delay_count + 1;
|
||
|
delay->read_index = 0;
|
||
|
delay->write_index = delay_count;
|
||
|
|
||
|
delay->mem_block = (SANE_Byte *) malloc (bytes_per_line * line_count);
|
||
|
if (!delay->mem_block)
|
||
|
{
|
||
|
XDBG ((3, "%s: no memory for delay block\n", function_name));
|
||
|
return SANE_STATUS_NO_MEM;
|
||
|
}
|
||
|
/* make sure that we will see if one of the unitialized lines get displayed */
|
||
|
for (i = 0; i < bytes_per_line * line_count; i++)
|
||
|
delay->mem_block[i] = i % 256;
|
||
|
|
||
|
delay->lines =
|
||
|
(unsigned int **) malloc (sizeof (unsigned int *) * line_count);
|
||
|
if (!delay->lines)
|
||
|
{
|
||
|
free (delay->mem_block);
|
||
|
XDBG ((3, "%s: no memory for delay line pointers\n", function_name));
|
||
|
return SANE_STATUS_NO_MEM;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < line_count; ++i)
|
||
|
delay->lines[i] =
|
||
|
(unsigned int *) (delay->mem_block + i * bytes_per_line);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
gt68xx_delay_buffer_done (GT68xx_Delay_Buffer * delay)
|
||
|
{
|
||
|
if (delay->lines)
|
||
|
{
|
||
|
free (delay->lines);
|
||
|
delay->lines = NULL;
|
||
|
}
|
||
|
|
||
|
if (delay->mem_block)
|
||
|
{
|
||
|
free (delay->mem_block);
|
||
|
delay->mem_block = NULL;
|
||
|
}
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
#define DELAY_BUFFER_WRITE_PTR(delay) ( (delay)->lines[(delay)->write_index] )
|
||
|
|
||
|
#define DELAY_BUFFER_SELECT_PTR(delay,dist) \
|
||
|
((delay)->lines[((delay)->read_index + (dist)) % (delay)->line_count])
|
||
|
|
||
|
#define DELAY_BUFFER_READ_PTR(delay) ( (delay)->lines[(delay)->read_index ] )
|
||
|
|
||
|
#define DELAY_BUFFER_STEP(delay) \
|
||
|
do \
|
||
|
{ \
|
||
|
(delay)->read_index = ((delay)->read_index + 1) % (delay)->line_count; \
|
||
|
(delay)->write_index = ((delay)->write_index + 1) % (delay)->line_count; \
|
||
|
} \
|
||
|
while (SANE_FALSE)
|
||
|
|
||
|
|
||
|
static inline void
|
||
|
unpack_8_mono (SANE_Byte * src, unsigned int *dst, SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; ++src, ++dst, --pixels_per_line)
|
||
|
{
|
||
|
*dst = (((unsigned int) *src) << 8) | *src;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline void
|
||
|
unpack_8_rgb (SANE_Byte * src, unsigned int *dst, SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; src += 3, ++dst, --pixels_per_line)
|
||
|
{
|
||
|
*dst = (((unsigned int) *src) << 8) | *src;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 12-bit routines use the fact that pixels_per_line is aligned */
|
||
|
|
||
|
static inline void
|
||
|
unpack_12_le_mono (SANE_Byte * src, unsigned int *dst,
|
||
|
SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; src += 3, dst += 2, pixels_per_line -= 2)
|
||
|
{
|
||
|
dst[0] = ((((unsigned int) (src[1] & 0x0f)) << 12)
|
||
|
| (((unsigned int) src[0]) << 4) | (src[1] & 0x0f));
|
||
|
dst[1] = ((((unsigned int) src[2]) << 8)
|
||
|
| (src[1] & 0xf0) | (((unsigned int) src[2]) >> 0x04));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline void
|
||
|
unpack_12_le_rgb (SANE_Byte * src,
|
||
|
unsigned int *dst1,
|
||
|
unsigned int *dst2,
|
||
|
unsigned int *dst3, SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; pixels_per_line -= 2)
|
||
|
{
|
||
|
*dst1++ = ((((unsigned int) (src[1] & 0x0f)) << 12)
|
||
|
| (((unsigned int) src[0]) << 4) | (src[1] & 0x0f));
|
||
|
*dst2++ = ((((unsigned int) src[2]) << 8)
|
||
|
| (src[1] & 0xf0) | (((unsigned int) src[2]) >> 0x04));
|
||
|
src += 3;
|
||
|
|
||
|
*dst3++ = ((((unsigned int) (src[1] & 0x0f)) << 12)
|
||
|
| (((unsigned int) src[0]) << 4) | (src[1] & 0x0f));
|
||
|
*dst1++ = ((((unsigned int) src[2]) << 8)
|
||
|
| (src[1] & 0xf0) | (((unsigned int) src[2]) >> 0x04));
|
||
|
src += 3;
|
||
|
|
||
|
*dst2++ = ((((unsigned int) (src[1] & 0x0f)) << 12)
|
||
|
| (((unsigned int) src[0]) << 4) | (src[1] & 0x0f));
|
||
|
*dst3++ = ((((unsigned int) src[2]) << 8)
|
||
|
| (src[1] & 0xf0) | (((unsigned int) src[2]) >> 0x04));
|
||
|
src += 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline void
|
||
|
unpack_16_le_mono (SANE_Byte * src, unsigned int *dst,
|
||
|
SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; src += 2, dst++, --pixels_per_line)
|
||
|
{
|
||
|
*dst = (((unsigned int) src[1]) << 8) | src[0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static inline void
|
||
|
unpack_16_le_rgb (SANE_Byte * src, unsigned int *dst,
|
||
|
SANE_Int pixels_per_line)
|
||
|
{
|
||
|
for (; pixels_per_line > 0; src += 6, ++dst, --pixels_per_line)
|
||
|
{
|
||
|
*dst = (((unsigned int) src[1]) << 8) | src[0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_8 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
unpack_8_mono (reader->pixel_buffer, buffer, reader->pixels_per_line);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_double_8 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
unpack_8_mono (reader->pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
reader->pixels_per_line);
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
buffer[i] = DELAY_BUFFER_WRITE_PTR (&reader->g_delay)[i];
|
||
|
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_12 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
unpack_12_le_mono (reader->pixel_buffer, buffer, reader->pixels_per_line);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_double_12 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
unpack_12_le_mono (reader->pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
reader->pixels_per_line);
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
buffer[i] = DELAY_BUFFER_WRITE_PTR (&reader->g_delay)[i];
|
||
|
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_16 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
unpack_16_le_mono (reader->pixel_buffer, buffer, reader->pixels_per_line);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_gray_double_16 (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
unsigned int *buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
|
||
|
RIE (gt68xx_device_read (reader->dev, reader->pixel_buffer, &size));
|
||
|
unpack_16_le_mono (reader->pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
reader->pixels_per_line);
|
||
|
|
||
|
buffer = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
buffer[i] = DELAY_BUFFER_WRITE_PTR (&reader->g_delay)[i];
|
||
|
|
||
|
buffer_pointers_return[0] = buffer;
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
return SANE_STATUS_GOOD;
|
||
|
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_8_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay), pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_double_8_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay), pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
{
|
||
|
DELAY_BUFFER_READ_PTR (&reader->r_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->r_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->g_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->g_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->b_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->b_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
}
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_bgr_8_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay), pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_8_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay), pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_12_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_double_12_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
{
|
||
|
DELAY_BUFFER_READ_PTR (&reader->r_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->r_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->g_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->g_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->b_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->b_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
}
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_16_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_double_16_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
int i;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
for (i = reader->params.double_column; i < reader->pixels_per_line; i += 2)
|
||
|
{
|
||
|
DELAY_BUFFER_READ_PTR (&reader->r_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->r_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->g_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->g_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
DELAY_BUFFER_READ_PTR (&reader->b_delay)[i] =
|
||
|
DELAY_BUFFER_SELECT_PTR (&reader->b_delay,
|
||
|
reader->params.ld_shift_double)[i];
|
||
|
}
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_bgr_12_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_12_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_bgr_16_line_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl * 3;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += reader->params.scan_bpl;
|
||
|
unpack_16_le_mono (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_8_pixel_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_8_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay), pixels_per_line);
|
||
|
++pixel_buffer;
|
||
|
unpack_8_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay), pixels_per_line);
|
||
|
++pixel_buffer;
|
||
|
unpack_8_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay), pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_12_pixel_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
unpack_12_le_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
reader->pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static SANE_Status
|
||
|
line_read_rgb_16_pixel_mode (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
size_t size;
|
||
|
SANE_Int pixels_per_line;
|
||
|
SANE_Byte *pixel_buffer = reader->pixel_buffer;
|
||
|
|
||
|
size = reader->params.scan_bpl;
|
||
|
RIE (gt68xx_device_read (reader->dev, pixel_buffer, &size));
|
||
|
|
||
|
pixels_per_line = reader->pixels_per_line;
|
||
|
unpack_16_le_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->r_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += 2;
|
||
|
unpack_16_le_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->g_delay),
|
||
|
pixels_per_line);
|
||
|
pixel_buffer += 2;
|
||
|
unpack_16_le_rgb (pixel_buffer,
|
||
|
DELAY_BUFFER_WRITE_PTR (&reader->b_delay),
|
||
|
pixels_per_line);
|
||
|
|
||
|
buffer_pointers_return[0] = DELAY_BUFFER_READ_PTR (&reader->r_delay);
|
||
|
buffer_pointers_return[1] = DELAY_BUFFER_READ_PTR (&reader->g_delay);
|
||
|
buffer_pointers_return[2] = DELAY_BUFFER_READ_PTR (&reader->b_delay);
|
||
|
|
||
|
DELAY_BUFFER_STEP (&reader->r_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->g_delay);
|
||
|
DELAY_BUFFER_STEP (&reader->b_delay);
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
|
||
|
static SANE_Status
|
||
|
gt68xx_line_reader_init_delays (GT68xx_Line_Reader * reader)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
|
||
|
if (reader->params.color)
|
||
|
{
|
||
|
status = gt68xx_delay_buffer_init (&reader->r_delay,
|
||
|
reader->params.scan_xs,
|
||
|
reader->params.ld_shift_r +
|
||
|
reader->params.ld_shift_double);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
return status;
|
||
|
|
||
|
status = gt68xx_delay_buffer_init (&reader->g_delay,
|
||
|
reader->params.scan_xs,
|
||
|
reader->params.ld_shift_g +
|
||
|
reader->params.ld_shift_double);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
{
|
||
|
gt68xx_delay_buffer_done (&reader->r_delay);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
status = gt68xx_delay_buffer_init (&reader->b_delay,
|
||
|
reader->params.scan_xs,
|
||
|
reader->params.ld_shift_b +
|
||
|
reader->params.ld_shift_double);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
{
|
||
|
gt68xx_delay_buffer_done (&reader->g_delay);
|
||
|
gt68xx_delay_buffer_done (&reader->r_delay);
|
||
|
return status;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
status = gt68xx_delay_buffer_init (&reader->g_delay,
|
||
|
reader->params.scan_xs,
|
||
|
reader->params.ld_shift_double);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
return status;
|
||
|
}
|
||
|
reader->delays_initialized = SANE_TRUE;
|
||
|
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
gt68xx_line_reader_free_delays (GT68xx_Line_Reader * reader)
|
||
|
{
|
||
|
if (reader->delays_initialized)
|
||
|
{
|
||
|
if (reader->params.color)
|
||
|
{
|
||
|
gt68xx_delay_buffer_done (&reader->b_delay);
|
||
|
gt68xx_delay_buffer_done (&reader->g_delay);
|
||
|
gt68xx_delay_buffer_done (&reader->r_delay);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gt68xx_delay_buffer_done (&reader->g_delay);
|
||
|
}
|
||
|
reader->delays_initialized = SANE_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SANE_Status
|
||
|
gt68xx_line_reader_new (GT68xx_Device * dev,
|
||
|
GT68xx_Scan_Parameters * params,
|
||
|
SANE_Bool final_scan,
|
||
|
GT68xx_Line_Reader ** reader_return)
|
||
|
{
|
||
|
DECLARE_FUNCTION_NAME ("gt68xx_line_reader_new") SANE_Status status;
|
||
|
GT68xx_Line_Reader *reader;
|
||
|
SANE_Int image_size;
|
||
|
SANE_Int scan_bpl_full;
|
||
|
|
||
|
XDBG ((6, "%s: enter\n", function_name));
|
||
|
|
||
|
*reader_return = NULL;
|
||
|
|
||
|
reader = (GT68xx_Line_Reader *) malloc (sizeof (GT68xx_Line_Reader));
|
||
|
if (!reader)
|
||
|
{
|
||
|
XDBG ((3, "%s: cannot allocate GT68xx_Line_Reader\n", function_name));
|
||
|
return SANE_STATUS_NO_MEM;
|
||
|
}
|
||
|
memset (reader, 0, sizeof (GT68xx_Line_Reader));
|
||
|
|
||
|
reader->dev = dev;
|
||
|
memcpy (&reader->params, params, sizeof (GT68xx_Scan_Parameters));
|
||
|
reader->pixel_buffer = 0;
|
||
|
reader->delays_initialized = SANE_FALSE;
|
||
|
|
||
|
reader->read = NULL;
|
||
|
|
||
|
status = gt68xx_line_reader_init_delays (reader);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
{
|
||
|
XDBG ((3, "%s: cannot allocate line buffers: %s\n",
|
||
|
function_name, sane_strstatus (status)));
|
||
|
free (reader);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
reader->pixels_per_line = reader->params.pixel_xs;
|
||
|
|
||
|
if (!reader->params.color)
|
||
|
{
|
||
|
if (reader->params.depth == 8)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_gray_double_8;
|
||
|
else
|
||
|
reader->read = line_read_gray_8;
|
||
|
}
|
||
|
else if (reader->params.depth == 12)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_gray_double_12;
|
||
|
else
|
||
|
reader->read = line_read_gray_12;
|
||
|
}
|
||
|
else if (reader->params.depth == 16)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_gray_double_16;
|
||
|
else
|
||
|
reader->read = line_read_gray_16;
|
||
|
}
|
||
|
}
|
||
|
else if (reader->params.line_mode)
|
||
|
{
|
||
|
if (reader->params.depth == 8)
|
||
|
{
|
||
|
if (dev->model->line_mode_color_order == COLOR_ORDER_RGB)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_rgb_double_8_line_mode;
|
||
|
else
|
||
|
reader->read = line_read_rgb_8_line_mode;
|
||
|
}
|
||
|
else if (dev->model->line_mode_color_order == COLOR_ORDER_BGR)
|
||
|
reader->read = line_read_bgr_8_line_mode;
|
||
|
}
|
||
|
else if (reader->params.depth == 12)
|
||
|
{
|
||
|
if (dev->model->line_mode_color_order == COLOR_ORDER_RGB)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_rgb_double_12_line_mode;
|
||
|
else
|
||
|
reader->read = line_read_rgb_12_line_mode;
|
||
|
}
|
||
|
else if (dev->model->line_mode_color_order == COLOR_ORDER_BGR)
|
||
|
reader->read = line_read_bgr_12_line_mode;
|
||
|
}
|
||
|
else if (reader->params.depth == 16)
|
||
|
{
|
||
|
if (dev->model->line_mode_color_order == COLOR_ORDER_RGB)
|
||
|
{
|
||
|
if (reader->params.ld_shift_double > 0)
|
||
|
reader->read = line_read_rgb_double_16_line_mode;
|
||
|
else
|
||
|
reader->read = line_read_rgb_16_line_mode;
|
||
|
}
|
||
|
else if (dev->model->line_mode_color_order == COLOR_ORDER_BGR)
|
||
|
reader->read = line_read_bgr_16_line_mode;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (reader->params.depth == 8)
|
||
|
reader->read = line_read_rgb_8_pixel_mode;
|
||
|
else if (reader->params.depth == 12)
|
||
|
reader->read = line_read_rgb_12_pixel_mode;
|
||
|
else if (reader->params.depth == 16)
|
||
|
reader->read = line_read_rgb_16_pixel_mode;
|
||
|
}
|
||
|
|
||
|
if (reader->read == NULL)
|
||
|
{
|
||
|
XDBG ((3, "%s: unsupported bit depth (%d)\n",
|
||
|
function_name, reader->params.depth));
|
||
|
gt68xx_line_reader_free_delays (reader);
|
||
|
free (reader);
|
||
|
return SANE_STATUS_UNSUPPORTED;
|
||
|
}
|
||
|
|
||
|
scan_bpl_full = reader->params.scan_bpl;
|
||
|
|
||
|
if (reader->params.color && reader->params.line_mode)
|
||
|
scan_bpl_full *= 3;
|
||
|
|
||
|
reader->pixel_buffer = malloc (scan_bpl_full);
|
||
|
if (!reader->pixel_buffer)
|
||
|
{
|
||
|
XDBG ((3, "%s: cannot allocate pixel buffer\n", function_name));
|
||
|
gt68xx_line_reader_free_delays (reader);
|
||
|
free (reader);
|
||
|
return SANE_STATUS_NO_MEM;
|
||
|
}
|
||
|
|
||
|
gt68xx_device_set_read_buffer_size (reader->dev,
|
||
|
scan_bpl_full /* * 200 */ );
|
||
|
|
||
|
image_size = reader->params.scan_bpl * reader->params.scan_ys;
|
||
|
status = gt68xx_device_read_prepare (reader->dev, image_size, final_scan);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
{
|
||
|
XDBG ((3, "%s: gt68xx_device_read_prepare failed: %s\n",
|
||
|
function_name, sane_strstatus (status)));
|
||
|
free (reader->pixel_buffer);
|
||
|
gt68xx_line_reader_free_delays (reader);
|
||
|
free (reader);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
XDBG ((6, "%s: leave: ok\n", function_name));
|
||
|
*reader_return = reader;
|
||
|
return SANE_STATUS_GOOD;
|
||
|
}
|
||
|
|
||
|
SANE_Status
|
||
|
gt68xx_line_reader_free (GT68xx_Line_Reader * reader)
|
||
|
{
|
||
|
DECLARE_FUNCTION_NAME ("gt68xx_line_reader_free") SANE_Status status;
|
||
|
|
||
|
XDBG ((6, "%s: enter\n", function_name));
|
||
|
|
||
|
gt68xx_line_reader_free_delays (reader);
|
||
|
|
||
|
if (reader->pixel_buffer)
|
||
|
{
|
||
|
free (reader->pixel_buffer);
|
||
|
reader->pixel_buffer = NULL;
|
||
|
}
|
||
|
|
||
|
status = gt68xx_device_read_finish (reader->dev);
|
||
|
if (status != SANE_STATUS_GOOD)
|
||
|
{
|
||
|
XDBG ((3, "%s: gt68xx_device_read_finish failed: %s\n",
|
||
|
function_name, sane_strstatus (status)));
|
||
|
}
|
||
|
|
||
|
free (reader);
|
||
|
|
||
|
XDBG ((6, "%s: leave\n", function_name));
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
SANE_Status
|
||
|
gt68xx_line_reader_read (GT68xx_Line_Reader * reader,
|
||
|
unsigned int **buffer_pointers_return)
|
||
|
{
|
||
|
SANE_Status status;
|
||
|
|
||
|
status = (*reader->read) (reader, buffer_pointers_return);
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
|