kopia lustrzana https://gitlab.com/sane-project/backends
hp-backend V 0.91, 04-Sep-2000, David Paschal (paschal@rcsis.com):
- Added support for flatbed HP OfficeJets - (PK) fix problem with cancel preview hp-backend V 0.91, V 0.90, 02-Sep-2000, PK: - fix timing problem between killing child and writing to pipe - change fprintf(stderr,...) to DBG - change include <sane..> to "sane.." in hp.h - change handling of options that have global effects. i.e. if option scanmode is received (has global effect), all options that "may change" are send to the scanner again. This fixes a problem that --resolution specified infront of --mode on command line of scanimage was ignored. NOTE: This change does not allow to specify --depth 12 infront of --mode color, because --depth is only enabled with --mode color. - add depth greater 8 bits for mode grayscale - add option for 8 bit output but 10/12 bit scanningDEVEL_2_0_BRANCH-1
rodzic
e56def0c53
commit
e907811055
|
@ -157,6 +157,9 @@ sanei_hp_device_support_probe (HpScsi scsi)
|
|||
SCL_BW_DITHER,
|
||||
SCL_CONTRAST,
|
||||
SCL_BRIGHTNESS,
|
||||
#ifdef SCL_SHARPENING
|
||||
SCL_SHARPENING,
|
||||
#endif
|
||||
SCL_MIRROR_IMAGE,
|
||||
SCL_X_RESOLUTION,
|
||||
SCL_Y_RESOLUTION,
|
||||
|
@ -175,6 +178,7 @@ sanei_hp_device_support_probe (HpScsi scsi)
|
|||
SCL_CHANGE_DOC,
|
||||
SCL_ADF_BFEED
|
||||
};
|
||||
enum hp_device_compat_e compat;
|
||||
|
||||
DBG(1, "hp_device_support_probe: Check supported commands for %s\n",
|
||||
sanei_hp_scsi_devicename (scsi) );
|
||||
|
@ -194,6 +198,14 @@ sanei_hp_device_support_probe (HpScsi scsi)
|
|||
sclsupport->is_supported = (status == SANE_STATUS_GOOD);
|
||||
sclsupport->checked = 1;
|
||||
|
||||
/* The OfficeJets seem to ignore brightness and contrast settings,
|
||||
* so we'll pretend they're not supported at all. */
|
||||
if (((sclprobe[k]==SCL_BRIGHTNESS) || (sclprobe[k]==SCL_CONTRAST)) &&
|
||||
(sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD) &&
|
||||
(compat & HP_COMPAT_OJ_1150C)) {
|
||||
sclsupport->is_supported=0;
|
||||
}
|
||||
|
||||
if (sclsupport->is_supported)
|
||||
{
|
||||
DBG(1, "hp_device_support_probe: %d supported (%d..%d, %d)\n",
|
||||
|
@ -217,18 +229,20 @@ sanei_hp_device_probe (enum hp_device_compat_e *compat, HpScsi scsi)
|
|||
const char * model;
|
||||
enum hp_device_compat_e flag;
|
||||
} probes[] = {
|
||||
{ SCL_HP_MODEL_1, "Plus", HP_COMPAT_PLUS },
|
||||
{ SCL_HP_MODEL_2, "IIc", HP_COMPAT_2C },
|
||||
{ SCL_HP_MODEL_3, "IIp", HP_COMPAT_2P },
|
||||
{ SCL_HP_MODEL_4, "IIcx", HP_COMPAT_2CX },
|
||||
{ SCL_HP_MODEL_5, "4c/3c", HP_COMPAT_4C },
|
||||
{ SCL_HP_MODEL_6, "3p", HP_COMPAT_3P },
|
||||
{ SCL_HP_MODEL_8, "4P", HP_COMPAT_4P },
|
||||
{ SCL_HP_MODEL_9, "5P", HP_COMPAT_5P },
|
||||
{ SCL_HP_MODEL_10, "Photo Scanner", HP_COMPAT_PS },
|
||||
{ SCL_HP_MODEL_14, "6200C/6250C", HP_COMPAT_6200C },
|
||||
{ SCL_HP_MODEL_16, "5200C",HP_COMPAT_5200C },
|
||||
{ SCL_HP_MODEL_17, "6300C/6350C",HP_COMPAT_6300C }
|
||||
{ SCL_HP_MODEL_1, "ScanJet Plus", HP_COMPAT_PLUS },
|
||||
{ SCL_HP_MODEL_2, "ScanJet IIc", HP_COMPAT_2C },
|
||||
{ SCL_HP_MODEL_3, "ScanJet IIp", HP_COMPAT_2P },
|
||||
{ SCL_HP_MODEL_4, "ScanJet IIcx", HP_COMPAT_2CX },
|
||||
{ SCL_HP_MODEL_5, "ScanJet 3c/4c/6100C", HP_COMPAT_4C },
|
||||
{ SCL_HP_MODEL_6, "ScanJet 3p", HP_COMPAT_3P },
|
||||
{ SCL_HP_MODEL_8, "ScanJet 4p", HP_COMPAT_4P },
|
||||
{ SCL_HP_MODEL_9, "ScanJet 5p/4100C/5100C", HP_COMPAT_5P },
|
||||
{ SCL_HP_MODEL_10,"PhotoSmart Photo Scanner", HP_COMPAT_PS },
|
||||
{ SCL_HP_MODEL_11,"OfficeJet 1150C", HP_COMPAT_OJ_1150C },
|
||||
{ SCL_HP_MODEL_12,"OfficeJet 1170C or later", HP_COMPAT_OJ_1170C },
|
||||
{ SCL_HP_MODEL_14,"ScanJet 6200C/6250C", HP_COMPAT_6200C },
|
||||
{ SCL_HP_MODEL_16,"ScanJet 5200C", HP_COMPAT_5200C },
|
||||
{ SCL_HP_MODEL_17,"ScanJet 6300C/6350C", HP_COMPAT_6300C }
|
||||
};
|
||||
int i;
|
||||
char buf[8];
|
||||
|
@ -260,7 +274,7 @@ sanei_hp_device_probe (enum hp_device_compat_e *compat, HpScsi scsi)
|
|||
if (!FAILED( status = sanei_hp_scl_upload(scsi, probes[i].cmd,
|
||||
buf, sizeof(buf)) ))
|
||||
{
|
||||
DBG(1, "probe_scanner: Scanjet %s compatible\n", probes[i].model);
|
||||
DBG(1, "probe_scanner: %s compatible\n", probes[i].model);
|
||||
*compat |= probes[i].flag;
|
||||
}
|
||||
else if (!UNSUPPORTED( status ))
|
||||
|
@ -298,7 +312,7 @@ hp_nonscsi_device_new (HpDevice * newp, const char * devname, HpConnect connect)
|
|||
|| memcmp(sanei_hp_scsi_vendor(scsi), "HP ", 8) != 0)
|
||||
{
|
||||
DBG(1, "%s: does not seem to be an HP scanner\n", devname);
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
#endif
|
||||
|
@ -307,7 +321,7 @@ hp_nonscsi_device_new (HpDevice * newp, const char * devname, HpConnect connect)
|
|||
if (FAILED( sanei_hp_scl_reset(scsi) ))
|
||||
{
|
||||
DBG(1, "hp_nonscsi_device_new: SCL reset failed\n");
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -334,7 +348,7 @@ hp_nonscsi_device_new (HpDevice * newp, const char * devname, HpConnect connect)
|
|||
sanei_hp_device_support_probe (scsi);
|
||||
status = sanei_hp_optset_new(&(this->options), scsi, this);
|
||||
}
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
|
@ -363,6 +377,8 @@ sanei_hp_device_new (HpDevice * newp, const char * devname)
|
|||
SANE_Status status;
|
||||
char * str;
|
||||
|
||||
DBG(3, "sanei_hp_device_new: %s\n", devname);
|
||||
|
||||
connect = sanei_hp_get_connect (devname);
|
||||
if ( connect != HP_CONNECT_SCSI )
|
||||
return hp_nonscsi_device_new (newp, devname, connect);
|
||||
|
@ -377,7 +393,7 @@ sanei_hp_device_new (HpDevice * newp, const char * devname)
|
|||
|| memcmp(sanei_hp_scsi_vendor(scsi), "HP ", 8) != 0)
|
||||
{
|
||||
DBG(1, "%s: does not seem to be an HP scanner\n", devname);
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
|
@ -385,7 +401,7 @@ sanei_hp_device_new (HpDevice * newp, const char * devname)
|
|||
if (FAILED( sanei_hp_scl_reset(scsi) ))
|
||||
{
|
||||
DBG(1, "sanei_hp_device_new: SCL reset failed\n");
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -412,7 +428,7 @@ sanei_hp_device_new (HpDevice * newp, const char * devname)
|
|||
sanei_hp_device_support_probe (scsi);
|
||||
status = sanei_hp_optset_new(&this->options, scsi, this);
|
||||
}
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
|
|
|
@ -47,19 +47,21 @@
|
|||
#include "hp.h"
|
||||
|
||||
enum hp_device_compat_e {
|
||||
HP_COMPAT_PLUS = 1 << 0, /* Hp ScanJet Plus */
|
||||
HP_COMPAT_PLUS = 1 << 0, /* HP ScanJet Plus */
|
||||
HP_COMPAT_2C = 1 << 1,
|
||||
HP_COMPAT_2P = 1 << 2,
|
||||
HP_COMPAT_2CX = 1 << 3,
|
||||
HP_COMPAT_4C = 1 << 4, /* also for 3C, 6100C */
|
||||
HP_COMPAT_4C = 1 << 4, /* also 3c, 6100C */
|
||||
HP_COMPAT_3P = 1 << 5,
|
||||
HP_COMPAT_4P = 1 << 6,
|
||||
HP_COMPAT_5P = 1 << 7,
|
||||
HP_COMPAT_5100C = 1 << 8, /* also 4100 C */
|
||||
HP_COMPAT_PS = 1 << 9, /* Hp PhotoSmart Photo Scanner */
|
||||
HP_COMPAT_6200C = 1 << 10,
|
||||
HP_COMPAT_5200C = 1 << 11,
|
||||
HP_COMPAT_6300C = 1 << 12
|
||||
HP_COMPAT_5P = 1 << 7, /* also 4100C, 5100C */
|
||||
HP_COMPAT_5100C = 1 << 8, /* redundant with 5p */
|
||||
HP_COMPAT_PS = 1 << 9, /* HP PhotoSmart Photo Scanner */
|
||||
HP_COMPAT_OJ_1150C = 1 << 10,
|
||||
HP_COMPAT_OJ_1170C = 1 << 11, /* also later OfficeJets */
|
||||
HP_COMPAT_6200C = 1 << 12,
|
||||
HP_COMPAT_5200C = 1 << 13,
|
||||
HP_COMPAT_6300C = 1 << 14
|
||||
};
|
||||
|
||||
struct hp_device_s
|
||||
|
|
|
@ -130,6 +130,7 @@ hp_handle_startReader (HpHandle this, HpScsi scsi, HpProcessData *procdata)
|
|||
/* not closing fds[1] gives an infinite loop on Digital UNIX */
|
||||
status = sanei_hp_scsi_pipeout(scsi,fds[1],procdata);
|
||||
close (fds[1]);
|
||||
DBG(3,"hp_handle_startReader: Exiting child (%s)\n",sane_strstatus(status));
|
||||
_exit(status);
|
||||
}
|
||||
|
||||
|
@ -144,10 +145,10 @@ hp_handle_stopScan (HpHandle this)
|
|||
if (this->reader_pid)
|
||||
{
|
||||
int info;
|
||||
DBG(3, "do_cancel: killing child (%d)\n", this->reader_pid);
|
||||
DBG(3, "hp_handle_stopScan: killing child (%d)\n", this->reader_pid);
|
||||
kill(this->reader_pid, SIGTERM);
|
||||
waitpid(this->reader_pid, &info, 0);
|
||||
DBG(1, "do_cancel: child %s = %d\n",
|
||||
DBG(1, "hp_handle_stopScan: child %s = %d\n",
|
||||
WIFEXITED(info) ? "exited, status" : "signalled, signal",
|
||||
WIFEXITED(info) ? WEXITSTATUS(info) : WTERMSIG(info));
|
||||
close(this->pipefd);
|
||||
|
@ -161,15 +162,19 @@ hp_handle_stopScan (HpHandle this)
|
|||
sanei_hp_scl_errcheck(scsi);
|
||||
*/
|
||||
sanei_hp_scl_reset(scsi);
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG(3, "hp_handle_stopScan: no pid for child\n");
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
hp_handle_uploadParameters (HpHandle this, HpScsi scsi, int *scan_depth,
|
||||
hp_bool_t *soft_invert)
|
||||
hp_bool_t *soft_invert, hp_bool_t *out8)
|
||||
{
|
||||
SANE_Parameters * p = &this->scan_params;
|
||||
int data_width;
|
||||
|
@ -178,6 +183,7 @@ hp_handle_uploadParameters (HpHandle this, HpScsi scsi, int *scan_depth,
|
|||
assert(scsi);
|
||||
|
||||
*soft_invert = 0;
|
||||
*out8 = 0;
|
||||
|
||||
p->last_frame = SANE_TRUE;
|
||||
/* inquire resulting size of image after setting it up */
|
||||
|
@ -196,17 +202,48 @@ hp_handle_uploadParameters (HpHandle this, HpScsi scsi, int *scan_depth,
|
|||
p->format = SANE_FRAME_GRAY;
|
||||
p->depth = 1;
|
||||
*scan_depth = 1;
|
||||
|
||||
/* The OfficeJets don't seem to handle SCL_INVERSE_IMAGE, so we'll
|
||||
* have to invert in software. */
|
||||
if ((sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
|
||||
&& (compat & HP_COMPAT_OJ_1150C)) {
|
||||
*soft_invert=1;
|
||||
}
|
||||
|
||||
break;
|
||||
case HP_SCANMODE_GRAYSCALE: /* Grayscale */
|
||||
p->format = SANE_FRAME_GRAY;
|
||||
p->depth = 8;
|
||||
*scan_depth = 8;
|
||||
p->depth = (data_width > 8) ? 16 : 8;
|
||||
*scan_depth = data_width;
|
||||
|
||||
/* 8 bit output forced ? */
|
||||
if ( *scan_depth > 8 )
|
||||
{
|
||||
*out8 = sanei_hp_optset_output_8bit (this->dev->options, this->data);
|
||||
DBG(1,"hp_handle_uploadParameters: out8=%d\n", (int)*out8);
|
||||
if (*out8)
|
||||
{
|
||||
p->depth = 8;
|
||||
p->bytes_per_line /= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HP_SCANMODE_COLOR: /* RGB */
|
||||
p->format = SANE_FRAME_RGB;
|
||||
p->depth = (data_width > 24) ? 16 : 8;
|
||||
*scan_depth = data_width / 3;
|
||||
|
||||
/* 8 bit output forced ? */
|
||||
if ( *scan_depth > 8 )
|
||||
{
|
||||
*out8 = sanei_hp_optset_output_8bit (this->dev->options, this->data);
|
||||
DBG(1,"hp_handle_uploadParameters: out8=%d\n", (int)*out8);
|
||||
if (*out8)
|
||||
{
|
||||
p->depth = 8;
|
||||
p->bytes_per_line /= 2;
|
||||
}
|
||||
}
|
||||
/* HP PhotoSmart does not invert when depth > 8. Lets do it by software */
|
||||
if ( (*scan_depth > 8)
|
||||
&& (sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
|
||||
|
@ -245,7 +282,17 @@ sanei_hp_handle_new (HpDevice dev)
|
|||
void
|
||||
sanei_hp_handle_destroy (HpHandle this)
|
||||
{
|
||||
HpScsi scsi=0;
|
||||
|
||||
DBG(3,"sanei_hp_handle_destroy: stop scan\n");
|
||||
|
||||
hp_handle_stopScan(this);
|
||||
|
||||
if (sanei_hp_scsi_new(&scsi,this->dev->sanedev.name)==SANE_STATUS_GOOD &&
|
||||
scsi) {
|
||||
sanei_hp_scsi_destroy(scsi,1);
|
||||
}
|
||||
|
||||
sanei_hp_data_destroy(this->data);
|
||||
sanei_hp_free(this);
|
||||
}
|
||||
|
@ -253,6 +300,11 @@ sanei_hp_handle_destroy (HpHandle this)
|
|||
const SANE_Option_Descriptor *
|
||||
sanei_hp_handle_saneoption (HpHandle this, SANE_Int optnum)
|
||||
{
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(1, "sanei_hp_handle_saneoption: cancelled. Stop scan\n");
|
||||
hp_handle_stopScan(this);
|
||||
}
|
||||
return sanei_hp_optset_saneoption(this->dev->options, this->data, optnum);
|
||||
}
|
||||
|
||||
|
@ -264,10 +316,11 @@ sanei_hp_handle_control(HpHandle this, SANE_Int optnum,
|
|||
HpScsi scsi;
|
||||
hp_bool_t immediate;
|
||||
|
||||
#if 0
|
||||
if (hp_handle_isScanning(this))
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
#endif
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(1, "sanei_hp_handle_control: cancelled. Stop scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
}
|
||||
|
||||
if (hp_handle_isScanning(this))
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
|
@ -279,7 +332,7 @@ sanei_hp_handle_control(HpHandle this, SANE_Int optnum,
|
|||
status = sanei_hp_optset_control(this->dev->options, this->data,
|
||||
optnum, action, valp, info, scsi,
|
||||
immediate);
|
||||
sanei_hp_scsi_destroy ( scsi );
|
||||
sanei_hp_scsi_destroy ( scsi,0 );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -292,6 +345,12 @@ sanei_hp_handle_getParameters (HpHandle this, SANE_Parameters *params)
|
|||
if (!params)
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(1, "sanei_hp_handle_getParameters: cancelled. Stop scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
}
|
||||
|
||||
if (hp_handle_isScanning(this))
|
||||
{
|
||||
*params = this->scan_params;
|
||||
|
@ -310,7 +369,7 @@ sanei_hp_handle_getParameters (HpHandle this, SANE_Parameters *params)
|
|||
if (!FAILED( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) )) {
|
||||
RETURN_IF_FAIL( sanei_hp_scl_inquire(scsi, SCL_NUMBER_OF_LINES,
|
||||
&p->lines,0,0));
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,0);
|
||||
*params = this->scan_params;
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +389,10 @@ sanei_hp_handle_startScan (HpHandle this)
|
|||
/* FIXME: setup preview mode stuff? */
|
||||
|
||||
if (hp_handle_isScanning(this))
|
||||
{
|
||||
DBG(3,"sanei_hp_handle_startScan: Stop current scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
}
|
||||
|
||||
RETURN_IF_FAIL( sanei_hp_scsi_new(&scsi, this->dev->sanedev.name) );
|
||||
|
||||
|
@ -339,11 +401,12 @@ sanei_hp_handle_startScan (HpHandle this)
|
|||
if (!FAILED(status))
|
||||
status = hp_handle_uploadParameters(this, scsi,
|
||||
&(procdata.bits_per_channel),
|
||||
&(procdata.invert));
|
||||
&(procdata.invert),
|
||||
&(procdata.out8));
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,0);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -394,10 +457,16 @@ sanei_hp_handle_startScan (HpHandle this)
|
|||
this->bytes_left = ( this->scan_params.bytes_per_line
|
||||
* this->scan_params.lines );
|
||||
|
||||
DBG(1, "start: %d pixels per line, %d bytes, %d lines high\n",
|
||||
DBG(1, "start: %d pixels per line, %d bytes per line, %d lines high\n",
|
||||
this->scan_params.pixels_per_line, this->scan_params.bytes_per_line,
|
||||
this->scan_params.lines);
|
||||
procdata.bytes_per_line = (int)this->scan_params.bytes_per_line;
|
||||
if (procdata.out8)
|
||||
{
|
||||
procdata.bytes_per_line *= 2;
|
||||
DBG(1,"(scanner will send %d bytes per line, 8 bit output forced)\n",
|
||||
procdata.bytes_per_line);
|
||||
}
|
||||
procdata.lines = this->scan_params.lines;
|
||||
|
||||
/* Wait for front-panel button push ? */
|
||||
|
@ -419,7 +488,7 @@ sanei_hp_handle_startScan (HpHandle this)
|
|||
status = hp_handle_startReader(this, scsi, &procdata);
|
||||
}
|
||||
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -431,17 +500,18 @@ sanei_hp_handle_read (HpHandle this, void * buf, size_t *lengthp)
|
|||
ssize_t nread;
|
||||
SANE_Status status;
|
||||
|
||||
DBG(3, "read: trying to read %lu bytes\n", (unsigned long) *lengthp);
|
||||
DBG(3, "sanei_hp_handle_read: trying to read %lu bytes\n",
|
||||
(unsigned long) *lengthp);
|
||||
|
||||
if (!hp_handle_isScanning(this))
|
||||
{
|
||||
DBG(1, "read: not scanning\n");
|
||||
DBG(1, "sanei_hp_handle_read: not scanning\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(1, "read: cancelled\n");
|
||||
DBG(1, "sanei_hp_handle_read: cancelled. Stop scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
@ -457,7 +527,8 @@ sanei_hp_handle_read (HpHandle this, void * buf, size_t *lengthp)
|
|||
*lengthp = 0;
|
||||
if (errno == EAGAIN)
|
||||
return SANE_STATUS_GOOD;
|
||||
DBG(1, "read: read from pipe: %s\n", strerror(errno));
|
||||
DBG(1, "sanei_hp_handle_read: read from pipe: %s. Stop scan\n",
|
||||
strerror(errno));
|
||||
hp_handle_stopScan(this);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
@ -466,11 +537,11 @@ sanei_hp_handle_read (HpHandle this, void * buf, size_t *lengthp)
|
|||
|
||||
if (nread > 0)
|
||||
{
|
||||
DBG(3, "read: read %lu bytes\n", (unsigned long) nread);
|
||||
DBG(3, "sanei_hp_handle_read: read %lu bytes\n", (unsigned long) nread);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
DBG(1, "read: EOF from pipe\n");
|
||||
DBG(1, "sanei_hp_handle_read: EOF from pipe. Stop scan\n");
|
||||
status = this->bytes_left ? SANE_STATUS_IO_ERROR : SANE_STATUS_EOF;
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
|
||||
|
@ -486,7 +557,7 @@ sanei_hp_handle_read (HpHandle this, void * buf, size_t *lengthp)
|
|||
== SANE_STATUS_GOOD )
|
||||
{
|
||||
sanei_hp_scl_set(scsi, SCL_UNLOAD, 0);
|
||||
sanei_hp_scsi_destroy(scsi);
|
||||
sanei_hp_scsi_destroy(scsi,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -497,6 +568,17 @@ void
|
|||
sanei_hp_handle_cancel (HpHandle this)
|
||||
{
|
||||
this->cancelled = 1;
|
||||
/* Office-Jets (K series) may not deliver enough data. */
|
||||
/* Therefor the read might not return until it is interrupted. */
|
||||
DBG(3,"sanei_hp_handle_cancel: compat flags: 0x%04x\n",
|
||||
(int)this->dev->compat);
|
||||
if ( (this->reader_pid)
|
||||
&& (this->dev->compat & (HP_COMPAT_OJ_1150C | HP_COMPAT_OJ_1170C)) )
|
||||
{
|
||||
DBG(3,"sanei_hp_handle_cancel: send SIGTERM to child (%d)\n",
|
||||
this->reader_pid);
|
||||
kill(this->reader_pid, SIGTERM);
|
||||
}
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
|
@ -507,6 +589,7 @@ sanei_hp_handle_setNonblocking (HpHandle this, hp_bool_t non_blocking)
|
|||
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(3,"sanei_hp_handle_setNonblocking: cancelled. Stop scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
@ -525,6 +608,7 @@ sanei_hp_handle_getPipefd (HpHandle this, SANE_Int *fd)
|
|||
|
||||
if (this->cancelled)
|
||||
{
|
||||
DBG(3,"sanei_hp_handle_getPipefd: cancelled. Stop scan\n");
|
||||
RETURN_IF_FAIL( hp_handle_stopScan(this) );
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,6 @@ struct hp_option_descriptor_s
|
|||
HpScl scl_command;
|
||||
int minval, maxval, startval; /* for simulation */
|
||||
HpChoice choices;
|
||||
/* unsigned nchan, chan */
|
||||
};
|
||||
|
||||
struct hp_data_info_s
|
||||
|
@ -163,7 +162,7 @@ static const struct hp_option_descriptor_s
|
|||
GAMMA_VECTOR_7x12[1],
|
||||
RGB_TONEMAP[1], GAMMA_VECTOR_R[1], GAMMA_VECTOR_G[1], GAMMA_VECTOR_B[1],
|
||||
#endif
|
||||
HALFTONE_PATTERN[1], MEDIA[1], BIT_DEPTH[1], SCAN_SOURCE[1],
|
||||
HALFTONE_PATTERN[1], MEDIA[1], OUT8[1], BIT_DEPTH[1], SCAN_SOURCE[1],
|
||||
#ifdef FAKE_COLORSEP_MATRIXES
|
||||
SEPMATRIX[1],
|
||||
#endif
|
||||
|
@ -517,7 +516,7 @@ hp_option_imm_set (HpOptSet optset, HpOption this, HpData data,
|
|||
|
||||
if (FAILED( status = sanei_constrain_value(optd, valp, info) ))
|
||||
{
|
||||
DBG(1, "option_set: %s: constrain_value failed :%s\n",
|
||||
DBG(1, "option_imm_set: %s: constrain_value failed :%s\n",
|
||||
this->descriptor->name, sane_strstatus(status));
|
||||
return status;
|
||||
}
|
||||
|
@ -526,7 +525,7 @@ hp_option_imm_set (HpOptSet optset, HpOption this, HpData data,
|
|||
|
||||
if (_values_are_equal(this, data, old_val, valp))
|
||||
{
|
||||
DBG(3, "option_set: value unchanged\n");
|
||||
DBG(3, "option_imm_set: value unchanged\n");
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -557,6 +556,7 @@ hp_option_set (HpOption this, HpData data, void * valp, SANE_Int * info)
|
|||
HpSaneOption optd = hp_option_saneoption(this, data);
|
||||
hp_byte_t * old_val = alloca(optd->size);
|
||||
SANE_Status status;
|
||||
char sval[64];
|
||||
|
||||
|
||||
if (!SANE_OPTION_IS_SETTABLE(optd->cap) || !this->data_acsr)
|
||||
|
@ -564,6 +564,12 @@ hp_option_set (HpOption this, HpData data, void * valp, SANE_Int * info)
|
|||
if (!old_val)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
sval[0] = '\0';
|
||||
if (this->descriptor->type == SANE_TYPE_INT)
|
||||
sprintf (sval," value=%d", *(int*)valp);
|
||||
|
||||
DBG(10,"hp_option_set: %s%s\n", this->descriptor->name, sval);
|
||||
|
||||
if (FAILED( status = sanei_constrain_value(optd, valp, info) ))
|
||||
{
|
||||
DBG(1, "option_set: %s: constrain_value failed :%s\n",
|
||||
|
@ -575,7 +581,7 @@ hp_option_set (HpOption this, HpData data, void * valp, SANE_Int * info)
|
|||
|
||||
if (_values_are_equal(this, data, old_val, valp))
|
||||
{
|
||||
DBG(3, "option_set: value unchanged\n");
|
||||
DBG(3, "option_set: %s: value unchanged\n",this->descriptor->name);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -592,6 +598,9 @@ hp_option_set (HpOption this, HpData data, void * valp, SANE_Int * info)
|
|||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||
if (this->descriptor->affects_scan_params)
|
||||
*info |= SANE_INFO_RELOAD_PARAMS;
|
||||
|
||||
DBG(3, "option_set: %s: info=0x%lx\n",this->descriptor->name,
|
||||
(long)*info);
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -644,11 +653,28 @@ hp_option_control (HpOption this, HpData data,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hp_option_reprogram (HpOption this, HpOptSet optset, HpData data, HpScsi scsi)
|
||||
{
|
||||
if (this->descriptor->may_change)
|
||||
{
|
||||
DBG(5, "hp_option_reprogram: %s\n", this->descriptor->name);
|
||||
|
||||
hp_option_program (this, scsi, optset, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hp_option_reprobe (HpOption this, HpOptSet optset, HpData data, HpScsi scsi)
|
||||
{
|
||||
if (this->descriptor->may_change)
|
||||
{
|
||||
DBG(5, "hp_option_reprobe: %s\n", this->descriptor->name);
|
||||
|
||||
(*this->descriptor->probe)((_HpOption)this, scsi, optset, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -701,7 +727,7 @@ _set_size (HpOption opt, HpData data, SANE_Int size)
|
|||
_hp_option_saneoption(opt, data)->size = size;
|
||||
}
|
||||
|
||||
#ifdef HP_EXPERIMENTAL
|
||||
/* #ifdef HP_EXPERIMENTAL */
|
||||
static SANE_Status
|
||||
_probe_int (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
||||
{
|
||||
|
@ -722,7 +748,7 @@ _probe_int (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
_set_size(this, data, sizeof(SANE_Int));
|
||||
return _set_range(this, data, minval, 1, maxval);
|
||||
}
|
||||
#endif
|
||||
/* #endif */
|
||||
|
||||
static SANE_Status
|
||||
_probe_int_brightness (_HpOption this, HpScsi scsi, HpOptSet optset,
|
||||
|
@ -787,6 +813,14 @@ _probe_resolution (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
sanei_hp_accessor_setint(this->data_acsr, data, val);
|
||||
_set_size(this, data, sizeof(SANE_Int));
|
||||
|
||||
/* The HP OfficeJet Pro 1150C crashes the scan head when scanning at
|
||||
* resolutions less than 42 dpi. Set a safe minimum resolution.
|
||||
* Hopefully 50 dpi is safe enough. */
|
||||
if ((sanei_hp_device_probe(&compat,scsi)==SANE_STATUS_GOOD) &&
|
||||
((compat&(HP_COMPAT_OJ_1150C|HP_COMPAT_OJ_1170C))==HP_COMPAT_OJ_1150C)) {
|
||||
if (minval<50) minval=50;
|
||||
}
|
||||
|
||||
/* HP Photosmart scanner does not allow scanning at arbitrary resolutions */
|
||||
/* for slides/negatives. Must be multiple of 300 dpi. Set quantization. */
|
||||
|
||||
|
@ -824,17 +858,6 @@ _probe_bool (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
_probe_preview (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if (!(this->data_acsr = sanei_hp_accessor_bool_new(data)))
|
||||
return SANE_STATUS_NO_MEM;
|
||||
sanei_hp_accessor_setint(this->data_acsr, data, val);
|
||||
_set_size(this, data, sizeof(SANE_Bool));
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
_probe_change_doc (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
||||
|
@ -862,6 +885,36 @@ _probe_change_doc (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/* The OfficeJets support SCL_UNLOAD even when no ADF is installed, so
|
||||
* this function was added to check for SCL_ADF_CAPABILITY, similar to
|
||||
* _probe_change_doc(), to hide the unnecessary "Unload" button on
|
||||
* non-ADF OfficeJets. */
|
||||
static SANE_Status
|
||||
_probe_unload (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
||||
|
||||
{SANE_Status status;
|
||||
int cap = 0;
|
||||
|
||||
DBG(2, "probe_unload: inquire ADF capability\n");
|
||||
|
||||
status = sanei_hp_scl_inquire(scsi, SCL_ADF_CAPABILITY, &cap, 0, 0);
|
||||
if ( (status != SANE_STATUS_GOOD) || (cap == 0))
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
|
||||
DBG(2, "probe_unload: check if unload is supported\n");
|
||||
|
||||
status = sanei_hp_scl_inquire(scsi, SCL_UNLOAD, &cap, 0, 0);
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
|
||||
if (!(this->data_acsr = sanei_hp_accessor_bool_new(data)))
|
||||
return SANE_STATUS_NO_MEM;
|
||||
sanei_hp_accessor_setint(this->data_acsr, data, cap);
|
||||
_set_size(this, data, sizeof(SANE_Bool));
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
_probe_calibrate (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
||||
{
|
||||
|
@ -871,6 +924,13 @@ _probe_calibrate (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
int download_calib_file = 1;
|
||||
enum hp_device_compat_e compat;
|
||||
|
||||
/* The OfficeJets don't seem to support calibration, so we'll
|
||||
* remove it from the option list to reduce frontend clutter. */
|
||||
if ((sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD) &&
|
||||
(compat & HP_COMPAT_OJ_1150C)) {
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* If we have a Photosmart scanner, we only download the calibration file */
|
||||
/* when medium is set to prints */
|
||||
media = -1;
|
||||
|
@ -972,14 +1032,24 @@ _probe_choice (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
{
|
||||
enum hp_scanmode_e scanmode = sanei_hp_optset_scanmode (optset, data);
|
||||
|
||||
/* Some PhotoSmart scanner report support for only 24 bit. */
|
||||
/* But they also support 30 bit. Dont rely on the inquire in this case */
|
||||
if ( (maxval == 24)
|
||||
&& (sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
|
||||
/* The data width inquiries seem not to work properly on PhotoSmart */
|
||||
/* Sometimes they report just 24 bits, but support 30 bits too. */
|
||||
/* Sometimes they report min/max to be 24/8. Assume they all support */
|
||||
/* at least 10 bits per channel for RGB. Grayscale is only supported */
|
||||
/* with 8 bits. */
|
||||
if ( (sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD)
|
||||
&& (compat & HP_COMPAT_PS))
|
||||
{
|
||||
DBG(1, "choice_option_probe: set max. datawidth to 30 for photosmart");
|
||||
maxval = 30;
|
||||
if (scanmode == HP_SCANMODE_GRAYSCALE)
|
||||
{
|
||||
minval = 8; if (maxval < 8) maxval = 8;
|
||||
}
|
||||
else if (scanmode == HP_SCANMODE_COLOR)
|
||||
{
|
||||
minval = 24; if (maxval < 30) maxval = 30;
|
||||
}
|
||||
DBG(1, "choice_option_probe: set max. datawidth to %d for photosmart\n",
|
||||
maxval);
|
||||
}
|
||||
|
||||
if ( scanmode == HP_SCANMODE_COLOR )
|
||||
|
@ -988,6 +1058,15 @@ _probe_choice (_HpOption this, HpScsi scsi, HpOptSet optset, HpData data)
|
|||
maxval /= 3; if ( maxval <= 0) maxval = 1;
|
||||
val /= 3; if (val <= 0) val = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* The OfficeJets claim to support >8 bits per color, but it may not
|
||||
* work on some models. This code (if not commented out) disables it. */
|
||||
if ((sanei_hp_device_probe (&compat, scsi) == SANE_STATUS_GOOD) &&
|
||||
(compat & HP_COMPAT_OJ_1150C)) {
|
||||
if (maxval>8) maxval=8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
choices = _make_choice_list(this->descriptor->choices, minval, maxval);
|
||||
|
@ -1114,7 +1193,8 @@ _probe_scan_type (_HpOption this, HpScsi scsi, HpOptSet optset,
|
|||
/* Inquire XPA capability is supported only by IIcx and 6100c/4c/3c. */
|
||||
/* But more devices support XPA scan window. So dont inquire XPA cap. */
|
||||
if ( compat & ( HP_COMPAT_2CX | HP_COMPAT_4C | HP_COMPAT_4P
|
||||
| HP_COMPAT_5P | HP_COMPAT_5100C | HP_COMPAT_6200C) )
|
||||
| HP_COMPAT_5P | HP_COMPAT_5100C | HP_COMPAT_6200C) &&
|
||||
!(compat&HP_COMPAT_OJ_1150C) )
|
||||
{
|
||||
scan_types[numchoices++] = this->descriptor->choices[2];
|
||||
}
|
||||
|
@ -1222,8 +1302,6 @@ static SANE_Status _probe_front_button(_HpOption this, HpScsi scsi,
|
|||
HpOptSet optset, HpData data)
|
||||
{
|
||||
int val = 0;
|
||||
const HpDeviceInfo *info =
|
||||
sanei_hp_device_info_get(sanei_hp_scsi_devicename(scsi));
|
||||
|
||||
if ( sanei_hp_scl_inquire(scsi, SCL_FRONT_BUTTON, &val, 0, 0)
|
||||
!= SANE_STATUS_GOOD )
|
||||
|
@ -2412,8 +2490,22 @@ _enable_halftonevec (HpOption this, HpOptSet optset, HpData data,
|
|||
static hp_bool_t
|
||||
_enable_data_width (HpOption this, HpOptSet optset, HpData data,
|
||||
const HpDeviceInfo *info)
|
||||
{enum hp_scanmode_e mode;
|
||||
|
||||
mode = sanei_hp_optset_scanmode (optset, data);
|
||||
return ( (mode == HP_SCANMODE_GRAYSCALE) || (mode == HP_SCANMODE_COLOR) );
|
||||
}
|
||||
|
||||
static hp_bool_t
|
||||
_enable_out8 (HpOption this, HpOptSet optset, HpData data,
|
||||
const HpDeviceInfo *info)
|
||||
{
|
||||
return (sanei_hp_optset_scanmode (optset, data) == HP_SCANMODE_COLOR);
|
||||
if (hp_optset_isEnabled (optset, data, SANE_NAME_BIT_DEPTH, info))
|
||||
{
|
||||
int data_width = sanei_hp_optset_data_width (optset, data);
|
||||
return (((data_width > 8) && (data_width <= 16)) || (data_width > 24));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static hp_bool_t
|
||||
|
@ -2507,7 +2599,7 @@ static const struct hp_option_descriptor_s SCAN_MODE_GROUP[1] = {{
|
|||
static const struct hp_option_descriptor_s PREVIEW_MODE[1] = {{
|
||||
SCANNER_OPTION(PREVIEW, BOOL, NONE),
|
||||
NO_REQUIRES,
|
||||
_probe_preview,
|
||||
_probe_bool,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0 /* for gcc-s sake */
|
||||
}};
|
||||
|
||||
|
@ -2553,6 +2645,14 @@ static const struct hp_option_descriptor_s CONTRAST[1] = {{
|
|||
_probe_int_brightness, _program_generic_simulate, _enable_brightness,
|
||||
0, 0, 0, 0, 0, SCL_CONTRAST, -127, 127, 0, 0
|
||||
}};
|
||||
#ifdef SCL_SHARPENING
|
||||
static const struct hp_option_descriptor_s SHARPENING[1] = {{
|
||||
SCANNER_OPTION(SHARPENING, INT, NONE),
|
||||
NO_REQUIRES,
|
||||
_probe_int, _program_generic, 0,
|
||||
0, 0, 0, 0, 0, SCL_SHARPENING, -127, 127, 0, 0
|
||||
}};
|
||||
#endif
|
||||
static const struct hp_option_descriptor_s AUTO_THRESHOLD[1] = {{
|
||||
SCANNER_OPTION(AUTO_THRESHOLD, BOOL, NONE),
|
||||
NO_REQUIRES,
|
||||
|
@ -2779,6 +2879,27 @@ static const struct hp_option_descriptor_s BIT_DEPTH[1] = {{
|
|||
1, 1, 1, 0, 1, SCL_DATA_WIDTH, 0, 0, 0, _data_widths
|
||||
}};
|
||||
|
||||
static const struct hp_option_descriptor_s OUT8[1] =
|
||||
{
|
||||
{
|
||||
SCANNER_OPTION(OUTPUT_8BIT, BOOL, NONE),
|
||||
NO_REQUIRES, /* enum hp_device_compat_e requires */
|
||||
_probe_bool, /* SANE_Status (*probe)() */
|
||||
0, /* SANE_Status (*program)() */
|
||||
_enable_out8, /* hp_bool_t (*enable)() */
|
||||
0, /* hp_bool_t has_global_effect */
|
||||
0, /* hp_bool_t affects_scan_params */
|
||||
0, /* hp_bool_t program_immediate */
|
||||
0, /* hp_bool_t suppress_for_scan */
|
||||
0, /* hp_bool_t may_change */
|
||||
0, /* HpScl scl_command */
|
||||
0, /* int minval */
|
||||
0, /* int maxval */
|
||||
0, /* int startval */
|
||||
0 /* HpChoice choices */
|
||||
}
|
||||
};
|
||||
|
||||
/* The 100% setting may cause problems within the scanner */
|
||||
static const struct hp_choice_s _ps_exposure_times[] = {
|
||||
/* {0, "100%", 0, 0, 0}, */
|
||||
|
@ -2839,7 +2960,7 @@ static const struct hp_option_descriptor_s CHANGE_DOC[1] = {{
|
|||
static const struct hp_option_descriptor_s UNLOAD[1] = {{
|
||||
SCANNER_OPTION(UNLOAD, BUTTON, NONE),
|
||||
NO_REQUIRES,
|
||||
_probe_bool, _program_unload, 0,
|
||||
_probe_unload, _program_unload, 0,
|
||||
0, 0, 1, 1, 0, SCL_UNLOAD, 0, 0, 0, 0
|
||||
}};
|
||||
|
||||
|
@ -2983,7 +3104,11 @@ static HpOptionDescriptor hp_options[] = {
|
|||
SCAN_MODE, SCAN_RESOLUTION, DEVPIX_RESOLUTION,
|
||||
|
||||
ENHANCEMENT_GROUP,
|
||||
BRIGHTNESS, CONTRAST, AUTO_THRESHOLD,
|
||||
BRIGHTNESS, CONTRAST,
|
||||
#ifdef SCL_SHARPENING
|
||||
SHARPENING,
|
||||
#endif
|
||||
AUTO_THRESHOLD,
|
||||
|
||||
ADVANCED_GROUP,
|
||||
CUSTOM_GAMMA,
|
||||
|
@ -3008,7 +3133,7 @@ static HpOptionDescriptor hp_options[] = {
|
|||
#endif
|
||||
HALFTONE_PATTERN_8x8, HORIZONTAL_DITHER_8x8,
|
||||
|
||||
SCAN_SPEED, SMOOTHING, MEDIA, PS_EXPOSURE_TIME, BIT_DEPTH,
|
||||
SCAN_SPEED, SMOOTHING, MEDIA, PS_EXPOSURE_TIME, BIT_DEPTH, OUT8,
|
||||
SCAN_SOURCE, BUTTON_WAIT, UNLOAD_AFTER_SCAN,
|
||||
CHANGE_DOC, UNLOAD, CALIBRATE,
|
||||
|
||||
|
@ -3099,6 +3224,25 @@ sanei_hp_optset_scanmode (HpOptSet this, HpData data)
|
|||
return hp_option_getint(mode, data);
|
||||
}
|
||||
|
||||
|
||||
hp_bool_t
|
||||
sanei_hp_optset_output_8bit (HpOptSet this, HpData data)
|
||||
{
|
||||
HpOption option_out8;
|
||||
int out8;
|
||||
|
||||
option_out8 = hp_optset_get(this, OUT8);
|
||||
if (option_out8)
|
||||
{
|
||||
out8 = hp_option_getint(option_out8, data);
|
||||
return out8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the data width that is send to the scanner, depending */
|
||||
/* on the scanmode. (b/w: 1, gray: 8..12, color: 24..36 */
|
||||
int
|
||||
sanei_hp_optset_data_width (HpOptSet this, HpData data)
|
||||
{
|
||||
|
@ -3114,12 +3258,19 @@ sanei_hp_optset_data_width (HpOptSet this, HpData data)
|
|||
break;
|
||||
|
||||
case HP_SCANMODE_GRAYSCALE:
|
||||
datawidth = 8;
|
||||
opt_dwidth = hp_optset_get(this, BIT_DEPTH);
|
||||
if (opt_dwidth)
|
||||
datawidth = hp_option_getint (opt_dwidth, data);
|
||||
else
|
||||
datawidth = 8;
|
||||
break;
|
||||
|
||||
case HP_SCANMODE_COLOR:
|
||||
opt_dwidth = hp_optset_get(this, BIT_DEPTH);
|
||||
datawidth = 3 * hp_option_getint (opt_dwidth, data);
|
||||
if (opt_dwidth)
|
||||
datawidth = 3 * hp_option_getint (opt_dwidth, data);
|
||||
else
|
||||
datawidth = 24;
|
||||
break;
|
||||
}
|
||||
return datawidth;
|
||||
|
@ -3148,7 +3299,7 @@ sanei_hp_optset_mirror_vert (HpOptSet this, HpData data, HpScsi scsi)
|
|||
hp_bool_t sanei_hp_optset_start_wait(HpOptSet this, HpData data, HpScsi scsi)
|
||||
{
|
||||
HpOption mode;
|
||||
int wait, sec_dir;
|
||||
int wait;
|
||||
|
||||
if ((mode = hp_optset_get(this, BUTTON_WAIT)) == 0)
|
||||
return(0);
|
||||
|
@ -3254,6 +3405,20 @@ hp_optset_fix_geometry_options (HpOptSet this, HpDevice dev)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
hp_optset_reprogram (HpOptSet this, HpData data, HpScsi scsi)
|
||||
{
|
||||
int i;
|
||||
|
||||
DBG(5, "hp_optset_reprogram: %lu options\n",
|
||||
(unsigned long) this->num_opts);
|
||||
|
||||
for (i = 0; i < (int)this->num_opts; i++)
|
||||
hp_option_reprogram(this->options[i], this, data, scsi);
|
||||
|
||||
DBG(5, "hp_optset_reprogram: finished\n");
|
||||
}
|
||||
|
||||
static void
|
||||
hp_optset_reprobe (HpOptSet this, HpData data, HpScsi scsi)
|
||||
{
|
||||
|
@ -3265,6 +3430,7 @@ hp_optset_reprobe (HpOptSet this, HpData data, HpScsi scsi)
|
|||
for (i = 0; i < (int)this->num_opts; i++)
|
||||
hp_option_reprobe(this->options[i], this, data, scsi);
|
||||
|
||||
DBG(5, "hp_optset_reprobe: finished\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3344,6 +3510,8 @@ sanei_hp_optset_download (HpOptSet this, HpData data, HpScsi scsi)
|
|||
is_preview = hp_option_getint (option, data);
|
||||
if ( is_preview )
|
||||
{
|
||||
/* For preview we only use 8 bit per channel */
|
||||
|
||||
DBG(3, "sanei_hp_optset_download: Set up preview options\n");
|
||||
|
||||
info = sanei_hp_device_info_get ( sanei_hp_scsi_devicename (scsi) );
|
||||
|
@ -3355,6 +3523,10 @@ sanei_hp_optset_download (HpOptSet this, HpData data, HpScsi scsi)
|
|||
{
|
||||
sanei_hp_scl_set(scsi, SCL_DATA_WIDTH, 24);
|
||||
}
|
||||
else if ((data_width > 8) && (data_width <= 16))
|
||||
{
|
||||
sanei_hp_scl_set(scsi, SCL_DATA_WIDTH, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3441,6 +3613,8 @@ sanei_hp_optset_control (HpOptSet this, HpData data,
|
|||
HpOption opt = hp_optset_getByIndex(this, optnum);
|
||||
SANE_Int my_info = 0;
|
||||
|
||||
DBG(3,"sanei_hp_optset_control: %s\n", opt ? opt->descriptor->name : "");
|
||||
|
||||
if (infop)
|
||||
*infop = 0;
|
||||
else
|
||||
|
@ -3458,6 +3632,15 @@ sanei_hp_optset_control (HpOptSet this, HpData data,
|
|||
if ((*infop & SANE_INFO_RELOAD_OPTIONS) != 0)
|
||||
{const HpDeviceInfo *info;
|
||||
|
||||
DBG(3,"sanei_hp_optset_control: reprobe\n");
|
||||
|
||||
/* At first we try to reprogram the parameters that may have changed */
|
||||
/* by an option that had a global effect. This is necessary to */
|
||||
/* specify options in an arbitrary order. Example: */
|
||||
/* Changing scan mode resets scan resolution in the scanner. */
|
||||
/* If resolution is set from the API before scan mode, we must */
|
||||
/* reprogram the resolution afterwards. */
|
||||
hp_optset_reprogram(this, data, scsi);
|
||||
hp_optset_reprobe(this, data, scsi);
|
||||
info = sanei_hp_device_info_get ( sanei_hp_scsi_devicename (scsi) );
|
||||
hp_optset_updateEnables(this, data, info);
|
||||
|
@ -3492,16 +3675,28 @@ sanei_hp_optset_guessParameters (HpOptSet this, HpData data,
|
|||
p->format = SANE_FRAME_GRAY;
|
||||
p->depth = 8;
|
||||
p->bytes_per_line = p->pixels_per_line;
|
||||
if ( !sanei_hp_optset_output_8bit (this, data) )
|
||||
{
|
||||
data_width = sanei_hp_optset_data_width (this, data);
|
||||
if ( data_width > 8 )
|
||||
{
|
||||
p->depth *= 2;
|
||||
p->bytes_per_line *= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HP_SCANMODE_COLOR: /* RGB */
|
||||
p->format = SANE_FRAME_RGB;
|
||||
p->depth = 8;
|
||||
p->bytes_per_line = 3 * p->pixels_per_line;
|
||||
data_width = sanei_hp_optset_data_width (this, data);
|
||||
if ( data_width > 24 )
|
||||
if ( !sanei_hp_optset_output_8bit (this, data) )
|
||||
{
|
||||
p->depth *= 2;
|
||||
p->bytes_per_line *= 2;
|
||||
data_width = sanei_hp_optset_data_width (this, data);
|
||||
if ( data_width > 24 )
|
||||
{
|
||||
p->depth *= 2;
|
||||
p->bytes_per_line *= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
*
|
||||
* FIXME: this should become standard
|
||||
*/
|
||||
|
||||
#ifndef SANE_NAME_SHARPENING
|
||||
# define SANE_NAME_SHARPENING "sharpening"
|
||||
# define SANE_TITLE_SHARPENING "Sharpening"
|
||||
# define SANE_DESC_SHARPENING "Set sharpening value."
|
||||
#endif
|
||||
|
||||
#ifndef SANE_NAME_AUTO_THRESHOLD
|
||||
# define SANE_NAME_AUTO_THRESHOLD "auto-threshold"
|
||||
# define SANE_TITLE_AUTO_THRESHOLD "Auto Threshold"
|
||||
|
@ -140,6 +147,13 @@
|
|||
# define SANE_DESC_UPDATE "Update options."
|
||||
#endif
|
||||
|
||||
#ifndef SANE_NAME_OUTPUT_8BIT
|
||||
# define SANE_NAME_OUTPUT_8BIT "output-8bit"
|
||||
# define SANE_TITLE_OUTPUT_8BIT "8 bit output"
|
||||
# define SANE_DESC_OUTPUT_8BIT "Use bit depth greater eight internally,\
|
||||
but output only eight bits"
|
||||
#endif
|
||||
|
||||
#ifndef SANE_NAME_BUTTON_WAIT
|
||||
# define SANE_NAME_BUTTON_WAIT "button-wait"
|
||||
# define SANE_TITLE_BUTTON_WAIT "Front button wait"
|
||||
|
@ -248,6 +262,7 @@ SANE_Status sanei_hp_optset_control (HpOptSet this, HpData data,
|
|||
SANE_Status sanei_hp_optset_guessParameters (HpOptSet this, HpData data,
|
||||
SANE_Parameters * p);
|
||||
enum hp_scanmode_e sanei_hp_optset_scanmode (HpOptSet this, HpData data);
|
||||
hp_bool_t sanei_hp_optset_output_8bit (HpOptSet this, HpData data);
|
||||
int sanei_hp_optset_data_width (HpOptSet this, HpData data);
|
||||
hp_bool_t sanei_hp_optset_isImmediate (HpOptSet this, int optnum);
|
||||
hp_bool_t sanei_hp_optset_mirror_vert (HpOptSet this, HpData data, HpScsi scsi);
|
||||
|
|
259
backend/hp-scl.c
259
backend/hp-scl.c
|
@ -69,6 +69,10 @@ extern int sanei_debug_hp;
|
|||
#include "hp-scsi.h"
|
||||
#include "hp-scl.h"
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
#include <ptal.h>
|
||||
#endif
|
||||
|
||||
#define HP_SCSI_INQ_LEN (36)
|
||||
#define HP_SCSI_CMD_LEN (6)
|
||||
#define HP_SCSI_BUFSIZ (HP_SCSI_MAX_WRITE + HP_SCSI_CMD_LEN)
|
||||
|
@ -80,6 +84,10 @@ extern int sanei_debug_hp;
|
|||
*/
|
||||
struct hp_scsi_s
|
||||
{
|
||||
#ifdef HAVE_PTAL
|
||||
ptalDevice_t dev;
|
||||
ptalChannel_t chan;
|
||||
#endif
|
||||
int fd;
|
||||
char * devname;
|
||||
|
||||
|
@ -119,6 +127,10 @@ static SANE_Status
|
|||
hp_nonscsi_write (HpScsi this, hp_byte_t *data, size_t len, HpConnect connect)
|
||||
|
||||
{int n = -1;
|
||||
#ifdef HAVE_PTAL
|
||||
int isReset;
|
||||
struct timeval startTimeout,continueTimeout;
|
||||
#endif
|
||||
|
||||
if (len <= 0) return SANE_STATUS_GOOD;
|
||||
|
||||
|
@ -140,6 +152,45 @@ hp_nonscsi_write (HpScsi this, hp_byte_t *data, size_t len, HpConnect connect)
|
|||
n = -1;
|
||||
break;
|
||||
|
||||
case HP_CONNECT_PTAL:
|
||||
#ifndef HAVE_PTAL
|
||||
n = -1;
|
||||
#else
|
||||
/* Check to see if we need to re-open the scan channel in case
|
||||
* JetDirect closed it due to an idle timeout. */
|
||||
if (ptalChannelOpenOrReopen(this->chan)==PTAL_ERROR) {
|
||||
|
||||
break;
|
||||
}
|
||||
if (ptalChannelPrepareForSelect(this->chan,&this->fd,0,0,0,0)==
|
||||
PTAL_ERROR) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we're sending an SCL RESET command, then flush stale
|
||||
* response data after sending the command. Otherwise,
|
||||
* flush stale data before sending the command. This is
|
||||
* necessary because data is buffered between us and the
|
||||
* scanner, which will not be affected by the SCL RESET. */
|
||||
isReset=(len==2 && data[0]==27 && data[1]=='E');
|
||||
startTimeout.tv_sec=0;
|
||||
startTimeout.tv_usec=0;
|
||||
continueTimeout.tv_sec=2;
|
||||
continueTimeout.tv_usec=0;
|
||||
|
||||
if (!isReset) {
|
||||
ptalChannelFlush(this->chan,&startTimeout,&continueTimeout);
|
||||
}
|
||||
|
||||
n=ptalChannelWrite(this->chan,data,len);
|
||||
|
||||
if (isReset) {
|
||||
ptalChannelFlush(this->chan,&startTimeout,&continueTimeout);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
n = -1;
|
||||
break;
|
||||
|
@ -152,9 +203,13 @@ hp_nonscsi_write (HpScsi this, hp_byte_t *data, size_t len, HpConnect connect)
|
|||
}
|
||||
|
||||
static SANE_Status
|
||||
hp_nonscsi_read (HpScsi this, hp_byte_t *data, size_t *len, HpConnect connect)
|
||||
hp_nonscsi_read (HpScsi this, hp_byte_t *data, size_t *len, HpConnect connect,
|
||||
int isResponse)
|
||||
|
||||
{int n = -1;
|
||||
#ifdef HAVE_PTAL
|
||||
struct timeval continueTimeout;
|
||||
#endif
|
||||
|
||||
if (*len <= 0) return SANE_STATUS_GOOD;
|
||||
|
||||
|
@ -176,6 +231,18 @@ hp_nonscsi_read (HpScsi this, hp_byte_t *data, size_t *len, HpConnect connect)
|
|||
n = -1;
|
||||
break;
|
||||
|
||||
case HP_CONNECT_PTAL:
|
||||
#ifndef HAVE_PTAL
|
||||
n = -1;
|
||||
#else
|
||||
continueTimeout.tv_sec=0;
|
||||
if (isResponse) continueTimeout.tv_sec=1;
|
||||
if (*len>1024) continueTimeout.tv_sec=2;
|
||||
continueTimeout.tv_usec=10000;
|
||||
n=ptalSclChannelRead(this->chan,data,*len,0,&continueTimeout,isResponse);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
n = -1;
|
||||
break;
|
||||
|
@ -237,6 +304,12 @@ hp_nonscsi_open (const char *devname, int *fd, HpConnect connect)
|
|||
status = SANE_STATUS_INVAL;
|
||||
break;
|
||||
|
||||
case HP_CONNECT_PTAL:
|
||||
/* This is handled in hp_nonscsi_write()
|
||||
* because we need more than the file descriptor. */
|
||||
status = SANE_STATUS_INVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = SANE_STATUS_INVAL;
|
||||
break;
|
||||
|
@ -271,6 +344,11 @@ hp_nonscsi_close (int fd, HpConnect connect)
|
|||
case HP_CONNECT_RESERVE:
|
||||
break;
|
||||
|
||||
case HP_CONNECT_PTAL:
|
||||
/* This is handled in hp_scsi_close()
|
||||
* because we need more than the file descriptor. */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -286,6 +364,26 @@ sanei_hp_nonscsi_new (HpScsi * newp, const char * devname, HpConnect connect)
|
|||
if (!new)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
if (connect==HP_CONNECT_PTAL) {
|
||||
/* The constant allocation and deallocation of the HpScsi object
|
||||
* does not work well with OfficeJets, especially when connected
|
||||
* to JetDirect. As a somewhat inefficient workaround, we
|
||||
* allocate and set up the PTAL channel once, and look it up by
|
||||
* device name and service type on successive HpScsi instantiations. */
|
||||
new->dev=ptalDeviceOpen((char *)devname);
|
||||
if (!new->dev) {
|
||||
sanei_hp_free(new);
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
new->chan=ptalChannelFindOrAllocate(new->dev,PTAL_STYPE_SCAN,0,0);
|
||||
if (!new->chan) {
|
||||
sanei_hp_free(new);
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
new->fd=PTAL_NO_FD;
|
||||
} else {
|
||||
#endif
|
||||
status = hp_nonscsi_open(devname, &new->fd, connect);
|
||||
if (FAILED(status))
|
||||
{
|
||||
|
@ -293,6 +391,9 @@ sanei_hp_nonscsi_new (HpScsi * newp, const char * devname, HpConnect connect)
|
|||
sanei_hp_free(new);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
#ifdef HAVE_PTAL
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For SCSI-devices we would have the inquire command here */
|
||||
strncpy (new->inq_data, "\003zzzzzzzHP MODELx R000",
|
||||
|
@ -308,15 +409,28 @@ sanei_hp_nonscsi_new (HpScsi * newp, const char * devname, HpConnect connect)
|
|||
|
||||
static void
|
||||
hp_scsi_close (HpScsi this)
|
||||
|
||||
{HpConnect connect;
|
||||
|
||||
DBG(3, "scsi_close: closing fd %ld\n", (long)this->fd);
|
||||
|
||||
connect = sanei_hp_scsi_get_connect (this);
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
if (connect==HP_CONNECT_PTAL) {
|
||||
ptalChannelClose(this->chan);
|
||||
} else {
|
||||
#endif
|
||||
|
||||
assert(this->fd >= 0);
|
||||
|
||||
if (connect != HP_CONNECT_SCSI)
|
||||
hp_nonscsi_close (this->fd, connect);
|
||||
else
|
||||
sanei_scsi_close (this->fd);
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
|
@ -374,12 +488,29 @@ sanei_hp_scsi_new (HpScsi * newp, const char * devname)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_hp_scsi_destroy (HpScsi this)
|
||||
{
|
||||
assert(this->fd >= 0);
|
||||
DBG(3, "scsi_close: closing fd %d\n", this->fd);
|
||||
|
||||
|
||||
/* The "completely" parameter was added for OfficeJet support.
|
||||
* For JetDirect connections, closing and re-opening the scan
|
||||
* channel is very time consuming. Also, the OfficeJet G85
|
||||
* unloads a loaded document in the ADF when the scan channel
|
||||
* gets closed. The solution is to "completely" destroy the
|
||||
* connection, including closing and deallocating the PTAL
|
||||
* channel, when initially probing the device in hp-device.c,
|
||||
* but leave it open while the frontend is actually using the
|
||||
* device (from hp-handle.c), and "completely" destroy it when
|
||||
* the frontend closes its handle. */
|
||||
void
|
||||
sanei_hp_scsi_destroy (HpScsi this,int completely)
|
||||
{
|
||||
/* Moved to hp_scsi_close():
|
||||
* assert(this->fd >= 0);
|
||||
* DBG(3, "scsi_close: closing fd %d\n", this->fd);
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
if (sanei_hp_scsi_get_connect(this)!=HP_CONNECT_PTAL || completely)
|
||||
#endif
|
||||
hp_scsi_close (this);
|
||||
if ( this->devname ) sanei_hp_free (this->devname);
|
||||
sanei_hp_free(this);
|
||||
|
@ -542,8 +673,13 @@ hp_scsi_scl(HpScsi this, HpScl scl, int val)
|
|||
}
|
||||
|
||||
|
||||
/* The OfficeJets tend to return inquiry responses containing array
|
||||
* data in two packets. The added "isResponse" parameter tells
|
||||
* ptalSclChannelRead whether it should keep reading until it gets
|
||||
* a well-formed response. Naturally, this parameter would be zero
|
||||
* when reading scan data. */
|
||||
static SANE_Status
|
||||
hp_scsi_read (HpScsi this, void * dest, size_t *len)
|
||||
hp_scsi_read (HpScsi this, void * dest, size_t *len, int isResponse)
|
||||
{
|
||||
HpConnect connect;
|
||||
static hp_byte_t read_cmd[6] = { 0x08, 0, 0, 0, 0, 0 };
|
||||
|
@ -562,7 +698,7 @@ hp_scsi_read (HpScsi this, void * dest, size_t *len)
|
|||
}
|
||||
else
|
||||
{
|
||||
RETURN_IF_FAIL( hp_nonscsi_read (this, dest, len, connect) );
|
||||
RETURN_IF_FAIL( hp_nonscsi_read (this, dest, len, connect, isResponse) );
|
||||
}
|
||||
DBG(16, "scsi_read: %lu bytes:\n", (unsigned long) *len);
|
||||
DBGDUMP(16, dest, *len);
|
||||
|
@ -575,6 +711,7 @@ static int signal_caught = 0;
|
|||
static RETSIGTYPE
|
||||
signal_catcher (int sig)
|
||||
{
|
||||
DBG(1,"signal_catcher(sig=%d): old signal_caught=%d\n",sig,signal_caught);
|
||||
if (!signal_caught)
|
||||
signal_caught = sig;
|
||||
}
|
||||
|
@ -688,6 +825,53 @@ hp_scale_to_16bit(int count, register unsigned char *data, int depth,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hp_scale_to_8bit(int count, register unsigned char *data, int depth,
|
||||
hp_bool_t invert)
|
||||
{
|
||||
register unsigned int tmp, mask;
|
||||
register hp_bool_t lowbyte_first = is_lowbyte_first_byteorder ();
|
||||
unsigned int shift1 = depth-8;
|
||||
int k;
|
||||
unsigned char *dataout = data;
|
||||
|
||||
if ((count <= 0) || (shift1 <= 0)) return;
|
||||
|
||||
mask = 1;
|
||||
for (k = 1; k < depth; k++) mask |= (1 << k);
|
||||
|
||||
if (lowbyte_first)
|
||||
{
|
||||
while (count--) {
|
||||
tmp = ((((unsigned int)data[0])<<8) | ((unsigned int)data[1])) & mask;
|
||||
tmp >>= shift1;
|
||||
if (invert) tmp = ~tmp;
|
||||
*(dataout++) = tmp & 255U;
|
||||
data += 2;
|
||||
}
|
||||
}
|
||||
else /* Highbyte first */
|
||||
{
|
||||
while (count--) {
|
||||
tmp = ((((unsigned int)data[0])<<8) | ((unsigned int)data[1])) & mask;
|
||||
tmp >>= shift1;
|
||||
if (invert) tmp = ~tmp;
|
||||
*(dataout++) = tmp & 255U;
|
||||
data += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hp_soft_invert(int count, register unsigned char *data) {
|
||||
while (count>0) {
|
||||
*data = ~(*data);
|
||||
data++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
static PROCDATA_HANDLE *
|
||||
process_data_init (HpProcessData *procdata, const unsigned char *map,
|
||||
int outfd, hp_bool_t use_imgbuf)
|
||||
|
@ -717,6 +901,7 @@ process_data_init (HpProcessData *procdata, const unsigned char *map,
|
|||
if ( procdata->mirror_vertical || use_imgbuf)
|
||||
{
|
||||
tsz = procdata->lines*procdata->bytes_per_line;
|
||||
if (procdata->out8) tsz /= 2;
|
||||
ph->image_ptr = ph->image_buf = sanei_hp_alloc (tsz);
|
||||
if ( !ph->image_buf )
|
||||
{
|
||||
|
@ -756,7 +941,9 @@ process_data_write (PROCDATA_HANDLE *ph, unsigned char *data, int nbytes)
|
|||
return SANE_STATUS_GOOD;
|
||||
|
||||
DBG(12, "process_data_write: write %d bytes\n", ph->wr_buf_size);
|
||||
if ( write (ph->outfd, ph->wr_buf, ph->wr_buf_size) != ph->wr_buf_size)
|
||||
/* Don't write data if we got a signal in the meantime */
|
||||
if ( signal_caught
|
||||
|| (write (ph->outfd, ph->wr_buf, ph->wr_buf_size) != ph->wr_buf_size))
|
||||
{
|
||||
DBG(1, "process_data_write: write failed: %s\n",
|
||||
signal_caught ? "signal caught" : strerror(errno));
|
||||
|
@ -768,7 +955,8 @@ process_data_write (PROCDATA_HANDLE *ph, unsigned char *data, int nbytes)
|
|||
/* For large amount of data write it from data-buffer */
|
||||
while ( nbytes > ph->wr_buf_size )
|
||||
{
|
||||
if ( write (ph->outfd, data, ph->wr_buf_size) != ph->wr_buf_size)
|
||||
if ( signal_caught
|
||||
|| (write (ph->outfd, data, ph->wr_buf_size) != ph->wr_buf_size))
|
||||
{
|
||||
DBG(1, "process_data_write: write failed: %s\n",
|
||||
signal_caught ? "signal caught" : strerror(errno));
|
||||
|
@ -787,12 +975,11 @@ process_data_write (PROCDATA_HANDLE *ph, unsigned char *data, int nbytes)
|
|||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status
|
||||
process_scanline (PROCDATA_HANDLE *ph, unsigned char *linebuf,
|
||||
int bytes_per_line)
|
||||
|
||||
{
|
||||
{int out_bytes_per_line = bytes_per_line;
|
||||
HpProcessData *procdata;
|
||||
|
||||
if (ph == NULL) return SANE_STATUS_INVAL;
|
||||
|
@ -802,18 +989,33 @@ process_scanline (PROCDATA_HANDLE *ph, unsigned char *linebuf,
|
|||
hp_data_map (ph->map, bytes_per_line, linebuf);
|
||||
|
||||
if (procdata->bits_per_channel > 8)
|
||||
hp_scale_to_16bit( bytes_per_line/2, linebuf,
|
||||
procdata->bits_per_channel,
|
||||
procdata->invert);
|
||||
{
|
||||
if (procdata->out8)
|
||||
{
|
||||
hp_scale_to_8bit( bytes_per_line/2, linebuf,
|
||||
procdata->bits_per_channel,
|
||||
procdata->invert);
|
||||
out_bytes_per_line /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
hp_scale_to_16bit( bytes_per_line/2, linebuf,
|
||||
procdata->bits_per_channel,
|
||||
procdata->invert);
|
||||
}
|
||||
} else if (procdata->invert) {
|
||||
hp_soft_invert(bytes_per_line,linebuf);
|
||||
}
|
||||
|
||||
if ( ph->image_buf )
|
||||
{
|
||||
DBG(5, "process_scanline: save in memory\n");
|
||||
|
||||
if ( ph->image_ptr+bytes_per_line-1 <= ph->image_buf+ph->image_buf_size-1 )
|
||||
if ( ph->image_ptr+out_bytes_per_line-1
|
||||
<= ph->image_buf+ph->image_buf_size-1 )
|
||||
{
|
||||
memcpy(ph->image_ptr, linebuf, bytes_per_line);
|
||||
ph->image_ptr += bytes_per_line;
|
||||
memcpy(ph->image_ptr, linebuf, out_bytes_per_line);
|
||||
ph->image_ptr += out_bytes_per_line;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -823,7 +1025,7 @@ process_scanline (PROCDATA_HANDLE *ph, unsigned char *linebuf,
|
|||
else /* Save scanlines in a bigger buffer. */
|
||||
{ /* Otherwise we will get performance problems */
|
||||
|
||||
RETURN_IF_FAIL ( process_data_write (ph, linebuf, bytes_per_line) );
|
||||
RETURN_IF_FAIL ( process_data_write (ph, linebuf, out_bytes_per_line) );
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -892,7 +1094,7 @@ process_data_flush (PROCDATA_HANDLE *ph)
|
|||
if ( ph->wr_left != ph->wr_buf_size ) /* Something in write buffer ? */
|
||||
{
|
||||
nbytes = ph->wr_buf_size - ph->wr_left;
|
||||
if ( write (ph->outfd, ph->wr_buf, nbytes) != nbytes)
|
||||
if ( signal_caught || (write (ph->outfd, ph->wr_buf, nbytes) != nbytes))
|
||||
{
|
||||
DBG(1, "process_data_flush: write failed: %s\n",
|
||||
signal_caught ? "signal caught" : strerror(errno));
|
||||
|
@ -906,6 +1108,7 @@ process_data_flush (PROCDATA_HANDLE *ph)
|
|||
if ( ph->image_buf )
|
||||
{
|
||||
bytes_per_line = procdata->bytes_per_line;
|
||||
if (procdata->out8) bytes_per_line /= 2;
|
||||
image_len = (size_t) (ph->image_ptr - ph->image_buf);
|
||||
num_lines = ((int)(image_len + bytes_per_line-1)) / bytes_per_line;
|
||||
|
||||
|
@ -917,7 +1120,8 @@ process_data_flush (PROCDATA_HANDLE *ph)
|
|||
image_data = ph->image_buf + (num_lines-1) * bytes_per_line;
|
||||
while (num_lines > 0 )
|
||||
{
|
||||
if (write(ph->outfd, image_data, bytes_per_line) != bytes_per_line)
|
||||
if ( signal_caught
|
||||
|| (write(ph->outfd, image_data, bytes_per_line) != bytes_per_line))
|
||||
{
|
||||
DBG(1,"process_data_finish: write from memory failed: %s\n",
|
||||
signal_caught ? "signal caught" : strerror(errno));
|
||||
|
@ -933,7 +1137,8 @@ process_data_flush (PROCDATA_HANDLE *ph)
|
|||
image_data = ph->image_buf;
|
||||
while (num_lines > 0 )
|
||||
{
|
||||
if (write(ph->outfd, image_data, bytes_per_line) != bytes_per_line)
|
||||
if ( signal_caught
|
||||
|| (write(ph->outfd, image_data, bytes_per_line) != bytes_per_line))
|
||||
{
|
||||
DBG(1,"process_data_finish: write from memory failed: %s\n",
|
||||
signal_caught ? "signal caught" : strerror(errno));
|
||||
|
@ -1173,7 +1378,7 @@ sanei_hp_scsi_pipeout (HpScsi this, int outfd, HpProcessData *procdata)
|
|||
|
||||
DBG(3, "do_read: try to read data (%lu bytes)\n", (unsigned long)nread);
|
||||
|
||||
status = hp_scsi_read (this, read_buf, &nread);
|
||||
status = hp_scsi_read (this, read_buf, &nread, 0);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG(1, "do_read: Error from scsi_read: %s\n",sane_strstatus(status));
|
||||
|
@ -1258,7 +1463,7 @@ _hp_scl_inq (HpScsi scsi, HpScl scl, HpScl inq_cmnd,
|
|||
|
||||
RETURN_IF_FAIL( hp_scsi_scl(scsi, inq_cmnd, SCL_INQ_ID(scl)) );
|
||||
|
||||
status = hp_scsi_read(scsi, buf, &bufsize);
|
||||
status = hp_scsi_read(scsi, buf, &bufsize, 1);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DBG(1, "scl_inq: read failed (%s)\n", sane_strstatus(status));
|
||||
|
@ -1341,7 +1546,7 @@ sanei_hp_scl_upload_binary (HpScsi scsi, HpScl scl, size_t *lengthhp,
|
|||
|
||||
RETURN_IF_FAIL( hp_scsi_scl(scsi, SCL_UPLOAD_BINARY_DATA, SCL_INQ_ID(scl)) );
|
||||
|
||||
status = hp_scsi_read(scsi, buf, &bufsize);
|
||||
status = hp_scsi_read(scsi, buf, &bufsize, 0);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DBG(1, "scl_upload_binary: read failed (%s)\n", sane_strstatus(status));
|
||||
|
@ -1397,7 +1602,7 @@ sanei_hp_scl_upload_binary (HpScsi scsi, HpScl scl, size_t *lengthhp,
|
|||
if ( val > 0 )
|
||||
{
|
||||
sv = val;
|
||||
status = hp_scsi_read(scsi, hpdata, &sv);
|
||||
status = hp_scsi_read(scsi, hpdata, &sv, 0);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
sanei_hp_free ( *bufhp );
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#define SCL_CONTRAST HP_SCL_CONTROL(10316, 'a', 'K')
|
||||
#define SCL_BRIGHTNESS HP_SCL_CONTROL(10317, 'a', 'L')
|
||||
#define SCL_MIRROR_IMAGE HP_SCL_CONTROL(10318, 'a', 'M')
|
||||
#define SCL_SHARPENING HP_SCL_CONTROL(10319, 'a', 'N')
|
||||
#define SCL_X_RESOLUTION HP_SCL_CONTROL(10323, 'a', 'R')
|
||||
#define SCL_Y_RESOLUTION HP_SCL_CONTROL(10324, 'a', 'S')
|
||||
#define SCL_OUTPUT_DATA_TYPE HP_SCL_CONTROL(10325, 'a', 'T')
|
||||
|
@ -116,6 +117,8 @@
|
|||
#define SCL_HP_MODEL_8 HP_SCL_PARAMETER(15)
|
||||
#define SCL_HP_MODEL_9 HP_SCL_PARAMETER(16)
|
||||
#define SCL_HP_MODEL_10 HP_SCL_PARAMETER(17)
|
||||
#define SCL_HP_MODEL_11 HP_SCL_PARAMETER(18)
|
||||
#define SCL_HP_MODEL_12 HP_SCL_PARAMETER(19)
|
||||
#define SCL_HP_MODEL_14 HP_SCL_PARAMETER(21)
|
||||
#define SCL_HP_MODEL_16 HP_SCL_PARAMETER(31)
|
||||
#define SCL_HP_MODEL_17 HP_SCL_PARAMETER(32)
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
SANE_Status sanei_hp_nonscsi_new (HpScsi * newp, const char * devname,
|
||||
HpConnect connect);
|
||||
SANE_Status sanei_hp_scsi_new (HpScsi * newp, const char * devname);
|
||||
void sanei_hp_scsi_destroy (HpScsi this);
|
||||
void sanei_hp_scsi_destroy (HpScsi this,int completely);
|
||||
|
||||
hp_byte_t * sanei_hp_scsi_inq (HpScsi this);
|
||||
const char *sanei_hp_scsi_model (HpScsi this);
|
||||
|
|
149
backend/hp.c
149
backend/hp.c
|
@ -43,9 +43,26 @@
|
|||
HP Scanner Control Language (SCL).
|
||||
*/
|
||||
|
||||
static char *hp_backend_version = "0.88";
|
||||
static char *hp_backend_version = "0.91";
|
||||
/* Changes:
|
||||
|
||||
V 0.91, 04-Sep-2000, David Paschal (paschal@rcsis.com):
|
||||
- Added support for flatbed HP OfficeJets
|
||||
- (PK) fix problem with cancel preview
|
||||
|
||||
V 0.90, 02-Sep-2000, PK:
|
||||
- fix timing problem between killing child and writing to pipe
|
||||
- change fprintf(stderr,...) to DBG
|
||||
- change include <sane..> to "sane.." in hp.h
|
||||
- change handling of options that have global effects.
|
||||
i.e. if option scanmode is received (has global effect),
|
||||
all options that "may change" are send to the scanner again.
|
||||
This fixes a problem that --resolution specified infront of
|
||||
--mode on command line of scanimage was ignored.
|
||||
NOTE: This change does not allow to specify --depth 12 infront of
|
||||
--mode color, because --depth is only enabled with --mode color.
|
||||
- add depth greater 8 bits for mode grayscale
|
||||
- add option for 8 bit output but 10/12 bit scanning
|
||||
V 0.88, 25-Jul-2000, PK:
|
||||
- remove inlines
|
||||
V 0.88, 20-Jul-2000, PK:
|
||||
|
@ -162,6 +179,10 @@ static char *hp_backend_version = "0.88";
|
|||
#include "hp-device.h"
|
||||
#include "hp-handle.h"
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
#include <ptal.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
|
@ -174,19 +195,25 @@ sanei_hp_dbgdump (const void * bufp, size_t len)
|
|||
const hp_byte_t *buf = bufp;
|
||||
int offset = 0;
|
||||
int i;
|
||||
FILE * fp = stderr;
|
||||
char line[128], pt[32];
|
||||
|
||||
for (offset = 0; offset < (int)len; offset += 16)
|
||||
{
|
||||
fprintf(fp, " 0x%04X ", offset);
|
||||
sprintf (line," 0x%04X ", offset);
|
||||
for (i = offset; i < offset + 16 && i < (int)len; i++)
|
||||
fprintf(fp, " %02X", buf[i]);
|
||||
{
|
||||
sprintf (pt," %02X", buf[i]);
|
||||
strcat (line, pt);
|
||||
}
|
||||
while (i++ < offset + 16)
|
||||
fputs(" ", fp);
|
||||
fputs(" ", fp);
|
||||
strcat (line, " ");
|
||||
strcat (line, " ");
|
||||
for (i = offset; i < offset + 16 && i < (int)len; i++)
|
||||
fprintf(fp, "%c", isprint(buf[i]) ? buf[i] : '.');
|
||||
fputs("\n", fp);
|
||||
{
|
||||
sprintf (pt, "%c", isprint(buf[i]) ? buf[i] : '.');
|
||||
strcat (line, pt);
|
||||
}
|
||||
DBG(16,"%s\n",line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,6 +507,7 @@ hp_get_dev (const char *devname, HpDevice* devp)
|
|||
else if (hp_connect == HP_CONNECT_PIO) connect = "pio";
|
||||
else if (hp_connect == HP_CONNECT_USB) connect = "usb";
|
||||
else if (hp_connect == HP_CONNECT_RESERVE) connect = "reserve";
|
||||
else if (hp_connect == HP_CONNECT_PTAL) connect = "ptal";
|
||||
else connect = "unknown";
|
||||
|
||||
DBG(3, "hp_get_dev: New device %s, connect-%s, scsi-request=%lu\n",
|
||||
|
@ -581,6 +609,16 @@ hp_read_config (void)
|
|||
config->connect = HP_CONNECT_RESERVE;
|
||||
config->use_scsi_request = 0;
|
||||
}
|
||||
else if (strcmp (arg2, "connect-ptal") == 0)
|
||||
{
|
||||
#ifdef HAVE_PTAL
|
||||
config->connect = HP_CONNECT_PTAL;
|
||||
config->use_scsi_request = 0;
|
||||
#else
|
||||
DBG(1,"hp_read_config: connect-ptal:\n");
|
||||
DBG(1," hp-backend not compiled with PTAL support.\n");
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (arg2, "disable-scsi-request") == 0)
|
||||
{
|
||||
config->use_scsi_request = 0;
|
||||
|
@ -673,32 +711,42 @@ hp_update_devlist (void)
|
|||
|
||||
SANE_Status
|
||||
sane_init (SANE_Int *version_code, SANE_Auth_Callback authorize)
|
||||
{
|
||||
{SANE_Status status;
|
||||
|
||||
DBG_INIT();
|
||||
DBG(3, "init called\n");
|
||||
DBG(3, "sane_init called\n");
|
||||
|
||||
#ifdef HAVE_PTAL
|
||||
ptalInit();
|
||||
#endif
|
||||
|
||||
hp_destroy();
|
||||
|
||||
if (version_code)
|
||||
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, VERSIO);
|
||||
|
||||
return hp_init();
|
||||
status = hp_init();
|
||||
DBG(3, "sane_init will finish with %s\n", sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
sane_exit (void)
|
||||
{
|
||||
DBG(3, "exit called\n");
|
||||
DBG(3, "sane_exit called\n");
|
||||
hp_destroy();
|
||||
DBG(3, "sane_exit will finish\n");
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_get_devices (const SANE_Device ***device_list, SANE_Bool local_only)
|
||||
{
|
||||
DBG(3, "get_devices called\n");
|
||||
DBG(3, "sane_get_devices called\n");
|
||||
|
||||
RETURN_IF_FAIL( hp_update_devlist() );
|
||||
*device_list = global.devlist;
|
||||
DBG(3, "sane_get_devices will finish with %s\n",
|
||||
sane_strstatus (SANE_STATUS_GOOD));
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -708,6 +756,8 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)
|
|||
HpDevice dev = 0;
|
||||
HpHandle h;
|
||||
|
||||
DBG(3, "sane_open called\n");
|
||||
|
||||
RETURN_IF_FAIL( hp_read_config() );
|
||||
|
||||
if (devicename[0])
|
||||
|
@ -727,6 +777,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)
|
|||
RETURN_IF_FAIL( hp_handle_list_add(&global.handle_list, h) );
|
||||
|
||||
*handle = h;
|
||||
DBG(3, "sane_open will finish with %s\n", sane_strstatus (SANE_STATUS_GOOD));
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -735,15 +786,27 @@ sane_close (SANE_Handle handle)
|
|||
{
|
||||
HpHandle h = handle;
|
||||
|
||||
DBG(3, "sane_close called\n");
|
||||
|
||||
if (!FAILED( hp_handle_list_remove(&global.handle_list, h) ))
|
||||
sanei_hp_handle_destroy(h);
|
||||
|
||||
DBG(3, "sane_close will finish\n");
|
||||
}
|
||||
|
||||
const SANE_Option_Descriptor *
|
||||
sane_get_option_descriptor (SANE_Handle handle, SANE_Int optnum)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_saneoption(h, optnum);
|
||||
const SANE_Option_Descriptor *optd;
|
||||
|
||||
DBG(10, "sane_get_option_descriptor called\n");
|
||||
|
||||
optd = sanei_hp_handle_saneoption(h, optnum);
|
||||
|
||||
DBG(10, "sane_get_option_descriptor will finish\n");
|
||||
|
||||
return optd;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
|
@ -751,21 +814,44 @@ sane_control_option (SANE_Handle handle, SANE_Int optnum,
|
|||
SANE_Action action, void *valp, SANE_Int *info)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_control(h, optnum, action, valp, info);
|
||||
SANE_Status status;
|
||||
|
||||
DBG(10, "sane_control_option called\n");
|
||||
|
||||
status = sanei_hp_handle_control(h, optnum, action, valp, info);
|
||||
|
||||
DBG(10, "sane_control_option will finish with %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_getParameters(h, params);
|
||||
SANE_Status status;
|
||||
|
||||
DBG(10, "sane_get_parameters called\n");
|
||||
|
||||
status = sanei_hp_handle_getParameters(h, params);
|
||||
|
||||
DBG(10, "sane_get_parameters will finish with %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_start (SANE_Handle handle)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_startScan(h);
|
||||
SANE_Status status;
|
||||
|
||||
DBG(3, "sane_start called\n");
|
||||
|
||||
status = sanei_hp_handle_startScan(h);
|
||||
|
||||
DBG(3, "sane_start will finish with %s\n", sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
|
@ -775,8 +861,12 @@ sane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len, SANE_Int *len)
|
|||
size_t length = max_len;
|
||||
SANE_Status status;
|
||||
|
||||
DBG(16, "sane_read called\n");
|
||||
|
||||
status = sanei_hp_handle_read(h, buf, &length);
|
||||
*len = length;
|
||||
|
||||
DBG(16, "sane_read will finish with %s\n", sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -784,19 +874,40 @@ void
|
|||
sane_cancel (SANE_Handle handle)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
|
||||
DBG(3, "sane_cancel called\n");
|
||||
|
||||
sanei_hp_handle_cancel(h);
|
||||
|
||||
DBG(3, "sane_cancel will finish\n");
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_setNonblocking(h, non_blocking);
|
||||
SANE_Status status;
|
||||
|
||||
DBG(3, "sane_set_io_mode called\n");
|
||||
|
||||
status = sanei_hp_handle_setNonblocking(h, non_blocking);
|
||||
|
||||
DBG(3, "sane_set_io_mode will finish with %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
|
||||
{
|
||||
HpHandle h = handle;
|
||||
return sanei_hp_handle_getPipefd(h, fd);
|
||||
SANE_Status status;
|
||||
|
||||
DBG(10, "sane_get_select_fd called\n");
|
||||
|
||||
status = sanei_hp_handle_getPipefd(h, fd);
|
||||
|
||||
DBG(10, "sane_get_select_fd will finish with %s\n",
|
||||
sane_strstatus (status));
|
||||
return status;
|
||||
}
|
||||
|
|
11
backend/hp.h
11
backend/hp.h
|
@ -46,11 +46,11 @@
|
|||
#define HP_H_INCLUDED
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sane/sane.h>
|
||||
#include "sane/sane.h"
|
||||
|
||||
#undef BACKEND_NAME
|
||||
#define BACKEND_NAME hp
|
||||
#include <sane/sanei_debug.h>
|
||||
#include "sane/sanei_debug.h"
|
||||
|
||||
/* FIXME: these should be options? */
|
||||
#undef ENABLE_7x12_TONEMAPS
|
||||
|
@ -102,7 +102,8 @@ typedef int hp_bool_t;
|
|||
typedef unsigned char hp_byte_t;
|
||||
|
||||
typedef enum { HP_CONNECT_SCSI, HP_CONNECT_DEVICE,
|
||||
HP_CONNECT_PIO, HP_CONNECT_USB, HP_CONNECT_RESERVE } HpConnect;
|
||||
HP_CONNECT_PIO, HP_CONNECT_USB, HP_CONNECT_RESERVE,
|
||||
HP_CONNECT_PTAL } HpConnect;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -156,8 +157,10 @@ typedef long int HpScl;
|
|||
typedef struct
|
||||
{
|
||||
int lines;
|
||||
int bytes_per_line;
|
||||
int bytes_per_line; /* as received from scanner */
|
||||
int bits_per_channel;
|
||||
hp_bool_t out8; /* This flag is set and only set, when data with */
|
||||
/* depths > 8 is to be mapped to 8 bit output. */
|
||||
hp_bool_t mirror_vertical;
|
||||
hp_bool_t invert;
|
||||
HpScl startscan;
|
||||
|
|
Ładowanie…
Reference in New Issue