diff options
Diffstat (limited to 'backend/avision.c')
| -rw-r--r-- | backend/avision.c | 2112 | 
1 files changed, 1058 insertions, 1054 deletions
diff --git a/backend/avision.c b/backend/avision.c index 61491a2..55b5f4f 100644 --- a/backend/avision.c +++ b/backend/avision.c @@ -44,7 +44,7 @@     74xx, Minolta FS-V1 ...) or Fujitsu ScanPartner with the AVISION SCSI-2/3     or USB command set and written by René Rebe and Meino Cramer. -    +     Copyright 2002 - 2015 by                 	"Ren Rebe" <rene@exactcode.de> @@ -54,7 +54,7 @@     Copyright 2002 by                  "Jose Paulo Moitinho de Almeida" <moitinho@civil.ist.utl.pt> -    +     Copyright 2010, 2011 by                  "Mike Kelly" <mike@piratehaven.org> @@ -73,7 +73,7 @@                     OS/2 threading support                  "Falk Rohsiepe"                     Spelling and whitespace as well as HP5370 quirks -    +     Many additional special thanks to:                  Avision INC for providing protocol documentation.                  Avision INC for sponsoring an AV 8000S with ADF. @@ -90,7 +90,7 @@                  Thanks to all the people and companies above. Without you                  the Avision backend would not be in the shape it is today! ;-) -    +  ********************************************************************************/  /* SANE-FLOW-DIAGRAMM (from umax.c) @@ -166,13 +166,13 @@ static Avision_HWEntry Avision_Device_List [] =        "Avision", "AV100CS",        0},      /* status="untested" */ -     +      { "AVISION", "AV100IIICS",        0, 0,        "Avision", "AV100IIICS",        0},      /* status="untested" */ -     +      { "AVISION", "AV100S",        0, 0,        "Avision", "AV100S", @@ -199,7 +199,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON | AV_2ND_LINE_INTERLACED | AV_NO_REAR | AV_SOFT_SCALE | AV_DOES_KEEP_WINDOW | AV_DOES_KEEP_GAMMA | AV_REAR_OFFSET},      /* comment="sheetfed duplex scanner" */      /* status="good" */ -     +      { NULL, NULL,        0x0638, 0x0A93,        "Avision", "AV122 C2", @@ -213,7 +213,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON  | AV_ACCEL_TABLE},      /* comment="sheetfed scanner" */      /* status="complete" */ -     +      { NULL, NULL,        0x0638, 0x0A25,        "Avision", "AV210", @@ -303,37 +303,37 @@ static Avision_HWEntry Avision_Device_List [] =        "Avision", "AV240SC",        0},      /* status="untested" */ -     +      { "AVISION", "AV260CS",        0, 0,        "Avision", "AV260CS",        0},      /* status="untested" */ -     +      { "AVISION", "AV360CS",        0, 0,        "Avision", "AV360CS",        0},      /* status="untested" */ -     +      { "AVISION", "AV363CS",        0, 0,        "Avision", "AV363CS",        0},      /* status="untested" */ -     +      { "AVISION", "AV420CS",        0, 0,        "Avision", "AV420CS",        0},      /* status="untested" */ -     +      { "AVISION", "AV6120",        0, 0,        "Avision", "AV6120",        0},      /* status="untested" */ -     +      { NULL, "AV610",        0x0638, 0x0a18,        "Avision", "AV610", @@ -353,7 +353,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_NO_BACKGROUND | AV_INT_BUTTON}, /* cancel button -> sense abort! */      /* status="good" */ -   { NULL, NULL,  +   { NULL, NULL,       0x0638, 0x0a41,       "Avision", "AM3000 Series",        0}, @@ -373,35 +373,35 @@ static Avision_HWEntry Avision_Device_List [] =        0},      /* comment="1 pass, 600 dpi" */      /* status="complete" */ -     +      { "AVISION", "AV620CS Plus",        0, 0,        "Avision", "AV620CS Plus",        0},      /* comment="1 pass, 1200 dpi" */      /* status="complete" */ -     +      { "AVISION", "AV630CS",        0, 0,        "Avision", "AV630CS",        0},      /* comment="1 pass, 1200 dpi" */      /* status="complete" */ -     +      { "AVISION", "AV630CSL",        0, 0,        "Avision", "AV630CSL",        0},      /* comment="1 pass, 1200 dpi" */      /* status="untested" */ -     +      { "AVISION", "AV6240",        0, 0,        "Avision", "AV6240",        0},      /* comment="1 pass, ??? dpi" */      /* status="complete" */ -     +      { NULL, NULL,        0x0638, 0x0A13,        "Avision", "AV600U", @@ -422,70 +422,70 @@ static Avision_HWEntry Avision_Device_List [] =        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV690U",        0, 0,        "Avision", "AV690U",        0},      /* comment="1 pass, 2400 dpi" */      /* status="untested" */ -     +      { "AVISION", "AV800S",        0, 0,        "Avision", "AV800S",        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV810C",        0, 0,        "Avision", "AV810C",        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV820",        0, 0,        "Avision", "AV820",        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV820C",        0, 0,        "Avision", "AV820C",        0},      /* comment="1 pass, ??? dpi" */      /* status="complete" */ -     +      { "AVISION", "AV820C Plus",        0, 0,        "Avision", "AV820C Plus",        0},      /* comment="1 pass, ??? dpi" */      /* status="complete" */ -     +      { "AVISION", "AV830C",        0, 0,        "Avision", "AV830C",        0},      /* comment="1 pass, ??? dpi" */      /* status="complete" */ -     +      { "AVISION", "AV830C Plus",        0, 0,        "Avision", "AV830C Plus",        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV880",        0, 0,        "Avision", "AV880",        0},      /* comment="1 pass, ??? dpi" */      /* status="untested" */ -     +      { "AVISION", "AV880C",        0, 0,        "Avision", "AV880C", @@ -613,7 +613,7 @@ static Avision_HWEntry Avision_Device_List [] =      /* status="basic" */      /* and possibly more avisions ;-) */ -     +      { "HP",      "ScanJet 5300C",        0x03f0, 0x0701,        "Hewlett-Packard", "ScanJet 5300C", @@ -627,14 +627,14 @@ static Avision_HWEntry Avision_Device_List [] =        AV_MULTI_CALIB_CMD | AV_INT_STATUS},      /* comment="1 pass, 2400 dpi - some FW revisions have x-axis image scaling problems over 1200 dpi" */      /* status="good" */ -     +      { "hp",      "scanjet 7400c",        0x03f0, 0x0801,        "Hewlett-Packard", "ScanJet 7400c",        AV_LIGHT_CHECK_BOGUS | AV_NO_64BYTE_ALIGN | AV_INT_STATUS},      /* comment="1 pass, 2400 dpi - dual USB/SCSI interface" */      /* status="good" */ -     +  #ifdef FAKE_ENTRIES_FOR_DESC_GENERATION      { "hp",      "scanjet 7450c",        0x03f0, 0x0801, @@ -642,7 +642,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_NO_64BYTE_ALIGN | AV_INT_STATUS},      /* comment="1 pass, 2400 dpi - dual USB/SCSI interface" */      /* status="good" */ -     +      { "hp",      "scanjet 7490c",        0x03f0, 0x0801,        "Hewlett-Packard", "ScanJet 7490c", @@ -681,8 +681,8 @@ static Avision_HWEntry Avision_Device_List [] =        AV_ADF_FLIPPING_DUPLEX | AV_FIRMWARE},      /* comment="1 pass, 4800 (?) dpi - USB 2.0 and SCSI - only SCSI tested so far" */      /* status="good" */ -     -#endif  + +#endif      { "HP", "C9930A",        0x03f0, 0x3805,        "Hewlett-Packard", "ScanJet 8300", @@ -705,7 +705,7 @@ static Avision_HWEntry Avision_Device_List [] =      /* comment="1 pass, 4800 (?) dpi - USB 2.0" */      /* status="good" */ -#endif  +#endif      { "Minolta", "#2882",        0, 0,        "Minolta", "Dimage Scan Dual I", @@ -717,21 +717,21 @@ static Avision_HWEntry Avision_Device_List [] =        "Minolta", "Scan Multi Pro",        AV_FORCE_FILM | AV_NO_START_SCAN}, /* AV_FILMSCANNER (frame control)? */      /* status="untested" */ -     +      { "MINOLTA", "FS-V1",        0x0638, 0x026a,        "Minolta", "Dimage Scan Dual II",        AV_FILMSCANNER | AV_ONE_CALIB_CMD | AV_12_BIT_MODE},      /* comment="1 pass, film-scanner" */      /* status="good" */ -     +      { "MINOLTA", "Elite II",        0x0686, 0x4004,        "Minolta", "Elite II",        AV_FILMSCANNER | AV_ONE_CALIB_CMD},      /* comment="1 pass, film-scanner" */      /* status="untested" */ -     +      { "MINOLTA", "FS-V3",        0x0686, 0x400d,        "Minolta", "Dimage Scan Dual III", @@ -759,33 +759,33 @@ static Avision_HWEntry Avision_Device_List [] =        0},      /* comment="" */      /* status="good" */ -     +      { "MITSBISH", "MCA-ADFC",        0, 0,        "Mitsubishi", "MCA-ADFC",        0},      /* status="untested" */ -     +      { "MITSBISH", "MCA-S1200C",        0, 0,        "Mitsubishi", "S1200C",        0},      /* status="untested" */ -     +      { "MITSBISH", "MCA-S600C",        0, 0,        "Mitsubishi", "S600C",        0},      /* status="untested" */ -     +      { "MITSBISH", "SS600",        0, 0,        "Mitsubishi", "SS600",        0},      /* status="good" */ -     +      /* The next are all untested ... */ -     +      { "FCPA", "ScanPartner",        0, 0,        "Fujitsu", "ScanPartner", @@ -797,25 +797,25 @@ static Avision_HWEntry Avision_Device_List [] =        "Fujitsu", "ScanPartner 10",        AV_FUJITSU},      /* status="untested" */ -     +      { "FCPA", "ScanPartner 10C",        0, 0,        "Fujitsu", "ScanPartner 10C",        AV_FUJITSU},      /* status="untested" */ -     +      { "FCPA", "ScanPartner 15C",        0, 0,        "Fujitsu", "ScanPartner 15C",        AV_FUJITSU},      /* status="untested" */ -     +      { "FCPA", "ScanPartner 300C",        0, 0,        "Fujitsu", "ScanPartner 300C",        0},      /* status="untested" */ -     +      { "FCPA", "ScanPartner 600C",        0, 0,        "Fujitsu", "ScanPartner 600C", @@ -827,13 +827,13 @@ static Avision_HWEntry Avision_Device_List [] =        "Fujitsu", "ScanPartner 620C",        AV_LIGHT_CHECK_BOGUS},      /* status="good" */ -     +      { "FCPA", "ScanPartner Jr",        0, 0,        "Fujitsu", "ScanPartner Jr",        0},      /* status="untested" */ -     +      { "FCPA", "ScanStation",        0, 0,        "Fujitsu", "ScanStation", @@ -863,13 +863,13 @@ static Avision_HWEntry Avision_Device_List [] =        "Kodak", "i40",        AV_INT_BUTTON | AV_GRAY_MODES},      /* status="basic" */ -     +      { NULL, NULL,        0x040a, 0x6003,        "Kodak", "i50",        AV_INT_BUTTON},      /* status="untested" */ -     +  #ifdef FAKE_ENTRIES_FOR_DESC_GENERATION      { NULL, NULL,        0x040a, 0x6003, @@ -877,13 +877,13 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON},      /* status="untested" */  #endif -     +      { NULL, NULL,        0x040a, 0x6004,        "Kodak", "i60",        AV_INT_BUTTON},      /* status="untested" */ -     +  #ifdef FAKE_ENTRIES_FOR_DESC_GENERATION      { NULL, NULL,        0x040a, 0x6004, @@ -891,19 +891,19 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON},      /* status="untested" */  #endif -     +      { NULL, NULL,        0x040a, 0x6005,        "Kodak", "i80",        AV_INT_BUTTON}, -     /* status="good" */  -     +     /* status="good" */ +      { "iVina", "1200U",        0x0638, 0x0268,        "iVina", "1200U",        0},      /* status="untested" */ -     +      { NULL, NULL,        0x04a7, 0x0424,        "Visioneer", "Strobe XP 450", @@ -917,7 +917,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON  | AV_ACCEL_TABLE},        /* comment="sheetfed scanner" */        /* status="complete" */ -     +      { NULL, NULL,        0x04a7, 0x0479,        "Visioneer", "Strobe XP 470", @@ -931,7 +931,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON  | AV_ACCEL_TABLE},        /* comment="sheetfed scanner" */        /* status="complete" */ -     +      { NULL, NULL,        0x04a7, 0x0420,        "Visioneer", "9320", @@ -973,7 +973,7 @@ static Avision_HWEntry Avision_Device_List [] =        0},        /* comment="sheetfed scanner" */        /* status="complete" */ -     +      { NULL, NULL,        0x04a7, 0x0423,        "Visioneer", "9750", @@ -1017,7 +1017,7 @@ static Avision_HWEntry Avision_Device_List [] =        AV_INT_BUTTON},        /* comment="sheetfed scanner" */        /* status="complete" */ -     +      { NULL, NULL,        0x04a7, 0x049C,        "Xerox", "DocuMate150", @@ -1047,7 +1047,7 @@ static Avision_HWEntry Avision_Device_List [] =        "Xerox", "DocuMate250-G",        AV_INT_BUTTON},      /* status="good" */ -     +      { NULL, NULL,        0x04a7, 0x0449,        "Xerox", "DocuMate252", @@ -1059,7 +1059,7 @@ static Avision_HWEntry Avision_Device_List [] =        "Xerox", "DocuMate252-G",        AV_INT_BUTTON},      /* status="good" */ -     +      { NULL, NULL,        0x04a7, 0x0476,        "Xerox", "DocuMate232", @@ -1077,7 +1077,7 @@ static Avision_HWEntry Avision_Device_List [] =        "Xerox", "DocuMate262-G",        AV_INT_BUTTON},      /* status="good" */ -     +      { NULL, NULL,        0x04a7, 0x04a7,        "Xerox", "DocuMate262i", @@ -1095,7 +1095,7 @@ static Avision_HWEntry Avision_Device_List [] =        "Xerox", "DocuMate272-G",        AV_INT_BUTTON},      /* status="untested" */ -     +      { NULL, NULL,        0x04a7, 0x0446,        "Xerox", "DocuMate510", @@ -1179,35 +1179,35 @@ static Avision_HWEntry Avision_Device_List [] =         V6240 */      /* Possibly: -Lexmark 4600 MFP Option MFP Options  -Lexmark 4600 MFP Option (C772n) MFP Options    +Lexmark 4600 MFP Option MFP Options +Lexmark 4600 MFP Option (C772n) MFP Options  Lexmark X215 -Lexmark Optra Image X242  +Lexmark Optra Image X242  Lexmark X443  Lexmark 3100 -Lexmark 3200  -Lexmark X340 MFP Multifunction    -Lexmark X342n MFP Multifunction    +Lexmark 3200 +Lexmark X340 MFP Multifunction +Lexmark X342n MFP Multifunction  Lexmark X522  Lexmark X630  Lexmark X632E -Lexmark X642e MFP Multifunction    -Lexmark X644e MFP Multifunction    -Lexmark X646dte MFP Multifunction    -Lexmark X646e MFP Multifunction    -Lexmark X646ef MFP Multifunction    -Lexmark X772e Multifunction    -Lexmark X850e MFP Multifunction    -Lexmark X852e MFP Multifunction    -Lexmark X854e MFP Multifunction    +Lexmark X642e MFP Multifunction +Lexmark X644e MFP Multifunction +Lexmark X646dte MFP Multifunction +Lexmark X646e MFP Multifunction +Lexmark X646ef MFP Multifunction +Lexmark X772e Multifunction +Lexmark X850e MFP Multifunction +Lexmark X852e MFP Multifunction +Lexmark X854e MFP Multifunction  Lexmark X4500 MFP       */ -     +      /* last entry detection */      { NULL, NULL,        0, 0,        NULL, NULL, -      0}  +      0}    };  #if 0 @@ -1316,13 +1316,6 @@ static const SANE_Range percentage_range =      SANE_FIX (1) /* quantization */    }; -static const SANE_Range abs_percentage_range = -  { -    SANE_FIX (0), /* minimum */ -    SANE_FIX (100), /* maximum */ -    SANE_FIX (1) /* quantization */ -  }; -  static const SANE_Range exposure_range =    {      0, /* minimum */ @@ -1352,20 +1345,26 @@ static const uint8_t test_unit_ready[] =      AVISION_SCSI_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00    }; +/* Remove #ifdef and this comment when this SCSI command is used for +   something.  Keeping this definition around so we don't loose info +   about the protocol. + */ +#ifdef ENABLE_AVISION_SCSI_GET_DATA_STATUS  static const uint8_t get_status[] =    { -    AVISION_SCSI_GET_DATA_STATUS, 0x00, 0x00, 0x00, 0x00, 0x00,  +    AVISION_SCSI_GET_DATA_STATUS, 0x00, 0x00, 0x00, 0x00, 0x00,      0x00, 0x00, 0x0c, 0x00    }; +#endif  static size_t  max_string_size (const SANE_String_Const strings[])  {    size_t size, max_size = 0;    int i; -   +    DBG (3, "max_string_size:\n"); -   +    for (i = 0; strings[i]; ++ i) {      size = strlen (strings[i]) + 1;      if (size > max_size) @@ -1386,7 +1385,7 @@ static void debug_print_raw (int dbg_level, char* info, const uint8_t* data,  			     size_t count)  {    size_t i; -   +    DBG (dbg_level, "%s", info);    for (i = 0; i < count; ++ i) {      DBG (dbg_level, "  [%lu] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n", @@ -1412,7 +1411,7 @@ static void debug_print_hex_raw (int dbg_level, char* info, const uint8_t* data,        count--; i++;      }      *--t = 0; -     +      DBG (dbg_level, "  [%08x] %s\n", address, text);      address += 16;    } @@ -1429,7 +1428,7 @@ static void debug_print_nvram_data (int dbg_level, char* func,         func, get_quad(nvram->adf_duplex_scans));    DBG (dbg_level, "%s: flatbed scans:         %d\n",         func, get_quad(nvram->flatbed_scans)); -   +    DBG (dbg_level, "%s: flatbed leading edge:  %d\n",         func, (int16_t)get_double(nvram->flatbed_leading_edge));    DBG (dbg_level, "%s: flatbed side edge:     %d\n", @@ -1442,7 +1441,7 @@ static void debug_print_nvram_data (int dbg_level, char* func,         func, (int16_t)get_double(nvram->adf_rear_leading_edge));    DBG (dbg_level, "%s: ADF rear side edge:    %d\n",         func, (int16_t)get_double(nvram->adf_rear_side_edge)); -   +    DBG (dbg_level, "%s: born month:            %d\n",         func, get_double(nvram->born_month));    DBG (dbg_level, "%s: born day:              %d\n", @@ -1456,7 +1455,7 @@ static void debug_print_nvram_data (int dbg_level, char* func,         func, get_double(nvram->first_scan_day));    DBG (dbg_level, "%s: first scan year:       %d\n",         func, get_double(nvram->first_scan_year)); -   +    DBG (dbg_level, "%s: vert. magnification:   %d\n",         func, get_double(nvram->vertical_magnification)); @@ -1467,10 +1466,10 @@ static void debug_print_nvram_data (int dbg_level, char* func,         func, nvram->ccd_type);    DBG (dbg_level, "%s: scan speed:            %d\n",         func, nvram->scan_speed); -   +    DBG (dbg_level, "%s: serial:                '%.24s'\n", /* 24 chars max */         func, nvram->serial); -   +    DBG (dbg_level, "%s: power saving time:     %d\n",         func, get_double(nvram->power_saving_time)); @@ -1495,11 +1494,11 @@ static void debug_print_avdimen (int dbg_level, char* func,  {    DBG (dbg_level, "%s: hw_xres: %d, hw_yres: %d, line_difference: %d\n",         func, avdimen->hw_xres, avdimen->hw_yres, avdimen->line_difference); -   +    DBG (dbg_level, "%s: tlx: %ld, tly: %ld, brx: %ld, bry: %ld\n",         func, avdimen->tlx, avdimen->tly,         avdimen->brx, avdimen->bry); -   +    DBG (dbg_level, "%s: hw_pixel_per_line: %d, hw_lines: %d, hw_bytes_per_line: %d\n",         func, avdimen->hw_pixels_per_line, avdimen->hw_lines, avdimen->hw_bytes_per_line); @@ -1520,18 +1519,18 @@ static void debug_print_calib_format (int dbg_level, char* func,  				      uint8_t* result)  {    debug_print_raw (dbg_level + 2, "debug_print_calib_format:\n", result, 32); -   +    DBG (dbg_level, "%s: [0-1]  pixels per line: %d\n",         func, get_double ( &(result[0]) ));    DBG (dbg_level, "%s: [2]    bytes per channel: %d\n", func, result[2]);    DBG (dbg_level, "%s: [3]    line count: %d\n", func, result[3]); -   +    DBG (dbg_level, "%s: [4]    FLAG:%s%s%s\n",         func,         result[4] == 1?" MUST_DO_CALIBRATION":"",         result[4] == 2?" SCAN_IMAGE_DOES_CALIBRATION":"",         result[4] == 3?" NEEDS_NO_CALIBRATION":""); -   +    DBG (dbg_level, "%s: [5]    Ability1:%s%s%s%s%s%s%s%s\n",         func,         BIT(result[5],7)?" NONE_PACKED":" PACKED", @@ -1542,18 +1541,18 @@ static void debug_print_calib_format (int dbg_level, char* func,         BIT(result[5],2)?" DARK_CALIB":"",         BIT(result[5],1)?" NEEDS_WHITE_BLACK_SHADING_DATA":"",         BIT(result[5],0)?" NEEDS_CALIB_TABLE_CHANNEL_BY_CHANNEL":""); -   +    DBG (dbg_level, "%s: [6]    R gain: %d\n", func, result[6]);    DBG (dbg_level, "%s: [7]    G gain: %d\n", func, result[7]);    DBG (dbg_level, "%s: [8]    B gain: %d\n", func, result[8]); -   +    DBG (dbg_level, "%s: [9-10] R shading target: %x\n",         func, get_double ( &(result[9]) ) );    DBG (dbg_level, "%s: [11-12] G shading target: %x\n",         func, get_double ( &(result[11]) ) );    DBG (dbg_level, "%s: [13-14] B shading target: %x\n",         func, get_double ( &(result[13]) ) ); -   +    DBG (dbg_level, "%s: [15-16] R dark shading target: %x\n",         func, get_double ( &(result[15]) ) );    DBG (dbg_level, "%s: [17-18] G dark shading target: %x\n", @@ -1564,7 +1563,7 @@ static void debug_print_calib_format (int dbg_level, char* func,    DBG (dbg_level, "%s: [21]    true-gray gain: %d\n", func, result[21]);    DBG (dbg_level, "%s: [22-23] true-gray shading target: %x\n",         func, get_double ( &(result[22]) ) ); -   +    DBG (dbg_level, "%s: [24-25] true-gray dark shading target: %x\n",         func, get_double ( &(result[24]) ) );  } @@ -1573,7 +1572,7 @@ static void debug_print_accel_info (int dbg_level, char* func,  				    uint8_t* result)  {    debug_print_raw (dbg_level + 2, "debug_print_accel_info:\n", result, 24); -   +    DBG (dbg_level, "%s: [0-1]   acceleration step count: %d\n",         func, get_double ( &(result[0]) ));    DBG (dbg_level, "%s: [2-3]   stable step count: %d\n", @@ -1591,7 +1590,7 @@ static void debug_print_accel_info (int dbg_level, char* func,         BIT(result[16],0)?" TWO_BYTES_PER_ELEM":" SINGLE_BYTE_PER_ELEM",         BIT(result[16],1)?" LOW_HIGH_ORDER":" HIGH_LOW_ORDER");    DBG (dbg_level, "%s: [17]    table count: %d\n", func, result[17]); -   +  }  static void debug_print_window_descriptor (int dbg_level, char* func, @@ -1605,7 +1604,7 @@ static void debug_print_window_descriptor (int dbg_level, char* func,  		   (uint8_t*)(&window->descriptor),  		   sizeof(*window) -  		   sizeof(window->header)); -   +    DBG (dbg_level, "%s: [0]     window_id: %d\n", func,         window->descriptor.winid);    DBG (dbg_level, "%s: [2-3]   x-axis res: %d\n", func, @@ -1618,7 +1617,7 @@ static void debug_print_window_descriptor (int dbg_level, char* func,         func, get_quad (window->descriptor.uly));    DBG (dbg_level, "%s: [14-17] window width: %d\n", func,         get_quad (window->descriptor.width)); -  DBG (dbg_level, "%s: [18-21] window length: %d\n", func,  +  DBG (dbg_level, "%s: [18-21] window length: %d\n", func,         get_quad (window->descriptor.length));    DBG (dbg_level, "%s: [22]    brightness: %d\n", func,         window->descriptor.brightness); @@ -1660,14 +1659,14 @@ static void debug_print_window_descriptor (int dbg_level, char* func,         window->avision.type.normal.bitset2);    DBG (dbg_level, "%s: [50]    ir exposure time: %x\n",         func, window->avision.type.normal.ir_exposure_time); -   +    DBG (dbg_level, "%s: [51-52] r exposure: %x\n", func,         get_double (window->avision.type.normal.r_exposure_time));    DBG (dbg_level, "%s: [53-54] g exposure: %x\n", func,         get_double (window->avision.type.normal.g_exposure_time));    DBG (dbg_level, "%s: [55-56] b exposure: %x\n", func,         get_double (window->avision.type.normal.b_exposure_time)); -   +    DBG (dbg_level, "%s: [57]    bitset3: %x\n", func,         window->avision.type.normal.bitset3);    DBG (dbg_level, "%s: [58]    auto focus: %d\n", func, @@ -1685,7 +1684,7 @@ static int write_pnm_header (FILE* f, color_mode m, int depth, int width, int he    int maxval = (1 << depth) - 1;    const char* hdr_str = NULL;    /* construct PNM header */ -   +    switch (m) {    case AV_THRESHOLDED:    case AV_DITHERED: @@ -1704,7 +1703,7 @@ static int write_pnm_header (FILE* f, color_mode m, int depth, int width, int he    case  AV_COLOR_MODE_LAST:      ; /* silence compiler warning */    } -   +    return fprintf (f, hdr_str, width, height, maxval);  } @@ -1712,19 +1711,19 @@ static SANE_Status  sense_handler (int fd, u_char* sense, void* arg)  {    SANE_Status status = SANE_STATUS_IO_ERROR; /* default case */ -   +    char* text;    char textbuf[64]; -   +    uint8_t error_code = sense[0] & 0x7f;    uint8_t sense_key = sense[2] & 0xf;    uint8_t additional_sense = sense[7]; -   +    fd = fd; /* silence gcc */    arg = arg; /* silence gcc */ -   +    DBG (3, "sense_handler:\n"); -   +    switch (error_code)      {      case 0x70: @@ -1736,15 +1735,15 @@ sense_handler (int fd, u_char* sense, void* arg)      default:        text = "unknown sense";      } -   +    debug_print_raw (1, "sense_handler: data:\n", sense, 8 + additional_sense); -   +    /* request valid? */    if (! (sense[0] & (1<<7))) {      DBG (1, "sense_handler: sense not valid ...\n");      return status;    } -   +    switch (sense_key)      {      case 0x00: @@ -1778,26 +1777,26 @@ sense_handler (int fd, u_char* sense, void* arg)        sprintf (textbuf, "got unknown sense code 0x%02x", (int)sense_key);        text = textbuf;      } -   +    DBG (1, "sense_handler: sense code: %s\n", text); -   +    if (sense[2] & (1<<6)) -    DBG (1, "sense_handler: end of scan\n");    -  else  +    DBG (1, "sense_handler: end of scan\n"); +  else      DBG (1, "sense_handler: scan has not yet been completed\n"); -   +    if (sense[2] & (1<<5))      DBG (1, "sense_handler: incorrect logical length\n"); -  else  +  else      DBG (1, "sense_handler: correct logical length\n"); -  {   +  {      uint8_t asc = sense[12];      uint8_t ascq = sense[13]; -     +  #define ADDITIONAL_SENSE(asc,ascq,txt)			\      case ( (asc << 8) + ascq): text = txt; break -     +      switch ( (asc << 8) + ascq )        {  	/* normal */ @@ -1808,9 +1807,9 @@ sense_handler (int fd, u_char* sense, void* arg)  	ADDITIONAL_SENSE (0x15,0x02, "Flatbed Home Sensor Error (OKI only");  	ADDITIONAL_SENSE (0x15,0x03, "ADF Home Sensor Error (OKI only)");  	ADDITIONAL_SENSE (0x15,0x04, "Lock Error (OKI only)"); -	 +  	ADDITIONAL_SENSE (0x1a,0x00, "parameter list length error"); -	 +  	ADDITIONAL_SENSE (0x20,0x00, "Invalid command");  	ADDITIONAL_SENSE (0x24,0x00, "Invalid field in CDB");  	ADDITIONAL_SENSE (0x25,0x00, "Logical unit not supported"); @@ -1822,7 +1821,7 @@ sense_handler (int fd, u_char* sense, void* arg)  	ADDITIONAL_SENSE (0x2f,0x00, "Command cleared by another initiator");  	ADDITIONAL_SENSE (0x3D,0x00, "Invalid Bit in Identify Message"); -	 +  	ADDITIONAL_SENSE (0x43,0x00, "Message error");  	ADDITIONAL_SENSE (0x44,0x00, "Internal target failure");  	ADDITIONAL_SENSE (0x44,0x01, "Flatbed DRAM Error(OKI only)"); @@ -1830,12 +1829,12 @@ sense_handler (int fd, u_char* sense, void* arg)  	ADDITIONAL_SENSE (0x44,0x03, "Write NVRAM Error");  	ADDITIONAL_SENSE (0x47,0x00, "SCSI parity error");  	ADDITIONAL_SENSE (0x49,0x00, "Invalid message error"); -	 +  	ADDITIONAL_SENSE (0x60,0x00, "Lamp failure");  	ADDITIONAL_SENSE (0x60,0x01, "Flatbed Lamp error (Oki only)");  	ADDITIONAL_SENSE (0x60,0x02, "ADF lamp error (Oki only)");  	ADDITIONAL_SENSE (0x62,0x00, "Scan head positioning error"); -	 +  	ADDITIONAL_SENSE (0x80,0x01, "ADF paper jam"; status = SANE_STATUS_JAMMED);  	ADDITIONAL_SENSE (0x80,0x02, "ADF cover open"; status = SANE_STATUS_COVER_OPEN);  	ADDITIONAL_SENSE (0x80,0x03, "ADF chute empty"; status = SANE_STATUS_NO_DOCS); @@ -1848,7 +1847,7 @@ sense_handler (int fd, u_char* sense, void* arg)          ADDITIONAL_SENSE (0x80,0x0A, "ADF Paper Start");          ADDITIONAL_SENSE (0x80,0x0B, "Multiple ADF paper End and Start");          ADDITIONAL_SENSE (0x80,0x0C, "Multiple ADF paper End"); -	 +          /* film scanner */  	ADDITIONAL_SENSE (0x81,0x00, "ADF/MFP front door open"; status = SANE_STATUS_COVER_OPEN);  	ADDITIONAL_SENSE (0x81,0x01, "ADF holder cartridge open"; status = SANE_STATUS_COVER_OPEN); @@ -1861,19 +1860,19 @@ sense_handler (int fd, u_char* sense, void* arg)  	ADDITIONAL_SENSE (0x81,0x08, "ADF adapter error");  	ADDITIONAL_SENSE (0xA0,0x01, "Filter Positioning Error"); -	 +  	ADDITIONAL_SENSE (0x90,0x00, "Scanner busy (FW busy)"); -	 +        default:  	sprintf (textbuf, "Unknown sense code asc: 0x%02x, ascq: 0x%02x",  		 (int)asc, (int)ascq);  	text = textbuf;        } -     +  #undef ADDITIONAL_SENSE -     +      DBG (1, "sense_handler: sense code: %s\n", text); -     +      /* sense code specific for invalid request       * it is possible to get a detailed error location here ;-)*/      if (sense_key == 0x05) { @@ -1883,10 +1882,10 @@ sense_handler (int fd, u_char* sense, void* arg)  	    DBG (1, "sense_handler: error in command parameter\n");  	  else  	    DBG (1, "sense_handler: error in data parameter\n"); -	   +  	  DBG (1, "sense_handler: error in parameter byte: %d, %x\n",  	       get_double(&(sense[16])),  get_double(&(sense[16]))); -	   +  	  /* bit pointer valid ?*/  	  if (sense[15] & (1<<3) )  	    DBG (1, "sense_handler: error in command parameter\n"); @@ -1895,7 +1894,7 @@ sense_handler (int fd, u_char* sense, void* arg)  	}      }    } -   +    return status;  } @@ -1912,7 +1911,7 @@ avision_usb_status (Avision_Connection* av_con, int retry, int timeout)    int t_retry = retry;  #define valid_status(status,a) (status == SANE_STATUS_GOOD ? a : 0) -   +    DBG (4, "avision_usb_status: timeout %d, %d retries\n", timeout, retry);  #ifndef HAVE_SANEI_USB_SET_TIMEOUT  #error "You must update include/sane/sanei_usb.h and sanei/sanei_usb.c accordingly!" @@ -1928,7 +1927,7 @@ avision_usb_status (Avision_Connection* av_con, int retry, int timeout)         --retry)      {        count = sizeof (usb_status); -       +        DBG (5, "==> (bulk read) going down ...\n");        status = sanei_usb_read_bulk (av_con->usb_dn, usb_status,  				    &count); @@ -1939,10 +1938,10 @@ avision_usb_status (Avision_Connection* av_con, int retry, int timeout)  	av_con->usb_status = AVISION_USB_BULK_STATUS;        }      } -   +    /* reset retry count ... */    retry = t_retry; -     +    /* 2nd try interrupt status read - if not yet disabled */    for (;         count == 0 && @@ -1952,23 +1951,23 @@ avision_usb_status (Avision_Connection* av_con, int retry, int timeout)         --retry)    {      count = sizeof (usb_status); -     +      DBG (5, "==> (interrupt read) going down ...\n");      status = sanei_usb_read_int (av_con->usb_dn, usb_status,  				 &count);      DBG (5, "<== (interrupt read) got: %ld, status: %d\n",  	 (u_long)count, valid_status(status, usb_status[0])); -     +      if (count > 0)        av_con->usb_status = AVISION_USB_INT_STATUS; -  }   -   +  } +    if (status != SANE_STATUS_GOOD)      return status; -  +    if (count == 0)      return SANE_STATUS_IO_ERROR; -  +    /* 0 = ok, 2 => request sense, 8 ==> busy, else error */    switch (usb_status[0])      { @@ -2051,7 +2050,7 @@ static SANE_Status avision_cmd (Avision_Connection* av_con,    }    else {      SANE_Status status = SANE_STATUS_GOOD; -     +      size_t i, count, out_count;      /* some commands on some devices need a rather long time to respond */  #define STD_TIMEOUT 30000 @@ -2065,11 +2064,11 @@ static SANE_Status avision_cmd (Avision_Connection* av_con,      const uint8_t* m_cmd = (const uint8_t*)cmd;      const uint8_t* m_src = (const uint8_t*)src;      uint8_t* m_dst = (uint8_t*)dst; -     +      /* may I vote for the possibility to use C99 ... */  #define min_usb_size 10  #define max_usb_size 256 * 1024 /* or 0x10000, used by AV Windows driver during background raster read, ... ? */ -     +      /* 1st send command data - at least 10 Bytes for USB scanners */      uint8_t enlarged_cmd [min_usb_size];      if (cmd_size < min_usb_size) { @@ -2106,12 +2105,12 @@ write_usb_cmd:      sanei_usb_set_timeout (write_timeout);      DBG (8, "try to write cmd, count: %lu.\n", (u_long) count);      status = sanei_usb_write_bulk (av_con->usb_dn, m_cmd, &count); -       +      DBG (8, "wrote %lu bytes\n", (u_long) count);      if (status != SANE_STATUS_GOOD || count != cmd_size) {        DBG (3, "=== Got error %d trying to write, wrote: %ld. ===\n",             status, (long)count); -       +        if (status != SANE_STATUS_GOOD) /* == SANE_STATUS_EOF) */ {  	DBG (3, "try to read status to clear the FIFO\n");  	status = avision_usb_status (av_con, 1, 500); @@ -2125,21 +2124,21 @@ write_usb_cmd:  	DBG (3, "Retrying to send command\n");  	goto write_usb_cmd;        } -       +        return SANE_STATUS_IO_ERROR;      } -     +      /* 2nd send command data (if any) */      for (i = 0; i < src_size; ) { -       +        count = src_size - i;        /* if (count > max_usb_size)    	   count = max_usb_size; */ -       +        DBG (8, "try to write src, count: %lu.\n", (u_long) count);        sanei_usb_set_timeout (write_timeout);        status = sanei_usb_write_bulk (av_con->usb_dn, &(m_src[i]), &count); -       +        DBG (8, "wrote %lu bytes\n", (u_long) count);        if (status == SANE_STATUS_GOOD) {  	i += count; @@ -2155,7 +2154,7 @@ write_usb_cmd:        sanei_usb_set_timeout (read_timeout);        while (out_count < *dst_size) {  	count = (*dst_size - out_count); -	 +  	DBG (8, "try to read %lu bytes\n", (u_long) count);          status = sanei_usb_read_bulk(av_con->usb_dn, &(m_dst[out_count]),  				     &count); @@ -2174,7 +2173,7 @@ write_usb_cmd:  	}        }      } -     +      /* last: read the device status via a pseudo interrupt transfer       * this is needed - otherwise the scanner will hang ... */      sanei_usb_set_timeout (status_timeout); @@ -2182,49 +2181,49 @@ write_usb_cmd:      /* next i/o hardening attempt - and yes this gets ugly ... */      if (status != SANE_STATUS_GOOD && status != SANE_STATUS_INVAL)        goto write_usb_cmd; -    +      if (status == SANE_STATUS_INVAL) {        struct {  	command_header header;  	uint8_t pad[4];        } sense_cmd; -       +        uint8_t sense_buffer[22]; -       +        DBG (3, "Error during status read!\n");        DBG (3, "=== Try to request sense ===\n"); -       +        /* we can not call avision_cmd recursively - we might ending in  	 an endless recursion requesting sense for failing request  	 sense transfers ...*/ -       +        memset (&sense_cmd, 0, sizeof (sense_cmd) );        memset (&sense_buffer, 0, sizeof (sense_buffer) );        sense_cmd.header.opc = AVISION_SCSI_REQUEST_SENSE;        sense_cmd.header.len = sizeof (sense_buffer); -       +        count = sizeof(sense_cmd); -       +        DBG (8, "try to write %lu bytes\n", (u_long) count);        sanei_usb_set_timeout (write_timeout);        status = sanei_usb_write_bulk (av_con->usb_dn,  				     (uint8_t*) &sense_cmd, &count);        DBG (8, "wrote %lu bytes\n", (u_long) count); -       +        if (status != SANE_STATUS_GOOD) {  	DBG (3, "=== Got error %d trying to request sense! ===\n", status);        }        else {  	count = sizeof (sense_buffer); -	 +  	DBG (8, "try to read %lu bytes sense data\n", (u_long) count);  	sanei_usb_set_timeout (read_timeout);  	status = sanei_usb_read_bulk(av_con->usb_dn, sense_buffer, &count);  	DBG (8, "read %lu bytes sense data\n", (u_long) count); -	 +  	/* we need to read out the status from the scanner i/o buffer */  	status = avision_usb_status (av_con, 1, status_timeout); -	 +  	/* some scanner return NEED_SENSE even after reading it */  	if (status != SANE_STATUS_GOOD && status != SANE_STATUS_INVAL)  	  DBG (3, "=== Got error %d trying to read sense! ===\n", status); @@ -2248,33 +2247,33 @@ bubble_sort (uint8_t* sort_data, size_t count)  {    size_t i, j, limit, k;    double sum = 0.0; -   +    limit = count / 3; -   +    for (i = 0; i < limit; ++i)      {        uint16_t ti = 0;        uint16_t tj = 0; -       +        for (j = (i + 1); j < count; ++j)  	{  	  ti = get_double ((sort_data + i*2));  	  tj = get_double ((sort_data + j*2)); -	   +  	  if (ti > tj) {  	    set_double ((sort_data + i*2), tj);  	    set_double ((sort_data + j*2), ti);  	  }  	}      } -   +    for (k = 0, i = limit; i < count; ++i) {      sum += get_double ((sort_data + i*2));      ++ k;    } -   +    /* DBG (7, "bubble_sort: %d values for average\n", k); */ -   +    if (k > 0) /* if avg to compute */      return (uint16_t) (sum / k);    else @@ -2286,7 +2285,7 @@ add_color_mode (Avision_Device* dev, color_mode mode, SANE_String name)  {    int i;    DBG (3, "add_color_mode: %d %s\n", mode, name); -   +    for (i = 0; i < AV_COLOR_MODE_LAST; ++i)      {        if (dev->color_list [i] == 0) { @@ -2298,7 +2297,7 @@ add_color_mode (Avision_Device* dev, color_mode mode, SANE_String name)  	return SANE_STATUS_GOOD;        }      } -   +    DBG (3, "add_color_mode: failed\n");    return SANE_STATUS_NO_MEM;  } @@ -2307,13 +2306,13 @@ static int  last_color_mode (Avision_Device* dev)  {    int i = 1; -   +    while (dev->color_list [i] != 0 && i < AV_COLOR_MODE_LAST)      ++i; -   +    /* we are off by one */    --i; -   +    return i;  } @@ -2331,7 +2330,7 @@ match_color_mode (Avision_Device* dev, SANE_String name)  	return dev->color_list_num [i];        }      } -   +    DBG (3, "match_color_mode: source mode invalid\n");    return AV_GRAYSCALE;  } @@ -2352,14 +2351,14 @@ static SANE_Bool  is_adf_scan (Avision_Scanner* s)  {    return s->hw->scanner_type == AV_SHEETFEED || (s->hw->scanner_type == AV_FLATBED && s->source_mode_dim == AV_ADF_DIM); -     +  }  static SANE_Status  add_source_mode (Avision_Device* dev, source_mode mode, SANE_String name)  {    int i; -   +    for (i = 0; i < AV_SOURCE_MODE_LAST; ++i)      {        if (dev->source_list [i] == 0) { @@ -2371,7 +2370,7 @@ add_source_mode (Avision_Device* dev, source_mode mode, SANE_String name)  	return SANE_STATUS_GOOD;        }      } -   +    return SANE_STATUS_NO_MEM;  } @@ -2379,7 +2378,7 @@ static source_mode  match_source_mode (Avision_Device* dev, SANE_String name)  {    int i; -   +    DBG (3, "match_source_mode: \"%s\"\n", name);    for (i = 0; i < AV_SOURCE_MODE_LAST; ++i) @@ -2390,7 +2389,7 @@ match_source_mode (Avision_Device* dev, SANE_String name)  	return dev->source_list_num [i];        }      } -   +    DBG (3, "match_source_mode: source mode invalid\n");    return AV_NORMAL;  } @@ -2399,7 +2398,7 @@ static source_mode_dim  match_source_mode_dim (source_mode sm)  {    DBG (3, "match_source_mode_dim: %d\n", sm); -   +    switch (sm) {    case AV_NORMAL:      return AV_NORMAL_DIM; @@ -2420,7 +2419,7 @@ get_pixel_boundary (Avision_Scanner* s)  {    Avision_Device* dev = s->hw;    int boundary; -   +    switch (s->c_mode) {    case AV_TRUECOLOR:    case AV_TRUECOLOR12: @@ -2447,7 +2446,7 @@ get_pixel_boundary (Avision_Scanner* s)    default:      boundary = 8;    } -   +    return boundary;  } @@ -2458,11 +2457,11 @@ compute_parameters (Avision_Scanner* s)    int boundary = get_pixel_boundary (s);    SANE_Bool gray_mode = color_mode_is_shaded (s->c_mode); -   +    /* interlaced duplex (higher end) or flipping paper (HP8xxx)? */    s->avdimen.interlaced_duplex = s->source_mode == AV_ADF_DUPLEX &&                                   dev->inquiry_duplex_interlaced; -   +    /* for infra-red we use the same code path es for interlaced       duplex */    if (s->val[OPT_IR].w) @@ -2491,23 +2490,23 @@ compute_parameters (Avision_Scanner* s)        break;    }  #endif -   +    DBG (3, "sane_compute_parameters:\n"); -     +    DBG (3, "sane_compute_parameters: boundary %d, gray_mode: %d, \n",         boundary, gray_mode); -       +    /* TODO: Implement different x/y resolutions support */    s->avdimen.xres = s->val[OPT_RESOLUTION].w;    s->avdimen.yres = s->val[OPT_RESOLUTION].w; -   +    /* soft scale ? */    if (dev->hw->feature_type & AV_SOFT_SCALE) {      /* find supported hardware resolution */      const int* hw_res;      const int* hw_res_list =        dev->inquiry_asic_type == AV_ASIC_C5 ? hw_res_list_c5 : hw_res_list_generic; -     +      for (hw_res = hw_res_list; *hw_res && *hw_res < s->avdimen.xres; ++hw_res)        /* just iterate */;      s->avdimen.hw_xres = *hw_res; @@ -2515,11 +2514,11 @@ compute_parameters (Avision_Scanner* s)      for (hw_res = hw_res_list; *hw_res && *hw_res < s->avdimen.yres; ++hw_res)        /* just iterate */;      s->avdimen.hw_yres = *hw_res; -     +      DBG (3, "sane_compute_parameters: soft scale, hw res: %dx%d\n",  	 s->avdimen.hw_xres,  	 s->avdimen.hw_yres); -     +      if (!s->avdimen.hw_xres || ! s->avdimen.hw_yres) {        DBG (1, "sane_compute_parameters: no matching HW res for: %dx%d\n",  	   s->avdimen.xres, @@ -2531,11 +2530,11 @@ compute_parameters (Avision_Scanner* s)      s->avdimen.hw_xres = s->val[OPT_RESOLUTION].w;      s->avdimen.hw_yres = s->val[OPT_RESOLUTION].w;    } -   +    DBG (3, "sane_compute_parameters: tlx: %f, tly: %f, brx: %f, bry: %f\n",         SANE_UNFIX (s->val[OPT_TL_X].w), SANE_UNFIX (s->val[OPT_TL_Y].w),         SANE_UNFIX (s->val[OPT_BR_X].w), SANE_UNFIX (s->val[OPT_BR_Y].w)); -       +    /* window parameter in pixel */    s->avdimen.tlx = s->avdimen.hw_xres * SANE_UNFIX (s->val[OPT_TL_X].w)      / MM_PER_INCH; @@ -2545,7 +2544,7 @@ compute_parameters (Avision_Scanner* s)      / MM_PER_INCH;    s->avdimen.bry = s->avdimen.hw_yres * SANE_UNFIX (s->val[OPT_BR_Y].w)      / MM_PER_INCH; -       +    /* line difference */    if (color_mode_is_color (s->c_mode) &&        dev->inquiry_needs_software_colorpack && @@ -2553,27 +2552,27 @@ compute_parameters (Avision_Scanner* s)      {        s->avdimen.line_difference =  	(dev->inquiry_line_difference * s->avdimen.hw_yres) / dev->inquiry_optical_res; -       +        s->avdimen.bry += 2 * s->avdimen.line_difference; -	 +        /* limit bry + line_difference to real scan boundary */        {  	long y_max = dev->inquiry_y_ranges[s->source_mode_dim] *  	  s->avdimen.hw_yres / MM_PER_INCH;  	DBG (3, "sane_compute_parameters: y_max: %ld, bry: %ld, line_difference: %d\n",  	     y_max, s->avdimen.bry, s->avdimen.line_difference); -	     +  	if (s->avdimen.bry + 2 * s->avdimen.line_difference > y_max) {  	  DBG (1, "sane_compute_parameters: bry limited!\n");  	  s->avdimen.bry = y_max - 2 * s->avdimen.line_difference;  	}        } -	   +      } /* end if needs software colorpack */    else {      s->avdimen.line_difference = 0;    } -   +    /* add overscan */    if (dev->inquiry_tune_scan_length && is_adf_scan (s)) {      /* some extra effort for precise rounding ... */ @@ -2584,7 +2583,7 @@ compute_parameters (Avision_Scanner* s)      DBG (3, "sane_compute_parameters: overscan lines: %d\n", overscan);      s->avdimen.bry += overscan;    } -   +    /* rear offset compensation */    if (s->avdimen.interlaced_duplex && dev->hw->feature_type & AV_REAR_OFFSET) {      const double offset = 0.5; /* in current affected models 1/2 inch */ @@ -2598,16 +2597,16 @@ compute_parameters (Avision_Scanner* s)    }    memset (&s->params, 0, sizeof (s->params)); -       +    s->avdimen.hw_pixels_per_line = (s->avdimen.brx - s->avdimen.tlx);    s->avdimen.hw_pixels_per_line -= s->avdimen.hw_pixels_per_line % boundary; -   +    s->avdimen.hw_lines = (s->avdimen.bry - s->avdimen.tly -  			 2 * s->avdimen.line_difference); -   +    if (s->avdimen.interlaced_duplex && dev->scanner_type != AV_FILM)      s->avdimen.hw_lines -= s->avdimen.hw_lines % dev->read_stripe_size; -   +    s->params.pixels_per_line = s->avdimen.hw_pixels_per_line * s->avdimen.xres / s->avdimen.hw_xres;    s->params.lines = s->avdimen.hw_lines * s->avdimen.xres / s->avdimen.hw_xres;    if (is_adf_scan (s)) @@ -2615,9 +2614,9 @@ compute_parameters (Avision_Scanner* s)      s->params.lines = -1;    if (s->c_mode == AV_THRESHOLDED || s->c_mode == AV_DITHERED)      s->params.pixels_per_line -= s->params.pixels_per_line % 8; -   +    debug_print_avdimen (1, "sane_compute_parameters", &s->avdimen); -   +    switch (s->c_mode)      {      case AV_THRESHOLDED: @@ -2662,9 +2661,9 @@ compute_parameters (Avision_Scanner* s)        DBG (1, "Invalid mode. %d\n", s->c_mode);        return SANE_STATUS_INVAL;      } /* end switch */ -   +    s->params.last_frame = SANE_TRUE; -   +    debug_print_params (1, "sane_compute_parameters", &s->params);    return SANE_STATUS_GOOD;  } @@ -2675,26 +2674,26 @@ inquiry (Avision_Connection av_con, uint8_t* data, size_t len)    SANE_Status status;    command_header inquiry;    int try = 2; -   +    DBG (3, "inquiry: length: %ld\n", (long)len); -  +    memset (&inquiry, 0, sizeof(inquiry));    inquiry.opc = AVISION_SCSI_INQUIRY;    inquiry.len = len; -   +    do {      size_t size = inquiry.len; -     +      DBG (3, "inquiry: inquiring ...\n");      status = avision_cmd (&av_con, &inquiry, sizeof (inquiry), 0, 0,  			  data, &size);      if (status == SANE_STATUS_GOOD && size == inquiry.len)        break; -     +      DBG (1, "inquiry: inquiry failed (%s)\n", sane_strstatus (status));      --try;    } while (try > 0); -   +    return status;  } @@ -2703,14 +2702,14 @@ wait_ready (Avision_Connection* av_con, int delay)  {    SANE_Status status;    int try; -   +    for (try = 0; try < 10; ++ try)      {        DBG (3, "wait_ready: sending TEST_UNIT_READY\n");        status = avision_cmd (av_con, test_unit_ready, sizeof (test_unit_ready),  			    0, 0, 0, 0);        sleep (delay); -       +        switch (status)  	{  	default: @@ -2734,45 +2733,45 @@ static SANE_Status  wait_4_light (Avision_Scanner* s)  {    Avision_Device* dev = s->hw; -   +    /* read stuff */    struct command_read rcmd;    char* light_status[] = -    { "off", "on", "warming up", "needs warm up test",  +    { "off", "on", "warming up", "needs warm up test",        "light check error", "backlight on", "RESERVED" }; -   +    SANE_Status status;    uint8_t result;    int try;    size_t size = 1; -   +    DBG (3, "wait_4_light: getting light status.\n"); -   +    memset (&rcmd, 0, sizeof (rcmd)); -   +    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0xa0; /* get light status */    set_double (rcmd.datatypequal, dev->data_dq);    set_triple (rcmd.transferlen, size); -   +    for (try = 0; try < 90; ++ try) {      if (s->cancelled) {        DBG (3, "wait_4_light: cancelled\n");        return SANE_STATUS_CANCELLED;      } -     +      DBG (5, "wait_4_light: read bytes %lu\n", (u_long) size);      status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, &result, &size); -     +      if (status != SANE_STATUS_GOOD || size != sizeof (result)) {        DBG (1, "wait_4_light: read failed (%s)\n", sane_strstatus (status));        return status;      } -     +      DBG (3, "wait_4_light: command is %d. Result is %d (%s)\n",  	 status, result, light_status[(result>5)?6:result]); -     +      if (result == 1 || result == 5) {        return SANE_STATUS_GOOD;      } @@ -2783,20 +2782,20 @@ wait_4_light (Avision_Scanner* s)      else {        struct command_send scmd;        uint8_t light_on = 1; -       +        /* turn on the light */        DBG (3, "wait_4_light: setting light status.\n"); -       +        memset (&scmd, 0, sizeof (scmd)); -       +        scmd.opc = AVISION_SCSI_SEND;        scmd.datatypecode = 0xa0; /* send light status */        set_double (scmd.datatypequal, dev->data_dq);        set_triple (scmd.transferlen, size); -       +        status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  			    &light_on, sizeof (light_on), 0, 0); -       +        if (status != SANE_STATUS_GOOD) {  	DBG (1, "wait_4_light: send failed (%s)\n", sane_strstatus (status));  	return status; @@ -2804,7 +2803,7 @@ wait_4_light (Avision_Scanner* s)      }      sleep (1);    } -   +    DBG (1, "wait_4_light: timed out after %d attempts\n", try);    return SANE_STATUS_DEVICE_BUSY;  } @@ -2846,27 +2845,27 @@ get_firmware_status (Avision_Connection* av_con)    SANE_Status status;    firmware_status result; -   +    DBG (3, "get_firmware_status\n"); -  +    size = sizeof (result); -  +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ; -  +    rcmd.datatypecode = 0x90; /* firmware status */    set_double (rcmd.datatypequal, 0); /* dev->data_dq not available */    set_triple (rcmd.transferlen, size); -  +    status = avision_cmd (av_con, &rcmd, sizeof (rcmd), 0, 0, &result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result)) {      DBG (1, "get_firmware_status: read failed (%s)\n",  	 sane_strstatus (status));      return (status);    } -  +    debug_print_raw (6, "get_firmware_status: raw data:\n", (uint8_t*)&result, size); -  +    DBG (3, "get_firmware_status: [0]  needs firmware %x\n", result.download_firmware);    DBG (3, "get_firmware_status: [1]  side edge: %d\n", get_double ( result.first_effective_pixel_flatbed ));    DBG (3, "get_firmware_status: [3]  side edge: %d\n", get_double ( result.first_effective_pixel_adf_front )); @@ -2883,28 +2882,28 @@ get_flash_ram_info (Avision_Connection* av_con)    size_t size;    SANE_Status status;    uint8_t result[40]; -   +    DBG (3, "get_flash_ram_info\n"); -  +    size = sizeof (result); -  +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ; -  +    rcmd.datatypecode = 0x6a; /* flash ram information */    set_double (rcmd.datatypequal, 0); /* dev->data_dq not available */    set_triple (rcmd.transferlen, size); -  +    status = avision_cmd (av_con, &rcmd, sizeof (rcmd), 0, 0, result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result)) {      DBG (1, "get_flash_ram_info: read failed (%s)\n",  	 sane_strstatus (status));      return (status);    } -  +    debug_print_raw (6, "get_flash_ram_info: raw data:\n", result, size); -   -  DBG (3, "get_flash_ram_info: [0]    data type %x\n", result [0]);   + +  DBG (3, "get_flash_ram_info: [0]    data type %x\n", result [0]);    DBG (3, "get_flash_ram_info: [1]    Ability1:%s%s%s%s%s%s%s%s\n",         BIT(result[1],7)?" RESERVED_BIT7":"",         BIT(result[1],6)?" RESERVED_BIT6":"", @@ -2914,7 +2913,7 @@ get_flash_ram_info (Avision_Connection* av_con)         BIT(result[1],2)?" RAWLINE(r)":"",         BIT(result[1],1)?" FIRMWARE(r/w)":"",         BIT(result[1],0)?" CTAB(r/w)":""); -   +    DBG (3, "get_flash_ram_info: [2-5]   size CTAB: %d\n",         get_quad ( &(result[2]) ) ); @@ -2938,7 +2937,7 @@ get_flash_ram_info (Avision_Connection* av_con)    DBG (3, "get_flash_ram_info: [30-33] size RESERVED: %d\n",         get_quad ( &(result[30]) ) ); -   +    return SANE_STATUS_GOOD;  } @@ -2947,23 +2946,23 @@ get_nvram_data (Avision_Scanner* s, nvram_data* nvram)  {    /* read stuff */    struct command_send rcmd; -   +    size_t size;    SANE_Status status; -   +    DBG (3, "get_nvram_data\n"); -   +    size = sizeof (*nvram); -   +    memset (&rcmd, 0, sizeof (rcmd));    memset (nvram, 0, size); -   +    rcmd.opc = AVISION_SCSI_READ; -   +    rcmd.datatypecode = 0x69; /* Read NVM RAM data */    set_double (rcmd.datatypequal, 0); /* dev->data_dq not available */    set_triple (rcmd.transferlen, size); -  +    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0,  			nvram, &size);    if (status != SANE_STATUS_GOOD) { @@ -2971,9 +2970,9 @@ get_nvram_data (Avision_Scanner* s, nvram_data* nvram)  	 sane_strstatus (status));      return (status);    } -   +    debug_print_nvram_data (5, "get_nvram_data", nvram); -   +    return SANE_STATUS_GOOD;  } @@ -2985,7 +2984,7 @@ get_and_parse_nvram (Avision_Scanner* s, char* str, int n)    int x;    nvram_data nvram;    uint8_t inquiry_result [AVISION_INQUIRY_SIZE_V1]; -   +    status = inquiry (s->av_con, inquiry_result, sizeof(inquiry_result));    if (status == SANE_STATUS_GOOD) {      i += snprintf (str+i, n-i, "Vendor: %.8s", @@ -2995,17 +2994,17 @@ get_and_parse_nvram (Avision_Scanner* s, char* str, int n)      i += snprintf (str+i, n-i, "\nFirmware: %.4s",  		   inquiry_result+32);    } -   +    if (!s->hw->inquiry_nvram_read)      return SANE_STATUS_GOOD; -   +    status = get_nvram_data (s, &nvram);    if (status == SANE_STATUS_GOOD)      {        if (nvram.serial[0])  	i += snprintf (str+i, n-i, "\nSerial: %.24s",  		       nvram.serial); -       +        if (nvram.born_year)  	i += snprintf (str+i, n-i, "\nManufacturing date: %d-%d-%d",  		       get_double(nvram.born_year), @@ -3016,7 +3015,7 @@ get_and_parse_nvram (Avision_Scanner* s, char* str, int n)  		       get_double(nvram.first_scan_year),  		       get_double(nvram.first_scan_month),  		       get_double(nvram.first_scan_day)); -       +        x = get_quad (nvram.flatbed_scans);        if (x)  	i += snprintf (str+i, n-i, "\nFlatbed scans: %d", x); @@ -3030,7 +3029,7 @@ get_and_parse_nvram (Avision_Scanner* s, char* str, int n)        if (x)  	i += snprintf (str+i, n-i, "\nADF duplex scans: %d", x);      } -   +    return status;  } @@ -3039,21 +3038,21 @@ get_power_save_time (Avision_Scanner* s, SANE_Word* time)  {    SANE_Status status;    nvram_data nvram; -   +    DBG (3, "get_power_save_time\n"); -   +    if (!s->hw->inquiry_nvram_read)      return SANE_STATUS_INVAL; -   +    status = get_nvram_data (s, &nvram); -   +    if (status != SANE_STATUS_GOOD) {      DBG (1, "get_power_save_time: read nvram failed (%s)\n", sane_strstatus (status));      return status;    } -   +    *time = get_double (nvram.power_saving_time); -   +    return SANE_STATUS_GOOD;  } @@ -3066,18 +3065,18 @@ send_nvram_data (Avision_Connection* av_con)    struct command_send scmd;    size_t size;    SANE_Status status; -   +    DBG (3, "send_nvram_data\n"); -  +    size = sizeof (c7_nvram); -  +    memset (&scmd, 0, sizeof (scmd));    scmd.opc = AVISION_SCSI_SEND; -   +    scmd.datatypecode = 0x85; /* nvram data */    set_double (scmd.datatypequal, 0); /* dev->data_dq not available */    set_triple (scmd.transferlen, size); -  +    status = avision_cmd (av_con, &scmd, sizeof (scmd), &c7_nvram, size,  			0, 0);    if (status != SANE_STATUS_GOOD) { @@ -3085,7 +3084,7 @@ send_nvram_data (Avision_Connection* av_con)  	 sane_strstatus (status));      return (status);    } -   +    return SANE_STATUS_GOOD;  } @@ -3096,18 +3095,18 @@ send_flash_ram_data (Avision_Connection* av_con)    struct command_send scmd;    size_t size;    SANE_Status status; -   +    DBG (3, "send_flash_ram_data\n"); -  +    size = sizeof (c7_flash_ram); -  +    memset (&scmd, 0, sizeof (scmd));    scmd.opc = AVISION_SCSI_SEND; -   +    scmd.datatypecode = 0x86; /* flash data */    set_double (scmd.datatypequal, 0);    set_triple (scmd.transferlen, size); -  +    status = avision_cmd (av_con, &scmd, sizeof (scmd), &c7_flash_ram, size,  			0, 0);    if (status != SANE_STATUS_GOOD) { @@ -3115,7 +3114,7 @@ send_flash_ram_data (Avision_Connection* av_con)  	 sane_strstatus (status));      return (status);    } -   +    return SANE_STATUS_GOOD;  }  #endif @@ -3177,28 +3176,28 @@ get_accessories_info (Avision_Scanner* s)  {    Avision_Device* dev = s->hw;    int try = 3; -   +    /* read stuff */    struct command_read rcmd;    size_t size;    SANE_Status status;    uint8_t result[8]; -   +    char* adf_model[] =      { "Origami", "Oodles", "HP9930", "unknown" };    const int adf_models = sizeof (adf_model) / sizeof(char*) - 1; -   +    DBG (3, "get_accessories_info\n"); -   +    size = sizeof (result); -  +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ; -  +    rcmd.datatypecode = 0x64; /* detect accessories */    set_double (rcmd.datatypequal, dev->data_dq);    set_triple (rcmd.transferlen, size); -  +    /* after resetting the ADF unit, try reprobing it again */    RETRY: @@ -3291,7 +3290,7 @@ string_for_button (Avision_Scanner* s, int button)  	case 2: return "duplex";  	}      } -   +    if (strcmp (dev->sane.model, "AV210C2") == 0 ||        strcmp (dev->sane.model, "AV210D2+") == 0 ||        strcmp (dev->sane.model, "AV220C2") == 0 || @@ -3303,7 +3302,7 @@ string_for_button (Avision_Scanner* s, int button)        else  	goto return_scan;      } -   +    /* those are unique, right now */    if (strcmp (dev->sane.model, "AV610") == 0)      { @@ -3314,11 +3313,11 @@ string_for_button (Avision_Scanner* s, int button)  	case 2: return "scan";  	}      } -   +    /* last resort */    snprintf (buffer, sizeof (buffer), "button%d", button);    return buffer; -   +   return_scan:    return "scan";  } @@ -3327,7 +3326,7 @@ static SANE_Status  get_button_status (Avision_Scanner* s)  {    Avision_Device* dev = s->hw; -   +    /* read stuff */    struct command_read rcmd;    size_t size; @@ -3341,21 +3340,21 @@ get_button_status (Avision_Scanner* s)    } result;    unsigned int i; -   +    DBG (3, "get_button_status:\n"); -   +    size = sizeof (result); -   +    /* AV220 et.al. */    if (! (dev->hw->feature_type & AV_INT_BUTTON))      {        memset (&rcmd, 0, sizeof (rcmd));        rcmd.opc = AVISION_SCSI_READ; -       +        rcmd.datatypecode = 0xA1; /* button status */        set_double (rcmd.datatypequal, dev->data_dq);        set_triple (rcmd.transferlen, size); -       +        status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0,  			    (uint8_t*)&result, &size);        if (status != SANE_STATUS_GOOD || size != sizeof (result)) { @@ -3367,7 +3366,7 @@ get_button_status (Avision_Scanner* s)      {        /* only try to read the first 8 bytes ...*/        size = 8; -       +        /* no SCSI equivalent */        /* either there was a button press and this completes quickly           or there is no point waiting for a future press */ @@ -3376,21 +3375,21 @@ get_button_status (Avision_Scanner* s)        status = sanei_usb_read_int (s->av_con.usb_dn, (uint8_t*)&result,  				   &size);        DBG (5, "==> (interrupt read) got: %ld\n", (long)size); -       +        if (status != SANE_STATUS_GOOD) {  	DBG (1, "get_button_status: interrupt read failed (%s)\n",  	     sane_strstatus (status));  	return SANE_STATUS_GOOD;        } -       +        if (size < sizeof (result))  	memset ((char*)result.buttons + size, 0, sizeof (result) - size); -       +        /* hack to fill in meaningful values for the AV 210 / 610 and  	 under some conditions the AV 220 */        if (size == 1) { /* AV 210, AV 610 */  	DBG (1, "get_button_status: just one byte, filling the rest\n"); -	 +  	if (result.press_state > 0) {  	  debug_print_raw (6, "get_button_status: raw data\n",  			   (uint8_t*)&result, size); @@ -3402,72 +3401,72 @@ get_button_status (Avision_Scanner* s)  	  return SANE_STATUS_GOOD;        }        else if (size >= 8 && result.press_state == 0) { /* AV 220 */ -	 +  	debug_print_raw (6, "get_button_status: raw data\n",  		   (uint8_t*)&result, size); -	 +  	DBG (1, "get_button_status: zero buttons  - filling values ...\n"); -	 +  	/* simulate button press of the last button ... */  	result.press_state = 0x80 | 1;  	result.buttons[0] = dev->inquiry_buttons; /* 1 based */        }      } -   +    debug_print_raw (6, "get_button_status: raw data\n",  		   (uint8_t*)&result, size); -   +    DBG (3, "get_button_status: [0]  Button status: %x\n", result.press_state);    for (i = 0; i < 5; ++i)      DBG (3, "get_button_status: [%d]  Button number %d: %x\n", i+1, i,  	 result.buttons[i]);    DBG (3, "get_button_status: [7]  Display: %d\n", result.display); -   +    {      char* message_begin = s->val[OPT_MESSAGE].s;      char* message_end = s->val[OPT_MESSAGE].s + s->opt[OPT_MESSAGE].size;      char* message = message_begin; -     +  #define add_token(format,value) do {				     \        int n = snprintf (message, message_end - message, "%s" format, \                          message == message_begin ? "" : ":", value); \        message += n > 0 ? n : 0;					     \      } while (0) -     +      if (result.display > 0)        add_token ("%d", result.display); -     +      if (result.press_state >> 7) /* AV220 et.al. bit 6 is long/short press? */        { -       +  	const unsigned int buttons_pressed = result.press_state & 0x7F;  	DBG (3, "get_button_status: %d button(s) pressed\n", buttons_pressed); -             +  	/* reset the hardware button status */  	if (! (dev->hw->feature_type & AV_INT_BUTTON))  	  {  	    struct command_send scmd;  	    uint8_t button_reset = 1; -	   +  	    DBG (3, "get_button_status: resetting status\n"); -	   +  	    memset (&scmd, 0, sizeof (scmd)); -	   +  	    scmd.opc = AVISION_SCSI_SEND;  	    scmd.datatypecode = 0xA1; /* button control */  	    set_double (scmd.datatypequal, dev->data_dq);  	    set_triple (scmd.transferlen, size); -	   +  	    status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  				  &button_reset, sizeof (button_reset), 0, 0); -	   +  	    if (status != SANE_STATUS_GOOD) {  	      DBG (1, "get_button_status: send failed (%s)\n",  		   sane_strstatus (status));  	      return status;  	    }  	  } -	 +  	for (i = 0; i < buttons_pressed; ++i) {  	  const unsigned int button = result.buttons[i] - 1; /* 1 based ... */  	  DBG (3, "get_button_status: button %d pressed\n", button); @@ -3487,7 +3486,7 @@ get_button_status (Avision_Scanner* s)      else        DBG (3, "get_button_status: no button pressed\n");    } -   +    return SANE_STATUS_GOOD;  #undef add_token  } @@ -3496,33 +3495,33 @@ static SANE_Status  get_frame_info (Avision_Scanner* s)  {    Avision_Device* dev = s->hw; -   +    /* read stuff */    struct command_read rcmd;    size_t size;    SANE_Status status;    uint8_t result[8];    size_t i; -   +    DBG (3, "get_frame_info:\n"); -   +    size = sizeof (result); -  +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ; -  +    rcmd.datatypecode = 0x87; /* film holder sense */    set_double (rcmd.datatypequal, dev->data_dq);    set_triple (rcmd.transferlen, size); -  +    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result)) {      DBG (1, "get_frame_info: read failed (%s)\n", sane_strstatus (status));      return (status);    } -   +    debug_print_raw (6, "get_frame_info: raw data\n", result, size); -   +    DBG (3, "get_frame_info: [0]  Holder type: %s\n",         (result[0]==1)?"APS":         (result[0]==2)?"Film holder (35mm)": @@ -3531,24 +3530,24 @@ get_frame_info (Avision_Scanner* s)    DBG (3, "get_frame_info: [1]  Current frame number: %d\n", result[1]);    DBG (3, "get_frame_info: [2]  Frame amount: %d\n", result[2]);    DBG (3, "get_frame_info: [3]  Mode: %s\n", BIT(result[3],4)?"APS":"Not APS"); -  DBG (3, "get_frame_info: [3]  Exposures (if APS): %s\n",  +  DBG (3, "get_frame_info: [3]  Exposures (if APS): %s\n",         ((i=(BIT(result[3],3)<<1)+BIT(result[2],2))==0)?"Unknown":         (i==1)?"15":(i==2)?"25":"40"); -  DBG (3, "get_frame_info: [3]  Film Type (if APS): %s\n",  +  DBG (3, "get_frame_info: [3]  Film Type (if APS): %s\n",         ((i=(BIT(result[1],3)<<1)+BIT(result[0],2))==0)?"Unknown":         (i==1)?"B&W Negative":(i==2)?"Color slide":"Color Negative");    dev->holder_type = result[0];    dev->current_frame = result[1]; -  +    dev->frame_range.min = 1;    dev->frame_range.quant = 1; -   +    if (result[0] != 0xff)      dev->frame_range.max = result[2];    else      dev->frame_range.max = 1; -   +    return SANE_STATUS_GOOD;  } @@ -3556,7 +3555,7 @@ static SANE_Status  get_duplex_info (Avision_Scanner* s)  {    Avision_Device* dev = s->hw; -   +    /* read stuff */    struct command_read rcmd; @@ -3567,30 +3566,30 @@ get_duplex_info (Avision_Scanner* s)       uint8_t lineart_line_difference[2];       uint8_t image_info;    } result; -   +    size_t size;    SANE_Status status; -   +    DBG (3, "get_duplex_info:\n"); -   +    size = sizeof (result); -  +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ; -  +    rcmd.datatypecode = 0xB1; /* read duplex info */    set_double (rcmd.datatypequal, dev->data_dq);    set_triple (rcmd.transferlen, size); -  +    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0,  			&result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result)) {      DBG (1, "get_duplex_info: read failed (%s)\n", sane_strstatus (status));      return (status);    } -   +    debug_print_raw (6, "get_duplex_info: raw data\n", (uint8_t*)&result, size); -   +    DBG (3, "get_duplex_info: [0]    Mode: %s%s\n",         BIT(result.mode,0)?"MERGED_PAGES":"",         BIT(result.mode,1)?"2ND_PAGE_FOLLOWS":""); @@ -3606,7 +3605,7 @@ get_duplex_info (Avision_Scanner* s)         BIT(result.image_info,1)?" ADF_BGR":" ADF_RGB",         BIT(result.image_info,2)?" FLATBED_NEEDS_MIRROR_IMAGE":"",         BIT(result.image_info,3)?" ADF_NEEDS_MIRROR_IMAGE":""); -   +    return SANE_STATUS_GOOD;  } @@ -3617,45 +3616,45 @@ set_frame (Avision_Scanner* s, SANE_Word frame)      struct command_send cmd;      uint8_t data[8];    } scmd; -   +    Avision_Device* dev = s->hw;    SANE_Status status; -   +    DBG (3, "set_frame: request frame %d\n", frame); -   +    /* Better check the current status of the film holder, because it       can be changed between scans. */    status = get_frame_info (s);    if (status != SANE_STATUS_GOOD)      return status; -   +    /* No film holder? */    if (dev->holder_type == 0xff) {      DBG (1, "set_frame: No film holder!!\n");      return SANE_STATUS_INVAL;    } -   +    /* Requesting frame 0xff indicates eject/rewind */    if (frame != 0xff && (frame < 1 || frame > dev->frame_range.max) ) {      DBG (1, "set_frame: Illegal frame (%d) requested (min=1, max=%d)\n", -	 frame, dev->frame_range.max);  +	 frame, dev->frame_range.max);      return SANE_STATUS_INVAL;    } -   +    memset (&scmd, 0, sizeof (scmd));    scmd.cmd.opc = AVISION_SCSI_SEND;    scmd.cmd.datatypecode = 0x87; /* send film holder "sense" */    set_double (scmd.cmd.datatypequal, dev->data_dq);    set_triple (scmd.cmd.transferlen, sizeof (scmd.data) ); -   +    scmd.data[0] = dev->holder_type; -  scmd.data[1] = frame;  -   +  scmd.data[1] = frame; +    status = avision_cmd (&s->av_con, &scmd.cmd, sizeof (scmd.cmd),  			&scmd.data, sizeof (scmd.data), 0, 0);    if (status != SANE_STATUS_GOOD) {      DBG (1, "set_frame: send_data (%s)\n", sane_strstatus (status)); -  }   +  }    return status;  } @@ -3669,20 +3668,20 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,    Avision_Device* dev;    SANE_Status status; -   +    Avision_Connection av_con;    char mfg [9];    char model [17];    char rev [5]; -   +    unsigned int i;    char* s;    SANE_Bool found; -   +    DBG (3, "attach:\n");    memset (result, 0, sizeof(result)); -   +    for (dev = first_dev; dev; dev = dev->next)      if (strcmp (dev->sane.name, devname) == 0) {        if (devp) @@ -3693,25 +3692,25 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,    av_con.connection_type = con_type;    if (av_con.connection_type == AV_USB)      av_con.usb_status = AVISION_USB_UNTESTED_STATUS; -   +    /* set known USB status type */    if (attaching_hw && attaching_hw->feature_type & AV_INT_STATUS)      av_con.usb_status = AVISION_USB_INT_STATUS; -   +    DBG (3, "attach: opening %s\n", devname);    status = avision_open (devname, &av_con, sense_handler, 0);    if (status != SANE_STATUS_GOOD) {      DBG (1, "attach: open failed (%s)\n", sane_strstatus (status));      return SANE_STATUS_INVAL;    } -   +    /* first: get the standard inquiry? */    status = inquiry (av_con, result, AVISION_INQUIRY_SIZE_V1);    if (status != SANE_STATUS_GOOD) {      DBG (1, "attach: 1st inquiry failed (%s)\n", sane_strstatus (status));      return status;    } -   +    /* copy string information - and zero terminate them c-style */    memcpy (&mfg, result + 8, 8);    mfg [8] = 0; @@ -3719,7 +3718,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,    model [16] = 0;    memcpy (&rev, result + 32, 4);    rev [4] = 0; -   +    /* shorten strings (-1 for last index       -1 for last 0; >0 because one char at least) */    for (i = sizeof (mfg) - 2; i > 0; i--) { @@ -3734,10 +3733,10 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,      else        break;    } -   +    DBG (1, "attach: Inquiry gives mfg=%s, model=%s, product revision=%s.\n",         mfg, model, rev); -   +    model_num = 0;    found = 0;    /* while not at at end of list NULL terminator */ @@ -3746,7 +3745,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,    {      int matches = 0, match_count = 0; /* count number of matches */      DBG (1, "attach: Checking model: %d\n", model_num); -     +      if (Avision_Device_List[model_num].scsi_mfg) {        ++match_count;        if (strcmp(mfg, Avision_Device_List[model_num].scsi_mfg) == 0) @@ -3757,7 +3756,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,        if (strcmp(model, Avision_Device_List[model_num].scsi_model) == 0)          ++matches;      } -     +      /* we need 2 matches (mfg, model) for SCSI entries, or the ones available         for "we know what we are looking for" USB entries */      if ((attaching_hw == &(Avision_Device_List [model_num]) && @@ -3775,16 +3774,16 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,      }      ++model_num;    } -   +    if (!found) {      DBG (0, "attach: \"%s\" - \"%s\" not yet in whitelist!\n", mfg, model);      DBG (0, "attach: You might want to report this output.\n");      DBG (0, "attach: To: rene@exactcode.de (the Avision backend author)\n"); -     +      status = SANE_STATUS_INVAL;      goto close_scanner_and_return;    } -   +    /* second: maybe ask for the firmware status and flash ram info */    if (Avision_Device_List [model_num].feature_type & AV_FIRMWARE)    { @@ -3795,7 +3794,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,  	     sane_strstatus (status));  	goto close_scanner_and_return;        } -       +        DBG (3, "attach: reading flash ram info\n");        status = get_flash_ram_info (&av_con);        if (status != SANE_STATUS_GOOD) { @@ -3803,7 +3802,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,  	     sane_strstatus (status));  	goto close_scanner_and_return;        } -       +  #ifdef FIRMWARE_DATABASE_INCLUDED        /* Send new NV-RAM (firmware) data */        status = send_nvram_data (&av_con); @@ -3811,7 +3810,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,  	goto close_scanner_and_return;  #endif    } -   +    /* third: get the extended Avision inquiry */    status = inquiry (av_con, result, AVISION_INQUIRY_SIZE_V1);    if (status != SANE_STATUS_GOOD) { @@ -3824,17 +3823,17 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,      status = SANE_STATUS_NO_MEM;      goto close_scanner_and_return;    } -   +    memset (dev, 0, sizeof (*dev));    dev->hw = &Avision_Device_List[model_num]; -   +    dev->sane.name   = strdup (devname);    dev->sane.vendor = dev->hw->real_mfg   ? dev->hw->real_mfg   : strdup (mfg);    dev->sane.model  = dev->hw->real_model ? dev->hw->real_model : strdup (model);    dev->connection.connection_type = av_con.connection_type;    dev->connection.usb_status = av_con.usb_status; -   +    /* and finally Avision even extended this one later on       the AV220C2 does not grok this */    dev->inquiry_asic_type = (int) result[91]; @@ -3846,13 +3845,13 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,  	goto close_scanner_and_return;        }      } -   +    debug_print_raw (6, "attach: raw data:\n", result, sizeof (result) ); -   +    DBG (3, "attach: [8-15]  Vendor id.:      '%8.8s'\n", result+8);    DBG (3, "attach: [16-31] Product id.:     '%16.16s'\n", result+16);    DBG (3, "attach: [32-35] Product rev.:    '%4.4s'\n", result+32); -   +    i = (result[36] >> 4) & 0x7;    switch (result[36] & 0x07) {    case 0: @@ -3873,7 +3872,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,    DBG (3, "attach: [37]    Optical res.:    %d00 dpi\n", result[37]);    DBG (3, "attach: [38]    Maximum res.:    %d00 dpi\n", result[38]); -   +    DBG (3, "attach: [39]    Bitfield1:%s%s%s%s%s%s\n",         BIT(result[39],7)?" TRANS":"",         BIT(result[39],6)?" Q_SCAN":"", @@ -3881,7 +3880,7 @@ attach (SANE_String_Const devname, Avision_ConnectionType con_type,         BIT(result[39],4)?" SUPPORTS_CALIB":"",         BIT(result[39],2)?" NEW_PROTOCOL":"",         (result[39] & 0x03) == 0x03 ? " AVISION":" OEM"); -   +    DBG (3, "attach: [40-41] X res. in gray:  %d dpi\n",         get_double ( &(result[40]) ));    DBG (3, "attach: [42-43] Y res. in gray:  %d dpi\n", @@ -3920,7 +3919,7 @@ get_double ( &(result[48] ) ));         BIT(result[52],2)?" INDEX_COLOR":"",         BIT(result[52],1)?" POWER_SAVING_TIMER":"",         BIT(result[52],0)?" NVM_DATA_REC":""); -    +    /* print some more scanner features/params */    DBG (3, "attach: [53]    line difference (software color pack): %d\n", result[53]);    DBG (3, "attach: [54]    color mode pixel boundary: %d\n", result[54]); @@ -3929,13 +3928,13 @@ get_double ( &(result[48] ) ));    DBG (3, "attach: [57]    lineart mode pixel boundary: %d\n", result[57]);    DBG (3, "attach: [58]    halftone mode pixel boundary: %d\n", result[58]);    DBG (3, "attach: [59]    error-diffusion mode pixel boundary: %d\n", result[59]); -   +    DBG (3, "attach: [60]    channels per pixel:%s%s%s\n",         BIT(result[60],7)?" 1":"",         BIT(result[60],6)?" 3":"",         (result[60] & 0x3F) != 0 ? " RESERVED":""); -   -  DBG (3, "attach: [61]    bits per channel:%s%s%s%s%s%s%s\n",  + +  DBG (3, "attach: [61]    bits per channel:%s%s%s%s%s%s%s\n",         BIT(result[61],7)?" 1":"",         BIT(result[61],6)?" 4":"",         BIT(result[61],5)?" 6":"", @@ -3943,40 +3942,40 @@ get_double ( &(result[48] ) ));         BIT(result[61],3)?" 10":"",         BIT(result[61],2)?" 12":"",         BIT(result[61],1)?" 16":""); -   -  DBG (3, "attach: [62]    scanner type:%s%s%s%s%s%s\n",  + +  DBG (3, "attach: [62]    scanner type:%s%s%s%s%s%s\n",         BIT(result[62],7)?" Flatbed":"",         BIT(result[62],6)?" Roller (ADF)":"",         BIT(result[62],5)?" Flatbed (ADF)":"",         BIT(result[62],4)?" Roller":"", /* does not feed multiple pages, AV25 */         BIT(result[62],3)?" Film scanner":"",         BIT(result[62],2)?" Duplex":""); -   +    DBG (3, "attach: [75-76] Max shading target : %x\n",         get_double ( &(result[75]) )); -   +    DBG (3, "attach: [77-78] Max X of transparency: %d dots * base_dpi\n",         get_double ( &(result[77]) ));    DBG (3, "attach: [79-80] Max Y of transparency: %d dots * base_dpi\n",         get_double ( &(result[79]) )); -   +    DBG (3, "attach: [81-82] Max X of flatbed:      %d dots * base_dpi\n",         get_double ( &(result[81]) ));    DBG (3, "attach: [83-84] Max Y of flatbed:      %d dots * base_dpi\n",         get_double ( &(result[83]) )); -   +    DBG (3, "attach: [85-86] Max X of ADF:          %d dots * base_dpi\n",         get_double ( &(result[85]) ));    DBG (3, "attach: [87-88] Max Y of ADF:          %d dots * base_dpi\n",         get_double ( &(result[87]) )); /* 0xFFFF means unlimited length */ -   +    DBG (3, "attach: [89-90] Res. in Ex. mode:      %d dpi\n",         get_double ( &(result[89]) )); -   +    DBG (3, "attach: [91]    ASIC:     %d\n", result[91]); -    +    DBG (3, "attach: [92]    Buttons:  %d\n", result[92]); -   +    DBG (3, "attach: [93]    ESA4:%s%s%s%s%s%s%s%s\n",         BIT(result[93],7)?" SUPPORTS_ACCESSORIES_DETECT":"",         BIT(result[93],6)?" ADF_IS_BGR_ORDERED":"", @@ -3986,7 +3985,7 @@ get_double ( &(result[48] ) ));         BIT(result[93],2)?" SUPPORTS_LIGHT_DETECT":"",         BIT(result[93],1)?" SUPPORTS_READ_PRNU_DATA":"",         BIT(result[93],0)?" FLATBED_MIRRORS_IMAGE":""); -   +    DBG (3, "attach: [94]    ESA5:%s%s%s%s%s%s%s%s\n",         BIT(result[94],7)?" IGNORE_LINE_DIFFERENCE_FOR_ADF":"",         BIT(result[94],6)?" NEEDS_SW_LINE_COLOR_PACK":"", @@ -3996,7 +3995,7 @@ get_double ( &(result[48] ) ));         BIT(result[94],2)?" SUPPORTS_TUNE_SCAN_LENGTH":"",         BIT(result[94],1)?" SUPPORTS_SWITCH_STRIP_FOR_DESKEW":"", /* Kodak i80 only */         BIT(result[94],0)?" SEARCHES_LEADING_SIDE_EDGE_BY_FIRMWARE":""); -   +    DBG (3, "attach: [95]    ESA6:%s%s%s%s%s%s%s%s\n",         BIT(result[95],7)?" SUPPORTS_PAPER_SIZE_AUTO_DETECTION":"",         BIT(result[95],6)?" SUPPORTS_DO_HOUSEKEEPING":"", /* Kodak i80 only */ @@ -4006,7 +4005,7 @@ get_double ( &(result[48] ) ));         BIT(result[95],2)?" SUPPORTS_GET_BACKGROUND_RASTER":"", /* AV220 et.al. */         BIT(result[95],1)?" SUPPORTS_NVRAM_RESET":"",         BIT(result[95],0)?" SUPPORTS_BATCH_SCAN":""); -   +    DBG (3, "attach: [128]    ESA7:%s%s%s%s%s%s%s%s\n",         BIT(result[128],7)?" SUPPORTS_ADF_CONTINUOUS":"",         BIT(result[128],6)?" SUPPORTS_YCbCr_COLOR":"", @@ -4016,7 +4015,7 @@ get_double ( &(result[48] ) ));         BIT(result[128],2)?" SUPPORTS_JOB_CONTROL":"",         BIT(result[128],1)?" SUPPORTS_INF_LENGTH":"",         BIT(result[128],0)?" ULTRA_SONIC_DOUBLE_FEED_DETECTION":""); -   +    DBG (3, "attach: [129]    YCbCr:%s%s%s%s%s%s%s%s\n",         BIT(result[129],7)?" YCC4:2:0":"",         BIT(result[129],6)?" YCC(profile2)":"", @@ -4026,7 +4025,7 @@ get_double ( &(result[48] ) ));         BIT(result[129],2)?" JPEG(profile2)":"",         BIT(result[129],1)?" JPEG(profile3)":"",         BIT(result[129],0)?" JPEG(profile4)":""); -   +    /* I have no idea how film scanner could reliably be detected -ReneR */    if (dev->hw->feature_type & AV_FILMSCANNER) {      dev->scanner_type = AV_FILM; @@ -4046,19 +4045,19 @@ get_double ( &(result[48] ) ));    dev->inquiry_nvram_read = BIT(result[52],0);    dev->inquiry_power_save_time = BIT(result[52],1); -   +    dev->inquiry_adf = BIT (result[62], 5);    dev->inquiry_duplex = BIT (result[62], 2) || BIT (result[94], 5); -  dev->inquiry_duplex_interlaced = BIT(result[62],2) || BIT (result[94], 4);  +  dev->inquiry_duplex_interlaced = BIT(result[62],2) || BIT (result[94], 4);    /* the first avision scanners (AV3200) do not set the interlaced bit */    if (dev->inquiry_duplex && dev->inquiry_asic_type < AV_ASIC_C6)      dev->inquiry_duplex_interlaced = 1;    dev->inquiry_paper_length = BIT (result[95], 5);    dev->inquiry_batch_scan = BIT (result[95], 0); /* AV122, DM152 */ -   +    dev->inquiry_detect_accessories = BIT (result[93], 7); -  +    dev->inquiry_needs_calibration = BIT (result[50], 4);    dev->inquiry_keeps_window = BIT (result[50], 1); @@ -4066,7 +4065,7 @@ get_double ( &(result[48] ) ));      dev->inquiry_keeps_window = 0;    if (Avision_Device_List [model_num].feature_type & AV_DOES_KEEP_WINDOW)      dev->inquiry_keeps_window = 1; -   +    dev->inquiry_needs_gamma = BIT (result[50], 3);    dev->inquiry_keeps_gamma = BIT (result[50], 2);    if (Avision_Device_List [model_num].feature_type & AV_DOES_NOT_KEEP_GAMMA) @@ -4076,33 +4075,33 @@ get_double ( &(result[48] ) ));    dev->inquiry_3x3_matrix = BIT (result[51], 1);    dev->inquiry_needs_software_colorpack = BIT (result[50],5); -   +    dev->inquiry_needs_line_pack = BIT (result[94], 6); -   +    dev->inquiry_adf_need_mirror = BIT (result[51], 0);    dev->inquiry_adf_bgr_order = BIT (result[93], 6);    if (Avision_Device_List [model_num].feature_type & AV_ADF_BGR_ORDER_INVERT)      dev->inquiry_adf_bgr_order = ! dev->inquiry_adf_bgr_order; -   +    dev->inquiry_light_detect = BIT (result[93], 2);    dev->inquiry_light_control = BIT (result[50], 7);    dev->inquiry_button_control = BIT (result[50], 6) | BIT (result[51],2); -   +    dev->inquiry_exposure_control = BIT(result[51],7);    dev->inquiry_max_shading_target = get_double ( &(result[75]) ); -   +    dev->inquiry_color_boundary = result[54];    if (dev->inquiry_color_boundary == 0)      dev->inquiry_color_boundary = 8; -   +    dev->inquiry_gray_boundary = result[55];    if (dev->inquiry_gray_boundary == 0)      dev->inquiry_gray_boundary = 8; -   +    dev->inquiry_dithered_boundary = result[59];    if (dev->inquiry_dithered_boundary == 0)      dev->inquiry_dithered_boundary = 8; -   +    dev->inquiry_thresholded_boundary = result[57];    if (dev->inquiry_thresholded_boundary == 0)      dev->inquiry_thresholded_boundary = 8; @@ -4121,7 +4120,7 @@ get_double ( &(result[48] ) ));      default:        ;    } -   +    if (dev->inquiry_new_protocol) {      dev->inquiry_optical_res = get_double ( &(result[89]) );      dev->inquiry_max_res = get_double ( &(result[44]) ); @@ -4136,7 +4135,7 @@ get_double ( &(result[48] ) ));      DBG (1, "Inquiry optical resolution > max_resolution, adjusting!\n");      dev->inquiry_max_res = dev->inquiry_optical_res;    } -   +    if (dev->inquiry_optical_res == 0)      {        DBG (1, "Inquiry optical resolution is invalid!\n"); @@ -4151,7 +4150,7 @@ get_double ( &(result[48] ) ));      DBG (1, "Inquiry max resolution is invalid, using 1200 dpi!\n");      dev->inquiry_max_res = 1200;    } -   +    DBG (1, "attach: optical resolution set to: %d dpi\n", dev->inquiry_optical_res);    DBG (1, "attach: max resolution set to: %d dpi\n", dev->inquiry_max_res); @@ -4163,7 +4162,7 @@ get_double ( &(result[48] ) ));      dev->inquiry_channels_per_pixel = 3;    else      dev->inquiry_channels_per_pixel = 1; -   +    if (BIT(result[61],1))      dev->inquiry_bits_per_channel = 16;    else if (BIT(result[61],2)) @@ -4192,7 +4191,7 @@ get_double ( &(result[48] ) ));    if (! (dev->hw->feature_type & AV_NO_BUTTON))      dev->inquiry_buttons = result[92]; -   +    /* get max x/y ranges for the different modes */    {      double base_dpi; /* TODO: make int */ @@ -4205,39 +4204,39 @@ get_double ( &(result[48] ) ));         */        base_dpi = dev->inquiry_optical_res;      } -     +      /* .1 to slightly increase the size to match the one of American standard paper         formats that would otherwise be .1 mm too large to scan ... */      dev->inquiry_x_ranges [AV_NORMAL_DIM] =        (double)get_double (&(result[81])) * MM_PER_INCH / base_dpi + .1;      dev->inquiry_y_ranges [AV_NORMAL_DIM] =        (double)get_double (&(result[83])) * MM_PER_INCH / base_dpi; -   +      dev->inquiry_x_ranges [AV_TRANSPARENT_DIM] =        (double)get_double (&(result[77])) * MM_PER_INCH / base_dpi + .1;      dev->inquiry_y_ranges [AV_TRANSPARENT_DIM] =        (double)get_double (&(result[79])) * MM_PER_INCH / base_dpi; -   +      dev->inquiry_x_ranges [AV_ADF_DIM] =        (double)get_double (&(result[85])) * MM_PER_INCH / base_dpi + .1;      dev->inquiry_y_ranges [AV_ADF_DIM] =        (double)get_double (&(result[87])) * MM_PER_INCH / base_dpi;    } -   +    dev->inquiry_tune_scan_length = BIT(result[94],2);    if (Avision_Device_List [model_num].feature_type & AV_NO_TUNE_SCAN_LENGTH)      dev->inquiry_tune_scan_length = 0;    dev->inquiry_background_raster = BIT(result[95],2); -   +    if (dev->hw->feature_type & AV_NO_BACKGROUND)      dev->inquiry_background_raster = 0; -   +    if (dev->inquiry_background_raster) {      dev->inquiry_background_raster_pixel =        get_double(&(result[85])) * dev->inquiry_optical_res / AVISION_BASE_RES;    } -   +    /* check if x/y ranges are valid :-((( */    {      source_mode_dim mode; @@ -4271,7 +4270,7 @@ get_double ( &(result[48] ) ));  	    }  	    else {  	      dev->inquiry_x_ranges [mode] = A4_X_RANGE * MM_PER_INCH; -	       +  	      if (dev->scanner_type == AV_SHEETFEED)  		dev->inquiry_y_ranges [mode] = SHEETFEED_Y_RANGE * MM_PER_INCH;  	      else @@ -4283,7 +4282,7 @@ get_double ( &(result[48] ) ));  	     dev->inquiry_x_ranges [mode], dev->inquiry_y_ranges [mode]);        } /* end for all modes */    } -   +    /* We need a bigger buffer for USB devices, since they seem to have       a firmware bug and do not support reading the calibration data in       tiny chunks */ @@ -4298,26 +4297,26 @@ get_double ( &(result[48] ) ));      dev->read_stripe_size = 32;    else  /* tested on AV3200 with it's max of 300dpi @color */      dev->read_stripe_size = 8; /* maybe made dynamic on scan res ... */ -   +    /* normally the data_dq is 0x0a0d - but some newer scanner hang with it ... */    if (dev->inquiry_new_protocol) /* TODO: match on ASIC? which model hung? */      dev->data_dq = 0x0a0d;    else      dev->data_dq = 0; -   +    avision_close (&av_con); -   +    ++ num_devices;    dev->next = first_dev;    first_dev = dev;    if (devp)      *devp = dev; -   +    return SANE_STATUS_GOOD; -   +   close_scanner_and_return:    avision_close (&av_con); -   +    return status;  } @@ -4327,39 +4326,39 @@ get_tune_scan_length (Avision_Scanner* s)  {    SANE_Status status;    int i; -   +    struct command_read rcmd;    size_t size; -   +    struct max_value {      uint8_t max [2];    } payload; -   +    /* turn on the light */    DBG (3, "get_tune_scan_length:\n");    memset (&rcmd, 0, sizeof (rcmd));    size = sizeof (payload); -   +    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0xD2; /* Read General Ability/Parameter */ -   +    for (i = 1; i <= 8; ++i) {      memset (&payload, 0, sizeof (payload)); -     +      set_double (rcmd.datatypequal, i); /* type */      set_triple (rcmd.transferlen, size); -     +      status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd),  			  0, 0, &payload, &size); -     +      if (status != SANE_STATUS_GOOD) {        DBG (1, "get_tune_scan_length: read %d failed (%s)\n", i, sane_strstatus (status));        return status;      }      DBG (1, "get_tune_scan_length: %d: %d\n", i, get_double (payload.max));    } -   +    return SANE_STATUS_GOOD;  } @@ -4367,7 +4366,7 @@ static SANE_Status  send_tune_scan_length (Avision_Scanner* s)  {    int top, bottom; -   +    SANE_Status status;    size_t size;    struct command_send scmd; @@ -4375,31 +4374,31 @@ send_tune_scan_length (Avision_Scanner* s)      uint8_t vertical [2];   /*   uint8_t horizontal [2]; not send by the Windows driver, yet */    } payload; -   +    DBG (3, "send_tune_scan_length:\n"); -   +    memset (&scmd, 0, sizeof (scmd)); -   +    size = sizeof (payload);    scmd.opc = AVISION_SCSI_SEND;    scmd.datatypecode = 0x96; /* Attach/Truncate head(left) of scan length */    set_triple (scmd.transferlen, size); -   +    /* the SPEC says optical DPI, but real world measuring suggests it is 1200       as in the window descriptor */    top = 1200 * SANE_UNFIX (s->val[OPT_OVERSCAN_TOP].w) / MM_PER_INCH;    DBG (3, "send_tune_scan_length: top: %d\n", top); -   +    set_double (scmd.datatypequal, 0x0001); /* attach, 0x000 is shorten */    set_double (payload.vertical, top);    /* set_double (payload.horizontal, 0); */ -   +    /* we alway send it, even for 0 as the scanner keeps it in RAM and       previous runs could already have set something */ -   +    status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  			&payload, sizeof (payload), 0, 0); -   +    if (status != SANE_STATUS_GOOD) {      DBG (1, "send_tune_scan_length: send top/left failed (%s)\n", sane_strstatus (status));      return status; @@ -4411,16 +4410,16 @@ send_tune_scan_length (Avision_Scanner* s)    set_double (payload.vertical, bottom);    /*set_double (payload.horizontal, 0); */ -   +    size = sizeof (payload);    status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  			&payload, sizeof (payload), 0, 0); -   +    if (status != SANE_STATUS_GOOD) {      DBG (1, "send_tune_scan_length: send bottom/right failed (%s)\n", sane_strstatus (status));      return status;    } -   +    return SANE_STATUS_GOOD;  } @@ -4428,10 +4427,10 @@ static SANE_Status  additional_probe (Avision_Scanner* s)  {    Avision_Device* dev = s->hw; -   +    /* we should wait until the scanner is ready before we       perform further actions */ -   +    SANE_Status status;    /* try to retrieve additional accessory information */    if (dev->inquiry_detect_accessories) { @@ -4439,28 +4438,28 @@ additional_probe (Avision_Scanner* s)      if (status != SANE_STATUS_GOOD)        return status;    } -   +    /* for a film scanner try to retrieve additional frame information */    if (dev->scanner_type == AV_FILM) {      status = get_frame_info (s);      if (status != SANE_STATUS_GOOD)        return status;    } -   +    /* no scanner did support this so far: tried on AV220, DM152 */    if (0 && dev->inquiry_duplex) {      status = get_duplex_info (s);      if (status != SANE_STATUS_GOOD)        return status;    } -   +    /* get overscan ("head/tail tune") information: hangs AV220, zeros on AV122 */    if (0 && dev->inquiry_tune_scan_length) {      status = get_tune_scan_length (s);      if (status != SANE_STATUS_GOOD)        return status;    } -   +    /* create dynamic *-mode entries */    if (!dev->inquiry_no_gray_modes)    { @@ -4474,7 +4473,7 @@ additional_probe (Avision_Scanner* s)      if (dev->inquiry_bits_per_channel == 12)        add_color_mode (dev, AV_GRAYSCALE12, "12bit Gray"); -   +      if (dev->inquiry_bits_per_channel >= 16)        add_color_mode (dev, AV_GRAYSCALE16, "16bit Gray");    } @@ -4484,17 +4483,17 @@ additional_probe (Avision_Scanner* s)      if (dev->inquiry_bits_per_channel == 12)        add_color_mode (dev, AV_TRUECOLOR12, "12bit Color"); -     +      if (dev->inquiry_bits_per_channel >= 16)        add_color_mode (dev, AV_TRUECOLOR16, "16bit Color");    } -   +    /* now choose the default mode - avoiding the 12/16 bit modes */    dev->color_list_default = last_color_mode (dev);    if (dev->inquiry_bits_per_channel > 8 && dev->color_list_default > 0) {      dev->color_list_default--;    } -   +    if (dev->scanner_type == AV_SHEETFEED)      {        add_source_mode (dev, AV_ADF, "ADF Front"); @@ -4502,20 +4501,20 @@ additional_probe (Avision_Scanner* s)    else      {        add_source_mode (dev, AV_NORMAL, "Normal"); -       +        if (dev->inquiry_light_box)  	add_source_mode (dev, AV_TRANSPARENT, "Transparency"); -       +        if (dev->inquiry_adf)          add_source_mode (dev, AV_ADF, "ADF Front");      } -   +    if (dev->inquiry_duplex) {      if (dev->inquiry_duplex_interlaced && !(dev->hw->feature_type & AV_NO_REAR))        add_source_mode (dev, AV_ADF_REAR, "ADF Back");      add_source_mode (dev, AV_ADF_DUPLEX, "ADF Duplex");    } -   +    return SANE_STATUS_GOOD;  } @@ -4523,21 +4522,21 @@ static SANE_Status  get_calib_format (Avision_Scanner* s, struct calibration_format* format)  {    SANE_Status status; -   +    struct command_read rcmd;    uint8_t result [32];    size_t size; -   +    DBG (3, "get_calib_format:\n");    size = sizeof (result); -   +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0x60; /* get calibration format */    set_double (rcmd.datatypequal, s->hw->data_dq);    set_triple (rcmd.transferlen, size); -   +    DBG (3, "get_calib_format: read_data: %lu bytes\n", (u_long) size);    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result) ) { @@ -4545,9 +4544,9 @@ get_calib_format (Avision_Scanner* s, struct calibration_format* format)  	 sane_strstatus (status) );      return status;    } -   +    debug_print_calib_format (3, "get_calib_format", result); -   +    format->pixel_per_line = get_double (&(result[0]));    format->bytes_per_channel = result[2];    format->lines = result[3]; @@ -4562,21 +4561,21 @@ get_calib_format (Avision_Scanner* s, struct calibration_format* format)    format->r_dark_shading_target = get_double (&(result[15]));    format->g_dark_shading_target = get_double (&(result[17]));    format->b_dark_shading_target = get_double (&(result[19])); -   +    /* now translate to normal! */    /* firmware return R--RG--GB--B with 3 line count */    /* software format it as 1 line if true color scan */    /* only line interleave format to be supported */ -   +    if (color_mode_is_color (s->c_mode) || BIT(format->ability1, 3)) {      format->channels = 3;      format->lines /= 3; /* line interleave */    }    else      format->channels = 1; -   +    DBG (3, "get_calib_format: channels: %d\n", format->channels); -   +    return SANE_STATUS_GOOD;  } @@ -4587,26 +4586,26 @@ get_calib_data (Avision_Scanner* s, uint8_t data_type,  {    SANE_Status status;    uint8_t *calib_ptr; -   +    size_t get_size, data_size, chunk_size; -   +    struct command_read rcmd; -   +    chunk_size = calib_size; -   +    DBG (3, "get_calib_data: type %x, size %lu, chunk_size: %lu\n",         data_type, (u_long) calib_size, (u_long) chunk_size); -   +    memset (&rcmd, 0, sizeof (rcmd)); -   +    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = data_type;    set_double (rcmd.datatypequal, s->hw->data_dq); -   +    calib_ptr = calib_data;    get_size = chunk_size;    data_size = calib_size; -   +    while (data_size) {      if (get_size > data_size)        get_size = data_size; @@ -4617,7 +4616,7 @@ get_calib_data (Avision_Scanner* s, uint8_t data_type,      DBG (3, "get_calib_data: Reading %ld bytes calibration data\n",           (long)get_size); -  +      status = avision_cmd (&s->av_con, &rcmd,  			  sizeof (rcmd), 0, 0, calib_ptr, &get_size);      if (status != SANE_STATUS_GOOD) { @@ -4631,7 +4630,7 @@ get_calib_data (Avision_Scanner* s, uint8_t data_type,      data_size -= get_size;      calib_ptr += get_size;    } -   +    return SANE_STATUS_GOOD;  } @@ -4640,22 +4639,22 @@ set_calib_data (Avision_Scanner* s, struct calibration_format* format,  		uint8_t* dark_data, uint8_t* white_data)  {    Avision_Device* dev = s->hw; -   +    const int elements_per_line = format->pixel_per_line * format->channels; -   +    SANE_Status status; -   +    uint8_t send_type;    uint16_t send_type_q; -   +    struct command_send scmd; -   +    int i; -   +    DBG (3, "set_calib_data:\n"); -   +    send_type = 0x82; /* download calibration data */ -   +    /* do we use a color mode? */    if (format->channels > 1) {      send_type_q = 0x12; /* color calib data */ @@ -4666,40 +4665,40 @@ set_calib_data (Avision_Scanner* s, struct calibration_format* format,      else        send_type_q = 0x11; /* gray/bw calib data */    } -   +    memset (&scmd, 0x00, sizeof (scmd));    scmd.opc = AVISION_SCSI_SEND;    scmd.datatypecode = send_type; -   +    /* data corrections due to dark calibration data merge */    if (BIT (format->ability1, 2) ) {      DBG (3, "set_calib_data: merging dark calibration data\n");      for (i = 0; i < elements_per_line; ++i) {        uint16_t value_orig = get_double_le (white_data + i*2);        uint16_t value_new = value_orig; -       +        value_new &= 0xffc0;        value_new |= (get_double_le (dark_data + i*2) >> 10) & 0x3f; -       +        DBG (9, "set_calib_data: element %d, dark difference %d\n",  	   i, value_orig - value_new); -       +        set_double_le ((white_data + i*2), value_new);      }    } -   +    /* send data in one command? */    /* FR: HP5370 reports one-pass, but needs multi (or other format in single) */    if (format->channels == 1 ||        ( ( (dev->hw->feature_type & AV_ONE_CALIB_CMD) || -	  ! BIT(format->ability1, 0) ) &&  +	  ! BIT(format->ability1, 0) ) &&  	! (dev->hw->feature_type & AV_MULTI_CALIB_CMD) ) )      /* one command (most scanners) */      {        size_t send_size = elements_per_line * 2;        DBG (3, "set_calib_data: all channels in one command\n");        DBG (3, "set_calib_data: send_size: %lu\n", (u_long) send_size); -       +        memset (&scmd, 0, sizeof (scmd) );        scmd.opc = AVISION_SCSI_SEND;        scmd.datatypecode = send_type; @@ -4715,9 +4714,9 @@ set_calib_data (Avision_Scanner* s, struct calibration_format* format,        int conv_out_size = format->pixel_per_line * 2;        uint16_t* conv_out_data; /* here it is save to use 16bit data  				   since we only move whole words around */ -       +        DBG (3, "set_calib_data: channels in single commands\n"); -       +        conv_out_data =  (uint16_t*) malloc (conv_out_size);        if (!conv_out_data) {  	status = SANE_STATUS_NO_MEM; @@ -4727,24 +4726,24 @@ set_calib_data (Avision_Scanner* s, struct calibration_format* format,  	for (channel = 0; channel < 3; ++ channel)  	  {  	    int i; -	     +  	    /* no need for endianness handling since whole word copy */  	    uint16_t* casted_avg_data = (uint16_t*) white_data; -	     +  	    DBG (3, "set_calib_data_calibration: channel: %i\n", channel); -	     +  	    for (i = 0; i < format->pixel_per_line; ++ i)  	      conv_out_data [i] = casted_avg_data [i * 3 + channel]; -	     +  	    DBG (3, "set_calib_data: sending %i bytes now\n",  		 conv_out_size); -	     +  	    memset (&scmd, 0, sizeof (scmd));  	    scmd.opc = AVISION_SCSI_SEND;  	    scmd.datatypecode = send_type; /* send calibration data */  	    set_double (scmd.datatypequal, channel);  	    set_triple (scmd.transferlen, conv_out_size); -	     +  	    status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  				  conv_out_data, conv_out_size, 0, 0);  	    if (status != SANE_STATUS_GOOD) { @@ -4756,14 +4755,14 @@ set_calib_data (Avision_Scanner* s, struct calibration_format* format,  	free (conv_out_data);        } /* end else send calib data*/      } -   +    return SANE_STATUS_GOOD;  }  /* Sort data pixel by pixel and average first 2/3 of the data.     The caller has to free return pointer. R,G,B pixels     interleave to R,G,B line interleave. -    +     The input data data is in 16 bits little endian, always.     That is a = b[1] << 8 + b[0] in all system. @@ -4776,34 +4775,34 @@ sort_and_average (struct calibration_format* format, uint8_t* data)    const int elements_per_line = format->pixel_per_line * format->channels;    const int stride = format->bytes_per_channel * elements_per_line;    int i, line; -     +    uint8_t *sort_data, *avg_data; -   +    DBG (1, "sort_and_average:\n"); -   +    if (!format || !data)      return NULL; -   +    sort_data = malloc (format->lines * 2);    if (!sort_data)      return NULL; -   +    avg_data = malloc (elements_per_line * 2);    if (!avg_data) {      free (sort_data);      return NULL;    } -   +    /* for each pixel */    for (i = 0; i < elements_per_line; ++ i)      {        uint8_t* ptr1 = data + i * format->bytes_per_channel;        uint16_t temp; -       +        /* copy all lines for pixel i into the linear array sort_data */        for (line = 0; line < format->lines; ++ line) {  	uint8_t* ptr2 = ptr1 + line * stride; /* pixel */ -	 +  	if (format->bytes_per_channel == 1)  	  temp = 0xffff * *ptr2 / 255;  	else @@ -4811,12 +4810,12 @@ sort_and_average (struct calibration_format* format, uint8_t* data)  	set_double ((sort_data + line*2), temp); /* store big-endian */  	/* DBG (7, "ReneR to sort: %x\n", temp); */        } -       +        temp = bubble_sort (sort_data, format->lines);        /* DBG (7, "ReneR averaged: %x\n", temp); */        set_double ((avg_data + i*2), temp); /* store big-endian */      } -   +    free ((void *) sort_data);    return avg_data;  } @@ -4828,28 +4827,28 @@ compute_dark_shading_data (Avision_Scanner* s,  {    uint16_t map_value = DEFAULT_DARK_SHADING;    uint16_t rgb_map_value[3]; -   +    int elements_per_line, i; -   +    DBG (3, "compute_dark_shading_data:\n"); -   +    if (s->hw->inquiry_max_shading_target != INVALID_DARK_SHADING)      map_value = s->hw->inquiry_max_shading_target << 8; -   +    rgb_map_value[0] = format->r_dark_shading_target;    rgb_map_value[1] = format->g_dark_shading_target;    rgb_map_value[2] = format->b_dark_shading_target; -   +    for (i = 0; i < format->channels; ++i) {      if (rgb_map_value[i] == INVALID_DARK_SHADING)        rgb_map_value[i] = map_value;    } -   +    if (format->channels == 1) {      /* set to green, TODO: should depend on color drop-out and true-gray -ReneR */      rgb_map_value[0] = rgb_map_value[1] = rgb_map_value[2] = rgb_map_value[1];    } -   +    elements_per_line = format->pixel_per_line * format->channels;    /* Check line interleave or pixel interleave. */ @@ -4874,22 +4873,22 @@ compute_white_shading_data (Avision_Scanner* s,    int i;    uint16_t inquiry_mst = DEFAULT_WHITE_SHADING;    uint16_t mst[3]; -   +    int elements_per_line = format->pixel_per_line * format->channels; -   +    /* debug counter */    int values_invalid = 0;    int values_limitted = 0; -   +    DBG (3, "compute_white_shading_data:\n"); -   +    if (s->hw->inquiry_max_shading_target != INVALID_WHITE_SHADING)      inquiry_mst = s->hw->inquiry_max_shading_target << 4; -   +    mst[0] = format->r_shading_target;    mst[1] = format->g_shading_target;    mst[2] = format->b_shading_target; -   +    for (i = 0; i < 3; ++i) {      if (mst[i] == INVALID_WHITE_SHADING) /* mst[i] > MAX_WHITE_SHADING) */  {        DBG (3, "compute_white_shading_data: target %d invalid (%x) using inquiry (%x)\n", @@ -4913,7 +4912,7 @@ compute_white_shading_data (Avision_Scanner* s,      else        DBG (3, "compute_white_shading_data: target %d: %x\n", i, mst[0]);    } -   +    /* some Avision example code was present here until SANE/Avision     * BUILD 57. */ @@ -4921,31 +4920,31 @@ compute_white_shading_data (Avision_Scanner* s,      /* set to green, TODO: should depend on color drop-out and true-gray -ReneR */      mst[0] = mst[1] = mst[2] = mst[1];    } -   +    /* calculate calibration data */    for (i = 0; i < elements_per_line; ++ i)      {        int result;        /* calculate calibration value for pixel i */        uint16_t tmp_data = get_double((data + i*2)); -       +        if (tmp_data == INVALID_WHITE_SHADING) {         	tmp_data = DEFAULT_WHITE_SHADING;  	++ values_invalid;        } -       +        result = ( (int)mst[i % 3] * WHITE_MAP_RANGE / (tmp_data + 0.5)); -       +        /* sanity check for over-amplification, clipping */        if (result > MAX_WHITE_SHADING) {  	result = WHITE_MAP_RANGE;  	++ values_limitted;        } -       +        /* for visual debugging ... */        if (static_calib_list [i % 3] == SANE_TRUE)  	result = 0xA000; -       +        /* the output to the scanner will be 16 bit little endian again */        set_double_le ((data + i*2), result);      } @@ -4959,20 +4958,20 @@ static SANE_Status  normal_calibration (Avision_Scanner* s)  {    SANE_Status status; -   +    struct calibration_format calib_format; -   +    int calib_data_size, calib_bytes_per_line;    uint8_t read_type;    uint8_t *calib_tmp_data; -   +    DBG (1, "normal_calibration:\n"); -   +    /* get calibration format and data */    status = get_calib_format (s, &calib_format);    if (status != SANE_STATUS_GOOD)      return status; -   +    /* check if need do calibration */    if (calib_format.flags != 1) {      DBG (1, "normal_calibration: Scanner claims no calibration needed -> skipped!\n"); @@ -4983,27 +4982,27 @@ normal_calibration (Avision_Scanner* s)    /* size = lines * bytes_per_channel * pixels_per_line * channel */    calib_bytes_per_line = calib_format.bytes_per_channel *      calib_format.pixel_per_line * calib_format.channels; -   +    calib_data_size = calib_format.lines * calib_bytes_per_line; -   +    calib_tmp_data = malloc (calib_data_size);    if (!calib_tmp_data)      return SANE_STATUS_NO_MEM; -   +    /* check if we need to do dark calibration (shading) */    if (BIT(calib_format.ability1, 3))      {        DBG (1, "normal_calibration: reading dark data\n");        /* read dark calib data */        status = get_calib_data (s, 0x66, calib_tmp_data, calib_data_size); -       +        if (status != SANE_STATUS_GOOD) {  	free (calib_tmp_data);  	return status;        } -       +        /* process dark data: sort and average. */ -       +        if (s->dark_avg_data) {  	free (s->dark_avg_data);  	s->dark_avg_data = 0; @@ -5015,7 +5014,7 @@ normal_calibration (Avision_Scanner* s)        }        compute_dark_shading_data (s, &calib_format, s->dark_avg_data);      } -   +    /* do we use a color mode? */    if (calib_format.channels > 1) {      DBG (3, "normal_calibration: using color calibration\n"); @@ -5025,15 +5024,15 @@ normal_calibration (Avision_Scanner* s)      DBG (3, "normal_calibration: using gray calibration\n");      read_type = 0x61; /* gray calib data */    } -   +    /* do white calibration: read gray or color data */    status = get_calib_data (s, read_type, calib_tmp_data, calib_data_size); -   +    if (status != SANE_STATUS_GOOD) {      free (calib_tmp_data);      return status;    } -   +    if (0) /* debug */      {        FILE* f = NULL; @@ -5041,11 +5040,11 @@ normal_calibration (Avision_Scanner* s)        write_pnm_header (f, AV_GRAYSCALE, calib_format.bytes_per_channel * 8,  			calib_format.pixel_per_line,  			calib_format.lines * calib_format.channels); -       +        fwrite (calib_tmp_data, 1, calib_data_size, f);        fclose (f);      } -   +    if (s->white_avg_data) {      free (s->white_avg_data);      s->white_avg_data = 0; @@ -5055,24 +5054,24 @@ normal_calibration (Avision_Scanner* s)      free (calib_tmp_data);      return SANE_STATUS_NO_MEM;    } -   +    /* decrease white average data (if dark average data is present) */    if (s->dark_avg_data) {      int elements_per_line = calib_format.pixel_per_line * calib_format.channels;      int i;      DBG (1, "normal_calibration: dark data present - decreasing white average data\n"); -     +      for (i = 0; i < elements_per_line; ++ i) {        s->white_avg_data[i] -= s->dark_avg_data[i];      }    } -   +    compute_white_shading_data (s, &calib_format, s->white_avg_data); -   +    status = set_calib_data (s, &calib_format,  			   s->dark_avg_data, s->white_avg_data); -   +    free (calib_tmp_data);    return status;  } @@ -5080,12 +5079,12 @@ normal_calibration (Avision_Scanner* s)  /* next was taken from the GIMP and is a bit modified ... ;-)   * original Copyright (C) 1995 Spencer Kimball and Peter Mattis   */ -static double  +static double  brightness_contrast_func (double brightness, double contrast, double value)  {    double nvalue;    double power; -   +    /* apply brightness */    if (brightness < 0.0)      value = value * (1.0 + brightness); @@ -5130,28 +5129,28 @@ send_gamma (Avision_Scanner* s)  {    Avision_Device* dev = s->hw;    SANE_Status status = SANE_STATUS_GOOD; -   +    int invert_table = 0; -   +    size_t gamma_table_raw_size;    size_t gamma_table_size;    size_t gamma_values; -   +    struct command_send scmd;    uint8_t *gamma_data; -   +    int color; /* current color */    size_t i; /* big table index */    size_t j; /* little table index */    size_t k; /* big table sub index */    double v1, v2; -   +    double brightness;    double contrast; -   +    if (dev->inquiry_asic_type != AV_ASIC_OA980)      invert_table = (s->c_mode == AV_THRESHOLDED) || (s->c_mode == AV_DITHERED); -   +    switch (dev->inquiry_asic_type)      {      case AV_ASIC_Cx: @@ -5176,37 +5175,37 @@ send_gamma (Avision_Scanner* s)        gamma_table_raw_size = 512; /* SPEC claims: 256 ... ? */        gamma_table_size = 512;      } -   +    gamma_values = gamma_table_size / 256; -   +    DBG (3, "send_gamma: table_raw_size: %lu, table_size: %lu\n",         (u_long) gamma_table_raw_size, (u_long) gamma_table_size);    DBG (3, "send_gamma: values: %lu, invert_table: %d\n",         (u_long) gamma_values, invert_table); -   +    /* prepare for emulating contrast, brightness ... via the gamma-table */    brightness = SANE_UNFIX (s->val[OPT_BRIGHTNESS].w);    brightness /= 100;    contrast = SANE_UNFIX (s->val[OPT_CONTRAST].w);    contrast /= 100; -   +    DBG (3, "send_gamma: brightness: %f, contrast: %f\n", brightness, contrast); -   +    gamma_data = malloc (gamma_table_raw_size);    if (!gamma_data)      return SANE_STATUS_NO_MEM; -   +    memset (&scmd, 0, sizeof (scmd) ); -   +    scmd.opc = AVISION_SCSI_SEND;    scmd.datatypecode = 0x81; /* 0x81 for download gamma table */    set_triple (scmd.transferlen, gamma_table_raw_size); -   +    for (color = 0; color < 3 && status == SANE_STATUS_GOOD; ++ color)      {        /* color: 0=red; 1=green; 2=blue */        set_double (scmd.datatypequal, color); -       +        i = 0; /* big table index */        for (j = 0; j < 256; ++ j) /* little table index */  	{ @@ -5237,21 +5236,21 @@ send_gamma (Avision_Scanner* s)  		  v2 = (double) s->gamma_table [0][j + 1];  	      }  	    } /*end switch */ -	   +  	  /* Emulate brightness and contrast (at least the Avision AV6[2,3]0  	   * as well as many others do not have a hardware implementation,  	   * --$. The function was taken from the GIMP source - maybe I'll  	   * optimize it in the future (when I have spare time). */ -	   +  	  v1 /= 255;  	  v2 /= 255; -	       +  	  v1 = (brightness_contrast_func (brightness, contrast, v1) );  	  v2 = (brightness_contrast_func (brightness, contrast, v2) ); -	       +  	  v1 *= 255;  	  v2 *= 255; -	   +  	  if (invert_table) {  	    v1 = 255 - v1;  	    v2 = 255 - v2; @@ -5260,7 +5259,7 @@ send_gamma (Avision_Scanner* s)  	    if (v2 <= 0)  	      v2 = 0;  	  } -	   +  	  for (k = 0; k < gamma_values; ++ k, ++ i) {  	    gamma_data [i] = (uint8_t)  	      (((v1 * (gamma_values - k)) + (v2 * k) ) / (double) gamma_values); @@ -5275,12 +5274,12 @@ send_gamma (Avision_Scanner* s)  	    gamma_data [i] = gamma_data [t_i];  	}        } -       +        DBG (4, "send_gamma: sending %lu bytes gamma table.\n",  	   (u_long) gamma_table_raw_size);        status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  			    gamma_data, gamma_table_raw_size, 0, 0); -       +        if (status != SANE_STATUS_GOOD) {  	DBG (1, "send_gamma: gamma table upload failed: %s\n",  	     sane_strstatus (status)); @@ -5294,33 +5293,33 @@ static SANE_Status  send_3x3_matrix (Avision_Scanner* s)  {    SANE_Status status; -   +  #define SIGN_BIT 0x1000  #define INT_PART 10 -   +    struct matrix_cmd    {      struct command_send scmd;      struct matrix_3x3 matrix;    } cmd; -   -  /* 04 00  00 00  00 00  + +  /* 04 00  00 00  00 00       00 00  04 00  00 00       00 00  00 00  04 00 */ -   +    int i, a_i;    static const double c5_matrix[] =      { 1.000, 0.000, 0.000,        0.000, 1.000, 0.000,        0.000, 0.000, 1.000 }; -   +    double a_f, b_f;    uint16_t m; -   +    DBG (3, "send_3x3_matrix:\n"); -   +    memset (&cmd, 0, sizeof (cmd)); -   +    for (i = 0; i < 9; i++)      {        m = 0; @@ -5329,18 +5328,18 @@ send_3x3_matrix (Avision_Scanner* s)  	m |= SIGN_BIT;  	a_f = -a_f;        } -       +        a_i = (int) a_f; /* integer */        b_f = a_f - (double) a_i;  /* float */        m |= ((a_i & 0x3) << INT_PART);        m |= (uint16_t) (b_f * 1024);        set_double (((uint8_t*)(&cmd.matrix.v[i])), m);      } -   +    cmd.scmd.opc = AVISION_SCSI_SEND;    cmd.scmd.datatypecode = 0x83; /* 0x83 for 3x3 color matrix */    set_triple (cmd.scmd.transferlen, sizeof (struct matrix_3x3)); -   +    if (1) {      DBG (3, "send_3x3_matrix: sending matrix split into two commands\n");      status = avision_cmd (&s->av_con, &cmd.scmd, sizeof (cmd.scmd), @@ -5350,7 +5349,7 @@ send_3x3_matrix (Avision_Scanner* s)      DBG (3, "send_3x3_matrix: sending matrix in one command\n");      status = avision_cmd (&s->av_con, &cmd, sizeof (cmd), 0, 0, 0, 0);    } -   +    return status;  } @@ -5358,21 +5357,21 @@ static SANE_Status  get_acceleration_info (Avision_Scanner* s, struct acceleration_info* info)  {    SANE_Status status; -   +    struct command_read rcmd;    uint8_t result [24];    size_t size; -   +    DBG (3, "get_acceleration_info:\n");    size = sizeof (result); -   +    memset (&rcmd, 0, sizeof (rcmd));    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0x6c; /* get acceleration information */    set_double (rcmd.datatypequal, s->hw->data_dq);    set_triple (rcmd.transferlen, size); -   +    DBG (3, "get_acceleration_info: read_data: %lu bytes\n", (u_long) size);    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, result, &size);    if (status != SANE_STATUS_GOOD || size != sizeof (result) ) { @@ -5380,9 +5379,9 @@ get_acceleration_info (Avision_Scanner* s, struct acceleration_info* info)  	 sane_strstatus (status) );      return status;    } -   +    debug_print_accel_info (3, "get_acceleration_info", result); -   +    info->total_steps = get_double (&(result[0]));    info->stable_steps = get_double (&(result[2]));    info->table_units = get_quad (&(result[4])); @@ -5391,7 +5390,7 @@ get_acceleration_info (Avision_Scanner* s, struct acceleration_info* info)    info->target_speed = get_double (&(result[14]));    info->ability = result[16];    info->table_count = result[17]; -   +    return SANE_STATUS_GOOD;  } @@ -5399,45 +5398,45 @@ static SANE_Status  send_acceleration_table (Avision_Scanner* s)  {    SANE_Status status; -   +    struct command_send scmd;    int table = 0;    int i;    struct acceleration_info accel_info = accel_info;    uint8_t* table_data; -   +    DBG (3, "send_acceleration_table:\n");    do {      status = get_acceleration_info (s, &accel_info); -     +      if (accel_info.table_count == 0) {        DBG (3, "send_acceleration_table: device does not need tables\n");        return SANE_STATUS_GOOD;      } -     +      if (accel_info.target_speed > accel_info.start_speed ||          accel_info.target_speed == 0 ||          accel_info.total_steps <= accel_info.stable_steps) {        DBG (1, "send_acceleration_table: table does not look right.\n");        return SANE_STATUS_INVAL;      } -     +      if (accel_info.ability != 0) {        DBG (1, "send_acceleration_table: ability non-zero - insert code\n");        return SANE_STATUS_INVAL;      } -     +      /* so far I assume we have one byte tables as used in the C6 ASIC ... */      table_data = malloc (accel_info.total_steps + 1000); -     +      memset (&scmd, 0x00, sizeof (scmd));      scmd.opc = AVISION_SCSI_SEND;      scmd.datatypecode = 0x6c; /* send acceleration table */ -       +      set_double (scmd.datatypequal, table);      set_triple (scmd.transferlen, accel_info.total_steps); -     +      /* construct the table - Warning: This code is derived from Avision         sample code and is a bit scary! I have no idea why the scanner         needs such a dumb table and also do not know /why/ it has to be @@ -5447,16 +5446,16 @@ send_acceleration_table (Avision_Scanner* s)        float up_lim  = 1.0;        uint16_t accel_steps = accel_info.total_steps - accel_info.stable_steps + 1; -       +        /* acceleration ramp */        while ((up_lim - low_lim) > 0.0001)        {  	float mid = (up_lim + low_lim) / 2; /* accel rate */ -	 +  	uint16_t now_count = accel_info.start_speed; -	 +  	uint16_t i = 0; -	 +  	float now_count_f = now_count;  	table_data [i++] = (uint8_t) accel_info.start_speed; @@ -5467,8 +5466,8 @@ send_acceleration_table (Avision_Scanner* s)  	    now_count = (uint16_t)(now_count_f + 0.5);  	    table_data[i++] = (uint8_t) now_count;  	  } -	 -	 + +  	if (i == accel_steps)  	  break;  	if (i > accel_steps) @@ -5476,23 +5475,23 @@ send_acceleration_table (Avision_Scanner* s)  	else  	  up_lim = mid;        } -       +        /* fill stable steps */        for (i = accel_steps; i < accel_info.total_steps; i++)  	  table_data [i] = table_data [i-1]; -       +        debug_print_hex_raw (5, "send_acceleration_table: first pass:\n",  			   table_data, accel_info.total_steps); -       +        /* maybe post fix-up */        {  	int add_count; -	 +  	/* count total steps in table */  	int table_total = 0;  	for (i = 0; i < accel_info.total_steps; i++)  	  table_total += table_data [i]; -	 +  	i = 0;  	if (((table_total * accel_info.table_units) % accel_info.base_units) == 0)  	  add_count = 0; @@ -5500,7 +5499,7 @@ send_acceleration_table (Avision_Scanner* s)  	  add_count = (accel_info.base_units -  		       ((table_total*accel_info.table_units) % accel_info.base_units))  	    / accel_info.table_units; -	 +  	/* add_count should not be bigger than 255 */  	if (add_count > 255) {  	  DBG (1, "send_acceleration_table: add_count limited, was: %d\n", add_count); @@ -5510,26 +5509,26 @@ send_acceleration_table (Avision_Scanner* s)  	  {  	    uint16_t temp_count = 255 - table_data [i];  	    temp_count = temp_count > add_count ? add_count : temp_count; -	     +  	    table_data [i] += (uint8_t) temp_count;  	    add_count -= temp_count;  	  }        }      } -     +      debug_print_hex_raw (5, "send_acceleration_table: fixed up:\n",  			 table_data, accel_info.total_steps); -     +      /* decrease all by one ... */      for (i = 0; i < accel_info.total_steps; i++) {        table_data[i]--;      } -     +      DBG (1, "send_acceleration_table: sending table %d\n", table); -     +      debug_print_hex_raw (5, "send_acceleration_table: final:\n",  			 table_data, accel_info.total_steps); -     +      status = avision_cmd (&s->av_con, &scmd, sizeof (scmd),  			  (char*) table_data, accel_info.total_steps,  			  0, 0); @@ -5537,13 +5536,13 @@ send_acceleration_table (Avision_Scanner* s)        DBG (3, "send_acceleration_table: send_data failed (%s)\n",  	   sane_strstatus (status));      } -     +      free (table_data); table_data = 0; -     +      table++;    } while (table < accel_info.table_count); -   -   + +    return status;  } @@ -5555,17 +5554,17 @@ set_window (Avision_Scanner* s)    int base_dpi_abs, base_dpi_rel;    int transferlen;    int paralen; -   +    int bytes_per_line;    int line_count; -   +    struct {      struct command_set_window cmd;      struct command_set_window_window window;    } cmd; -   +    DBG (1, "set_window:\n"); -   +    /* plain old scanners, the C3 ASIC HP 53xx and the C6 ASIC HP 74xx       and up do use 1200 as base - only the C5 differs */    switch (dev->inquiry_asic_type) { @@ -5582,64 +5581,64 @@ set_window (Avision_Scanner* s)      base_dpi_abs = 1200;      base_dpi_rel = 1200;    } -   +    DBG (2, "set_window: base_dpi_abs: %d, base_dpi_rel: %d\n", base_dpi_abs, base_dpi_rel); -   +    /* wipe out anything */    memset (&cmd, 0, sizeof (cmd) );    cmd.window.descriptor.winid = AV_WINID; /* normally defined to be zero */ -   +    /* optional parameter length to use */    paralen = sizeof (cmd.window.avision) - sizeof (cmd.window.avision.type); -   +    DBG (2, "set_window: base paralen: %d\n", paralen); -   +    if (dev->hw->feature_type & AV_FUJITSU)      paralen += sizeof (cmd.window.avision.type.fujitsu);    else if (!dev->inquiry_new_protocol)      paralen += sizeof (cmd.window.avision.type.old);    else      paralen += sizeof (cmd.window.avision.type.normal); -   +    DBG (2, "set_window: final paralen: %d\n", paralen); -   +    transferlen = sizeof (cmd.window)      - sizeof (cmd.window.avision) + paralen; -   +    DBG (2, "set_window: transferlen: %d\n", transferlen); -   +    /* command setup */    cmd.cmd.opc = AVISION_SCSI_SET_WINDOW;    set_triple (cmd.cmd.transferlen, transferlen);    set_double (cmd.window.header.desclen,  	      sizeof (cmd.window.descriptor) + paralen); -   +    /* resolution parameters */    set_double (cmd.window.descriptor.xres, s->avdimen.hw_xres);    set_double (cmd.window.descriptor.yres, s->avdimen.hw_yres); -   +    /* upper left corner x/y as well as width/length in inch * base_dpi       - avdimen are world pixels */    set_quad (cmd.window.descriptor.ulx, s->avdimen.tlx * base_dpi_abs / s->avdimen.hw_xres);    set_quad (cmd.window.descriptor.uly, s->avdimen.tly * base_dpi_abs / s->avdimen.hw_yres); -   +    set_quad (cmd.window.descriptor.width,  	    s->avdimen.hw_pixels_per_line * base_dpi_rel / s->avdimen.hw_xres + 1);    line_count = s->avdimen.hw_lines + 2 * s->avdimen.line_difference + s->avdimen.rear_offset;    set_quad (cmd.window.descriptor.length,  	    line_count * base_dpi_rel / s->avdimen.hw_yres + 1); -   +    /* interlaced duplex scans are twice as long */    if (s->avdimen.interlaced_duplex && dev->scanner_type != AV_FILM) {      DBG (2, "set_window: interlaced duplex scan, doubled line count\n");      line_count *= 2;    } -   +    bytes_per_line = s->avdimen.hw_bytes_per_line; -   +    set_double (cmd.window.avision.line_width, bytes_per_line);    set_double (cmd.window.avision.line_count, line_count); -   +    /* here go the most significant bits if bigger than 16 bit */    if (dev->inquiry_new_protocol && !(dev->hw->feature_type & AV_FUJITSU) ) {      DBG (2, "set_window: large data-transfer support (>16bit)!\n"); @@ -5648,16 +5647,16 @@ set_window (Avision_Scanner* s)      cmd.window.avision.type.normal.line_count_msb =        line_count >> 16;    } -   +    if (dev->inquiry_background_raster)      cmd.window.avision.type.normal.background_lines = s->val[OPT_BACKGROUND].w; -   +    /* scanner should use our line-width and count */ -  SET_BIT (cmd.window.avision.bitset1, 6);  -   +  SET_BIT (cmd.window.avision.bitset1, 6); +    /* set speed */    cmd.window.avision.bitset1 |= s->val[OPT_SPEED].w & 0x07; /* only 3 bit */ -   +    /* ADF scan? */    DBG (3, "set_window: source mode %d source mode dim %d\n",         s->source_mode, s->source_mode_dim); @@ -5687,43 +5686,43 @@ set_window (Avision_Scanner* s)        SET_BIT(cmd.window.avision.type.normal.bitset3, 2); /* MIRR 0x04 */      }    } -   +    if (s->val[OPT_PAPERLEN].w != SANE_FALSE) {       set_double (cmd.window.descriptor.paper_length, (int)((double)30.0*1200));    }    if ( !(dev->hw->feature_type & AV_FUJITSU) ) -    {  +    {        /* quality scan option switch */        if (s->val[OPT_QSCAN].w == SANE_TRUE) {  	SET_BIT (cmd.window.avision.type.normal.bitset2, 4);        } -   +        /* quality calibration option switch (inverted! if set == speed) */        if (s->val[OPT_QCALIB].w == SANE_FALSE) {  	SET_BIT (cmd.window.avision.type.normal.bitset2, 3);        } -       +        /* transparency option switch */        if (s->source_mode_dim == AV_TRANSPARENT_DIM) {  	SET_BIT (cmd.window.avision.type.normal.bitset2, 7);        } -       +        if (dev->scanner_type == AV_FILM) {  	/* TODO: wire to IR exposure option? */  	cmd.window.avision.type.normal.ir_exposure_time = 100;  	set_double (cmd.window.avision.type.normal.r_exposure_time, s->val[OPT_EXPOSURE].w);  	set_double (cmd.window.avision.type.normal.g_exposure_time, s->val[OPT_EXPOSURE].w);  	set_double (cmd.window.avision.type.normal.b_exposure_time, s->val[OPT_EXPOSURE].w); -	 +  	if (s->val[OPT_IR].w)  	  cmd.window.avision.type.normal.bitset3 |= (1 << 0); -	 +  	if (s->val[OPT_MULTISAMPLE].w)  	  cmd.window.avision.type.normal.bitset3 |= (1 << 1);        }      } -   +    /* fixed values */    cmd.window.descriptor.padding_and_bitset = 3;    cmd.window.descriptor.vendor_specific = 0xFF; @@ -5732,7 +5731,7 @@ set_window (Avision_Scanner* s)    /* This is normally unsupported by Avision scanners, and we do this       via the gamma table - which works for all devices ... */    cmd.window.descriptor.threshold = 128; -  cmd.window.descriptor.brightness = 128;  +  cmd.window.descriptor.brightness = 128;    cmd.window.descriptor.contrast = 128;    cmd.window.avision.highlight = 0xFF;    cmd.window.avision.shadow = 0x00; @@ -5744,17 +5743,17 @@ set_window (Avision_Scanner* s)        cmd.window.descriptor.bpc = 1;        cmd.window.descriptor.image_comp = 0;        break; -     +      case AV_DITHERED:        cmd.window.descriptor.bpc = 1;        cmd.window.descriptor.image_comp = 1;        break; -       +      case AV_GRAYSCALE:        cmd.window.descriptor.bpc = 8;        cmd.window.descriptor.image_comp = 2;        break; -       +      case AV_GRAYSCALE12:        cmd.window.descriptor.bpc = 12;        cmd.window.descriptor.image_comp = 2; @@ -5764,7 +5763,7 @@ set_window (Avision_Scanner* s)        cmd.window.descriptor.bpc = 16;        cmd.window.descriptor.image_comp = 2;        break; -       +      case AV_TRUECOLOR:        cmd.window.descriptor.bpc = 8;        cmd.window.descriptor.image_comp = 5; @@ -5779,7 +5778,7 @@ set_window (Avision_Scanner* s)        cmd.window.descriptor.bpc = 16;        cmd.window.descriptor.image_comp = 5;        break; -       +      default:        DBG (1, "Invalid mode. %d\n", s->c_mode);        return SANE_STATUS_INVAL; @@ -5796,13 +5795,13 @@ set_window (Avision_Scanner* s)      else        cmd.window.avision.bitset1 |= AVISION_FILTER_NONE;    } -   +    debug_print_window_descriptor (5, "set_window", &(cmd.window)); -   +    DBG (3, "set_window: sending command. Bytes: %d\n", transferlen);    status = avision_cmd (&s->av_con, &cmd, sizeof (cmd.cmd),  			&(cmd.window), transferlen, 0, 0); -   +    return status;  } @@ -5813,13 +5812,13 @@ get_background_raster (Avision_Scanner* s)    Avision_Device* dev = s->hw;    SANE_Status status; -   +    struct command_read rcmd;    size_t size;    int bytes_per_line, i;    const int bpp = color_mode_is_color (s->c_mode) ? 3 : 1;    const int lines = s->val[OPT_BACKGROUND].w * (s->avdimen.interlaced_duplex ? 2 : 1); -   +    uint8_t* background = NULL;    DBG (1, "get_background_raster:\n"); @@ -5828,20 +5827,20 @@ get_background_raster (Avision_Scanner* s)      DBG (1, "get_background_raster: no background requested\n");      return SANE_STATUS_GOOD;    } -   +    /* full width, always :-(, duplex *2 for front and rear */    bytes_per_line = dev->inquiry_background_raster_pixel *      s->avdimen.hw_xres / dev->inquiry_optical_res;    bytes_per_line *= bpp; -   +    DBG (3, "get_background_raster: native raster pixels: %d, raster bytes_per_line: %d\n",         dev->inquiry_background_raster_pixel, bytes_per_line); -   +    /* according to spec only 8-bit gray or color, TODO: test for bi-level scans */    size = bytes_per_line * lines;    DBG (3, "get_background_raster: buffer size: %ld\n", (long)size); -   +    background = s->background_raster = realloc (s->background_raster, size);    if (!background)      return SANE_STATUS_NO_MEM; @@ -5850,13 +5849,13 @@ get_background_raster (Avision_Scanner* s)    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0x9b; /* get background raster */    set_double (rcmd.datatypequal, s->hw->data_dq); -   +    /* Ok, well - this part is very messy. The AV122 and DM152 appear to       contain differently buggy ASICs. The only combination I found to       at least get a correct front raster out of them is to read it       line by line and then every second line appears to be valid front       data, ... */ -   +    /* read the raster data */    for (i = 0; i < lines;)      { @@ -5864,7 +5863,7 @@ get_background_raster (Avision_Scanner* s)        /* read stripe by stripe, or all in one chunk */        size_t this_read, read_size;        int this_lines; -       +        if (dev->hw->feature_type & AV_2ND_LINE_INTERLACED) {  	if (dev->hw->feature_type & AV_BACKGROUND_QUIRK)  	  this_lines = 1; @@ -5875,12 +5874,12 @@ get_background_raster (Avision_Scanner* s)  	this_lines = s->val[OPT_BACKGROUND].w;        }        this_read = bytes_per_line * this_lines; -       +        DBG (3, "get_background_raster: line: %d, lines: %d, %lu bytes\n",  	   i, this_lines, (u_long) this_read);        set_triple (rcmd.transferlen, this_read); -       +        read_size = this_read;        status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, dst_raster, &read_size);        if (status != SANE_STATUS_GOOD || read_size != this_read) { @@ -5888,29 +5887,29 @@ get_background_raster (Avision_Scanner* s)  	     sane_strstatus (status) );  	return status;        } -       +        i += this_lines;      } -   +    /* dump raw result while debugging */    if (debug)      {        FILE* f = NULL;        f = fopen ("background-raw.pnm", "w"); -       +        write_pnm_header (f, (color_mode_is_color (s->c_mode) ? AV_TRUECOLOR : AV_GRAYSCALE), 8,  			bytes_per_line / bpp, lines); -       +        fwrite (background, 1, bytes_per_line * lines, f);        fclose (f);      }    /* line-pack - move to unified processing flow, later */    if (dev->inquiry_needs_line_pack) -    {  +    {        /* TODO: add 16bit per sample code? */        int l, p; -       +        uint8_t* tmp_data = malloc (bytes_per_line);        for (l = 0; l < lines; ++l)  	{ @@ -5918,47 +5917,47 @@ get_background_raster (Avision_Scanner* s)  	  uint8_t* r_ptr = background + (bytes_per_line * l);  	  uint8_t* g_ptr = r_ptr + bytes_per_line / bpp;  	  uint8_t* b_ptr = g_ptr + bytes_per_line / bpp; -	   +  	  for (p = 0; p < bytes_per_line;) {  	    out_data [p++] = *(r_ptr++);  	    out_data [p++] = *(g_ptr++);  	    out_data [p++] = *(b_ptr++);  	  } -	   +  	  memcpy (background + (bytes_per_line * l), tmp_data, bytes_per_line);  	} -       +        free (tmp_data);      } /* end line pack */ -   +    /* deinterlace? */    if (s->avdimen.interlaced_duplex && dev->hw->feature_type & AV_2ND_LINE_INTERLACED)      {        uint8_t* deinterlaced = malloc (size * 2);        if (!deinterlaced)  	return SANE_STATUS_NO_MEM; -       +        for (i = 0; i < lines; ++i)  	{  	  int dst_i = i / 2 + (i % 2) * (lines / 2);  	  uint8_t* dst_raster; /* just no C99 in SANE :-( */  	  uint8_t* src_raster; -	   +  	  /* for the quirky devices and some resolutions the interlacing differs */  	  if (dev->hw->feature_type & AV_BACKGROUND_QUIRK && s->avdimen.hw_xres >= 150)  	    dst_i = i / 2 + ((i+1) % 2) * (lines / 2); -	   +  	  dst_raster = deinterlaced + bytes_per_line * dst_i;  	  src_raster = background + bytes_per_line * i; -	   +  	  DBG(3, "get_background_raster: deinterlaced %d -> %d\n", i, dst_i);  	  memcpy(dst_raster, src_raster, bytes_per_line);  	} -       +        free (background);        background = s->background_raster = deinterlaced;      } -   +    /* dump raw result while debugging */    for (i = 0; debug && i < (s->avdimen.interlaced_duplex ? 2 : 1); ++i)      { @@ -5971,14 +5970,14 @@ get_background_raster (Avision_Scanner* s)        f = fopen ("background-rear.pnm", "w");        raster += bytes_per_line * s->val[OPT_BACKGROUND].w;      } -     +      write_pnm_header (f, (color_mode_is_color (s->c_mode) ? AV_TRUECOLOR : AV_GRAYSCALE), 8,  		      bytes_per_line / bpp, s->val[OPT_BACKGROUND].w); -	 +      fwrite (raster, 1, bytes_per_line * s->val[OPT_BACKGROUND].w, f);      fclose (f);    } -   +    /* crop from full-width scanlines to scan window */    {      uint8_t *dst_ptr, *src_ptr; @@ -5991,19 +5990,19 @@ get_background_raster (Avision_Scanner* s)  	src_ptr += bytes_per_line;        }    } -   +    /* soft-scale - move to unified processing flow, later */    if (s->avdimen.hw_xres != s->avdimen.xres)      {        const uint8_t* out_data = background;        uint8_t* dst = background; -       +        int l;        for (l = 0; l < lines; ++l)  	{  	  const int hwbpl = s->avdimen.hw_bytes_per_line;  	  const int sy = l; -	   +  	  int x;  	  for (x = 0; x < s->params.pixels_per_line; ++x)  	    { @@ -6011,24 +6010,24 @@ get_background_raster (Avision_Scanner* s)  	      const int sx = (int)floor(bx);  	      const int xdist = (int) ((bx - sx) * 256);  	      const int sxx = sx + 1; -	       +  	      switch (bpp) {  	      case 1:  		{ -		  uint8_t v =  +		  uint8_t v =  		    ( out_data [sy*hwbpl  + sx ] * (256-xdist) +  		      out_data [sy*hwbpl  + sxx] * xdist  		    ) / (256);  		  *dst++ = v;  		}  		break; -		 +  	      case 3:  		{  		  int c;  		  for (c = 0; c < 3; ++c)  		    { -		      uint8_t v =  +		      uint8_t v =  			( out_data [sy*hwbpl  + sx*3  + c] * (256-xdist) +  			  out_data [sy*hwbpl  + sxx*3 + c] * xdist  			  ) / (256); @@ -6040,7 +6039,7 @@ get_background_raster (Avision_Scanner* s)  	    }  	}      } -   +    /* dump final result while debugging */    if (debug) {      for (i = 0; i < (s->avdimen.interlaced_duplex ? 2 : 1); ++i) @@ -6054,15 +6053,15 @@ get_background_raster (Avision_Scanner* s)  	  f = fopen ("background-final-rear.pnm", "w");  	  raster += s->params.bytes_per_line * s->val[OPT_BACKGROUND].w;  	} -	 +  	write_pnm_header (f, (color_mode_is_color (s->c_mode) ? AV_TRUECOLOR : AV_GRAYSCALE), 8,  			  s->params.bytes_per_line / bpp, s->val[OPT_BACKGROUND].w); -	 +  	fwrite (raster, 1, s->params.bytes_per_line * s->val[OPT_BACKGROUND].w, f);  	fclose (f);        }    } -   +    return SANE_STATUS_GOOD;  } @@ -6072,9 +6071,9 @@ reserve_unit (Avision_Scanner* s)    char cmd[] =      {AVISION_SCSI_RESERVE_UNIT, 0, 0, 0, 0, 0};    SANE_Status status; -   +    DBG (1, "reserve_unit:\n"); -   +    status = avision_cmd (&s->av_con, cmd, sizeof (cmd), 0, 0, 0, 0);    return status;  } @@ -6085,7 +6084,7 @@ release_unit (Avision_Scanner* s, int type)    char cmd[] =      {AVISION_SCSI_RELEASE_UNIT, 0, 0, 0, 0, 0};    SANE_Status status; -   +    DBG (1, "release unit: type: %d\n", type);    cmd[5] = type; /* latest scanners also allow 1: release paper and 2: end job */    status = avision_cmd (&s->av_con, cmd, sizeof (cmd), 0, 0, 0, 0); @@ -6100,17 +6099,17 @@ media_check (Avision_Scanner* s)    SANE_Status status;    uint8_t result[1]; /* 4 */    size_t size = sizeof(result); -   +    status = avision_cmd (&s->av_con, cmd, sizeof (cmd),  			0, 0, result, &size); -   +    debug_print_raw (5, "media_check: result\n", result, size); -   +    if (status == SANE_STATUS_GOOD) {      if (!(result[0] & 0x1))        status = SANE_STATUS_NO_DOCS;    } -   +    return status;  } @@ -6120,7 +6119,7 @@ flush_media (Avision_Scanner* s)  {    Avision_Device* dev = s->hw;    SANE_Status status; -   +    if (s->source_mode_dim == AV_ADF_DIM && dev->inquiry_batch_scan)      {        DBG (1, "flush_media: flushing pages out of batch scanner\n"); @@ -6133,7 +6132,7 @@ flush_media (Avision_Scanner* s)  	  DBG (1, "flush_media: release status: %d\n", status2);  	}        } while (status == SANE_STATUS_GOOD); -    }  +    }    return SANE_STATUS_GOOD;  }  #endif /* 0 - unused */ @@ -6142,15 +6141,15 @@ static SANE_Status  object_position (Avision_Scanner* s, uint8_t position)  {    SANE_Status status; -   +    uint8_t cmd [10]; -   +    memset (cmd, 0, sizeof (cmd));    cmd[0] = AVISION_SCSI_OBJECT_POSITION;    cmd[1] = position; -   +    DBG (1, "object_position: %d\n", position); -   +    status = avision_cmd (&s->av_con, cmd, sizeof(cmd), 0, 0, 0, 0);    return status;  } @@ -6159,11 +6158,11 @@ static SANE_Status  start_scan (Avision_Scanner* s)  {    struct command_scan cmd; -   +    size_t size = sizeof (cmd); -   +    DBG (3, "start_scan:\n"); -   +    memset (&cmd, 0, sizeof (cmd));    cmd.opc = AVISION_SCSI_SCAN;    cmd.transferlen = 1; @@ -6176,7 +6175,7 @@ start_scan (Avision_Scanner* s)    if (s->val[OPT_QSCAN].w == SANE_TRUE) {      SET_BIT(cmd.bitset1,7);    } -   +    DBG (3, "start_scan: sending command. Bytes: %lu\n", (u_long) size);    return avision_cmd (&s->av_con, &cmd, size, 0, 0, 0, 0);  } @@ -6185,12 +6184,12 @@ static SANE_Status  do_eof (Avision_Scanner *s)  {    int exit_status; -   +    DBG (3, "do_eof:\n");    /* we do not scan anymore */    s->prepared = s->scanning = SANE_FALSE; -   +    /* we can now mark the rear data as valid */    if (s->avdimen.interlaced_duplex ||        (s->hw->hw->feature_type & AV_ADF_FLIPPING_DUPLEX && s->source_mode == AV_ADF_DUPLEX)) { @@ -6199,16 +6198,16 @@ do_eof (Avision_Scanner *s)      DBG (3, "do_eof: duplex rear data valid: %x\n",  	 s->duplex_rear_valid);    } -   +    if (s->read_fds >= 0) {      close (s->read_fds);      s->read_fds = -1;    } -   +    /* join our processes - without a wait() you will produce zombies       (defunct children) */    sanei_thread_waitpid (s->reader_pid, &exit_status); -  s->reader_pid = -1; +  sanei_thread_invalidate (s->reader_pid);    DBG (3, "do_eof: returning %d\n", exit_status);    return (SANE_Status)exit_status; @@ -6218,19 +6217,19 @@ static SANE_Status  do_cancel (Avision_Scanner* s)  {    DBG (3, "do_cancel:\n"); -   +    s->prepared = s->scanning = SANE_FALSE;    s->duplex_rear_valid = SANE_FALSE;    s->page = 0;    s->cancelled = 1; -   +    if (sanei_thread_is_valid (s->reader_pid)) {      int exit_status; -     +      /* ensure child knows it's time to stop: */      sanei_thread_kill (s->reader_pid);      sanei_thread_waitpid (s->reader_pid, &exit_status); -    s->reader_pid = -1; +    sanei_thread_invalidate (s->reader_pid);    }    return SANE_STATUS_CANCELLED; @@ -6243,16 +6242,16 @@ read_data (Avision_Scanner* s, SANE_Byte* buf, size_t* count)    SANE_Status status;    DBG (9, "read_data: %lu\n", (u_long) *count); -   +    memset (&rcmd, 0, sizeof (rcmd)); -   +    rcmd.opc = AVISION_SCSI_READ;    rcmd.datatypecode = 0x00; /* read image data */    set_double (rcmd.datatypequal, s->hw->data_dq);    set_triple (rcmd.transferlen, *count); -   +    status = avision_cmd (&s->av_con, &rcmd, sizeof (rcmd), 0, 0, buf, count); -   +    return status;  } @@ -6261,9 +6260,9 @@ init_options (Avision_Scanner* s)  {    Avision_Device* dev = s->hw;    int i; -   +    DBG (3, "init_options:\n"); -   +    memset (s->opt, 0, sizeof (s->opt));    memset (s->val, 0, sizeof (s->val)); @@ -6271,9 +6270,9 @@ init_options (Avision_Scanner* s)      s->opt[i].size = sizeof (SANE_Word);      s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;    } -   +    /* Init the SANE option from the scanner inquiry data */ -   +    switch (dev->inquiry_asic_type) {      case AV_ASIC_C2:        dev->dpi_range.min = 100; @@ -6294,11 +6293,11 @@ init_options (Avision_Scanner* s)    dev->dpi_range.quant = 1; /* any, including 72, 144, etc. */    dev->dpi_range.max = dev->inquiry_max_res; -   +    dev->speed_range.min = (SANE_Int)0;    dev->speed_range.max = (SANE_Int)4;    dev->speed_range.quant = (SANE_Int)1; -   +    s->opt[OPT_NUM_OPTS].name = "";    s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;    s->opt[OPT_NUM_OPTS].desc = ""; @@ -6306,7 +6305,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;    s->opt[OPT_NUM_OPTS].size = sizeof(SANE_TYPE_INT);    s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; -   +    /* "Mode" group: */    s->opt[OPT_MODE_GROUP].title = SANE_TITLE_SCAN_MODE;    s->opt[OPT_MODE_GROUP].desc = ""; /* for groups only title and type are valid */ @@ -6314,7 +6313,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_MODE_GROUP].cap = 0;    s->opt[OPT_MODE_GROUP].size = 0;    s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; -   +    /* color mode */    s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;    s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; @@ -6325,7 +6324,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_MODE].constraint.string_list = dev->color_list;    s->val[OPT_MODE].s = strdup (dev->color_list[dev->color_list_default]);    s->c_mode = match_color_mode (dev, s->val[OPT_MODE].s); -   +    /* source mode */    s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;    s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE; @@ -6366,7 +6365,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_SPEED].desc  = SANE_DESC_SCAN_SPEED;    s->opt[OPT_SPEED].type  = SANE_TYPE_INT;    s->opt[OPT_SPEED].constraint_type  = SANE_CONSTRAINT_RANGE; -  s->opt[OPT_SPEED].constraint.range = &dev->speed_range;  +  s->opt[OPT_SPEED].constraint.range = &dev->speed_range;    s->val[OPT_SPEED].w = 0;    if (dev->scanner_type == AV_SHEETFEED)      s->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE; @@ -6418,7 +6417,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_BR_Y].constraint.range = &dev->y_range;    s->val[OPT_BR_Y].w = dev->y_range.max; -   +    /* overscan top */    s->opt[OPT_OVERSCAN_TOP].name = "overscan-top";    s->opt[OPT_OVERSCAN_TOP].title = "Overscan top"; @@ -6428,7 +6427,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_OVERSCAN_TOP].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_OVERSCAN_TOP].constraint.range = &overscan_range;    s->val[OPT_OVERSCAN_TOP].w = SANE_FIX(0); -   +    /* overscan bottom */    s->opt[OPT_OVERSCAN_BOTTOM].name = "overscan-bottom";    s->opt[OPT_OVERSCAN_BOTTOM].title = "Overscan bottom"; @@ -6438,12 +6437,12 @@ init_options (Avision_Scanner* s)    s->opt[OPT_OVERSCAN_BOTTOM].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_OVERSCAN_BOTTOM].constraint.range = &overscan_range;    s->val[OPT_OVERSCAN_BOTTOM].w = SANE_FIX(0); -   +    if (!dev->inquiry_tune_scan_length)      s->opt[OPT_OVERSCAN_TOP].cap |= SANE_CAP_INACTIVE;    if (!dev->inquiry_tune_scan_length)      s->opt[OPT_OVERSCAN_BOTTOM].cap |= SANE_CAP_INACTIVE; -   +    /* background raster */    s->opt[OPT_BACKGROUND].name = "background-lines";    s->opt[OPT_BACKGROUND].title = "Background raster lines"; @@ -6453,11 +6452,11 @@ init_options (Avision_Scanner* s)    s->opt[OPT_BACKGROUND].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_BACKGROUND].constraint.range = &background_range;    s->val[OPT_BACKGROUND].w = 0; -   +    if (!dev->inquiry_background_raster) {      s->opt[OPT_BACKGROUND].cap |= SANE_CAP_INACTIVE;    } -   +    /* "Enhancement" group: */    s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";    s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; /* for groups only title and type are valid */ @@ -6553,7 +6552,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;    s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0]; -  +    if (!disable_gamma_table)    {      if (color_mode_is_color (s->c_mode)) { @@ -6565,7 +6564,7 @@ init_options (Avision_Scanner* s)        s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;      }    } -   +    /* exposure */    s->opt[OPT_EXPOSURE].name = "exposure";    s->opt[OPT_EXPOSURE].title = "Exposure"; @@ -6575,7 +6574,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_EXPOSURE].constraint_type = SANE_CONSTRAINT_RANGE;    s->opt[OPT_EXPOSURE].constraint.range = &exposure_range;    s->val[OPT_EXPOSURE].w = 100; -   +    if (!dev->inquiry_exposure_control) {      s->opt[OPT_EXPOSURE].cap |= SANE_CAP_INACTIVE;    } @@ -6587,7 +6586,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_MULTISAMPLE].type  = SANE_TYPE_BOOL;    s->opt[OPT_MULTISAMPLE].unit  = SANE_UNIT_NONE;    s->val[OPT_MULTISAMPLE].w     = SANE_FALSE; -   +    /* TODO: No idea how to detect, assume exposure control devices are       new enough to support this, for now. -ReneR */    if (!dev->inquiry_exposure_control) { @@ -6601,13 +6600,13 @@ init_options (Avision_Scanner* s)    s->opt[OPT_IR].type  = SANE_TYPE_BOOL;    s->opt[OPT_IR].unit  = SANE_UNIT_NONE;    s->val[OPT_IR].w     = SANE_FALSE; -   +    /* TODO: No idea how to detect, assume exposure control devices are       new enough to support this, for now. -ReneR */    if (!dev->inquiry_exposure_control) {      s->opt[OPT_IR].cap |= SANE_CAP_INACTIVE;    } -   +    /* "MISC" group: */    s->opt[OPT_MISC_GROUP].title = SANE_TITLE_SCAN_MODE;    s->opt[OPT_MISC_GROUP].desc = ""; /* for groups only title and type are valid */ @@ -6615,7 +6614,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_MISC_GROUP].cap = 0;    s->opt[OPT_MISC_GROUP].size = 0;    s->opt[OPT_MISC_GROUP].constraint_type = SANE_CONSTRAINT_NONE; -   +    /* film holder control */    if (dev->scanner_type != AV_FILM)      s->opt[OPT_FRAME].cap |= SANE_CAP_INACTIVE; @@ -6649,7 +6648,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_MESSAGE].constraint_type = SANE_CONSTRAINT_NONE;    s->val[OPT_MESSAGE].s = malloc(s->opt[OPT_MESSAGE].size);    s->val[OPT_MESSAGE].s[0] = 0; -   +    /* NVRAM */    s->opt[OPT_NVRAM].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;    if (!dev->inquiry_nvram_read) @@ -6663,7 +6662,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_NVRAM].constraint_type = SANE_CONSTRAINT_NONE;    s->val[OPT_NVRAM].s = malloc(s->opt[OPT_NVRAM].size);    s->val[OPT_NVRAM].s[0] = 0; -   +    /* paper_length */    s->opt[OPT_PAPERLEN].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;    if (!dev->inquiry_paper_length) @@ -6676,7 +6675,7 @@ init_options (Avision_Scanner* s)    s->opt[OPT_PAPERLEN].size = sizeof(SANE_Word);    s->opt[OPT_PAPERLEN].constraint_type = SANE_CONSTRAINT_NONE;    s->val[OPT_PAPERLEN].w     = SANE_FALSE; -   +    /* ADF page flipping */    s->opt[OPT_ADF_FLIP].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC | SANE_CAP_ADVANCED;    if (!(s->hw->hw->feature_type & AV_ADF_FLIPPING_DUPLEX && s->source_mode == AV_ADF_DUPLEX)) @@ -6711,24 +6710,24 @@ reader_process (void *data)    int fd = s->write_fds;    Avision_Device* dev = s->hw; -   +    SANE_Status status;    SANE_Status exit_status = SANE_STATUS_GOOD;    sigset_t sigterm_set;    sigset_t ignore_set;    struct SIGACTION act; -   +    FILE* fp;    FILE* rear_fp = 0; /* used to store the deinterlaced rear data */    FILE* raw_fp = 0; /* used to write the RAW image data for debugging */ -   +    /* the complex params */    unsigned int lines_per_stripe;    unsigned int lines_per_output;    unsigned int max_bytes_per_read; -   +    SANE_Bool gray_mode; -   +    /* the simple params for the data reader */    int hw_line = 0;    int line = 0; @@ -6736,17 +6735,17 @@ reader_process (void *data)    unsigned int stripe_size;    unsigned int stripe_fill;    unsigned int out_size; -   +    size_t total_size;    size_t processed_bytes; -   +    enum {      NONE,   /* do not de-interlace at all */      STRIPE, /* every 2nd stripe */      HALF,   /* the 2nd half */      LINE    /* every 2nd line */    } deinterlace = NONE; -   +    /* the fat strip we currently puzzle together to perform software-colorpack       and more */    uint8_t* stripe_data; @@ -6755,44 +6754,44 @@ reader_process (void *data)    /* interpolation output data, one line */    uint8_t* ip_history = 0;    uint8_t* ip_data = 0; -   +    DBG (3, "reader_process:\n"); -   +    if (sanei_thread_is_forked())      close (s->read_fds); -   +    sigfillset (&ignore_set);    sigdelset (&ignore_set, SIGTERM);  #if defined (__APPLE__) && defined (__MACH__)    sigdelset (&ignore_set, SIGUSR2);  #endif    sigprocmask (SIG_SETMASK, &ignore_set, 0); -   +    memset (&act, 0, sizeof (act));    sigaction (SIGTERM, &act, 0); -   +    sigemptyset (&sigterm_set);    sigaddset (&sigterm_set, SIGTERM); -   +    gray_mode = color_mode_is_shaded (s->c_mode);    if (s->avdimen.interlaced_duplex) {      deinterlace = STRIPE; -     +      if ( (dev->hw->feature_type & AV_NON_INTERLACED_DUPLEX_300) &&  	 (s->avdimen.hw_xres <= 300 && s->avdimen.hw_yres <= 300) )        deinterlace = HALF;      if (dev->hw->feature_type & AV_2ND_LINE_INTERLACED)        deinterlace = LINE; -     +      if (dev->scanner_type == AV_FILM)        deinterlace = LINE;    } -   +    fp = fdopen (fd, "w");    if (!fp)      return SANE_STATUS_NO_MEM; -   +    /* start scan ? */    if ((deinterlace == NONE && !((dev->hw->feature_type & AV_ADF_FLIPPING_DUPLEX) && s->source_mode == AV_ADF_DUPLEX && s->duplex_rear_valid)) ||        (deinterlace != NONE && !s->duplex_rear_valid)) @@ -6806,7 +6805,7 @@ reader_process (void *data)  	     sane_strstatus (status));  	return status;        } -   +        if (dev->hw->feature_type & AV_NO_START_SCAN) {  	DBG (1, "reader_process: start_scan skipped due to device-list!\n");        } @@ -6818,7 +6817,7 @@ reader_process (void *data)  	  return status;  	}        } -       +        if (dev->hw->feature_type & AV_ACCEL_TABLE)       /*  (s->hw->inquiry_asic_type == AV_ASIC_C6) */ {  	status = send_acceleration_table (s); @@ -6829,7 +6828,7 @@ reader_process (void *data)  	}        }      } -   +    /* setup file i/o for deinterlacing scans or if we are the back page with a flipping duplexer */    if (deinterlace != NONE ||       (dev->hw->feature_type & AV_ADF_FLIPPING_DUPLEX && s->source_mode == AV_ADF_DUPLEX && !(s->page % 2))) @@ -6851,38 +6850,38 @@ reader_process (void *data)  	}        }      } -   +    /* it takes quite a few lines to saturate the (USB) bus */    lines_per_stripe = dev->read_stripe_size;    if (s->avdimen.line_difference)      lines_per_stripe += 2 * s->avdimen.line_difference; -   +    stripe_size = s->avdimen.hw_bytes_per_line * lines_per_stripe;    lines_per_output = lines_per_stripe - 2 * s->avdimen.line_difference; -   +    if (s->av_con.connection_type == AV_SCSI)      /* maybe better not /2 ... */      max_bytes_per_read = dev->scsi_buffer_size / 2; -  else  +  else      /* vast buffer size to saturate the bus */      max_bytes_per_read = 0x100000; -   +    out_size = s->avdimen.hw_bytes_per_line * lines_per_output; -   +    DBG (3, "dev->scsi_buffer_size / 2: %d\n",         dev->scsi_buffer_size / 2); -   +    DBG (3, "bytes_per_line: %d, pixels_per_line: %d\n",         s->avdimen.hw_bytes_per_line, s->avdimen.hw_pixels_per_line); -   +    DBG (3, "lines_per_stripe: %d, lines_per_output: %d\n",         lines_per_stripe, lines_per_output); -   +    DBG (3, "max_bytes_per_read: %d, stripe_size: %d, out_size: %d\n",         max_bytes_per_read, stripe_size, out_size); -   +    stripe_data = malloc (stripe_size); -   +    /* for software scaling we need an additional interpolation line buffer */    if (s->avdimen.hw_xres != s->avdimen.xres ||        s->avdimen.hw_yres != s->avdimen.yres) @@ -6890,13 +6889,13 @@ reader_process (void *data)      /* layout out_data so that the interpolation history is exactly in front */      ip_history = malloc (s->avdimen.hw_bytes_per_line + out_size);      out_data = ip_history + s->avdimen.hw_bytes_per_line; -  +      ip_data = malloc (s->params.bytes_per_line);    }    else {      out_data = malloc (out_size);    } -   +    /* calculate params for the reading loop */    total_size = s->avdimen.hw_bytes_per_line * (s->avdimen.hw_lines +  					       2 * s->avdimen.line_difference + @@ -6904,7 +6903,7 @@ reader_process (void *data)    if (deinterlace != NONE && !s->duplex_rear_valid)      total_size *= 2;    DBG (3, "reader_process: total_size: %lu\n", (u_long) total_size); -   +    /* write a RAW PNM file for debugging -ReneR */    if (0 /* DEBUG */ &&        (deinterlace == NONE || (deinterlace != NONE && !s->duplex_rear_valid)) ) @@ -6913,36 +6912,36 @@ reader_process (void *data)        write_pnm_header (fp, s->c_mode, s->params.depth,  			s->avdimen.hw_pixels_per_line, total_size / s->avdimen.hw_bytes_per_line);      } -   +    processed_bytes = 0;    stripe_fill = 0; -   +    /* First, dump background raster, bypassing all the other processing. */    if (dev->inquiry_background_raster && s->val[OPT_BACKGROUND].w)      {        uint8_t* background = s->background_raster;        if (s->duplex_rear_valid)  	background += s->params.bytes_per_line * s->val[OPT_BACKGROUND].w; -       +        DBG (5, "reader_process: dumping background raster\n");        fwrite (background, s->params.bytes_per_line, s->val[OPT_BACKGROUND].w, fp);      } -   +    /* Data read; loop until all data has been processed.  Might exit       before all lines are transferred for ADF paper end. */    while (exit_status == SANE_STATUS_GOOD && processed_bytes < total_size)      {        unsigned int useful_bytes; -       +        DBG (5, "reader_process: stripe filled: %d\n", stripe_fill); -       +        /* fill the stripe buffer with real data */        while (!s->duplex_rear_valid &&  	     processed_bytes < total_size && stripe_fill < stripe_size &&               exit_status  == SANE_STATUS_GOOD)  	{  	  size_t this_read = stripe_size - stripe_fill; -	   +  	  /* Limit reads to max_bytes_per_read and global data  	     boundaries. Rounded to the next lower multiple of  	     byte_per_lines, otherwise some scanners freeze. */ @@ -6962,7 +6961,7 @@ reader_process (void *data)  	  sigprocmask (SIG_BLOCK, &sigterm_set, 0);  	  status = read_data (s, stripe_data + stripe_fill, &this_read);  	  sigprocmask (SIG_UNBLOCK, &sigterm_set, 0); -	   +  	  /* only EOF on the second stripe, as otherwise the rear page  	     is shorter */  	  if (status == SANE_STATUS_EOF && deinterlace == STRIPE) { @@ -6977,59 +6976,59 @@ reader_process (void *data)  	      }  	    }  	  } -	   +  	  /* write RAW data to file for debugging */  	  if (raw_fp && this_read > 0)  	    fwrite (stripe_data + stripe_fill, this_read, 1, raw_fp); -	   +  	  if (status == SANE_STATUS_EOF || this_read == 0) {  	    DBG (1, "reader_process: read_data failed due to EOF\n");  	    exit_status = SANE_STATUS_EOF;  	  } -	   +  	  if (status != SANE_STATUS_GOOD) {  	    DBG (1, "reader_process: read_data failed with status: %d\n",  		 status);  	    exit_status = status;  	  } -           +  	  stripe_fill += this_read;  	  processed_bytes += this_read;  	} -       +        /* fill the stripe buffer with stored, virtual data */        if (s->duplex_rear_valid)  	{  	  size_t this_read = stripe_size - stripe_fill;  	  size_t got; -	   +  	  /* limit reads to max_read and global data boundaries */  	  if (this_read > max_bytes_per_read)  	    this_read = max_bytes_per_read; -	   +  	  if (processed_bytes + this_read > total_size)  	    this_read = total_size - processed_bytes; -	   +  	  DBG (5, "reader_process: virtual processed_bytes: %lu, total_size: %lu\n",  	       (u_long) processed_bytes, (u_long) total_size);  	  DBG (5, "reader_process: virtual this_read: %lu\n", (u_long) this_read); -	   +  	  got = fread (stripe_data + stripe_fill, 1, this_read, rear_fp);  	  stripe_fill += got;  	  processed_bytes += got;  	  if (got != this_read)  	    exit_status = SANE_STATUS_EOF;  	} -       +        DBG (5, "reader_process: stripe filled: %d\n", stripe_fill); -       +        useful_bytes = stripe_fill;        if (color_mode_is_color (s->c_mode))  	useful_bytes -= 2 * s->avdimen.line_difference * s->avdimen.hw_bytes_per_line; -       +        DBG (3, "reader_process: useful_bytes %i\n", useful_bytes); -       +        /* Deinterlace, save the rear stripes. For some scanners (AV220)  	 that is every 2nd stripe, the 2nd half of the transferred  	 data ((AV83xx), or every 2nd line (AV122)). */ @@ -7078,12 +7077,12 @@ reader_process (void *data)  	DBG (9, "reader_process: after page flip: useful_bytes: %d, stripe_fill: %d\n",  	       useful_bytes, stripe_fill);        } else { -       +        /*         * Perform needed data conversions (packing, ...) and/or copy the         * image data.         */ -       +        if (s->c_mode != AV_TRUECOLOR && s->c_mode != AV_TRUECOLOR16)  	/* simple copy */  	{ @@ -7098,11 +7097,11 @@ reader_process (void *data)  	      /* TODO: add 16bit per sample code? */  	      unsigned int i;  	      int c_offset = s->avdimen.line_difference * s->avdimen.hw_bytes_per_line; -	       +  	      uint8_t* r_ptr = stripe_data;  	      uint8_t* g_ptr = stripe_data + c_offset + 1;  	      uint8_t* b_ptr = stripe_data + 2 * c_offset + 2; -	       +  	      for (i = 0; i < useful_bytes;) {  		out_data [i++] = *r_ptr; r_ptr += 3;  		out_data [i++] = *g_ptr; g_ptr += 3; @@ -7110,17 +7109,17 @@ reader_process (void *data)  	      }  	    } /* end color pack */  	  else if (dev->inquiry_needs_line_pack) /* line-pack */ -	    {  +	    {  	      /* TODO: add 16bit per sample code? */  	      int i = 0, l, p;  	      const int lines = useful_bytes / s->avdimen.hw_bytes_per_line; -	       +  	      for (l = 0; l < lines; ++l)  		{  		  uint8_t* r_ptr = stripe_data + (s->avdimen.hw_bytes_per_line * l);  		  uint8_t* g_ptr = r_ptr + s->avdimen.hw_pixels_per_line;  		  uint8_t* b_ptr = g_ptr + s->avdimen.hw_pixels_per_line; -		   +  		  for (p = 0; p < s->avdimen.hw_pixels_per_line; ++p) {  		    out_data [i++] = *(r_ptr++);  		    out_data [i++] = *(g_ptr++); @@ -7129,13 +7128,13 @@ reader_process (void *data)  		}  	    } /* end line pack */  	  else /* else no packing was required -> simple copy */ -	    {  +	    {  	      memcpy (out_data, stripe_data, useful_bytes);  	    }  	} /* end if AV_TRUECOLOR* */ -       +        /* FURTHER POST-PROCESSING ON THE FINAL OUTPUT DATA */ -       +        /* maybe mirroring in ADF mode */        if (s->source_mode_dim == AV_ADF_DIM && dev->inquiry_adf_need_mirror)          { @@ -7152,7 +7151,7 @@ reader_process (void *data)  	      {  		uint8_t* begin_ptr = out_data + (l * s->avdimen.hw_bytes_per_line);  		uint8_t* end_ptr = begin_ptr + s->avdimen.hw_bytes_per_line; -		 +  		while (begin_ptr < end_ptr) {  		  uint8_t tmp;  		  tmp = *begin_ptr; @@ -7164,7 +7163,7 @@ reader_process (void *data)  	else /* non trivial mirroring */  	  {  	    /* Non-trivial Mirroring with element swapping */ -	     +  	    int l;  	    int lines = useful_bytes / s->avdimen.hw_bytes_per_line; @@ -7172,25 +7171,25 @@ reader_process (void *data)  	      {  		uint8_t* begin_ptr = out_data + (l * s->avdimen.hw_bytes_per_line);  		uint8_t* end_ptr = begin_ptr + s->avdimen.hw_bytes_per_line - 3; -		 +  		while (begin_ptr < end_ptr) {  		  uint8_t tmp; -		   +  		  /* R */  		  tmp = *begin_ptr;  		  *begin_ptr++ = *end_ptr;  		  *end_ptr++ = tmp; -		   +  		  /* G */  		  tmp = *begin_ptr;  		  *begin_ptr++ = *end_ptr;  		  *end_ptr++ = tmp; -		   +  		  /* B */  		  tmp = *begin_ptr;  		  *begin_ptr++ = *end_ptr;  		  *end_ptr = tmp; -		   +  		  end_ptr -= 5;  		}  	      } @@ -7202,13 +7201,13 @@ reader_process (void *data)            s->c_mode == AV_GRAYSCALE16 ||            s->c_mode == AV_TRUECOLOR12 ||            s->c_mode == AV_TRUECOLOR16) { -	 +  	int l;  	int lines = useful_bytes / s->avdimen.hw_bytes_per_line;  	uint8_t* dark_avg_data = s->dark_avg_data;  	uint8_t* white_avg_data = s->white_avg_data; -	 +  	uint8_t* begin_ptr = out_data;  	uint8_t* end_ptr = begin_ptr + s->avdimen.hw_bytes_per_line;  	uint8_t* line_ptr; @@ -7216,16 +7215,16 @@ reader_process (void *data)          double scale = 1.0;          if (s->c_mode == AV_GRAYSCALE12 || s->c_mode == AV_TRUECOLOR12)            scale = (double) (1<<4); -	 +  	while (begin_ptr < end_ptr) {  	  uint16_t dark_avg = 0;  	  uint16_t white_avg = WHITE_MAP_RANGE; -	   +  	  if (dark_avg_data)  	    dark_avg = get_double_le (dark_avg_data);  	  if (white_avg_data)  	    white_avg = get_double_le (white_avg_data); -	   +  	  line_ptr = begin_ptr;  	  for (l = 0; l < lines; ++ l)  	    { @@ -7233,16 +7232,16 @@ reader_process (void *data)  	      uint16_t v2;  	      if (0)  		v = (v - dark_avg) * white_avg / WHITE_MAP_RANGE; -	       +  	      v2 = v < 0xFFFF ? v : 0xFFFF; -	       +  	      /* SANE Standard 3.2.1 "... bytes of each sample value are  		 transmitted in the machine's native byte order." */  	      *line_ptr = v2; -	       +  	      line_ptr += s->avdimen.hw_bytes_per_line;  	    } -	   +  	  begin_ptr += 2;  	  if (dark_avg_data)  	    dark_avg_data += 2; @@ -7250,9 +7249,9 @@ reader_process (void *data)  	    white_avg_data += 2;  	}        } -       +        /* SOFTWARE SCALING WITH INTERPOLATION (IF NECESSARY) */ -       +        if (s->avdimen.hw_xres == s->avdimen.xres &&  	  s->avdimen.hw_yres == s->avdimen.yres) /* No scaling */  	{ @@ -7280,22 +7279,22 @@ reader_process (void *data)  	  int x;  	  /* for convenience in the 16bit code path */  	  uint16_t* out_data16 = (uint16_t*) out_data; -	   +  	  const int hw_line_end = hw_line + useful_bytes / s->avdimen.hw_bytes_per_line; -	   +  	  /* on-the-fly bi-linear interpolation */  	  while (1) {  	    double by = (-1.0 + s->avdimen.hw_lines) * line / (s->avdimen.hw_lines * s->avdimen.xres / s->avdimen.hw_xres + s->val[OPT_BACKGROUND].w);  	    int sy = (int)floor(by);  	    int ydist = (int) ((by - sy) * 256);  	    int syy = sy + 1; -	     +  	    const int hwbpl = s->avdimen.hw_bytes_per_line; -	     +  	    uint8_t* dst = ip_data;  	    uint16_t* dst16 = (uint16_t*) ip_data;  	    unsigned int v; /* accumulator */ -	     +  	    /* Break out if we do not have the hw source line - yet,  	       or when we are past the end of wanted data (e.g. on the  	       front page due to rear_offset). Also take the read_offset @@ -7312,35 +7311,35 @@ reader_process (void *data)  		syy += s->avdimen.rear_offset;  	      }  	    } -	     +  	    if (sy >= hw_line_end || syy >= hw_line_end) {  	      DBG (3, "reader_process: source line %d-%d not yet avail\n",  		   sy, syy);  	      break;  	    } -	     +  	    /* convert to offset in current stripe */  	    sy -= hw_line;  	    syy -= hw_line; -	     +  	    if (sy < -1) {  	      DBG (1, "reader_process: need more history: %d???\n", sy);  	      sy = -1;  	    } -	     +  	    DBG (8, "reader_process: out line: %d <- from: %d-%d\n",  		 line, sy, syy); -	     +  	    for (x = 0; x < s->params.pixels_per_line; ++x) {  	      const double bx = (-1.0 + s->avdimen.hw_pixels_per_line) * x / s->params.pixels_per_line;  	      const int sx = (int)floor(bx);  	      const int xdist = (int) ((bx - sx) * 256);  	      const int sxx = sx + 1; -	       +  	      if (x == 0 || x == s->params.pixels_per_line - 1)  		 DBG (8, "reader_process: x: %d <- from: %d-%d\n",  		      x, sx, sxx); -	       +  	      switch (s->c_mode) {  	      case AV_THRESHOLDED:  	      case AV_DITHERED: @@ -7348,13 +7347,13 @@ reader_process (void *data)  		  /* Repeating this over and over again is not fast, but  		     as a seldom used code-path we want it readable.  		     x/8 is the byte, and x%8 the bit position. */ -		  v =  +		  v =  		    ( ((out_data [sy*hwbpl  + sx/8 ] >> (7-sx%8 )) & 1) * (256-xdist) * (256-ydist) +  		      ((out_data [sy*hwbpl  + sxx/8] >> (7-sxx%8)) & 1) * xdist       * (256-ydist) +  		      ((out_data [syy*hwbpl + sx/8 ] >> (7-sx%8 )) & 1) * (256-xdist) * ydist +  		      ((out_data [syy*hwbpl + sxx/8] >> (7-sxx%8)) & 1) * xdist       * ydist  		      ) / (1 + 1 * 256); -		   +  		  /* Shift and or the result together and eventually  		     jump to the next byte. */  		  *dst = (*dst << 1) | ((v>>7)&1); @@ -7362,10 +7361,10 @@ reader_process (void *data)  		     ++dst;  		}  		break; -		 +  	      case AV_GRAYSCALE:  		{ -		  v =  +		  v =  		    ( out_data [sy*hwbpl  + sx ] * (256-xdist) * (256-ydist) +  		      out_data [sy*hwbpl  + sxx] * xdist       * (256-ydist) +  		      out_data [syy*hwbpl + sx ] * (256-xdist) * ydist + @@ -7374,12 +7373,12 @@ reader_process (void *data)  		  *dst++ = v;  		}  		break; -		 +  	      case AV_GRAYSCALE12:  	      case AV_GRAYSCALE16:  		{ -		  /* TODO: test! */		   -		  v =  +		  /* TODO: test! */ +		  v =  		    ( out_data16 [sy*hwbpl  + sx ] * (256-xdist) * (256-ydist) +  		      out_data16 [sy*hwbpl  + sxx] * xdist       * (256-ydist) +  		      out_data16 [syy*hwbpl + sx ] * (256-xdist) * ydist + @@ -7388,13 +7387,13 @@ reader_process (void *data)  		  *dst16++ = v;  		}  		break; -		 +  	      case AV_TRUECOLOR:  		{  		  int c;  		  for (c = 0; c < 3; ++c)  		    { -		      v =  +		      v =  			( out_data [sy*hwbpl  + sx*3  + c] * (256-xdist) * (256-ydist) +  			  out_data [sy*hwbpl  + sxx*3 + c] * xdist       * (256-ydist) +  			  out_data [syy*hwbpl + sx*3  + c] * (256-xdist) * ydist + @@ -7404,7 +7403,7 @@ reader_process (void *data)  		    }  		}  		break; -		 +  	      case AV_TRUECOLOR12:  	      case AV_TRUECOLOR16:  		{ @@ -7412,7 +7411,7 @@ reader_process (void *data)  		  int c;  		  for (c = 0; c < 3; ++c)  		    { -		      v =  +		      v =  			( out_data16 [sy*hwbpl  + sx*3  + c] * (256-xdist) * (256-ydist) +  			  out_data16 [sy*hwbpl  + sxx*3 + c] * xdist       * (256-ydist) +  			  out_data16 [syy*hwbpl + sx*3  + c] * (256-xdist) * ydist + @@ -7422,7 +7421,7 @@ reader_process (void *data)  		    }  		}  		break; -		 +  	      case AV_COLOR_MODE_LAST:  		; /* silence compiler warning */  	      } @@ -7436,29 +7435,29 @@ reader_process (void *data)  		  s->avdimen.hw_bytes_per_line);  	}        } -       +        /* save image date in stripe buffer for next next stripe */        stripe_fill -= useful_bytes;        if (stripe_fill > 0)  	memcpy (stripe_data, stripe_data + useful_bytes, stripe_fill); -       +        hw_line += useful_bytes / s->avdimen.hw_bytes_per_line; -       +        DBG (3, "reader_process: end of iteration\n");      } /* end while not all lines or inf. mode */ -   +    DBG (3, "reader_process: i/o loop finished\n");    if (exit_status == SANE_STATUS_GOOD)      exit_status = SANE_STATUS_EOF; -   +    if (raw_fp)      fclose (raw_fp); -   +    /* maybe we need to fill in some white data */    if (exit_status == SANE_STATUS_EOF && line < s->params.lines) {      DBG (3, "reader_process: padding with white data\n");      memset (out_data, gray_mode ? 0xff : 0x00, s->params.bytes_per_line); -     +      DBG (6, "reader_process: padding line %d - %d\n",  	 line, s->params.lines);      while (line < s->params.lines) { @@ -7466,7 +7465,7 @@ reader_process (void *data)        ++line;      }    } -   +    /* Eject film holder and/or release_unit - but only for       non-duplex-rear / non-virtual scans. */    if ((deinterlace != NONE && s->duplex_rear_valid) || @@ -7485,14 +7484,14 @@ reader_process (void *data)        status = release_unit (s, 0);        if (status != SANE_STATUS_GOOD)  	DBG (1, "reader_process: release_unit failed\n"); -       +        if (dev->inquiry_new_protocol && dev->scanner_type == AV_FILM) {  	status = object_position (s, AVISION_SCSI_OP_GO_HOME);  	if (status != SANE_STATUS_GOOD)  	  DBG (1, "reader_process: object position go-home failed!\n");        }      } -   +    if ((dev->hw->feature_type & AV_ADF_FLIPPING_DUPLEX) && s->source_mode == AV_ADF_DUPLEX && s->page % 2) {      /* front page of flipping duplex */      if (exit_status == SANE_STATUS_EOF) { @@ -7507,10 +7506,15 @@ reader_process (void *data)            return status;          }        } -      /* we can set anything here without fear because the process will terminate soon and take our changes with it */ +      /* We run in a separate process or thread.  In the latter case, +         any change we make to s before the reader_process invocation +         needs to be reverted. */ +      SANE_Int lines = s->params.lines;        s->page += 1;        s->params.lines = -line;        exit_status = reader_process (s); +      s->params.lines = lines; +      s->page -= 1;      }      /* TODO:      * else { @@ -7522,15 +7526,15 @@ reader_process (void *data)    }    if (rear_fp)      fclose (rear_fp); -  +    if (ip_data) free (ip_data);    if (ip_history)      free (ip_history);    else      free (out_data); /* if we have ip_history out_data is included there */ -   +    free (stripe_data); -   +    DBG (3, "reader_process: returning success\n");    return exit_status;  } @@ -7550,17 +7554,17 @@ attach_one_usb (const char* dev)    attach (dev, AV_USB, 0);    return SANE_STATUS_GOOD;  } -   +  static SANE_Status  sane_reload_devices (void)  {    FILE* fp; -   +    char line[PATH_MAX];    const char* cp = 0;    char* word;    int linenumber = 0; -  int model_num = 0;   +  int model_num = 0;    sanei_usb_init ();    fp = sanei_config_open (AVISION_CONFIG_FILE); @@ -7574,15 +7578,15 @@ sane_reload_devices (void)        while (sanei_config_read  (line, sizeof (line), fp))  	{  	  attaching_hw = 0; -	   +  	  word = NULL;  	  ++ linenumber; -       +  	  DBG (5, "sane_reload_devices: parsing config line \"%s\"\n",  	       line); -       +  	  cp = sanei_config_get_string (line, &word); -	   +  	  if (!word || cp == line) {  	    DBG (5, "sane_reload_devices: config file line %d: ignoring empty line\n",  		 linenumber); @@ -7592,13 +7596,13 @@ sane_reload_devices (void)  	    }  	    continue;  	  } -	   +  	  if (!word) {  	    DBG (1, "sane_reload_devices: config file line %d: could not be parsed\n",  		 linenumber);  	    continue;  	  } -	   +  	  if (word[0] == '#') {  	    DBG (5, "sane_reload_devices: config file line %d: ignoring comment line\n",  		 linenumber); @@ -7606,13 +7610,13 @@ sane_reload_devices (void)  	    word = NULL;  	    continue;  	  } -                     +  	  if (strcmp (word, "option") == 0)  	    {  	      free (word);  	      word = NULL;  	      cp = sanei_config_get_string (cp, &word); -	   +  	      if (strcmp (word, "disable-gamma-table") == 0) {  		DBG (3, "sane_reload_devices: config file line %d: disable-gamma-table\n",  		     linenumber); @@ -7656,7 +7660,7 @@ sane_reload_devices (void)  	      else if (strcmp (word, "static-blue-calib") == 0) {  		DBG (3, "sane_reload_devices: config file line %d: static blue calibration\n",  		    linenumber); -		static_calib_list [2] = SANE_TRUE;  +		static_calib_list [2] = SANE_TRUE;  	      }  	      else  		DBG (1, "sane_reload_devices: config file line %d: options unknown!\n", @@ -7671,7 +7675,7 @@ sane_reload_devices (void)  	  else if (strcmp (word, "scsi") == 0) {  	    DBG (2, "sane_reload_devices: config file line %d: trying to attach SCSI: %s'\n",  		 linenumber, line); -	     +  	    /* the last time I verified (2003-03-18) this function  	       only matches SCSI devices ... */  	    sanei_config_attach_matching_devices (line, attach_one_scsi); @@ -7681,7 +7685,7 @@ sane_reload_devices (void)  		linenumber);  	    DBG (1, "sane_reload_devices:   (see man sane-avision for details): trying to attach SCSI: %s'\n",  		line); -	   +  	    /* the last time I verified (2003-03-18) this function  	       only matched SCSI devices ... */  	    sanei_config_attach_matching_devices (line, attach_one_scsi); @@ -7689,13 +7693,13 @@ sane_reload_devices (void)  	  free (word);  	  word = NULL;  	} /* end while read */ -       +        fclose (fp); -       +        if (word)  	free (word);      } /* end if fp */ -   +    /* search for all supported SCSI/USB devices */    while (Avision_Device_List [model_num].scsi_mfg != NULL ||           Avision_Device_List [model_num].real_mfg != NULL) @@ -7707,13 +7711,13 @@ sane_reload_devices (void)  				               attaching_hw->scsi_model, NULL,  				               -1, -1, -1, -1,  				               attach_one_scsi); -       +  	if (attaching_hw->usb_vendor != 0 && attaching_hw->usb_product != 0 )  	{  	  DBG (1, "sane_reload_devices: Trying to find USB device %.4x %.4x ...\n",  	       attaching_hw->usb_vendor,  	       attaching_hw->usb_product); -	   +  	  /* TODO: check return value */  	  if (sanei_usb_find_devices (attaching_hw->usb_vendor,  				      attaching_hw->usb_product, @@ -7723,7 +7727,7 @@ sane_reload_devices (void)  	}        ++ model_num;      } /* end for all devices in supported list */ -   +    attaching_hw = 0;    return SANE_STATUS_GOOD;  } @@ -7732,16 +7736,16 @@ SANE_Status  sane_init (SANE_Int* version_code, SANE_Auth_Callback authorize)  {    authorize = authorize; /* silence gcc */ -   +    DBG_INIT();  #ifdef AVISION_STATIC_DEBUG_LEVEL    DBG_LEVEL = AVISION_STATIC_DEBUG_LEVEL;  #endif -   +    DBG (3, "sane_init:(Version: %i.%i Build: %i)\n",         SANE_CURRENT_MAJOR, V_MINOR, BACKEND_BUILD); -   +    /* must come first */    sanei_thread_init (); @@ -7812,7 +7816,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)    uint8_t inquiry_result[AVISION_INQUIRY_SIZE_V1];    DBG (3, "sane_open:\n"); -   +    if (devicename[0]) {      for (dev = first_dev; dev; dev = dev->next)        if (strcmp (dev->sane.name, devicename) == 0) @@ -7830,26 +7834,26 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)    if (!dev)      return SANE_STATUS_INVAL; -   +    s = malloc (sizeof (*s));    if (!s)      return SANE_STATUS_NO_MEM; -   +    /* initialize ... */    /* the other states (scanning, ...) rely on this memset (0) */    memset (s, 0, sizeof (*s)); -   +    /* initialize connection state */    s->av_con.connection_type = dev->connection.connection_type;    s->av_con.usb_status = dev->connection.usb_status;    s->av_con.scsi_fd = -1;    s->av_con.usb_dn = -1; -   -  s->reader_pid = -1; + +  sanei_thread_initialize (s->reader_pid);    s->read_fds = -1;    s->hw = dev; -   +    /* We initialize the table to a gamma value of 2.22, since this is what       papers about Colorimetry suggest. @@ -7859,17 +7863,17 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)    {      const double gamma = 2.22;      const double one_over_gamma = 1. / gamma; -     +      for (i = 0; i < 4; ++ i)        for (j = 0; j < 256; ++ j)  	s->gamma_table[i][j] = pow( (double) j / 255, one_over_gamma) * 255;    } -   +    /* insert newly opened handle into list of open handles: */    s->next = first_handle;    first_handle = s;    *handle = s; -   +    /* open the device */    if (! avision_is_open (&s->av_con) ) {  #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED @@ -7907,17 +7911,17 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)      DBG (1, "sane_open: additional probe failed: %s\n", sane_strstatus (status));      return status;    } -   +    /* initialize the options */    init_options (s); -   +    if (dev->inquiry_duplex_interlaced || dev->scanner_type == AV_FILM ||        dev->hw->feature_type & AV_ADF_FLIPPING_DUPLEX) {      /* Might need at least *DOS (Windows flavour and OS/2) portability fix         However, I was told Cygwin (et al.) takes care of it. */      strncpy(s->duplex_rear_fname, "/tmp/avision-rear-XXXXXX", PATH_MAX); -     -    if (! mktemp(s->duplex_rear_fname) ) { + +    if (! mkstemp(s->duplex_rear_fname) ) {        DBG (1, "sane_open: failed to generate temporary fname for duplex scans\n");        return SANE_STATUS_NO_MEM;      } @@ -7926,25 +7930,25 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)  	   s->duplex_rear_fname);      }    } -   +    /* calibrate film scanners, as this must be done without the       film holder and at the full resolution */    if (dev->scanner_type == AV_FILM)      {        int default_res = s->val[OPT_RESOLUTION].w;        s->val[OPT_RESOLUTION].w = dev->inquiry_optical_res; -       +        DBG (1, "sane_open: early calibration for film scanner.\n"); -       +        compute_parameters (s); -       +        status = set_window (s);        if (status != SANE_STATUS_GOOD) {  	DBG (1, "sane_open: set scan window command failed: %s\n",  	     sane_strstatus (status));  	return status;        } -       +        if (!(dev->hw->feature_type & AV_NO_CALIB))  	{  	  status = normal_calibration (s); @@ -7954,16 +7958,16 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)  	    return status;  	  }  	} -       +        if (dev->scanner_type == AV_FILM) {  	status = object_position (s, AVISION_SCSI_OP_GO_HOME);  	if (status != SANE_STATUS_GOOD)  	  DBG (1, "reader_open: object position go-home failed!\n");        } -       +        s->val[OPT_RESOLUTION].w = default_res;      } -   +    return SANE_STATUS_GOOD;  } @@ -7975,12 +7979,12 @@ sane_close (SANE_Handle handle)    int i;    DBG (3, "sane_close:\n"); -   +    /* close the device */    if (avision_is_open (&s->av_con) ) {      avision_close (&s->av_con);    } -   +    /* remove handle from list of open handles: */    prev = 0;    for (s = first_handle; s; s = s->next) { @@ -8008,20 +8012,20 @@ sane_close (SANE_Handle handle)        free (s->val[i].s);      }    } -   +    if (s->white_avg_data)      free (s->white_avg_data);    if (s->dark_avg_data)      free (s->dark_avg_data); -   +    if (s->background_raster)      free (s->background_raster); -   +    if (*(s->duplex_rear_fname)) {      unlink (s->duplex_rear_fname);      *(s->duplex_rear_fname) = 0;    } -   +    free (handle);  } @@ -8029,7 +8033,7 @@ const SANE_Option_Descriptor*  sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)  {    Avision_Scanner* s = handle; -   +    DBG (3, "sane_get_option_descriptor: %d\n", option);    if ((unsigned) option >= NUM_OPTIONS) @@ -8045,7 +8049,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,    Avision_Device* dev = s->hw;    SANE_Status status;    SANE_Word cap; -   +    DBG (3, "sane_control_option: option=%d, action=%d\n",         (int)option, (int)action); @@ -8060,7 +8064,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,    if (s->scanning)      return SANE_STATUS_DEVICE_BUSY; -   +    if (option >= NUM_OPTIONS)      return SANE_STATUS_INVAL; @@ -8075,7 +8079,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	{  	  /* word options: */  	case OPT_PREVIEW: -	   +  	case OPT_RESOLUTION:  	case OPT_SPEED:  	case OPT_TL_X: @@ -8086,7 +8090,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_OVERSCAN_BOTTOM:  	case OPT_BACKGROUND:  	case OPT_NUM_OPTS: -	   +  	case OPT_BRIGHTNESS:  	case OPT_CONTRAST:  	case OPT_EXPOSURE: @@ -8098,19 +8102,19 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_ADF_FLIP:  	  *(SANE_Word*) val = s->val[option].w;  	  return SANE_STATUS_GOOD; -	   +  	  /* specially treated word options */ -	   +  	case OPT_FRAME:  	  status = get_frame_info (s);  	  *(SANE_Word*) val = s->val[option].w;  	  return status; -	   +  	case OPT_POWER_SAVE_TIME:  	  get_power_save_time (s, &(s->val[option].w));  	  *(SANE_Word*) val = s->val[option].w;  	  return SANE_STATUS_GOOD; -	   +  	  /* word-array options: */  	case OPT_GAMMA_VECTOR:  	case OPT_GAMMA_VECTOR_R: @@ -8118,7 +8122,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_GAMMA_VECTOR_B:  	  memcpy (val, s->val[option].wa, s->opt[option].size);  	  return SANE_STATUS_GOOD; -	   +  	  /* string options: */  	case OPT_MODE:  	case OPT_SOURCE: @@ -8129,28 +8133,28 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_MESSAGE:  	  if (dev->inquiry_button_control || dev->inquiry_buttons)  	    status = get_button_status (s); -	   +  	  strcpy (val, s->val[option].s);  	  s->val[option].s[0] = 0;  	  return SANE_STATUS_GOOD;  	case OPT_NVRAM:  	  get_and_parse_nvram (s, s->val[option].s, 1024); -	   +  	  strcpy (val, s->val[option].s);  	  return SANE_STATUS_GOOD; -	   +  	} /* end switch option */      } /* end if GET_ACTION_GET_VALUE */    else if (action == SANE_ACTION_SET_VALUE)      {        if (!SANE_OPTION_IS_SETTABLE (cap))  	return SANE_STATUS_INVAL; -       +        status = constrain_value (s, option, val, info);        if (status != SANE_STATUS_GOOD)  	return status; -       +        switch (option)  	{  	  /* side-effect-free word options: */ @@ -8170,7 +8174,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_ADF_FLIP:  	  s->val[option].w = *(SANE_Word*) val;  	  return SANE_STATUS_GOOD; -	   +  	  /* side-effect-free word-array options: */  	case OPT_GAMMA_VECTOR:  	case OPT_GAMMA_VECTOR_R: @@ -8178,7 +8182,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_GAMMA_VECTOR_B:  	  memcpy (s->val[option].wa, val, s->opt[option].size);  	  return SANE_STATUS_GOOD; -		  +  	  /* options with side-effects: */  	case OPT_RESOLUTION:  	case OPT_TL_X: @@ -8195,14 +8199,14 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	  /* string options with side-effects: */  	case OPT_SOURCE: -	   +  	  if (s->val[option].s) {  	    free(s->val[option].s);  	  }  	  s->val[option].s = strdup(val);  	  s->source_mode = match_source_mode (dev, s->val[option].s);  	  s->source_mode_dim = match_source_mode_dim (s->source_mode); -	   +  	  /* set side-effects */  	  dev->x_range.max =  	    SANE_FIX ( dev->inquiry_x_ranges[s->source_mode_dim]); @@ -8214,22 +8218,22 @@ sane_control_option (SANE_Handle handle, SANE_Int option,            } else {              s->opt[OPT_ADF_FLIP].cap |= SANE_CAP_INACTIVE;            } -	   +  	  if (info)  	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; -	   +  	  return SANE_STATUS_GOOD; -	   +  	case OPT_MODE:  	  {  	    if (s->val[option].s)  	      free (s->val[option].s); -	     +  	    s->val[option].s = strdup (val);  	    s->c_mode = match_color_mode (dev, s->val[OPT_MODE].s); -	     +  	    /* set to mode specific values */ -	     +  	    /* the gamma table related */  	    if (!disable_gamma_table)  	      { @@ -8246,7 +8250,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  		    s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;  		    s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;  		  } -	      }		 +	      }  	    if (info)  	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;  	    return SANE_STATUS_GOOD; @@ -8254,7 +8258,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,  	case OPT_FRAME:  	  {  	    SANE_Word frame = *((SANE_Word  *) val); -	     +  	    status = set_frame (s, frame);  	    if (status == SANE_STATUS_GOOD) {  	      s->val[OPT_FRAME].w = frame; @@ -8292,9 +8296,9 @@ SANE_Status  sane_get_parameters (SANE_Handle handle, SANE_Parameters* params)  {    Avision_Scanner* s = handle; -   +    DBG (3, "sane_get_parameters:\n"); -   +    /* During an actual scan these parameters will have been computed in       sane_start().  Otherwise, the values must be computed on demand.  The       values cannot be changed during a scan to avoid inconsistency. */ @@ -8309,7 +8313,7 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters* params)      /* add background raster lines */      params->lines += s->val[OPT_BACKGROUND].w;    } -   +    return SANE_STATUS_GOOD;  } @@ -8318,25 +8322,25 @@ sane_start (SANE_Handle handle)  {    Avision_Scanner* s = handle;    Avision_Device* dev = s->hw; -   +    SANE_Status status;    int fds [2];    DBG (1, "sane_start:\n"); -   +    /* Make sure there is no scan running!!! */    if (s->scanning)      return SANE_STATUS_DEVICE_BUSY;    /* Clear cancellation status */    s->cancelled = 0; -  +    /* Make sure we have a current parameter set. Some of the       parameters will be overwritten below, but that's OK. */    status = sane_get_parameters (s, &s->params);    if (status != SANE_STATUS_GOOD) {      return status;    } -   +    /* for non ADF scans (e.g. scanimage --batch-prompt on a Flatbed       scanner) make sure we do not assume it's an ADF scan and       optimize something away*/ @@ -8347,7 +8351,7 @@ sane_start (SANE_Handle handle)      DBG (1, "sane_start: virtual duplex rear data valid.\n");      goto start_scan_end;    } -   +    /* Check for paper during ADF scans and for sheetfed scanners. */    if (is_adf_scan (s)) {      status = media_check (s); @@ -8359,7 +8363,7 @@ sane_start (SANE_Handle handle)      else        DBG (1, "sane_start: media_check ok\n");    } -   +    /* Check the light early, to return to the GUI and notify the user. */    if (s->prepared == SANE_FALSE) {      if (dev->inquiry_light_control) { @@ -8397,28 +8401,28 @@ sane_start (SANE_Handle handle)      {        size_t size = 16;        uint8_t result[16]; -       +        DBG (5, "sane_start: reading scanner window size\n"); -       +        status = simple_read (s, 0x80, 0, &size, result); -       +        if (status != SANE_STATUS_GOOD) {  	DBG (1, "sane_start: get pixel size command failed: %s\n",  	     sane_strstatus (status));  	goto stop_scanner_and_return; -      }  +      }        debug_print_raw (5, "sane_start: pixel_size:", result, size);        DBG (5, "sane_start: x-pixels: %d, y-pixels: %d\n",  	   get_quad (&(result[0])), get_quad (&(result[4])));      }  #endif -   +    /* no calibration for ADF pages */    if (s->page > 0) {      DBG (1, "sane_start: optimized calibration away.\n");      goto calib_end;    } -   +    /* check whether the user enforces calibration */    if (force_calibration) {      DBG (1, "sane_start: calibration enforced in config!\n"); @@ -8431,12 +8435,12 @@ sane_start (SANE_Handle handle)      DBG (1, "sane_start: old protocol no calibration needed!\n");      goto calib_end;    } -   +    if (!dev->inquiry_needs_calibration) {      DBG (1, "sane_start: due to inquiry no calibration needed!\n");      goto calib_end;    } -   +    /* calibration allowed for this scanner? */    if (dev->hw->feature_type & AV_NO_CALIB) {      DBG (1, "sane_start: calibration disabled in device list!!\n"); @@ -8448,28 +8452,28 @@ sane_start (SANE_Handle handle)      DBG (1, "sane_start: no calibration for film scanner!\n");      goto calib_end;    } -   +    /* check whether calibration is disabled by the user */    if (disable_calibration) {      DBG (1, "sane_start: calibration disabled in config - skipped!\n");      goto calib_end;    } -   +    /* R² reminder: We must not skip the calibration for ADF scans, some       scanner (HP 53xx/74xx ASIC series) rely on a calibration data       read (and will hang otherwise) */   calib:    status = normal_calibration (s); -   +    if (status != SANE_STATUS_GOOD) {      DBG (1, "sane_start: perform calibration failed: %s\n",  	 sane_strstatus (status));  	goto stop_scanner_and_return;    } -   +   calib_end: -   +    if (dev->inquiry_3x3_matrix && dev->inquiry_asic_type >= AV_ASIC_C6 &&        s->page == 0)    { @@ -8478,13 +8482,13 @@ sane_start (SANE_Handle handle)        return status;      }    } -   +    /* check whether gamma-table is disabled by the user? */    if (disable_gamma_table) {      DBG (1, "sane_start: gamma-table disabled in config - skipped!\n");      goto gamma_end;    } -   +    if (dev->hw->feature_type & AV_NO_GAMMA) {      DBG (1, "sane_start: gamma table skipped due to device-list!!\n");      goto gamma_end; @@ -8501,9 +8505,9 @@ sane_start (SANE_Handle handle)        goto stop_scanner_and_return;      }    } -   +   gamma_end: -   +    if (dev->inquiry_tune_scan_length && is_adf_scan (s)) {      status = send_tune_scan_length (s);      if (status != SANE_STATUS_GOOD) { @@ -8512,7 +8516,7 @@ sane_start (SANE_Handle handle)        goto stop_scanner_and_return;      }    } -   +    /* if the device supports retrieving background raster data       inquire the data no matter if the user/applications asks for       it in order to use it for bottom padding */ @@ -8524,11 +8528,11 @@ sane_start (SANE_Handle handle)        goto stop_scanner_and_return;      }    } -   +    /* check film holder */    if (dev->scanner_type == AV_FILM && dev->holder_type == 0xff) {      DBG (1, "sane_start: no film holder or APS cassette!\n"); -     +      /* Normally "go_home" is executed from the reader process,         but as it will not start we have to reset things here */      if (dev->inquiry_new_protocol) { @@ -8539,33 +8543,33 @@ sane_start (SANE_Handle handle)      }      goto stop_scanner_and_return;    } -   +   start_scan_end: -   +    s->scanning = SANE_TRUE;    s->page += 1; /* processing next page */ -   +    if (pipe (fds) < 0) {      return SANE_STATUS_IO_ERROR;    } -   +    s->read_fds = fds[0];    s->write_fds = fds[1];    /* create reader routine as new process or thread */    DBG (3, "sane_start: starting thread\n");    s->reader_pid = sanei_thread_begin (reader_process, (void *) s); -   +    if (sanei_thread_is_forked())  	close (s->write_fds); -  +    return SANE_STATUS_GOOD; -   +   stop_scanner_and_return: -   +    /* cancel the scan nicely */    do_cancel (s); -   +    return status;  } @@ -8588,7 +8592,7 @@ sane_read (SANE_Handle handle, SANE_Byte* buf, SANE_Int max_len, SANE_Int* len)    if (!s->scanning)      return SANE_STATUS_CANCELLED; -   +    if (nread < 0) {      if (errno == EAGAIN) {        return SANE_STATUS_GOOD; @@ -8597,9 +8601,9 @@ sane_read (SANE_Handle handle, SANE_Byte* buf, SANE_Int max_len, SANE_Int* len)        return SANE_STATUS_IO_ERROR;      }    } -   +    *len = nread; -   +    /* if all data was passed through */    if (nread == 0)      return do_eof (s); @@ -8621,16 +8625,16 @@ SANE_Status  sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)  {    Avision_Scanner* s = handle; -   +    DBG (3, "sane_set_io_mode:\n");    if (!s->scanning) {      DBG (3, "sane_set_io_mode: not yet scanning\n");      return SANE_STATUS_INVAL;    } -   +    if (fcntl (s->read_fds, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)      return SANE_STATUS_IO_ERROR; -   +    return SANE_STATUS_GOOD;  } @@ -8638,14 +8642,14 @@ SANE_Status  sane_get_select_fd (SANE_Handle handle, SANE_Int* fd)  {    Avision_Scanner* s = handle; -   +    DBG (3, "sane_get_select_fd:\n"); -   +    if (!s->scanning) {      DBG (3, "sane_get_select_fd: not yet scanning\n");      return SANE_STATUS_INVAL;    } -   +    *fd = s->read_fds;    return SANE_STATUS_GOOD;  }  | 
