kopia lustrzana https://gitlab.com/sane-project/backends
brother_mfp: Added support for source option.
Can now select Flatbed or ADF for supported machines.brother_mfp_backend
rodzic
ca760d54b3
commit
b64b8c13bb
|
@ -39,19 +39,20 @@
|
||||||
#define CAP_MODE_GRAY_DITHER (1u << 2)
|
#define CAP_MODE_GRAY_DITHER (1u << 2)
|
||||||
#define CAP_MODE_BW (1u << 3)
|
#define CAP_MODE_BW (1u << 3)
|
||||||
|
|
||||||
#define CAP_MODE_BUTTON_SCAN_EMAIL (1u << 4)
|
#define CAP_BUTTON_HAS_SCAN_EMAIL (1u << 4)
|
||||||
#define CAP_MODE_BUTTON_SCAN_OCR (1u << 5)
|
#define CAP_BUTTON_HAS_SCAN_OCR (1u << 5)
|
||||||
#define CAP_MODE_BUTTON_SCAN_FILE (1u << 6)
|
#define CAP_BUTTON_HAS_SCAN_FILE (1u << 6)
|
||||||
#define CAP_MODE_BUTTON_SCAN_IMAGE (1u << 7)
|
#define CAP_BUTTON_HAS_SCAN_IMAGE (1u << 7)
|
||||||
|
|
||||||
#define CAP_MODE_HAS_ADF (1u << 8)
|
#define CAP_SOURCE_HAS_FLATBED (1u << 8)
|
||||||
#define CAP_MODE_HAS_ADF_IS_DUPLEX (1u << 9)
|
#define CAP_SOURCE_HAS_ADF (1u << 9)
|
||||||
|
#define CAP_SOURCE_HAS_ADF_DUPLEX (1u << 10)
|
||||||
|
|
||||||
#define CAP_MODE_HAS_RAW (1u << 10)
|
#define CAP_ENCODING_HAS_RAW (1u << 11)
|
||||||
#define CAP_MODE_HAS_JPEG (1u << 11)
|
#define CAP_ENCODING_HAS_JPEG (1u << 12)
|
||||||
|
|
||||||
// Oddities of particular models.
|
// Oddities of particular models.
|
||||||
#define CAP_MODE_RAW_IS_CrYCb (1u << 12)
|
#define CAP_ENCODING_RAW_IS_CrYCb (1u << 13)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Diagnostic levels.
|
* Diagnostic levels.
|
||||||
|
|
|
@ -418,7 +418,8 @@ SANE_Status BrotherUSBDriver::ReadScanData (SANE_Byte *data, size_t max_length,
|
||||||
|
|
||||||
res = encoder->DecodeStatusToSaneStatus(dec_ret);
|
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++;
|
next_frame_number++;
|
||||||
out_of_docs = true;
|
out_of_docs = true;
|
||||||
|
@ -850,23 +851,17 @@ SANE_Status BrotherUSBDriver::StartScan ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct the "ADF" block.
|
* Construct the Source select 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.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
packet_len = 0;
|
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_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
if (dec_ret != DECODE_STATUS_GOOD)
|
if (dec_ret != DECODE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherUSBDriver::StartScan: failed to generate ADF block: %d\n",
|
"BrotherUSBDriver::StartScan: failed to generate source select block: %d\n",
|
||||||
dec_ret);
|
dec_ret);
|
||||||
(void) CancelScan ();
|
(void) CancelScan ();
|
||||||
return SANE_STATUS_INVAL;
|
return SANE_STATUS_INVAL;
|
||||||
|
@ -876,14 +871,14 @@ SANE_Status BrotherUSBDriver::StartScan ()
|
||||||
res = sanei_usb_write_bulk (fd, small_buffer, &buf_size);
|
res = sanei_usb_write_bulk (fd, small_buffer, &buf_size);
|
||||||
if (res != SANE_STATUS_GOOD)
|
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 ();
|
(void) CancelScan ();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_size != packet_len)
|
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 ();
|
(void) CancelScan ();
|
||||||
return SANE_STATUS_IO_ERROR;
|
return SANE_STATUS_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -899,27 +894,27 @@ SANE_Status BrotherUSBDriver::StartScan ()
|
||||||
if (res != SANE_STATUS_GOOD)
|
if (res != SANE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
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);
|
res);
|
||||||
(void) CancelScan ();
|
(void) CancelScan ();
|
||||||
return res;
|
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)
|
if (dec_ret != DECODE_STATUS_GOOD)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherUSBDriver::StartScan: ADF block response block invalid: %d\n",
|
"BrotherUSBDriver::StartScan: source select response block invalid: %d\n",
|
||||||
dec_ret);
|
dec_ret);
|
||||||
(void) CancelScan ();
|
(void) CancelScan ();
|
||||||
return encoder->DecodeStatusToSaneStatus(dec_ret);
|
return encoder->DecodeStatusToSaneStatus(dec_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_DETAIL,
|
DBG (DBG_DETAIL,
|
||||||
"BrotherUSBDriver::StartScan: ADF reports readiness?: %s\n",
|
"BrotherUSBDriver::StartScan: Source reports readiness?: %s\n",
|
||||||
adf_resp.adf_ready? "Yes": "No");
|
source_resp.source_ready? "Yes": "No");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -105,6 +105,11 @@ public:
|
||||||
* Parameter setting.
|
* Parameter setting.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
SANE_Status SetSource (BrotherSource source)
|
||||||
|
{
|
||||||
|
return encoder->DecodeStatusToSaneStatus (encoder->SetSource (source));
|
||||||
|
}
|
||||||
|
|
||||||
SANE_Status SetScanMode (BrotherScanMode scan_mode)
|
SANE_Status SetScanMode (BrotherScanMode scan_mode)
|
||||||
{
|
{
|
||||||
return encoder->DecodeStatusToSaneStatus (encoder->SetScanMode (scan_mode));
|
return encoder->DecodeStatusToSaneStatus (encoder->SetScanMode (scan_mode));
|
||||||
|
@ -144,7 +149,6 @@ protected:
|
||||||
|
|
||||||
BrotherFamily family;
|
BrotherFamily family;
|
||||||
SANE_Word capabilities;
|
SANE_Word capabilities;
|
||||||
BrotherParameters scan_params;
|
|
||||||
BrotherEncoder *encoder;
|
BrotherEncoder *encoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,11 @@
|
||||||
// unsure as to the meaning of this or how to get it again.
|
// unsure as to the meaning of this or how to get it again.
|
||||||
#define BROTHER_DATA_BLOCK_CLEARING_PAPER 0xc5
|
#define BROTHER_DATA_BLOCK_CLEARING_PAPER 0xc5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Other protocol error?
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define BROTHER_DATA_BLOCK_PROTOCOL_ERROR 0xd0
|
||||||
|
|
||||||
const char* BrotherEncoder::ScanModeToText (BrotherScanMode scan_mode)
|
const char* BrotherEncoder::ScanModeToText (BrotherScanMode scan_mode)
|
||||||
{
|
{
|
||||||
|
@ -87,6 +92,14 @@ const char* BrotherEncoder::ScanModeToText (BrotherScanMode scan_mode)
|
||||||
return scan_mode_text[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)
|
DecodeStatus BrotherEncoder::SetScanMode (BrotherScanMode scan_mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -212,14 +225,14 @@ DecodeStatus BrotherEncoderFamily2::DecodeQueryBlockResp (const SANE_Byte *data,
|
||||||
return DECODE_STATUS_GOOD;
|
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");
|
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
|
||||||
|
|
||||||
if (*length > data_len)
|
if (*length > data_len)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherEncoderFamily2::EncodeBasicParameterBlock: ADF block too long for buffer: %zu\n",
|
"BrotherEncoderFamily2::EncodeBasicParameterBlock: source status too long for buffer: %zu\n",
|
||||||
*length);
|
*length);
|
||||||
return DECODE_STATUS_INVAL;
|
return DECODE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
@ -227,13 +240,13 @@ DecodeStatus BrotherEncoderFamily2::EncodeADFBlock (SANE_Byte *data, size_t data
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeStatus BrotherEncoderFamily2::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
|
DecodeStatus BrotherEncoderFamily2::DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherADFResponse &response)
|
BrotherSourceStatusResponse &response)
|
||||||
{
|
{
|
||||||
if (data_len != 1)
|
if (data_len != 1)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
|
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
|
||||||
data_len);
|
data_len);
|
||||||
return DECODE_STATUS_ERROR;
|
return DECODE_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -251,11 +264,11 @@ DecodeStatus BrotherEncoderFamily2::DecodeADFBlockResp (const SANE_Byte *data, s
|
||||||
return DECODE_STATUS_COVER_OPEN;
|
return DECODE_STATUS_COVER_OPEN;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_NO_DOCS:
|
case BROTHER_DATA_BLOCK_NO_DOCS:
|
||||||
response.adf_ready = SANE_FALSE;
|
response.source_ready = SANE_FALSE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
||||||
response.adf_ready = SANE_TRUE;
|
response.source_ready = SANE_TRUE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
default:
|
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,
|
DecodeStatus BrotherEncoderFamily2::DecodeSessionResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherSessionResponse &response)
|
BrotherSessionResponse &response)
|
||||||
|
@ -493,12 +554,11 @@ DecodeStatus BrotherEncoderFamily2::DecodeScanData (const SANE_Byte *src_data, s
|
||||||
* Detect special case situations.
|
* Detect special case situations.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|
if (ret_status != DECODE_STATUS_GOOD)
|
||||||
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
|
|
||||||
{
|
{
|
||||||
DBG (DBG_IMPORTANT,
|
DBG (DBG_IMPORTANT,
|
||||||
"BrotherEncoderFamily2::DecodeScanData: %s detected.\n",
|
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
|
||||||
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" : "ENDOFFRAME_WITH_MORE");
|
DecodeStatusToString (ret_status));
|
||||||
|
|
||||||
current_header.block_type = 0;
|
current_header.block_type = 0;
|
||||||
|
|
||||||
|
@ -682,6 +742,12 @@ DecodeStatus BrotherEncoderFamily2::DecodeScanDataHeader (const SANE_Byte *src_d
|
||||||
|
|
||||||
header.block_len = 0;
|
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)
|
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
|
||||||
{
|
{
|
||||||
*src_data_consumed = 1;
|
*src_data_consumed = 1;
|
||||||
|
@ -833,14 +899,14 @@ DecodeStatus BrotherEncoderFamily3::DecodeQueryBlockResp (const SANE_Byte *data,
|
||||||
return DECODE_STATUS_GOOD;
|
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");
|
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
|
||||||
|
|
||||||
if (*length > data_len)
|
if (*length > data_len)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherEncoderFamily3::EncodeBasicParameterBlock: ADF block too long for buffer: %zu\n",
|
"BrotherEncoderFamily3::EncodeBasicParameterBlock: source status too long for buffer: %zu\n",
|
||||||
*length);
|
*length);
|
||||||
return DECODE_STATUS_INVAL;
|
return DECODE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
@ -848,13 +914,13 @@ DecodeStatus BrotherEncoderFamily3::EncodeADFBlock (SANE_Byte *data, size_t data
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeStatus BrotherEncoderFamily3::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
|
DecodeStatus BrotherEncoderFamily3::DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherADFResponse &response)
|
BrotherSourceStatusResponse &response)
|
||||||
{
|
{
|
||||||
if (data_len != 1)
|
if (data_len != 1)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
|
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
|
||||||
data_len);
|
data_len);
|
||||||
return DECODE_STATUS_ERROR;
|
return DECODE_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -872,11 +938,11 @@ DecodeStatus BrotherEncoderFamily3::DecodeADFBlockResp (const SANE_Byte *data, s
|
||||||
return DECODE_STATUS_COVER_OPEN;
|
return DECODE_STATUS_COVER_OPEN;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_NO_DOCS:
|
case BROTHER_DATA_BLOCK_NO_DOCS:
|
||||||
response.adf_ready = SANE_FALSE;
|
response.source_ready = SANE_FALSE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
||||||
response.adf_ready = SANE_TRUE;
|
response.source_ready = SANE_TRUE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
default:
|
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,
|
DecodeStatus BrotherEncoderFamily3::DecodeSessionResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherSessionResponse &response)
|
BrotherSessionResponse &response)
|
||||||
{
|
{
|
||||||
|
@ -1113,12 +1228,11 @@ DecodeStatus BrotherEncoderFamily3::DecodeScanData (const SANE_Byte *src_data, s
|
||||||
* Detect special case situations.
|
* Detect special case situations.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|
if (ret_status != DECODE_STATUS_GOOD)
|
||||||
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
|
|
||||||
{
|
{
|
||||||
DBG (DBG_IMPORTANT,
|
DBG (DBG_IMPORTANT,
|
||||||
"BrotherEncoderFamily3::DecodeScanData: %s.\n",
|
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
|
||||||
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" : "ENDOFFRAME_WITH_MORE");
|
DecodeStatusToString (ret_status));
|
||||||
|
|
||||||
current_header.block_type = 0;
|
current_header.block_type = 0;
|
||||||
|
|
||||||
|
@ -1312,6 +1426,12 @@ DecodeStatus BrotherEncoderFamily3::DecodeScanDataHeader (const SANE_Byte *src_d
|
||||||
|
|
||||||
header.block_len = 0;
|
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)
|
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
|
||||||
{
|
{
|
||||||
*src_data_consumed = 1;
|
*src_data_consumed = 1;
|
||||||
|
@ -1567,14 +1687,14 @@ DecodeStatus BrotherEncoderFamily4::DecodeBasicParameterBlockResp (const SANE_By
|
||||||
return DECODE_STATUS_GOOD;
|
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");
|
*length = snprintf ((char*) data, data_len, "\x1b" "D\nADF\n" "\x80");
|
||||||
|
|
||||||
if (*length > data_len)
|
if (*length > data_len)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
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);
|
*length);
|
||||||
return DECODE_STATUS_INVAL;
|
return DECODE_STATUS_INVAL;
|
||||||
}
|
}
|
||||||
|
@ -1582,13 +1702,14 @@ DecodeStatus BrotherEncoderFamily4::EncodeADFBlock (SANE_Byte *data, size_t data
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeStatus BrotherEncoderFamily4::DecodeADFBlockResp (const SANE_Byte *data, size_t data_len,
|
DecodeStatus BrotherEncoderFamily4::DecodeSourceStatusBlockResp (const SANE_Byte *data,
|
||||||
BrotherADFResponse &response)
|
size_t data_len,
|
||||||
|
BrotherSourceStatusResponse &response)
|
||||||
{
|
{
|
||||||
if (data_len != 1)
|
if (data_len != 1)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_SERIOUS,
|
||||||
"BrotherEncoderFamily2::DecodeADFBlockResp: ADF block response invalid: %zu\n",
|
"BrotherEncoderFamily2::DecodeSourceStatusBlockResp: source status response invalid: %zu\n",
|
||||||
data_len);
|
data_len);
|
||||||
return DECODE_STATUS_ERROR;
|
return DECODE_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1606,11 +1727,11 @@ DecodeStatus BrotherEncoderFamily4::DecodeADFBlockResp (const SANE_Byte *data, s
|
||||||
return DECODE_STATUS_COVER_OPEN;
|
return DECODE_STATUS_COVER_OPEN;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_NO_DOCS:
|
case BROTHER_DATA_BLOCK_NO_DOCS:
|
||||||
response.adf_ready = SANE_FALSE;
|
response.source_ready = SANE_FALSE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
case BROTHER_DATA_BLOCK_SCAN_FINISHED:
|
||||||
response.adf_ready = SANE_TRUE;
|
response.source_ready = SANE_TRUE;
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
|
|
||||||
default:
|
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,
|
DecodeStatus BrotherEncoderFamily4::EncodeParameterBlockBlank (SANE_Byte *data, size_t data_len,
|
||||||
size_t *length)
|
size_t *length)
|
||||||
{
|
{
|
||||||
|
@ -1753,15 +1923,11 @@ DecodeStatus BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, s
|
||||||
* Detect special case situations.
|
* Detect special case situations.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if ((ret_status == DECODE_STATUS_ENDOFDATA)
|
if (ret_status != DECODE_STATUS_GOOD)
|
||||||
|| (ret_status == DECODE_STATUS_ENDOFFRAME_NO_MORE)
|
|
||||||
|| (ret_status == DECODE_STATUS_ENDOFFRAME_WITH_MORE))
|
|
||||||
{
|
{
|
||||||
DBG (DBG_IMPORTANT,
|
DBG (DBG_IMPORTANT,
|
||||||
"BrotherEncoderFamily4::DecodeScanData: %s.\n",
|
"BrotherEncoderFamily2::DecodeScanData: %s.\n",
|
||||||
ret_status == DECODE_STATUS_ENDOFDATA ? "ENDOFDATA" :
|
DecodeStatusToString (ret_status));
|
||||||
ret_status == DECODE_STATUS_ENDOFFRAME_NO_MORE ?
|
|
||||||
"ENDOFFRAME_NO_MORE" : "ENDOFFRAME_WITH_MORE");
|
|
||||||
|
|
||||||
current_header.block_type = 0;
|
current_header.block_type = 0;
|
||||||
|
|
||||||
|
@ -1935,6 +2101,12 @@ DecodeStatus BrotherEncoderFamily4::DecodeScanDataHeader (const SANE_Byte *src_d
|
||||||
|
|
||||||
header.block_len = 0;
|
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)
|
if (header.block_type == BROTHER_DATA_BLOCK_SCAN_FINISHED)
|
||||||
{
|
{
|
||||||
*src_data_consumed = 1;
|
*src_data_consumed = 1;
|
||||||
|
@ -2304,7 +2476,7 @@ DecodeStatus BrotherInterleavedRGBColourDecoder::DecodeScanData (const SANE_Byte
|
||||||
* Sort out the raw encoding format.
|
* 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 R;
|
||||||
SANE_Byte G;
|
SANE_Byte G;
|
||||||
|
|
|
@ -82,6 +82,13 @@ typedef enum
|
||||||
BROTHER_SCAN_MODE_TEXT
|
BROTHER_SCAN_MODE_TEXT
|
||||||
} BrotherScanMode;
|
} BrotherScanMode;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BROTHER_SOURCE_FLATBED,
|
||||||
|
BROTHER_SOURCE_ADF,
|
||||||
|
} BrotherSource;
|
||||||
|
|
||||||
typedef SANE_Int BrotherSensor;
|
typedef SANE_Int BrotherSensor;
|
||||||
|
|
||||||
#define BROTHER_SENSOR_NONE 0
|
#define BROTHER_SENSOR_NONE 0
|
||||||
|
@ -116,6 +123,7 @@ struct BrotherParameters
|
||||||
param_pixel_y_offset (0),
|
param_pixel_y_offset (0),
|
||||||
param_pixel_y_height (0),
|
param_pixel_y_height (0),
|
||||||
param_scan_mode (BROTHER_SCAN_MODE_COLOR),
|
param_scan_mode (BROTHER_SCAN_MODE_COLOR),
|
||||||
|
param_source(BROTHER_SOURCE_FLATBED),
|
||||||
param_x_res(100),
|
param_x_res(100),
|
||||||
param_y_res(100)
|
param_y_res(100)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +138,7 @@ struct BrotherParameters
|
||||||
SANE_Int param_pixel_y_height;
|
SANE_Int param_pixel_y_height;
|
||||||
|
|
||||||
BrotherScanMode param_scan_mode;
|
BrotherScanMode param_scan_mode;
|
||||||
|
BrotherSource param_source;
|
||||||
|
|
||||||
SANE_Int param_x_res;
|
SANE_Int param_x_res;
|
||||||
SANE_Int param_y_res;
|
SANE_Int param_y_res;
|
||||||
|
@ -148,9 +157,9 @@ struct BrotherQueryResponse
|
||||||
// fill me
|
// 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_UNSUPPORTED,
|
||||||
DECODE_STATUS_PAPER_JAM,
|
DECODE_STATUS_PAPER_JAM,
|
||||||
DECODE_STATUS_COVER_OPEN,
|
DECODE_STATUS_COVER_OPEN,
|
||||||
|
DECODE_STATUS_NO_DOCS,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ScanDataHeader
|
struct ScanDataHeader
|
||||||
|
@ -199,6 +209,7 @@ public:
|
||||||
|
|
||||||
virtual void NewPage () = 0;
|
virtual void NewPage () = 0;
|
||||||
|
|
||||||
|
DecodeStatus SetSource (BrotherSource source);
|
||||||
DecodeStatus SetScanMode (BrotherScanMode scan_mode);
|
DecodeStatus SetScanMode (BrotherScanMode scan_mode);
|
||||||
DecodeStatus SetRes (SANE_Int x, SANE_Int y);
|
DecodeStatus SetRes (SANE_Int x, SANE_Int y);
|
||||||
DecodeStatus SetContrast (SANE_Int contrast);
|
DecodeStatus SetContrast (SANE_Int contrast);
|
||||||
|
@ -224,6 +235,29 @@ public:
|
||||||
SANE_STATUS_UNSUPPORTED,
|
SANE_STATUS_UNSUPPORTED,
|
||||||
SANE_STATUS_JAMMED,
|
SANE_STATUS_JAMMED,
|
||||||
SANE_STATUS_COVER_OPEN,
|
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];
|
return status_lookup[dec_ret];
|
||||||
|
@ -254,10 +288,15 @@ public:
|
||||||
virtual DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
|
virtual DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherBasicParamResponse &response) = 0;
|
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,
|
virtual DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherADFResponse &response) = 0;
|
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;
|
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,
|
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherBasicParamResponse &response) override;
|
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,
|
DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherADFResponse &response) override;
|
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;
|
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,
|
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherBasicParamResponse &response) override;
|
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 EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
|
||||||
|
|
||||||
DecodeStatus EncodeParameterBlockBlank (SANE_Byte *data, size_t data_len, size_t *length)
|
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,
|
DecodeStatus DecodeBasicParameterBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherBasicParamResponse &response) override;
|
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,
|
DecodeStatus DecodeSourceStatusBlockResp (const SANE_Byte *data, size_t data_len,
|
||||||
BrotherADFResponse &response) override;
|
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;
|
DecodeStatus EncodeParameterBlock (SANE_Byte *data, size_t data_len, size_t *length) override;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,10 @@
|
||||||
* Messages.
|
* 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_FILE_BUTTON "file-sensor"
|
||||||
#define SANE_NAME_EMAIL_BUTTON "email-sensor"
|
#define SANE_NAME_EMAIL_BUTTON "email-sensor"
|
||||||
|
@ -81,6 +84,7 @@ enum Brother_Option
|
||||||
OPT_NUM_OPTS = 0,
|
OPT_NUM_OPTS = 0,
|
||||||
|
|
||||||
OPT_MODE_GROUP,
|
OPT_MODE_GROUP,
|
||||||
|
OPT_SOURCE,
|
||||||
OPT_MODE,
|
OPT_MODE,
|
||||||
OPT_SPLIT_RESOLUTION,
|
OPT_SPLIT_RESOLUTION,
|
||||||
OPT_RESOLUTION,
|
OPT_RESOLUTION,
|
||||||
|
@ -139,14 +143,15 @@ static Brother_Model models[] =
|
||||||
CAP_MODE_GRAY |
|
CAP_MODE_GRAY |
|
||||||
CAP_MODE_GRAY_DITHER |
|
CAP_MODE_GRAY_DITHER |
|
||||||
CAP_MODE_BW |
|
CAP_MODE_BW |
|
||||||
CAP_MODE_BUTTON_SCAN_EMAIL |
|
CAP_BUTTON_HAS_SCAN_EMAIL |
|
||||||
CAP_MODE_BUTTON_SCAN_FILE |
|
CAP_BUTTON_HAS_SCAN_FILE |
|
||||||
CAP_MODE_BUTTON_SCAN_OCR |
|
CAP_BUTTON_HAS_SCAN_OCR |
|
||||||
CAP_MODE_BUTTON_SCAN_IMAGE |
|
CAP_BUTTON_HAS_SCAN_IMAGE |
|
||||||
CAP_MODE_HAS_ADF |
|
CAP_SOURCE_HAS_ADF |
|
||||||
CAP_MODE_RAW_IS_CrYCb |
|
CAP_SOURCE_HAS_FLATBED |
|
||||||
CAP_MODE_HAS_RAW |
|
CAP_ENCODING_RAW_IS_CrYCb |
|
||||||
CAP_MODE_HAS_JPEG },
|
CAP_ENCODING_HAS_RAW |
|
||||||
|
CAP_ENCODING_HAS_JPEG },
|
||||||
|
|
||||||
{ "Brother", "DCP-7030", BROTHER_FAMILY_3, 0x04f9, 0x01ea,
|
{ "Brother", "DCP-7030", BROTHER_FAMILY_3, 0x04f9, 0x01ea,
|
||||||
{ 0, SANE_FIX(210), 0 },
|
{ 0, SANE_FIX(210), 0 },
|
||||||
|
@ -157,12 +162,13 @@ static Brother_Model models[] =
|
||||||
CAP_MODE_GRAY |
|
CAP_MODE_GRAY |
|
||||||
CAP_MODE_GRAY_DITHER |
|
CAP_MODE_GRAY_DITHER |
|
||||||
CAP_MODE_BW |
|
CAP_MODE_BW |
|
||||||
CAP_MODE_BUTTON_SCAN_EMAIL |
|
CAP_BUTTON_HAS_SCAN_EMAIL |
|
||||||
CAP_MODE_BUTTON_SCAN_FILE |
|
CAP_BUTTON_HAS_SCAN_FILE |
|
||||||
CAP_MODE_BUTTON_SCAN_OCR |
|
CAP_BUTTON_HAS_SCAN_OCR |
|
||||||
CAP_MODE_BUTTON_SCAN_IMAGE |
|
CAP_BUTTON_HAS_SCAN_IMAGE |
|
||||||
CAP_MODE_HAS_RAW |
|
CAP_SOURCE_HAS_FLATBED |
|
||||||
CAP_MODE_HAS_JPEG},
|
CAP_ENCODING_HAS_RAW |
|
||||||
|
CAP_ENCODING_HAS_JPEG},
|
||||||
|
|
||||||
// TODO: check dimensions
|
// TODO: check dimensions
|
||||||
{ "Brother", "MFC-290C", BROTHER_FAMILY_3, 0x04f9, 0x01fd,
|
{ "Brother", "MFC-290C", BROTHER_FAMILY_3, 0x04f9, 0x01fd,
|
||||||
|
@ -174,13 +180,15 @@ static Brother_Model models[] =
|
||||||
CAP_MODE_GRAY |
|
CAP_MODE_GRAY |
|
||||||
CAP_MODE_GRAY_DITHER |
|
CAP_MODE_GRAY_DITHER |
|
||||||
CAP_MODE_BW |
|
CAP_MODE_BW |
|
||||||
CAP_MODE_BUTTON_SCAN_EMAIL |
|
CAP_SOURCE_HAS_FLATBED |
|
||||||
CAP_MODE_BUTTON_SCAN_FILE |
|
CAP_SOURCE_HAS_ADF |
|
||||||
CAP_MODE_BUTTON_SCAN_OCR |
|
CAP_BUTTON_HAS_SCAN_EMAIL |
|
||||||
CAP_MODE_BUTTON_SCAN_IMAGE |
|
CAP_BUTTON_HAS_SCAN_FILE |
|
||||||
CAP_MODE_RAW_IS_CrYCb |
|
CAP_BUTTON_HAS_SCAN_OCR |
|
||||||
CAP_MODE_HAS_RAW |
|
CAP_BUTTON_HAS_SCAN_IMAGE |
|
||||||
CAP_MODE_HAS_JPEG},
|
CAP_ENCODING_RAW_IS_CrYCb |
|
||||||
|
CAP_ENCODING_HAS_RAW |
|
||||||
|
CAP_ENCODING_HAS_JPEG},
|
||||||
|
|
||||||
{ "Brother", "MFC-J4320DW", BROTHER_FAMILY_4, 0x04f9, 0x033a,
|
{ "Brother", "MFC-J4320DW", BROTHER_FAMILY_4, 0x04f9, 0x033a,
|
||||||
{ 0, SANE_FIX(211.5), 0 },
|
{ 0, SANE_FIX(211.5), 0 },
|
||||||
|
@ -191,11 +199,46 @@ static Brother_Model models[] =
|
||||||
CAP_MODE_GRAY |
|
CAP_MODE_GRAY |
|
||||||
CAP_MODE_GRAY_DITHER |
|
CAP_MODE_GRAY_DITHER |
|
||||||
CAP_MODE_BW |
|
CAP_MODE_BW |
|
||||||
CAP_MODE_BUTTON_SCAN_EMAIL |
|
CAP_BUTTON_HAS_SCAN_EMAIL |
|
||||||
CAP_MODE_BUTTON_SCAN_FILE |
|
CAP_BUTTON_HAS_SCAN_FILE |
|
||||||
CAP_MODE_BUTTON_SCAN_OCR |
|
CAP_BUTTON_HAS_SCAN_OCR |
|
||||||
CAP_MODE_BUTTON_SCAN_IMAGE |
|
CAP_BUTTON_HAS_SCAN_IMAGE |
|
||||||
CAP_MODE_HAS_JPEG },
|
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}
|
{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},
|
sane_device {nullptr, nullptr, nullptr, nullptr},
|
||||||
name (nullptr),
|
name (nullptr),
|
||||||
modes {0},
|
modes {0},
|
||||||
|
sources {0},
|
||||||
params {SANE_FRAME_GRAY, SANE_FALSE, 0, 0, 0, 0},
|
params {SANE_FRAME_GRAY, SANE_FALSE, 0, 0, 0, 0},
|
||||||
internal_scan_mode(nullptr),
|
internal_scan_mode(nullptr),
|
||||||
x_res (0),
|
x_res (0),
|
||||||
|
@ -228,6 +272,7 @@ struct BrotherDevice
|
||||||
Option_Value val[NUM_OPTIONS];
|
Option_Value val[NUM_OPTIONS];
|
||||||
|
|
||||||
SANE_String_Const modes[10];
|
SANE_String_Const modes[10];
|
||||||
|
SANE_String_Const sources[10];
|
||||||
SANE_Parameters params;
|
SANE_Parameters params;
|
||||||
const char *internal_scan_mode;
|
const char *internal_scan_mode;
|
||||||
SANE_Int x_res;
|
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;
|
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;
|
++num_devices;
|
||||||
device->next = first_dev;
|
device->next = first_dev;
|
||||||
first_dev = device;
|
first_dev = device;
|
||||||
|
@ -423,6 +482,39 @@ init_options (BrotherDevice *device)
|
||||||
od->constraint.range = 0;
|
od->constraint.range = 0;
|
||||||
device->val[OPT_MODE_GROUP].w = 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 */
|
/* opt_mode */
|
||||||
od = &device->opt[OPT_MODE];
|
od = &device->opt[OPT_MODE];
|
||||||
od->name = SANE_NAME_SCAN_MODE;
|
od->name = SANE_NAME_SCAN_MODE;
|
||||||
|
@ -622,8 +714,8 @@ init_options (BrotherDevice *device)
|
||||||
od->unit = SANE_UNIT_NONE;
|
od->unit = SANE_UNIT_NONE;
|
||||||
od->size = 1 * sizeof(SANE_Bool);
|
od->size = 1 * sizeof(SANE_Bool);
|
||||||
od->constraint_type = SANE_CONSTRAINT_NONE;
|
od->constraint_type = SANE_CONSTRAINT_NONE;
|
||||||
if ((device->model->capabilities & CAP_MODE_HAS_JPEG)
|
if ((device->model->capabilities & CAP_ENCODING_HAS_JPEG)
|
||||||
&& (device->model->capabilities & CAP_MODE_HAS_RAW))
|
&& (device->model->capabilities & CAP_ENCODING_HAS_RAW))
|
||||||
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
|
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
|
||||||
else
|
else
|
||||||
od->cap = SANE_CAP_INACTIVE;
|
od->cap = SANE_CAP_INACTIVE;
|
||||||
|
@ -649,7 +741,7 @@ init_options (BrotherDevice *device)
|
||||||
od->type = SANE_TYPE_BOOL;
|
od->type = SANE_TYPE_BOOL;
|
||||||
od->unit = SANE_UNIT_NONE;
|
od->unit = SANE_UNIT_NONE;
|
||||||
od->size = 1 * sizeof(SANE_Bool);
|
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 =
|
od->cap =
|
||||||
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
||||||
else
|
else
|
||||||
|
@ -663,7 +755,7 @@ init_options (BrotherDevice *device)
|
||||||
od->type = SANE_TYPE_BOOL;
|
od->type = SANE_TYPE_BOOL;
|
||||||
od->unit = SANE_UNIT_NONE;
|
od->unit = SANE_UNIT_NONE;
|
||||||
od->size = 1 * sizeof(SANE_Bool);
|
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 =
|
od->cap =
|
||||||
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
||||||
else
|
else
|
||||||
|
@ -677,7 +769,7 @@ init_options (BrotherDevice *device)
|
||||||
od->type = SANE_TYPE_BOOL;
|
od->type = SANE_TYPE_BOOL;
|
||||||
od->unit = SANE_UNIT_NONE;
|
od->unit = SANE_UNIT_NONE;
|
||||||
od->size = 1 * sizeof(SANE_Bool);
|
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 =
|
od->cap =
|
||||||
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
||||||
else
|
else
|
||||||
|
@ -691,7 +783,7 @@ init_options (BrotherDevice *device)
|
||||||
od->type = SANE_TYPE_BOOL;
|
od->type = SANE_TYPE_BOOL;
|
||||||
od->unit = SANE_UNIT_NONE;
|
od->unit = SANE_UNIT_NONE;
|
||||||
od->size = 1 * sizeof(SANE_Bool);
|
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 =
|
od->cap =
|
||||||
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
|
||||||
else
|
else
|
||||||
|
@ -1078,39 +1170,54 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
|
||||||
status = SANE_STATUS_GOOD;
|
status = SANE_STATUS_GOOD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_MODE:
|
case OPT_MODE:
|
||||||
if (strcmp (device->val[option].s, (SANE_String)value) == 0)
|
if (strcmp (device->val[option].s, (SANE_String)value) == 0)
|
||||||
{
|
{
|
||||||
DBG (DBG_DETAIL, "sane_control_option: option %d (%s) not changed\n",
|
DBG (DBG_DETAIL, "sane_control_option: option %d (%s) not changed\n",
|
||||||
option, device->opt[option].name);
|
option, device->opt[option].name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
strcpy (device->val[option].s, (SANE_String) value);
|
strcpy (device->val[option].s, (SANE_String) value);
|
||||||
|
|
||||||
myinfo |= SANE_INFO_RELOAD_PARAMS;
|
myinfo |= SANE_INFO_RELOAD_PARAMS;
|
||||||
myinfo |= SANE_INFO_RELOAD_OPTIONS;
|
myinfo |= SANE_INFO_RELOAD_OPTIONS;
|
||||||
DBG (DBG_DETAIL, "sane_control_option: set option %d (%s) to %s\n",
|
DBG (DBG_DETAIL, "sane_control_option: set option %d (%s) to %s\n",
|
||||||
option, device->opt[option].name, (SANE_String) value);
|
option, device->opt[option].name, (SANE_String) value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mode affects other options:
|
* Mode affects other options:
|
||||||
*
|
*
|
||||||
* OPT_CONTRAST
|
* OPT_CONTRAST
|
||||||
* OPT_BRIGHTNESS
|
* OPT_BRIGHTNESS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if ((strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_COLOR) == 0) ||
|
if ((strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_COLOR) == 0) ||
|
||||||
(strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_GRAY) == 0))
|
(strcmp((SANE_String)value, SANE_VALUE_SCAN_MODE_GRAY) == 0))
|
||||||
{
|
{
|
||||||
device->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
|
device->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
|
||||||
device->opt[OPT_BRIGHTNESS].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_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
|
||||||
device->opt[OPT_BRIGHTNESS].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:
|
default:
|
||||||
DBG (DBG_SERIOUS, "sane_control_option: trying to set unexpected option\n");
|
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" : ""));
|
(device->opt[option].unit == SANE_UNIT_DPI ? "dpi" : ""));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_MODE: /* String (list) options */
|
case OPT_MODE: /* String (list) options */
|
||||||
strcpy ((SANE_String)value, device->val[option].s);
|
case OPT_SOURCE:
|
||||||
DBG (DBG_DETAIL, "sane_control_option: get option %d (%s), value=`%s'\n",
|
strcpy ((SANE_String)value, device->val[option].s);
|
||||||
option, device->opt[option].name, (SANE_String) value);
|
DBG (DBG_DETAIL, "sane_control_option: get option %d (%s), value=`%s'\n",
|
||||||
break;
|
option, device->opt[option].name, (SANE_String) value);
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_RESOLUTION:
|
case OPT_RESOLUTION:
|
||||||
case OPT_X_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.
|
* Compute the geometry in terms of pixels at the selected resolution.
|
||||||
* This is how the scanner wants it.
|
* This is how the scanner wants it.
|
||||||
|
@ -1289,13 +1420,14 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
||||||
*/
|
*/
|
||||||
// pixel_x_width += 16;
|
// 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 -
|
SANE_Int pixel_y_height = SANE_UNFIX (device->val[OPT_BR_Y].w -
|
||||||
device->val[OPT_TL_Y].w) / MM_IN_INCH * y_res;
|
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;
|
SANE_Int pixel_y_offset = SANE_UNFIX (device->val[OPT_TL_Y].w) / MM_IN_INCH * y_res;
|
||||||
|
|
||||||
|
|
||||||
params->lines = pixel_y_height;
|
params->lines = pixel_y_height;
|
||||||
params->last_frame = SANE_TRUE;
|
params->last_frame = SANE_TRUE;
|
||||||
|
|
||||||
|
|
|
@ -101,28 +101,28 @@ static void test_family4_decode_basic_param_resp()
|
||||||
static void test_family4_decode_adf_resp()
|
static void test_family4_decode_adf_resp()
|
||||||
{
|
{
|
||||||
DecodeStatus decode_resp;
|
DecodeStatus decode_resp;
|
||||||
BrotherADFResponse adf_resp;
|
BrotherSourceStatusResponse adf_resp;
|
||||||
|
|
||||||
BrotherEncoderFamily4 encoder(0);
|
BrotherEncoderFamily4 encoder(0);
|
||||||
|
|
||||||
// SUCCESS status
|
// SUCCESS status
|
||||||
const SANE_Byte *data = (const SANE_Byte *)"\xc2";
|
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_EQ(decode_resp, DECODE_STATUS_GOOD);
|
||||||
ASSERT_FALSE(adf_resp.adf_ready);
|
ASSERT_FALSE(adf_resp.source_ready);
|
||||||
|
|
||||||
data = (const SANE_Byte *)"\x80";
|
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_EQ(decode_resp, DECODE_STATUS_GOOD);
|
||||||
ASSERT_TRUE(adf_resp.adf_ready);
|
ASSERT_TRUE(adf_resp.source_ready);
|
||||||
|
|
||||||
// Wrong length.
|
// 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);
|
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);
|
ASSERT_EQ(decode_resp, DECODE_STATUS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ static void test_family4_encode_adf()
|
||||||
BrotherEncoderFamily4 encoder(0);
|
BrotherEncoderFamily4 encoder(0);
|
||||||
|
|
||||||
// Standard call.
|
// 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);
|
ASSERT_EQ(decode_resp, DECODE_STATUS_GOOD);
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ static void test_family4_encode_adf()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer too short.
|
// 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);
|
ASSERT_EQ(decode_resp, DECODE_STATUS_INVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue