kopia lustrzana https://gitlab.com/sane-project/backends
improved read data expansion in lineart mode
rodzic
4e9895aca0
commit
410021d1e8
|
@ -5400,13 +5400,13 @@ Problems with the first approach:
|
|||
|
||||
if (dst_lines != 0)
|
||||
{
|
||||
|
||||
if (depth == 1)
|
||||
status = genesys_shrink_lines_1 (work_buffer_src,
|
||||
work_buffer_dst,
|
||||
dst_lines,
|
||||
src_pixels,
|
||||
dev->settings.pixels, channels);
|
||||
dev->settings.pixels,
|
||||
channels);
|
||||
else if (depth == 8)
|
||||
status = genesys_shrink_lines_8 (work_buffer_src,
|
||||
work_buffer_dst,
|
||||
|
@ -6355,7 +6355,6 @@ attach (SANE_String_Const devname, Genesys_Device ** devp, SANE_Bool may_wait)
|
|||
sanei_usb_find_devices (vendor, 0x1006, check_present);
|
||||
sanei_usb_find_devices (vendor, 0x1007, check_present);
|
||||
sanei_usb_find_devices (vendor, 0x1010, check_present);
|
||||
sanei_usb_find_devices (vendor, 0x100f, check_present);
|
||||
if(present==SANE_FALSE)
|
||||
{
|
||||
DBG (DBG_error,"attach: master device not present\n");
|
||||
|
|
|
@ -206,6 +206,11 @@ genesys_gray_lineart(
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/** @brief shrink or grow scanned data to fit the final scan size
|
||||
* This function shrinks the scanned data it the required resolution is lower than the hardware one,
|
||||
* or grows it in case it is the opposite like when motor resolution is higher than
|
||||
* sensor's one.
|
||||
*/
|
||||
static SANE_Status
|
||||
genesys_shrink_lines_1 (
|
||||
uint8_t *src_data,
|
||||
|
@ -215,55 +220,102 @@ genesys_shrink_lines_1 (
|
|||
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];
|
||||
uint8_t *src = (uint8_t *)src_data;
|
||||
uint8_t *dst = (uint8_t *)dst_data;
|
||||
unsigned int dst_x, src_x, y, c, cnt;
|
||||
unsigned int avg[3], val;
|
||||
uint8_t *src = (uint8_t *) src_data;
|
||||
uint8_t *dst = (uint8_t *) dst_data;
|
||||
|
||||
src_pixels /= 8;
|
||||
dst_pixels /= 8;
|
||||
/* choose between case where me must reduce or grow the scanned data */
|
||||
if (src_pixels > dst_pixels)
|
||||
{
|
||||
/* shrink data */
|
||||
/* TODO action must be taken at bit level, no bytes */
|
||||
src_pixels /= 8;
|
||||
dst_pixels /= 8;
|
||||
/*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;
|
||||
|
||||
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++;
|
||||
for (c = 0; c < channels; c++)
|
||||
avg[c] = *src++;
|
||||
src_x++;
|
||||
}
|
||||
cnt -= src_pixels;
|
||||
cnt -= src_pixels;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c];
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* common case where y res is double x res */
|
||||
for (y = 0; y < lines; y++)
|
||||
{
|
||||
if (2 * src_pixels == dst_pixels)
|
||||
{
|
||||
/* double and interleave on line */
|
||||
for (c = 0; c < src_pixels/8; c++)
|
||||
{
|
||||
/* first 4 bits */
|
||||
val = 0;
|
||||
val |= (*src & 0x80) >> 0; /* X___ ____ --> X___ ____ */
|
||||
val |= (*src & 0x80) >> 1; /* X___ ____ --> _X__ ____ */
|
||||
val |= (*src & 0x40) >> 1; /* _X__ ____ --> __X_ ____ */
|
||||
val |= (*src & 0x40) >> 2; /* _X__ ____ --> ___X ____ */
|
||||
val |= (*src & 0x20) >> 2; /* __X_ ____ --> ____ X___ */
|
||||
val |= (*src & 0x20) >> 3; /* __X_ ____ --> ____ _X__ */
|
||||
val |= (*src & 0x10) >> 3; /* ___X ____ --> ____ __X_ */
|
||||
val |= (*src & 0x10) >> 4; /* ___X ____ --> ____ ___X */
|
||||
*dst = val;
|
||||
dst++;
|
||||
|
||||
for (c = 0; c < channels; c++)
|
||||
*dst++ = avg[c];
|
||||
dst_x++;
|
||||
/* last for bits */
|
||||
val = 0;
|
||||
val |= (*src & 0x08) << 4; /* ____ X___ --> X___ ____ */
|
||||
val |= (*src & 0x08) << 3; /* ____ X___ --> _X__ ____ */
|
||||
val |= (*src & 0x04) << 3; /* ____ _X__ --> __X_ ____ */
|
||||
val |= (*src & 0x04) << 2; /* ____ _X__ --> ___X ____ */
|
||||
val |= (*src & 0x02) << 2; /* ____ __X_ --> ____ X___ */
|
||||
val |= (*src & 0x02) << 1; /* ____ __X_ --> ____ _X__ */
|
||||
val |= (*src & 0x01) << 1; /* ____ ___X --> ____ __X_ */
|
||||
val |= (*src & 0x01) << 0; /* ____ ___X --> ____ ___X */
|
||||
*dst = val;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: since depth is 1, we must interpolate bit within bytes */
|
||||
DBG (DBG_warn, "%s: inaccurate bit expansion!\n", __FUNCTION__);
|
||||
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;
|
||||
}
|
||||
cnt -= dst_pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue