kopia lustrzana https://gitlab.com/sane-project/backends
brother_mfp: Added basic test framework and moved source into brother_mfp directory
rodzic
8280db1eef
commit
6eb9e1cc43
|
@ -382,12 +382,13 @@ libsane_bh_la_LIBADD = $(COMMON_LIBS) libbh.la \
|
||||||
EXTRA_DIST += bh.conf.in
|
EXTRA_DIST += bh.conf.in
|
||||||
|
|
||||||
|
|
||||||
libbrother_mfp_la_SOURCES = brother_mfp-driver.cpp \
|
libbrother_mfp_la_SOURCES = \
|
||||||
brother_mfp-driver.h \
|
brother_mfp/brother_mfp-driver.cpp \
|
||||||
brother_mfp-common.h \
|
brother_mfp/brother_mfp-driver.h \
|
||||||
brother_mfp-encoder.cpp \
|
brother_mfp/brother_mfp-common.h \
|
||||||
brother_mfp-encoder.h \
|
brother_mfp/brother_mfp-encoder.cpp \
|
||||||
brother_mfp.cpp
|
brother_mfp/brother_mfp-encoder.h \
|
||||||
|
brother_mfp/brother_mfp.cpp
|
||||||
libbrother_mfp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=brother_mfp
|
libbrother_mfp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=brother_mfp
|
||||||
|
|
||||||
nodist_libsane_brother_mfp_la_SOURCES = brother_mfp-s.cpp
|
nodist_libsane_brother_mfp_la_SOURCES = brother_mfp-s.cpp
|
||||||
|
@ -399,7 +400,7 @@ libsane_brother_mfp_la_LIBADD = $(COMMON_LIBS) libbrother_mfp.la \
|
||||||
../sanei/sanei_usb.lo \
|
../sanei/sanei_usb.lo \
|
||||||
../sanei/sanei_config.lo \
|
../sanei/sanei_config.lo \
|
||||||
sane_strstatus.lo \
|
sane_strstatus.lo \
|
||||||
$(USB_LIBS)
|
$(USB_LIBS) $(JPEG_LIBS)
|
||||||
EXTRA_DIST += brother_mfp.conf.in
|
EXTRA_DIST += brother_mfp.conf.in
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Options for the canon_lide70 backend
|
|
||||||
|
|
||||||
# Autodetect the Canon CanoScan LiDE 70
|
|
||||||
usb 0x04a9 0x2225
|
|
||||||
|
|
||||||
# Autodetect the Canon CanoScan LiDE 600
|
|
||||||
usb 0x04a9 0x2224
|
|
||||||
|
|
||||||
# device list for non-linux-systems (enable if autodetect fails):
|
|
||||||
#/dev/scanner
|
|
||||||
#/dev/usb/scanner0
|
|
|
@ -1,7 +1,10 @@
|
||||||
# Options for the brother_mfp backend
|
# Options for the canon_lide70 backend
|
||||||
|
|
||||||
# Brother MFC-J4320DW
|
# Autodetect the Canon CanoScan LiDE 70
|
||||||
usb 0x04f9 0x033a
|
usb 0x04a9 0x2225
|
||||||
|
|
||||||
|
# Autodetect the Canon CanoScan LiDE 600
|
||||||
|
usb 0x04a9 0x2224
|
||||||
|
|
||||||
# device list for non-linux-systems (enable if autodetect fails):
|
# device list for non-linux-systems (enable if autodetect fails):
|
||||||
#/dev/scanner
|
#/dev/scanner
|
||||||
|
|
|
@ -883,7 +883,7 @@ SANE_Status BrotherUSBDriver::StartScan ()
|
||||||
* Reset the encoder/decoder.
|
* Reset the encoder/decoder.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
encoder->Reset();
|
encoder->NewPage();
|
||||||
|
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
}
|
}
|
|
@ -389,8 +389,10 @@ SANE_Status BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, si
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG (DBG_IMPORTANT, "BrotherEncoderFamily4::DecodeScanData: decoded new block header: 0x%2.2x\n",
|
DBG (DBG_IMPORTANT,
|
||||||
current_header.block_type);
|
"BrotherEncoderFamily4::DecodeScanData: decoded new block header: 0x%2.2x, length=%zu\n",
|
||||||
|
current_header.block_type,
|
||||||
|
current_header.block_len);
|
||||||
|
|
||||||
src_data += header_consumed;
|
src_data += header_consumed;
|
||||||
src_data_len -= header_consumed;
|
src_data_len -= header_consumed;
|
||||||
|
@ -413,7 +415,7 @@ SANE_Status BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, si
|
||||||
{
|
{
|
||||||
if (new_block)
|
if (new_block)
|
||||||
{
|
{
|
||||||
jfif_decoder.Reset ();
|
jfif_decoder.NewBlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = jfif_decoder.DecodeScanData (src_data,
|
res = jfif_decoder.DecodeScanData (src_data,
|
||||||
|
@ -427,7 +429,7 @@ SANE_Status BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, si
|
||||||
{
|
{
|
||||||
if (new_block)
|
if (new_block)
|
||||||
{
|
{
|
||||||
gray_decoder.Reset ();
|
gray_decoder.NewBlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = gray_decoder.DecodeScanData (src_data,
|
res = gray_decoder.DecodeScanData (src_data,
|
||||||
|
@ -441,7 +443,7 @@ SANE_Status BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, si
|
||||||
{
|
{
|
||||||
if (new_block)
|
if (new_block)
|
||||||
{
|
{
|
||||||
gray_raw_decoder.Reset ();
|
gray_raw_decoder.NewBlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = gray_raw_decoder.DecodeScanData (src_data,
|
res = gray_raw_decoder.DecodeScanData (src_data,
|
||||||
|
@ -464,6 +466,10 @@ SANE_Status BrotherEncoderFamily4::DecodeScanData (const SANE_Byte *src_data, si
|
||||||
src_data_len -= bytes_consumed;
|
src_data_len -= bytes_consumed;
|
||||||
current_header.block_len -= bytes_consumed;
|
current_header.block_len -= bytes_consumed;
|
||||||
|
|
||||||
|
DBG (DBG_IMPORTANT,
|
||||||
|
"BrotherEncoderFamily4::DecodeScanData: bytes remaining after decode=%zu\n",
|
||||||
|
current_header.block_len);
|
||||||
|
|
||||||
dest_data += bytes_written;
|
dest_data += bytes_written;
|
||||||
dest_data_len -= bytes_written;
|
dest_data_len -= bytes_written;
|
||||||
|
|
||||||
|
@ -563,13 +569,18 @@ DecodeStatus BrotherEncoderFamily4::DecodeScanDataHeader (const SANE_Byte *src_d
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrotherGrayRLengthDecoder::Reset ()
|
void BrotherGrayRLengthDecoder::NewBlock ()
|
||||||
{
|
{
|
||||||
decode_state = BROTHER_DECODE_RLEN_INIT;
|
decode_state = BROTHER_DECODE_RLEN_INIT;
|
||||||
decode_expand_char = 0;
|
decode_expand_char = 0;
|
||||||
block_bytes_left = 0;
|
block_bytes_left = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrotherGrayRLengthDecoder::NewPage ()
|
||||||
|
{
|
||||||
|
NewBlock();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns:
|
* Returns:
|
||||||
*
|
*
|
||||||
|
@ -695,28 +706,226 @@ DecodeStatus BrotherGrayRLengthDecoder::DecodeScanData (const SANE_Byte *in_buff
|
||||||
return DECODE_STATUS_GOOD;
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrotherJFIFDecoder::Reset ()
|
|
||||||
|
#include <jpeglib.h>
|
||||||
|
#include <jerror.h>
|
||||||
|
|
||||||
|
void BrotherJFIFDecoder::NewBlock()
|
||||||
{
|
{
|
||||||
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrotherJFIFDecoder::NewPage ()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Aborting a non-running state should be OK.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
jpeg_abort_decompress(&state.cinfo);
|
||||||
|
state.have_read_header = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrotherJFIFDecoder::InitSource (j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::InitSource.\n");
|
||||||
|
|
||||||
|
(void)cinfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We will have already setup all the available data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean BrotherJFIFDecoder::FillInputBuffer(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
(void)cinfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can not supply more data.
|
||||||
|
* We setup the data buffer already with everything we have.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::FillInputBuffer.\n");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrotherJFIFDecoder::SkipInputData(j_decompress_ptr cinfo, long num_bytes)
|
||||||
|
{
|
||||||
|
(void)cinfo;
|
||||||
|
(void)num_bytes;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Note the special attention required here.
|
||||||
|
* num_bytes might exceed the number of bytes in the src_data so we must remember
|
||||||
|
* the excess so that we can discard it when we add more data later!!!!!!!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::SkipInputData.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrotherJFIFDecoder::TermSource(j_decompress_ptr cinfo)
|
||||||
|
{
|
||||||
|
(void)cinfo;
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::TermSource.\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jmp_buf BrotherJFIFDecoder::my_env;
|
||||||
|
|
||||||
DecodeStatus BrotherJFIFDecoder::DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
DecodeStatus BrotherJFIFDecoder::DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
||||||
size_t *src_data_consumed, SANE_Byte *dest_data,
|
size_t *src_data_consumed, SANE_Byte *dest_data,
|
||||||
size_t dest_data_len, size_t *dest_data_written)
|
size_t dest_data_len, size_t *dest_data_written)
|
||||||
{
|
{
|
||||||
(void)src_data;
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData\n");
|
||||||
(void)src_data_len;
|
|
||||||
(void)src_data_consumed;
|
|
||||||
(void)dest_data;
|
|
||||||
(void)dest_data_len;
|
|
||||||
(void)dest_data_written;
|
|
||||||
|
|
||||||
// TODO: finish me.
|
|
||||||
|
*src_data_consumed = 0;
|
||||||
|
*dest_data_written = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise read buffer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
state.src_mgr.bytes_in_buffer = src_data_len;
|
||||||
|
state.src_mgr.next_input_byte = src_data;
|
||||||
|
|
||||||
|
if (setjmp(my_env) != 0)
|
||||||
|
{
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData: setjmp error return\n");
|
||||||
return DECODE_STATUS_ERROR;
|
return DECODE_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read header if we haven't yet.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (!state.have_read_header)
|
||||||
|
{
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData: Trying to read header.\n");
|
||||||
|
|
||||||
|
int read_status = jpeg_read_header(&state.cinfo, TRUE);
|
||||||
|
if (read_status == JPEG_SUSPENDED)
|
||||||
|
{
|
||||||
|
return DECODE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
else if (read_status != JPEG_HEADER_OK)
|
||||||
|
{
|
||||||
|
return DECODE_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
state.have_read_header = true;
|
||||||
|
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData: Starting decompress.\n");
|
||||||
|
|
||||||
|
if (!jpeg_start_decompress(&state.cinfo))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Need more data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
return DECODE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that we will be getting the data that we expect.
|
||||||
|
* This is for colour only, so we expect 3 components.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (state.cinfo.out_color_components != 3)
|
||||||
|
{
|
||||||
|
return DECODE_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Perhaps also check the dimensions are what we are expecting.
|
||||||
|
* Depending on the issues related to width alignment, we might
|
||||||
|
* have to do some trimming on the scan lines if we had to round up the
|
||||||
|
* the width and/or round down the left margin.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let's try to decompress some JPEG!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData: Converting data.\n");
|
||||||
|
|
||||||
|
SANE_Byte *output_ptr = dest_data;
|
||||||
|
|
||||||
|
const size_t line_size = sizeof(JSAMPLE) * state.cinfo.output_width * state.cinfo.out_color_components;
|
||||||
|
|
||||||
|
size_t output_size = dest_data_len;
|
||||||
|
|
||||||
|
while (output_size >= line_size)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Estimate the number of lines we can generate from
|
||||||
|
* the available output space.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// JDIMENSION max_lines = dest_data_len / (state.cinfo.output_width * 3);
|
||||||
|
|
||||||
|
JDIMENSION converted = jpeg_read_scanlines (&state.cinfo, &output_ptr, 1);
|
||||||
|
|
||||||
|
DBG (DBG_IMPORTANT,
|
||||||
|
"BrotherJFIFDecoder::DecodeScanData: Convert %u scanlines. Remaining scanlines: %u\n",
|
||||||
|
(unsigned int) converted, (unsigned int)(state.cinfo.output_height - state.cinfo.output_scanline));
|
||||||
|
|
||||||
|
output_size -= line_size;
|
||||||
|
output_ptr += converted * line_size;
|
||||||
|
|
||||||
|
if (converted == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Account for what we have processed.
|
||||||
|
*
|
||||||
|
* Note that libjpeg will have altered state.src_mgr.bytes_in_buffer
|
||||||
|
* to a backtracked position for it to restart again.
|
||||||
|
* This is why it is CRUCIAL that we do not try to guess.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
*dest_data_written = output_ptr - dest_data;
|
||||||
|
*src_data_consumed = src_data_len - state.src_mgr.bytes_in_buffer;
|
||||||
|
|
||||||
|
DBG (DBG_IMPORTANT,
|
||||||
|
"BrotherJFIFDecoder::DecodeScanData: Finished: consumed %zu bytes, written %zu bytes\n",
|
||||||
|
*src_data_consumed,
|
||||||
|
*dest_data_written);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have output all the scanlines, then we need to finish up.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (state.cinfo.output_scanline >= state.cinfo.output_height)
|
||||||
|
{
|
||||||
|
DBG (DBG_EVENT, "BrotherJFIFDecoder::DecodeScanData: Converted all scanlines. Finishing.\n");
|
||||||
|
|
||||||
|
if (!jpeg_finish_decompress(&state.cinfo))
|
||||||
|
{
|
||||||
|
return DECODE_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DECODE_STATUS_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BrotherGrayRawDecoder::Reset ()
|
void BrotherGrayRawDecoder::NewPage ()
|
||||||
|
{
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrotherGrayRawDecoder::NewBlock()
|
||||||
{
|
{
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
|
@ -33,6 +33,9 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <jpeglib.h>
|
||||||
|
#include <jerror.h>
|
||||||
|
|
||||||
#include "brother_mfp-common.h"
|
#include "brother_mfp-common.h"
|
||||||
|
|
||||||
#include "../include/sane/sane.h"
|
#include "../include/sane/sane.h"
|
||||||
|
@ -141,7 +144,6 @@ enum DecodeStatus
|
||||||
{
|
{
|
||||||
DECODE_STATUS_GOOD,
|
DECODE_STATUS_GOOD,
|
||||||
DECODE_STATUS_TRUNCATED,
|
DECODE_STATUS_TRUNCATED,
|
||||||
DECODE_STATUS_MORE,
|
|
||||||
DECODE_STATUS_ENDOFDATA,
|
DECODE_STATUS_ENDOFDATA,
|
||||||
DECODE_STATUS_ENDOFFRAME,
|
DECODE_STATUS_ENDOFFRAME,
|
||||||
DECODE_STATUS_ERROR
|
DECODE_STATUS_ERROR
|
||||||
|
@ -169,7 +171,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Reset() = 0;
|
virtual void NewPage() = 0;
|
||||||
|
|
||||||
SANE_Status SetScanMode (BrotherScanMode scan_mode);
|
SANE_Status SetScanMode (BrotherScanMode scan_mode);
|
||||||
SANE_Status SetRes (SANE_Int x, SANE_Int y);
|
SANE_Status SetRes (SANE_Int x, SANE_Int y);
|
||||||
|
@ -205,14 +207,79 @@ protected:
|
||||||
BrotherParameters scan_params;
|
BrotherParameters scan_params;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
|
||||||
class BrotherJFIFDecoder
|
class BrotherJFIFDecoder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Reset();
|
BrotherJFIFDecoder():
|
||||||
|
is_running(false)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Not sure if this is a safe way to get the cinfo into
|
||||||
|
* a consistent state but at least all pointers will be NULL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(void)memset(&state.cinfo, 0, sizeof(state.cinfo));
|
||||||
|
|
||||||
|
// TODO: override error stuff to avoid exit on error.
|
||||||
|
// Also provide a mechanism to check for errors.
|
||||||
|
state.cinfo.err = jpeg_std_error(&state.jerr);
|
||||||
|
state.cinfo.err->error_exit = ErrorExitManager;
|
||||||
|
|
||||||
|
jpeg_create_decompress (&state.cinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up source manager.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
state.src_mgr.init_source = InitSource;
|
||||||
|
state.src_mgr.fill_input_buffer = FillInputBuffer;
|
||||||
|
state.src_mgr.skip_input_data = SkipInputData;
|
||||||
|
state.src_mgr.resync_to_restart = jpeg_resync_to_restart;
|
||||||
|
state.src_mgr.term_source = TermSource;
|
||||||
|
|
||||||
|
state.cinfo.src = &state.src_mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ErrorExitManager(j_common_ptr cinfo)
|
||||||
|
{
|
||||||
|
(void)cinfo;
|
||||||
|
longjmp(my_env, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
~BrotherJFIFDecoder()
|
||||||
|
{
|
||||||
|
jpeg_destroy_decompress(&state.cinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewBlock();
|
||||||
|
void NewPage();
|
||||||
|
|
||||||
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
||||||
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
||||||
size_t *dest_data_written);
|
size_t *dest_data_written);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void InitSource (j_decompress_ptr cinfo);
|
||||||
|
static boolean FillInputBuffer(j_decompress_ptr cinfo);
|
||||||
|
static void SkipInputData(j_decompress_ptr cinfo, long num_bytes);
|
||||||
|
static void TermSource(j_decompress_ptr cinfo);
|
||||||
|
|
||||||
|
struct CompressionState
|
||||||
|
{
|
||||||
|
struct jpeg_decompress_struct cinfo;
|
||||||
|
struct jpeg_error_mgr jerr;
|
||||||
|
struct jpeg_source_mgr src_mgr;
|
||||||
|
bool have_read_header;
|
||||||
|
} state;
|
||||||
|
|
||||||
|
bool is_running;
|
||||||
|
|
||||||
|
// TODO: Move me to the state.
|
||||||
|
static jmp_buf my_env;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BrotherGrayRLengthDecoder
|
class BrotherGrayRLengthDecoder
|
||||||
|
@ -224,7 +291,8 @@ public:
|
||||||
block_bytes_left(0)
|
block_bytes_left(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void Reset();
|
void NewBlock();
|
||||||
|
void NewPage();
|
||||||
|
|
||||||
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
||||||
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
||||||
|
@ -251,7 +319,8 @@ public:
|
||||||
BrotherGrayRawDecoder()
|
BrotherGrayRawDecoder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void Reset();
|
void NewBlock();
|
||||||
|
void NewPage();
|
||||||
|
|
||||||
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
DecodeStatus DecodeScanData (const SANE_Byte *src_data, size_t src_data_len,
|
||||||
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
size_t *src_data_consumed, SANE_Byte *dst_data, size_t dest_data_len,
|
||||||
|
@ -267,7 +336,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void NewPage() override
|
||||||
{
|
{
|
||||||
current_header.block_type = 0;
|
current_header.block_type = 0;
|
||||||
}
|
}
|
|
@ -56,7 +56,7 @@
|
||||||
* TODO: I will remove this shortly anyway. For dev only.
|
* TODO: I will remove this shortly anyway. For dev only.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//#define BROTHER_ENABLE_SCAN_FILE 1
|
#define BROTHER_ENABLE_SCAN_FILE 1
|
||||||
|
|
||||||
/*-----------------------------------------------------------------*/
|
/*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -180,7 +180,9 @@ struct BrotherDevice
|
||||||
SANE_Int x_res;
|
SANE_Int x_res;
|
||||||
SANE_Int y_res;
|
SANE_Int y_res;
|
||||||
|
|
||||||
|
#ifdef BROTHER_ENABLE_SCAN_FILE
|
||||||
FILE *scan_file;
|
FILE *scan_file;
|
||||||
|
#endif
|
||||||
|
|
||||||
BrotherDriver *driver;
|
BrotherDriver *driver;
|
||||||
|
|
||||||
|
@ -1060,7 +1062,7 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
||||||
*/
|
*/
|
||||||
device->params = *params;
|
device->params = *params;
|
||||||
|
|
||||||
DBG (DBG_SERIOUS,
|
DBG (DBG_IMPORTANT,
|
||||||
"sane_get_parameters: params: format:%d last_frame:%d bytes_per_line:%d "
|
"sane_get_parameters: params: format:%d last_frame:%d bytes_per_line:%d "
|
||||||
"pixels_per_line: %d lines:%d depth:%d\n",
|
"pixels_per_line: %d lines:%d depth:%d\n",
|
||||||
params->format,
|
params->format,
|
||||||
|
@ -1070,12 +1072,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
||||||
params->lines,
|
params->lines,
|
||||||
params->depth);
|
params->depth);
|
||||||
|
|
||||||
// SANE_Frame format;
|
|
||||||
// SANE_Bool last_frame;
|
|
||||||
// SANE_Int bytes_per_line;
|
|
||||||
// SANE_Int pixels_per_line;
|
|
||||||
// SANE_Int lines;
|
|
||||||
// SANE_Int depth;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,11 +1127,13 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
|
||||||
|
|
||||||
*length = 0;
|
*length = 0;
|
||||||
|
|
||||||
|
#ifdef BROTHER_ENABLE_SCAN_FILE
|
||||||
if (!device->scan_file)
|
if (!device->scan_file)
|
||||||
{
|
{
|
||||||
DBG (DBG_SERIOUS, "sane_read: no scan data file.\n");
|
DBG (DBG_SERIOUS, "sane_read: no scan data file.\n");
|
||||||
return SANE_STATUS_EOF;
|
return SANE_STATUS_EOF;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t scan_len = 0;
|
size_t scan_len = 0;
|
||||||
SANE_Status res = device->driver->ReadScanData(data, (size_t)max_length, &scan_len);
|
SANE_Status res = device->driver->ReadScanData(data, (size_t)max_length, &scan_len);
|
||||||
|
@ -1147,14 +1145,17 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
|
||||||
*/
|
*/
|
||||||
#ifdef BROTHER_ENABLE_SCAN_FILE
|
#ifdef BROTHER_ENABLE_SCAN_FILE
|
||||||
fwrite(data, *length, 1, device->scan_file);
|
fwrite(data, *length, 1, device->scan_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (res == SANE_STATUS_EOF)
|
if (res == SANE_STATUS_EOF)
|
||||||
{
|
{
|
||||||
DBG (DBG_EVENT, "sane_read: read receives EOF.\n");
|
DBG (DBG_EVENT, "sane_read: read receives EOF.\n");
|
||||||
|
#ifdef BROTHER_ENABLE_SCAN_FILE
|
||||||
fclose(device->scan_file);
|
fclose(device->scan_file);
|
||||||
device->scan_file = NULL;
|
device->scan_file = NULL;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Options for the brother_mfp backend
|
||||||
|
|
||||||
|
# Brother MFC-J4320DW
|
||||||
|
usb 0x04f9 0x033a
|
||||||
|
|
||||||
|
# device list for non-linux-systems (enable if autodetect fails):
|
||||||
|
#/dev/scanner
|
||||||
|
#/dev/usb/scanner0
|
|
@ -723,6 +723,9 @@ for backend in ${BACKENDS} ; do
|
||||||
BACKEND_LIBS_ENABLED="${BACKEND_LIBS_ENABLED} libsane-${backend}.la"
|
BACKEND_LIBS_ENABLED="${BACKEND_LIBS_ENABLED} libsane-${backend}.la"
|
||||||
BACKEND_CONFS_ENABLED="${BACKEND_CONFS_ENABLED} ${backend}.conf"
|
BACKEND_CONFS_ENABLED="${BACKEND_CONFS_ENABLED} ${backend}.conf"
|
||||||
BACKEND_MANS_ENABLED="${BACKEND_MANS_ENABLED} sane-${backend}.5"
|
BACKEND_MANS_ENABLED="${BACKEND_MANS_ENABLED} sane-${backend}.5"
|
||||||
|
if test x$backend = xbrother_mfp; then
|
||||||
|
with_brother_mfp_tests=yes
|
||||||
|
fi
|
||||||
if test x$backend = xgenesys; then
|
if test x$backend = xgenesys; then
|
||||||
with_genesys_tests=yes
|
with_genesys_tests=yes
|
||||||
fi
|
fi
|
||||||
|
@ -732,6 +735,7 @@ for backend in ${BACKENDS} ; do
|
||||||
done
|
done
|
||||||
AC_SUBST(BACKEND_LIBS_ENABLED)
|
AC_SUBST(BACKEND_LIBS_ENABLED)
|
||||||
AM_CONDITIONAL(WITH_GENESYS_TESTS, test xyes = x$with_genesys_tests)
|
AM_CONDITIONAL(WITH_GENESYS_TESTS, test xyes = x$with_genesys_tests)
|
||||||
|
AM_CONDITIONAL(WITH_BROTHER_MFP_TESTS, test xyes = x$with_brother_mfp_tests)
|
||||||
AM_CONDITIONAL(INSTALL_UMAX_PP_TOOLS, test xyes = x$install_umax_pp_tools)
|
AM_CONDITIONAL(INSTALL_UMAX_PP_TOOLS, test xyes = x$install_umax_pp_tools)
|
||||||
|
|
||||||
AC_ARG_VAR(PRELOADABLE_BACKENDS, [list of backends to preload into single DLL])
|
AC_ARG_VAR(PRELOADABLE_BACKENDS, [list of backends to preload into single DLL])
|
||||||
|
@ -824,6 +828,7 @@ AC_CONFIG_FILES([Makefile lib/Makefile sanei/Makefile frontend/Makefile \
|
||||||
po/Makefile.in testsuite/Makefile \
|
po/Makefile.in testsuite/Makefile \
|
||||||
testsuite/backend/Makefile \
|
testsuite/backend/Makefile \
|
||||||
testsuite/backend/genesys/Makefile \
|
testsuite/backend/genesys/Makefile \
|
||||||
|
testsuite/backend/brother_mfp/Makefile \
|
||||||
testsuite/sanei/Makefile testsuite/tools/Makefile \
|
testsuite/sanei/Makefile testsuite/tools/Makefile \
|
||||||
tools/Makefile doc/doxygen-sanei.conf doc/doxygen-genesys.conf])
|
tools/Makefile doc/doxygen-sanei.conf doc/doxygen-genesys.conf])
|
||||||
AC_CONFIG_FILES([tools/sane-config], [chmod a+x tools/sane-config])
|
AC_CONFIG_FILES([tools/sane-config], [chmod a+x tools/sane-config])
|
||||||
|
|
|
@ -5,5 +5,11 @@
|
||||||
## included LICENSE file for license information.
|
## included LICENSE file for license information.
|
||||||
|
|
||||||
if WITH_GENESYS_TESTS
|
if WITH_GENESYS_TESTS
|
||||||
SUBDIRS = genesys
|
SUBDIR_GENESYS = genesys
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if WITH_BROTHER_MFP_TESTS
|
||||||
|
SUBDIR_BROTHER_MFP = brother_mfp
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUBDIRS = $(SUBDIR_GENESYS) $(SUBDIR_BROTHER_MFP)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
## Makefile.am -- an automake template for Makefile.in file
|
||||||
|
## Copyright (C) 2022 Ralph Little <skelband@gmail.com>
|
||||||
|
##
|
||||||
|
## This file is part of the "Sane" build infra-structure. See
|
||||||
|
## included LICENSE file for license information.
|
||||||
|
|
||||||
|
TEST_LDADD = \
|
||||||
|
../../../sanei/libsanei.la \
|
||||||
|
../../../sanei/sanei_usb.lo \
|
||||||
|
../../../sanei/sanei_magic.lo \
|
||||||
|
../../../lib/liblib.la \
|
||||||
|
../../../backend/libbrother_mfp.la \
|
||||||
|
../../../backend/sane_strstatus.lo \
|
||||||
|
$(USB_LIBS) $(XML_LIBS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
check_PROGRAMS = brother_mfp_unit_tests
|
||||||
|
TESTS = brother_mfp_unit_tests
|
||||||
|
|
||||||
|
AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include $(USB_CFLAGS) \
|
||||||
|
-DBACKEND_NAME=brother_mfp -DTESTSUITE_BACKEND_BROTHER_MFP_SRCDIR=$(srcdir)
|
||||||
|
|
||||||
|
brother_mfp_unit_tests_SOURCES = brother_mfp_tests.cpp brother_mfp_tests.h
|
||||||
|
|
||||||
|
brother_mfp_unit_tests_LDADD = $(TEST_LDADD)
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* sane - Scanner Access Now Easy.
|
||||||
|
|
||||||
|
Copyright (C) 2022 Ralph Little <skelband@gmail.com>
|
||||||
|
|
||||||
|
This file is part of the SANE package.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG_DECLARE_ONLY
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "brother_mfp_tests.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("Brother MFP tests.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* sane - Scanner Access Now Easy.
|
||||||
|
|
||||||
|
Copyright (C) 2022 Ralph Little <skelband@gmail.com>
|
||||||
|
|
||||||
|
This file is part of the SANE package.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
Ładowanie…
Reference in New Issue