brother_mfp: Added support for source option.

Can now select Flatbed or ADF for supported machines.
brother_mfp_backend
Ralph Little 2022-11-19 14:20:00 -08:00
rodzic ca760d54b3
commit b64b8c13bb
7 zmienionych plików z 514 dodań i 155 usunięć

Wyświetl plik

@ -39,19 +39,20 @@
#define CAP_MODE_GRAY_DITHER (1u << 2)
#define CAP_MODE_BW (1u << 3)
#define CAP_MODE_BUTTON_SCAN_EMAIL (1u << 4)
#define CAP_MODE_BUTTON_SCAN_OCR (1u << 5)
#define CAP_MODE_BUTTON_SCAN_FILE (1u << 6)
#define CAP_MODE_BUTTON_SCAN_IMAGE (1u << 7)
#define CAP_BUTTON_HAS_SCAN_EMAIL (1u << 4)
#define CAP_BUTTON_HAS_SCAN_OCR (1u << 5)
#define CAP_BUTTON_HAS_SCAN_FILE (1u << 6)
#define CAP_BUTTON_HAS_SCAN_IMAGE (1u << 7)
#define CAP_MODE_HAS_ADF (1u << 8)
#define CAP_MODE_HAS_ADF_IS_DUPLEX (1u << 9)
#define CAP_SOURCE_HAS_FLATBED (1u << 8)
#define CAP_SOURCE_HAS_ADF (1u << 9)
#define CAP_SOURCE_HAS_ADF_DUPLEX (1u << 10)
#define CAP_MODE_HAS_RAW (1u << 10)
#define CAP_MODE_HAS_JPEG (1u << 11)
#define CAP_ENCODING_HAS_RAW (1u << 11)
#define CAP_ENCODING_HAS_JPEG (1u << 12)
// Oddities of particular models.
#define CAP_MODE_RAW_IS_CrYCb (1u << 12)
#define CAP_ENCODING_RAW_IS_CrYCb (1u << 13)
/*
* Diagnostic levels.

Wyświetl plik

@ -418,7 +418,8 @@ SANE_Status BrotherUSBDriver::ReadScanData (SANE_Byte *data, size_t max_length,
res = encoder->DecodeStatusToSaneStatus(dec_ret);
if ((dec_ret == DECODE_STATUS_ENDOFDATA) || (dec_ret == DECODE_STATUS_ENDOFFRAME_NO_MORE))
if ((dec_ret == DECODE_STATUS_ENDOFDATA) || (dec_ret == DECODE_STATUS_ENDOFFRAME_NO_MORE)
|| (dec_ret == DECODE_STATUS_NO_DOCS))
{
next_frame_number++;
out_of_docs = true;
@ -850,23 +851,17 @@ SANE_Status BrotherUSBDriver::StartScan ()
}
/*
* Construct the "ADF" block.
*
* This is a query to see if the ADF contains documents.
* TBH I don't really know why we would do this because the source
* (flatbed/ADF) selection seems to be automatic. Perhaps there is a way
* to select the source that we haven't seen to override that behaviour?
* I add it here for completeness though.
* Construct the Source select block.
*
*/
packet_len = 0;
dec_ret = encoder->EncodeADFBlock (small_buffer, sizeof(small_buffer), &packet_len);
dec_ret = encoder->EncodeSourceSelectBlock (small_buffer, sizeof(small_buffer), &packet_len);
if (dec_ret != DECODE_STATUS_UNSUPPORTED)
{
if (dec_ret != DECODE_STATUS_GOOD)
{
DBG (DBG_SERIOUS,
"BrotherUSBDriver::StartScan: failed to generate ADF block: %d\n",
"BrotherUSBDriver::StartScan: failed to generate source select block: %d\n",
dec_ret);
(void) CancelScan ();
return SANE_STATUS_INVAL;
@ -876,14 +871,14 @@ SANE_Status BrotherUSBDriver::StartScan ()
res = sanei_usb_write_bulk (fd, small_buffer, &buf_size);
if (res != SANE_STATUS_GOOD)
{
DBG (DBG_SERIOUS, "BrotherUSBDriver::StartScan: failed to send ADF block: %d\n", res);
DBG (DBG_SERIOUS, "BrotherUSBDriver::StartScan: failed to send source select block: %d\n", res);
(void) CancelScan ();
return res;
}
if (buf_size != packet_len)
{
DBG (DBG_SERIOUS, "BrotherUSBDriver::StartScan: failed to write ADF block\n");
DBG (DBG_SERIOUS, "BrotherUSBDriver::StartScan: failed to write source select block\n");
(void) CancelScan ();
return SANE_STATUS_IO_ERROR;
}
@ -899,27 +894,27 @@ SANE_Status BrotherUSBDriver::StartScan ()
if (res != SANE_STATUS_GOOD)
{
DBG (DBG_SERIOUS,
"BrotherUSBDriver::StartScan: failed to read ADF block response: %d\n",
"BrotherUSBDriver::StartScan: failed to read source select block response: %d\n",
res);
(void) CancelScan ();
return res;
}
BrotherADFResponse adf_resp;
BrotherSourceStatusResponse source_resp;
dec_ret = encoder->DecodeADFBlockResp (small_buffer, buf_size, adf_resp);
dec_ret = encoder->DecodeSourceStatusBlockResp (small_buffer, buf_size, source_resp);
if (dec_ret != DECODE_STATUS_GOOD)
{
DBG (DBG_SERIOUS,
"BrotherUSBDriver::StartScan: ADF block response block invalid: %d\n",
"BrotherUSBDriver::StartScan: source select response block invalid: %d\n",
dec_ret);
(void) CancelScan ();
return encoder->DecodeStatusToSaneStatus(dec_ret);
}
DBG (DBG_DETAIL,
"BrotherUSBDriver::StartScan: ADF reports readiness?: %s\n",
adf_resp.adf_ready? "Yes": "No");
"BrotherUSBDriver::StartScan: Source reports readiness?: %s\n",
source_resp.source_ready? "Yes": "No");
}
/*

Wyświetl plik

@ -105,6 +105,11 @@ public:
* Parameter setting.
*
*/
SANE_Status SetSource (BrotherSource source)
{
return encoder->DecodeStatusToSaneStatus (encoder->SetSource (source));
}
SANE_Status SetScanMode (BrotherScanMode scan_mode)
{
return encoder->DecodeStatusToSaneStatus (encoder->SetScanMode (scan_mode));
@ -144,7 +149,6 @@ protected:
BrotherFamily family;
SANE_Word capabilities;
BrotherParameters scan_params;
BrotherEncoder *encoder;
};

Wyświetl plik

@ -78,6 +78,11 @@
// unsure as to the meaning of this or how to get it again.
#define BROTHER_DATA_BLOCK_CLEARING_PAPER 0xc5
/*
* Other protocol error?
*
*/
#define BROTHER_DATA_BLOCK_PROTOCOL_ERROR 0xd0
const char* BrotherEncoder::ScanModeToText (BrotherScanMode scan_mode)
{
@ -87,6 +92,14 @@ const char* BrotherEncoder::ScanModeToText (BrotherScanMode scan_mode)
return scan_mode_text[scan_mode];
}
DecodeStatus BrotherEncoder::SetSource (BrotherSource source)
{
scan_params.param_source = source;
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoder::SetScanMode (BrotherScanMode scan_mode)
{
@ -212,14 +225,14 @@ DecodeStatus BrotherEncoderFamily2::DecodeQueryBlockResp (const SANE_Byte *data,
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily2::EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length)
DecodeStatus BrotherEncoderFamily2::EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::EncodeBasicParameterBlock: ADF block too long for buffer: %zu\n",
"BrotherEncoderFamily2::EncodeBasicParameterBlock: source status too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
@ -227,13 +240,13 @@ DecodeStatus BrotherEncoderFamily2::EncodeADFBlock (SANE_Byte *data, size_t data
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily2::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response)
DecodeStatus BrotherEncoderFamily2::DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
@ -251,11 +264,11 @@ DecodeStatus BrotherEncoderFamily2::DecodeADFBlockResp (const SANE_Byte *data, s
return DECODE_STATUS_COVER_OPEN;
case BROTHER_DATA_BLOCK_NO_DOCS:
response.adf_ready = SANE_FALSE;
response.source_ready = SANE_FALSE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.adf_ready = SANE_TRUE;
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
default:
@ -263,6 +276,54 @@ DecodeStatus BrotherEncoderFamily2::DecodeADFBlockResp (const SANE_Byte *data, s
}
}
DecodeStatus BrotherEncoderFamily2::EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data,
data_len,
"\x1b" "S\n%s\n" "\x80",
scan_params.param_source == BROTHER_SOURCE_FLATBED ? "FB" : "ADF");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::EncodeSourceSelectBlock: Source select block too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily2::DecodeSourceSelectBlockResp (const SANE_Byte *data,
size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source select response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
/*
* We can get error condition codes from this block.
*
*/
switch (data[0])
{
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_PROTOCOL_ERROR:
response.source_ready = SANE_FALSE;
return DECODE_STATUS_INVAL;
default:
return DECODE_STATUS_ERROR;
}
}
DecodeStatus BrotherEncoderFamily2::DecodeSessionResp (const SANE_Byte *data, size_t data_len,
BrotherSessionResponse &response)
@ -493,12 +554,11 @@ DecodeStatus BrotherEncoderFamily2::DecodeScanData (const SANE_Byte *src_data, s
* Detect special case situations.
*
*/
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
if (ret_status != DECODE_STATUS_GOOD)
{
DBG (DBG_IMPORTANT,
"BrotherEncoderFamily2::DecodeScanData: %s detected.\n",
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" : "ENDOFFRAME_WITH_MORE");
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
DecodeStatusToString (ret_status));
current_header.block_type = 0;
@ -682,6 +742,12 @@ DecodeStatus BrotherEncoderFamily2::DecodeScanDataHeader (const SANE_Byte *src_d
header.block_len = 0;
if (header.block_type == BROTHER_DATA_BLOCK_NO_DOCS)
{
*src_data_consumed = 1;
return DECODE_STATUS_NO_DOCS;
}
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
{
*src_data_consumed = 1;
@ -833,14 +899,14 @@ DecodeStatus BrotherEncoderFamily3::DecodeQueryBlockResp (const SANE_Byte *data,
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily3::EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length)
DecodeStatus BrotherEncoderFamily3::EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily3::EncodeBasicParameterBlock: ADF block too long for buffer: %zu\n",
"BrotherEncoderFamily3::EncodeBasicParameterBlock: source status too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
@ -848,13 +914,13 @@ DecodeStatus BrotherEncoderFamily3::EncodeADFBlock (SANE_Byte *data, size_t data
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily3::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response)
DecodeStatus BrotherEncoderFamily3::DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
@ -872,11 +938,11 @@ DecodeStatus BrotherEncoderFamily3::DecodeADFBlockResp (const SANE_Byte *data, s
return DECODE_STATUS_COVER_OPEN;
case BROTHER_DATA_BLOCK_NO_DOCS:
response.adf_ready = SANE_FALSE;
response.source_ready = SANE_FALSE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.adf_ready = SANE_TRUE;
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
default:
@ -884,6 +950,55 @@ DecodeStatus BrotherEncoderFamily3::DecodeADFBlockResp (const SANE_Byte *data, s
}
}
DecodeStatus BrotherEncoderFamily3::EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data,
data_len,
"\x1b" "S\n%s\n" "\x80",
scan_params.param_source == BROTHER_SOURCE_FLATBED ? "FB" : "ADF");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily3::EncodeSourceSelectBlock: Source select block too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily3::DecodeSourceSelectBlockResp (const SANE_Byte *data,
size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily3::DecodeSourceStatusBlockResp: source select response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
/*
* We can get error condition codes from this block.
*
*/
switch (data[0])
{
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_PROTOCOL_ERROR:
response.source_ready = SANE_FALSE;
return DECODE_STATUS_INVAL;
default:
return DECODE_STATUS_ERROR;
}
}
DecodeStatus BrotherEncoderFamily3::DecodeSessionResp (const SANE_Byte *data, size_t data_len,
BrotherSessionResponse &response)
{
@ -1113,12 +1228,11 @@ DecodeStatus BrotherEncoderFamily3::DecodeScanData (const SANE_Byte *src_data, s
* Detect special case situations.
*
*/
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
if (ret_status != DECODE_STATUS_GOOD)
{
DBG (DBG_IMPORTANT,
"BrotherEncoderFamily3::DecodeScanData: %s.\n",
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" : "ENDOFFRAME_WITH_MORE");
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
DecodeStatusToString (ret_status));
current_header.block_type = 0;
@ -1312,6 +1426,12 @@ DecodeStatus BrotherEncoderFamily3::DecodeScanDataHeader (const SANE_Byte *src_d
header.block_len = 0;
if (header.block_type == BROTHER_DATA_BLOCK_NO_DOCS)
{
*src_data_consumed = 1;
return DECODE_STATUS_NO_DOCS;
}
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
{
*src_data_consumed = 1;
@ -1567,14 +1687,14 @@ DecodeStatus BrotherEncoderFamily4::DecodeBasicParameterBlockResp (const SANE_By
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily4::EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length)
DecodeStatus BrotherEncoderFamily4::EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily4::EncodeBasicParameterBlock: ADF block too long for buffer: %zu\n",
"BrotherEncoderFamily4::EncodeSourceStatusBlock: Source status block too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
@ -1582,13 +1702,14 @@ DecodeStatus BrotherEncoderFamily4::EncodeADFBlock (SANE_Byte *data, size_t data
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily4::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response)
DecodeStatus BrotherEncoderFamily4::DecodeSourceStatusBlockResp (const SANE_Byte *data,
size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
@ -1606,11 +1727,11 @@ DecodeStatus BrotherEncoderFamily4::DecodeADFBlockResp (const SANE_Byte *data, s
return DECODE_STATUS_COVER_OPEN;
case BROTHER_DATA_BLOCK_NO_DOCS:
response.adf_ready = SANE_FALSE;
response.source_ready = SANE_FALSE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.adf_ready = SANE_TRUE;
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
default:
@ -1618,6 +1739,55 @@ DecodeStatus BrotherEncoderFamily4::DecodeADFBlockResp (const SANE_Byte *data, s
}
}
DecodeStatus BrotherEncoderFamily4::EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length)
{
*length = snprintf ((char*) data,
data_len,
"\x1b" "S\n%s\n" "\x80",
scan_params.param_source == BROTHER_SOURCE_FLATBED ? "FB" : "ADF");
if (*length > data_len)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily4::EncodeSourceSelectBlock: Source select block too long for buffer: %zu\n",
*length);
return DECODE_STATUS_INVAL;
}
return DECODE_STATUS_GOOD;
}
DecodeStatus BrotherEncoderFamily4::DecodeSourceSelectBlockResp (const SANE_Byte *data,
size_t data_len,
BrotherSourceStatusResponse &response)
{
if (data_len != 1)
{
DBG (DBG_SERIOUS,
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source select response invalid: %zu\n",
data_len);
return DECODE_STATUS_ERROR;
}
/*
* We can get error condition codes from this block.
*
*/
switch (data[0])
{
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
response.source_ready = SANE_TRUE;
return DECODE_STATUS_GOOD;
case BROTHER_DATA_BLOCK_PROTOCOL_ERROR:
response.source_ready = SANE_FALSE;
return DECODE_STATUS_INVAL;
default:
return DECODE_STATUS_ERROR;
}
}
DecodeStatus BrotherEncoderFamily4::EncodeParameterBlockBlank (SANE_Byte *data, size_t data_len,
size_t *length)
{
@ -1753,15 +1923,11 @@ DecodeStatus BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, s
* Detect special case situations.
*
*/
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|| (ret_status == DECODE_STATUS_ENDOFFRAME_NO_MORE)
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
if (ret_status != DECODE_STATUS_GOOD)
{
DBG (DBG_IMPORTANT,
"BrotherEncoderFamily4::DecodeScanData: %s.\n",
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" :
ret_status == DECODE_STATUS_ENDOFFRAME_NO_MORE ?
"ENDOFFRAME_NO_MORE" : "ENDOFFRAME_WITH_MORE");
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
DecodeStatusToString (ret_status));
current_header.block_type = 0;
@ -1935,6 +2101,12 @@ DecodeStatus BrotherEncoderFamily4::DecodeScanDataHeader (const SANE_Byte *src_d
header.block_len = 0;
if (header.block_type == BROTHER_DATA_BLOCK_NO_DOCS)
{
*src_data_consumed = 1;
return DECODE_STATUS_NO_DOCS;
}
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
{
*src_data_consumed = 1;
@ -2304,7 +2476,7 @@ DecodeStatus BrotherInterleavedRGBColourDecoder::DecodeScanData (const SANE_Byte
* Sort out the raw encoding format.
*
*/
if (capabilities & CAP_MODE_RAW_IS_CrYCb)
if (capabilities & CAP_ENCODING_RAW_IS_CrYCb)
{
SANE_Byte R;
SANE_Byte G;

Wyświetl plik

@ -82,6 +82,13 @@ typedef enum
BROTHER_SCAN_MODE_TEXT
} BrotherScanMode;
typedef enum
{
BROTHER_SOURCE_FLATBED,
BROTHER_SOURCE_ADF,
} BrotherSource;
typedef SANE_Int BrotherSensor;
#define BROTHER_SENSOR_NONE 0
@ -116,6 +123,7 @@ struct BrotherParameters
param_pixel_y_offset (0),
param_pixel_y_height (0),
param_scan_mode (BROTHER_SCAN_MODE_COLOR),
param_source(BROTHER_SOURCE_FLATBED),
param_x_res(100),
param_y_res(100)
{
@ -130,6 +138,7 @@ struct BrotherParameters
SANE_Int param_pixel_y_height;
BrotherScanMode param_scan_mode;
BrotherSource param_source;
SANE_Int param_x_res;
SANE_Int param_y_res;
@ -148,9 +157,9 @@ struct BrotherQueryResponse
// fill me
};
struct BrotherADFResponse
struct BrotherSourceStatusResponse
{
SANE_Bool adf_ready;
SANE_Bool source_ready;
};
@ -173,6 +182,7 @@ enum DecodeStatus
DECODE_STATUS_UNSUPPORTED,
DECODE_STATUS_PAPER_JAM,
DECODE_STATUS_COVER_OPEN,
DECODE_STATUS_NO_DOCS,
};
struct ScanDataHeader
@ -199,6 +209,7 @@ public:
virtual void NewPage () = 0;
DecodeStatus SetSource (BrotherSource source);
DecodeStatus SetScanMode (BrotherScanMode scan_mode);
DecodeStatus SetRes (SANE_Int x, SANE_Int y);
DecodeStatus SetContrast (SANE_Int contrast);
@ -224,6 +235,29 @@ public:
SANE_STATUS_UNSUPPORTED,
SANE_STATUS_JAMMED,
SANE_STATUS_COVER_OPEN,
SANE_STATUS_NO_DOCS,
};
return status_lookup[dec_ret];
}
const char *DecodeStatusToString(DecodeStatus dec_ret)
{
static const char * status_lookup[] =
{
"DECODE_STATUS_GOOD",
"DECODE_STATUS_TRUNCATED",
"DECODE_STATUS_ENDOFDATA",
"DECODE_STATUS_ENDOFFRAME_NO_MORE",
"DECODE_STATUS_ENDOFFRAME_WITH_MORE",
"DECODE_STATUS_CANCEL",
"DECODE_STATUS_ERROR",
"DECODE_STATUS_MEMORY",
"DECODE_STATUS_INVAL",
"DECODE_STATUS_UNSUPPORTED",
"DECODE_STATUS_PAPER_JAM",
"DECODE_STATUS_COVER_OPEN",
"DECODE_STATUS_NO_DOCS",
};
return status_lookup[dec_ret];
@ -254,10 +288,15 @@ public:
virtual DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
BrotherBasicParamResponse &response) = 0;
virtual DecodeStatus EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length) = 0;
virtual DecodeStatus EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length) = 0;
virtual DecodeStatus DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response) = 0;
virtual DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) = 0;
virtual DecodeStatus EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length) = 0;
virtual DecodeStatus DecodeSourceSelectBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) = 0;
virtual DecodeStatus EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) = 0;
@ -462,10 +501,15 @@ public:
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
BrotherBasicParamResponse &response) override;
DecodeStatus EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response) override;
DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeSourceSelectBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
@ -530,10 +574,16 @@ public:
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
BrotherBasicParamResponse &response) override;
DecodeStatus EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeSourceSelectBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response) override;
DecodeStatus EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus EncodeParameterBlockBlank (SANE_Byte *data, size_t data_len, size_t *length)
@ -596,10 +646,15 @@ public:
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
BrotherBasicParamResponse &response) override;
DecodeStatus EncodeADFBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus EncodeSourceStatusBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
BrotherADFResponse &response) override;
DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus EncodeSourceSelectBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
DecodeStatus DecodeSourceSelectBlockResp (const SANE_Byte *data, size_t data_len,
BrotherSourceStatusResponse &response) override;
DecodeStatus EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) override;

Wyświetl plik

@ -53,7 +53,10 @@
* Messages.
*
*/
#define SANE_VALUE_SCAN_MODE_GRAY_DITHER SANE_I18N("Gray (Dithered)")
#define SANE_VALUE_SCAN_MODE_GRAY_DITHER SANE_I18N("Gray (Dithered)")
#define SANE_VALUE_SOURCE_FLATBED SANE_I18N("Flatbed")
#define SANE_VALUE_SOURCE_ADF SANE_I18N("Automatic Document Feeder")
#define SANE_NAME_FILE_BUTTON "file-sensor"
#define SANE_NAME_EMAIL_BUTTON "email-sensor"
@ -81,6 +84,7 @@ enum Brother_Option
OPT_NUM_OPTS = 0,
OPT_MODE_GROUP,
OPT_SOURCE,
OPT_MODE,
OPT_SPLIT_RESOLUTION,
OPT_RESOLUTION,
@ -139,14 +143,15 @@ static Brother_Model models[] =
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_MODE_BUTTON_SCAN_EMAIL |
CAP_MODE_BUTTON_SCAN_FILE |
CAP_MODE_BUTTON_SCAN_OCR |
CAP_MODE_BUTTON_SCAN_IMAGE |
CAP_MODE_HAS_ADF |
CAP_MODE_RAW_IS_CrYCb |
CAP_MODE_HAS_RAW |
CAP_MODE_HAS_JPEG },
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_SOURCE_HAS_ADF |
CAP_SOURCE_HAS_FLATBED |
CAP_ENCODING_RAW_IS_CrYCb |
CAP_ENCODING_HAS_RAW |
CAP_ENCODING_HAS_JPEG },
{ "Brother", "DCP-7030", BROTHER_FAMILY_3, 0x04f9, 0x01ea,
{ 0, SANE_FIX(210), 0 },
@ -157,12 +162,13 @@ static Brother_Model models[] =
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_MODE_BUTTON_SCAN_EMAIL |
CAP_MODE_BUTTON_SCAN_FILE |
CAP_MODE_BUTTON_SCAN_OCR |
CAP_MODE_BUTTON_SCAN_IMAGE |
CAP_MODE_HAS_RAW |
CAP_MODE_HAS_JPEG},
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_SOURCE_HAS_FLATBED |
CAP_ENCODING_HAS_RAW |
CAP_ENCODING_HAS_JPEG},
// TODO: check dimensions
{ "Brother", "MFC-290C", BROTHER_FAMILY_3, 0x04f9, 0x01fd,
@ -174,13 +180,15 @@ static Brother_Model models[] =
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_MODE_BUTTON_SCAN_EMAIL |
CAP_MODE_BUTTON_SCAN_FILE |
CAP_MODE_BUTTON_SCAN_OCR |
CAP_MODE_BUTTON_SCAN_IMAGE |
CAP_MODE_RAW_IS_CrYCb |
CAP_MODE_HAS_RAW |
CAP_MODE_HAS_JPEG},
CAP_SOURCE_HAS_FLATBED |
CAP_SOURCE_HAS_ADF |
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_ENCODING_RAW_IS_CrYCb |
CAP_ENCODING_HAS_RAW |
CAP_ENCODING_HAS_JPEG},
{ "Brother", "MFC-J4320DW", BROTHER_FAMILY_4, 0x04f9, 0x033a,
{ 0, SANE_FIX(211.5), 0 },
@ -191,11 +199,46 @@ static Brother_Model models[] =
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_MODE_BUTTON_SCAN_EMAIL |
CAP_MODE_BUTTON_SCAN_FILE |
CAP_MODE_BUTTON_SCAN_OCR |
CAP_MODE_BUTTON_SCAN_IMAGE |
CAP_MODE_HAS_JPEG },
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_ENCODING_HAS_JPEG |
CAP_SOURCE_HAS_FLATBED},
{ "Brother", "MFC-J4620DW", BROTHER_FAMILY_4, 0x04f9, 0x0340,
{ 0, SANE_FIX(211.881), 0 },
{ 0, SANE_FIX(355.567), 0 },
{ 6, 100, 150, 200, 300, 600, 1200 },
{ 7, 100, 150, 200, 300, 600, 1200, 2400 },
CAP_MODE_COLOUR |
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_SOURCE_HAS_FLATBED |
CAP_SOURCE_HAS_ADF |
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_ENCODING_HAS_JPEG },
{ "Brother", "ADS-2800W", BROTHER_FAMILY_4, 0x04f9, 0x0340,
{ 0, SANE_FIX(215.000), 0 },
{ 0, SANE_FIX(355.000), 0 },
{ 6, 100, 150, 200, 300, 600 },
{ 6, 100, 150, 200, 300, 600 },
CAP_MODE_COLOUR |
CAP_MODE_GRAY |
CAP_MODE_GRAY_DITHER |
CAP_MODE_BW |
CAP_SOURCE_HAS_FLATBED |
CAP_SOURCE_HAS_ADF |
CAP_BUTTON_HAS_SCAN_EMAIL |
CAP_BUTTON_HAS_SCAN_FILE |
CAP_BUTTON_HAS_SCAN_OCR |
CAP_BUTTON_HAS_SCAN_IMAGE |
CAP_ENCODING_HAS_JPEG },
{NULL, NULL, BROTHER_FAMILY_NONE, 0, 0, {0, 0, 0}, {0, 0, 0}, {0}, {0}, 0}
};
@ -208,6 +251,7 @@ struct BrotherDevice
sane_device {nullptr, nullptr, nullptr, nullptr},
name (nullptr),
modes {0},
sources {0},
params {SANE_FRAME_GRAY, SANE_FALSE, 0, 0, 0, 0},
internal_scan_mode(nullptr),
x_res (0),
@ -228,6 +272,7 @@ struct BrotherDevice
Option_Value val[NUM_OPTIONS];
SANE_String_Const modes[10];
SANE_String_Const sources[10];
SANE_Parameters params;
const char *internal_scan_mode;
SANE_Int x_res;
@ -354,6 +399,20 @@ attach_with_ret (const char *devicename, BrotherDevice **dev)
device->modes[num_modes++] = SANE_VALUE_SCAN_MODE_LINEART;
}
/*
* Create the sources list.
*
*/
size_t num_sources = 0;
if (model->capabilities & CAP_SOURCE_HAS_FLATBED)
{
device->sources[num_sources++] = SANE_VALUE_SOURCE_FLATBED;
}
if (model->capabilities & CAP_SOURCE_HAS_ADF)
{
device->sources[num_sources++] = SANE_VALUE_SOURCE_ADF;
}
++num_devices;
device->next = first_dev;
first_dev = device;
@ -423,6 +482,39 @@ init_options (BrotherDevice *device)
od->constraint.range = 0;
device->val[OPT_MODE_GROUP].w = 0;
/* opt_source */
od = &device->opt[OPT_SOURCE];
od->name = SANE_NAME_SCAN_SOURCE;
od->title = SANE_TITLE_SCAN_SOURCE;
od->desc = SANE_DESC_SCAN_SOURCE;
od->type = SANE_TYPE_STRING;
od->unit = SANE_UNIT_NONE;
od->size = max_string_size (device->sources);
od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
od->constraint.string_list = device->sources;
if (!device->sources[0])
{
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_INACTIVE;
device->val[OPT_SOURCE].s = new char[1];
if (NULL == device->val[OPT_SOURCE].s)
{
DBG (DBG_SERIOUS, "init_options: failed to allocate source storage %zu\n", (size_t) od->size);
return SANE_STATUS_NO_MEM;
}
(void) strcpy (device->val[OPT_SOURCE].s, "");
}
else
{
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
device->val[OPT_SOURCE].s = new char[od->size];
if (NULL == device->val[OPT_SOURCE].s)
{
DBG (DBG_SERIOUS, "init_options: failed to allocate source storage %zu\n", (size_t) od->size);
return SANE_STATUS_NO_MEM;
}
(void) strcpy (device->val[OPT_SOURCE].s, device->sources[0]);
}
/* opt_mode */
od = &device->opt[OPT_MODE];
od->name = SANE_NAME_SCAN_MODE;
@ -622,8 +714,8 @@ init_options (BrotherDevice *device)
od->unit = SANE_UNIT_NONE;
od->size = 1 * sizeof(SANE_Bool);
od->constraint_type = SANE_CONSTRAINT_NONE;
if ((device->model->capabilities & CAP_MODE_HAS_JPEG)
&& (device->model->capabilities & CAP_MODE_HAS_RAW))
if ((device->model->capabilities & CAP_ENCODING_HAS_JPEG)
&& (device->model->capabilities & CAP_ENCODING_HAS_RAW))
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
else
od->cap = SANE_CAP_INACTIVE;
@ -649,7 +741,7 @@ init_options (BrotherDevice *device)
od->type = SANE_TYPE_BOOL;
od->unit = SANE_UNIT_NONE;
od->size = 1 * sizeof(SANE_Bool);
if (device->model->capabilities & CAP_MODE_BUTTON_SCAN_EMAIL)
if (device->model->capabilities & CAP_BUTTON_HAS_SCAN_EMAIL)
od->cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
@ -663,7 +755,7 @@ init_options (BrotherDevice *device)
od->type = SANE_TYPE_BOOL;
od->unit = SANE_UNIT_NONE;
od->size = 1 * sizeof(SANE_Bool);
if (device->model->capabilities & CAP_MODE_BUTTON_SCAN_FILE)
if (device->model->capabilities & CAP_BUTTON_HAS_SCAN_FILE)
od->cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
@ -677,7 +769,7 @@ init_options (BrotherDevice *device)
od->type = SANE_TYPE_BOOL;
od->unit = SANE_UNIT_NONE;
od->size = 1 * sizeof(SANE_Bool);
if (device->model->capabilities & CAP_MODE_BUTTON_SCAN_IMAGE)
if (device->model->capabilities & CAP_BUTTON_HAS_SCAN_IMAGE)
od->cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
@ -691,7 +783,7 @@ init_options (BrotherDevice *device)
od->type = SANE_TYPE_BOOL;
od->unit = SANE_UNIT_NONE;
od->size = 1 * sizeof(SANE_Bool);
if (device->model->capabilities & CAP_MODE_BUTTON_SCAN_OCR)
if (device->model->capabilities & CAP_BUTTON_HAS_SCAN_OCR)
od->cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
else
@ -1078,39 +1170,54 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
status = SANE_STATUS_GOOD;
break;
case OPT_MODE:
if (strcmp (device->val[option].s, (SANE_String)value) == 0)
{
DBG (DBG_DETAIL, "sane_control_option: option %d (%s) not changed\n",
option, device->opt[option].name);
break;
}
strcpy (device->val[option].s, (SANE_String) value);
case OPT_MODE:
if (strcmp (device->val[option].s, (SANE_String)value) == 0)
{
DBG (DBG_DETAIL, "sane_control_option: option %d (%s) not changed\n",
option, device->opt[option].name);
break;
}
strcpy (device->val[option].s, (SANE_String) value);
myinfo |= SANE_INFO_RELOAD_PARAMS;
myinfo |= SANE_INFO_RELOAD_OPTIONS;
DBG (DBG_DETAIL, "sane_control_option: set option %d (%s) to %s\n",
option, device->opt[option].name, (SANE_String) value);
myinfo |= SANE_INFO_RELOAD_PARAMS;
myinfo |= SANE_INFO_RELOAD_OPTIONS;
DBG (DBG_DETAIL, "sane_control_option: set option %d (%s) to %s\n",
option, device->opt[option].name, (SANE_String) value);
/*
* Mode affects other options:
*
* OPT_CONTRAST
* OPT_BRIGHTNESS
*
*/
if ((strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_COLOR) == 0) ||
(strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_GRAY) == 0))
{
/*
* Mode affects other options:
*
* OPT_CONTRAST
* OPT_BRIGHTNESS
*
*/
if ((strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_COLOR) == 0) ||
(strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_GRAY) == 0))
{
device->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
device->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
}
else
{
}
else
{
device->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
device->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
}
break;
}
break;
case OPT_SOURCE:
if (strcmp (device->val[option].s, (SANE_String)value) == 0)
{
DBG (DBG_DETAIL, "sane_control_option: option %d (%s) not changed\n",
option, device->opt[option].name);
break;
}
strcpy (device->val[option].s, (SANE_String) value);
myinfo |= SANE_INFO_RELOAD_PARAMS;
myinfo |= SANE_INFO_RELOAD_OPTIONS;
DBG (DBG_DETAIL, "sane_control_option: set option %d (%s) to %s\n",
option, device->opt[option].name, (SANE_String) value);
break;
default:
DBG (DBG_SERIOUS, "sane_control_option: trying to set unexpected option\n");
@ -1140,11 +1247,12 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
(device->opt[option].unit == SANE_UNIT_DPI ? "dpi" : ""));
break;
}
case OPT_MODE: /* String (list) options */
strcpy ((SANE_String)value, device->val[option].s);
DBG (DBG_DETAIL, "sane_control_option: get option %d (%s), value=`%s'\n",
option, device->opt[option].name, (SANE_String) value);
break;
case OPT_MODE: /* String (list) options */
case OPT_SOURCE:
strcpy ((SANE_String)value, device->val[option].s);
DBG (DBG_DETAIL, "sane_control_option: get option %d (%s), value=`%s'\n",
option, device->opt[option].name, (SANE_String) value);
break;
case OPT_RESOLUTION:
case OPT_X_RESOLUTION:
@ -1273,6 +1381,29 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
}
}
/*
* Get the source from the option.
* Also note if we are doing centered geometry.
*
*/
if (strcmp(device->val[OPT_SOURCE].s, SANE_VALUE_SOURCE_FLATBED) == 0)
{
rc = device->driver->SetSource(BROTHER_SOURCE_FLATBED);
if (rc != SANE_STATUS_GOOD)
{
return rc;
}
}
else if (strcmp(device->val[OPT_SOURCE].s, SANE_VALUE_SOURCE_ADF) == 0)
{
rc = device->driver->SetSource(BROTHER_SOURCE_ADF);
if (rc != SANE_STATUS_GOOD)
{
return rc;
}
}
/*
* Compute the geometry in terms of pixels at the selected resolution.
* This is how the scanner wants it.
@ -1289,13 +1420,14 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
*/
// pixel_x_width += 16;
SANE_Int pixel_x_offset = SANE_UNFIX (device->val[OPT_TL_X].w) / MM_IN_INCH * x_res;
SANE_Int pixel_y_height = SANE_UNFIX (device->val[OPT_BR_Y].w -
device->val[OPT_TL_Y].w) / MM_IN_INCH * y_res;
SANE_Int pixel_x_offset = SANE_UNFIX (device->val[OPT_TL_X].w) / MM_IN_INCH * x_res;
SANE_Int pixel_y_offset = SANE_UNFIX (device->val[OPT_TL_Y].w) / MM_IN_INCH * y_res;
params->lines = pixel_y_height;
params->last_frame = SANE_TRUE;

Wyświetl plik

@ -101,28 +101,28 @@ static void test_family4_decode_basic_param_resp()
static void test_family4_decode_adf_resp()
{
DecodeStatus decode_resp;
BrotherADFResponse adf_resp;
BrotherSourceStatusResponse adf_resp;
BrotherEncoderFamily4 encoder(0);
// SUCCESS status
const SANE_Byte *data = (const SANE_Byte *)"\xc2";
decode_resp = encoder.DecodeADFBlockResp (data, 1, adf_resp);
decode_resp = encoder.DecodeSourceStatusBlockResp (data, 1, adf_resp);
ASSERT_EQ(decode_resp, DECODE_STATUS_GOOD);
ASSERT_FALSE(adf_resp.adf_ready);
ASSERT_FALSE(adf_resp.source_ready);
data = (const SANE_Byte *)"\x80";
decode_resp = encoder.DecodeADFBlockResp (data, 1, adf_resp);
decode_resp = encoder.DecodeSourceStatusBlockResp (data, 1, adf_resp);
ASSERT_EQ(decode_resp, DECODE_STATUS_GOOD);
ASSERT_TRUE(adf_resp.adf_ready);
ASSERT_TRUE(adf_resp.source_ready);
// Wrong length.
decode_resp = encoder.DecodeADFBlockResp (data, 0, adf_resp);
decode_resp = encoder.DecodeSourceStatusBlockResp (data, 0, adf_resp);
ASSERT_EQ(decode_resp, DECODE_STATUS_ERROR);
decode_resp = encoder.DecodeADFBlockResp (data, 20, adf_resp);
decode_resp = encoder.DecodeSourceStatusBlockResp (data, 20, adf_resp);
ASSERT_EQ(decode_resp, DECODE_STATUS_ERROR);
}
@ -376,7 +376,7 @@ static void test_family4_encode_adf()
BrotherEncoderFamily4 encoder(0);
// Standard call.
decode_resp = encoder.EncodeADFBlock (data_buffer, sizeof(data_buffer), &ret_length);
decode_resp = encoder.EncodeSourceStatusBlock (data_buffer, sizeof(data_buffer), &ret_length);
ASSERT_EQ(decode_resp, DECODE_STATUS_GOOD);
@ -387,7 +387,7 @@ static void test_family4_encode_adf()
}
// Buffer too short.
decode_resp = encoder.EncodeADFBlock (data_buffer, 5, &ret_length);
decode_resp = encoder.EncodeSourceStatusBlock (data_buffer, 5, &ret_length);
ASSERT_EQ(decode_resp, DECODE_STATUS_INVAL);
}