kopia lustrzana https://gitlab.com/sane-project/backends
Changes for ADF simplex and duplex scan, MP970 4800 dpi and TPU scan.
rodzic
7fa6ae708c
commit
1aa1677ef2
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2008-10-04 Nicolas Martin <nicols-guest at users.alioth.debian.org>
|
||||
* backend/pixma.c, backend/pixma.h, backend/pixma_common.c,
|
||||
backend/pixma_io_sanei.c, backend/pixma_mp150.c,
|
||||
doc/sane-pixma.man, doc/description/pixma.desc:
|
||||
MP970 scanning improvements, up to 4800 dpi. On the way soon,
|
||||
network BJNP protocol designed by Louis Lagendijk to be added to CVS.
|
||||
MX7600 reported to work fine with the backend.
|
||||
ADF scanning:
|
||||
- improved for latest PIXMAs like MX850, MX310.
|
||||
- bug fix in Sane_start, when scanning several pages with ADF.
|
||||
ADF DUPLEX scanning:
|
||||
- new code for ADF Duplex, (to be tested) based on a MX850 Snoop. Changes
|
||||
might fit also MP830 (To be confirmed).
|
||||
TPU scanning:
|
||||
- MP970 TPU scanning: Protocol works, get scanned TPU images with 48 bits
|
||||
to 24 bits conversion, full 48 bit version yet to be debugged.
|
||||
|
||||
2008-10-03 m. allan noah <kitno455 a t gmail d o t com>
|
||||
* backend/epjitsu.[ch]: backend v17:
|
||||
- increase scan height ~1/2 inch due to head offset
|
||||
|
|
480
backend/pixma.c
480
backend/pixma.c
|
@ -174,11 +174,11 @@ cleanup_device_list (void)
|
|||
{
|
||||
int i;
|
||||
for (i = 0; dev_list[i]; i++)
|
||||
{
|
||||
free (CONST_CAST (void *, dev_list[i]->name));
|
||||
free (CONST_CAST (void *, dev_list[i]->model));
|
||||
free (CONST_CAST (void *, dev_list[i]));
|
||||
}
|
||||
{
|
||||
free (CONST_CAST (void *, dev_list[i]->name));
|
||||
free (CONST_CAST (void *, dev_list[i]->model));
|
||||
free (CONST_CAST (void *, dev_list[i]));
|
||||
}
|
||||
}
|
||||
free (dev_list);
|
||||
dev_list = NULL;
|
||||
|
@ -201,16 +201,16 @@ find_scanners (void)
|
|||
SANE_Device *sdev = (SANE_Device *) calloc (1, sizeof (*sdev));
|
||||
char *name, *model;
|
||||
if (!sdev)
|
||||
goto nomem;
|
||||
goto nomem;
|
||||
name = strdup (pixma_get_device_id (i));
|
||||
model = strdup (pixma_get_device_model (i));
|
||||
if (!name || !model)
|
||||
{
|
||||
free (name);
|
||||
free (model);
|
||||
free (sdev);
|
||||
goto nomem;
|
||||
}
|
||||
{
|
||||
free (name);
|
||||
free (model);
|
||||
free (sdev);
|
||||
goto nomem;
|
||||
}
|
||||
sdev->name = name;
|
||||
sdev->model = model;
|
||||
sdev->vendor = vendor_str;
|
||||
|
@ -281,23 +281,23 @@ clamp_value (pixma_sane_t * ss, SANE_Int n, void *v, SANE_Int * info)
|
|||
{
|
||||
SANE_Word value = va[i];
|
||||
if (value < range->min)
|
||||
{
|
||||
value = range->min;
|
||||
}
|
||||
{
|
||||
value = range->min;
|
||||
}
|
||||
else if (value > range->max)
|
||||
{
|
||||
value = range->max;
|
||||
}
|
||||
{
|
||||
value = range->max;
|
||||
}
|
||||
if (range->quant != 0)
|
||||
{
|
||||
value = (value - range->min + range->quant / 2) /
|
||||
range->quant * range->quant;
|
||||
}
|
||||
{
|
||||
value = (value - range->min + range->quant / 2) /
|
||||
range->quant * range->quant;
|
||||
}
|
||||
if (value != va[i])
|
||||
{
|
||||
va[i] = value;
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
{
|
||||
va[i] = value;
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,21 +317,21 @@ select_value_from_list (pixma_sane_t * ss, SANE_Int n, void *v,
|
|||
SANE_Word mindelta = abs (value - list[1]);
|
||||
SANE_Word nearest = list[1];
|
||||
for (j = 2; j <= list[0]; j++)
|
||||
{
|
||||
SANE_Word delta = abs (value - list[j]);
|
||||
if (delta < mindelta)
|
||||
{
|
||||
mindelta = delta;
|
||||
nearest = list[j];
|
||||
}
|
||||
if (mindelta == 0)
|
||||
break;
|
||||
}
|
||||
{
|
||||
SANE_Word delta = abs (value - list[j]);
|
||||
if (delta < mindelta)
|
||||
{
|
||||
mindelta = delta;
|
||||
nearest = list[j];
|
||||
}
|
||||
if (mindelta == 0)
|
||||
break;
|
||||
}
|
||||
if (va[i] != nearest)
|
||||
{
|
||||
va[i] = nearest;
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
{
|
||||
va[i] = nearest;
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,51 +346,51 @@ control_scalar_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v,
|
|||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
switch (opt->sod.type)
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
*(SANE_Word *) v = opt->val.w;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
*(SANE_Word *) v = opt->val.w;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
switch (opt->sod.type)
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
val = *(SANE_Word *) v;
|
||||
if (val != SANE_TRUE && val != SANE_FALSE)
|
||||
return SANE_STATUS_INVAL;
|
||||
opt->val.w = val;
|
||||
break;
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
if (opt->sod.constraint_type == SANE_CONSTRAINT_RANGE)
|
||||
clamp_value (ss, n, v, info);
|
||||
else if (opt->sod.constraint_type == SANE_CONSTRAINT_WORD_LIST)
|
||||
select_value_from_list (ss, n, v, info);
|
||||
opt->val.w = *(SANE_Word *) v;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
val = *(SANE_Word *) v;
|
||||
if (val != SANE_TRUE && val != SANE_FALSE)
|
||||
return SANE_STATUS_INVAL;
|
||||
opt->val.w = val;
|
||||
break;
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
if (opt->sod.constraint_type == SANE_CONSTRAINT_RANGE)
|
||||
clamp_value (ss, n, v, info);
|
||||
else if (opt->sod.constraint_type == SANE_CONSTRAINT_WORD_LIST)
|
||||
select_value_from_list (ss, n, v, info);
|
||||
opt->val.w = *(SANE_Word *) v;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
*info |= opt->info;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
switch (opt->sod.type)
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
opt->val.w = opt->def.w;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
{
|
||||
case SANE_TYPE_BOOL:
|
||||
case SANE_TYPE_INT:
|
||||
case SANE_TYPE_FIXED:
|
||||
opt->val.w = opt->def.w;
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
*info |= opt->info;
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -409,45 +409,45 @@ control_string_option (pixma_sane_t * ss, SANE_Int n, SANE_Action a, void *v,
|
|||
if (opt->sod.constraint_type == SANE_CONSTRAINT_NONE)
|
||||
{
|
||||
switch (a)
|
||||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
strcpy (str, opt->val.s);
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
str = opt->def.s;
|
||||
/* fall through */
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
strncpy (opt->val.s, str, opt->sod.size - 1);
|
||||
*info |= opt->info;
|
||||
break;
|
||||
}
|
||||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
strcpy (str, opt->val.s);
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
str = opt->def.s;
|
||||
/* fall through */
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
strncpy (opt->val.s, str, opt->sod.size - 1);
|
||||
*info |= opt->info;
|
||||
break;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (a)
|
||||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
strcpy (str, slist[opt->val.w]);
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
str = opt->def.ptr;
|
||||
/* fall through */
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
i = 0;
|
||||
while (slist[i] && strcasecmp (str, slist[i]) != 0)
|
||||
i++;
|
||||
if (!slist[i])
|
||||
return SANE_STATUS_INVAL;
|
||||
if (strcmp (slist[i], str) != 0)
|
||||
{
|
||||
strcpy (str, slist[i]);
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
opt->val.w = i;
|
||||
*info |= opt->info;
|
||||
break;
|
||||
}
|
||||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
strcpy (str, slist[opt->val.w]);
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
str = opt->def.ptr;
|
||||
/* fall through */
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
i = 0;
|
||||
while (slist[i] && strcasecmp (str, slist[i]) != 0)
|
||||
i++;
|
||||
if (!slist[i])
|
||||
return SANE_STATUS_INVAL;
|
||||
if (strcmp (slist[i], str) != 0)
|
||||
{
|
||||
strcpy (str, slist[i]);
|
||||
*info |= SANE_INFO_INEXACT;
|
||||
}
|
||||
opt->val.w = i;
|
||||
*info |= opt->info;
|
||||
break;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
}
|
||||
|
@ -461,37 +461,37 @@ control_option (pixma_sane_t * ss, SANE_Int n,
|
|||
result = SANE_STATUS_UNSUPPORTED;
|
||||
switch (n)
|
||||
{
|
||||
case opt_gamma_table:
|
||||
switch (a)
|
||||
{
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
clamp_value (ss, n, v, info);
|
||||
for (i = 0; i != 4096; i++)
|
||||
ss->gamma_table[i] = *((SANE_Int *) v + i);
|
||||
break;
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
for (i = 0; i != 4096; i++)
|
||||
*((SANE_Int *) v + i) = ss->gamma_table[i];
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table,
|
||||
sizeof (ss->gamma_table));
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
case opt_gamma_table:
|
||||
switch (a)
|
||||
{
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
clamp_value (ss, n, v, info);
|
||||
for (i = 0; i != 4096; i++)
|
||||
ss->gamma_table[i] = *((SANE_Int *) v + i);
|
||||
break;
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
for (i = 0; i != 4096; i++)
|
||||
*((SANE_Int *) v + i) = ss->gamma_table[i];
|
||||
break;
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
pixma_fill_gamma_table (AUTO_GAMMA, ss->gamma_table,
|
||||
sizeof (ss->gamma_table));
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case opt_button_update:
|
||||
if (a == SANE_ACTION_SET_VALUE)
|
||||
{
|
||||
update_button_state (ss, info);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
{
|
||||
update_button_state (ss, info);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -518,10 +518,10 @@ control_option (pixma_sane_t * ss, SANE_Int n,
|
|||
{
|
||||
case opt_custom_gamma:
|
||||
if (a == SANE_ACTION_SET_VALUE || a == SANE_ACTION_SET_AUTO)
|
||||
{
|
||||
if (enable_option (ss, opt_gamma_table, OVAL (opt_custom_gamma).b))
|
||||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||
}
|
||||
{
|
||||
if (enable_option (ss, opt_gamma_table, OVAL (opt_custom_gamma).b))
|
||||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -582,6 +582,7 @@ calc_scan_param (pixma_sane_t * ss, pixma_scan_param_t * sp)
|
|||
|
||||
sp->gamma_table = (OVAL (opt_custom_gamma).b) ? ss->gamma_table : NULL;
|
||||
sp->source = ss->source_map[OVAL (opt_source).w];
|
||||
sp->adf_pageid = ss->page_count;
|
||||
|
||||
error = pixma_check_scan_param (ss->s, sp);
|
||||
if (error < 0)
|
||||
|
@ -646,7 +647,7 @@ init_option_descriptors (pixma_sane_t * ss)
|
|||
ss->source_map[i] = PIXMA_SOURCE_ADFDUP;
|
||||
i++;
|
||||
}
|
||||
#if 0
|
||||
#if 1
|
||||
if (cfg->cap & PIXMA_CAP_TPU)
|
||||
{
|
||||
ss->source_list[i] = SANE_I18N ("Transparency Unit");
|
||||
|
@ -728,36 +729,36 @@ reader_loop (pixma_sane_t * ss)
|
|||
"To cancel, press 'GRAY' button.\n");
|
||||
#endif
|
||||
while (pixma_wait_event (ss->s, 10) != 0)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
while (!start)
|
||||
{
|
||||
uint32_t events;
|
||||
if (ss->reader_stop)
|
||||
{
|
||||
count = PIXMA_ECANCELED;
|
||||
goto done;
|
||||
}
|
||||
events = pixma_wait_event (ss->s, 1000);
|
||||
switch (events & ~PIXMA_EV_ACTION_MASK)
|
||||
{
|
||||
case PIXMA_EV_BUTTON1:
|
||||
start = 1;
|
||||
break;
|
||||
case PIXMA_EV_BUTTON2:
|
||||
count = PIXMA_ECANCELED;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
{
|
||||
uint32_t events;
|
||||
if (ss->reader_stop)
|
||||
{
|
||||
count = PIXMA_ECANCELED;
|
||||
goto done;
|
||||
}
|
||||
events = pixma_wait_event (ss->s, 1000);
|
||||
switch (events & ~PIXMA_EV_ACTION_MASK)
|
||||
{
|
||||
case PIXMA_EV_BUTTON1:
|
||||
start = 1;
|
||||
break;
|
||||
case PIXMA_EV_BUTTON2:
|
||||
count = PIXMA_ECANCELED;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = pixma_scan (ss->s, &ss->sp);
|
||||
if (count >= 0)
|
||||
{
|
||||
while ((count = pixma_read_image (ss->s, buf, bufsize)) > 0)
|
||||
{
|
||||
if (write_all (ss, buf, count) != count)
|
||||
pixma_cancel (ss->s);
|
||||
}
|
||||
{
|
||||
if (write_all (ss, buf, count) != count)
|
||||
pixma_cancel (ss->s);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -839,7 +840,7 @@ terminate_reader_task (pixma_sane_t * ss, int *exit_code)
|
|||
if (result == pid)
|
||||
{
|
||||
if (exit_code)
|
||||
*exit_code = status;
|
||||
*exit_code = status;
|
||||
return pid;
|
||||
}
|
||||
else
|
||||
|
@ -886,10 +887,10 @@ start_reader_task (pixma_sane_t * ss)
|
|||
{
|
||||
pid = sanei_thread_begin (reader_process, ss);
|
||||
if (pid > 0)
|
||||
{
|
||||
close (ss->wpipe);
|
||||
ss->wpipe = -1;
|
||||
}
|
||||
{
|
||||
close (ss->wpipe);
|
||||
ss->wpipe = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -923,8 +924,8 @@ read_image (pixma_sane_t * ss, void *buf, unsigned size, int *readlen)
|
|||
do
|
||||
{
|
||||
if (ss->cancel)
|
||||
/* ss->rpipe has already been closed by sane_cancel(). */
|
||||
return SANE_STATUS_CANCELLED;
|
||||
/* ss->rpipe has already been closed by sane_cancel(). */
|
||||
return SANE_STATUS_CANCELLED;
|
||||
count = read (ss->rpipe, buf, size);
|
||||
}
|
||||
while (count == -1 && errno == EINTR);
|
||||
|
@ -932,12 +933,12 @@ read_image (pixma_sane_t * ss, void *buf, unsigned size, int *readlen)
|
|||
if (count == -1)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
return SANE_STATUS_GOOD;
|
||||
return SANE_STATUS_GOOD;
|
||||
if (!ss->cancel)
|
||||
{
|
||||
PDBG (pixma_dbg (1, "WARNING:read_image():read() failed %s\n",
|
||||
strerror (errno)));
|
||||
}
|
||||
{
|
||||
PDBG (pixma_dbg (1, "WARNING:read_image():read() failed %s\n",
|
||||
strerror (errno)));
|
||||
}
|
||||
close (ss->rpipe);
|
||||
ss->rpipe = -1;
|
||||
terminate_reader_task (ss, NULL);
|
||||
|
@ -964,16 +965,16 @@ read_image (pixma_sane_t * ss, void *buf, unsigned size, int *readlen)
|
|||
close (ss->rpipe);
|
||||
ss->rpipe = -1;
|
||||
if (terminate_reader_task (ss, &status) != -1
|
||||
&& status != SANE_STATUS_GOOD)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
&& status != SANE_STATUS_GOOD)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* either terminate_reader_task failed or
|
||||
rpipe was closed but we expect more data */
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
{
|
||||
/* either terminate_reader_task failed or
|
||||
rpipe was closed but we expect more data */
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
if (readlen)
|
||||
*readlen = count;
|
||||
|
@ -1051,17 +1052,17 @@ sane_open (SANE_String_Const name, SANE_Handle * h)
|
|||
for (ss = first_scanner; ss; ss = ss->next)
|
||||
{
|
||||
if (strcmp (pixma_get_string (ss->s, PIXMA_STRING_ID), name) == 0)
|
||||
{
|
||||
/* We have already opened it! */
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
{
|
||||
/* We have already opened it! */
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (strcmp (pixma_get_device_id (i), name) != 0)
|
||||
{
|
||||
if (++i >= nscanners)
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
cfg = pixma_get_device_config (i);
|
||||
if ((cfg->cap & PIXMA_CAP_EXPERIMENT) != 0)
|
||||
|
@ -1070,13 +1071,13 @@ sane_open (SANE_String_Const name, SANE_Handle * h)
|
|||
pixma_dbg (1, "WARNING:"
|
||||
"Experimental backend CAN DAMAGE your hardware!\n");
|
||||
if (getenv_atoi ("PIXMA_EXPERIMENT", 0) == 0)
|
||||
{
|
||||
pixma_dbg (1, "Experimental SANE backend for %s is disabled "
|
||||
"by default.\n", pixma_get_device_model (i));
|
||||
pixma_dbg (1, "To enable it, set the environment variable "
|
||||
"PIXMA_EXPERIMENT to non-zero.\n");
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
{
|
||||
pixma_dbg (1, "Experimental SANE backend for %s is disabled "
|
||||
"by default.\n", pixma_get_device_model (i));
|
||||
pixma_dbg (1, "To enable it, set the environment variable "
|
||||
"PIXMA_EXPERIMENT to non-zero.\n");
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
#else
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
#endif
|
||||
|
@ -1220,9 +1221,20 @@ sane_start (SANE_Handle h)
|
|||
if (!ss)
|
||||
return SANE_STATUS_INVAL;
|
||||
if (!ss->idle && ss->scanning)
|
||||
return SANE_STATUS_INVAL;
|
||||
{
|
||||
PDBG (pixma_dbg (3, "Warning in Sane_start: !idle && scanning. idle=%d, ss->scanning=%d\n",
|
||||
ss->idle, ss->scanning));
|
||||
if (ss->sp.source != PIXMA_SOURCE_ADF && ss->sp.source != PIXMA_SOURCE_ADFDUP)
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
ss->cancel = SANE_FALSE;
|
||||
if (ss->idle ||
|
||||
ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_FLATBED ||
|
||||
ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_TPU)
|
||||
ss->page_count = 0; /* start from idle state or scan from flatbed or TPU */
|
||||
else
|
||||
ss->page_count++;
|
||||
if (calc_scan_param (ss, &ss->sp) < 0)
|
||||
return SANE_STATUS_INVAL;
|
||||
ss->image_bytes_read = 0;
|
||||
|
@ -1233,12 +1245,6 @@ sane_start (SANE_Handle h)
|
|||
{
|
||||
ss->output_line_size = ss->sp.w * ss->sp.channels * (ss->sp.depth / 8);
|
||||
ss->byte_pos_in_line = 0;
|
||||
if (ss->idle ||
|
||||
ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_FLATBED ||
|
||||
ss->source_map[OVAL (opt_source).w] == PIXMA_SOURCE_TPU)
|
||||
ss->page_count = 0; /* start from idle state or scan from flatbed or TPU */
|
||||
else
|
||||
ss->page_count++;
|
||||
ss->last_read_status = SANE_STATUS_GOOD;
|
||||
ss->scanning = SANE_TRUE;
|
||||
ss->idle = SANE_FALSE;
|
||||
|
@ -1277,38 +1283,36 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
|
|||
the end of line, we've to remove it here in the backend! */
|
||||
sum = 0;
|
||||
while (sum < maxlen)
|
||||
{
|
||||
if (ss->byte_pos_in_line < ss->output_line_size)
|
||||
{
|
||||
n = ss->output_line_size - ss->byte_pos_in_line;
|
||||
if ((maxlen - sum) < n)
|
||||
n = maxlen - sum;
|
||||
status = read_image (ss, buf, n, &n);
|
||||
if (n == 0)
|
||||
break;
|
||||
sum += n;
|
||||
buf += n;
|
||||
ss->byte_pos_in_line += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* skip padding */
|
||||
n = ss->sp.line_size - ss->byte_pos_in_line;
|
||||
if (n > (int) sizeof (temp))
|
||||
{
|
||||
PDBG (pixma_dbg (3,
|
||||
"Inefficient skip buffer. Should be %d\n",
|
||||
n));
|
||||
n = sizeof (temp);
|
||||
}
|
||||
status = read_image (ss, temp, n, &n);
|
||||
if (n == 0)
|
||||
break;
|
||||
ss->byte_pos_in_line += n;
|
||||
if (ss->byte_pos_in_line == ss->sp.line_size)
|
||||
ss->byte_pos_in_line = 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
if (ss->byte_pos_in_line < ss->output_line_size)
|
||||
{
|
||||
n = ss->output_line_size - ss->byte_pos_in_line;
|
||||
if ((maxlen - sum) < n)
|
||||
n = maxlen - sum;
|
||||
status = read_image (ss, buf, n, &n);
|
||||
if (n == 0)
|
||||
break;
|
||||
sum += n;
|
||||
buf += n;
|
||||
ss->byte_pos_in_line += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* skip padding */
|
||||
n = ss->sp.line_size - ss->byte_pos_in_line;
|
||||
if (n > (int) sizeof (temp))
|
||||
{
|
||||
PDBG (pixma_dbg (3, "Inefficient skip buffer. Should be %d\n", n));
|
||||
n = sizeof (temp);
|
||||
}
|
||||
status = read_image (ss, temp, n, &n);
|
||||
if (n == 0)
|
||||
break;
|
||||
ss->byte_pos_in_line += n;
|
||||
if (ss->byte_pos_in_line == ss->sp.line_size)
|
||||
ss->byte_pos_in_line = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ss->cancel)
|
||||
status = SANE_STATUS_CANCELLED;
|
||||
|
|
|
@ -266,6 +266,9 @@ struct pixma_scan_param_t
|
|||
|
||||
/** \see #pixma_paper_source_t */
|
||||
pixma_paper_source_t source;
|
||||
|
||||
/** The current page # in the same ADF scan session, 0 in non ADF */
|
||||
unsigned adf_pageid;
|
||||
};
|
||||
|
||||
/** PIXMA model information */
|
||||
|
|
|
@ -122,16 +122,16 @@ pixma_hexdump (int level, const void *d_, unsigned len)
|
|||
line[9] = ':';
|
||||
p = line + 10;
|
||||
for (c = 0; c != 16 && (ofs + c) < len; c++)
|
||||
{
|
||||
u8tohex (d[ofs + c], p);
|
||||
p[2] = ' ';
|
||||
p += 3;
|
||||
if (c == 7)
|
||||
{
|
||||
p[0] = ' ';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
{
|
||||
u8tohex (d[ofs + c], p);
|
||||
p[2] = ' ';
|
||||
p += 3;
|
||||
if (c == 7)
|
||||
{
|
||||
p[0] = ' ';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
p[0] = '\0';
|
||||
pixma_dbg (level, "%s\n", line);
|
||||
ofs += c;
|
||||
|
@ -621,67 +621,65 @@ pixma_read_image (pixma_t * s, void *buf, unsigned len)
|
|||
if (s->underrun)
|
||||
{
|
||||
if (s->cur_image_size < s->param->image_size)
|
||||
{
|
||||
ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(3, "pixma_read_image():completed (underrun detected)\n"));
|
||||
s->scanning = 0;
|
||||
}
|
||||
{
|
||||
ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDBG (pixma_dbg
|
||||
(3, "pixma_read_image():completed (underrun detected)\n"));
|
||||
s->scanning = 0;
|
||||
}
|
||||
return ib.wptr - (uint8_t *) buf;
|
||||
}
|
||||
|
||||
while (ib.wptr != ib.wend)
|
||||
{
|
||||
if (ib.rptr == ib.rend)
|
||||
{
|
||||
ib.rptr = ib.rend = NULL;
|
||||
result = s->ops->fill_buffer (s, &ib);
|
||||
if (result < 0)
|
||||
goto cancel;
|
||||
if (result == 0)
|
||||
{ /* end of image? */
|
||||
s->ops->finish_scan (s);
|
||||
#ifndef NDEBUG
|
||||
if (s->cur_image_size != s->param->image_size)
|
||||
{
|
||||
pixma_dbg (1, "WARNING:image size mismatches\n");
|
||||
pixma_dbg (1,
|
||||
" %u expected (%d lines) but %u received (%d lines)\n",
|
||||
s->param->image_size, s->param->h,
|
||||
s->cur_image_size,
|
||||
s->cur_image_size / s->param->line_size);
|
||||
if ((s->cur_image_size % s->param->line_size) != 0)
|
||||
{
|
||||
pixma_dbg (1,
|
||||
"BUG:received data not multiple of line_size\n");
|
||||
}
|
||||
}
|
||||
#endif /* !NDEBUG */
|
||||
if (s->cur_image_size < s->param->image_size)
|
||||
{
|
||||
s->underrun = 1;
|
||||
ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDBG (pixma_dbg (3, "pixma_read_image():completed\n"));
|
||||
s->scanning = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
s->cur_image_size += result;
|
||||
PASSERT (s->cur_image_size <= s->param->image_size);
|
||||
}
|
||||
{
|
||||
ib.rptr = ib.rend = NULL;
|
||||
result = s->ops->fill_buffer (s, &ib);
|
||||
if (result < 0)
|
||||
goto cancel;
|
||||
if (result == 0)
|
||||
{ /* end of image? */
|
||||
s->ops->finish_scan (s);
|
||||
if (s->cur_image_size != s->param->image_size)
|
||||
{
|
||||
pixma_dbg (1, "WARNING:image size mismatches\n");
|
||||
pixma_dbg (1,
|
||||
" %u expected (%d lines) but %u received (%d lines)\n",
|
||||
s->param->image_size, s->param->h,
|
||||
s->cur_image_size,
|
||||
s->cur_image_size / s->param->line_size);
|
||||
if ((s->cur_image_size % s->param->line_size) != 0)
|
||||
{
|
||||
pixma_dbg (1,
|
||||
"BUG:received data not multiple of line_size\n");
|
||||
}
|
||||
}
|
||||
if (s->cur_image_size < s->param->image_size)
|
||||
{
|
||||
s->underrun = 1;
|
||||
ib.wptr = fill_pixels (s, ib.wptr, ib.wend, 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
PDBG (pixma_dbg (3, "pixma_read_image():completed\n"));
|
||||
s->scanning = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
s->cur_image_size += result;
|
||||
PASSERT (s->cur_image_size <= s->param->image_size);
|
||||
}
|
||||
if (ib.rptr)
|
||||
{
|
||||
unsigned count = MIN (ib.rend - ib.rptr, ib.wend - ib.wptr);
|
||||
memcpy (ib.wptr, ib.rptr, count);
|
||||
ib.rptr += count;
|
||||
ib.wptr += count;
|
||||
}
|
||||
{
|
||||
unsigned count = MIN (ib.rend - ib.rptr, ib.wend - ib.wptr);
|
||||
memcpy (ib.wptr, ib.rptr, count);
|
||||
ib.rptr += count;
|
||||
ib.wptr += count;
|
||||
}
|
||||
}
|
||||
s->imagebuf = ib; /* store rptr and rend */
|
||||
return ib.wptr - (uint8_t *) buf;
|
||||
|
@ -764,37 +762,37 @@ pixma_check_scan_param (pixma_t * s, pixma_scan_param_t * sp)
|
|||
|
||||
case PIXMA_SOURCE_TPU:
|
||||
if ((s->cfg->cap & PIXMA_CAP_TPU) != PIXMA_CAP_TPU)
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: TPU unsupported, fallback to flatbed.\n"));
|
||||
}
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: TPU unsupported, fallback to flatbed.\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMA_SOURCE_ADF:
|
||||
if ((s->cfg->cap & PIXMA_CAP_ADF) != PIXMA_CAP_ADF)
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: ADF unsupported, fallback to flatbed.\n"));
|
||||
}
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: ADF unsupported, fallback to flatbed.\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMA_SOURCE_ADFDUP:
|
||||
if ((s->cfg->cap & PIXMA_CAP_ADFDUP) != PIXMA_CAP_ADFDUP)
|
||||
{
|
||||
if (s->cfg->cap & PIXMA_CAP_ADF)
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_ADF;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
}
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: ADF duplex unsupported, fallback to %d.\n",
|
||||
sp->source));
|
||||
}
|
||||
{
|
||||
if (s->cfg->cap & PIXMA_CAP_ADF)
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_ADF;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp->source = PIXMA_SOURCE_FLATBED;
|
||||
}
|
||||
PDBG (pixma_dbg
|
||||
(1, "WARNING: ADF duplex unsupported, fallback to %d.\n",
|
||||
sp->source));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,19 +272,19 @@ pixma_collect_devices (const struct pixma_config_t *const pixma_devices[])
|
|||
for (i = 0; pixma_devices[i]; i++)
|
||||
{
|
||||
for (cfg = pixma_devices[i]; cfg->name; cfg++)
|
||||
{
|
||||
sanei_usb_find_devices (cfg->vid, cfg->pid, attach);
|
||||
si = first_scanner;
|
||||
while (j < nscanners)
|
||||
{
|
||||
PDBG (pixma_dbg (3, "pixma_collect_devices() found %s at %s\n",
|
||||
cfg->name, si->devname));
|
||||
si->cfg = cfg;
|
||||
read_serial_number (si);
|
||||
si = si->next;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
{
|
||||
sanei_usb_find_devices (cfg->vid, cfg->pid, attach);
|
||||
si = first_scanner;
|
||||
while (j < nscanners)
|
||||
{
|
||||
PDBG (pixma_dbg (3, "pixma_collect_devices() found %s at %s\n",
|
||||
cfg->name, si->devname));
|
||||
si->cfg = cfg;
|
||||
read_serial_number (si);
|
||||
si = si->next;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nscanners;
|
||||
}
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -158,7 +158,7 @@
|
|||
:interface "USB"
|
||||
:usbid "0x04a9" "0x1713"
|
||||
:status :basic
|
||||
:comment "Single-side ADF works but duplex doesn't work yet."
|
||||
:comment "Single-side ADF works, Duplex ADF to be tested."
|
||||
|
||||
:model "PIXMA MP960"
|
||||
:interface "USB"
|
||||
|
@ -169,7 +169,7 @@
|
|||
:interface "USB"
|
||||
:usbid "0x04a9" "0x1726"
|
||||
:status :good
|
||||
:comment "All resolutions supported (up to 4800DPI)"
|
||||
:comment "All resolutions supported (up to 4800DPI). TPU support currently experimental."
|
||||
|
||||
:model "SmartBase MP360"
|
||||
:interface "USB"
|
||||
|
@ -240,8 +240,8 @@
|
|||
:model "PIXMA MX7600"
|
||||
:interface "USB"
|
||||
:usbid "0x04a9" "0x171c"
|
||||
:status :untested
|
||||
:comment "Generation 3 protocol? Testers needed!"
|
||||
:status :good
|
||||
:comment "Flatbed and ADF scan. All resolutions supported (up to 4800DPI)"
|
||||
|
||||
:model "imageCLASS MF5630"
|
||||
:interface "USB"
|
||||
|
|
|
@ -18,7 +18,7 @@ PIXMA MP600, MP600R, MP610, MP710
|
|||
.br
|
||||
PIXMA MP800, MP800R, MP810, MP830, MP960, MP970
|
||||
.br
|
||||
PIXMA MX300, MX310, MX700
|
||||
PIXMA MX300, MX310, MX700, MX850, MX7600
|
||||
.br
|
||||
MultiPASS MP700, PIXMA MP750 (no grayscale)
|
||||
.br
|
||||
|
@ -47,13 +47,13 @@ ImageCLASS MF3110, MF3240
|
|||
ImageCLASS MF5630, MF5650, MF5730, MF5750, MF5770, MF8170c
|
||||
.RE
|
||||
.PP
|
||||
The following models may use partly the same Pixma protocol as MPs listed
|
||||
above, but may still need some work. They are declared in the backend as
|
||||
experimental. Snoop logs are required to further investigate, please contact
|
||||
the sane\-devel mailing list.
|
||||
\#The following models may use partly the same Pixma protocol as MPs listed
|
||||
\#above, but may still need some work. They are declared in the backend as
|
||||
\#experimental. Snoop logs are required to further investigate, please contact
|
||||
\#the sane\-devel mailing list.
|
||||
.PP
|
||||
.RS
|
||||
PIXMA MX850
|
||||
\#PIXMA MX850
|
||||
.RE
|
||||
.PP
|
||||
The backend supports
|
||||
|
@ -64,7 +64,9 @@ The backend supports
|
|||
.br
|
||||
* a custom gamma table and
|
||||
.br
|
||||
* automatic document feeder (only single side, duplex needs some work).
|
||||
* Automatic Document Feeder (Duplex for some models).
|
||||
.br
|
||||
* Transparency Unit support is still experimental.
|
||||
.PP
|
||||
The device name is in the form pixma:xxxxyyyy_zzzzz
|
||||
where x, y and z are vendor ID, product ID and serial number respectively.
|
||||
|
|
Ładowanie…
Reference in New Issue