1
/************************************************************************************\
3
hpaio.c - HP SANE backend for multi-function peripherals (libsane-hpaio)
5
(c) 2001-2008 Copyright Hewlett-Packard Development Company, LP
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
of the Software, and to permit persons to whom the Software is furnished to do
12
so, subject to the following conditions:
14
The above copyright notice and this permission notice shall be included in all
15
copies or substantial portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
Contributing Authors: David Paschal, Don Welch, David Suffield, Narla Naga Samrat Chowdary,
25
Yashwant Sahu, Sarbeswar Meher
27
\************************************************************************************/
39
#include <sys/types.h>
43
#include <cups/cups.h>
58
#define DEBUG_DECLARE_ONLY
59
#include "sanei_debug.h"
61
static SANE_Device **DeviceList = NULL;
63
static hpaioScanner_t FirstScanner = 0;
64
static hpaioScanner_t LastScanner = 0;
66
static int ResetDeviceList(SANE_Device ***pd)
72
for (i=0; (*pd)[i] && i<MAX_DEVICE; i++)
75
free((void *)(*pd)[i]->name);
77
free((void *)(*pd)[i]->model);
87
static int AddDeviceList(char *uri, char *model, SANE_Device ***pd)
93
/* Allocate array of pointers. */
94
*pd = malloc(sizeof(SANE_Device *) * MAX_DEVICE);
95
memset(*pd, 0, sizeof(SANE_Device *) * MAX_DEVICE);
98
/* Find empty slot in array of pointers. */
99
for (i=0; i<MAX_DEVICE; i++)
101
if ((*pd)[i] == NULL)
103
/* Allocate Sane_Device and members. */
104
(*pd)[i] = malloc(sizeof(SANE_Device));
105
(*pd)[i]->name = malloc(strlen(uri));
106
strcpy((char *)(*pd)[i]->name, uri+3); /* remove "hp:" */
107
(*pd)[i]->model = strdup(model);
108
(*pd)[i]->vendor = "Hewlett-Packard";
109
(*pd)[i]->type = "all-in-one";
117
static int AddCupsList(char *uri, char ***printer)
121
/* Look for hp network URIs only. */
122
if (strncasecmp(uri, "hp:/net/", 8) !=0)
125
if (*printer == NULL)
127
/* Allocate array of string pointers. */
128
*printer = malloc(sizeof(char *) * MAX_DEVICE);
129
memset(*printer, 0, sizeof(char *) * MAX_DEVICE);
132
/* Ignor duplicates (ie: printer queues using the same device). */
133
for (i=0; (*printer)[i] != NULL && i<MAX_DEVICE; i++)
135
if (strcmp((*printer)[i], uri) == 0)
139
/* Find empty slot in array of pointers. */
140
for (i=0; i<MAX_DEVICE; i++)
142
if ((*printer)[i] == NULL)
144
(*printer)[i] = strdup(uri);
156
/* Parse URI record from buf. Assumes one record per line. All returned strings are zero terminated. */
157
static int GetUriLine(char *buf, char *uri, char **tail)
160
int maxBuf = HPMUD_LINE_SIZE*64;
164
if (strncasecmp(&buf[i], "direct ", 7) == 0)
168
for (; buf[i] == ' ' && i < maxBuf; i++); /* eat white space before string */
169
while ((buf[i] != ' ') && (i < maxBuf) && (j < HPMUD_LINE_SIZE))
173
for (; buf[i] != '\n' && i < maxBuf; i++); /* eat rest of line */
177
for (; buf[i] != '\n' && i < maxBuf; i++); /* eat line */
180
i++; /* bump past '\n' */
183
*tail = buf + i; /* tail points to next line */
188
static int GetCupsPrinters(char ***printer)
190
http_t *http=NULL; /* HTTP object */
191
ipp_t *request=NULL; /* IPP request object */
192
ipp_t *response=NULL; /* IPP response object */
193
ipp_attribute_t *attr; /* Current IPP attribute */
196
/* Connect to the HTTP server */
197
if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL)
200
/* Assemble the IPP request */
203
request->request.op.operation_id = CUPS_GET_PRINTERS;
204
request->request.any.request_id = 1;
206
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8");
207
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, "en");
208
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "device-uri");
210
/* Send the request and get a response. */
211
if ((response = cupsDoRequest(http, request, "/")) == NULL)
214
for (attr = response->attrs; attr != NULL; attr = attr->next)
216
/* Skip leading attributes until we hit a printer. */
217
while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
223
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
225
if (strcmp(attr->name, "device-uri") == 0 && attr->value_tag == IPP_TAG_URI && AddCupsList(attr->values[0].string.text, printer) == 0)
240
static int DevDiscovery(int localOnly)
242
struct hpmud_model_attributes ma;
243
char message[HPMUD_LINE_SIZE*64];
244
char uri[HPMUD_LINE_SIZE];
245
char model[HPMUD_LINE_SIZE];
247
int i, scan_type, cnt=0, total=0, bytes_read;
248
char **cups_printer=NULL; /* list of printers */
249
enum HPMUD_RESULT stat;
251
stat = hpmud_probe_devices(HPMUD_BUS_ALL, message, sizeof(message), &cnt, &bytes_read);
253
if (stat != HPMUD_R_OK)
256
/* Look for local all-in-one scan devices (defined by hpmud). */
258
for (i=0; i<cnt; i++)
261
GetUriLine(tail, uri, &tail);
262
hpmud_query_model(uri, &ma);
265
hpmud_get_uri_model(uri, model, sizeof(model));
266
AddDeviceList(uri, model, &DeviceList);
271
DBG(6,"unsupported scantype=%d %s\n", ma.scantype, uri);
275
/* Ignore localOnly flag (used by saned) and always look for network all-in-one scan devices (defined by cups). */
276
cnt = GetCupsPrinters(&cups_printer);
277
for (i=0; i<cnt; i++)
279
hpmud_query_model(cups_printer[i], &ma);
282
hpmud_get_uri_model(cups_printer[i], model, sizeof(model));
283
AddDeviceList(cups_printer[i], model, &DeviceList);
288
DBG(6,"unsupported scantype=%d %s\n", ma.scantype, cups_printer[i]);
290
free(cups_printer[i]);
299
static void hpaioAddScanner( hpaioScanner_t scanner )
303
FirstScanner = scanner;
305
scanner->prev = LastScanner;
309
LastScanner->next = scanner;
311
LastScanner = scanner;
314
static hpaioScanner_t hpaioFindScanner( SANE_String_Const name )
316
hpaioScanner_t p = FirstScanner;
320
if( strcasecmp( name, p->saneDevice.name ) == 0 )
329
SANE_Status __attribute__ ((visibility ("hidden"))) hpaioScannerToSaneError( hpaioScanner_t hpaio )
333
if( hpaio->scannerType == SCANNER_TYPE_SCL )
337
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
338
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
339
SCL_INQ_CURRENT_ERROR,
344
if( retcode == SANE_STATUS_UNSUPPORTED )
346
retcode = SANE_STATUS_GOOD;
348
else if( retcode == SANE_STATUS_GOOD )
350
bug("hpaio: hpaioScannerToSaneError: sclError=%d.\n", sclError);
353
case SCL_ERROR_UNRECOGNIZED_COMMAND:
354
case SCL_ERROR_PARAMETER_ERROR:
355
retcode = SANE_STATUS_UNSUPPORTED;
358
case SCL_ERROR_NO_MEMORY:
359
retcode = SANE_STATUS_NO_MEM;
362
case SCL_ERROR_CANCELLED:
363
retcode = SANE_STATUS_CANCELLED;
366
case SCL_ERROR_PEN_DOOR_OPEN:
367
retcode = SANE_STATUS_COVER_OPEN;
370
case SCL_ERROR_SCANNER_HEAD_LOCKED:
371
case SCL_ERROR_ADF_PAPER_JAM:
372
case SCL_ERROR_HOME_POSITION_MISSING:
373
case SCL_ERROR_ORIGINAL_ON_GLASS:
374
retcode = SANE_STATUS_JAMMED;
377
case SCL_ERROR_PAPER_NOT_LOADED:
378
retcode = SANE_STATUS_NO_DOCS;
382
retcode = SANE_STATUS_IO_ERROR;
387
else /* if (hpaio->scannerType==SCANNER_TYPE_PML) */
391
//if( ptalPmlRequestGet( hpaio->pml.objUploadError, 0 ) == ERROR )
392
if( PmlRequestGet( hpaio->deviceid, hpaio->cmd_channelid, hpaio->pml.objUploadError ) == ERROR )
394
retcode = SANE_STATUS_GOOD;
396
else if( PmlGetIntegerValue( hpaio->pml.objUploadError,
398
&pmlError ) == ERROR )
400
bug("hpaio: hpaioScannerToSaneError: PmlGetIntegerValue failed, type=%d!\n", type);
401
retcode = SANE_STATUS_IO_ERROR;
405
bug("hpaio: hpaioScannerToSaneError: pmlError=%d.\n", pmlError);
409
case PML_UPLOAD_ERROR_SCANNER_JAM:
410
retcode = SANE_STATUS_JAMMED;
413
case PML_UPLOAD_ERROR_MLC_CHANNEL_CLOSED:
414
case PML_UPLOAD_ERROR_STOPPED_BY_HOST:
415
case PML_UPLOAD_ERROR_STOP_KEY_PRESSED:
416
retcode = SANE_STATUS_CANCELLED;
419
case PML_UPLOAD_ERROR_NO_DOC_IN_ADF:
420
case PML_UPLOAD_ERROR_DOC_LOADED:
421
retcode = SANE_STATUS_NO_DOCS;
424
case PML_UPLOAD_ERROR_COVER_OPEN:
425
retcode = SANE_STATUS_COVER_OPEN;
428
case PML_UPLOAD_ERROR_DEVICE_BUSY:
429
retcode = SANE_STATUS_DEVICE_BUSY;
433
retcode = SANE_STATUS_IO_ERROR;
443
SANE_Status __attribute__ ((visibility ("hidden"))) hpaioScannerToSaneStatus( hpaioScanner_t hpaio )
449
// if( hpaio->scannerType == SCANNER_TYPE_SCL )
453
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
454
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
455
SCL_INQ_ADF_FEED_STATUS,
460
if( retcode == SANE_STATUS_UNSUPPORTED )
462
retcode = SANE_STATUS_GOOD;
464
else if( retcode == SANE_STATUS_GOOD )
468
case SCL_ADF_FEED_STATUS_OK:
469
retcode = SANE_STATUS_GOOD;
472
case SCL_ADF_FEED_STATUS_BUSY:
473
/* retcode=SANE_STATUS_DEVICE_BUSY; */
474
retcode = SANE_STATUS_GOOD;
477
case SCL_ADF_FEED_STATUS_PAPER_JAM:
478
case SCL_ADF_FEED_STATUS_ORIGINAL_ON_GLASS:
479
retcode = SANE_STATUS_JAMMED;
482
case SCL_ADF_FEED_STATUS_PORTRAIT_FEED:
483
retcode = SANE_STATUS_UNSUPPORTED;
487
retcode = SANE_STATUS_IO_ERROR;
495
static int hpaioScannerIsUninterruptible( hpaioScanner_t hpaio,
501
pUploadState = &uploadState;
504
return ( hpaio->scannerType == SCANNER_TYPE_PML &&
505
hpaio->pml.scanDone &&
506
PmlRequestGet( hpaio->deviceid, hpaio->cmd_channelid,
507
hpaio->pml.objUploadState ) != ERROR &&
508
PmlGetIntegerValue( hpaio->pml.objUploadState, 0, pUploadState ) != ERROR &&
509
( *pUploadState == PML_UPLOAD_STATE_START ||
510
*pUploadState == PML_UPLOAD_STATE_ACTIVE ||
511
*pUploadState == PML_UPLOAD_STATE_NEWPAGE ) );
514
static SANE_Status hpaioResetScanner( hpaioScanner_t hpaio )
518
if( hpaio->scannerType == SCANNER_TYPE_SCL )
520
retcode = SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_RESET, 0 );
521
if( retcode != SANE_STATUS_GOOD )
525
sleep(1); /* delay for embeded jetdirect scl scanners (ie: PS 3300, PS C7280, PS C6100) */
527
else /* if (hpaio->scannerType==SCANNER_TYPE_PML) */
529
if( !hpaioScannerIsUninterruptible( hpaio, 0 ) )
531
PmlSetIntegerValue( hpaio->pml.objUploadState,
532
PML_TYPE_ENUMERATION,
533
PML_UPLOAD_STATE_IDLE );
535
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
536
hpaio->pml.objUploadState, 0, 0 ) == ERROR )
538
return SANE_STATUS_IO_ERROR;
542
/* Clear upload error for the sake of the LaserJet 1100A. */
543
PmlSetIntegerValue( hpaio->pml.objUploadError,
544
PML_TYPE_SIGNED_INTEGER,
547
PmlRequestSet( hpaio->deviceid, hpaio->cmd_channelid, hpaio->pml.objUploadError ); /* No retry. */
550
return SANE_STATUS_GOOD;
553
static PmlObject_t hpaioPmlAllocate( hpaioScanner_t hpaio )
555
int size = sizeof( struct PmlObject_s );
558
/* Malloc and zero object. */
559
obj = malloc( size );
561
memset( obj, 0, size );
563
/* Insert into linked list of PML objects for this device. */
564
if( !hpaio->firstPmlObject )
566
hpaio->firstPmlObject = obj;
568
obj->prev = hpaio->lastPmlObject;
570
if( hpaio->lastPmlObject )
572
hpaio->lastPmlObject->next = obj;
574
hpaio->lastPmlObject = obj;
579
static PmlObject_t hpaioPmlAllocateID( hpaioScanner_t hpaio, char * oid )
581
PmlObject_t obj = hpaioPmlAllocate( hpaio );
585
bug("hpaioPmlAllocateID: out of memory!\n");
588
PmlSetID( obj, oid );
593
static void hpaioPmlDeallocateObjects( hpaioScanner_t hpaio )
596
PmlObject_t current, next;
598
current = hpaio->firstPmlObject;
602
next = current->next;
610
static SANE_Status hpaioPmlAllocateObjects(hpaioScanner_t hpaio)
612
/* SNMP oids for PML scanners. */
613
hpaio->pml.objScannerStatus = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.2.1.0" );
614
hpaio->pml.objResolutionRange = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.2.3.0" );
615
hpaio->pml.objUploadTimeout = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.1.1.18.0" );
616
hpaio->pml.objContrast = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.1.0" );
617
hpaio->pml.objResolution = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.2.0" );
618
hpaio->pml.objPixelDataType = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.3.0" );
619
hpaio->pml.objCompression = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.4.0" );
620
hpaio->pml.objCompressionFactor = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.5.0" );
621
hpaio->pml.objUploadError = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.6.0" );
622
hpaio->pml.objUploadState = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.12.0" );
623
hpaio->pml.objAbcThresholds = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.14.0" );
624
hpaio->pml.objSharpeningCoefficient = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.15.0" );
625
hpaio->pml.objNeutralClipThresholds = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.31.0" );
626
hpaio->pml.objToneMap = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.32.0" );
627
hpaio->pml.objCopierReduction = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.5.1.4.0" );
628
hpaio->pml.objScanToken = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.1.1.25.0" );
629
hpaio->pml.objModularHardware = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.2.2.1.75.0" );
631
/* Some PML objects for SCL scanners. */
632
hpaio->scl.objSupportedFunctions = hpaioPmlAllocateID( hpaio, "1.3.6.1.4.1.11.2.3.9.4.2.1.1.2.67.0" );
634
return SANE_STATUS_GOOD;
637
static int hpaioConnClose( hpaioScanner_t hpaio )
639
if (hpaio->cmd_channelid > 0)
640
hpmud_close_channel(hpaio->deviceid, hpaio->cmd_channelid);
641
hpaio->cmd_channelid = -1;
642
if (hpaio->scan_channelid > 0)
643
hpmud_close_channel(hpaio->deviceid, hpaio->scan_channelid);
644
hpaio->scan_channelid = -1;
647
} // hpaioConnClose()
649
static SANE_Status hpaioConnOpen( hpaioScanner_t hpaio )
652
enum HPMUD_RESULT stat;
654
if (hpaio->scannerType==SCANNER_TYPE_SCL)
656
stat = hpmud_open_channel(hpaio->deviceid, "HP-SCAN", &hpaio->scan_channelid);
657
if(stat != HPMUD_R_OK)
659
bug("failed to open scan channel: %s %d\n", __FILE__, __LINE__);
660
retcode = SANE_STATUS_DEVICE_BUSY;
665
stat = hpmud_open_channel(hpaio->deviceid, "HP-MESSAGE", &hpaio->cmd_channelid);
666
if(stat != HPMUD_R_OK)
668
bug("failed to open pml channel: %s %d\n", __FILE__, __LINE__);
669
retcode = SANE_STATUS_IO_ERROR;
673
retcode = SANE_STATUS_GOOD;
676
if( retcode != SANE_STATUS_GOOD )
678
SendScanEvent( hpaio->deviceuri, EVENT_SCANNER_FAIL);
683
static SANE_Status hpaioConnPrepareScan( hpaioScanner_t hpaio )
688
/* ADF may already have channel(s) open. */
689
if (hpaio->cmd_channelid < 0)
691
retcode = hpaioConnOpen( hpaio );
693
if( retcode != SANE_STATUS_GOOD )
699
retcode = hpaioResetScanner( hpaio );
701
/* Reserve scanner and make sure it got reserved. */
702
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_SET_DEVICE_LOCK, 1 );
703
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
704
SCL_CMD_SET_DEVICE_LOCK_TIMEOUT,
705
SCL_DEVICE_LOCK_TIMEOUT );
709
char buffer[LEN_SCL_BUFFER];
711
struct timeval tv1, tv2;
712
gettimeofday( &tv1, 0 );
714
if( SclInquire( hpaio->deviceid, hpaio->scan_channelid,
715
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
719
LEN_SCL_BUFFER ) != SANE_STATUS_GOOD )
722
return SANE_STATUS_IO_ERROR;
725
gettimeofday( &tv2, 0 );
727
for( j = 0; j < len && buffer[j] == '0'; j++ ) ;
734
if( i >= SCL_PREPARE_SCAN_DEVICE_LOCK_MAX_RETRIES )
736
return SANE_STATUS_DEVICE_BUSY;
739
DBG(8, "hpaioConnPrepareScan: Waiting for device lock %s %d\n", __FILE__, __LINE__);
741
if( ( ( unsigned ) ( tv2.tv_sec - tv1.tv_sec ) ) <= SCL_PREPARE_SCAN_DEVICE_LOCK_DELAY )
743
sleep( SCL_PREPARE_SCAN_DEVICE_LOCK_DELAY );
747
SendScanEvent( hpaio->deviceuri, EVENT_START_SCAN_JOB);
749
return SANE_STATUS_GOOD;
752
static void hpaioConnEndScan( hpaioScanner_t hpaio )
754
hpaioResetScanner( hpaio );
755
hpaioConnClose( hpaio );
757
SendScanEvent( hpaio->deviceuri, EVENT_END_SCAN_JOB);
760
static SANE_Status SetResolutionListSCL(hpaioScanner_t hpaio)
762
int supported_res[] = {50, 75, 100, 150, 200, 300, 600, 1200, 2400, 4800, 9600};
763
int i, len = sizeof(supported_res)/sizeof(int);
765
if (hpaio->currentAdfMode == ADF_MODE_ADF || hpaio->currentAdfMode == ADF_MODE_AUTO)
767
hpaio->resolutionRange.min = hpaio->scl.minResAdf;
768
hpaio->resolutionRange.max = hpaio->scl.maxResAdf;
772
hpaio->resolutionRange.min = hpaio->scl.minRes;
773
hpaio->resolutionRange.max = hpaio->scl.maxRes;
776
DBG(6,"minRes=%d maxRes=%d minResAdf=%d maxResAdf=%d\n", hpaio->scl.minRes, hpaio->scl.maxRes, hpaio->scl.minResAdf, hpaio->scl.maxResAdf);
778
NumListClear( hpaio->resolutionList );
779
NumListClear( hpaio->lineartResolutionList );
780
for (i = 0; i < len; i++)
782
if (supported_res[i] >= hpaio->resolutionRange.min &&
783
supported_res[i] <= hpaio->resolutionRange.max)
785
NumListAdd (hpaio->resolutionList, supported_res[i]);
786
NumListAdd (hpaio->lineartResolutionList, supported_res[i]);
789
hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
791
return SANE_STATUS_GOOD;
794
static SANE_Status hpaioSetDefaultValue( hpaioScanner_t hpaio, int option )
798
case OPTION_SCAN_MODE:
799
if( hpaio->supportsScanMode[SCAN_MODE_COLOR] )
801
hpaio->currentScanMode = SCAN_MODE_COLOR;
803
else if( hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] )
805
hpaio->currentScanMode = SCAN_MODE_GRAYSCALE;
807
else /* if (hpaio->supportsScanMode[SCAN_MODE_LINEART]) */
809
hpaio->currentScanMode = SCAN_MODE_LINEART;
813
case OPTION_SCAN_RESOLUTION:
814
if( hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type == SANE_CONSTRAINT_WORD_LIST )
816
hpaio->currentResolution = NumListGetFirst( ( SANE_Int * )
817
hpaio->option[OPTION_SCAN_RESOLUTION].constraint.word_list );
821
hpaio->currentResolution = hpaio->resolutionRange.min;
825
case OPTION_CONTRAST:
826
hpaio->currentContrast = hpaio->defaultContrast;
829
case OPTION_COMPRESSION:
832
int supportedCompression = hpaio->supportsScanMode[hpaio->currentScanMode];
833
int defaultCompression = hpaio->defaultCompression[hpaio->currentScanMode];
835
if( supportedCompression & defaultCompression )
837
hpaio->currentCompression = defaultCompression;
839
else if( supportedCompression & COMPRESSION_JPEG )
841
hpaio->currentCompression = COMPRESSION_JPEG;
843
else if( supportedCompression & COMPRESSION_MH )
845
hpaio->currentCompression = COMPRESSION_MH;
847
else if( supportedCompression & COMPRESSION_MR )
849
hpaio->currentCompression = COMPRESSION_MR;
851
else if( supportedCompression & COMPRESSION_MMR )
853
hpaio->currentCompression = COMPRESSION_MMR;
857
hpaio->currentCompression = COMPRESSION_NONE;
862
case OPTION_JPEG_COMPRESSION_FACTOR:
863
hpaio->currentJpegCompressionFactor = hpaio->defaultJpegCompressionFactor;
866
case OPTION_BATCH_SCAN:
867
hpaio->currentBatchScan = SANE_FALSE;
870
case OPTION_ADF_MODE:
871
if( hpaio->supportedAdfModes & ADF_MODE_AUTO )
873
if( hpaio->scannerType == SCANNER_TYPE_PML &&
874
!hpaio->pml.flatbedCapability &&
875
hpaio->supportedAdfModes & ADF_MODE_ADF )
879
hpaio->currentAdfMode = ADF_MODE_AUTO;
881
else if( hpaio->supportedAdfModes & ADF_MODE_FLATBED )
883
hpaio->currentAdfMode = ADF_MODE_FLATBED;
885
else if( hpaio->supportedAdfModes & ADF_MODE_ADF )
888
hpaio->currentAdfMode = ADF_MODE_ADF;
892
hpaio->currentAdfMode = ADF_MODE_AUTO;
897
hpaio->currentDuplex = SANE_FALSE;
900
case OPTION_LENGTH_MEASUREMENT:
901
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_PADDED;
905
hpaio->currentTlx = hpaio->tlxRange.min;
909
hpaio->currentTly = hpaio->tlyRange.min;
913
hpaio->currentBrx = hpaio->brxRange.max;
917
hpaio->currentBry = hpaio->bryRange.max;
921
return SANE_STATUS_INVAL;
924
return SANE_STATUS_GOOD;
927
static int hpaioUpdateDescriptors( hpaioScanner_t hpaio, int option )
929
int initValues = ( option == OPTION_FIRST );
932
/* OPTION_SCAN_MODE: */
935
StrListClear( hpaio->scanModeList );
936
if( hpaio->supportsScanMode[SCAN_MODE_LINEART] )
938
StrListAdd( hpaio->scanModeList, SANE_VALUE_SCAN_MODE_LINEART );
940
if( hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] )
942
StrListAdd( hpaio->scanModeList, SANE_VALUE_SCAN_MODE_GRAY );
944
if( hpaio->supportsScanMode[SCAN_MODE_COLOR] )
946
StrListAdd( hpaio->scanModeList, SANE_VALUE_SCAN_MODE_COLOR );
948
hpaioSetDefaultValue( hpaio, OPTION_SCAN_MODE );
949
reload |= SANE_INFO_RELOAD_OPTIONS;
950
reload |= SANE_INFO_RELOAD_PARAMS;
952
else if( option == OPTION_SCAN_MODE )
954
reload |= SANE_INFO_RELOAD_PARAMS;
957
if (hpaio->scannerType == SCANNER_TYPE_SCL)
958
SetResolutionListSCL(hpaio);
959
/* OPTION_SCAN_RESOLUTION: */
960
if( hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type ==
961
SANE_CONSTRAINT_WORD_LIST )
963
SANE_Int ** pList = ( SANE_Int ** ) &hpaio->option[OPTION_SCAN_RESOLUTION].constraint.word_list;
965
if( hpaio->currentScanMode == SCAN_MODE_LINEART )
967
if( *pList != hpaio->lineartResolutionList )
969
*pList = hpaio->lineartResolutionList;
970
reload |= SANE_INFO_RELOAD_OPTIONS;
975
if( *pList != hpaio->resolutionList )
977
*pList = hpaio->resolutionList;
978
reload |= SANE_INFO_RELOAD_OPTIONS;
981
if( initValues || !NumListIsInList( *pList,
982
hpaio->currentResolution ) )
984
hpaioSetDefaultValue( hpaio, OPTION_SCAN_RESOLUTION );
985
reload |= SANE_INFO_RELOAD_OPTIONS;
986
reload |= SANE_INFO_RELOAD_PARAMS;
992
hpaio->currentResolution<hpaio->resolutionRange.min ||
993
hpaio->currentResolution>hpaio->resolutionRange.max )
995
hpaioSetDefaultValue( hpaio, OPTION_SCAN_RESOLUTION );
996
reload |= SANE_INFO_RELOAD_OPTIONS;
997
reload |= SANE_INFO_RELOAD_PARAMS;
1000
if( option == OPTION_SCAN_RESOLUTION )
1002
reload |= SANE_INFO_RELOAD_PARAMS;
1005
/* OPTION_CONTRAST: */
1008
hpaioSetDefaultValue( hpaio, OPTION_CONTRAST );
1011
/* OPTION_COMPRESSION: */
1014
int supportedCompression = hpaio->supportsScanMode[hpaio->currentScanMode];
1016
!( supportedCompression & hpaio->currentCompression ) ||
1017
( ( ( supportedCompression & COMPRESSION_NONE ) != 0 ) !=
1018
( StrListIsInList( hpaio->compressionList,
1019
STR_COMPRESSION_NONE ) != 0 ) ) ||
1020
( ( ( supportedCompression & COMPRESSION_MH ) != 0 ) !=
1021
( StrListIsInList( hpaio->compressionList,
1022
STR_COMPRESSION_MH ) != 0 ) ) ||
1023
( ( ( supportedCompression & COMPRESSION_MR ) != 0 ) !=
1024
( StrListIsInList( hpaio->compressionList,
1025
STR_COMPRESSION_MR ) != 0 ) ) ||
1026
( ( ( supportedCompression & COMPRESSION_MMR ) != 0 ) !=
1027
( StrListIsInList( hpaio->compressionList,
1028
STR_COMPRESSION_MMR ) != 0 ) ) ||
1029
( ( ( supportedCompression & COMPRESSION_JPEG ) != 0 ) !=
1030
( StrListIsInList( hpaio->compressionList,
1031
STR_COMPRESSION_JPEG ) != 0 ) ) )
1033
StrListClear( hpaio->compressionList );
1034
if( supportedCompression & COMPRESSION_NONE )
1036
StrListAdd( hpaio->compressionList, STR_COMPRESSION_NONE );
1038
if( supportedCompression & COMPRESSION_MH )
1040
StrListAdd( hpaio->compressionList, STR_COMPRESSION_MH );
1042
if( supportedCompression & COMPRESSION_MR )
1044
StrListAdd( hpaio->compressionList, STR_COMPRESSION_MR );
1046
if( supportedCompression & COMPRESSION_MMR )
1048
StrListAdd( hpaio->compressionList, STR_COMPRESSION_MMR );
1050
if( supportedCompression & COMPRESSION_JPEG )
1052
StrListAdd( hpaio->compressionList, STR_COMPRESSION_JPEG );
1054
hpaioSetDefaultValue( hpaio, OPTION_COMPRESSION );
1055
reload |= SANE_INFO_RELOAD_OPTIONS;
1059
/* OPTION_JPEG_COMPRESSION_FACTOR: */
1061
( ( hpaio->currentCompression == COMPRESSION_JPEG ) !=
1062
( ( hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].cap & SANE_CAP_INACTIVE ) == 0 ) ) )
1064
if( hpaio->currentCompression == COMPRESSION_JPEG )
1066
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].cap &= ~SANE_CAP_INACTIVE;
1070
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].cap |= SANE_CAP_INACTIVE;
1072
hpaioSetDefaultValue( hpaio, OPTION_JPEG_COMPRESSION_FACTOR );
1073
reload |= SANE_INFO_RELOAD_OPTIONS;
1076
/* OPTION_BATCH_SCAN: */
1079
hpaioSetDefaultValue( hpaio, OPTION_BATCH_SCAN );
1080
if( hpaio->preDenali )
1082
hpaio->option[OPTION_BATCH_SCAN].cap |= SANE_CAP_INACTIVE;
1084
reload |= SANE_INFO_RELOAD_OPTIONS;
1086
if( !hpaio->currentBatchScan )
1088
hpaio->noDocsConditionPending = 0;
1091
/* OPTION_ADF_MODE: */
1094
StrListClear( hpaio->adfModeList );
1095
if( hpaio->supportedAdfModes & ADF_MODE_AUTO )
1097
StrListAdd( hpaio->adfModeList, STR_ADF_MODE_AUTO );
1099
if( hpaio->supportedAdfModes & ADF_MODE_FLATBED )
1101
StrListAdd( hpaio->adfModeList, STR_ADF_MODE_FLATBED );
1103
if( hpaio->supportedAdfModes & ADF_MODE_ADF )
1105
StrListAdd( hpaio->adfModeList, STR_ADF_MODE_ADF );
1107
hpaioSetDefaultValue( hpaio, OPTION_ADF_MODE );
1108
reload |= SANE_INFO_RELOAD_OPTIONS;
1112
/* OPTION_DUPLEX: */
1114
( ( hpaio->supportsDuplex &&
1115
hpaio->currentAdfMode != ADF_MODE_FLATBED ) !=
1116
( ( hpaio->option[OPTION_DUPLEX].cap & SANE_CAP_INACTIVE ) == 0 ) ) )
1118
if( hpaio->supportsDuplex &&
1119
hpaio->currentAdfMode != ADF_MODE_FLATBED )
1121
hpaio->option[OPTION_DUPLEX].cap &= ~SANE_CAP_INACTIVE;
1125
hpaio->option[OPTION_DUPLEX].cap |= SANE_CAP_INACTIVE;
1127
hpaioSetDefaultValue( hpaio, OPTION_DUPLEX );
1128
reload |= SANE_INFO_RELOAD_OPTIONS;
1132
/* OPTION_LENGTH_MEASUREMENT: */
1135
hpaioSetDefaultValue( hpaio, OPTION_LENGTH_MEASUREMENT );
1136
StrListClear( hpaio->lengthMeasurementList );
1137
StrListAdd( hpaio->lengthMeasurementList,
1138
STR_LENGTH_MEASUREMENT_UNKNOWN );
1139
if( hpaio->scannerType == SCANNER_TYPE_PML )
1141
StrListAdd( hpaio->lengthMeasurementList,
1142
STR_LENGTH_MEASUREMENT_UNLIMITED );
1144
StrListAdd( hpaio->lengthMeasurementList,
1145
STR_LENGTH_MEASUREMENT_APPROXIMATE );
1146
StrListAdd( hpaio->lengthMeasurementList,
1147
STR_LENGTH_MEASUREMENT_PADDED );
1148
/* TODO: hpaioStrListAdd(hpaio->lengthMeasurementList,
1149
STR_LENGTH_MEASUREMENT_EXACT); */
1152
/* OPTION_TL_X, OPTION_TL_Y, OPTION_BR_X, OPTION_BR_Y: */
1155
hpaioSetDefaultValue( hpaio, OPTION_TL_X );
1156
hpaioSetDefaultValue( hpaio, OPTION_TL_Y );
1157
hpaioSetDefaultValue( hpaio, OPTION_BR_X );
1158
hpaioSetDefaultValue( hpaio, OPTION_BR_Y );
1159
reload |= SANE_INFO_RELOAD_OPTIONS;
1160
goto processGeometry;
1162
else if( option == OPTION_TL_X ||
1163
option == OPTION_TL_Y ||
1164
option == OPTION_BR_X ||
1165
option == OPTION_BR_Y )
1167
processGeometry : hpaio->effectiveTlx = hpaio->currentTlx;
1168
hpaio->effectiveBrx = hpaio->currentBrx;
1169
FIX_GEOMETRY( hpaio->effectiveTlx,
1170
hpaio->effectiveBrx,
1171
hpaio->brxRange.min,
1172
hpaio->brxRange.max );
1173
hpaio->effectiveTly = hpaio->currentTly;
1174
hpaio->effectiveBry = hpaio->currentBry;
1175
FIX_GEOMETRY( hpaio->effectiveTly,
1176
hpaio->effectiveBry,
1177
hpaio->bryRange.min,
1178
hpaio->bryRange.max );
1179
reload |= SANE_INFO_RELOAD_PARAMS;
1181
if( ( hpaio->currentLengthMeasurement != LENGTH_MEASUREMENT_UNLIMITED ) !=
1182
( ( hpaio->option[OPTION_BR_Y].cap & SANE_CAP_INACTIVE ) == 0 ) )
1184
if( hpaio->currentLengthMeasurement == LENGTH_MEASUREMENT_UNLIMITED )
1186
hpaio->option[OPTION_BR_Y].cap |= SANE_CAP_INACTIVE;
1190
hpaio->option[OPTION_BR_Y].cap &= ~SANE_CAP_INACTIVE;
1192
reload |= SANE_INFO_RELOAD_OPTIONS;
1195
/* Pre-scan parameters: */
1196
if( reload & SANE_INFO_RELOAD_PARAMS )
1198
switch( hpaio->currentScanMode )
1200
case SCAN_MODE_LINEART:
1201
hpaio->prescanParameters.format = SANE_FRAME_GRAY;
1202
hpaio->prescanParameters.depth = 1;
1205
case SCAN_MODE_GRAYSCALE:
1206
hpaio->prescanParameters.format = SANE_FRAME_GRAY;
1207
hpaio->prescanParameters.depth = 8;
1210
case SCAN_MODE_COLOR:
1212
hpaio->prescanParameters.format = SANE_FRAME_RGB;
1213
hpaio->prescanParameters.depth = 8;
1216
hpaio->prescanParameters.last_frame = SANE_TRUE;
1219
hpaio->prescanParameters.lines = MILLIMETERS_TO_PIXELS( hpaio->effectiveBry - hpaio->effectiveTly,
1220
hpaio->currentResolution );
1222
hpaio->prescanParameters.pixels_per_line = MILLIMETERS_TO_PIXELS( hpaio->effectiveBrx - hpaio->effectiveTlx,
1223
hpaio->currentResolution );
1225
hpaio->prescanParameters.bytes_per_line = BYTES_PER_LINE( hpaio->prescanParameters.pixels_per_line,
1226
hpaio->prescanParameters.depth * ( hpaio->prescanParameters.format ==
1235
static void hpaioSetupOptions( hpaioScanner_t hpaio )
1237
hpaio->option[OPTION_NUM_OPTIONS].name = SANE_NAME_NUM_OPTIONS;
1238
hpaio->option[OPTION_NUM_OPTIONS].title = SANE_TITLE_NUM_OPTIONS;
1239
hpaio->option[OPTION_NUM_OPTIONS].desc = SANE_DESC_NUM_OPTIONS;
1240
hpaio->option[OPTION_NUM_OPTIONS].type = SANE_TYPE_INT;
1241
hpaio->option[OPTION_NUM_OPTIONS].unit = SANE_UNIT_NONE;
1242
hpaio->option[OPTION_NUM_OPTIONS].size = sizeof( SANE_Int );
1243
hpaio->option[OPTION_NUM_OPTIONS].cap = SANE_CAP_SOFT_DETECT;
1244
hpaio->option[OPTION_NUM_OPTIONS].constraint_type = SANE_CONSTRAINT_NONE;
1246
hpaio->option[GROUP_SCAN_MODE].title = SANE_TITLE_SCAN_MODE;
1247
hpaio->option[GROUP_SCAN_MODE].type = SANE_TYPE_GROUP;
1249
hpaio->option[OPTION_SCAN_MODE].name = SANE_NAME_SCAN_MODE;
1250
hpaio->option[OPTION_SCAN_MODE].title = SANE_TITLE_SCAN_MODE;
1251
hpaio->option[OPTION_SCAN_MODE].desc = SANE_DESC_SCAN_MODE;
1252
hpaio->option[OPTION_SCAN_MODE].type = SANE_TYPE_STRING;
1253
hpaio->option[OPTION_SCAN_MODE].unit = SANE_UNIT_NONE;
1254
hpaio->option[OPTION_SCAN_MODE].size = LEN_STRING_OPTION_VALUE;
1255
hpaio->option[OPTION_SCAN_MODE].cap = SANE_CAP_SOFT_SELECT |
1256
SANE_CAP_SOFT_DETECT;
1257
hpaio->option[OPTION_SCAN_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1258
hpaio->option[OPTION_SCAN_MODE].constraint.string_list = hpaio->scanModeList;
1260
hpaio->option[OPTION_SCAN_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1261
hpaio->option[OPTION_SCAN_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1262
hpaio->option[OPTION_SCAN_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1263
hpaio->option[OPTION_SCAN_RESOLUTION].type = SANE_TYPE_INT;
1264
hpaio->option[OPTION_SCAN_RESOLUTION].unit = SANE_UNIT_DPI;
1265
hpaio->option[OPTION_SCAN_RESOLUTION].size = sizeof( SANE_Int );
1266
hpaio->option[OPTION_SCAN_RESOLUTION].cap = SANE_CAP_SOFT_SELECT |
1267
SANE_CAP_SOFT_DETECT;
1268
hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1269
hpaio->option[OPTION_SCAN_RESOLUTION].constraint.range = &hpaio->resolutionRange;
1270
hpaio->resolutionRange.quant = 0;
1272
hpaio->option[GROUP_ADVANCED].title = STR_TITLE_ADVANCED;
1273
hpaio->option[GROUP_ADVANCED].type = SANE_TYPE_GROUP;
1274
hpaio->option[GROUP_ADVANCED].cap = SANE_CAP_ADVANCED;
1276
hpaio->option[OPTION_CONTRAST].name = SANE_NAME_CONTRAST;
1277
hpaio->option[OPTION_CONTRAST].title = SANE_TITLE_CONTRAST;
1278
hpaio->option[OPTION_CONTRAST].desc = SANE_DESC_CONTRAST;
1279
hpaio->option[OPTION_CONTRAST].type = SANE_TYPE_INT;
1280
hpaio->option[OPTION_CONTRAST].unit = SANE_UNIT_NONE;
1281
hpaio->option[OPTION_CONTRAST].size = sizeof( SANE_Int );
1282
hpaio->option[OPTION_CONTRAST].cap = SANE_CAP_SOFT_SELECT |
1283
SANE_CAP_SOFT_DETECT |
1286
hpaio->option[OPTION_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
1287
hpaio->option[OPTION_CONTRAST].constraint.range = &hpaio->contrastRange;
1288
hpaio->contrastRange.min = PML_CONTRAST_MIN;
1289
hpaio->contrastRange.max = PML_CONTRAST_MAX;
1290
hpaio->contrastRange.quant = 0;
1291
hpaio->defaultContrast = PML_CONTRAST_DEFAULT;
1293
hpaio->option[OPTION_COMPRESSION].name = STR_NAME_COMPRESSION;
1294
hpaio->option[OPTION_COMPRESSION].title = STR_TITLE_COMPRESSION;
1295
hpaio->option[OPTION_COMPRESSION].desc = STR_DESC_COMPRESSION;
1296
hpaio->option[OPTION_COMPRESSION].type = SANE_TYPE_STRING;
1297
hpaio->option[OPTION_COMPRESSION].unit = SANE_UNIT_NONE;
1298
hpaio->option[OPTION_COMPRESSION].size = LEN_STRING_OPTION_VALUE;
1299
hpaio->option[OPTION_COMPRESSION].cap = SANE_CAP_SOFT_SELECT |
1300
SANE_CAP_SOFT_DETECT |
1302
hpaio->option[OPTION_COMPRESSION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1303
hpaio->option[OPTION_COMPRESSION].constraint.string_list = hpaio->compressionList;
1305
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].name = STR_NAME_JPEG_QUALITY;
1306
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].title = STR_TITLE_JPEG_QUALITY;
1307
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].desc = STR_DESC_JPEG_QUALITY;
1308
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].type = SANE_TYPE_INT;
1309
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].unit = SANE_UNIT_NONE;
1310
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].size = sizeof( SANE_Int );
1311
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].cap = SANE_CAP_SOFT_SELECT |
1312
SANE_CAP_SOFT_DETECT |
1314
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1315
hpaio->option[OPTION_JPEG_COMPRESSION_FACTOR].constraint.range = &hpaio->jpegCompressionFactorRange;
1316
hpaio->jpegCompressionFactorRange.min = MIN_JPEG_COMPRESSION_FACTOR;
1317
hpaio->jpegCompressionFactorRange.max = MAX_JPEG_COMPRESSION_FACTOR;
1318
hpaio->jpegCompressionFactorRange.quant = 0;
1319
hpaio->defaultJpegCompressionFactor = SAFER_JPEG_COMPRESSION_FACTOR;
1321
hpaio->option[OPTION_BATCH_SCAN].name = STR_NAME_BATCH_SCAN;
1322
hpaio->option[OPTION_BATCH_SCAN].title = STR_TITLE_BATCH_SCAN;
1323
hpaio->option[OPTION_BATCH_SCAN].desc = STR_DESC_BATCH_SCAN;
1324
hpaio->option[OPTION_BATCH_SCAN].type = SANE_TYPE_BOOL;
1325
hpaio->option[OPTION_BATCH_SCAN].unit = SANE_UNIT_NONE;
1326
hpaio->option[OPTION_BATCH_SCAN].size = sizeof( SANE_Bool );
1327
hpaio->option[OPTION_BATCH_SCAN].cap = SANE_CAP_SOFT_SELECT |
1328
SANE_CAP_SOFT_DETECT |
1330
hpaio->option[OPTION_BATCH_SCAN].constraint_type = SANE_CONSTRAINT_NONE;
1332
hpaio->option[OPTION_ADF_MODE].name = SANE_NAME_SCAN_SOURCE; // xsane expects this.
1333
hpaio->option[OPTION_ADF_MODE].title = SANE_TITLE_SCAN_SOURCE;
1334
hpaio->option[OPTION_ADF_MODE].desc = SANE_DESC_SCAN_SOURCE;
1335
hpaio->option[OPTION_ADF_MODE].type = SANE_TYPE_STRING;
1336
hpaio->option[OPTION_ADF_MODE].unit = SANE_UNIT_NONE;
1337
hpaio->option[OPTION_ADF_MODE].size = LEN_STRING_OPTION_VALUE;
1338
hpaio->option[OPTION_ADF_MODE].cap = SANE_CAP_SOFT_SELECT |
1339
SANE_CAP_SOFT_DETECT |
1341
hpaio->option[OPTION_ADF_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1342
hpaio->option[OPTION_ADF_MODE].constraint.string_list = hpaio->adfModeList;
1344
// Duplex scanning is supported
1345
if (hpaio->supportsDuplex == 1)
1347
hpaio->option[OPTION_DUPLEX].name = STR_NAME_DUPLEX;
1348
hpaio->option[OPTION_DUPLEX].title = STR_TITLE_DUPLEX;
1349
hpaio->option[OPTION_DUPLEX].desc = STR_DESC_DUPLEX;
1350
hpaio->option[OPTION_DUPLEX].type = SANE_TYPE_BOOL;
1351
hpaio->option[OPTION_DUPLEX].unit = SANE_UNIT_NONE;
1352
hpaio->option[OPTION_DUPLEX].size = sizeof( SANE_Bool );
1353
hpaio->option[OPTION_DUPLEX].cap = SANE_CAP_SOFT_SELECT |
1354
SANE_CAP_SOFT_DETECT |
1356
hpaio->option[OPTION_DUPLEX].constraint_type = SANE_CONSTRAINT_NONE;
1358
hpaio->option[GROUP_GEOMETRY].title = STR_TITLE_GEOMETRY;
1359
hpaio->option[GROUP_GEOMETRY].type = SANE_TYPE_GROUP;
1360
hpaio->option[GROUP_GEOMETRY].cap = SANE_CAP_ADVANCED;
1362
hpaio->option[OPTION_LENGTH_MEASUREMENT].name = STR_NAME_LENGTH_MEASUREMENT;
1363
hpaio->option[OPTION_LENGTH_MEASUREMENT].title = STR_TITLE_LENGTH_MEASUREMENT;
1364
hpaio->option[OPTION_LENGTH_MEASUREMENT].desc = STR_DESC_LENGTH_MEASUREMENT;
1365
hpaio->option[OPTION_LENGTH_MEASUREMENT].type = SANE_TYPE_STRING;
1366
hpaio->option[OPTION_LENGTH_MEASUREMENT].unit = SANE_UNIT_NONE;
1367
hpaio->option[OPTION_LENGTH_MEASUREMENT].size = LEN_STRING_OPTION_VALUE;
1368
hpaio->option[OPTION_LENGTH_MEASUREMENT].cap = SANE_CAP_SOFT_SELECT |
1369
SANE_CAP_SOFT_DETECT |
1371
hpaio->option[OPTION_LENGTH_MEASUREMENT].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1372
hpaio->option[OPTION_LENGTH_MEASUREMENT].constraint.string_list = hpaio->lengthMeasurementList;
1374
hpaio->option[OPTION_TL_X].name = SANE_NAME_SCAN_TL_X;
1375
hpaio->option[OPTION_TL_X].title = SANE_TITLE_SCAN_TL_X;
1376
hpaio->option[OPTION_TL_X].desc = SANE_DESC_SCAN_TL_X;
1377
hpaio->option[OPTION_TL_X].type = GEOMETRY_OPTION_TYPE;
1378
hpaio->option[OPTION_TL_X].unit = SANE_UNIT_MM;
1379
hpaio->option[OPTION_TL_X].size = sizeof( SANE_Int );
1380
hpaio->option[OPTION_TL_X].cap = SANE_CAP_SOFT_SELECT |
1381
SANE_CAP_SOFT_DETECT;
1382
hpaio->option[OPTION_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1383
hpaio->option[OPTION_TL_X].constraint.range = &hpaio->tlxRange;
1384
hpaio->tlxRange.min = 0;
1385
hpaio->tlxRange.quant = 0;
1387
hpaio->option[OPTION_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1388
hpaio->option[OPTION_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1389
hpaio->option[OPTION_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1390
hpaio->option[OPTION_TL_Y].type = GEOMETRY_OPTION_TYPE;
1391
hpaio->option[OPTION_TL_Y].unit = SANE_UNIT_MM;
1392
hpaio->option[OPTION_TL_Y].size = sizeof( SANE_Int );
1393
hpaio->option[OPTION_TL_Y].cap = SANE_CAP_SOFT_SELECT |
1394
SANE_CAP_SOFT_DETECT;
1395
hpaio->option[OPTION_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1396
hpaio->option[OPTION_TL_Y].constraint.range = &hpaio->tlyRange;
1397
hpaio->tlyRange.min = 0;
1398
hpaio->tlyRange.quant = 0;
1400
hpaio->option[OPTION_BR_X].name = SANE_NAME_SCAN_BR_X;
1401
hpaio->option[OPTION_BR_X].title = SANE_TITLE_SCAN_BR_X;
1402
hpaio->option[OPTION_BR_X].desc = SANE_DESC_SCAN_BR_X;
1403
hpaio->option[OPTION_BR_X].type = GEOMETRY_OPTION_TYPE;
1404
hpaio->option[OPTION_BR_X].unit = SANE_UNIT_MM;
1405
hpaio->option[OPTION_BR_X].size = sizeof( SANE_Int );
1406
hpaio->option[OPTION_BR_X].cap = SANE_CAP_SOFT_SELECT |
1407
SANE_CAP_SOFT_DETECT;
1408
hpaio->option[OPTION_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1409
hpaio->option[OPTION_BR_X].constraint.range = &hpaio->brxRange;
1410
hpaio->brxRange.min = 0;
1411
hpaio->brxRange.quant = 0;
1413
hpaio->option[OPTION_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1414
hpaio->option[OPTION_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1415
hpaio->option[OPTION_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1416
hpaio->option[OPTION_BR_Y].type = GEOMETRY_OPTION_TYPE;
1417
hpaio->option[OPTION_BR_Y].unit = SANE_UNIT_MM;
1418
hpaio->option[OPTION_BR_Y].size = sizeof( SANE_Int );
1419
hpaio->option[OPTION_BR_Y].cap = SANE_CAP_SOFT_SELECT |
1420
SANE_CAP_SOFT_DETECT;
1421
hpaio->option[OPTION_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1422
hpaio->option[OPTION_BR_Y].constraint.range = &hpaio->bryRange;
1423
hpaio->bryRange.min = 0;
1424
hpaio->bryRange.quant = 0;
1427
static int hpaioSclSendCommandCheckError( hpaioScanner_t hpaio, int cmd, int param )
1429
SANE_Status retcode;
1431
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_CLEAR_ERROR_STACK, 0 );
1433
retcode = SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, cmd, param );
1435
if( retcode == SANE_STATUS_GOOD &&
1436
( ( cmd != SCL_CMD_CHANGE_DOCUMENT && cmd != SCL_CMD_UNLOAD_DOCUMENT ) ||
1437
hpaio->beforeScan ) )
1439
retcode = hpaioScannerToSaneError( hpaio );
1445
static SANE_Status hpaioProgramOptions( hpaioScanner_t hpaio )
1449
hpaio->effectiveScanMode = hpaio->currentScanMode;
1450
hpaio->effectiveResolution = hpaio->currentResolution;
1452
// if( hpaio->scannerType == SCANNER_TYPE_SCL )
1454
/* Set output data type and width. */
1455
switch( hpaio->currentScanMode )
1457
case SCAN_MODE_LINEART:
1458
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1459
SCL_CMD_SET_OUTPUT_DATA_TYPE,
1460
SCL_DATA_TYPE_LINEART );
1461
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1462
SCL_CMD_SET_DATA_WIDTH,
1463
SCL_DATA_WIDTH_LINEART );
1466
case SCAN_MODE_GRAYSCALE:
1467
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1468
SCL_CMD_SET_OUTPUT_DATA_TYPE,
1469
SCL_DATA_TYPE_GRAYSCALE );
1470
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1471
SCL_CMD_SET_DATA_WIDTH,
1472
SCL_DATA_WIDTH_GRAYSCALE );
1475
case SCAN_MODE_COLOR:
1477
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1478
SCL_CMD_SET_OUTPUT_DATA_TYPE,
1479
SCL_DATA_TYPE_COLOR );
1480
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1481
SCL_CMD_SET_DATA_WIDTH,
1482
SCL_DATA_WIDTH_COLOR );
1487
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1489
hpaio->mfpdtf ? SCL_MFPDTF_ON : SCL_MFPDTF_OFF );
1492
/* Set compression. */
1493
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1494
SCL_CMD_SET_COMPRESSION,
1495
( hpaio->currentCompression ==
1496
COMPRESSION_JPEG ? SCL_COMPRESSION_JPEG : SCL_COMPRESSION_NONE ) );
1498
/* Set JPEG compression factor. */
1499
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1500
SCL_CMD_SET_JPEG_COMPRESSION_FACTOR,
1501
hpaio->currentJpegCompressionFactor );
1503
/* Set X and Y resolution. */
1504
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1505
SCL_CMD_SET_X_RESOLUTION,
1506
hpaio->currentResolution );
1508
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1509
SCL_CMD_SET_Y_RESOLUTION,
1510
hpaio->currentResolution );
1512
/* Set X and Y position and extent. */
1513
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1514
SCL_CMD_SET_X_POSITION,
1515
MILLIMETERS_TO_DECIPIXELS( hpaio->effectiveTlx ) );
1517
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1518
SCL_CMD_SET_Y_POSITION,
1519
MILLIMETERS_TO_DECIPIXELS( hpaio->effectiveTly ) );
1521
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1522
SCL_CMD_SET_X_EXTENT,
1523
MILLIMETERS_TO_DECIPIXELS( hpaio->effectiveBrx -
1524
hpaio->effectiveTlx ) );
1526
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1527
SCL_CMD_SET_Y_EXTENT,
1528
MILLIMETERS_TO_DECIPIXELS( hpaio->effectiveBry -
1529
hpaio->effectiveTly ) );
1531
/* Download color map to OfficeJet Pro 11xx. */
1532
if( hpaio->scl.compat & ( SCL_COMPAT_1150 | SCL_COMPAT_1170 ) )
1534
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1535
SCL_CMD_SET_DOWNLOAD_TYPE,
1536
SCL_DOWNLOAD_TYPE_COLORMAP );
1538
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1539
SCL_CMD_DOWNLOAD_BINARY_DATA,
1540
sizeof( hp11xxSeriesColorMap ) );
1542
hpmud_write_channel(hpaio->deviceid, hpaio->scan_channelid, hp11xxSeriesColorMap, sizeof(hp11xxSeriesColorMap),
1543
EXCEPTION_TIMEOUT, &bytes_wrote);
1546
/* For OfficeJet R and PSC 500 series, set CCD resolution to 600
1548
if( hpaio->scl.compat & SCL_COMPAT_R_SERIES &&
1549
hpaio->currentScanMode == SCAN_MODE_LINEART )
1551
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid,
1552
SCL_CMD_SET_CCD_RESOLUTION, 600 );
1555
return SANE_STATUS_GOOD;
1558
static SANE_Status hpaioAdvanceDocument(hpaioScanner_t hpaio)
1560
SANE_Status retcode = SANE_STATUS_GOOD;
1561
int documentLoaded = 0;
1563
DBG(8, "hpaioAdvanceDocument: papersource=%s batch=%d %s %d\n",
1564
hpaio->currentAdfMode==ADF_MODE_FLATBED ? "FLATBED" : hpaio->currentAdfMode==ADF_MODE_AUTO ? "AUTO" : "ADF",
1565
hpaio->currentBatchScan, __FILE__, __LINE__);
1567
if (hpaio->currentAdfMode == ADF_MODE_FLATBED)
1568
goto bugout; /* nothing to do */
1570
/* If there is an ADF see if paper is loaded. */
1571
if (hpaio->supportedAdfModes & ADF_MODE_ADF)
1573
retcode = SclInquire(hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_INQUIRE_DEVICE_PARAMETER,
1574
SCL_INQ_ADF_DOCUMENT_LOADED, &documentLoaded, 0, 0);
1576
if (retcode != SANE_STATUS_GOOD)
1580
/* If in Batch mode, by definition we are in ADF mode. */
1581
if (hpaio->currentBatchScan && !documentLoaded)
1583
retcode = SANE_STATUS_NO_DOCS;
1584
goto bugout; /* no paper loaded */
1587
/* If in Auto mode and no paper loaded use flatbed. */
1588
if (hpaio->currentAdfMode == ADF_MODE_AUTO && !documentLoaded)
1589
goto bugout; /* no paper loaded, use flatbed */
1591
/* Assume ADF mode. */
1592
if (documentLoaded || (hpaio->currentSideNumber == 2) )
1594
if (hpaio->currentDuplex)
1596
/* Duplex change document. */
1597
if(hpaio->currentSideNumber == 2)
1598
hpaio->currentSideNumber = 1;
1600
hpaio->currentSideNumber = 2;
1602
retcode=hpaioSclSendCommandCheckError(hpaio, SCL_CMD_CHANGE_DOCUMENT, SCL_CHANGE_DOC_DUPLEX);
1606
/* Simplex change document. */
1607
retcode = hpaioSclSendCommandCheckError(hpaio, SCL_CMD_CHANGE_DOCUMENT, SCL_CHANGE_DOC_SIMPLEX);
1609
hpaio->currentPageNumber++;
1612
retcode = SANE_STATUS_NO_DOCS;
1616
DBG(8, "hpaioAdvanceDocument returns %d ADF-loaded=%d: %s %d\n", retcode, documentLoaded, __FILE__, __LINE__);
1621
/******************************************************* SANE API *******************************************************/
1623
extern SANE_Status sane_hpaio_init(SANE_Int * pVersionCode, SANE_Auth_Callback authorize)
1630
DBG(8, "sane_hpaio_init(): %s %d\n", __FILE__, __LINE__);
1634
*pVersionCode = SANE_VERSION_CODE( 1, 0, 0 );
1636
stat = SANE_STATUS_GOOD;
1639
} /* sane_hpaio_init() */
1641
extern void sane_hpaio_exit(void)
1643
DBG(8, "sane_hpaio_exit(): %s %d\n", __FILE__, __LINE__);
1644
ResetDeviceList(&DeviceList);
1647
extern SANE_Status sane_hpaio_get_devices(const SANE_Device ***deviceList, SANE_Bool localOnly)
1649
DBG(8, "sane_hpaio_get_devices(local=%d): %s %d\n", localOnly, __FILE__, __LINE__);
1650
ResetDeviceList(&DeviceList);
1651
DevDiscovery(localOnly);
1652
*deviceList = (const SANE_Device **)DeviceList;
1653
return SANE_STATUS_GOOD;
1656
extern SANE_Status sane_hpaio_open(SANE_String_Const devicename, SANE_Handle * pHandle)
1658
struct hpmud_model_attributes ma;
1659
SANE_Status retcode = SANE_STATUS_INVAL;
1660
hpaioScanner_t hpaio = 0;
1662
char deviceIDString[LEN_DEVICE_ID_STRING];
1664
int forceJpegForGrayAndColor = 0;
1665
int force300dpiForLineart = 0;
1666
int force300dpiForGrayscale = 0;
1667
int supportsMfpdtf = 1;
1668
int modularHardware = 0;
1670
enum HPMUD_RESULT stat;
1672
/* Get device attributes and determine what backend to call. */
1673
snprintf(devname, sizeof(devname)-1, "hp:%s", devicename); /* prepend "hp:" */
1674
hpmud_query_model(devname, &ma);
1675
DBG(8, "sane_hpaio_open(%s): %s %d scan_type=%d scansrc=%d\n", devicename, __FILE__, __LINE__, ma.scantype, ma.scansrc);
1677
if ((ma.scantype == HPMUD_SCANTYPE_MARVELL) || (ma.scantype == HPMUD_SCANTYPE_MARVELL2))
1678
return marvell_open(devicename, pHandle);
1679
if (ma.scantype == HPMUD_SCANTYPE_SOAP)
1680
return soap_open(devicename, pHandle);
1681
if (ma.scantype == HPMUD_SCANTYPE_SOAPHT)
1682
return soapht_open(devicename, pHandle);
1683
if (ma.scantype == HPMUD_SCANTYPE_LEDM)
1684
return ledm_open(devicename, pHandle);
1686
hpaio = hpaioFindScanner(devicename);
1690
goto done; /* reuse same device, why?? (des) */
1693
hpaio = malloc( sizeof( struct hpaioScanner_s ) );
1697
retcode = SANE_STATUS_NO_MEM;
1701
hpaioAddScanner( hpaio );
1708
memset( hpaio, 0, sizeof( struct hpaioScanner_s ) );
1710
hpaio->tag = "SCL-PML";
1712
stat = hpmud_open_device(devname, ma.mfp_mode, &hpaio->deviceid);
1713
strncpy(hpaio->deviceuri, devname, sizeof(hpaio->deviceuri));
1715
if(stat != HPMUD_R_OK)
1717
retcode = SANE_STATUS_IO_ERROR;
1721
hpaio->scan_channelid = -1;
1722
hpaio->cmd_channelid = -1;
1724
// Set the duplex type supported
1725
if (ma.scantype == HPMUD_SCANTYPE_SCL_DUPLEX)
1726
hpaio->supportsDuplex = 1;
1728
hpaio->supportsDuplex = 0;
1730
/* Get the device ID string and initialize the SANE_Device structure. */
1731
memset(deviceIDString, 0, sizeof(deviceIDString));
1733
if(hpmud_get_device_id(hpaio->deviceid, deviceIDString, sizeof(deviceIDString), &bytes_read) != HPMUD_R_OK)
1735
retcode = SANE_STATUS_INVAL;
1739
DBG(6, "device ID string=<%s>: %s %d\n", deviceIDString, __FILE__, __LINE__);
1741
hpaio->saneDevice.name = strdup( devicename );
1743
hpaio->saneDevice.vendor = "Hewlett-Packard";
1745
hpmud_get_model(deviceIDString, model, sizeof(model));
1747
DBG(6, "Model = %s: %s %d\n", model, __FILE__, __LINE__);
1749
hpaio->saneDevice.model = strdup(model);
1750
hpaio->saneDevice.type = "multi-function peripheral";
1752
/* Initialize option descriptors. */
1753
hpaioSetupOptions( hpaio );
1754
hpaio->currentSideNumber = 1;
1759
/* Guess the command language (SCL or PML) based on the model string. */
1760
if( UNDEFINED_MODEL( hpaio ) )
1762
hpaio->scannerType = SCANNER_TYPE_SCL;
1764
else if( strcasestr( hpaio->saneDevice.model, "laserjet" ) )
1766
hpaio->scannerType = SCANNER_TYPE_PML;
1767
hpaio->pml.openFirst = 1;
1769
if( strcasecmp( hpaio->saneDevice.model, "HP_LaserJet_1100" ) == 0 )
1771
hpaio->pml.dontResetBeforeNextNonBatchPage = 1;
1775
hpaio->pml.startNextBatchPageEarly = 1;
1778
else if( strcasecmp( hpaio->saneDevice.model, "OfficeJet" ) == 0 ||
1779
strcasecmp( hpaio->saneDevice.model, "OfficeJet_LX" ) == 0 ||
1780
strcasecmp( hpaio->saneDevice.model, "OfficeJet_Series_300" ) == 0 )
1782
hpaio->scannerType = SCANNER_TYPE_PML;
1783
hpaio->preDenali = 1;
1785
else if( strcasecmp( hpaio->saneDevice.model, "OfficeJet_Series_500" ) == 0 ||
1786
strcasecmp( hpaio->saneDevice.model, "All-in-One_IJP-V100" ) == 0 )
1788
hpaio->scannerType = SCANNER_TYPE_PML;
1789
hpaio->fromDenali = 1;
1790
force300dpiForLineart = 1;
1791
force300dpiForGrayscale = 1;
1792
hpaio->defaultCompression[SCAN_MODE_LINEART] = COMPRESSION_MH;
1793
hpaio->defaultCompression[SCAN_MODE_GRAYSCALE] = COMPRESSION_JPEG;
1794
hpaio->defaultJpegCompressionFactor = SAFER_JPEG_COMPRESSION_FACTOR;
1796
else if( strcasecmp( hpaio->saneDevice.model, "OfficeJet_Series_600" ) == 0 )
1798
hpaio->scannerType = SCANNER_TYPE_PML;
1800
forceJpegForGrayAndColor = 1;
1801
force300dpiForLineart = 1;
1802
hpaio->defaultCompression[SCAN_MODE_LINEART] = COMPRESSION_MH;
1803
hpaio->defaultJpegCompressionFactor = SAFER_JPEG_COMPRESSION_FACTOR;
1805
else if( strcasecmp( hpaio->saneDevice.model, "Printer/Scanner/Copier_300" ) == 0 )
1807
hpaio->scannerType = SCANNER_TYPE_PML;
1808
forceJpegForGrayAndColor = 1;
1809
force300dpiForLineart = 1;
1810
hpaio->defaultCompression[SCAN_MODE_LINEART] = COMPRESSION_MH;
1811
hpaio->defaultJpegCompressionFactor = SAFER_JPEG_COMPRESSION_FACTOR;
1813
else if( strcasecmp( hpaio->saneDevice.model, "OfficeJet_Series_700" ) == 0 )
1815
hpaio->scannerType = SCANNER_TYPE_PML;
1816
forceJpegForGrayAndColor = 1;
1817
force300dpiForLineart = 1;
1818
hpaio->defaultCompression[SCAN_MODE_LINEART] = COMPRESSION_MH;
1819
hpaio->defaultJpegCompressionFactor = SAFER_JPEG_COMPRESSION_FACTOR;
1821
else if( strcasecmp( hpaio->saneDevice.model, "OfficeJet_T_Series" ) == 0 )
1823
hpaio->scannerType = SCANNER_TYPE_PML;
1824
forceJpegForGrayAndColor = 1;
1828
hpaio->scannerType = SCANNER_TYPE_SCL;
1831
DBG(6, "Scanner type=%s: %s %d\n", hpaio->scannerType==0 ? "SCL" : "PML", __FILE__, __LINE__);
1833
hpaioPmlAllocateObjects(hpaio); /* used by pml scanners and scl scanners */
1835
if ((retcode = hpaioConnOpen(hpaio)) != SANE_STATUS_GOOD)
1840
if ((retcode = hpaioResetScanner(hpaio)) != SANE_STATUS_GOOD)
1845
/* Probing and setup for SCL scanners... */
1846
if( hpaio->scannerType == SCANNER_TYPE_SCL )
1848
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_CLEAR_ERROR_STACK, 0 );
1850
/* Probe the SCL model. */
1851
retcode = SclInquire( hpaio->deviceid,
1852
hpaio->scan_channelid,
1853
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
1854
SCL_INQ_HP_MODEL_11,
1856
hpaio->scl.compat1150,
1857
LEN_MODEL_RESPONSE );
1859
if( retcode == SANE_STATUS_GOOD )
1861
hpaio->scl.compat |= SCL_COMPAT_OFFICEJET;
1863
else if( retcode != SANE_STATUS_UNSUPPORTED )
1867
DBG(6, "scl.compat1150=<%s>: %s %d\n", hpaio->scl.compat1150, __FILE__, __LINE__);
1869
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
1870
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
1871
SCL_INQ_HP_MODEL_12,
1873
hpaio->scl.compatPost1150,
1874
LEN_MODEL_RESPONSE );
1876
if( retcode == SANE_STATUS_GOOD )
1878
hpaio->scl.compat |= SCL_COMPAT_POST_1150;
1880
else if( retcode != SANE_STATUS_UNSUPPORTED )
1884
DBG(6, "scl.compatPost1150=<%s>: %s %d\n", hpaio->scl.compatPost1150, __FILE__, __LINE__);
1886
if( !hpaio->scl.compat )
1888
SET_DEFAULT_MODEL( hpaio, "(unknown scanner)" );
1890
else if( hpaio->scl.compat == SCL_COMPAT_OFFICEJET )
1892
hpaio->scl.compat |= SCL_COMPAT_1150;
1893
SET_DEFAULT_MODEL( hpaio, "(OfficeJet 1150)" );
1895
else if( !strcmp( hpaio->scl.compatPost1150, "5400A" ) )
1897
hpaio->scl.compat |= SCL_COMPAT_1170;
1898
SET_DEFAULT_MODEL( hpaio, "(OfficeJet 1170)" );
1900
else if( !strcmp( hpaio->scl.compatPost1150, "5500A" ) )
1902
hpaio->scl.compat |= SCL_COMPAT_R_SERIES;
1903
SET_DEFAULT_MODEL( hpaio, "(OfficeJet R Series)" );
1905
else if( !strcmp( hpaio->scl.compatPost1150, "5600A" ) )
1907
hpaio->scl.compat |= SCL_COMPAT_G_SERIES;
1908
SET_DEFAULT_MODEL( hpaio, "(OfficeJet G Series)" );
1910
else if( !strcmp( hpaio->scl.compatPost1150, "5700A" ) )
1912
hpaio->scl.compat |= SCL_COMPAT_K_SERIES;
1913
SET_DEFAULT_MODEL( hpaio, "(OfficeJet K Series)" );
1915
else if( !strcmp( hpaio->scl.compatPost1150, "5800A" ) )
1917
hpaio->scl.compat |= SCL_COMPAT_D_SERIES;
1918
SET_DEFAULT_MODEL( hpaio, "(OfficeJet D Series)" );
1920
else if( !strcmp( hpaio->scl.compatPost1150, "5900A" ) )
1922
hpaio->scl.compat |= SCL_COMPAT_6100_SERIES;
1923
SET_DEFAULT_MODEL( hpaio, "(OfficeJet 6100 Series)" );
1927
SET_DEFAULT_MODEL( hpaio, "(unknown OfficeJet)" );
1929
DBG(6, "scl.compat=0x%4.4X: %s %d\n", hpaio->scl.compat, __FILE__, __LINE__);
1931
/* Decide which position/extent unit to use. "Device pixels" works
1932
* better on most models, but the 1150 requires "decipoints." */
1933
if( hpaio->scl.compat & ( SCL_COMPAT_1150 ) )
1935
hpaio->scl.decipixelChar = SCL_CHAR_DECIPOINTS;
1936
hpaio->decipixelsPerInch = DECIPOINTS_PER_INCH;
1940
hpaio->scl.decipixelChar = SCL_CHAR_DEVPIXELS;
1941
hpaio->decipixelsPerInch = DEVPIXELS_PER_INCH;
1942
/* Check for non-default decipixelsPerInch definition. */
1943
SclInquire( hpaio->deviceid, hpaio->scan_channelid,
1944
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
1945
SCL_INQ_DEVICE_PIXELS_PER_INCH,
1946
&hpaio->decipixelsPerInch,
1950
DBG(6, "decipixelChar='%c', decipixelsPerInch=%d: %s %d\n", hpaio->scl.decipixelChar, hpaio->decipixelsPerInch, __FILE__, __LINE__);
1952
/* Is MFPDTF supported? */
1953
if( hpaioSclSendCommandCheckError( hpaio,
1955
SCL_MFPDTF_ON ) != SANE_STATUS_GOOD )
1957
DBG(6, "Doesn't support MFPDTF: %s %d\n", __FILE__, __LINE__);
1961
/* All scan modes are supported with no compression. */
1962
hpaio->supportsScanMode[SCAN_MODE_LINEART] = COMPRESSION_NONE;
1963
hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] = COMPRESSION_NONE;
1964
hpaio->supportsScanMode[SCAN_MODE_COLOR] = COMPRESSION_NONE;
1966
if( supportsMfpdtf )
1968
if( hpaioSclSendCommandCheckError( hpaio,
1969
SCL_CMD_SET_COMPRESSION,
1970
SCL_COMPRESSION_JPEG ) == SANE_STATUS_GOOD )
1972
hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] |= COMPRESSION_JPEG;
1973
hpaio->supportsScanMode[SCAN_MODE_COLOR] |= COMPRESSION_JPEG;
1977
/* Determine the minimum and maximum resolution.
1978
* Probe for both X and Y, and pick largest min and smallest max.
1979
* For the 1150, set min to 50 to prevent scan head crashes (<42). */
1980
int minXRes, minYRes, maxXRes, maxYRes;
1981
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
1982
SCL_CMD_INQUIRE_MINIMUM_VALUE,
1983
SCL_CMD_SET_X_RESOLUTION,
1988
DBG(6, "minXRes=%d retcode=%d\n",minXRes, retcode);
1990
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
1991
SCL_CMD_INQUIRE_MINIMUM_VALUE,
1992
SCL_CMD_SET_Y_RESOLUTION,
1997
DBG(6,"minYRes=%d retcode=%d\n", minYRes, retcode);
1999
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2000
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2001
SCL_CMD_SET_X_RESOLUTION,
2006
DBG(6,"maxXRes=%d retcode=%d\n", maxXRes, retcode);
2008
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2009
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2010
SCL_CMD_SET_Y_RESOLUTION,
2015
DBG(6,"maxYRes=%d retcode=%d\n", maxYRes, retcode);
2017
if( hpaio->scl.compat & SCL_COMPAT_1150 &&
2018
minYRes < SCL_MIN_Y_RES_1150 )
2020
minYRes = SCL_MIN_Y_RES_1150;
2022
hpaio->scl.minRes = minXRes;
2023
if( hpaio->scl.minRes < minYRes )
2025
hpaio->scl.minRes = minYRes;
2028
hpaio->resolutionRange.min = hpaio->scl.minRes;
2030
hpaio->scl.maxRes = maxXRes;
2032
if( hpaio->scl.maxRes > maxYRes )
2034
hpaio->scl.maxRes = maxYRes;
2037
if( hpaio->scl.compat & ( SCL_COMPAT_1150 | SCL_COMPAT_1170 )
2038
&& hpaio->scl.maxRes > SCL_MAX_RES_1150_1170 )
2040
hpaio->scl.maxRes = SCL_MAX_RES_1150_1170;
2042
hpaio->resolutionRange.max = hpaio->scl.maxRes;
2044
/* Determine ADF/duplex capabilities. */
2046
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2047
SCL_CMD_INQUIRE_DEVICE_PARAMETER,
2048
SCL_INQ_ADF_CAPABILITY,
2049
&hpaio->scl.adfCapability,
2053
DBG(6, "ADF capability=%d retcode=%d: %s %d\n", hpaio->scl.adfCapability, retcode,__FILE__, __LINE__);
2055
if (hpaio->scl.adfCapability)
2057
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2058
SCL_CMD_INQUIRE_MINIMUM_VALUE,
2059
SCL_PSEUDO_ADF_X_RESOLUTION,
2063
DBG(6, "minXResAdf=%d retcode=%d\n", minXRes, retcode);
2064
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2065
SCL_CMD_INQUIRE_MINIMUM_VALUE,
2066
SCL_PSEUDO_ADF_Y_RESOLUTION,
2070
DBG(6, "minYResAdf=%d retcode=%d\n", minYRes, retcode);
2071
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2072
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2073
SCL_PSEUDO_ADF_X_RESOLUTION,
2077
DBG(6, "maxXResAdf=%d retcode=%d\n", maxXRes, retcode);
2078
retcode = SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2079
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2080
SCL_PSEUDO_ADF_Y_RESOLUTION,
2084
DBG(6, "maxYResAdf=%d retcode=%d\n", maxYRes, retcode);
2085
if( hpaio->scl.compat & SCL_COMPAT_1150 &&
2086
minYRes < SCL_MIN_Y_RES_1150 )
2088
minYRes = SCL_MIN_Y_RES_1150;
2090
hpaio->scl.minResAdf = minXRes;
2091
if( hpaio->scl.minResAdf < minYRes )
2093
hpaio->scl.minResAdf = minYRes;
2096
hpaio->scl.maxResAdf = maxXRes;
2098
if( hpaio->scl.maxResAdf > maxYRes )
2100
hpaio->scl.maxResAdf = maxYRes;
2103
if( hpaio->scl.compat & ( SCL_COMPAT_1150 | SCL_COMPAT_1170 )
2104
&& hpaio->scl.maxResAdf > SCL_MAX_RES_1150_1170 )
2106
hpaio->scl.maxResAdf = SCL_MAX_RES_1150_1170;
2110
if(ma.scansrc & HPMUD_SCANSRC_FLATBED)
2112
hpaio->scl.flatbedCapability = 1;
2113
hpaio->supportedAdfModes = ADF_MODE_FLATBED;
2115
if (hpaio->scl.adfCapability)
2117
if( hpaio->scl.compat & SCL_COMPAT_K_SERIES)
2119
hpaio->supportedAdfModes |= ADF_MODE_ADF;
2123
int supportedFunctions;
2125
hpaio->supportedAdfModes |= ADF_MODE_ADF;
2126
if (hpaio->scl.flatbedCapability)
2127
hpaio->supportedAdfModes |= ADF_MODE_AUTO;
2129
if( hpaio->scl.compat & ( SCL_COMPAT_1170 | SCL_COMPAT_R_SERIES |SCL_COMPAT_G_SERIES ) )
2131
hpaio->scl.unloadAfterScan = 1;
2133
if( PmlRequestGet( hpaio->deviceid, hpaio->cmd_channelid, hpaio->scl.objSupportedFunctions ) != ERROR &&
2134
PmlGetIntegerValue( hpaio->scl.objSupportedFunctions,
2136
&supportedFunctions ) != ERROR &&
2137
supportedFunctions & PML_SUPPFUNC_DUPLEX )
2139
hpaio->supportsDuplex = 1;
2145
/* Determine maximum X and Y extents. */
2146
SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2147
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2148
SCL_CMD_SET_X_EXTENT,
2149
&hpaio->scl.maxXExtent,
2153
SclInquire( hpaio->deviceid, hpaio->scan_channelid,
2154
SCL_CMD_INQUIRE_MAXIMUM_VALUE,
2155
SCL_CMD_SET_Y_EXTENT,
2156
&hpaio->scl.maxYExtent,
2160
DBG(8, "Maximum extents: x=%d, y=%d %s %d\n", hpaio->scl.maxXExtent, hpaio->scl.maxYExtent, __FILE__, __LINE__);
2162
hpaio->tlxRange.max = hpaio->brxRange.max = DECIPIXELS_TO_MILLIMETERS( hpaio->scl.maxXExtent );
2163
hpaio->tlyRange.max = hpaio->bryRange.max = DECIPIXELS_TO_MILLIMETERS( hpaio->scl.maxYExtent );
2165
/* Probing and setup for PML scanners... */
2167
else /* if (hpaio->scannerType==SCANNER_TYPE_PML) */
2171
hpaio->decipixelsPerInch = DECIPOINTS_PER_INCH;
2173
/*ChannelSetSelectPollTimeout( hpaio->chan, &selectPollTimeout );
2175
ChannelSetSelectPollCallback( hpaio->chan,
2176
hpaioPmlSelectCallback,
2179
/* Determine supported scan modes and compression settings. */
2180
if( hpaio->preDenali )
2182
comps |= COMPRESSION_MMR;
2185
PmlSetIntegerValue( hpaio->pml.objCompression,
2186
PML_TYPE_ENUMERATION,
2187
PML_COMPRESSION_NONE );
2189
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2190
hpaio->pml.objCompression, 0, 0 ) != ERROR )
2192
comps |= COMPRESSION_NONE;
2195
PmlSetIntegerValue( hpaio->pml.objCompression,
2196
PML_TYPE_ENUMERATION,
2197
PML_COMPRESSION_MH );
2199
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2200
hpaio->pml.objCompression, 0, 0 ) != ERROR )
2202
comps |= COMPRESSION_MH;
2205
PmlSetIntegerValue( hpaio->pml.objCompression,
2206
PML_TYPE_ENUMERATION,
2207
PML_COMPRESSION_MR );
2209
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2210
hpaio->pml.objCompression, 0, 0 ) != ERROR )
2212
comps |= COMPRESSION_MR;
2215
PmlSetIntegerValue( hpaio->pml.objCompression,
2216
PML_TYPE_ENUMERATION,
2217
PML_COMPRESSION_MMR );
2219
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2220
hpaio->pml.objCompression, 0, 0 ) != ERROR )
2222
comps |= COMPRESSION_MMR;
2225
PmlSetIntegerValue( hpaio->pml.objPixelDataType,
2226
PML_TYPE_ENUMERATION,
2227
PML_DATA_TYPE_LINEART );
2229
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2230
hpaio->pml.objPixelDataType, 0, 0 ) != ERROR )
2232
hpaio->supportsScanMode[SCAN_MODE_LINEART] = comps;
2234
comps &= COMPRESSION_NONE;
2236
if( forceJpegForGrayAndColor )
2241
PmlSetIntegerValue( hpaio->pml.objCompression,
2242
PML_TYPE_ENUMERATION,
2243
PML_COMPRESSION_JPEG );
2245
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2246
hpaio->pml.objCompression, 0, 0 ) != ERROR )
2248
comps |= COMPRESSION_JPEG;
2251
PmlSetIntegerValue( hpaio->pml.objPixelDataType,
2252
PML_TYPE_ENUMERATION,
2253
PML_DATA_TYPE_GRAYSCALE );
2255
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2256
hpaio->pml.objPixelDataType, 0, 0 ) != ERROR )
2258
hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] = comps;
2261
PmlSetIntegerValue( hpaio->pml.objPixelDataType,
2262
PML_TYPE_ENUMERATION,
2263
PML_DATA_TYPE_COLOR );
2265
if( PmlRequestSetRetry( hpaio->deviceid, hpaio->cmd_channelid,
2266
hpaio->pml.objPixelDataType, 0, 0 ) != ERROR )
2268
hpaio->supportsScanMode[SCAN_MODE_COLOR] = comps;
2271
/* Determine supported resolutions. */
2272
NumListClear( hpaio->resolutionList );
2273
NumListClear( hpaio->lineartResolutionList );
2275
if( hpaio->preDenali )
2277
NumListAdd( hpaio->lineartResolutionList, 200 );
2278
if( !strcmp( hpaio->saneDevice.model, "OfficeJet_Series_300" ) )
2280
NumListAdd( hpaio->lineartResolutionList, 300 );
2282
hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2284
else if( PmlRequestGet( hpaio->deviceid, hpaio->cmd_channelid,
2285
hpaio->pml.objResolutionRange ) == ERROR )
2288
/* TODO: What are the correct X and Y resolution ranges
2289
* for the OfficeJet T series? */
2290
hpaio->resolutionRange.min = 75;
2291
hpaio->resolutionRange.max = 600;
2295
char resList[PML_MAX_VALUE_LEN + 1];
2296
int i, len, res, consumed;
2298
PmlGetStringValue( hpaio->pml.objResolutionRange,
2301
PML_MAX_VALUE_LEN );
2303
resList[PML_MAX_VALUE_LEN] = 0;
2304
len = strlen( resList );
2306
/* Parse "(100)x(100),(150)x(150),(200)x(200),(300)x(300)".
2307
* This isn't quite the right way to do it, but it'll do. */
2308
for( i = 0; i < len; )
2310
if( resList[i] < '0' || resList[i] > '9' )
2315
if( sscanf( resList + i, "%d%n", &res, &consumed ) != 1 )
2320
if( !force300dpiForGrayscale || res >= 300 )
2322
NumListAdd( hpaio->resolutionList, res );
2324
if( !force300dpiForLineart || res >= 300 )
2326
NumListAdd( hpaio->lineartResolutionList, res );
2330
if( !NumListGetCount( hpaio->resolutionList ) )
2332
goto pmlDefaultResRange;
2334
hpaio->option[OPTION_SCAN_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2337
/* Determine contrast support. (Removed, no LJ support, des 7/31/07) */
2338
// if( PmlRequestGet(hpaio->deviceid, hpaio->cmd_channelid, hpaio->pml.objContrast) != ERROR)
2340
// hpaio->option[OPTION_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
2343
/* Determine supported ADF modes. */
2344
if(PmlRequestGet(hpaio->deviceid, hpaio->cmd_channelid, hpaio->pml.objModularHardware) != ERROR &&
2345
PmlGetIntegerValue(hpaio->pml.objModularHardware, 0, &modularHardware) != ERROR)
2347
hpaio->pml.flatbedCapability = 1;
2349
DBG(6, "Valid PML modularHardware object value=%x: %s %d\n", modularHardware, __FILE__, __LINE__);
2351
/* LJ3200 does not report ADF mode, so we force it. DES 8/5/08 */
2352
if (strncasecmp(model, "hp_laserjet_3200", 16) == 0)
2353
modularHardware = PML_MODHW_ADF;
2355
if(modularHardware & PML_MODHW_ADF)
2356
hpaio->supportedAdfModes = ADF_MODE_AUTO | ADF_MODE_ADF;
2358
hpaio->supportedAdfModes = ADF_MODE_FLATBED;
2362
DBG(6, "No valid PML modularHardware object, default to ADF and AUTO support: %s %d\n", __FILE__, __LINE__);
2363
hpaio->supportedAdfModes = ADF_MODE_AUTO | ADF_MODE_ADF;
2365
hpaio->supportsDuplex = 0;
2367
hpaio->tlxRange.max = hpaio->brxRange.max = INCHES_TO_MILLIMETERS( PML_MAX_WIDTH_INCHES );
2368
hpaio->tlyRange.max = hpaio->bryRange.max = INCHES_TO_MILLIMETERS( PML_MAX_HEIGHT_INCHES );
2370
} /* if( hpaio->scannerType == SCANNER_TYPE_SCL ) */
2372
/* Allocate MFPDTF parser if supported. */
2373
if( supportsMfpdtf )
2375
hpaio->mfpdtf = MfpdtfAllocate( hpaio->deviceid, hpaio->scan_channelid );
2376
MfpdtfSetChannel( hpaio->mfpdtf, hpaio->scan_channelid );
2378
if( hpaio->preDenali )
2380
MfpdtfReadSetSimulateImageHeaders( hpaio->mfpdtf, 1 );
2385
/* Finish setting up option descriptors. */
2386
hpaioUpdateDescriptors( hpaio, OPTION_FIRST );
2392
//ptalDeviceSetAppInfo( dev, hpaio );
2393
retcode = SANE_STATUS_GOOD;
2398
hpaioConnClose( hpaio );
2400
if( retcode != SANE_STATUS_GOOD )
2404
if( hpaio->saneDevice.name )
2406
free( ( void * ) hpaio->saneDevice.name );
2408
if( hpaio->saneDevice.model )
2410
free( ( void * ) hpaio->saneDevice.model );
2416
} /* sane_hpaio_open() */
2418
extern void sane_hpaio_close(SANE_Handle handle)
2420
hpaioScanner_t hpaio = (hpaioScanner_t) handle;
2422
if (strcmp(*((char **)handle), "MARVELL") == 0)
2423
return marvell_close(handle);
2424
if (strcmp(*((char **)handle), "SOAP") == 0)
2425
return soap_close(handle);
2426
if (strcmp(*((char **)handle), "SOAPHT") == 0)
2427
return soapht_close(handle);
2428
if (strcmp(*((char **)handle), "LEDM") == 0)
2429
return ledm_close(handle);
2431
DBG(8, "sane_hpaio_close(): %s %d\n", __FILE__, __LINE__);
2433
hpaioPmlDeallocateObjects(hpaio);
2435
/* ADF may leave channel(s) open. */
2436
if (hpaio->cmd_channelid > 0)
2437
hpaioConnEndScan(hpaio);
2439
if (hpaio->deviceid > 0)
2441
hpmud_close_device(hpaio->deviceid);
2442
hpaio->deviceid = -1;
2445
/* free hpaio object?? (des) */
2446
} /* sane_hpaio_close() */
2448
extern const SANE_Option_Descriptor * sane_hpaio_get_option_descriptor(SANE_Handle handle, SANE_Int option)
2450
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
2452
if (strcmp(*((char **)handle), "MARVELL") == 0)
2453
return marvell_get_option_descriptor(handle, option);
2454
if (strcmp(*((char **)handle), "SOAP") == 0)
2455
return soap_get_option_descriptor(handle, option);
2456
if (strcmp(*((char **)handle), "SOAPHT") == 0)
2457
return soapht_get_option_descriptor(handle, option);
2458
if (strcmp(*((char **)handle), "LEDM") == 0)
2459
return ledm_get_option_descriptor(handle, option);
2461
DBG(8, "sane_hpaio_get_option_descriptor(option=%s): %s %d\n", hpaio->option[option].name, __FILE__, __LINE__);
2463
if( option < 0 || option >= OPTION_LAST )
2468
return &hpaio->option[option];
2469
} /* sane_hpaio_get_option_descriptor() */
2471
extern SANE_Status sane_hpaio_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void * pValue, SANE_Int * pInfo )
2473
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
2475
SANE_Int * pIntValue = pValue;
2476
SANE_String pStrValue = pValue;
2477
SANE_Status retcode;
2480
if (strcmp(*((char **)handle), "MARVELL") == 0)
2481
return marvell_control_option(handle, option, action, pValue, pInfo);
2482
if (strcmp(*((char **)handle), "SOAP") == 0)
2483
return soap_control_option(handle, option, action, pValue, pInfo);
2484
if (strcmp(*((char **)handle), "SOAPHT") == 0)
2485
return soapht_control_option(handle, option, action, pValue, pInfo);
2486
if (strcmp(*((char **)handle), "LEDM") == 0)
2487
return ledm_control_option(handle, option, action, pValue, pInfo);
2496
case SANE_ACTION_GET_VALUE:
2499
case OPTION_NUM_OPTIONS:
2500
*pIntValue = OPTION_LAST;
2503
case OPTION_SCAN_MODE:
2504
switch( hpaio->currentScanMode )
2506
case SCAN_MODE_LINEART:
2507
strcpy( pStrValue, SANE_VALUE_SCAN_MODE_LINEART );
2509
case SCAN_MODE_GRAYSCALE:
2510
strcpy( pStrValue, SANE_VALUE_SCAN_MODE_GRAY );
2512
case SCAN_MODE_COLOR:
2513
strcpy( pStrValue, SANE_VALUE_SCAN_MODE_COLOR );
2516
strcpy( pStrValue, STR_UNKNOWN );
2521
case OPTION_SCAN_RESOLUTION:
2522
*pIntValue = hpaio->currentResolution;
2525
case OPTION_CONTRAST:
2526
*pIntValue = hpaio->currentContrast;
2529
case OPTION_COMPRESSION:
2530
switch( hpaio->currentCompression )
2532
case COMPRESSION_NONE:
2533
strcpy( pStrValue, STR_COMPRESSION_NONE );
2535
case COMPRESSION_MH:
2536
strcpy( pStrValue, STR_COMPRESSION_MH );
2538
case COMPRESSION_MR:
2539
strcpy( pStrValue, STR_COMPRESSION_MR );
2541
case COMPRESSION_MMR:
2542
strcpy( pStrValue, STR_COMPRESSION_MMR );
2544
case COMPRESSION_JPEG:
2545
strcpy( pStrValue, STR_COMPRESSION_JPEG );
2548
strcpy( pStrValue, STR_UNKNOWN );
2553
case OPTION_JPEG_COMPRESSION_FACTOR:
2554
*pIntValue = hpaio->currentJpegCompressionFactor;
2557
case OPTION_BATCH_SCAN:
2558
*pIntValue = hpaio->currentBatchScan;
2561
case OPTION_ADF_MODE:
2562
switch( hpaio->currentAdfMode )
2565
strcpy( pStrValue, STR_ADF_MODE_AUTO );
2567
case ADF_MODE_FLATBED:
2568
strcpy( pStrValue, STR_ADF_MODE_FLATBED );
2571
strcpy( pStrValue, STR_ADF_MODE_ADF );
2574
strcpy( pStrValue, STR_UNKNOWN );
2580
*pIntValue = hpaio->currentDuplex;
2583
case OPTION_LENGTH_MEASUREMENT:
2584
switch( hpaio->currentLengthMeasurement )
2586
case LENGTH_MEASUREMENT_UNKNOWN:
2587
strcpy( pStrValue, STR_LENGTH_MEASUREMENT_UNKNOWN );
2589
case LENGTH_MEASUREMENT_UNLIMITED:
2591
STR_LENGTH_MEASUREMENT_UNLIMITED );
2593
case LENGTH_MEASUREMENT_APPROXIMATE:
2595
STR_LENGTH_MEASUREMENT_APPROXIMATE );
2597
case LENGTH_MEASUREMENT_PADDED:
2598
strcpy( pStrValue, STR_LENGTH_MEASUREMENT_PADDED );
2600
case LENGTH_MEASUREMENT_EXACT:
2601
strcpy( pStrValue, STR_LENGTH_MEASUREMENT_EXACT );
2604
strcpy( pStrValue, STR_UNKNOWN );
2610
*pIntValue = hpaio->currentTlx;
2614
*pIntValue = hpaio->currentTly;
2618
*pIntValue = hpaio->currentBrx;
2622
*pIntValue = hpaio->currentBry;
2626
return SANE_STATUS_INVAL;
2630
case SANE_ACTION_SET_VALUE:
2631
if( hpaio->option[option].cap & SANE_CAP_INACTIVE )
2633
return SANE_STATUS_INVAL;
2637
case OPTION_SCAN_MODE:
2638
if( !strcasecmp( pStrValue, SANE_VALUE_SCAN_MODE_LINEART ) &&
2639
hpaio->supportsScanMode[SCAN_MODE_LINEART] )
2641
hpaio->currentScanMode = SCAN_MODE_LINEART;
2644
if( !strcasecmp( pStrValue, SANE_VALUE_SCAN_MODE_GRAY ) &&
2645
hpaio->supportsScanMode[SCAN_MODE_GRAYSCALE] )
2647
hpaio->currentScanMode = SCAN_MODE_GRAYSCALE;
2650
if( !strcasecmp( pStrValue, SANE_VALUE_SCAN_MODE_COLOR ) &&
2651
hpaio->supportsScanMode[SCAN_MODE_COLOR] )
2653
hpaio->currentScanMode = SCAN_MODE_COLOR;
2656
return SANE_STATUS_INVAL;
2658
case OPTION_SCAN_RESOLUTION:
2659
if( ( hpaio->option[option].constraint_type ==
2660
SANE_CONSTRAINT_WORD_LIST &&
2661
!NumListIsInList( ( SANE_Int * )hpaio->option[option].constraint.word_list, *pIntValue ) ) ||
2662
( hpaio->option[option].constraint_type == SANE_CONSTRAINT_RANGE &&
2663
( *pIntValue<hpaio->resolutionRange.min ||
2664
*pIntValue>hpaio->resolutionRange.max ) ) )
2666
return SANE_STATUS_INVAL;
2668
hpaio->currentResolution = *pIntValue;
2671
case OPTION_CONTRAST:
2672
if( *pIntValue<hpaio->contrastRange.min ||
2673
*pIntValue>hpaio->contrastRange.max )
2675
return SANE_STATUS_INVAL;
2677
hpaio->currentContrast = *pIntValue;
2680
case OPTION_COMPRESSION:
2682
int supportedCompression = hpaio->supportsScanMode[hpaio->currentScanMode];
2683
if( !strcasecmp( pStrValue, STR_COMPRESSION_NONE ) &&
2684
supportedCompression & COMPRESSION_NONE )
2686
hpaio->currentCompression = COMPRESSION_NONE;
2689
if( !strcasecmp( pStrValue, STR_COMPRESSION_MH ) &&
2690
supportedCompression & COMPRESSION_MH )
2692
hpaio->currentCompression = COMPRESSION_MH;
2695
if( !strcasecmp( pStrValue, STR_COMPRESSION_MR ) &&
2696
supportedCompression & COMPRESSION_MR )
2698
hpaio->currentCompression = COMPRESSION_MR;
2701
if( !strcasecmp( pStrValue, STR_COMPRESSION_MMR ) &&
2702
supportedCompression & COMPRESSION_MMR )
2704
hpaio->currentCompression = COMPRESSION_MMR;
2707
if( !strcasecmp( pStrValue, STR_COMPRESSION_JPEG ) &&
2708
supportedCompression & COMPRESSION_JPEG )
2710
hpaio->currentCompression = COMPRESSION_JPEG;
2713
return SANE_STATUS_INVAL;
2716
case OPTION_JPEG_COMPRESSION_FACTOR:
2717
if( *pIntValue<MIN_JPEG_COMPRESSION_FACTOR ||
2718
*pIntValue>MAX_JPEG_COMPRESSION_FACTOR )
2720
return SANE_STATUS_INVAL;
2722
hpaio->currentJpegCompressionFactor = *pIntValue;
2725
case OPTION_BATCH_SCAN:
2726
if( *pIntValue != SANE_FALSE && *pIntValue != SANE_TRUE )
2728
return SANE_STATUS_INVAL;
2730
hpaio->currentBatchScan = *pIntValue;
2733
case OPTION_ADF_MODE:
2734
if( !strcasecmp( pStrValue, STR_ADF_MODE_AUTO ) &&
2735
hpaio->supportedAdfModes & ADF_MODE_AUTO )
2737
hpaio->currentAdfMode = ADF_MODE_AUTO;
2740
if( !strcasecmp( pStrValue, STR_ADF_MODE_FLATBED ) &&
2741
hpaio->supportedAdfModes & ADF_MODE_FLATBED )
2743
hpaio->currentAdfMode = ADF_MODE_FLATBED;
2746
if( !strcasecmp( pStrValue, STR_ADF_MODE_ADF ) &&
2747
hpaio->supportedAdfModes & ADF_MODE_ADF )
2749
hpaio->currentAdfMode = ADF_MODE_ADF;
2752
return SANE_STATUS_INVAL;
2755
if( *pIntValue != SANE_FALSE && *pIntValue != SANE_TRUE )
2757
return SANE_STATUS_INVAL;
2759
hpaio->currentDuplex = *pIntValue;
2762
case OPTION_LENGTH_MEASUREMENT:
2763
if( !strcasecmp( pStrValue,
2764
STR_LENGTH_MEASUREMENT_UNKNOWN ) )
2766
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_UNKNOWN;
2769
if( !strcasecmp( pStrValue,
2770
STR_LENGTH_MEASUREMENT_UNLIMITED ) )
2772
if( hpaio->scannerType != SCANNER_TYPE_PML )
2774
return SANE_STATUS_INVAL;
2776
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_UNLIMITED;
2779
if( !strcasecmp( pStrValue,
2780
STR_LENGTH_MEASUREMENT_APPROXIMATE ) )
2782
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_APPROXIMATE;
2785
if( !strcasecmp( pStrValue, STR_LENGTH_MEASUREMENT_PADDED ) )
2787
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_PADDED;
2790
if( !strcasecmp( pStrValue, STR_LENGTH_MEASUREMENT_EXACT ) )
2792
hpaio->currentLengthMeasurement = LENGTH_MEASUREMENT_EXACT;
2795
return SANE_STATUS_INVAL;
2798
if( *pIntValue<hpaio->tlxRange.min ||
2799
*pIntValue>hpaio->tlxRange.max )
2801
return SANE_STATUS_INVAL;
2803
hpaio->currentTlx = *pIntValue;
2807
if( *pIntValue<hpaio->tlyRange.min ||
2808
*pIntValue>hpaio->tlyRange.max )
2810
return SANE_STATUS_INVAL;
2812
hpaio->currentTly = *pIntValue;
2816
if( *pIntValue<hpaio->brxRange.min ||
2817
*pIntValue>hpaio->brxRange.max )
2819
return SANE_STATUS_INVAL;
2821
hpaio->currentBrx = *pIntValue;
2825
if( *pIntValue<hpaio->bryRange.min ||
2826
*pIntValue>hpaio->bryRange.max )
2828
return SANE_STATUS_INVAL;
2830
hpaio->currentBry = *pIntValue;
2834
return SANE_STATUS_INVAL;
2838
case SANE_ACTION_SET_AUTO:
2839
retcode = hpaioSetDefaultValue( hpaio, option );
2840
if( retcode != SANE_STATUS_GOOD )
2844
reload : *pInfo = hpaioUpdateDescriptors( hpaio, option );
2848
return SANE_STATUS_INVAL;
2851
DBG(8, "sane_hpaio_control_option (option=%s action=%s value=%s): %s %d\n", hpaio->option[option].name,
2852
action==SANE_ACTION_GET_VALUE ? "get" : action==SANE_ACTION_SET_VALUE ? "set" : "auto",
2853
pValue ? hpaio->option[option].type == SANE_TYPE_STRING ? (char *)pValue : psnprintf(sz, sizeof(sz), "%d", *(int *)pValue) : "na", __FILE__, __LINE__);
2855
return SANE_STATUS_GOOD;
2856
} /* sane_hpaio_control_option() */
2858
extern SANE_Status sane_hpaio_get_parameters(SANE_Handle handle, SANE_Parameters *pParams)
2860
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
2863
if (strcmp(*((char **)handle), "MARVELL") == 0)
2864
return marvell_get_parameters(handle, pParams);
2865
if (strcmp(*((char **)handle), "SOAP") == 0)
2866
return soap_get_parameters(handle, pParams);
2867
if (strcmp(*((char **)handle), "SOAPHT") == 0)
2868
return soapht_get_parameters(handle, pParams);
2869
if (strcmp(*((char **)handle), "LEDM") == 0)
2870
return ledm_get_parameters(handle, pParams);
2874
*pParams = hpaio->prescanParameters;
2879
*pParams = hpaio->scanParameters;
2881
DBG(8, "sane_hpaio_get_parameters(%sscan): format=%d, last_frame=%d, lines=%d, depth=%d, pixels_per_line=%d, bytes_per_line=%d %s %d\n",
2882
s, pParams->format, pParams->last_frame, pParams->lines, pParams->depth, pParams->pixels_per_line, pParams->bytes_per_line, __FILE__, __LINE__);
2884
return SANE_STATUS_GOOD;
2885
} /* sane_hpaio_get_parameters() */
2887
extern SANE_Status sane_hpaio_start(SANE_Handle handle)
2889
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
2890
SANE_Status retcode;
2891
IP_IMAGE_TRAITS traits;
2892
IP_XFORM_SPEC xforms[IP_MAX_XFORMS], * pXform = xforms;
2895
DBG(8, "sane_hpaio_start(): %s %d deviceuri=%s\n", __FILE__, __LINE__, hpaio->deviceuri);
2897
if (strcmp(*((char **)handle), "MARVELL") == 0)
2898
return marvell_start(handle);
2899
if (strcmp(*((char **)handle), "SOAP") == 0)
2900
return soap_start(handle);
2901
if (strcmp(*((char **)handle), "SOAPHT") == 0)
2902
return soapht_start(handle);
2903
if (strcmp(*((char **)handle), "LEDM") == 0)
2904
return ledm_start(handle);
2906
hpaio->user_cancel = FALSE;
2908
hpaio->endOfData = 0;
2910
if (hpaio->scannerType==SCANNER_TYPE_PML)
2911
return pml_start(hpaio);
2913
/* TODO: convert to scl_start. des */
2915
/* If we just scanned the last page of a batch scan, then return the obligatory SANE_STATUS_NO_DOCS condition. */
2916
if( hpaio->noDocsConditionPending )
2918
hpaio->noDocsConditionPending = 0;
2919
retcode = SANE_STATUS_NO_DOCS;
2922
/* Open scanner command channel. */
2923
retcode = hpaioConnPrepareScan( hpaio );
2925
if( retcode != SANE_STATUS_GOOD )
2929
/* Change document if needed. */
2930
hpaio->beforeScan = 1;
2931
retcode = hpaioAdvanceDocument( hpaio );
2932
hpaio->beforeScan = 0;
2934
if( retcode != SANE_STATUS_GOOD )
2939
/* Program options. */
2940
retcode = hpaioProgramOptions( hpaio );
2942
if( retcode != SANE_STATUS_GOOD )
2947
hpaio->scanParameters = hpaio->prescanParameters;
2948
memset( xforms, 0, sizeof( xforms ) );
2949
traits.iPixelsPerRow = -1;
2951
switch( hpaio->effectiveScanMode )
2953
case SCAN_MODE_LINEART:
2954
hpaio->scanParameters.format = SANE_FRAME_GRAY;
2955
hpaio->scanParameters.depth = 1;
2956
traits.iBitsPerPixel = 1;
2958
case SCAN_MODE_GRAYSCALE:
2959
hpaio->scanParameters.format = SANE_FRAME_GRAY;
2960
hpaio->scanParameters.depth = 8;
2961
traits.iBitsPerPixel = 8;
2963
case SCAN_MODE_COLOR:
2965
hpaio->scanParameters.format = SANE_FRAME_RGB;
2966
hpaio->scanParameters.depth = 8;
2967
traits.iBitsPerPixel = 24;
2970
traits.lHorizDPI = hpaio->effectiveResolution << 16;
2971
traits.lVertDPI = hpaio->effectiveResolution << 16;
2972
traits.lNumRows = -1;
2973
traits.iNumPages = 1;
2974
traits.iPageNum = 1;
2976
// if( hpaio->scannerType == SCANNER_TYPE_SCL )
2978
int lines, pixelsPerLine;
2980
/* Inquire exact image dimensions. */
2981
if( SclInquire( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_INQUIRE_DEVICE_PARAMETER, SCL_INQ_NUMBER_OF_SCAN_LINES,
2982
&lines, 0, 0 ) == SANE_STATUS_GOOD )
2984
traits.lNumRows = lines;
2986
SclInquire( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_INQUIRE_DEVICE_PARAMETER, SCL_INQ_PIXELS_PER_SCAN_LINE,
2987
&pixelsPerLine, 0, 0 );
2989
traits.iPixelsPerRow = pixelsPerLine;
2991
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_CLEAR_ERROR_STACK, 0 );
2993
/* Start scanning. */
2994
SclSendCommand( hpaio->deviceid, hpaio->scan_channelid, SCL_CMD_SCAN_WINDOW, 0 );
2998
MfpdtfSetChannel( hpaio->mfpdtf, hpaio->scan_channelid );
3000
//MfpdtfReadSetTimeout( hpaio->mfpdtf, MFPDTF_EARLY_READ_TIMEOUT );
3001
MfpdtfReadStart( hpaio->mfpdtf ); /* inits mfpdtf */
3014
sprintf(f, "/tmp/mfpdtf_%d.out", cnt++);
3016
bug("saving raw image to %s \n", f);
3018
MfpdtfLogToFile( hpaio->mfpdtf, f );
3023
int rService, sopEncoding;
3025
rService = MfpdtfReadService( hpaio->mfpdtf );
3027
if( retcode != SANE_STATUS_GOOD )
3032
if( rService & MFPDTF_RESULT_ERROR_MASK )
3034
retcode = SANE_STATUS_IO_ERROR;
3038
if( rService & MFPDTF_RESULT_NEW_VARIANT_HEADER && hpaio->preDenali )
3040
union MfpdtfVariantHeader_u vheader;
3041
MfpdtfReadGetVariantHeader( hpaio->mfpdtf, &vheader, sizeof( vheader ) );
3043
traits.iPixelsPerRow = LEND_GET_SHORT( vheader.faxArtoo.pixelsPerRow );
3044
traits.iBitsPerPixel = 1;
3046
switch( vheader.faxArtoo.dataCompression )
3048
case MFPDTF_RASTER_MH:
3049
sopEncoding = MFPDTF_RASTER_MH;
3051
case MFPDTF_RASTER_MR:
3052
sopEncoding = MFPDTF_RASTER_MR;
3054
case MFPDTF_RASTER_MMR:
3056
sopEncoding = MFPDTF_RASTER_MMR;
3061
else if( rService & MFPDTF_RESULT_NEW_START_OF_PAGE_RECORD )
3063
// struct MfpdtfImageStartPageRecord_s sop;
3065
// if( hpaio->scannerType == SCANNER_TYPE_SCL )
3067
if( hpaio->currentCompression == COMPRESSION_NONE )
3071
else /* if (hpaio->currentCompression==COMPRESSION_JPEG) */
3076
/* Read SOP record and set image pipeline input traits. */
3077
// MfpdtfReadGetStartPageRecord( hpaio->mfpdtf, &sop, sizeof( sop ) );
3078
// traits.iPixelsPerRow = LEND_GET_SHORT( sop.black.pixelsPerRow );
3079
// traits.iBitsPerPixel = LEND_GET_SHORT( sop.black.bitsPerPixel );
3080
// traits.lHorizDPI = LEND_GET_LONG( sop.black.xres );
3081
// traits.lVertDPI = LEND_GET_LONG( sop.black.yres );
3082
// sopEncoding = sop.encoding;
3085
/* Set up image-processing pipeline. */
3086
switch( sopEncoding )
3088
case MFPDTF_RASTER_MH:
3089
pXform->aXformInfo[IP_FAX_FORMAT].dword = IP_FAX_MH;
3090
ADD_XFORM( X_FAX_DECODE );
3092
case MFPDTF_RASTER_MR:
3093
pXform->aXformInfo[IP_FAX_FORMAT].dword = IP_FAX_MR;
3094
ADD_XFORM( X_FAX_DECODE );
3096
case MFPDTF_RASTER_MMR:
3097
pXform->aXformInfo[IP_FAX_FORMAT].dword = IP_FAX_MMR;
3098
ADD_XFORM( X_FAX_DECODE );
3101
case MFPDTF_RASTER_BITMAP:
3102
case MFPDTF_RASTER_GRAYMAP:
3103
case MFPDTF_RASTER_RGB:
3107
case MFPDTF_RASTER_JPEG:
3109
pXform->aXformInfo[IP_JPG_DECODE_FROM_DENALI].dword = hpaio->fromDenali;
3110
ADD_XFORM( X_JPG_DECODE );
3112
pXform->aXformInfo[IP_CNV_COLOR_SPACE_WHICH_CNV].dword = IP_CNV_YCC_TO_SRGB;
3113
pXform->aXformInfo[IP_CNV_COLOR_SPACE_GAMMA].dword = 0x00010000;
3114
ADD_XFORM( X_CNV_COLOR_SPACE );
3117
case MFPDTF_RASTER_YCC411:
3118
case MFPDTF_RASTER_PCL:
3119
case MFPDTF_RASTER_NOT:
3121
/* Skip processing for unknown encodings. */
3122
bug("unknown image encoding sane_start: name=%s sop=%d %s %d\n", hpaio->saneDevice.name,sopEncoding, __FILE__, __LINE__);
3127
if( rService & MFPDTF_RESULT_IMAGE_DATA_PENDING )
3129
/*MfpdtfReadSetTimeout( hpaio->mfpdtf, MFPDTF_LATER_READ_TIMEOUT );*/
3134
hpaio->scanParameters.pixels_per_line = traits.iPixelsPerRow;
3135
hpaio->scanParameters.lines = traits.lNumRows;
3137
if( hpaio->scanParameters.lines < 0 )
3139
hpaio->scanParameters.lines = MILLIMETERS_TO_PIXELS( hpaio->bryRange.max,
3140
hpaio->effectiveResolution );
3143
// if( hpaio->scannerType == SCANNER_TYPE_SCL )
3145
/* We have to invert bilevel data from SCL scanners. */
3146
if( hpaio->effectiveScanMode == SCAN_MODE_LINEART )
3148
ADD_XFORM( X_INVERT );
3150
else /* if (hpaio->effectiveScanMode==SCAN_MODE_COLOR) */
3152
/* Do gamma correction on OfficeJet Pro 11xx. */
3153
if( hpaio->scl.compat & ( SCL_COMPAT_1150 | SCL_COMPAT_1170 ) )
3155
pXform->aXformInfo[IP_TABLE_WHICH].dword = IP_TABLE_USER;
3156
pXform->aXformInfo[IP_TABLE_OPTION].pvoid = ( char * )hp11xxSeriesGammaTable;
3157
ADD_XFORM( X_TABLE );
3161
if( hpaio->currentLengthMeasurement == LENGTH_MEASUREMENT_PADDED )
3163
pXform->aXformInfo[IP_PAD_LEFT].dword = 0;
3164
pXform->aXformInfo[IP_PAD_RIGHT].dword = 0;
3165
pXform->aXformInfo[IP_PAD_TOP].dword = 0;
3166
pXform->aXformInfo[IP_PAD_BOTTOM].dword = 0;
3167
pXform->aXformInfo[IP_PAD_VALUE].dword = ( hpaio->effectiveScanMode == SCAN_MODE_LINEART ) ? PAD_VALUE_LINEART : PAD_VALUE_GRAYSCALE_COLOR;
3168
pXform->aXformInfo[IP_PAD_MIN_HEIGHT].dword = hpaio->scanParameters.lines;
3172
/* If we didn't set up any xforms by now, then add the dummy "skel" xform to simplify our subsequent code path. */
3173
if( pXform == xforms )
3175
ADD_XFORM( X_SKEL );
3178
wResult = ipOpen( pXform - xforms, xforms, 0, &hpaio->hJob );
3180
if( wResult != IP_DONE || !hpaio->hJob )
3182
retcode = SANE_STATUS_INVAL;
3186
traits.iComponentsPerPixel = ( ( traits.iBitsPerPixel % 3 ) ? 1 : 3 );
3187
wResult = ipSetDefaultInputTraits( hpaio->hJob, &traits );
3189
if( wResult != IP_DONE )
3191
retcode = SANE_STATUS_INVAL;
3195
hpaio->scanParameters.bytes_per_line = BYTES_PER_LINE( hpaio->scanParameters.pixels_per_line,
3196
hpaio->scanParameters.depth * ( hpaio->scanParameters.format == SANE_FRAME_RGB ? 3 : 1 ) );
3198
hpaio->totalBytesRemaining = hpaio->scanParameters.bytes_per_line * hpaio->scanParameters.lines;
3199
hpaio->bufferOffset = 0;
3200
hpaio->bufferBytesRemaining = 0;
3202
if( hpaio->currentLengthMeasurement == LENGTH_MEASUREMENT_UNKNOWN || hpaio->currentLengthMeasurement == LENGTH_MEASUREMENT_UNLIMITED )
3204
hpaio->scanParameters.lines = -1;
3206
else if( hpaio->currentLengthMeasurement == LENGTH_MEASUREMENT_EXACT )
3208
/* TODO: Set up spool file, scan the whole image into it,
3209
* and set "hpaio->scanParameters.lines" accordingly.
3210
* Then in sane_hpaio_read, read out of the file. */
3213
retcode = SANE_STATUS_GOOD;
3217
if( retcode != SANE_STATUS_GOOD )
3219
if (retcode == SANE_STATUS_NO_DOCS) SendScanEvent (hpaio->deviceuri, EVENT_SCAN_ADF_NO_DOCS);
3220
sane_hpaio_cancel( handle );
3224
} /* sane_hpaio_start() */
3227
extern SANE_Status sane_hpaio_read(SANE_Handle handle, SANE_Byte *data, SANE_Int maxLength, SANE_Int *pLength)
3229
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
3230
SANE_Status retcode;
3233
DWORD dwInputUsed, dwInputNextPos;
3234
DWORD dwOutputAvail = maxLength;
3235
LPBYTE pbOutputBuf = data;
3236
DWORD dwOutputUsed, dwOutputThisPos;
3239
if (strcmp(*((char **)handle), "LEDM") == 0)
3240
return ledm_read(handle, data, maxLength, pLength);
3241
if (strcmp(*((char **)handle), "MARVELL") == 0)
3242
return marvell_read(handle, data, maxLength, pLength);
3243
if (strcmp(*((char **)handle), "SOAP") == 0)
3244
return soap_read(handle, data, maxLength, pLength);
3245
if (strcmp(*((char **)handle), "SOAPHT") == 0)
3246
return soapht_read(handle, data, maxLength, pLength);
3248
if (hpaio->user_cancel) {
3249
bug("sane_hpaio_read(maxLength=%d): User cancelled!\n", maxLength);
3250
return SANE_STATUS_CANCELLED;
3257
bug("sane_hpaio_read(maxLength=%d): No scan pending!\n", maxLength);
3258
retcode = SANE_STATUS_EOF;
3262
if (hpaio->scannerType==SCANNER_TYPE_PML)
3264
retcode = pml_read(hpaio, data, maxLength, pLength);
3268
DBG(8, "sane_hpaio_read called handle=%p data=%p maxLength=%d length=%d: %s %d\n", (void *)handle, data, maxLength, *pLength, __FILE__, __LINE__);
3270
/* TODO: convert to scl_read. des */
3273
if( hpaio->bufferBytesRemaining <= 0 && !hpaio->endOfData )
3275
if( !hpaio->mfpdtf )
3277
int r, len = hpaio->totalBytesRemaining;
3280
hpaio->endOfData = 1;
3284
if( len > LEN_BUFFER )
3289
r = ReadChannelEx(hpaio->deviceid,
3290
hpaio->scan_channelid,
3297
retcode = SANE_STATUS_IO_ERROR;
3300
hpaio->bufferBytesRemaining = r;
3301
hpaio->totalBytesRemaining -= r;
3309
rService = MfpdtfReadService( hpaio->mfpdtf );
3311
if( rService & MFPDTF_RESULT_ERROR_MASK )
3313
// retcode = SANE_STATUS_IO_ERROR;
3315
hpaio->endOfData = 1; /* display any data (ie: OJ F380 1200dpi non-compressed can timeout after last scan). */
3318
if( rService & MFPDTF_RESULT_IMAGE_DATA_PENDING )
3320
hpaio->bufferBytesRemaining = MfpdtfReadInnerBlock( hpaio->mfpdtf, hpaio->inBuffer, LEN_BUFFER );
3322
rService = MfpdtfReadGetLastServiceResult( hpaio->mfpdtf );
3324
if( rService & MFPDTF_RESULT_ERROR_MASK )
3326
retcode = SANE_STATUS_IO_ERROR;
3330
else if( rService & MFPDTF_RESULT_NEW_END_OF_PAGE_RECORD || ( rService & MFPDTF_RESULT_END_PAGE && hpaio->preDenali ))
3332
hpaio->endOfData = 1;
3335
} /* if (!hpaio->mfpdtf) */
3337
hpaio->bufferOffset = 0;
3338
if( hpaio->preDenali )
3340
ipMirrorBytes( hpaio->inBuffer, hpaio->bufferBytesRemaining );
3343
} /* if( hpaio->bufferBytesRemaining <= 0 && !hpaio->endOfData ) */
3345
dwInputAvail = hpaio->bufferBytesRemaining;
3347
if( hpaio->bufferBytesRemaining <= 0 && hpaio->endOfData )
3353
pbInputBuf = hpaio->inBuffer + hpaio->bufferOffset;
3356
wResult = ipConvert( hpaio->hJob,
3366
hpaio->bufferOffset += dwInputUsed;
3367
hpaio->bufferBytesRemaining -= dwInputUsed;
3368
*pLength = dwOutputUsed;
3370
if( wResult & ( IP_INPUT_ERROR | IP_FATAL_ERROR ) )
3372
bug("ipConvert error=%x\n", wResult);
3373
retcode = SANE_STATUS_IO_ERROR;
3378
if( wResult & IP_DONE )
3380
retcode = SANE_STATUS_EOF;
3381
// hpaioAdvanceDocument(hpaio);
3382
ipClose(hpaio->hJob);
3389
retcode = SANE_STATUS_GOOD;
3392
if(!(retcode == SANE_STATUS_GOOD || retcode == SANE_STATUS_EOF))
3394
sane_hpaio_cancel( handle );
3397
DBG(8, "sane_hpaio_read returned output=%p outputUsed=%d length=%d status=%d: %s %d\n", pbOutputBuf, dwOutputUsed, *pLength, retcode, __FILE__, __LINE__);
3401
} /* sane_hpaio_read() */
3403
/* Note, sane_cancel is called normally not just during IO abort situations. */
3404
extern void sane_hpaio_cancel( SANE_Handle handle )
3406
hpaioScanner_t hpaio = ( hpaioScanner_t ) handle;
3407
DBG(8, "sane_hpaio_cancel(): %s %d\n", __FILE__, __LINE__);
3408
if (strcmp(*((char **)handle), "MARVELL") == 0)
3409
return marvell_cancel(handle);
3410
if (strcmp(*((char **)handle), "SOAP") == 0)
3411
return soap_cancel(handle);
3412
if (strcmp(*((char **)handle), "SOAPHT") == 0)
3413
return soapht_cancel(handle);
3414
if (strcmp(*((char **)handle), "LEDM") == 0)
3415
return ledm_cancel(handle);
3417
if (hpaio->user_cancel) {
3418
bug("sane_hpaio_cancel: already cancelled!\n");
3420
hpaio->user_cancel = TRUE;
3422
if (hpaio->scannerType==SCANNER_TYPE_PML)
3428
/* TODO: convert to scl_cancel. des */
3432
MfpdtfLogToFile( hpaio->mfpdtf, 0 );
3433
//MfpdtfDeallocate( hpaio->mfpdtf );
3438
ipClose( hpaio->hJob );
3442
/* Do not close pml/scan channels if in batch mode. */
3443
if (hpaio->currentBatchScan != SANE_TRUE && hpaio->cmd_channelid > 0)
3444
hpaioConnEndScan(hpaio);
3446
} /* sane_hpaio_cancel() */
3448
extern SANE_Status sane_hpaio_set_io_mode(SANE_Handle handle, SANE_Bool nonBlocking)
3450
return SANE_STATUS_UNSUPPORTED;
3453
extern SANE_Status sane_hpaio_get_select_fd(SANE_Handle handle, SANE_Int *pFd)
3455
return SANE_STATUS_UNSUPPORTED;