twain2/hugaotwainds/CScanner_FreeImage.cpp

888 lines
32 KiB
C++
Raw Normal View History

/***************************************************************************
* Copyright <EFBFBD> 2007 TWAIN Working Group:
* Adobe Systems Incorporated, AnyDoc Software Inc., Eastman Kodak Company,
* Fujitsu Computer Products of America, JFL Peripheral Solutions Inc.,
* Ricoh Corporation, and Xerox Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the TWAIN Working Group nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TWAIN Working Group ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TWAIN Working Group BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
***************************************************************************/
/**
* @file CScanner_FreeImage.cpp
* Defines a scanner.
* Create a virtual scanner.
* @author TWAIN Working Group
* @date April 2007
*/
#include "stdafx.h"
#include "CScanner_FreeImage.h"
#include <iostream>
#include <time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "scn_config.h"
#include "gscn_drv.h"
#include "PublicFunc.h"
#include "AutoCrop.h"
#include "ImageAdjustColors.h"
#include "ImageChannel.h"
#include "ImageApplyResize.h"
#include "ImageRotation.h"
#include "ImageProcDiscardBlank.h"
#ifdef TWH_CMP_MSC
#include <io.h>
#elif __APPLE__
//#include <io.h>
#else //#ifdef TWH_CMP_MSC
#include <sys/io.h>
#endif //#ifdef TWH_CMP_MSC
#ifdef TWNDS_OS_LINUX
#define kTWAIN_DS_DIR "/usr/local/lib/twain/sample2"
#endif
#include "DSMInterface.h"
using namespace std;
#ifdef TWNDS_OS_APPLE
#include "CoreFoundation/CoreFoundation.h"
#include "CoreFoundation/CFBundle.h"
#include "CoreFoundation/CFURL.h"
#include <Carbon/Carbon.h>
#endif
/**
* Environment vars to get the Xfer Count. Create this enviroment Varable on your system to simulate the
* number of pages sitting in the scanner waiting to be scanned.
*/
#define kGETENV_XFERCOUNT "CAP_XFERCOUNT"
#ifdef TWH_CMP_MSC
extern HINSTANCE g_hinstance;
#endif
class ImageTranferMat : public ImageTransfer
{
public:
ImageTranferMat(cv::Mat& mat):m_mat(mat)
{
//imwrite("Gray.bmp",mat);
}
virtual ~ImageTranferMat(){}
virtual unsigned char* getLineBits(int line = 0)
{
return m_mat.ptr<BYTE>(line);
}
virtual int step()
{
return m_mat.step1();
}
virtual int bpp()
{
return m_mat.elemSize()*8;
}
virtual int width()
{
return m_mat.cols;
}
virtual int height()
{
return m_mat.rows;
}
private:
cv::Mat m_mat;
};
class ImageTranferBW : public ImageTransfer
{
public:
ImageTranferBW(cv::Mat& mat)
{
threshold(mat,mat,128.0,255.0,CV_THRESH_BINARY);
//imwrite("threshold.bmp",mat);
m_width = mat.cols;
m_height = mat.rows;
//!< 生成图像
m_buffer = new unsigned char[height()*step()];
memset(m_buffer,0,height()*step());
unsigned char* binary = m_buffer;
int n_lineByte = (m_width + 7) >> 3;
unsigned char * imageData = mat.data;
unsigned char temp;
for(int row = 0 ; row<m_height; row++)
{
for(int col =0; col < m_width; col++ )
{
int pos = col % 8;
int pix = *(imageData+ row * mat.step1() + col);
temp = 1 << (7 - pos );
if( pix == 255 )
{
*(binary+row*m_lineByte + col /8) |= temp;
}
else
{
*(binary+row*m_lineByte + col / 8 ) &= (~temp);
}
}
}
}
virtual ~ImageTranferBW()
{
if(m_buffer != NULL)
{
delete[] m_buffer;
}
}
virtual unsigned char* getLineBits(int line = 0)
{
return m_buffer+step()*line;
}
virtual int step()
{
int n_lineByte = (m_width + 7) >> 3;
m_lineByte = ((n_lineByte * 8 + 31)>>5)<<2 ;
return m_lineByte;
}
virtual int bpp()
{
return 1;
}
virtual int width()
{
return m_width;
}
virtual int height()
{
return m_height;
}
private:
unsigned char* m_buffer;
int m_width;
int m_height;
int m_lineByte;
};
static std::map<int, SIZE> sizeS;
#define TWSS_A4R 60
enum TwSS : ushort
{
None = 0,
A4Letter = 1,
A4 = 1,
B5Letter = 2,
JISB5 = 2,
B5 = 2,
USLetter = 3,
USLegal = 4,
A5 = 5,
B4 = 6,
ISOB4 = 6,
B6 = 7,
ISOB6 = 7,
USLedger = 9,
USExecutive = 10,
A3 = 11,
B3 = 12,
ISOB3 = 12,
A6 = 13,
C4 = 14,
C5 = 15,
C6 = 16,
_4A0 = 17,
_2A0 = 18,
A0 = 19,
A1 = 20,
A2 = 21,
A7 = 22,
A8 = 23,
A9 = 24,
A10 = 25,
ISOB0 = 26,
ISOB1 = 27,
ISOB2 = 28,
ISOB5 = 29,
ISOB7 = 30,
ISOB8 = 31,
ISOB9 = 32,
ISOB10 = 33,
JISB0 = 34,
JISB1 = 35,
JISB2 = 36,
JISB3 = 37,
JISB4 = 38,
JISB6 = 39,
JISB7 = 40,
JISB8 = 41,
JISB9 = 42,
JISB10 = 43,
C0 = 44,
C1 = 45,
C2 = 46,
C3 = 47,
C7 = 48,
C8 = 49,
C9 = 50,
C10 = 51,
USStatement = 52,
BusinessCard = 53,
A4R = 60,
A5R = 61,
A6R = 62,
B5R = 70,
B6R = 71,
USLetterR = 80,
DOUBLELetter = 81,
AUTO = 90
};
static map<pair<TwSS, float>, CSize> dpiDct;
static void initialDictionary()
{
//自适应
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 50.0),CSize(594, 898)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 75),CSize(892, 1347)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 100),CSize(1189, 1795)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 150),CSize(1784, 2693)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 200),CSize(2338, 3307)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 240), CSize(2854, 4308)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 300),CSize(3567, 5385)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 400), CSize(4756, 7180) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)90, 600), CSize(7134, 10770)));
//A3
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 50), CSize(585, 827)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 75), CSize(877, 1240)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 100), CSize(1169, 1653)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 150), CSize(1753, 2480)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 200), CSize(2338, 3307)));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 240), CSize(2806, 3968) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 300), CSize(3507, 4960) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 400), CSize(4677, 6614) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A3, 600), CSize(7015, 9921) ));
//A4
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 50), CSize(413, 585) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 75), CSize(620, 877) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 100), CSize(826, 1169) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 150), CSize(1240, 1753) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 200), CSize(1653, 2338) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 240), CSize(1984, 2806) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 300), CSize(2480, 3507) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 400), CSize(3307, 4677) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4, 600), CSize(4960, 7015) ));
//A4R
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 50), CSize(585, 413) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 75), CSize(877, 620) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 100), CSize(1169, 826) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 150), CSize(1753, 1240) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 200), CSize(2338,1653) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 240), CSize(2806,1984) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 300), CSize(3507,2480) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 400), CSize(4677,3307) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A4R, 600), CSize(7015,4960) ));
//A5
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 50), CSize(291, 413) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 75), CSize(437, 620) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 100), CSize(582, 826) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 150), CSize(874, 1240) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 200), CSize(1165, 1653) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 240), CSize(1398, 1984) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 300), CSize(1748, 2480) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 400), CSize(2330, 3307) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5, 600), CSize(3496, 4960) ));
//A5R
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 50), CSize(413, 291) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 75), CSize(620, 437) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 100), CSize(826, 582) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 150), CSize(1240, 874) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 200), CSize(1653, 1165) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 240), CSize(1984, 1398) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 300), CSize(2480, 1748) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 400), CSize(3307, 2330) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A5R, 600), CSize(4960, 3496) ));
//A6
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 50), CSize(207, 291) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 75), CSize(310, 437) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 100), CSize(413, 582) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 150), CSize(620, 874) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 200), CSize(826, 1165) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 240), CSize(992, 1398) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 300), CSize(1240, 1748) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 400), CSize(1653, 2330) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6, 600), CSize(2480, 3496) ));
//A6R
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 50), CSize(291, 207) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 75), CSize(437, 310) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 100), CSize(582, 413) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 150), CSize(874, 620) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 200), CSize(1165, 826) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 240), CSize(1398, 992) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 300), CSize(1748, 1240) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 400), CSize(2330, 1653) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(A6R, 600), CSize(3496, 2480) ));
//长文稿2倍A3
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 50), CSize(585, 1653) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 75), CSize(877, 2480) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 100), CSize(1169, 1653*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 150), CSize(1753, 2480*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 200), CSize(2338, 3307*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 240), CSize(2806, 3968*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 300), CSize(3507, 4960*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 400), CSize(4677, 6614*2) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>((TwSS)91, 600), CSize(7015, 9921*2) ));
//B4
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 50), CSize(506, 717) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 75), CSize(759, 1075) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 100), CSize(1011, 1433) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 150), CSize(1517, 2149) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 200), CSize(2023, 2866) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 240), CSize(2428, 3439) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 300), CSize(3035, 4299) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 400), CSize(4047, 5732) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B4, 600), CSize(6070, 8598) ));
//B5
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 50), CSize(358, 506) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 75), CSize(537, 759) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 100), CSize(716, 1011) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 150), CSize(1074, 1517) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 200), CSize(1433, 2023) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 240), CSize(1719, 2428) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 300), CSize(2149, 3035) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 400), CSize(2866, 4047) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5, 600), CSize(4299, 6070) ));
//B5R
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 50), CSize(506, 358) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 75), CSize(759, 537) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 100), CSize(1011, 716) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 150), CSize(1517, 1075) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 200), CSize(2023, 1433) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 240), CSize(2428, 1719) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 300), CSize(3035, 2149) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 400), CSize(4047, 2866) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B5R, 600), CSize(6070, 4299) ));
//B6
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 50), CSize(252, 358) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 75), CSize(378, 537) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 100), CSize(503, 716) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 150), CSize(755, 1074) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 200), CSize(1007, 1433) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 240), CSize(1209, 1719) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 300), CSize(1511, 2149) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 400), CSize(2015, 2866) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6, 600), CSize(3023, 4299) ));
//B6R
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 50), CSize(358, 252) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 75), CSize(537, 378) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 100), CSize(716, 503) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 150), CSize(1074, 755) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 200), CSize(1433, 1007) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 240), CSize(1719, 1209) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 300), CSize(2149, 1511) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 400), CSize(2866, 2015) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(B6R, 600), CSize(4299, 3023) ));
//DOUBLE LETTER
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 50), CSize(550, 850) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 75), CSize(825, 1275) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 100), CSize(1100, 1700) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 150), CSize(1650, 2550) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 200), CSize(2200, 3400) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 240), CSize(2640, 4080) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 300), CSize(3300, 5100) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 400), CSize(4400, 6800) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(DOUBLELetter, 600), CSize(6600, 10200) ));
//LETTER
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 50), CSize(425, 550) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 75), CSize(638, 825) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 100), CSize(850, 1100) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 150), CSize(1275, 1650) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 200), CSize(1700, 2200) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 240), CSize(2040, 2640) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 300), CSize(2550, 3300) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 400), CSize(3400, 4400) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetter, 600), CSize(5100, 6600) ));
//LETTERR
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 50), CSize(550, 425) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 75), CSize(825, 638) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 100), CSize(1100, 850) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 150), CSize(1650, 1275) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 200), CSize(2200, 1700) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 240), CSize(2640, 2040) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 300), CSize(3300, 2550) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 400), CSize(4400, 3400) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLetterR, 600), CSize(6600, 5100) ));
//LETTERR
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 50), CSize(425, 700) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 75), CSize(638, 1050) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 100), CSize(850, 1400) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 150), CSize(1275, 2100) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 200), CSize(1700, 2800) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 240), CSize(2040, 3360) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 300), CSize(2550, 4200) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 400), CSize(3400, 5600) ));
dpiDct.insert(pair<pair<TwSS,float>,CSize>(pair<TwSS,float>(USLegal, 600), CSize(5100, 8400) ));
}
static CSize getSize(TwSS paperType, float dpi)
{
CSize retSize;
map<pair<TwSS, float>, CSize>::iterator iter;
iter = dpiDct.find(pair<TwSS, float>(paperType,dpi));
if(iter != dpiDct.end()){
retSize = (*iter).second;
return retSize;
}
return CSize(2338, 3307);
}
GScn_Drv g_drv;
//////////////////////////////////////////////////////////////////////////////
CScanner_FreeImage::CScanner_FreeImage() :
// m_pDIB(0),
m_nScanLine(0),
m_bReadOnly(false),
m_nDestBytesPerRow(0),
m_nRowOffset(0),
m_nDocCount(0),
m_nSourceWidth(0),
m_nSourceHeight(0)
{
memset(m_szSourceImagePath, 0, PATH_MAX);
initialDictionary();
// set default caps
resetScanner();
g_drv.open(0x064B, 0x7823);
}
//////////////////////////////////////////////////////////////////////////////
CScanner_FreeImage::~CScanner_FreeImage()
{
//g_drv.reset();
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::resetScanner()
{
bool bret = true;
// Unlock the scanner
Unlock();
m_nScanLine = 0;
m_nDestBytesPerRow = 0;
m_nRowOffset = 0;
m_nDocCount = m_nMaxDocCount = getDocumentCount();// Reloaded the scanner with paper
m_nPixelType = TWPT_RGB;
m_nPaperSource = SFI_PAPERSOURCE_ADF;
m_bDuplex = false;
m_fXResolution = 200.0;
m_fYResolution = 200.0;
if (g_drv.Get_IsImageQueueEmpty()!=0)
{
g_drv.reset();
}
return bret;
}
//////////////////////////////////////////////////////////////////////////////
SFreeImage* CScanner_FreeImage::getSetting() const
{
return (SFreeImage*)this;
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::acquireImage(bool bscan)
{
if (g_drv.IsConnected())
{
g_drv.run();
}
if (bscan)
{
if (getDeviceOnline())
{
while (!isPaperOn())
{
std::string cvt=StringToUtf("纸仓内无纸,请放纸!");
std::string notify=StringToUtf("提示");
int res= MessageBox(NULL, cvt.c_str(),notify.c_str(), MB_OKCANCEL | MB_ICONINFORMATION);
switch (res)
{
case IDCANCEL:
return false;
}
}
UpdateList();
g_drv.setlist(m_iaList);
hgConfigClass cf;
cf.setDoubleFeedEnable(m_HardWareParams.DoubleFeederOn);
cf.setResolution(200.0);
cf.setSkewDelection(m_HardWareParams.SkrewDetectOn);
switch (m_HardWareParams.SkrewDetectLevel)
{
case 1:
cf.setSkewLevel0bit(false);
cf.setSkewLevel1bit(false);
cf.setSkewLevel2bit(false);
break;
case 2:
cf.setSkewLevel0bit(true);
cf.setSkewLevel1bit(false);
cf.setSkewLevel2bit(false);
break;
case 3:
cf.setSkewLevel0bit(false);
cf.setSkewLevel1bit(true);
cf.setSkewLevel2bit(false);
break;
case 4:
cf.setSkewLevel0bit(true);
cf.setSkewLevel1bit(true);
cf.setSkewLevel2bit(false);
break;
case 5:
cf.setSkewLevel0bit(false);
cf.setSkewLevel1bit(false);
cf.setSkewLevel2bit(true);
break;
default:
break;
}
cf.setStapleEnable(m_HardWareParams.StapleDetectOn);
cf.setTwPixelType(m_HardWareParams.PixType);
cf.settwSS(m_HardWareParams.PaperType);
UINT32 cfg_Value =cf.GetData();
USBCB usbcb = { CONFIGURED_DATA , cfg_Value,0 };
g_drv.set_decompress_pix_type(m_HardWareParams.PixType);
g_drv.Config_Scanner(&usbcb);
g_drv.Scanner_StartScan(m_bDuplex?m_wScanCount/2:m_wScanCount);
}
else
{
std::string cvt=StringToUtf("请检查电源或USB通信是否正常!");
std::string notify=StringToUtf("提示");
MyMessageBox((TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_OK| MB_ICONINFORMATION);
return false;
}
}
#ifdef HW_VER
m_matDib.release();
int ret = g_drv.aquire_image(m_matDib);
//imwrite("1.bmp",m_matDib);
if (ret)
{
cout << "ds: Failed - could not acquire image" << endl;
return false;
}
#endif
if (m_matDib.empty())
{
cout << "ds: Failed - could not acquire image" << endl;
return false;
}
//Document scanned, remove it from simulated intray
m_nDocCount--;
// do whatever tranforms to the scanned image that was requested by the app
// before the image is sent to the app.
if (false == preScanPrep())
{
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::preScanPrep()
{
m_nRight = m_nSourceWidth = m_matDib.cols;
m_nBottom = m_nSourceHeight = m_matDib.rows;
m_nLeft = 0;
m_nTop = 0;
switch (m_nPixelType)
{
case TWPT_BW:
m_nDestBytesPerRow = BYTES_PERLINE(m_nSourceWidth, 1);
m_nRowOffset = BYTES_PERLINE(0, 1);
//m_imageTrans.reset(new ImageTranferBW(m_matDib));
m_imageTrans.reset(new ImageTranferBW(m_matDib));
break;
case TWPT_GRAY:
m_nDestBytesPerRow = BYTES_PERLINE(m_nSourceWidth, 8);
m_nRowOffset = BYTES_PERLINE(0, 8);
//m_imageTrans.reset(new ImageTranferMat(m_matDib));
m_imageTrans.reset(new ImageTranferMat(m_matDib));
break;
case TWPT_RGB:
m_nDestBytesPerRow = BYTES_PERLINE(m_nSourceWidth, 24);
m_nRowOffset = BYTES_PERLINE(0, 24);
//m_imageTrans.reset(new ImageTranferMat(m_matDib));
m_imageTrans.reset(new ImageTranferMat(m_matDib));
break;
}
// setup some convenience vars because they are used during
// every strip request
m_nScanLine = 0;
//XdPrint("m_nDestBytesPerRow = %d, m_nSourceWidth = %d\n", m_nDestBytesPerRow, m_nSourceWidth);
return true;
}
//////////////////////////////////////////////////////////////////////////////
// We want to simulate getting a scan form a scanner.
// if a size larger than the paper is scanned then there will be black on the bottom
// and to the right of the image. We want to transfer the image top to bottom,
// the black will be transfered after the image if neccessary.
bool CScanner_FreeImage::getScanStrip(BYTE *pTransferBuffer, DWORD dwRead, DWORD &dwReceived)
{
dwReceived = 0;
if (NULL == pTransferBuffer || // Invalid paramiter
dwRead < m_nDestBytesPerRow) // Need enough memory to transfer at least an entire row
{
return false;
}
BYTE *pBits = NULL;
int nRow = 0;
int nMaxRows = dwRead / m_nDestBytesPerRow; //number of rows to be transfered during this call (function of buffer size and line size)
DWORD step = (DWORD)m_imageTrans->step();
//XdPrint("step = %d, image width = %d\n", step, m_matDib.cols);
m_nScanLine = 0;
if (m_nScanLine < m_nSourceHeight)
{
//fill the buffer line by line to take care of alignment differences
for (nRow = 0; nRow < nMaxRows; nRow++)
{
//get the next scan line position and copy it
pBits = m_imageTrans->getLineBits(m_nScanLine);
memcpy(pTransferBuffer, pBits + m_nRowOffset, MIN(m_nDestBytesPerRow, step));
// Check to see if the result image width is wider than what we have.
// If it is wider fill it in with 0es
if (m_nDestBytesPerRow > step)
{
memset(pTransferBuffer + step, 0, m_nDestBytesPerRow - step);
}
//increment the destination by the aligned line size
pTransferBuffer += m_nDestBytesPerRow;
// increment the current scanline for next pass
m_nScanLine++;
//update the number of bytes written
dwReceived += m_nDestBytesPerRow;
// check for finished scan
if (m_nScanLine >= m_nSourceHeight)
{
//we are done early
break;
}
}
}
// Check to see if the result image length is longer than we have.
// If it is longer fill it in with 0es
//if (m_nBottom > m_nScanLine)
//{
// nMaxRows = (WORD)((dwRead - dwReceived) / m_nDestBytesPerRow);
// memset(pTransferBuffer, 0, m_nDestBytesPerRow * nMaxRows);
// m_nScanLine += nMaxRows;
// dwReceived += m_nDestBytesPerRow * nMaxRows;
//}
return true;
}
///////////////////////////////////////////////////////////////////////////////
void CScanner_FreeImage::UpdateList(bool canUpdate/*=true*/)
{
m_iaList.clear();
if (m_bAutoDiscardBlank||m_bAutoDiscardBlankInvoice)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageProcDiscardBlank(m_bAutoDiscardBlank?true:false)));
}
m_iaList.push_back(shared_ptr<CImageApply>(new CAutoCrop(m_bFillBlackRect, m_bAutoDeskew, m_bAutoCrop,getSize((TwSS)m_HardWareParams.PaperType,m_fXResolution),getSize((TwSS)m_HardWareParams.PaperType,200.0))));
if (m_nFilter)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageChannel(m_nFilter)));
}
if (m_fBrightness!=0||m_fContrast!=0||m_fGamma!=1.0)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageAdjustColors(m_fBrightness, m_fContrast, m_fGamma)));
}
if (m_fXResolution!=200.0)
{
m_iaList.push_back(ImageApplyPtr(new CImageApplyResize(200.0,m_fXResolution,m_bAutoCrop,getSize((TwSS)m_HardWareParams.PaperType,m_fXResolution))));
}
if (m_wRotation!=0||m_bBackRotate180)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageRotation(m_wRotation,m_bBackRotate180)));
}
g_drv.SetIsDuplex(m_bDuplex);
}
//////////////////////////////////////////////////////////////////////////////
short CScanner_FreeImage::getDocumentCount() const
{
// Simulate the number of pages sitting in the scanner.
int nCount = 1;
// Read this value from the environment. This will allow the simulation
// of a sheet feeder.
// If the value is <= 0, then a random number of pages will be scanned, else
// the exact number will be used.
char szCount[10];
memset(szCount, 0, sizeof(szCount));
if (0 != SGETENV(szCount, sizeof(szCount), kGETENV_XFERCOUNT))
{
// something found, convert it to an int
nCount = atoi(szCount);
if (nCount <= 0)
{
srand(int(time(0)));
nCount = rand();
nCount = nCount % 15;// upto 15 pages
}
}
return nCount;
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::isFeederLoaded()
{
//bool rtn = true;
bool rtn=g_drv.Get_Scanner_PaperOn();
return rtn;
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::getDeviceOnline() const
{
//MessageBox(NULL,g_drv.IsConnected()?"true":"false","aa",MB_OK);
return g_drv.IsConnected();
}
//////////////////////////////////////////////////////////////////////////////
std::string CScanner_FreeImage::getSerialNum() const
{
return g_drv.GetSerialNum();
}
//////////////////////////////////////////////////////////////////////////////
std::string CScanner_FreeImage::getFWVersion() const
{
return g_drv.GetFWVersion();
}
///////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::StopScan()
{
g_drv.Stop_scan();
if (g_drv.is_scan())
{
Sleep(100);
}
g_drv.reset();//清空图像队列
return g_drv.Get_IsImageQueueEmpty();
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::isPaperOn() const
{
return g_drv.Get_Scanner_PaperOn();
}
bool CScanner_FreeImage::isImageQueueEmpty()
{
bool ret=true;
if (!g_drv.is_scan()&&g_drv.Get_IsImageQueueEmpty())
{
m_nDocCount=0;
}
else
{
m_nDocCount=1;
ret=false;
}
//XdPrint("m_nDocCount %d\n",m_nDocCount);
return ret;
}