Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <errno.h></errno.h>
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "tscanner.h"
Toshihiro Shimizu 890ddd
#include "tscannerepson.h"
Toshihiro Shimizu 890ddd
#include "tscannerutil.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Shinya Kitaoka 9eb50d
Toshihiro Shimizu 890ddd
#include "TScannerIO/TUSBScannerIO.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
#include <cassert></cassert>
Shinya Kitaoka 9eb50d
#include <memory></memory>
Shinya Kitaoka 9eb50d
#include <fstream></fstream>
Shinya Kitaoka 9eb50d
#include <strstream></strstream>
Shinya Kitaoka 9eb50d
Toshihiro Shimizu 890ddd
using namespace TScannerUtil;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void sense(bool) {}
Shinya Kitaoka 120a6e
int scsi_maxlen() {
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BW_USES_GRAYTONES
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Toshihiro Shimizu 890ddd
#define SWAPIT
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef i386
Toshihiro Shimizu 890ddd
#undef SWAPIT
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Commands used to drive the scanner:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
cmd   spec                    Level
Toshihiro Shimizu 890ddd
@     Reset                B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
Q     Sharpness                  B4 B5 A5
Toshihiro Shimizu 890ddd
B     Halftoning        B1 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
Z     Gamma                B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
L     Brightness           B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
t     Threshold
Toshihiro Shimizu 890ddd
H     Zoom                 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
R     Resolution        B1 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
A     Set read Area     B1 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
C     Linesequence Mode B1 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
d     Line count                 B4 B5 A5
Toshihiro Shimizu 890ddd
D     Dataformat        B1 B2 B3 B4 B5 A5
Toshihiro Shimizu 890ddd
g     Scan speed                 B4 B5 A5
Toshihiro Shimizu 890ddd
G     Start Scan        B1 B2 B3 B4 B5
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
e     Activate ADF
Toshihiro Shimizu 890ddd
0x19  Load from ADF
Toshihiro Shimizu 890ddd
0x0C  Unload from ADF
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* NOTE: you can find these codes with "man ascii". */
Toshihiro Shimizu 890ddd
static unsigned char STX = 0x02;
Toshihiro Shimizu 890ddd
static unsigned char ACK = 0x06;
Toshihiro Shimizu 890ddd
static unsigned char NAK = 0x15;
Toshihiro Shimizu 890ddd
static unsigned char CAN = 0x18;
Toshihiro Shimizu 890ddd
static unsigned char ESC = 0x1B;
Shinya Kitaoka 120a6e
static unsigned char PF  = 0x19;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/* STATUS bit in readLineData */
Toshihiro Shimizu 890ddd
static unsigned char FatalError = 1 << 7;
Shinya Kitaoka 120a6e
static unsigned char NotReady   = 1 << 6;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define log
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TScannerExpection final : public TException {
Shinya Kitaoka 120a6e
  TString m_scannerMsg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TScannerExpection(const std::vector<std::string> ¬Fatal,</std::string>
Shinya Kitaoka 120a6e
                    const std::string &fatal)
Shinya Kitaoka 120a6e
      : TException("Scanner Expection") {
Shinya Kitaoka 120a6e
    m_scannerMsg = ::to_wstring(fatal);
Shinya Kitaoka 120a6e
    for (int i = notFatal.size(); i; i--)
Shinya Kitaoka 120a6e
      m_scannerMsg += L"\n" + ::to_wstring(notFatal[i - 1]);
Shinya Kitaoka 120a6e
    log("Exception created: " + ::to_string(m_scannerMsg));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  TString getMessage() const override { return m_scannerMsg; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void log(string s)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  std::ofstream os("C:\\butta.txt", std::ios::app);
Toshihiro Shimizu 890ddd
  os << s << std::endl;
Toshihiro Shimizu 890ddd
  os.flush();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TScannerEpson::TScannerEpson()
Shinya Kitaoka 120a6e
    : m_scannerIO(new TUSBScannerIO()), m_hasADF(false), m_isOpened(false) {
Shinya Kitaoka 120a6e
  log("Created");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::closeIO() {
Shinya Kitaoka 120a6e
  log("CloseIO.");
Shinya Kitaoka 120a6e
  if (m_scannerIO && m_isOpened) m_scannerIO->close();
Shinya Kitaoka 120a6e
  m_isOpened = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TScannerEpson::~TScannerEpson() {
Shinya Kitaoka 120a6e
  closeIO();
Shinya Kitaoka 120a6e
  log("Destroyed");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::selectDevice() {
Shinya Kitaoka 120a6e
  log(std::string("selectDevice; isOpened=") + (m_isOpened ? "true" : "false"));
Shinya Kitaoka 120a6e
  if (!m_scannerIO->open()) {
Shinya Kitaoka 120a6e
    log("open() failed");
Shinya Kitaoka 120a6e
    throw TException("unable to get handle to scanner");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_isOpened = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
char lev0, lev1;
Shinya Kitaoka 120a6e
unsigned short lowRes, hiRes, hMax,vMax;
Shinya Kitaoka 120a6e
collectInformation(&lev0, &lev1, &lowRes, &hiRes, &hMax, &vMax);
Shinya Kitaoka 120a6e
string version = toString(lev0) + "." + toString(lev1);
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  setName("Scanner EPSON (Internal driver)");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::isDeviceAvailable() { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::isDeviceSelected() { return m_isOpened; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::updateParameters(TScannerParameters ¶meters) {
Shinya Kitaoka 120a6e
  log("updateParameters()");
Shinya Kitaoka 120a6e
  char lev0, lev1;
Shinya Kitaoka 120a6e
  unsigned short lowRes, hiRes, hMax, vMax;
Shinya Kitaoka 120a6e
  collectInformation(&lev0, &lev1, &lowRes, &hiRes, &hMax, &vMax);
Shinya Kitaoka 120a6e
  log("collected info. res = " + std::to_string(lowRes) + "/" +
Shinya Kitaoka 120a6e
      std::to_string(hiRes));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // non supportiamo black & white
Shinya Kitaoka 120a6e
  parameters.setSupportedTypes(true, true, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // param.m_scanArea = TRectD(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  parameters.setMaxPaperSize((25.4 * hMax) / (float)hiRes,
Shinya Kitaoka 120a6e
                             (25.4 * vMax) / (float)hiRes);
Shinya Kitaoka 120a6e
  parameters.updatePaperFormat();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // cambio range, default, step, e supported. aggiorno, se necessario, il value
Shinya Kitaoka 120a6e
  // (n.b. non dovrebbe succedere
Shinya Kitaoka 120a6e
  // mai, perche' i range sono sempre gli stessi su tutti gli scanner
Shinya Kitaoka 120a6e
  TScanParam defaultEpsonParam(0., 255., 128., 1.);
Shinya Kitaoka 120a6e
  parameters.m_brightness.update(defaultEpsonParam);
Shinya Kitaoka 120a6e
  parameters.m_contrast.update(defaultEpsonParam);
Shinya Kitaoka 120a6e
  parameters.m_threshold.update(defaultEpsonParam);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_hasADF) {
Shinya Kitaoka 120a6e
    TScanParam defaultPaperFeederParam(0., 1., 0., 1.);
Shinya Kitaoka 120a6e
    parameters.m_paperFeeder.update(defaultPaperFeederParam);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    parameters.m_paperFeeder.m_supported = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // cerco un default per il dpi. il piu' piccolo possibile nella forma 100+k50
Shinya Kitaoka 120a6e
  float defaultDpi = 100;
Shinya Kitaoka 120a6e
  while (defaultDpi < lowRes) defaultDpi += 50;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TScanParam defaultDpiParam(lowRes, hiRes, defaultDpi,
Shinya Kitaoka 120a6e
                             hiRes > lowRes ? 1.F : 0.F);
Shinya Kitaoka 120a6e
  parameters.m_dpi.update(defaultDpiParam);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  parameters.m_twainVersion = "NATIVE";
Shinya Kitaoka 120a6e
  //  parameters.m_manufacturer = "EPSON";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  parameters.m_version = toString(lev0) + "." + toString(lev1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  log("end updateParameters()");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::acquire(const TScannerParameters ¶ms, int paperCount) {
Shinya Kitaoka 120a6e
  log("acquire");
Shinya Kitaoka 120a6e
  TRectD scanArea = params.getScanArea();
Shinya Kitaoka 120a6e
  if (scanArea.isEmpty())
Shinya Kitaoka 120a6e
    throw TException("Scan area is empty, select a paper size");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if ((scanArea.getSize().lx > params.m_maxPaperSize.lx) ||
Shinya Kitaoka 120a6e
(scanArea.getSize().ly > params.m_maxPaperSize.ly))
Shinya Kitaoka 120a6e
throw TException("Scan area too large, select a correct paper size");
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < paperCount; ++i) {
Shinya Kitaoka 120a6e
    log("paper " + std::to_string(i));
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
    m_scannerIO->trace(true);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    doSettings(params, i == 0);
Shinya Kitaoka 120a6e
    unsigned int nTimes = 0;
Shinya Kitaoka 120a6e
    unsigned int bytes_to_read;
Shinya Kitaoka 120a6e
    bool rc;
Shinya Kitaoka 120a6e
    unsigned char stx;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
    m_scannerIO->trace(false);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRasterP ras, rasBuffer;
Shinya Kitaoka 120a6e
    unsigned char *buffer = 0;
Shinya Kitaoka 120a6e
    log("Scan command");
Shinya Kitaoka 120a6e
    rc = ESCI_command('G', false); /* 'SCAN' command */
Shinya Kitaoka 120a6e
    if (!rc) throw TException("Start Scan failed");
Shinya Kitaoka 120a6e
    log("Scan command OK");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    unsigned short offsetx = 0, offsety = 0;
Shinya Kitaoka 120a6e
    unsigned short dimlx = 0, dimly = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TRectD scanArea =
Shinya Kitaoka 120a6e
        params.isPreview() ? params.getScanArea() : params.getCropBox();
Shinya Kitaoka 120a6e
    scanArea2pix(params, offsetx, offsety, dimlx, dimly, scanArea);
Shinya Kitaoka 120a6e
    tswap(dimlx, dimly);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    unsigned int bytes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    switch (params.getScanType()) {
Shinya Kitaoka 120a6e
    case TScannerParameters::BW:
Toshihiro Shimizu 890ddd
#ifdef BW_USES_GRAYTONES
Shinya Kitaoka 120a6e
      ras       = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      bytes     = dimlx * dimly;
Shinya Kitaoka 120a6e
      rasBuffer = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      buffer    = rasBuffer->getRawData();
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      ras       = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      bytes     = tceil(dimlx / 8) * dimly;
Shinya Kitaoka 120a6e
      rasBuffer = TRasterGR8P(tceil(dimlx / 8), dimly);
Shinya Kitaoka 120a6e
      // bytes = (dimlx + 7) % 8 * dimly;
Shinya Kitaoka 120a6e
      // rasBuffer = TRasterGR8P((dimlx + 7) % 8,dimly);
Shinya Kitaoka 120a6e
      buffer = rasBuffer->getRawData();
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    case TScannerParameters::GR8:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GRAYTONES_USES_RGB
Shinya Kitaoka 120a6e
      ras       = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      bytes     = dimlx * dimly * 3;
Shinya Kitaoka 120a6e
      rasBuffer = TRasterGR8P(dimlx * 3, dimly);
Shinya Kitaoka 120a6e
      buffer    = rasBuffer->getRawData();
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      ras       = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      bytes     = dimlx * dimly;
Shinya Kitaoka 120a6e
      rasBuffer = TRasterGR8P(dimlx, dimly);
Shinya Kitaoka 120a6e
      buffer    = rasBuffer->getRawData();
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    case TScannerParameters::RGB24:
Shinya Kitaoka 120a6e
      ras       = TRaster32P(dimlx, dimly);
Shinya Kitaoka 120a6e
      bytes     = dimlx * dimly * 3;
Shinya Kitaoka 120a6e
      rasBuffer = TRasterGR8P(dimlx * 3, dimly);
Shinya Kitaoka 120a6e
      buffer    = rasBuffer->getRawData();
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      throw TException("Unknown scanner mode");
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    log("sleep");
Shinya Kitaoka 120a6e
    TSystem::sleep(2000);
Shinya Kitaoka 120a6e
    log("reading data");
Shinya Kitaoka 120a6e
    bool areaEnd            = false;
Shinya Kitaoka 120a6e
    unsigned int bytes_read = 0;
Shinya Kitaoka 120a6e
    while (!areaEnd) {
Shinya Kitaoka 120a6e
      unsigned short lines, counter;
Shinya Kitaoka 120a6e
      unsigned char status    = 0;
Shinya Kitaoka 120a6e
      unsigned int retryCount = 0;
Shinya Kitaoka 120a6e
      do {
Shinya Kitaoka 120a6e
        ESCI_readLineData(stx, status, counter, lines, areaEnd);
Shinya Kitaoka 120a6e
        if (status & FatalError) {
Shinya Kitaoka 120a6e
          retryCount++;
Shinya Kitaoka 120a6e
          if (retryCount == 1) throw TException("Error scanning");
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } while (status & FatalError);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      bytes_to_read = lines * counter;
Shinya Kitaoka 120a6e
      if (stx != 0x02) {
Shinya Kitaoka 120a6e
        std::ostrstream os;
Shinya Kitaoka 120a6e
        os << "header corrupted (" << std::hex << stx << ")" << '\0';
Shinya Kitaoka 120a6e
        throw TException(os.str());
Toshihiro Shimizu 890ddd
      }
Shinya Kitaoka 120a6e
      unsigned long reqBytes                      = bytes_to_read;
Shinya Kitaoka 120a6e
      std::unique_ptr<unsigned char[]=""> readBuffer = ESCI_read_data2(reqBytes);</unsigned>
Shinya Kitaoka 120a6e
      if (!readBuffer) throw TException("Error reading image data");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      log("readline: OK");
Shinya Kitaoka 120a6e
      /*
Shinya Kitaoka 120a6e
if (params.getScanType() == TScannerParameters::BW )
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
for (unsigned int i = 0; i< reqBytes;i++)
Shinya Kitaoka 120a6e
readBuffer[i] = ~readBuffer[i];
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
      memcpy(buffer + bytes_read, readBuffer.get(), reqBytes);
Shinya Kitaoka 120a6e
      bytes_read += reqBytes;
Shinya Kitaoka 120a6e
      nTimes++;
Shinya Kitaoka 120a6e
      if (bytes_read == bytes) break; /* I've read enough bytes */
Shinya Kitaoka 120a6e
      if (!(stx & 0x20)) sendACK();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    log("read: OK");
Shinya Kitaoka 120a6e
    { /*
Shinya Kitaoka 120a6e
FILE *myFile = fopen("C:\\temp\\prova.dmp", "w+");
Shinya Kitaoka 120a6e
fwrite(buffer, 1, bytes_to_read, myFile);
Shinya Kitaoka 120a6e
fclose(myFile);*/
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (params.m_paperFeeder.m_supported &&
Shinya Kitaoka 120a6e
        (params.m_paperFeeder.m_value == 1.)) {
Shinya Kitaoka 120a6e
      log("Advance paper");
Shinya Kitaoka 120a6e
      if (m_settingsMode == OLD_STYLE) ESCI_doADF(0);
Shinya Kitaoka 120a6e
      log("Advance paper: OK");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    switch (params.getScanType()) {
Shinya Kitaoka 120a6e
    case TScannerParameters::BW:
Toshihiro Shimizu 890ddd
#ifdef BW_USES_GRAYTONES
Shinya Kitaoka 120a6e
      copyGR8BufferToTRasterBW(buffer, dimlx, dimly, ras, true,
Shinya Kitaoka 120a6e
                               params.m_threshold.m_value);
Shinya Kitaoka 120a6e
      // copyGR8BufferToTRasterGR8(buffer, dimlx, dimly, ras, true);
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      copyBWBufferToTRasterGR8(buffer, dimlx, dimly, ras, true, true);
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    case TScannerParameters::GR8:
Toshihiro Shimizu 890ddd
#ifdef GRAYTONES_USES_RGB
Shinya Kitaoka 120a6e
      copyRGBBufferToTRasterGR8(buffer, dimlx, dimly, dimlx, ras);
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      copyGR8BufferToTRasterGR8(buffer, dimlx, dimly, ras, true);
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    case TScannerParameters::RGB24:
Shinya Kitaoka 120a6e
      copyRGBBufferToTRaster32(buffer, dimlx, dimly, ras, true);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      throw TException("Unknown scanner mode");
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (params.getCropBox() != params.getScanArea() && !params.isPreview()) {
Shinya Kitaoka 120a6e
      TRect scanRect(
Shinya Kitaoka 120a6e
          TPoint(offsetx, offsety),
Shinya Kitaoka 120a6e
          TDimension(dimly, dimlx));  // dimLx and ly was has been swapped
Shinya Kitaoka 120a6e
      scanArea2pix(params, offsetx, offsety, dimlx, dimly,
Shinya Kitaoka 120a6e
                   params.getScanArea());
Shinya Kitaoka 120a6e
      TRasterP app = ras->create(dimly, dimlx);
Shinya Kitaoka 120a6e
      TRaster32P app32(app);
Shinya Kitaoka 120a6e
      TRasterGR8P appGR8(app);
Shinya Kitaoka 120a6e
      if (app32)
Shinya Kitaoka 120a6e
        app32->fill(TPixel32::White);
Shinya Kitaoka 120a6e
      else if (appGR8)
Shinya Kitaoka 120a6e
        appGR8->fill(TPixelGR8::White);
Shinya Kitaoka 120a6e
      app->copy(ras, TPoint(dimly - scanRect.y1 - 1, dimlx - scanRect.x1 - 1));
Shinya Kitaoka 120a6e
      ras = app;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TRasterImageP rasImg(ras);
Shinya Kitaoka 120a6e
    if (ras) {
Shinya Kitaoka 120a6e
      rasImg->setDpi(params.m_dpi.m_value, params.m_dpi.m_value);
Shinya Kitaoka 120a6e
      rasImg->setSavebox(ras->getBounds());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    log("notifying");
Shinya Kitaoka 120a6e
    notifyImageDone(rasImg);
Shinya Kitaoka 120a6e
    if (!(params.m_paperFeeder.m_value == 1.) ||
Shinya Kitaoka 120a6e
        params.isPreview())  // feeder here!
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      if ((paperCount - i) > 1) notifyNextPaper();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      notifyAutomaticallyNextPaper();
Shinya Kitaoka 120a6e
    if (isScanningCanceled()) break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*Unload Paper if need*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if ((m_settingsMode == NEW_STYLE) && params.m_paperFeeder.m_supported &&
Shinya Kitaoka 120a6e
      (params.m_paperFeeder.m_value == 1.)) {
Shinya Kitaoka 120a6e
    if (!ESCI_command_1b('e', 1, true)) {
Shinya Kitaoka 120a6e
      std::vector<std::string> notFatal;</std::string>
Shinya Kitaoka 120a6e
      throw TScannerExpection(notFatal, "Scanner error (un)loading paper");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    unsigned char p = 0x0C;
Shinya Kitaoka 120a6e
    bool status     = true;
Shinya Kitaoka 120a6e
    send(&p, 1);
Shinya Kitaoka 120a6e
    status = expectACK();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  log("acquire OK");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::isAreaSupported() { return true; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline unsigned char B0(const unsigned int v) { return (v & 0x000000ff); }
Toshihiro Shimizu 890ddd
inline unsigned char B1(const unsigned int v) { return (v & 0x0000ff00) >> 8; }
Toshihiro Shimizu 890ddd
inline unsigned char B2(const unsigned int v) { return (v & 0x00ff0000) >> 16; }
Toshihiro Shimizu 890ddd
inline unsigned char B3(const unsigned int v) { return (v & 0xff000000) >> 24; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::doSettings(const TScannerParameters ¶ms,
Shinya Kitaoka 120a6e
                               bool firstSheet) {
Shinya Kitaoka 120a6e
  log("doSettings");
Shinya Kitaoka 120a6e
  int retryCount = 3;
Shinya Kitaoka 120a6e
  std::vector<std::string> notFatal;</std::string>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (retryCount--) {
Shinya Kitaoka 120a6e
    if (m_settingsMode == NEW_STYLE) {
Shinya Kitaoka 120a6e
      if (firstSheet)
Shinya Kitaoka 120a6e
        if (!resetScanner()) {
Shinya Kitaoka 120a6e
          notFatal.push_back("Scanner error resetting");
Shinya Kitaoka 120a6e
          continue;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (!resetScanner()) {
Shinya Kitaoka 120a6e
        notFatal.push_back("Scanner error resetting");
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    unsigned char cmd[64];
Shinya Kitaoka 120a6e
    memset(&cmd, 0, 64);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    unsigned char brightness = 0x00;
Shinya Kitaoka 120a6e
    float bv                 = params.m_brightness.m_value;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (bv >= 0 && bv < 43) brightness    = 0xFD;
Shinya Kitaoka 120a6e
    if (bv >= 43 && bv < 86) brightness   = 0xFE;
Shinya Kitaoka 120a6e
    if (bv >= 86 && bv < 128) brightness  = 0xFF;
Shinya Kitaoka 120a6e
    if (bv >= 128 && bv < 171) brightness = 0x00;
Shinya Kitaoka 120a6e
    if (bv >= 171 && bv < 214) brightness = 0x01;
Shinya Kitaoka 120a6e
    if (bv >= 214 && bv < 255) brightness = 0x02;
Shinya Kitaoka 120a6e
    if (bv == 255) brightness             = 0x03;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    unsigned short dpi = (unsigned short)params.m_dpi.m_value;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    unsigned short offsetx, offsety;
Shinya Kitaoka 120a6e
    unsigned short sizelx, sizely;
Shinya Kitaoka 120a6e
    TRectD scanArea =
Shinya Kitaoka 120a6e
        params.isPreview() ? params.getScanArea() : params.getCropBox();
Shinya Kitaoka 120a6e
    scanArea2pix(params, offsetx, offsety, sizelx, sizely, scanArea);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the main scan resolution (ESC R)
Shinya Kitaoka 120a6e
    cmd[0] = B0(dpi);
Shinya Kitaoka 120a6e
    cmd[1] = B1(dpi);
Shinya Kitaoka 120a6e
    cmd[2] = B2(dpi);
Shinya Kitaoka 120a6e
    cmd[3] = B3(dpi);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the sub scan resolution (ESC R)
Shinya Kitaoka 120a6e
    cmd[4] = B0(dpi);
Shinya Kitaoka 120a6e
    cmd[5] = B1(dpi);
Shinya Kitaoka 120a6e
    cmd[6] = B2(dpi);
Shinya Kitaoka 120a6e
    cmd[7] = B3(dpi);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // skipping length of main scan (ESC A)
Shinya Kitaoka 120a6e
    cmd[8]  = B0(offsetx);
Shinya Kitaoka 120a6e
    cmd[9]  = B1(offsetx);
Shinya Kitaoka 120a6e
    cmd[10] = B2(offsetx);
Shinya Kitaoka 120a6e
    cmd[11] = B3(offsetx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // skipping length of sub scan (ESC A)
Shinya Kitaoka 120a6e
    cmd[12] = B0(offsety);
Shinya Kitaoka 120a6e
    cmd[13] = B1(offsety);
Shinya Kitaoka 120a6e
    cmd[14] = B2(offsety);
Shinya Kitaoka 120a6e
    cmd[15] = B3(offsety);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the length of main scanning (ESC A)
Shinya Kitaoka 120a6e
    cmd[16] = B0(sizelx);
Shinya Kitaoka 120a6e
    cmd[17] = B1(sizelx);
Shinya Kitaoka 120a6e
    cmd[18] = B2(sizelx);
Shinya Kitaoka 120a6e
    cmd[19] = B3(sizelx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // the length of sub scanning (ESC A)
Shinya Kitaoka 120a6e
    cmd[20] = B0(sizely);
Shinya Kitaoka 120a6e
    cmd[21] = B1(sizely);
Shinya Kitaoka 120a6e
    cmd[22] = B2(sizely);
Shinya Kitaoka 120a6e
    cmd[23] = B3(sizely);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef GRAYTONES_USES_RGB
Shinya Kitaoka 120a6e
    cmd[24] = 0x13;  // scanning color (ESC C)
Shinya Kitaoka 120a6e
    cmd[25] = 0x08;  // data format (ESC D)
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    switch (params.getScanType()) {
Shinya Kitaoka 120a6e
    case TScannerParameters::BW:
Shinya Kitaoka 120a6e
      cmd[24] = 0x00;  // scanning BW/Gray (ESC C)
Toshihiro Shimizu 890ddd
#ifdef BW_USES_GRAYTONES
Shinya Kitaoka 120a6e
      cmd[25] = 0x08;  // data format (ESC D)
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
      cmd[25] = 0x01;  // data format (ESC D)
Shinya Kitaoka 120a6e
      break;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    case TScannerParameters::GR8:
Shinya Kitaoka 120a6e
      cmd[24] = 0x00;  // scanning BW/Gray (ESC C)
Shinya Kitaoka 120a6e
      cmd[25] = 0x08;  // data format (ESC D)
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    case TScannerParameters::RGB24:
Shinya Kitaoka 120a6e
      cmd[24] = 0x13;  // scanning color (ESC C)
Shinya Kitaoka 120a6e
      cmd[25] = 0x08;  // data format (ESC D)
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      throw TException("Unknown scanner mode");
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//  cmd[24] = (params.getScanType() == TScannerParameters::RGB24)?0x13:0x00;
Shinya Kitaoka 120a6e
//  //scanning color (ESC C)
Shinya Kitaoka 120a6e
//  cmd[25] = (params.getScanType() == TScannerParameters::RGB24)?0x08:0x08; //
Shinya Kitaoka 120a6e
//  data format (ESC D)
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (m_settingsMode == NEW_STYLE)
Shinya Kitaoka 120a6e
      cmd[26] = 0;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      cmd[26] = (params.m_paperFeeder.m_supported &&
Shinya Kitaoka 120a6e
                 (params.m_paperFeeder.m_value == 1.))
Shinya Kitaoka 120a6e
                    ? 0x01
Shinya Kitaoka 120a6e
                    : 0x00;  // option control (ESC e)
Shinya Kitaoka 120a6e
    cmd[27] = 0x00;          // scanning mode (ESC g)
Shinya Kitaoka 120a6e
    cmd[28] = 0xFF;          // the number of block line (ESC d)
Shinya Kitaoka 120a6e
    cmd[29] = 0x02;          // gamma (ESC Z)
Shinya Kitaoka 120a6e
    cmd[30] = brightness;    //  brightness (ESC L)
Shinya Kitaoka 120a6e
    cmd[31] = 0x80;          // color collection (ESC M)
Shinya Kitaoka 120a6e
    cmd[32] = 0x01;          // half toning processing (ESC B)
Shinya Kitaoka 120a6e
    cmd[33] = (unsigned char)params.m_threshold.m_value;  // threshold (ESC t)
Shinya Kitaoka 120a6e
    cmd[34] = 0x00;  // separate of area (ESC s)
Shinya Kitaoka 120a6e
    cmd[35] = 0x01;  // sharpness control (ESC Q)
Shinya Kitaoka 120a6e
    cmd[36] = 0x00;  // mirroring (ESC K)
Shinya Kitaoka 120a6e
    cmd[37] = 0x00;  // set film type (ESC N)
Shinya Kitaoka 120a6e
                     // other bytes should be set to 0x00 !
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_settingsMode == NEW_STYLE)
Shinya Kitaoka 120a6e
      if (params.m_paperFeeder.m_supported &&
Shinya Kitaoka 120a6e
          (params.m_paperFeeder.m_value == 1.)) {
Shinya Kitaoka 120a6e
        unsigned char v = (params.m_paperFeeder.m_value == 1.) ? 0x01 : 0x00;
Shinya Kitaoka 120a6e
        if (!ESCI_command_1b('e', v, true))
Shinya Kitaoka 120a6e
          throw TScannerExpection(notFatal, "Scanner error (un)loading paper");
Shinya Kitaoka 120a6e
        if (v) {
Shinya Kitaoka 120a6e
          unsigned char p = 0x19;
Shinya Kitaoka 120a6e
          bool status     = true;
Shinya Kitaoka 120a6e
          send(&p, 1);
Shinya Kitaoka 120a6e
          status = expectACK();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    unsigned char setParamCmd[2] = {0x1C, 0x57};
Shinya Kitaoka 120a6e
    int wrote                    = send(&setParamCmd[0], 2);
Shinya Kitaoka 120a6e
    if (wrote != 2)
Shinya Kitaoka 120a6e
      throw TScannerExpection(notFatal,
Shinya Kitaoka 120a6e
                              "Error setting scanner parameters - W -");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!expectACK()) {
Shinya Kitaoka 120a6e
      notFatal.push_back("Error setting scanner parameters - NAK on W -");
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    wrote = send(&cmd[0], 0x40);
Shinya Kitaoka 120a6e
    if (wrote != 0x40)
Shinya Kitaoka 120a6e
      throw TScannerExpection(notFatal,
Shinya Kitaoka 120a6e
                              "Error setting scanner parameters - D -");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!expectACK()) {
Shinya Kitaoka 120a6e
      notFatal.push_back("Error setting scanner parameters - NAK on D -");
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    // if here, everything is ok, exit from loop
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (retryCount <= 0)
Shinya Kitaoka 120a6e
    throw TScannerExpection(
Shinya Kitaoka 120a6e
        notFatal, "Error setting scanner parameters, too many retries");
Shinya Kitaoka 120a6e
  log("doSettings:OK");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::collectInformation(char *lev0, char *lev1,
Shinya Kitaoka 120a6e
                                       unsigned short *lowRes,
Shinya Kitaoka 120a6e
                                       unsigned short *hiRes,
Shinya Kitaoka 120a6e
                                       unsigned short *hMax,
Shinya Kitaoka 120a6e
                                       unsigned short *vMax) {
Shinya Kitaoka 120a6e
  log("collectInformation");
Shinya Kitaoka 120a6e
  unsigned char stx;
Shinya Kitaoka 120a6e
  int pos = 0;
Shinya Kitaoka 120a6e
  unsigned short counter;
Shinya Kitaoka 120a6e
  unsigned char status;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
if (!resetScanner())
Shinya Kitaoka 120a6e
throw TException("Scanner error resetting");
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  if (!ESCI_command('I', false))
Shinya Kitaoka 120a6e
    throw TException("Unable to get scanner info. Is it off ?");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unsigned long s = 4;  // 4 bytes cfr Identity Data Block on ESCI Manual!!!
Shinya Kitaoka 120a6e
  std::unique_ptr<unsigned char[]=""> buffer2 = ESCI_read_data2(s);</unsigned>
Shinya Kitaoka 120a6e
  if (!buffer2 || (s != 4)) throw TException("Error reading scanner info");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  memcpy(&stx, buffer2.get(), 1);
Shinya Kitaoka 120a6e
  memcpy(&counter, &(buffer2[2]), 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SWAPIT
Shinya Kitaoka 120a6e
  counter = swapUshort(counter);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  memcpy(&status, &(buffer2[1]), 1);
Shinya Kitaoka 120a6e
  std::ostrstream os;
Shinya Kitaoka 120a6e
  os.freeze(false);
Shinya Kitaoka 120a6e
  os << "stx = " << stx << " status = " << status << " counter=" << counter
Shinya Kitaoka 120a6e
     << '\n'
Shinya Kitaoka 120a6e
     << '\0';
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  s                                       = counter;
Shinya Kitaoka 120a6e
  std::unique_ptr<unsigned char[]=""> buffer = ESCI_read_data2(s);</unsigned>
Shinya Kitaoka 120a6e
  int len                                 = strlen((const char *)buffer.get());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*printf("Level %c%c", buffer[0], buffer[1]);*/
Shinya Kitaoka 120a6e
  if (len > 1) {
Shinya Kitaoka 120a6e
    *lev0 = buffer[0];
Shinya Kitaoka 120a6e
    *lev1 = buffer[1];
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  pos = 2;
Shinya Kitaoka 120a6e
  /* buffer[pos] contains 'R' */
Shinya Kitaoka 120a6e
  if (len < 3 || buffer[pos] != 'R') {
Shinya Kitaoka 120a6e
    *lev0   = '0';
Shinya Kitaoka 120a6e
    *lev1   = '0';
Shinya Kitaoka 120a6e
    *lowRes = 0;
Shinya Kitaoka 120a6e
    *hiRes  = 0;
Shinya Kitaoka 120a6e
    *vMax   = 0;
Shinya Kitaoka 120a6e
    *hMax   = 0;
Shinya Kitaoka 120a6e
    throw TException("unable to get information from scanner");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *lowRes = (buffer[pos + 2] * 256) + buffer[pos + 1];
Shinya Kitaoka 120a6e
  *hiRes  = *lowRes;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (buffer[pos] == 'R') {
Shinya Kitaoka 120a6e
    *hiRes = (buffer[pos + 2] * 256) + buffer[pos + 1];
Shinya Kitaoka 120a6e
    /*  printf("Resolution %c  %d", buffer[pos], *hiRes);*/
Shinya Kitaoka 120a6e
    pos += 3;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (buffer[pos] != 'A') {
Shinya Kitaoka 120a6e
    *lev0   = '0';
Shinya Kitaoka 120a6e
    *lev1   = '0';
Shinya Kitaoka 120a6e
    *lowRes = 0;
Shinya Kitaoka 120a6e
    *hiRes  = 0;
Shinya Kitaoka 120a6e
    *vMax   = 0;
Shinya Kitaoka 120a6e
    *hMax   = 0;
Shinya Kitaoka 120a6e
    throw TException("unable to get information from scanner");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  *hMax = (buffer[pos + 2] * 256) + buffer[pos + 1];
Shinya Kitaoka 120a6e
  *vMax = (buffer[pos + 4] * 256) + buffer[pos + 3];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ESCI_command('f', false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ESCI_readLineData2(stx, status, counter);
Shinya Kitaoka 120a6e
  if (status & FatalError)
Shinya Kitaoka 120a6e
    throw TException("Fatal error reading information from scanner");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  s      = counter;
Shinya Kitaoka 120a6e
  buffer = ESCI_read_data2(s);
Shinya Kitaoka 120a6e
  // name buffer+1A
Shinya Kitaoka 120a6e
  const char *name = (const char *)(buffer.get() + 0x1A);
Shinya Kitaoka 120a6e
  if (strncmp(name, "Perfection1640", strlen("Perfection1640"))) {
Shinya Kitaoka 120a6e
    m_settingsMode = NEW_STYLE;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    m_settingsMode = OLD_STYLE;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
scsi_new_d("ESCI_extended_status");
Toshihiro Shimizu 890ddd
scsi_len(42);
Toshihiro Shimizu 890ddd
/* main status*/
Toshihiro Shimizu 890ddd
scsi_b00(0, "push_button_supported", 0);
Toshihiro Shimizu 890ddd
scsi_b11(0, "warming_up", 0);
Toshihiro Shimizu 890ddd
scsi_b33(0, "adf_load_sequence", 0);  /* 1 from first sheet; 0 from last or not supp */
Toshihiro Shimizu 890ddd
scsi_b44(0, "both_sides_on_adf", 0);
Toshihiro Shimizu 890ddd
scsi_b55(0, "adf_installed_main_status", 0);
Toshihiro Shimizu 890ddd
scsi_b66(0, "NFlatbed", 0);   /*0 if scanner is flatbed else 1 */
Toshihiro Shimizu 890ddd
scsi_b77(0, "system_error", 0);
Toshihiro Shimizu 890ddd
/* adf status */
Toshihiro Shimizu 890ddd
scsi_b77(1, "adf_installed",0);
Toshihiro Shimizu 890ddd
/*... some other info.., refer to manual if needed*/
Toshihiro Shimizu 890ddd
/**/
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  m_hasADF = !!(buffer[1] & 0x80);
Shinya Kitaoka 120a6e
  log("collectInformation:OK");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::resetScanner() {
Shinya Kitaoka 120a6e
  log("resetScanner");
Shinya Kitaoka 120a6e
  bool ret = ESCI_command('@', true);
Shinya Kitaoka 120a6e
  log(std::string("resetScanner: ") + (ret ? "OK" : "FAILED"));
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TScannerEpson::receive(unsigned char *buffer, int size) {
Shinya Kitaoka 120a6e
  return m_scannerIO->receive(buffer, size);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TScannerEpson::send(unsigned char *buffer, int size) {
Shinya Kitaoka 120a6e
  return m_scannerIO->send(buffer, size);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TScannerEpson::sendACK() { return send(&ACK, 1); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::expectACK() {
Shinya Kitaoka 120a6e
  log("expectACK");
Shinya Kitaoka 120a6e
  unsigned char ack = NAK;
Shinya Kitaoka 120a6e
  int nb            = receive(&ack, 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  if (ack != ACK) {
Shinya Kitaoka 120a6e
    std::ostrstream os;
Shinya Kitaoka 120a6e
    os.freeze(false);
Shinya Kitaoka 120a6e
    os << "ack fails ret = 0x" << std::hex << (int)ack << '\n' << '\0';
Shinya Kitaoka 120a6e
    TSystem::outputDebug(os.str());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  log(std::string("expectACK: ") + (ack == ACK ? "ACK" : "FAILED"));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (ack == ACK);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
char *TScannerEpson::ESCI_inquiry(char cmd) /* returns 0 if failed */
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_command(char cmd, bool checkACK) {
Shinya Kitaoka 120a6e
  unsigned char p[2];
Shinya Kitaoka 120a6e
  p[0] = ESC;
Shinya Kitaoka 120a6e
  p[1] = cmd;
Shinya Kitaoka 120a6e
  bool status;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int count = send(&(p[0]), 2);
Shinya Kitaoka 120a6e
  status    = count == 2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (checkACK) status = expectACK();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_command_1b(char cmd, unsigned char p0, bool checkACK) {
Shinya Kitaoka 120a6e
  bool status = false;
Shinya Kitaoka 120a6e
  if (ESCI_command(cmd, checkACK)) {
Shinya Kitaoka 120a6e
    unsigned char p = p0;
Shinya Kitaoka 120a6e
    status          = true;
Shinya Kitaoka 120a6e
    send(&p, 1);
Shinya Kitaoka 120a6e
    if (checkACK) status = expectACK();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_command_2b(char cmd, unsigned char p0,
Shinya Kitaoka 120a6e
                                    unsigned char p1, bool checkACK) {
Shinya Kitaoka 120a6e
  bool status = false;
Shinya Kitaoka 120a6e
  if (ESCI_command(cmd, checkACK)) {
Shinya Kitaoka 120a6e
    status = true;
Shinya Kitaoka 120a6e
    unsigned char p[2];
Shinya Kitaoka 120a6e
    p[0]        = p0;
Shinya Kitaoka 120a6e
    p[1]        = p1;
Shinya Kitaoka 120a6e
    int timeout = 30000;
Shinya Kitaoka 120a6e
    send(&(p[0]), 2);
Shinya Kitaoka 120a6e
    if (checkACK) status = expectACK();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_command_2w(char cmd, unsigned short p0,
Shinya Kitaoka 120a6e
                                    unsigned short p1, bool checkACK) {
Shinya Kitaoka 120a6e
  bool status = false;
Shinya Kitaoka 120a6e
  if (ESCI_command(cmd, checkACK)) {
Shinya Kitaoka 120a6e
    status = true;
Shinya Kitaoka 120a6e
    unsigned short p[2];
Shinya Kitaoka 120a6e
    p[0]          = p0;
Shinya Kitaoka 120a6e
    p[1]          = p1;
Shinya Kitaoka 120a6e
    const int len = 1;
Shinya Kitaoka 120a6e
    int timeout   = 30000;
Shinya Kitaoka 120a6e
    send((unsigned char *)(&(p[0])), 4);
Shinya Kitaoka 120a6e
    if (checkACK) status = expectACK();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_command_4w(char cmd, unsigned short p0,
Shinya Kitaoka 120a6e
                                    unsigned short p1, unsigned short p2,
Shinya Kitaoka 120a6e
                                    unsigned short p3, bool checkACK) {
Shinya Kitaoka 120a6e
  bool status = false;
Shinya Kitaoka 120a6e
  if (ESCI_command(cmd, checkACK)) {
Shinya Kitaoka 120a6e
    status = true;
Shinya Kitaoka 120a6e
    unsigned char p[8];
Shinya Kitaoka 120a6e
    p[0] = (unsigned char)p0;
Shinya Kitaoka 120a6e
    p[1] = (unsigned char)(p0 >> 8);
Shinya Kitaoka 120a6e
    p[2] = (unsigned char)p1;
Shinya Kitaoka 120a6e
    p[3] = (unsigned char)(p1 >> 8);
Shinya Kitaoka 120a6e
    p[4] = (unsigned char)p2;
Shinya Kitaoka 120a6e
    p[5] = (unsigned char)(p2 >> 8);
Shinya Kitaoka 120a6e
    p[6] = (unsigned char)(p3);
Shinya Kitaoka 120a6e
    p[7] = (unsigned char)(p3 >> 8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    send((unsigned char *)&(p[0]), 8);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (checkACK) status = expectACK();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::unique_ptr<unsigned char[]=""> TScannerEpson::ESCI_read_data2(</unsigned>
Shinya Kitaoka 120a6e
    unsigned long &size) {
Shinya Kitaoka 120a6e
  std::unique_ptr<unsigned char[]=""> buffer(new unsigned char[size]);</unsigned>
Shinya Kitaoka 120a6e
  memset(buffer.get(), 0, size);
Shinya Kitaoka 120a6e
  unsigned long bytesToRead = size;
Shinya Kitaoka 120a6e
  size                      = receive(buffer.get(), bytesToRead);
Shinya Kitaoka 120a6e
  return buffer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TScannerEpson::ESCI_doADF(bool on) {
Shinya Kitaoka 120a6e
  // check ref esci documentation page 3-64
Shinya Kitaoka 120a6e
  unsigned char eject = 0x0c;
Shinya Kitaoka 120a6e
  int rc              = send(&eject, 1);
Shinya Kitaoka 120a6e
  bool status1        = expectACK();
Shinya Kitaoka 120a6e
  return status1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return 1;
Shinya Kitaoka 120a6e
  if (!ESCI_command_1b('e', 0x01, true)) {
Shinya Kitaoka 120a6e
    if (on)
Shinya Kitaoka 120a6e
      throw TException("Scanner error loading paper");
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      throw TException("Scanner error unloading paper");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  unsigned char p = on ? 0x19 : 0x0C;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  send(&p, 1);
Shinya Kitaoka 120a6e
  bool status = expectACK();
Shinya Kitaoka 120a6e
  return status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::scanArea2pix(const TScannerParameters ¶ms,
Shinya Kitaoka 120a6e
                                 unsigned short &offsetx,
Shinya Kitaoka 120a6e
                                 unsigned short &offsety,
Shinya Kitaoka 120a6e
                                 unsigned short &sizelx, unsigned short &sizely,
Shinya Kitaoka 120a6e
                                 const TRectD &scanArea) {
Shinya Kitaoka 120a6e
  const double f = 25.4;
Shinya Kitaoka 120a6e
  offsetx        = (unsigned short)((scanArea.x0 * params.m_dpi.m_value) / f);
Shinya Kitaoka 120a6e
  offsety        = (unsigned short)((scanArea.y0 * params.m_dpi.m_value) / f);
Shinya Kitaoka 120a6e
  sizelx =
Shinya Kitaoka 120a6e
      (unsigned short)(((scanArea.x1 - scanArea.x0) * params.m_dpi.m_value) /
Shinya Kitaoka 120a6e
                       f);
Shinya Kitaoka 120a6e
  sizelx = (sizelx >> 3) << 3;  // questo deve essere multiplo di 8
Shinya Kitaoka 120a6e
  sizely =
Shinya Kitaoka 120a6e
      (unsigned short)(((scanArea.y1 - scanArea.y0) * params.m_dpi.m_value) /
Shinya Kitaoka 120a6e
                       f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::ESCI_readLineData(unsigned char &stx, unsigned char &status,
Shinya Kitaoka 120a6e
                                      unsigned short &counter,
Shinya Kitaoka 120a6e
                                      unsigned short &lines, bool &areaEnd) {
Shinya Kitaoka 120a6e
  unsigned long s                         = 6;
Shinya Kitaoka 120a6e
  std::unique_ptr<unsigned char[]=""> buffer = ESCI_read_data2(s);</unsigned>
Shinya Kitaoka 120a6e
  if (!buffer) throw TException("Error reading scanner info");
Shinya Kitaoka 120a6e
  /* PACKET DATA LEN = 6
Shinya Kitaoka 120a6e
  type offs  descr
Shinya Kitaoka 120a6e
  byte  0    STX
Shinya Kitaoka 120a6e
  b77   1    fatal_error
Shinya Kitaoka 120a6e
  b66   1    not_ready
Shinya Kitaoka 120a6e
  b55   1    area_end
Shinya Kitaoka 120a6e
  b44   1    option_unit
Shinya Kitaoka 120a6e
  b33   1    col_attrib_bit_3
Shinya Kitaoka 120a6e
  b22   1    col_attrib_bit_2
Shinya Kitaoka 120a6e
  b11   1    extended_commands
Shinya Kitaoka 120a6e
  drow  2,   counter
Shinya Kitaoka 120a6e
  drow  4    lines
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  bool fatalError = !!(buffer[1] & 0x80);
Shinya Kitaoka 120a6e
  bool notReady   = !!(buffer[1] & 0x40);
Shinya Kitaoka 120a6e
  areaEnd         = !!(buffer[1] & 0x20);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  memcpy(&stx, buffer.get(), 1);
Shinya Kitaoka 120a6e
  memcpy(&counter, &(buffer[2]), 2);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef SWAPIT
Shinya Kitaoka 120a6e
  counter = swapUshort(counter);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  memcpy(&lines, &(buffer[4]), 2);
Toshihiro Shimizu 890ddd
#ifdef SWAPIT
Shinya Kitaoka 120a6e
  lines = swapUshort(lines);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  status = buffer[1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  std::ostrstream os;
Shinya Kitaoka 120a6e
  os.freeze(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << "fatal=" << fatalError;
Shinya Kitaoka 120a6e
  os << " notReady=" << notReady;
Shinya Kitaoka 120a6e
  os << " areaEnd=" << areaEnd;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << " stx=" << stx;
Shinya Kitaoka 120a6e
  os << " counter=" << counter;
Shinya Kitaoka 120a6e
  os << " lines=" << lines;
Shinya Kitaoka 120a6e
  os << '\n' << '\0';
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSystem::outputDebug(os.str());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TScannerEpson::ESCI_readLineData2(unsigned char &stx,
Shinya Kitaoka 120a6e
                                       unsigned char &status,
Shinya Kitaoka 120a6e
                                       unsigned short &counter) {
Shinya Kitaoka 120a6e
  unsigned long s                         = 4;
Shinya Kitaoka 120a6e
  std::unique_ptr<unsigned char[]=""> buffer = ESCI_read_data2(s);</unsigned>
Shinya Kitaoka 120a6e
  if (!buffer) throw TException("Error reading scanner info");
Shinya Kitaoka 120a6e
  bool fatalError = !!(buffer[1] & 0x80);
Shinya Kitaoka 120a6e
  bool notReady   = !!(buffer[1] & 0x40);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  memcpy(&stx, buffer.get(), 1);
Shinya Kitaoka 120a6e
  memcpy(&counter, &(buffer[2]), 2);
Toshihiro Shimizu 890ddd
#ifdef SWAPIT
Shinya Kitaoka 120a6e
  counter = swapUshort(counter);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  status = buffer[1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  std::ostrstream os;
Shinya Kitaoka 120a6e
  os.freeze(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << "fatal=" << fatalError;
Shinya Kitaoka 120a6e
  os << " notReady=" << notReady;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  os << " stx=" << stx;
Shinya Kitaoka 120a6e
  os << " counter=" << counter;
Shinya Kitaoka 120a6e
  os << '\n' << '\0';
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSystem::outputDebug(os.str());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}