kopia lustrzana https://gitlab.com/sane-project/backends
fujitsu backend v121
- add JFIF APP0 marker with resolution to jpeg images - improve jpeg duplex parsing code - simplify jpeg ifdefs - add offtimer option for more recent scannersmerge-requests/1/head
rodzic
17a6615a11
commit
50236fab4e
|
@ -560,6 +560,13 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
|
||||||
#define set_SD_preread_composition(sb, val) putnbyte(sb + 0x1c, val, 1)
|
#define set_SD_preread_composition(sb, val) putnbyte(sb + 0x1c, val, 1)
|
||||||
#define set_SD_preread_escan(sb, val) putnbyte(sb + 0x1d, val, 1)
|
#define set_SD_preread_escan(sb, val) putnbyte(sb + 0x1d, val, 1)
|
||||||
|
|
||||||
|
#define SD_powoff_string "SET POWOFF TIME "
|
||||||
|
#define SD_powoff_stringlen 16
|
||||||
|
#define SD_powoff_len 18
|
||||||
|
#define set_SD_powoff_disable(in, val) setbitfield(in + 16, 1, 7, val)
|
||||||
|
#define set_SD_powoff_interval(in, val) setbitfield(in + 16, 0x7f, 0, val)
|
||||||
|
#define set_SD_powoff_notify(sb, val) putnbyte(sb + 0x17, val, 1)
|
||||||
|
|
||||||
/* ==================================================================== */
|
/* ==================================================================== */
|
||||||
/* SET_WINDOW */
|
/* SET_WINDOW */
|
||||||
#define SET_WINDOW_code 0x24
|
#define SET_WINDOW_code 0x24
|
||||||
|
|
|
@ -554,6 +554,11 @@
|
||||||
v120 2014-01-29, MAN
|
v120 2014-01-29, MAN
|
||||||
- only call hopper_before_op code at batch start
|
- only call hopper_before_op code at batch start
|
||||||
- remove unused backup/restore_params
|
- remove unused backup/restore_params
|
||||||
|
v121 2014-04-07, MAN
|
||||||
|
- add JFIF APP0 marker with resolution to jpeg images
|
||||||
|
- improve jpeg duplex parsing code
|
||||||
|
- simplify jpeg ifdefs
|
||||||
|
- add offtimer option for more recent scanners
|
||||||
|
|
||||||
SANE FLOW DIAGRAM
|
SANE FLOW DIAGRAM
|
||||||
|
|
||||||
|
@ -603,7 +608,7 @@
|
||||||
#include "fujitsu.h"
|
#include "fujitsu.h"
|
||||||
|
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
#define BUILD 120
|
#define BUILD 121
|
||||||
|
|
||||||
/* values for SANE_DEBUG_FUJITSU env var:
|
/* values for SANE_DEBUG_FUJITSU env var:
|
||||||
- errors 5
|
- errors 5
|
||||||
|
@ -616,6 +621,12 @@
|
||||||
- useless noise 35
|
- useless noise 35
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
/* if JPEG support is not enabled in sane.h, we setup our own defines */
|
||||||
|
#ifndef SANE_FRAME_JPEG
|
||||||
|
#define SANE_FRAME_JPEG 0x0B
|
||||||
|
#define SANE_JPEG_DISABLED 1
|
||||||
|
#endif
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
#define STRING_FLATBED SANE_I18N("Flatbed")
|
#define STRING_FLATBED SANE_I18N("Flatbed")
|
||||||
#define STRING_ADFFRONT SANE_I18N("ADF Front")
|
#define STRING_ADFFRONT SANE_I18N("ADF Front")
|
||||||
|
@ -1593,9 +1604,8 @@ init_vpd (struct fujitsu *s)
|
||||||
|
|
||||||
s->has_comp_JPG1 = get_IN_compression_JPG_BASE (in);
|
s->has_comp_JPG1 = get_IN_compression_JPG_BASE (in);
|
||||||
DBG (15, " compression JPG1: %d\n", s->has_comp_JPG1);
|
DBG (15, " compression JPG1: %d\n", s->has_comp_JPG1);
|
||||||
#ifndef SANE_FRAME_JPEG
|
#ifdef SANE_JPEG_DISABLED
|
||||||
DBG (15, " (Disabled)\n");
|
DBG (15, " (Disabled)\n");
|
||||||
s->has_comp_JPG1 = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->has_comp_JPG2 = get_IN_compression_JPG_EXT (in);
|
s->has_comp_JPG2 = get_IN_compression_JPG_EXT (in);
|
||||||
|
@ -1687,6 +1697,8 @@ init_vpd (struct fujitsu *s)
|
||||||
DBG (15, " rgb lut: %d\n", get_IN_rgb_lut(in));
|
DBG (15, " rgb lut: %d\n", get_IN_rgb_lut(in));
|
||||||
DBG (15, " num lut dl: %d\n", get_IN_num_lut_dl(in));
|
DBG (15, " num lut dl: %d\n", get_IN_num_lut_dl(in));
|
||||||
|
|
||||||
|
s->has_off_mode = get_IN_erp_lot6_supp(in);
|
||||||
|
DBG (15, " ErP Lot6 (power off timer): %d\n", s->has_off_mode);
|
||||||
DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in));
|
DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2360,6 +2372,8 @@ init_user (struct fujitsu *s)
|
||||||
s->adv_paper_prot = MSEL_ON;
|
s->adv_paper_prot = MSEL_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->off_time = 240;
|
||||||
|
|
||||||
DBG (10, "init_user: finish\n");
|
DBG (10, "init_user: finish\n");
|
||||||
|
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
|
@ -3427,7 +3441,9 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
||||||
s->compress_list[i++]=STRING_NONE;
|
s->compress_list[i++]=STRING_NONE;
|
||||||
|
|
||||||
if(s->has_comp_JPG1){
|
if(s->has_comp_JPG1){
|
||||||
|
#ifndef SANE_JPEG_DISABLED
|
||||||
s->compress_list[i++]=STRING_JPEG;
|
s->compress_list[i++]=STRING_JPEG;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
s->compress_list[i]=NULL;
|
s->compress_list[i]=NULL;
|
||||||
|
@ -3763,7 +3779,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
||||||
opt->cap = SANE_CAP_INACTIVE;
|
opt->cap = SANE_CAP_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*sleep time*/
|
/*sleep_time*/
|
||||||
if(option==OPT_SLEEP_TIME){
|
if(option==OPT_SLEEP_TIME){
|
||||||
s->sleep_time_range.min = 0;
|
s->sleep_time_range.min = 0;
|
||||||
s->sleep_time_range.max = 60;
|
s->sleep_time_range.max = 60;
|
||||||
|
@ -3782,6 +3798,25 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
||||||
opt->cap = SANE_CAP_INACTIVE;
|
opt->cap = SANE_CAP_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*off_time*/
|
||||||
|
if(option==OPT_OFF_TIME){
|
||||||
|
s->off_time_range.min = 0;
|
||||||
|
s->off_time_range.max = 960;
|
||||||
|
s->off_time_range.quant = 15;
|
||||||
|
|
||||||
|
opt->name = "offtimer";
|
||||||
|
opt->title = "Off timer";
|
||||||
|
opt->desc = "Time in minutes until the internal power supply switches the scanner off, 0 = never.";
|
||||||
|
opt->type = SANE_TYPE_INT;
|
||||||
|
opt->unit = SANE_UNIT_NONE;
|
||||||
|
opt->constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
opt->constraint.range=&s->sleep_time_range;
|
||||||
|
if(s->has_off_mode)
|
||||||
|
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||||
|
else
|
||||||
|
opt->cap = SANE_CAP_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
/*duplex offset*/
|
/*duplex offset*/
|
||||||
if(option==OPT_DUPLEX_OFFSET){
|
if(option==OPT_DUPLEX_OFFSET){
|
||||||
s->duplex_offset_range.min = -16;
|
s->duplex_offset_range.min = -16;
|
||||||
|
@ -4864,6 +4899,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
*val_p = s->sleep_time;
|
*val_p = s->sleep_time;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
|
|
||||||
|
case OPT_OFF_TIME:
|
||||||
|
*val_p = s->off_time;
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
|
||||||
case OPT_DUPLEX_OFFSET:
|
case OPT_DUPLEX_OFFSET:
|
||||||
*val_p = s->duplex_offset;
|
*val_p = s->duplex_offset;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
|
@ -5496,6 +5535,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
s->sleep_time = val_c;
|
s->sleep_time = val_c;
|
||||||
return set_sleep_mode(s);
|
return set_sleep_mode(s);
|
||||||
|
|
||||||
|
case OPT_OFF_TIME:
|
||||||
|
s->off_time = val_c;
|
||||||
|
return set_off_mode(s);
|
||||||
|
|
||||||
case OPT_DUPLEX_OFFSET:
|
case OPT_DUPLEX_OFFSET:
|
||||||
s->duplex_offset = val_c;
|
s->duplex_offset = val_c;
|
||||||
return SANE_STATUS_GOOD;
|
return SANE_STATUS_GOOD;
|
||||||
|
@ -5642,6 +5685,50 @@ set_sleep_mode(struct fujitsu *s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SANE_Status
|
||||||
|
set_off_mode(struct fujitsu *s)
|
||||||
|
{
|
||||||
|
SANE_Status ret = SANE_STATUS_GOOD;
|
||||||
|
|
||||||
|
unsigned char cmd[SEND_DIAGNOSTIC_len]; /*also big enough for READ_DIAG*/
|
||||||
|
size_t cmdLen = SEND_DIAGNOSTIC_len;
|
||||||
|
|
||||||
|
unsigned char out[SD_powoff_len];
|
||||||
|
size_t outLen = SD_powoff_len;
|
||||||
|
|
||||||
|
DBG (10, "set_off_mode: start\n");
|
||||||
|
|
||||||
|
if (!s->has_cmd_sdiag || !s->has_cmd_rdiag || !s->has_off_mode){
|
||||||
|
DBG (5, "set_off_mode: not supported, returning\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(cmd,0,cmdLen);
|
||||||
|
set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code);
|
||||||
|
set_SD_slftst(cmd, 0);
|
||||||
|
set_SD_xferlen(cmd, outLen);
|
||||||
|
|
||||||
|
memcpy(out,SD_powoff_string,SD_powoff_stringlen);
|
||||||
|
set_SD_powoff_disable(out,!s->off_time);
|
||||||
|
set_SD_powoff_interval(out,s->off_time/15);
|
||||||
|
|
||||||
|
ret = do_cmd (
|
||||||
|
s, 1, 0,
|
||||||
|
cmd, cmdLen,
|
||||||
|
out, outLen,
|
||||||
|
NULL, NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ret != SANE_STATUS_GOOD){
|
||||||
|
DBG (5, "set_off_mode: send diag error: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (10, "set_off_mode: finish\n");
|
||||||
|
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
get_hardware_status (struct fujitsu *s, SANE_Int option)
|
get_hardware_status (struct fujitsu *s, SANE_Int option)
|
||||||
{
|
{
|
||||||
|
@ -6502,7 +6589,6 @@ update_params (struct fujitsu * s)
|
||||||
if (s->s_mode == MODE_COLOR) {
|
if (s->s_mode == MODE_COLOR) {
|
||||||
params->depth = 8;
|
params->depth = 8;
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
/* jpeg requires 8x8 squares */
|
/* jpeg requires 8x8 squares */
|
||||||
if(s->compress == COMP_JPEG){
|
if(s->compress == COMP_JPEG){
|
||||||
params->format = SANE_FRAME_JPEG;
|
params->format = SANE_FRAME_JPEG;
|
||||||
|
@ -6510,20 +6596,16 @@ update_params (struct fujitsu * s)
|
||||||
params->lines -= params->lines % 8;
|
params->lines -= params->lines % 8;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
#endif
|
|
||||||
params->format = SANE_FRAME_RGB;
|
params->format = SANE_FRAME_RGB;
|
||||||
params->pixels_per_line -= params->pixels_per_line
|
params->pixels_per_line -= params->pixels_per_line
|
||||||
% max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
|
% max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
params->bytes_per_line = params->pixels_per_line * 3;
|
params->bytes_per_line = params->pixels_per_line * 3;
|
||||||
}
|
}
|
||||||
else if (s->s_mode == MODE_GRAYSCALE) {
|
else if (s->s_mode == MODE_GRAYSCALE) {
|
||||||
params->depth = 8;
|
params->depth = 8;
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
/* jpeg requires 8x8 squares */
|
/* jpeg requires 8x8 squares */
|
||||||
if(s->compress == COMP_JPEG){
|
if(s->compress == COMP_JPEG){
|
||||||
params->format = SANE_FRAME_JPEG;
|
params->format = SANE_FRAME_JPEG;
|
||||||
|
@ -6531,13 +6613,10 @@ update_params (struct fujitsu * s)
|
||||||
params->lines -= params->lines % 8;
|
params->lines -= params->lines % 8;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
#endif
|
|
||||||
params->format = SANE_FRAME_GRAY;
|
params->format = SANE_FRAME_GRAY;
|
||||||
params->pixels_per_line -= params->pixels_per_line
|
params->pixels_per_line -= params->pixels_per_line
|
||||||
% max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
|
% max(s->ppl_mod_by_mode[s->s_mode], s->ppl_mod_by_mode[s->u_mode]);
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
params->bytes_per_line = params->pixels_per_line;
|
params->bytes_per_line = params->pixels_per_line;
|
||||||
}
|
}
|
||||||
|
@ -6808,8 +6887,8 @@ sane_start (SANE_Handle handle)
|
||||||
s->buff_tx[1]=0;
|
s->buff_tx[1]=0;
|
||||||
|
|
||||||
/* reset jpeg just in case... */
|
/* reset jpeg just in case... */
|
||||||
s->jpeg_stage = JPEG_STAGE_HEAD;
|
s->jpeg_stage = JPEG_STAGE_NONE;
|
||||||
s->jpeg_ff_offset = 0;
|
s->jpeg_ff_offset = -1;
|
||||||
s->jpeg_front_rst = 0;
|
s->jpeg_front_rst = 0;
|
||||||
s->jpeg_back_rst = 0;
|
s->jpeg_back_rst = 0;
|
||||||
|
|
||||||
|
@ -7284,13 +7363,11 @@ set_window (struct fujitsu *s)
|
||||||
set_WD_compress_type(desc1, COMP_NONE);
|
set_WD_compress_type(desc1, COMP_NONE);
|
||||||
set_WD_compress_arg(desc1, 0);
|
set_WD_compress_arg(desc1, 0);
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
/* some scanners support jpeg image compression, for color/gs only */
|
/* some scanners support jpeg image compression, for color/gs only */
|
||||||
if(s->s_params.format == SANE_FRAME_JPEG){
|
if(s->s_params.format == SANE_FRAME_JPEG){
|
||||||
set_WD_compress_type(desc1, COMP_JPEG);
|
set_WD_compress_type(desc1, COMP_JPEG);
|
||||||
set_WD_compress_arg(desc1, s->compress_arg);
|
set_WD_compress_arg(desc1, s->compress_arg);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* the remainder of the block varies based on model and mode,
|
/* the remainder of the block varies based on model and mode,
|
||||||
* except for gamma and paper size, those are in the same place */
|
* except for gamma and paper size, those are in the same place */
|
||||||
|
@ -7752,7 +7829,6 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
|
||||||
}
|
}
|
||||||
} /* end 3091 */
|
} /* end 3091 */
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
/* alternating jpeg duplex interlacing */
|
/* alternating jpeg duplex interlacing */
|
||||||
else if(s->source == SOURCE_ADF_DUPLEX
|
else if(s->source == SOURCE_ADF_DUPLEX
|
||||||
&& s->s_params.format == SANE_FRAME_JPEG
|
&& s->s_params.format == SANE_FRAME_JPEG
|
||||||
|
@ -7764,11 +7840,10 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} /* end alt jpeg */
|
} /* end alt jpeg */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* alternating pnm duplex interlacing */
|
/* alternating pnm duplex interlacing */
|
||||||
else if(s->source == SOURCE_ADF_DUPLEX
|
else if(s->source == SOURCE_ADF_DUPLEX
|
||||||
&& s->s_params.format <= SANE_FRAME_RGB
|
&& s->s_params.format != SANE_FRAME_JPEG
|
||||||
&& s->duplex_interlace == DUPLEX_INTERLACE_ALT
|
&& s->duplex_interlace == DUPLEX_INTERLACE_ALT
|
||||||
){
|
){
|
||||||
|
|
||||||
|
@ -7837,7 +7912,33 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
/* bare jpeg images dont contain resolution, but JFIF APP0 does, so we add */
|
||||||
|
static SANE_Status
|
||||||
|
inject_jfif_header(struct fujitsu *s, int side)
|
||||||
|
{
|
||||||
|
SANE_Status ret=SANE_STATUS_GOOD;
|
||||||
|
|
||||||
|
unsigned char out[] = {
|
||||||
|
0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46,
|
||||||
|
0x00, 0x01, 0x02, 0x01, 0x00, 0x48, 0x00, 0x48,
|
||||||
|
0x00, 0x00
|
||||||
|
};
|
||||||
|
size_t outLen=JFIF_APP0_LENGTH;
|
||||||
|
|
||||||
|
DBG (10, "inject_jfif_header: start %d\n", side);
|
||||||
|
|
||||||
|
putnbyte(out + 12, s->resolution_x, 2);
|
||||||
|
putnbyte(out + 14, s->resolution_y, 2);
|
||||||
|
|
||||||
|
memcpy(s->buffers[side]+s->buff_rx[side], out, outLen);
|
||||||
|
s->buff_rx[side] += outLen;
|
||||||
|
s->bytes_rx[side] += outLen;
|
||||||
|
|
||||||
|
DBG (10, "inject_jfif_header: finish %d\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
read_from_JPEGduplex(struct fujitsu *s)
|
read_from_JPEGduplex(struct fujitsu *s)
|
||||||
{
|
{
|
||||||
|
@ -7863,13 +7964,21 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
* so we only get enough to fill whichever is smaller (and not yet done) */
|
* so we only get enough to fill whichever is smaller (and not yet done) */
|
||||||
if(!s->eof_rx[SIDE_FRONT]){
|
if(!s->eof_rx[SIDE_FRONT]){
|
||||||
int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
|
int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
|
||||||
if(bytes > avail)
|
if(bytes > avail){
|
||||||
bytes = avail;
|
bytes = avail;
|
||||||
|
/* leave space for JFIF header at start of image */
|
||||||
|
if(s->bytes_rx[SIDE_FRONT] < 2)
|
||||||
|
bytes -= JFIF_APP0_LENGTH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!s->eof_rx[SIDE_BACK]){
|
if(!s->eof_rx[SIDE_BACK]){
|
||||||
int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
|
int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
|
||||||
if(bytes > avail)
|
if(bytes > avail){
|
||||||
bytes = avail;
|
bytes = avail;
|
||||||
|
/* leave space for JFIF header at start of image */
|
||||||
|
if(s->bytes_rx[SIDE_BACK] < 2)
|
||||||
|
bytes -= JFIF_APP0_LENGTH;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG(15, "read_from_JPEGduplex: fto:%d frx:%d bto:%d brx:%d pa:%d\n",
|
DBG(15, "read_from_JPEGduplex: fto:%d frx:%d bto:%d brx:%d pa:%d\n",
|
||||||
|
@ -7930,7 +8039,7 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
for(i=0;i<(int)inLen;i++){
|
for(i=0;i<(int)inLen;i++){
|
||||||
|
|
||||||
/* about to change stage */
|
/* about to change stage */
|
||||||
if(in[i] == 0xff){
|
if(in[i] == 0xff && s->jpeg_ff_offset != 0){
|
||||||
s->jpeg_ff_offset=0;
|
s->jpeg_ff_offset=0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7938,9 +8047,21 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
/* last byte was an ff, this byte will change stage */
|
/* last byte was an ff, this byte will change stage */
|
||||||
if(s->jpeg_ff_offset == 0){
|
if(s->jpeg_ff_offset == 0){
|
||||||
|
|
||||||
/* headers (SOI/HuffTab/QTab/DRI), in both sides */
|
/* first marker after SOI is not APP0, add one */
|
||||||
if(in[i] == 0xd8 || in[i] == 0xc4
|
if(s->jpeg_stage == JPEG_STAGE_SOI && in[i] != 0xe0){
|
||||||
|| in[i] == 0xdb || in[i] == 0xdd){
|
inject_jfif_header(s,SIDE_FRONT);
|
||||||
|
inject_jfif_header(s,SIDE_BACK);
|
||||||
|
s->jpeg_stage = JPEG_STAGE_HEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SOI header, in both sides */
|
||||||
|
if(in[i] == 0xd8){
|
||||||
|
s->jpeg_stage = JPEG_STAGE_SOI;
|
||||||
|
DBG(15, "read_from_JPEGduplex: stage SOI\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* headers (HuffTab/QTab/DRI), in both sides */
|
||||||
|
else if(in[i] == 0xc4 || in[i] == 0xdb || in[i] == 0xdd){
|
||||||
s->jpeg_stage = JPEG_STAGE_HEAD;
|
s->jpeg_stage = JPEG_STAGE_HEAD;
|
||||||
DBG(15, "read_from_JPEGduplex: stage head\n");
|
DBG(15, "read_from_JPEGduplex: stage head\n");
|
||||||
}
|
}
|
||||||
|
@ -8001,6 +8122,11 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
s->jpeg_stage = JPEG_STAGE_EOI;
|
s->jpeg_stage = JPEG_STAGE_EOI;
|
||||||
DBG(15, "read_from_JPEGduplex: stage eoi %d %d\n",(int)inLen,i);
|
DBG(15, "read_from_JPEGduplex: stage eoi %d %d\n",(int)inLen,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* unknown, warn */
|
||||||
|
else if(in[i] != 0xff){
|
||||||
|
DBG(15, "read_from_JPEGduplex: unknown %02x\n", in[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s->jpeg_ff_offset++;
|
s->jpeg_ff_offset++;
|
||||||
|
|
||||||
|
@ -8054,7 +8180,8 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy these stages to front */
|
/* copy these stages to front */
|
||||||
if(s->jpeg_stage == JPEG_STAGE_HEAD
|
if(s->jpeg_stage == JPEG_STAGE_SOI
|
||||||
|
|| s->jpeg_stage == JPEG_STAGE_HEAD
|
||||||
|| s->jpeg_stage == JPEG_STAGE_SOF
|
|| s->jpeg_stage == JPEG_STAGE_SOF
|
||||||
|| s->jpeg_stage == JPEG_STAGE_SOS
|
|| s->jpeg_stage == JPEG_STAGE_SOS
|
||||||
|| s->jpeg_stage == JPEG_STAGE_EOI
|
|| s->jpeg_stage == JPEG_STAGE_EOI
|
||||||
|
@ -8072,7 +8199,8 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
/* copy these stages to back */
|
/* copy these stages to back */
|
||||||
if( s->jpeg_interlace == JPEG_INTERLACE_ALT
|
if( s->jpeg_interlace == JPEG_INTERLACE_ALT
|
||||||
&&
|
&&
|
||||||
( s->jpeg_stage == JPEG_STAGE_HEAD
|
( s->jpeg_stage == JPEG_STAGE_SOI
|
||||||
|
|| s->jpeg_stage == JPEG_STAGE_HEAD
|
||||||
|| s->jpeg_stage == JPEG_STAGE_SOF
|
|| s->jpeg_stage == JPEG_STAGE_SOF
|
||||||
|| s->jpeg_stage == JPEG_STAGE_SOS
|
|| s->jpeg_stage == JPEG_STAGE_SOS
|
||||||
|| s->jpeg_stage == JPEG_STAGE_EOI
|
|| s->jpeg_stage == JPEG_STAGE_EOI
|
||||||
|
@ -8115,7 +8243,6 @@ read_from_JPEGduplex(struct fujitsu *s)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
read_from_3091duplex(struct fujitsu *s)
|
read_from_3091duplex(struct fujitsu *s)
|
||||||
|
@ -8297,6 +8424,10 @@ read_from_scanner(struct fujitsu *s, int side)
|
||||||
bytes -= s->s_params.bytes_per_line;
|
bytes -= s->s_params.bytes_per_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* jpeg scans leave space for JFIF header at start of image */
|
||||||
|
if(s->s_params.format == SANE_FRAME_JPEG && s->bytes_rx[side] < 2)
|
||||||
|
bytes -= JFIF_APP0_LENGTH;
|
||||||
|
|
||||||
DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d av:%d\n",
|
DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d av:%d\n",
|
||||||
side, remain, s->buffer_size, bytes, avail);
|
side, remain, s->buffer_size, bytes, avail);
|
||||||
|
|
||||||
|
@ -8370,6 +8501,9 @@ read_from_scanner(struct fujitsu *s, int side)
|
||||||
if(s->s_mode==MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
|
if(s->s_mode==MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
|
||||||
copy_3091 (s, in, inLen, side);
|
copy_3091 (s, in, inLen, side);
|
||||||
}
|
}
|
||||||
|
else if(s->s_params.format == SANE_FRAME_JPEG){
|
||||||
|
copy_JPEG (s, in, inLen, side);
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
copy_buffer (s, in, inLen, side);
|
copy_buffer (s, in, inLen, side);
|
||||||
}
|
}
|
||||||
|
@ -8482,6 +8616,48 @@ copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SANE_Status
|
||||||
|
copy_JPEG(struct fujitsu *s, unsigned char * buf, int len, int side)
|
||||||
|
{
|
||||||
|
SANE_Status ret=SANE_STATUS_GOOD;
|
||||||
|
int i, seen = 0;
|
||||||
|
|
||||||
|
DBG (10, "copy_JPEG: start\n");
|
||||||
|
|
||||||
|
/* A jpeg image starts with the SOI marker, FF D8.
|
||||||
|
* This is optionally followed by the JFIF APP0
|
||||||
|
* marker, FF E0. If that marker is not present,
|
||||||
|
* we add it, so we can insert the resolution */
|
||||||
|
|
||||||
|
if(!s->bytes_rx[side] && len >= 4
|
||||||
|
&& buf[0] == 0xFF && buf[1] == 0xD8
|
||||||
|
&& buf[2] == 0xFF && buf[3] != 0xE0
|
||||||
|
){
|
||||||
|
/* SOI marker */
|
||||||
|
for (i=0; i<2; i++){
|
||||||
|
s->buffers[side][s->buff_rx[side]++] = buf[i];
|
||||||
|
s->bytes_rx[side]++;
|
||||||
|
seen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* JFIF header after SOI */
|
||||||
|
inject_jfif_header(s,side);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(s->buffers[side]+s->buff_rx[side],buf+seen,len-seen);
|
||||||
|
s->buff_rx[side] += len-seen;
|
||||||
|
s->bytes_rx[side] += len-seen;
|
||||||
|
|
||||||
|
/* should never happen with jpeg */
|
||||||
|
if(s->bytes_rx[side] == s->bytes_tot[side]){
|
||||||
|
s->eof_rx[side] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (10, "copy_JPEG: finish\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side)
|
copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side)
|
||||||
{
|
{
|
||||||
|
@ -8494,7 +8670,7 @@ copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side)
|
||||||
|
|
||||||
/* invert image if scanner needs it for this mode */
|
/* invert image if scanner needs it for this mode */
|
||||||
/* jpeg data does not use inverting */
|
/* jpeg data does not use inverting */
|
||||||
if(s->s_params.format <= SANE_FRAME_RGB && s->reverse_by_mode[s->s_mode]){
|
if(s->s_params.format != SANE_FRAME_JPEG && s->reverse_by_mode[s->s_mode]){
|
||||||
for(i=0; i<len; i++){
|
for(i=0; i<len; i++){
|
||||||
buf[i] ^= 0xff;
|
buf[i] ^= 0xff;
|
||||||
}
|
}
|
||||||
|
@ -9483,9 +9659,7 @@ must_fully_buffer(struct fujitsu *s)
|
||||||
|
|
||||||
if(
|
if(
|
||||||
(s->swdeskew || s->swdespeck || s->swcrop || s->swskip)
|
(s->swdeskew || s->swdespeck || s->swcrop || s->swskip)
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
&& s->s_params.format != SANE_FRAME_JPEG
|
&& s->s_params.format != SANE_FRAME_JPEG
|
||||||
#endif
|
|
||||||
){
|
){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -9499,9 +9673,7 @@ static int
|
||||||
must_downsample(struct fujitsu *s)
|
must_downsample(struct fujitsu *s)
|
||||||
{
|
{
|
||||||
if(s->s_mode != s->u_mode
|
if(s->s_mode != s->u_mode
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
&& s->compress != COMP_JPEG
|
&& s->compress != COMP_JPEG
|
||||||
#endif
|
|
||||||
){
|
){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum fujitsu_Option
|
||||||
OPT_PREPICK,
|
OPT_PREPICK,
|
||||||
OPT_OVERSCAN,
|
OPT_OVERSCAN,
|
||||||
OPT_SLEEP_TIME,
|
OPT_SLEEP_TIME,
|
||||||
|
OPT_OFF_TIME,
|
||||||
OPT_DUPLEX_OFFSET,
|
OPT_DUPLEX_OFFSET,
|
||||||
OPT_GREEN_OFFSET,
|
OPT_GREEN_OFFSET,
|
||||||
OPT_BLUE_OFFSET,
|
OPT_BLUE_OFFSET,
|
||||||
|
@ -259,6 +260,7 @@ struct fujitsu
|
||||||
int has_ipc3;
|
int has_ipc3;
|
||||||
int has_rotation;
|
int has_rotation;
|
||||||
int has_hybrid_crop_deskew;
|
int has_hybrid_crop_deskew;
|
||||||
|
int has_off_mode;
|
||||||
|
|
||||||
int has_comp_MH;
|
int has_comp_MH;
|
||||||
int has_comp_MR;
|
int has_comp_MR;
|
||||||
|
@ -394,6 +396,7 @@ struct fujitsu
|
||||||
SANE_String_Const prepick_list[4];
|
SANE_String_Const prepick_list[4];
|
||||||
SANE_String_Const overscan_list[4];
|
SANE_String_Const overscan_list[4];
|
||||||
SANE_Range sleep_time_range;
|
SANE_Range sleep_time_range;
|
||||||
|
SANE_Range off_time_range;
|
||||||
SANE_Range duplex_offset_range;
|
SANE_Range duplex_offset_range;
|
||||||
SANE_Range green_offset_range;
|
SANE_Range green_offset_range;
|
||||||
SANE_Range blue_offset_range;
|
SANE_Range blue_offset_range;
|
||||||
|
@ -480,6 +483,7 @@ struct fujitsu
|
||||||
int overscan;
|
int overscan;
|
||||||
int lamp_color;
|
int lamp_color;
|
||||||
int sleep_time;
|
int sleep_time;
|
||||||
|
int off_time;
|
||||||
int duplex_offset;
|
int duplex_offset;
|
||||||
int green_offset;
|
int green_offset;
|
||||||
int blue_offset;
|
int blue_offset;
|
||||||
|
@ -628,12 +632,16 @@ struct fujitsu
|
||||||
#define COMP_NONE WD_cmp_NONE
|
#define COMP_NONE WD_cmp_NONE
|
||||||
#define COMP_JPEG WD_cmp_JPG1
|
#define COMP_JPEG WD_cmp_JPG1
|
||||||
|
|
||||||
#define JPEG_STAGE_HEAD 0
|
#define JPEG_STAGE_NONE 0
|
||||||
#define JPEG_STAGE_SOF 1
|
#define JPEG_STAGE_SOI 1
|
||||||
#define JPEG_STAGE_SOS 2
|
#define JPEG_STAGE_HEAD 2
|
||||||
#define JPEG_STAGE_FRONT 3
|
#define JPEG_STAGE_SOF 3
|
||||||
#define JPEG_STAGE_BACK 4
|
#define JPEG_STAGE_SOS 4
|
||||||
#define JPEG_STAGE_EOI 5
|
#define JPEG_STAGE_FRONT 5
|
||||||
|
#define JPEG_STAGE_BACK 6
|
||||||
|
#define JPEG_STAGE_EOI 7
|
||||||
|
|
||||||
|
#define JFIF_APP0_LENGTH 18
|
||||||
|
|
||||||
/* these are same as scsi data to make code easier */
|
/* these are same as scsi data to make code easier */
|
||||||
#define MODE_LINEART WD_comp_LA
|
#define MODE_LINEART WD_comp_LA
|
||||||
|
@ -795,6 +803,7 @@ static SANE_Status mode_select_prepick (struct fujitsu *s);
|
||||||
static SANE_Status mode_select_auto (struct fujitsu *s);
|
static SANE_Status mode_select_auto (struct fujitsu *s);
|
||||||
|
|
||||||
static SANE_Status set_sleep_mode(struct fujitsu *s);
|
static SANE_Status set_sleep_mode(struct fujitsu *s);
|
||||||
|
static SANE_Status set_off_mode(struct fujitsu *s);
|
||||||
|
|
||||||
static int must_downsample (struct fujitsu *s);
|
static int must_downsample (struct fujitsu *s);
|
||||||
static int must_fully_buffer (struct fujitsu *s);
|
static int must_fully_buffer (struct fujitsu *s);
|
||||||
|
@ -814,13 +823,12 @@ static SANE_Status start_scan (struct fujitsu *s);
|
||||||
|
|
||||||
static SANE_Status check_for_cancel(struct fujitsu *s);
|
static SANE_Status check_for_cancel(struct fujitsu *s);
|
||||||
|
|
||||||
#ifdef SANE_FRAME_JPEG
|
|
||||||
static SANE_Status read_from_JPEGduplex(struct fujitsu *s);
|
static SANE_Status read_from_JPEGduplex(struct fujitsu *s);
|
||||||
#endif
|
|
||||||
static SANE_Status read_from_3091duplex(struct fujitsu *s);
|
static SANE_Status read_from_3091duplex(struct fujitsu *s);
|
||||||
static SANE_Status read_from_scanner(struct fujitsu *s, int side);
|
static SANE_Status read_from_scanner(struct fujitsu *s, int side);
|
||||||
|
|
||||||
static SANE_Status copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side);
|
static SANE_Status copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side);
|
||||||
|
static SANE_Status copy_JPEG(struct fujitsu *s, unsigned char * buf, int len, int side);
|
||||||
static SANE_Status copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side);
|
static SANE_Status copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side);
|
||||||
|
|
||||||
static SANE_Status read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
|
static SANE_Status read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
|
||||||
|
|
Ładowanie…
Reference in New Issue