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