/*************************************************************************** * Copyright � 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 #include #include #include #include #include #include "scn_config.h" #include "gscn_drv.h" #include "PublicFunc.h" #include "ImageApplyHeaders.h" //#include "ImageApplyCrop.h" //#include "ImageApplyAdjustColors.h" //#include "ImageApplyChannel.h" //#include "ImageApplyResize.h" //#include "ImageApplyRotation.h" //#include "ImageApplyDiscardBlank.h" #include "filetools.h" #include "hugaotwainds.h" extern ChugaotwaindsApp theApp; #ifdef TWH_CMP_MSC #include #elif __APPLE__ //#include #else //#ifdef TWH_CMP_MSC #include #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 #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(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,200,255,CV_THRESH_BINARY); StopWatch sw; sw.start(); threshold(mat,mat,200,255,CV_THRESH_BINARY); float kernel_data[] = { -0.1f, 0, 0, 0, -0.1f, 0, 0, 0, 0, 0, 0, 0, 1.5f, 0, 0, 0, 0, 0, 0, 0, -0.1f, 0, 0, 0, -0.1f }; Mat kernel(5, 5, CV_32FC1, kernel_data); filter2D(mat, mat, mat.depth(), kernel); //adaptiveThreshold(mat,mat,255,0,1,5,12); //bitwise_not(mat,mat); sw.stop(); double time=sw.time_run(); XdPrint("time eplesed :%f\n",time); //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> 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 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, CSize> dpiDct; static void initialDictionary() { //自适应 dpiDct.insert(pair,CSize>(pair((TwSS)None, 50.0),CSize(594, 898))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 75),CSize(892, 1347))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 100),CSize(1189, 1795))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 150),CSize(1784, 2693))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 200),CSize(2338, 3307))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 240), CSize(2854, 4308))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 300),CSize(3567, 5385))); dpiDct.insert(pair,CSize>(pair((TwSS)None, 400), CSize(4756, 7180) )); dpiDct.insert(pair,CSize>(pair((TwSS)None, 600), CSize(7134, 10770))); //A3 dpiDct.insert(pair,CSize>(pair(A3, 50), CSize(585, 827))); dpiDct.insert(pair,CSize>(pair(A3, 75), CSize(877, 1240))); dpiDct.insert(pair,CSize>(pair(A3, 100), CSize(1169, 1653))); dpiDct.insert(pair,CSize>(pair(A3, 150), CSize(1753, 2480))); dpiDct.insert(pair,CSize>(pair(A3, 200), CSize(2338, 3307))); dpiDct.insert(pair,CSize>(pair(A3, 240), CSize(2806, 3968) )); dpiDct.insert(pair,CSize>(pair(A3, 300), CSize(3507, 4960) )); dpiDct.insert(pair,CSize>(pair(A3, 400), CSize(4677, 6614) )); dpiDct.insert(pair,CSize>(pair(A3, 600), CSize(7015, 9921) )); //A4 dpiDct.insert(pair,CSize>(pair(A4, 50), CSize(413, 585) )); dpiDct.insert(pair,CSize>(pair(A4, 75), CSize(620, 877) )); dpiDct.insert(pair,CSize>(pair(A4, 100), CSize(826, 1169) )); dpiDct.insert(pair,CSize>(pair(A4, 150), CSize(1240, 1753) )); dpiDct.insert(pair,CSize>(pair(A4, 200), CSize(1653, 2338) )); dpiDct.insert(pair,CSize>(pair(A4, 240), CSize(1984, 2806) )); dpiDct.insert(pair,CSize>(pair(A4, 300), CSize(2480, 3507) )); dpiDct.insert(pair,CSize>(pair(A4, 400), CSize(3307, 4677) )); dpiDct.insert(pair,CSize>(pair(A4, 600), CSize(4960, 7015) )); //A4R dpiDct.insert(pair,CSize>(pair(A4R, 50), CSize(585, 413) )); dpiDct.insert(pair,CSize>(pair(A4R, 75), CSize(877, 620) )); dpiDct.insert(pair,CSize>(pair(A4R, 100), CSize(1169, 826) )); dpiDct.insert(pair,CSize>(pair(A4R, 150), CSize(1753, 1240) )); dpiDct.insert(pair,CSize>(pair(A4R, 200), CSize(2338,1653) )); dpiDct.insert(pair,CSize>(pair(A4R, 240), CSize(2806,1984) )); dpiDct.insert(pair,CSize>(pair(A4R, 300), CSize(3507,2480) )); dpiDct.insert(pair,CSize>(pair(A4R, 400), CSize(4677,3307) )); dpiDct.insert(pair,CSize>(pair(A4R, 600), CSize(7015,4960) )); //A5 dpiDct.insert(pair,CSize>(pair(A5, 50), CSize(291, 413) )); dpiDct.insert(pair,CSize>(pair(A5, 75), CSize(437, 620) )); dpiDct.insert(pair,CSize>(pair(A5, 100), CSize(582, 826) )); dpiDct.insert(pair,CSize>(pair(A5, 150), CSize(874, 1240) )); dpiDct.insert(pair,CSize>(pair(A5, 200), CSize(1165, 1653) )); dpiDct.insert(pair,CSize>(pair(A5, 240), CSize(1398, 1984) )); dpiDct.insert(pair,CSize>(pair(A5, 300), CSize(1748, 2480) )); dpiDct.insert(pair,CSize>(pair(A5, 400), CSize(2330, 3307) )); dpiDct.insert(pair,CSize>(pair(A5, 600), CSize(3496, 4960) )); //A5R dpiDct.insert(pair,CSize>(pair(A5R, 50), CSize(413, 291) )); dpiDct.insert(pair,CSize>(pair(A5R, 75), CSize(620, 437) )); dpiDct.insert(pair,CSize>(pair(A5R, 100), CSize(826, 582) )); dpiDct.insert(pair,CSize>(pair(A5R, 150), CSize(1240, 874) )); dpiDct.insert(pair,CSize>(pair(A5R, 200), CSize(1653, 1165) )); dpiDct.insert(pair,CSize>(pair(A5R, 240), CSize(1984, 1398) )); dpiDct.insert(pair,CSize>(pair(A5R, 300), CSize(2480, 1748) )); dpiDct.insert(pair,CSize>(pair(A5R, 400), CSize(3307, 2330) )); dpiDct.insert(pair,CSize>(pair(A5R, 600), CSize(4960, 3496) )); //A6 dpiDct.insert(pair,CSize>(pair(A6, 50), CSize(207, 291) )); dpiDct.insert(pair,CSize>(pair(A6, 75), CSize(310, 437) )); dpiDct.insert(pair,CSize>(pair(A6, 100), CSize(413, 582) )); dpiDct.insert(pair,CSize>(pair(A6, 150), CSize(620, 874) )); dpiDct.insert(pair,CSize>(pair(A6, 200), CSize(826, 1165) )); dpiDct.insert(pair,CSize>(pair(A6, 240), CSize(992, 1398) )); dpiDct.insert(pair,CSize>(pair(A6, 300), CSize(1240, 1748) )); dpiDct.insert(pair,CSize>(pair(A6, 400), CSize(1653, 2330) )); dpiDct.insert(pair,CSize>(pair(A6, 600), CSize(2480, 3496) )); //A6R dpiDct.insert(pair,CSize>(pair(A6R, 50), CSize(291, 207) )); dpiDct.insert(pair,CSize>(pair(A6R, 75), CSize(437, 310) )); dpiDct.insert(pair,CSize>(pair(A6R, 100), CSize(582, 413) )); dpiDct.insert(pair,CSize>(pair(A6R, 150), CSize(874, 620) )); dpiDct.insert(pair,CSize>(pair(A6R, 200), CSize(1165, 826) )); dpiDct.insert(pair,CSize>(pair(A6R, 240), CSize(1398, 992) )); dpiDct.insert(pair,CSize>(pair(A6R, 300), CSize(1748, 1240) )); dpiDct.insert(pair,CSize>(pair(A6R, 400), CSize(2330, 1653) )); dpiDct.insert(pair,CSize>(pair(A6R, 600), CSize(3496, 2480) )); //长文稿,2倍A3 dpiDct.insert(pair,CSize>(pair((TwSS)91, 50), CSize(585, 1653) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 75), CSize(877, 2480) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 100), CSize(1169, 1653*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 150), CSize(1753, 2480*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 200), CSize(2338, 3307*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 240), CSize(2806, 3968*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 300), CSize(3507, 4960*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 400), CSize(4677, 6614*2) )); dpiDct.insert(pair,CSize>(pair((TwSS)91, 600), CSize(7015, 9921*2) )); //B4 dpiDct.insert(pair,CSize>(pair(B4, 50), CSize(506, 717) )); dpiDct.insert(pair,CSize>(pair(B4, 75), CSize(759, 1075) )); dpiDct.insert(pair,CSize>(pair(B4, 100), CSize(1011, 1433) )); dpiDct.insert(pair,CSize>(pair(B4, 150), CSize(1517, 2149) )); dpiDct.insert(pair,CSize>(pair(B4, 200), CSize(2023, 2866) )); dpiDct.insert(pair,CSize>(pair(B4, 240), CSize(2428, 3439) )); dpiDct.insert(pair,CSize>(pair(B4, 300), CSize(3035, 4299) )); dpiDct.insert(pair,CSize>(pair(B4, 400), CSize(4047, 5732) )); dpiDct.insert(pair,CSize>(pair(B4, 600), CSize(6070, 8598) )); //B5 dpiDct.insert(pair,CSize>(pair(B5, 50), CSize(358, 506) )); dpiDct.insert(pair,CSize>(pair(B5, 75), CSize(537, 759) )); dpiDct.insert(pair,CSize>(pair(B5, 100), CSize(716, 1011) )); dpiDct.insert(pair,CSize>(pair(B5, 150), CSize(1074, 1517) )); dpiDct.insert(pair,CSize>(pair(B5, 200), CSize(1433, 2023) )); dpiDct.insert(pair,CSize>(pair(B5, 240), CSize(1719, 2428) )); dpiDct.insert(pair,CSize>(pair(B5, 300), CSize(2149, 3035) )); dpiDct.insert(pair,CSize>(pair(B5, 400), CSize(2866, 4047) )); dpiDct.insert(pair,CSize>(pair(B5, 600), CSize(4299, 6070) )); //B5R dpiDct.insert(pair,CSize>(pair(B5R, 50), CSize(506, 358) )); dpiDct.insert(pair,CSize>(pair(B5R, 75), CSize(759, 537) )); dpiDct.insert(pair,CSize>(pair(B5R, 100), CSize(1011, 716) )); dpiDct.insert(pair,CSize>(pair(B5R, 150), CSize(1517, 1075) )); dpiDct.insert(pair,CSize>(pair(B5R, 200), CSize(2023, 1433) )); dpiDct.insert(pair,CSize>(pair(B5R, 240), CSize(2428, 1719) )); dpiDct.insert(pair,CSize>(pair(B5R, 300), CSize(3035, 2149) )); dpiDct.insert(pair,CSize>(pair(B5R, 400), CSize(4047, 2866) )); dpiDct.insert(pair,CSize>(pair(B5R, 600), CSize(6070, 4299) )); //B6 dpiDct.insert(pair,CSize>(pair(B6, 50), CSize(252, 358) )); dpiDct.insert(pair,CSize>(pair(B6, 75), CSize(378, 537) )); dpiDct.insert(pair,CSize>(pair(B6, 100), CSize(503, 716) )); dpiDct.insert(pair,CSize>(pair(B6, 150), CSize(755, 1074) )); dpiDct.insert(pair,CSize>(pair(B6, 200), CSize(1007, 1433) )); dpiDct.insert(pair,CSize>(pair(B6, 240), CSize(1209, 1719) )); dpiDct.insert(pair,CSize>(pair(B6, 300), CSize(1511, 2149) )); dpiDct.insert(pair,CSize>(pair(B6, 400), CSize(2015, 2866) )); dpiDct.insert(pair,CSize>(pair(B6, 600), CSize(3023, 4299) )); //B6R dpiDct.insert(pair,CSize>(pair(B6R, 50), CSize(358, 252) )); dpiDct.insert(pair,CSize>(pair(B6R, 75), CSize(537, 378) )); dpiDct.insert(pair,CSize>(pair(B6R, 100), CSize(716, 503) )); dpiDct.insert(pair,CSize>(pair(B6R, 150), CSize(1074, 755) )); dpiDct.insert(pair,CSize>(pair(B6R, 200), CSize(1433, 1007) )); dpiDct.insert(pair,CSize>(pair(B6R, 240), CSize(1719, 1209) )); dpiDct.insert(pair,CSize>(pair(B6R, 300), CSize(2149, 1511) )); dpiDct.insert(pair,CSize>(pair(B6R, 400), CSize(2866, 2015) )); dpiDct.insert(pair,CSize>(pair(B6R, 600), CSize(4299, 3023) )); //DOUBLE LETTER dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 50), CSize(550, 850) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 75), CSize(825, 1275) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 100), CSize(1100, 1700) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 150), CSize(1650, 2550) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 200), CSize(2200, 3400) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 240), CSize(2640, 4080) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 300), CSize(3300, 5100) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 400), CSize(4400, 6800) )); dpiDct.insert(pair,CSize>(pair(DOUBLELetter, 600), CSize(6600, 10200) )); //LETTER dpiDct.insert(pair,CSize>(pair(USLetter, 50), CSize(425, 550) )); dpiDct.insert(pair,CSize>(pair(USLetter, 75), CSize(638, 825) )); dpiDct.insert(pair,CSize>(pair(USLetter, 100), CSize(850, 1100) )); dpiDct.insert(pair,CSize>(pair(USLetter, 150), CSize(1275, 1650) )); dpiDct.insert(pair,CSize>(pair(USLetter, 200), CSize(1700, 2200) )); dpiDct.insert(pair,CSize>(pair(USLetter, 240), CSize(2040, 2640) )); dpiDct.insert(pair,CSize>(pair(USLetter, 300), CSize(2550, 3300) )); dpiDct.insert(pair,CSize>(pair(USLetter, 400), CSize(3400, 4400) )); dpiDct.insert(pair,CSize>(pair(USLetter, 600), CSize(5100, 6600) )); //LETTERR dpiDct.insert(pair,CSize>(pair(USLetterR, 50), CSize(550, 425) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 75), CSize(825, 638) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 100), CSize(1100, 850) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 150), CSize(1650, 1275) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 200), CSize(2200, 1700) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 240), CSize(2640, 2040) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 300), CSize(3300, 2550) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 400), CSize(4400, 3400) )); dpiDct.insert(pair,CSize>(pair(USLetterR, 600), CSize(6600, 5100) )); //LETTERR dpiDct.insert(pair,CSize>(pair(USLegal, 50), CSize(425, 700) )); dpiDct.insert(pair,CSize>(pair(USLegal, 75), CSize(638, 1050) )); dpiDct.insert(pair,CSize>(pair(USLegal, 100), CSize(850, 1400) )); dpiDct.insert(pair,CSize>(pair(USLegal, 150), CSize(1275, 2100) )); dpiDct.insert(pair,CSize>(pair(USLegal, 200), CSize(1700, 2800) )); dpiDct.insert(pair,CSize>(pair(USLegal, 240), CSize(2040, 3360) )); dpiDct.insert(pair,CSize>(pair(USLegal, 300), CSize(2550, 4200) )); dpiDct.insert(pair,CSize>(pair(USLegal, 400), CSize(3400, 5600) )); dpiDct.insert(pair,CSize>(pair(USLegal, 600), CSize(5100, 8400) )); } static CSize getSize(TwSS paperType, float dpi,int orentation=0) { CSize retSize; map, CSize>::iterator iter; iter = dpiDct.find(pair(paperType,dpi)); if(iter != dpiDct.end()){ if(orentation==0) retSize = (*iter).second; else { CSize size; size.cx = iter->second.cy; size.cy = iter->second.cx; return size; } 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(); InitMSGMap(); #ifdef G300 g_drv.open(0x3072, 0x300); #elif defined G400 g_drv.open(0x3072, 0x400); #else g_drv.open(0x064B, 0x7823); #endif // G300 } ////////////////////////////////////////////////////////////////////////////// CScanner_FreeImage::~CScanner_FreeImage() { //g_drv.reset(); } void CScanner_FreeImage::InitMSGMap() { if (ntcMsg.size()>0){ ntcMsg.clear(); } ntcMsg[COUNT_MODE]=StringToUtf("计数模式,请先退出计数模式!"); ntcMsg[NO_FEED]=StringToUtf("无纸,请放置纸张!"); ntcMsg[OPEN_COVER]=StringToUtf("扫描仪开盖!"); ntcMsg[FEED_IN_ERROR]=StringToUtf("拾纸错误!"); ntcMsg[PAPER_JAM]=StringToUtf("卡纸!"); ntcMsg[DETECT_DOUBLE_FEED]=StringToUtf("双张!"); ntcMsg[DETECT_STAPLE]=StringToUtf("订书针!"); ntcMsg[PAPER_SKEW]=StringToUtf("纸张歪斜!"); ntcMsg[HARDWARE_ERROR]=StringToUtf("硬件错误!"); ntcMsg[PC_SCAN_BUSY_or_ERROR]=StringToUtf("PC错误!"); } ////////////////////////////////////////////////////////////////////////////// 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; } //static bool isreported; ////////////////////////////////////////////////////////////////////////////// bool CScanner_FreeImage::acquireImage(bool bscan) { //if (g_drv.IsConnected()) //{ // g_drv.run(); //} if (bscan) { if (getDeviceOnline()) { UpdateList(); g_drv.setlist(m_iaList); g_drv.SetIsDuplex(m_bDuplex); hgConfigClass cf; cf.setDoubleFeedEnable(m_HardWareParams.DoubleFeederOn); cf.setResolution(200.0); #ifdef G200 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; } #endif // G200 g_drv.ResetScanner();//初始化DSP状态 cf.setStapleEnable(m_HardWareParams.StapleDetectOn); cf.setTwPixelType(m_HardWareParams.PixType); cf.settwSS(m_HardWareParams.PaperType); #ifndef G200 #ifdef G300 cf.setDstHeight_G400((getSize(TwSS::A4, 200.0f, m_wRotation).cy + 200) / 100); #else cf.setDstHeight_G400((getSize((TwSS)m_HardWareParams.PaperType, m_HardWareParams.Resolution,m_wRotation).cy+200)/100); #endif // G300 cf.setReversed_G400(0, 0); cf.setIsCorrect_G400(true); #endif // !G200 UINT32 cfg_Value =cf.GetData(); //cfg_Value = 9307488; USBCB usbcb = { CONFIGURED_DATA , cfg_Value,0 }; g_drv.set_decompress_pix_type(m_HardWareParams.PixType); g_drv.Config_Scanner(&usbcb); g_drv.run(); g_drv.Scanner_StartScan(m_wScanCount); //isreported=false; } else { std::string cvt=StringToUtf("请检查电源或USB通信是否正常!"); std::string notify=StringToUtf("提示"); MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),(TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_SYSTEMMODAL|MB_OK| MB_ICONINFORMATION); return false; } } #ifdef HW_VER m_matDib.release(); UINT32 ret = g_drv.aquire_image(m_matDib); if (ret!=0) { std::string notify=StringToUtf("提示"); MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),(TCHAR*)ntcMsg[ret].c_str(),(TCHAR*)notify.c_str(),MB_SYSTEMMODAL|MB_ICONINFORMATION|MB_OK); g_drv.Set_ErrorCode(0); return false; } 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; } if (m_bMultiOutput) { if (m_matDib.channels()==3) { m_nPixelType=TWPT_RGB; } else { m_nPixelType=TWPT_GRAY; } } //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_OutHole.EnOutHole) { m_iaList.push_back(shared_ptr(new CImageOutHole(50.0,m_OutHole.OutHoleRatio/100.0,50))); } CSize fixedSize = getSize((TwSS)m_HardWareParams.PaperType, 200.0f); m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(m_bAutoCrop, m_bAutoDeskew, m_bFillBlackRect,cv::Size(fixedSize.cx, fixedSize.cy),true))); if (m_bAutoDiscardBlank || m_bAutoDiscardBlankInvoice) { m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(m_bAutoDiscardBlank ? true : false))); } if(m_HardWareParams.PixType != 0) { m_iaList.push_back(shared_ptr(new CImageApplySharpen())); } //filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b if (m_nFilter != 3 || m_nEnhance_color) { int channel = 0; //filter none r g b enhance none r g b if (m_nFilter != 3) { channel = m_nFilter; } else { channel = m_nEnhance_color + 3; } m_iaList.push_back(shared_ptr(new CImageApplyChannel(static_cast(channel)))); } if (m_fBrightness!=0||m_fContrast!=0||m_fGamma!=1.0) { //double aa = (254.0 / 2000.0) * m_fBrightness + 0.5; //int bright = ceil(aa);//[-127,128] 0.128=256.0/2000.0 int contrast = (int)(m_fContrast / 333.0);//[-36,36] 0.036=72.0/2000.0; m_iaList.push_back(shared_ptr(new CImageApplyAdjustColors(m_fBrightness, contrast, m_fGamma))); } if (m_HardWareParams.PixType == 0) //threshold m_iaList.push_back(shared_ptr(new CImageApplyBWBinaray(CImageApplyBWBinaray::THRESH_BINARY))); if (m_fXResolution!=200.0) { CImageApplyResize* apply; if (m_bAutoCrop) { double ratio = m_fXResolution / 200.0; apply = new CImageApplyResize(CImageApplyResize::RATIO, cv::Size(0, 0), ratio, ratio); } else { CSize dSize = getSize((TwSS)m_HardWareParams.PaperType, m_fXResolution); apply = new CImageApplyResize(CImageApplyResize::DSIZE, cv::Size(dSize.cx, dSize.cy), 1.0, 1.0); } m_iaList.push_back(shared_ptr< CImageApply>(apply)); } if (m_wRotation!=0||m_bBackRotate180) { m_iaList.push_back(shared_ptr(new CImageApplyRotation((CImageApplyRotation::RotationType)m_wRotation,m_bBackRotate180, m_fXResolution, "C:/Windows/twain_32/HuaGoScan/tessdata/"))); //CImageApplyRotation::RotationType type; //if (m_wRotation > 89.0f && m_wRotation < 91.0f) // type = CImageApplyRotation::RotationType::Rotate_90_clockwise; //else if (m_wRotation > 269.0f && m_wRotation < 271.0f) // type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise; //else if (m_wRotation > 179.0f && m_wRotation < 181.0f) // type = CImageApplyRotation::RotationType::Rotate_180; //else // type = CImageApplyRotation::RotationType::Invalid; //if (is_autotext) //type = CImageApplyRotation::RotationType::AutoTextOrientation; //m_iaList.push_back(shared_ptr(new CImageApplyRotation(type, m_bBackRotate180, m_fXResolution, "C:/Windows/twain_32/HuaGoScan/tessdata/"))); } } ////////////////////////////////////////////////////////////////////////////// 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() &&(g_drv.get_ErrorCode() == 0)) { //FileTools::write_log("D:/1.txt","!g_drv.is_scan()&&g_drv.Get_IsImageQueueEmpty()"); m_nDocCount=0; } else { //FileTools::write_log("D:/1.txt","!g_drv.is_scan() m_nDocCount=1;"); m_nDocCount=1; ret=false; } //XdPrint("m_nDocCount %d\n",m_nDocCount); return ret; }