code_app/sdk/webservice/ManagerV2.cpp

3113 lines
79 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ManagerV2.h"
#include "base/HGBuffer.h"
#include "base/HGBase64.h"
#include "base/HGUtility.h"
#include "base/HGIni.h"
#include "base/HGInfo.h"
#include "base/HGTime.h"
#include "imgfmt/HGJpeg.h"
#include "imgfmt/HGOfd.h"
#include "imgfmt/HGPdf.h"
#include "imgfmt/HGTiff.h"
#include "imgfmt/HGImgFmt.h"
#include "imgproc/HGOCR.h"
#include "imgproc/HGImgProc.h"
#include "HGString.h"
extern "C"
{
#include "zip.h"
};
#include <curl/curl.h>
#include <list>
#include <algorithm>
namespace ver_2
{
static bool MainTableSort(const std::pair<int, std::string> &pr1, const std::pair<int, std::string> &pr2)
{
return pr1.first < pr2.first;
}
static bool BatchTableSort(const std::pair<int, int>& pr1, const std::pair<int, int>& pr2)
{
return pr1.second < pr2.second;
}
ManagerV2::ManagerV2(HGMsgPump msgPump)
: Manager(msgPump)
{
HGBase_CreateLock(&m_lock);
HGChar docsPath[256];
HGBase_GetDocumentsPath(docsPath, 256);
HGChar procName[256];
HGBase_GetProcessName(procName, 256);
HGChar defSavePath[256];
sprintf(defSavePath, "%s%s/", docsPath, procName);
m_globalCfg.fileSavePath = GetCfgStringValue("global", "fileSavePath", defSavePath);
m_globalCfg.fileNamePrefix = GetCfgStringValue("global", "fileNamePrefix", "Huago");
m_globalCfg.fileNameMode = GetCfgStringValue("global", "fileNameMode", "date_time");
m_globalCfg.imageFormat = GetCfgStringValue("global", "imageFormat", "jpg");
m_globalCfg.imageJpegQuality = GetCfgIntValue("global", "imageJpegQuality", 80);
m_globalCfg.imageTiffCompression = GetCfgStringValue("global", "imageTiffCompression", "lzw");
m_globalCfg.imageTiffJpegQuality = GetCfgIntValue("global", "imageTiffJpegQuality", 80);
m_globalCfg.uploadHttpHost = GetCfgStringValue("global", "uploadHttpHost", "");
m_globalCfg.uploadHttpPort = GetCfgIntValue("global", "uploadHttpPort", 80);
m_globalCfg.uploadHttpPath = GetCfgStringValue("global", "uploadHttpPath", "/upload.cgi");
m_globalCfg.uploadFtpUser = GetCfgStringValue("global", "uploadFtpUser", "");
m_globalCfg.uploadFtpPassword = GetCfgStringValue("global", "uploadFtpPassword", "");
m_globalCfg.uploadFtpHost = GetCfgStringValue("global", "uploadFtpHost", "");
m_globalCfg.uploadFtpPort = GetCfgIntValue("global", "uploadFtpPort", 21);
m_globalCfg.fileSavePath.push_back('/');
HGChar stdSavePath[256];
HGBase_StandardiseFileName(m_globalCfg.fileSavePath.c_str(), stdSavePath, 256);
m_globalCfg.fileSavePath = stdSavePath;
LoadSaveFilePathList(m_saveFilePathList);
m_saneEvent = NULL;
m_saneParam = NULL;
m_saneImageCallback = NULL;
m_saneImageParam = NULL;
m_initDevice = false;
m_devNameList.clear();
m_openDevice = false;
m_devName.clear();
m_devHandle = NULL;
m_devParam.Reset();
m_scanning = false;
m_scanEvent = NULL;
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "imageMgr.db");
m_sqlite = NULL;
sqlite3_open_v2(cfgPath, &m_sqlite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
if (NULL != m_sqlite)
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "open database success");
int ret = sqlite3_exec(m_sqlite, "create table table_ (id integer primary key autoincrement, name text)", NULL, NULL, NULL);
if (0 == ret)
{
ret = sqlite3_exec(m_sqlite, "create table 'table_default' (id integer primary key autoincrement, idx integer, format text, tag text, image blob)", NULL, NULL, NULL);
assert(0 == ret);
ret = sqlite3_exec(m_sqlite, "insert into table_ (name) values ('default')", NULL, NULL, NULL);
assert(0 == ret);
}
std::vector<std::pair<int, std::string>> tables;
char** result = NULL;
int rows, cols;
ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
assert(0 == ret && rows > 0 && cols == 2);
for (int i = 0; i < rows; i++)
{
std::pair<int, std::string> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("name", result[j]))
{
pr.second = result[(i + 1) * cols + j];
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
assert(!tables.empty());
std::sort(tables.begin(), tables.end(), MainTableSort);
m_currBatchId = tables[tables.size() - 1].second;
}
}
ManagerV2::~ManagerV2()
{
std::string errInfo;
DeinitDevice(errInfo);
if (NULL != m_sqlite)
{
sqlite3_close_v2(m_sqlite);
m_sqlite = NULL;
}
HGBase_DestroyLock(m_lock);
m_lock = NULL;
}
void ManagerV2::CloseDev(const CloseDevParam* param)
{
assert(NULL != param && this == param->mgr);
if (m_devName == param->devName)
{
std::string errInfo;
CloseDevice(errInfo);
}
}
void ManagerV2::ScanFinish(const ScanFinishParam* param)
{
assert(NULL != param && this == param->mgr);
std::string errInfo;
StopScan(errInfo);
}
void ManagerV2::SetSaneEvent(SaneEvent event, void* param)
{
assert(NULL != event && NULL != param);
HGBase_EnterLock(m_lock);
m_saneEvent = event;
m_saneParam = param;
HGBase_LeaveLock(m_lock);
}
void ManagerV2::SetSaneImageCallback(SaneImageCallback func, void* param)
{
assert(NULL != func && NULL != param);
HGBase_EnterLock(m_lock);
m_saneImageCallback = func;
m_saneImageParam = param;
HGBase_LeaveLock(m_lock);
}
void ManagerV2::ResetSaneEvent()
{
HGBase_EnterLock(m_lock);
m_saneEvent = NULL;
m_saneParam = NULL;
HGBase_LeaveLock(m_lock);
}
void ManagerV2::ResetSaneImageCallback()
{
HGBase_EnterLock(m_lock);
m_saneImageCallback = NULL;
m_saneImageParam = NULL;
HGBase_LeaveLock(m_lock);
}
int ManagerV2::SetGlobalConfig(const GlobalConfig& cfg, HGUInt mask, std::string& errInfo)
{
errInfo = "参数错误";
if ((mask & GlobalConfig::fileSavePathMask) && cfg.fileSavePath.empty())
return -1;
if ((mask & GlobalConfig::fileNameModeMask) && ("date_time" != cfg.fileNameMode && "random" != cfg.fileNameMode))
return -1;
if ((mask & GlobalConfig::imageFormatMask) && ("jpg" != cfg.imageFormat && "bmp" != cfg.imageFormat && "png" != cfg.imageFormat && "tif" != cfg.imageFormat
&& "pdf" != cfg.imageFormat && "ofd" != cfg.imageFormat && "ocr-pdf" != cfg.imageFormat && "ocr-ofd" != cfg.imageFormat))
return -1;
if ((mask & GlobalConfig::imageJpegQualityMask) && (cfg.imageJpegQuality < 0 || cfg.imageJpegQuality > 100))
return -1;
if ((mask & GlobalConfig::imageTiffCompressionMask) && ("none" != cfg.imageTiffCompression && "lzw" != cfg.imageTiffCompression
&& "jpeg" != cfg.imageTiffCompression && "ccitt-g4" != cfg.imageTiffCompression))
return -1;
if ((mask & GlobalConfig::imageTiffJpegQualityMask) && (cfg.imageTiffJpegQuality < 0 || cfg.imageTiffJpegQuality > 100))
return -1;
HGBase_EnterLock(m_lock);
if (mask & GlobalConfig::fileSavePathMask)
{
std::string fileSavePath = cfg.fileSavePath;
fileSavePath.push_back('/');
HGChar stdFileSavePath[256];
HGBase_StandardiseFileName(fileSavePath.c_str(), stdFileSavePath, 256);
m_globalCfg.fileSavePath = stdFileSavePath;
SetCfgStringValue("global", "fileSavePath", m_globalCfg.fileSavePath);
}
if (mask & GlobalConfig::fileNamePrefixMask)
{
m_globalCfg.fileNamePrefix = cfg.fileNamePrefix;
SetCfgStringValue("global", "fileNamePrefix", m_globalCfg.fileNamePrefix);
}
if (mask & GlobalConfig::fileNameModeMask)
{
m_globalCfg.fileNameMode = cfg.fileNameMode;
SetCfgStringValue("global", "fileNameMode", m_globalCfg.fileNameMode);
}
if (mask & GlobalConfig::imageFormatMask)
{
m_globalCfg.imageFormat = cfg.imageFormat;
SetCfgStringValue("global", "imageFormat", m_globalCfg.imageFormat);
}
if (mask & GlobalConfig::imageJpegQualityMask)
{
m_globalCfg.imageJpegQuality = cfg.imageJpegQuality;
SetCfgIntValue("global", "imageJpegQuality", m_globalCfg.imageJpegQuality);
}
if (mask & GlobalConfig::imageTiffCompressionMask)
{
m_globalCfg.imageTiffCompression = cfg.imageTiffCompression;
SetCfgStringValue("global", "imageTiffCompression", m_globalCfg.imageTiffCompression);
}
if (mask & GlobalConfig::imageTiffJpegQualityMask)
{
m_globalCfg.imageTiffJpegQuality = cfg.imageTiffJpegQuality;
SetCfgIntValue("global", "imageTiffJpegQuality", m_globalCfg.imageTiffJpegQuality);
}
if (mask & GlobalConfig::uploadHttpHostMask)
{
m_globalCfg.uploadHttpHost = cfg.uploadHttpHost;
SetCfgStringValue("global", "uploadHttpHost", m_globalCfg.uploadHttpHost);
}
if (mask & GlobalConfig::uploadHttpPortMask)
{
m_globalCfg.uploadHttpPort = cfg.uploadHttpPort;
SetCfgIntValue("global", "uploadHttpPort", m_globalCfg.uploadHttpPort);
}
if (mask & GlobalConfig::uploadHttpPathMask)
{
m_globalCfg.uploadHttpPath = cfg.uploadHttpPath;
SetCfgStringValue("global", "uploadHttpPath", m_globalCfg.uploadHttpPath);
}
if (mask & GlobalConfig::uploadFtpUserMask)
{
m_globalCfg.uploadFtpUser = cfg.uploadFtpUser;
SetCfgStringValue("global", "uploadFtpUser", m_globalCfg.uploadFtpUser);
}
if (mask & GlobalConfig::uploadFtpPasswordMask)
{
m_globalCfg.uploadFtpPassword = cfg.uploadFtpPassword;
SetCfgStringValue("global", "uploadFtpPassword", m_globalCfg.uploadFtpPassword);
}
if (mask & GlobalConfig::uploadFtpHostMask)
{
m_globalCfg.uploadFtpHost = cfg.uploadFtpHost;
SetCfgStringValue("global", "uploadFtpHost", m_globalCfg.uploadFtpHost);
}
if (mask & GlobalConfig::uploadFtpPortMask)
{
m_globalCfg.uploadFtpPort = cfg.uploadFtpPort;
SetCfgIntValue("global", "uploadFtpPort", m_globalCfg.uploadFtpPort);
}
HGBase_LeaveLock(m_lock);
errInfo.clear();
return 0;
}
int ManagerV2::GetGlobalConfig(GlobalConfig& cfg, std::string& errInfo)
{
cfg = m_globalCfg;
errInfo.clear();
return 0;
}
int ManagerV2::LoadLocalImage(const std::string& imagePath, std::string& imgBase64, std::string& errInfo)
{
imgBase64.clear();
errInfo = "错误";
HGUInt imgType = 0;
HGImgFmt_GetImgFmtType(imagePath.c_str(), &imgType);
if (0 == imgType)
return -1;
int ret = LoadBase64(imagePath, imgBase64);
if (0 != ret)
return ret;
std::string prefix = "data:image/jpeg;base64,";
if (HGIMGFMT_TYPE_BMP == imgType)
prefix = "data:image/bmp;base64,";
else if (HGIMGFMT_TYPE_PNG == imgType)
prefix = "data:image/png;base64,";
else if (HGIMGFMT_TYPE_TIFF == imgType)
prefix = "data:image/tiff;base64,";
else if (HGIMGFMT_TYPE_PDF == imgType)
prefix = "data:image/pdf;base64,";
else if (HGIMGFMT_TYPE_OFD == imgType)
prefix = "data:image/ofd;base64,";
imgBase64.insert(0, prefix);
errInfo.clear();
return 0;
}
int ManagerV2::SaveLocalImage(const std::string& imgBase64, std::string& imagePath, std::string& errInfo)
{
imagePath.clear();
errInfo = "错误";
size_t pos = imgBase64.find(',');
if (std::string::npos == pos)
return -1;
std::string prefix = imgBase64.substr(0, pos + 1);
std::string suffix = "jpg";
if ("data:image/bmp;base64," == prefix)
suffix = "bmp";
else if ("data:image/png;base64," == prefix)
suffix = "png";
else if ("data:image/tiff;base64," == prefix)
suffix = "tif";
else if ("data:image/pdf;base64," == prefix)
suffix = "pdf";
else if ("data:image/ofd;base64," == prefix)
suffix = "ofd";
std::string imagePath2 = GetFilePath(suffix);
int ret = SaveBase64(imgBase64.c_str() + pos + 1, imagePath2);
if (0 != ret)
return ret;
imagePath = imagePath2;
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(imagePath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
errInfo.clear();
return 0;
}
int ManagerV2::DeleteLocalFile(const std::string& filePath, std::string& errInfo)
{
int ret = -1;
errInfo = "错误";
HGBase_EnterLock(m_lock);
for (int i = 0; i < (int)m_saveFilePathList.size(); ++i)
{
if (filePath == m_saveFilePathList[i])
{
if (HGBASE_ERR_OK == HGBase_DeleteFile(filePath.c_str()))
{
m_saveFilePathList.erase(m_saveFilePathList.begin() + i);
errInfo.clear();
ret = 0;
}
break;
}
}
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
return ret;
}
int ManagerV2::ClearGlobalFileSavePath(std::string& errInfo)
{
HGBase_EnterLock(m_lock);
int i = 0;
while (i < (int)m_saveFilePathList.size())
{
HGChar path[256];
HGBase_GetFilePath(m_saveFilePathList[i].c_str(), path, 256);
if (0 == strcmp(path, m_globalCfg.fileSavePath.c_str()))
{
if (HGBASE_ERR_OK == HGBase_DeleteFile(m_saveFilePathList[i].c_str()))
{
m_saveFilePathList.erase(m_saveFilePathList.begin() + i);
}
else
{
++i;
}
}
else
{
++i;
}
}
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
HGBase_DeleteDir(m_globalCfg.fileSavePath.c_str());
errInfo.clear();
return 0;
}
int ManagerV2::MergeLocalImage(const std::vector<std::string>& imagePathList, const std::string& mode,
const std::string& align, int interval, std::string& outImagePath, std::string& errInfo)
{
outImagePath.clear();
errInfo = "错误";
if (imagePathList.empty() || interval < 0)
return -1;
if ("horz" == mode)
{
if ("top" != align && "bottom" != align && "center" != align)
return -1;
}
else if ("vert" == mode)
{
if ("left" != align && "right" != align && "center" != align)
return -1;
}
else
{
return -1;
}
HGUInt width = 0, height = 0;
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGImgFmtLoadInfo loadInfo;
if (HGBASE_ERR_OK == HGImgFmt_LoadImage(imagePathList[i].c_str(), 0, &loadInfo, 0, 0, NULL))
{
if ("horz" == mode)
{
if (0 != width)
width += interval;
width += loadInfo.width;
if (loadInfo.height > height)
height = loadInfo.height;
}
else
{
if (0 != height)
height += interval;
height += loadInfo.height;
if (loadInfo.width > width)
width = loadInfo.width;
}
}
}
HGImage outImage = NULL;
HGBase_CreateImage(width, height, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &outImage);
if (NULL == outImage)
return -1;
HGImageInfo outImageInfo;
HGBase_GetImageInfo(outImage, &outImageInfo);
HGByte *outImageData = NULL;
HGBase_GetImageData(outImage, &outImageData);
memset(outImageData, 255, outImageInfo.widthStep * outImageInfo.height);
HGUInt start = 0;
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGImage img = NULL;
HGImgFmt_LoadImage(imagePathList[i].c_str(), 0, NULL, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
HGImageInfo imgInfo;
HGBase_GetImageInfo(img, &imgInfo);
if (0 != start)
start += interval;
HGImageRoi outImageRoi;
if ("horz" == mode)
{
outImageRoi.left = start;
outImageRoi.top = 0;
if ("bottom" == align)
outImageRoi.top = height - imgInfo.height;
else if ("center" == align)
outImageRoi.top = (height - imgInfo.height) / 2;
start += imgInfo.width;
}
else
{
outImageRoi.left = 0;
if ("right" == align)
outImageRoi.left = width - imgInfo.width;
else if ("center" == align)
outImageRoi.left = (width - imgInfo.width) / 2;
outImageRoi.top = start;
start += imgInfo.height;
}
outImageRoi.right = outImageRoi.left + imgInfo.width;
outImageRoi.bottom = outImageRoi.top + imgInfo.height;
HGBase_SetImageROI(outImage, &outImageRoi);
HGBase_CopyImage(img, outImage);
HGBase_ResetImageROI(outImage);
HGBase_DestroyImage(img);
}
}
int ret = SaveImage(outImage, outImagePath);
if (0 == ret)
{
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(outImagePath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
errInfo.clear();
}
HGBase_DestroyImage(outImage);
return ret;
}
int ManagerV2::LocalMakeMultiImage(const std::vector<std::string>& imagePathList, const std::string& format,
const std::string& tiffCompression, int tiffJpegQuality, std::string& outImagePath, std::string& errInfo)
{
outImagePath.clear();
errInfo = "错误";
if (imagePathList.empty())
return -1;
if ("tif" != format && "pdf" != format && "ofd" != format)
return -1;
if ("none" != tiffCompression && "lzw" != tiffCompression && "jpeg" != tiffCompression
&& "ccitt-g4" != tiffCompression)
return -1;
if (tiffJpegQuality < 0 || tiffJpegQuality > 100)
return -1;
int ret = -1;
std::string outImagePath2 = GetFilePath(format);
HGImgFmtWriter writer = NULL;
HGImgFmt_OpenImageWriter(outImagePath2.c_str(), 0, &writer);
if (NULL != writer)
{
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGImage img = NULL;
HGImgFmt_LoadImage(imagePathList[i].c_str(), 0, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
HGImgFmtSaveInfo saveInfo;
saveInfo.jpegQuality = 80;
saveInfo.tiffJpegQuality = tiffJpegQuality;
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
if ("none" == tiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
else if ("jpeg" == tiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_JPEG;
else if ("ccitt-g4" == tiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_CCITTFAX4;
if (HGBASE_ERR_OK == HGImgFmt_SaveImageToWriter(writer, img, &saveInfo))
{
errInfo.clear();
ret = 0;
}
HGBase_DestroyImage(img);
}
}
HGImgFmt_CloseImageWriter(writer);
}
if (0 != ret)
{
HGBase_DeleteFile(outImagePath2.c_str());
return ret;
}
outImagePath = outImagePath2;
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(outImagePath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
return ret;
}
int ManagerV2::SplitLocalImage(const std::string& imagePath, const std::string& mode, int location,
std::vector<std::string>& outImagePathList, std::string& errInfo)
{
outImagePathList.clear();
errInfo = "错误";
if (imagePath.empty() || location < 0)
return -1;
if ("horz" != mode && "vert" != mode)
return -1;
int ret = -1;
HGImage image = NULL;
HGImgFmt_LoadImage(imagePath.c_str(), 0, NULL, 0, HGBASE_IMGORIGIN_TOP, &image);
{
HGImageInfo imageInfo;
HGBase_GetImageInfo(image, &imageInfo);
for (int i = 0; i < 2; ++i)
{
HGImageRoi imageRoi;
if ("horz" == mode)
{
imageRoi.top = 0;
imageRoi.bottom = imageInfo.height;
if (0 == i)
{
imageRoi.left = 0;
imageRoi.right = (HGUInt)location;
}
else
{
imageRoi.left = (HGUInt)location;
imageRoi.right = imageInfo.width;
}
}
else
{
imageRoi.left = 0;
imageRoi.right = imageInfo.width;
if (0 == i)
{
imageRoi.top = 0;
imageRoi.bottom = (HGUInt)location;
}
else
{
imageRoi.top = (HGUInt)location;
imageRoi.bottom = imageInfo.height;
}
}
if (HGBASE_ERR_OK == HGBase_SetImageROI(image, &imageRoi))
{
HGImage img = NULL;
HGBase_CloneImage(image, 0, 0, &img);
if (NULL != img)
{
std::string imgPath;
if (0 == SaveImage(img, imgPath))
{
outImagePathList.push_back(imgPath);
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(imgPath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
errInfo.clear();
ret = 0;
}
HGBase_DestroyImage(img);
}
HGBase_ResetImageROI(image);
}
}
HGBase_DestroyImage(image);
}
return ret;
}
int ManagerV2::LocalMakeZipFile(const std::vector<std::string>& filePathList, std::string& outZipPath, std::string& errInfo)
{
outZipPath.clear();
errInfo = "错误";
if (filePathList.empty())
return -1;
std::string outZipPath2 = GetFilePath("zip");
int error = 0;
zip* z = zip_open(StdStringToUtf8(outZipPath2).c_str(), ZIP_CREATE | ZIP_TRUNCATE, &error);
if (NULL == z)
{
return -1;
}
int ret = -1;
for (int i = 0; i < (int)filePathList.size(); ++i)
{
zip_source_t* s = zip_source_file(z, StdStringToUtf8(filePathList[i]).c_str(), 0, 0);
if (NULL != s)
{
HGChar name[256];
HGBase_GetFileName(filePathList[i].c_str(), name, 256);
if (zip_file_add(z, StdStringToUtf8(name).c_str(), s, ZIP_FL_OVERWRITE) >= 0)
{
errInfo.clear();
ret = 0;
}
else
{
zip_source_free(s);
}
}
}
zip_close(z);
z = NULL;
if (0 != ret)
{
HGBase_DeleteFile(outZipPath2.c_str());
return ret;
}
outZipPath = outZipPath2;
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(outZipPath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
return ret;
}
int ManagerV2::LocalImageDeskew(const std::string& imagePath, std::string& outImagePath, std::string& errInfo)
{
outImagePath.clear();
errInfo = "错误";
if (imagePath.empty())
return -1;
int ret = -1;
HGImage image = NULL;
HGImgFmt_LoadImage(imagePath.c_str(), 0, NULL, 0, HGBASE_IMGORIGIN_TOP, &image);
if (NULL != image)
{
HGImage img = NULL;
HGImgProc_ImageAutoCrop(image, HGTRUE, HGTRUE, HGTRUE, NULL, 0, 0, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
if (0 == SaveImage(img, outImagePath))
{
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(outImagePath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
errInfo.clear();
ret = 0;
}
HGBase_DestroyImage(img);
}
HGBase_DestroyImage(image);
}
return ret;
}
int ManagerV2::UploadLocalFile(const std::string& filePath, const std::string& mode, const std::string& remoteFilePath, std::string& errInfo)
{
errInfo = "错误";
if (filePath.empty() || remoteFilePath.empty())
return -1;
if ("http" != mode && "ftp" != mode)
return -1;
int ret = -1;
if ("http" == mode)
{
ret = HttpUpload(m_globalCfg.uploadHttpHost, m_globalCfg.uploadHttpPort, m_globalCfg.uploadHttpPath,
filePath, remoteFilePath);
}
else
{
ret = FtpUpload(m_globalCfg.uploadFtpUser, m_globalCfg.uploadFtpPassword, m_globalCfg.uploadFtpHost,
m_globalCfg.uploadFtpPort, filePath, remoteFilePath);
}
if (0 == ret)
errInfo.clear();
return ret;
}
int ManagerV2::InitDevice(std::string& errInfo)
{
errInfo = "错误";
if (m_initDevice)
return -1;
SANE_Int version_code = 0;
if (SANE_STATUS_GOOD != sane_init_ex(&version_code, sane_ex_callback, this))
{
return -1;
}
m_initDevice = true;
errInfo.clear();
return 0;
}
int ManagerV2::DeinitDevice(std::string& errInfo)
{
errInfo = "错误";
if (!m_initDevice)
return -1;
std::string errInfo2;
CloseDevice(errInfo2);
sane_exit();
m_devNameList.clear();
m_initDevice = false;
errInfo.clear();
return 0;
}
bool ManagerV2::IsDeviceInit()
{
return m_initDevice;
}
int ManagerV2::GetDeviceNameList(std::vector<std::string>& deviceNameList, std::string& errInfo)
{
deviceNameList.clear();
errInfo = "错误";
if (!m_initDevice)
return -1;
HGBase_EnterLock(m_lock);
deviceNameList = m_devNameList;
HGBase_LeaveLock(m_lock);
errInfo.clear();
return 0;
}
int ManagerV2::OpenDevice(const std::string& deviceName, std::string& errInfo)
{
errInfo = "错误";
if (!m_initDevice || m_openDevice)
return -1;
SANE_Handle dev = NULL;
SANE_Status status = sane_open(deviceName.c_str(), &dev);
if (SANE_STATUS_GOOD != status)
return -1;
// 从配置文件加载devParam
DeviceParam devParam;
LoadDeviceParam(deviceName, devParam);
// 设置devParam到设备
SetParamToDevice(dev, devParam, 0xFFFFFFFF);
// 从设备获取并设置m_devParam
GetParamFromDevice(dev, m_devParam);
// 保存到配置文件
RestoreDeviceParam(deviceName, m_devParam);
m_devHandle = dev;
m_devName = deviceName;
m_openDevice = true;
errInfo.clear();
return 0;
}
int ManagerV2::CloseDevice(std::string& errInfo)
{
errInfo = "错误";
if (!m_openDevice)
return -1;
std::string errInfo2;
StopScan(errInfo2);
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
m_devParam.Reset();
m_openDevice = false;
errInfo.clear();
return 0;
}
int ManagerV2::SetDeviceParam(const DeviceParam& param, HGUInt mask, std::string& errInfo)
{
errInfo = "错误";
if (!m_openDevice || m_scanning)
return -1;
// 设置devParam到设备
int ret = SetParamToDevice(m_devHandle, param, mask);
// 从设备获取并设置m_devParam
GetParamFromDevice(m_devHandle, m_devParam);
// 保存到配置文件
RestoreDeviceParam(m_devName, m_devParam);
if (0 == ret)
errInfo.clear();
return ret;
}
int ManagerV2::GetDeviceParam(DeviceParam& param, std::string& errInfo)
{
param.Reset();
errInfo = "错误";
if (!m_openDevice)
return -1;
param = m_devParam;
errInfo.clear();
return 0;
}
int ManagerV2::GetCurrDeviceName(std::string& deviceName, std::string& errInfo)
{
errInfo = "错误";
if (!m_openDevice)
return -1;
deviceName = m_devName;
errInfo.clear();
return 0;
}
int ManagerV2::StartScan(std::string& errInfo)
{
errInfo = "错误";
if (!m_openDevice || m_scanning)
return -1;
HGBase_CreateEvent(HGFALSE, HGFALSE, &m_scanEvent);
assert(NULL != m_scanEvent);
SANE_Status status = sane_start(m_devHandle);
if (SANE_STATUS_GOOD != status)
{
HGBase_DestroyEvent(m_scanEvent);
m_scanEvent = NULL;
return -1;
}
m_scanning = true;
errInfo.clear();
return 0;
}
int ManagerV2::StopScan(std::string& errInfo)
{
errInfo = "错误";
if (!m_scanning)
return -1;
assert(NULL != m_devHandle);
sane_cancel(m_devHandle);
assert(NULL != m_scanEvent);
HGBase_WaitEvent(m_scanEvent);
HGBase_DestroyEvent(m_scanEvent);
m_scanEvent = NULL;
m_scanning = false;
errInfo.clear();
return 0;
}
bool ManagerV2::IsScanning()
{
return m_scanning;
}
int ManagerV2::GetBatchIdList(std::vector<std::string>& batchIdList, std::string& errInfo)
{
batchIdList.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<std::pair<int, std::string>> tables;
char** result = NULL;
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
assert(0 == ret && rows > 0 && cols == 2);
for (int i = 0; i < rows; i++)
{
std::pair<int, std::string> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("name", result[j]))
{
pr.second = result[(i + 1) * cols + j];
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
assert(!tables.empty());
std::sort(tables.begin(), tables.end(), MainTableSort);
for (int i = 0; i < (int)tables.size(); ++i)
batchIdList.push_back(tables[i].second);
errInfo.clear();
return 0;
}
int ManagerV2::OpenBatch(const std::string& batchId, std::string& errInfo)
{
errInfo = "错误";
if (batchId.empty())
return -1;
std::vector<std::string> batchIdList;
std::string errInfo2;
GetBatchIdList(batchIdList, errInfo2);
int ret = -1;
for (int i = 0; i < (int)batchIdList.size(); ++i)
{
if (batchId == batchIdList[i])
{
m_currBatchId = batchIdList[i];
errInfo.clear();
ret = 0;
break;
}
}
return ret;
}
int ManagerV2::DeleteBatch(const std::string& batchId, std::string& errInfo)
{
errInfo = "错误";
if (batchId.empty() || batchId == m_currBatchId)
return -1;
if (NULL == m_sqlite)
return -1;
char sql[256];
sprintf(sql, "drop table 'table_%s'", batchId.c_str());
int ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
if (0 != ret)
return -1;
sprintf(sql, "delete from table_ where name = '%s'", batchId.c_str());
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
errInfo.clear();
return 0;
}
int ManagerV2::NewBatch(const std::string& batchId, std::string& errInfo)
{
errInfo = "错误";
if (batchId.empty())
return -1;
if (NULL == m_sqlite)
return -1;
char sql[256];
sprintf(sql, "create table 'table_%s' (id integer primary key autoincrement, idx integer, format text, tag text, image blob)", batchId.c_str());
int ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
if (0 != ret)
return -1;
sprintf(sql, "insert into table_ (name) values ('%s')", batchId.c_str());
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
m_currBatchId = batchId;
errInfo.clear();
return 0;
}
int ManagerV2::GetCurrBatchId(std::string& batchId, std::string& errInfo)
{
batchId.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
batchId = m_currBatchId;
errInfo.clear();
return 0;
}
int ManagerV2::ModifyBatchId(const std::string& batchId, const std::string& newBatchId, std::string& errInfo)
{
errInfo = "错误";
if (batchId.empty() || newBatchId.empty())
return -1;
if (NULL == m_sqlite)
return -1;
char sql[256];
sprintf(sql, "alter table 'table_%s' rename to 'table_%s'", batchId.c_str(), newBatchId.c_str());
int ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
if (0 != ret)
return -1;
sprintf(sql, "update table_ set name = '%s' where name = '%s'", newBatchId.c_str(), batchId.c_str());
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
if (batchId == m_currBatchId)
m_currBatchId = newBatchId;
errInfo.clear();
return 0;
}
int ManagerV2::GetImageCount(int& imageCount, std::string& errInfo)
{
imageCount = 0;
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
char** result = NULL;
char sql[256];
sprintf(sql, "select id from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
imageCount = rows;
sqlite3_free_table(result);
errInfo.clear();
return 0;
}
int ManagerV2::LoadImage(int imageIndex, std::string& imageTag, std::string& imageBase64, std::string& errInfo)
{
imageTag.clear();
imageBase64.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
int rc = -1;
sqlite3_stmt* stmt = NULL;
char sql[256];
sprintf(sql, "select * from 'table_%s'", m_currBatchId.c_str());
int ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_step(stmt);
while (SQLITE_ROW == ret)
{
int idx = sqlite3_column_int(stmt, 1);
if (idx == imageIndex)
{
std::string imgFmt = (const char*)sqlite3_column_text(stmt, 2);
imageTag = (const char*)sqlite3_column_text(stmt, 3);
const void* imgData = sqlite3_column_blob(stmt, 4);
int imgSize = sqlite3_column_bytes(stmt, 4);
GetBase64((const HGByte *)imgData, imgSize, imageBase64);
assert(!imageBase64.empty());
std::string prefix;
if ("jpg" == imgFmt)
prefix = "data:image/jpeg;base64,";
else if ("bmp" == imgFmt)
prefix = "data:image/bmp;base64,";
else if ("png" == imgFmt)
prefix = "data:image/png;base64,";
else if ("tif" == imgFmt)
prefix = "data:image/tiff;base64,";
else if ("pdf" == imgFmt)
prefix = "data:image/pdf;base64,";
else if ("ofd" == imgFmt)
prefix = "data:image/ofd;base64,";
imageBase64.insert(0, prefix);
errInfo.clear();
rc = 0;
break;
}
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
return rc;
}
int ManagerV2::SaveImage(int imageIndex, std::string& imagePath, std::string& errInfo)
{
imagePath.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
int rc = -1;
sqlite3_stmt* stmt = NULL;
char sql[256];
sprintf(sql, "select * from 'table_%s'", m_currBatchId.c_str());
int ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_step(stmt);
while (SQLITE_ROW == ret)
{
int idx = sqlite3_column_int(stmt, 1);
if (idx == imageIndex)
{
std::string imgFmt = (const char*)sqlite3_column_text(stmt, 2);
const void* imgData = sqlite3_column_blob(stmt, 4);
int imgSize = sqlite3_column_bytes(stmt, 4);
bool saveRet = false;
std::string imagePath2 = GetFilePath(imgFmt.c_str());
FILE* file = fopen(imagePath2.c_str(), "wb");
if (NULL != file)
{
size_t writeLen = fwrite(imgData, 1, imgSize, file);
if (writeLen == (size_t)imgSize)
saveRet = true;
fclose(file);
}
if (!saveRet)
{
HGBase_DeleteFile(imagePath2.c_str());
}
else
{
imagePath = imagePath2;
HGBase_EnterLock(m_lock);
m_saveFilePathList.push_back(imagePath);
RestoreSaveFilePathList(m_saveFilePathList);
HGBase_LeaveLock(m_lock);
errInfo.clear();
rc = 0;
}
break;
}
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
return rc;
}
int ManagerV2::InsertLocalImage(const std::string& imagePath, int insertPos, const std::string& imageTag, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imagePath.empty() || insertPos < -1)
return -1;
HGUInt imgType = 0;
HGImgFmt_GetImgFmtType(imagePath.c_str(), &imgType);
if (0 == imgType)
return -1;
std::string format;
if (HGIMGFMT_TYPE_JPEG == imgType)
format = "jpg";
else if (HGIMGFMT_TYPE_BMP == imgType)
format = "bmp";
else if (HGIMGFMT_TYPE_PNG == imgType)
format = "png";
else if (HGIMGFMT_TYPE_TIFF == imgType)
format = "tif";
else if (HGIMGFMT_TYPE_PDF == imgType)
format = "pdf";
else if (HGIMGFMT_TYPE_OFD == imgType)
format = "ofd";
if (format.empty())
return - 1;
HGByte* imgData = NULL;
HGUInt imgSize = 0;
FILE* file = fopen(imagePath.c_str(), "rb");
if (NULL != file)
{
fseek(file, 0, SEEK_END);
imgSize = ftell(file);
fseek(file, 0, SEEK_SET);
if (imgSize > 0)
{
imgData = new HGByte[imgSize];
HGUInt readLen = (HGUInt)fread(imgData, 1, imgSize, file);
if (readLen != imgSize)
{
delete[] imgData;
imgData = NULL;
imgSize = 0;
}
}
fclose(file);
}
if (NULL == imgData)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
if (tables.empty())
{
if (-1 == insertPos)
insertPos = 0;
else if (0 != insertPos)
{
delete[] imgData;
return -1;
}
}
else
{
if (-1 == insertPos)
insertPos = tables[tables.size() - 1].second + 1;
else if (insertPos > tables[tables.size() - 1].second + 1)
{
delete[] imgData;
return -1;
}
}
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].second >= insertPos)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), tables[i].second + 1, tables[i].first);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image) values ('%d', '%s', '%s', ?)", m_currBatchId.c_str(),
insertPos, format.c_str(), imageTag.c_str());
sqlite3_stmt* stmt = NULL;
ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_bind_blob(stmt, 1, imgData, (int)imgSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
delete[] imgData;
errInfo.clear();
return 0;
}
int ManagerV2::InsertImage(const std::string& imageBase64, int insertPos, const std::string& imageTag, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageBase64.empty() || insertPos < -1)
return -1;
size_t pos = imageBase64.find(',');
if (std::string::npos == pos)
return -1;
std::string format;
std::string prefix = imageBase64.substr(0, pos + 1);
if ("data:image/jpeg;base64," == prefix)
format = "jpg";
else if ("data:image/bmp;base64," == prefix)
format = "bmp";
else if ("data:image/png;base64," == prefix)
format = "png";
else if ("data:image/tiff;base64," == prefix)
format = "tif";
else if ("data:image/pdf;base64," == prefix)
format = "pdf";
else if ("data:image/ofd;base64," == prefix)
format = "ofd";
if (format.empty())
return -1;
HGByte* imgData = NULL;
HGSize imgSize = 0;
const HGChar *base64Data = imageBase64.c_str() + pos + 1;
HGSize base64Size = (HGSize)strlen(base64Data);
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, NULL, &imgSize);
if (0 != imgSize)
{
imgData = new HGByte[imgSize];
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, imgData, &imgSize);
}
if (NULL == imgData)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
if (tables.empty())
{
if (-1 == insertPos)
insertPos = 0;
else if (0 != insertPos)
{
delete[] imgData;
return -1;
}
}
else
{
if (-1 == insertPos)
insertPos = tables[tables.size() - 1].second + 1;
else if (insertPos > tables[tables.size() - 1].second + 1)
{
delete[] imgData;
return -1;
}
}
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].second >= insertPos)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), tables[i].second + 1, tables[i].first);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image) values ('%d', '%s', '%s', ?)", m_currBatchId.c_str(),
insertPos, format.c_str(), imageTag.c_str());
sqlite3_stmt* stmt = NULL;
ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_bind_blob(stmt, 1, imgData, (int)imgSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
delete[] imgData;
errInfo.clear();
return 0;
}
int ManagerV2::ModifyImageTag(const std::vector<int>& imageIndexList, const std::vector<std::string>& imageTagList, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndexList.empty() || imageTagList.empty()
|| imageIndexList.size() != imageTagList.size())
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
bool indexValid = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
bool find = false;
for (int j = 0; j < (int)tables.size(); ++j)
{
if (imageIndexList[i] == tables[j].second)
{
find = true;
break;
}
}
if (!find)
{
indexValid = false;
break;
}
}
if (!indexValid)
return -1;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
sprintf(sql, "update 'table_%s' set tag = '%s' where idx = '%d'", m_currBatchId.c_str(),
imageTagList[i].c_str(), imageIndexList[i]);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
errInfo.clear();
return 0;
}
int ManagerV2::DeleteImage(const std::vector<int>& imageIndexList, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndexList.empty())
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
bool indexValid = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
bool find = false;
for (int j = 0; j < (int)tables.size(); ++j)
{
if (imageIndexList[i] == tables[j].second)
{
find = true;
break;
}
}
if (!find)
{
indexValid = false;
break;
}
}
if (!indexValid)
return -1;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
sprintf(sql, "delete from 'table_%s' where idx = '%d'", m_currBatchId.c_str(), imageIndexList[i]);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
int value = 0;
for (int i = 0; i < (int)tables.size(); ++i)
{
bool find = false;
for (int j = 0; j < (int)imageIndexList.size(); ++j)
{
if (tables[i].second == imageIndexList[j])
{
find = true;
break;
}
}
if (find)
{
++value;
}
else
{
if (value > 0)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), tables[i].second - value, tables[i].first);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
}
errInfo.clear();
return 0;
}
int ManagerV2::ClearImageList(std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
char sql[256];
sprintf(sql, "delete from 'table_%s'", m_currBatchId.c_str());
int ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
errInfo.clear();
return 0;
}
int ManagerV2::ModifyImage(int imageIndex, const std::string& imageBase64, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndex < 0 || imageBase64.empty())
return -1;
size_t pos = imageBase64.find(',');
if (std::string::npos == pos)
return -1;
std::string format;
std::string prefix = imageBase64.substr(0, pos + 1);
if ("data:image/jpeg;base64," == prefix)
format = "jpg";
else if ("data:image/bmp;base64," == prefix)
format = "bmp";
else if ("data:image/png;base64," == prefix)
format = "png";
else if ("data:image/tiff;base64," == prefix)
format = "tif";
else if ("data:image/pdf;base64," == prefix)
format = "pdf";
else if ("data:image/ofd;base64," == prefix)
format = "ofd";
if (format.empty())
return -1;
HGByte* imgData = NULL;
HGSize imgSize = 0;
const HGChar* base64Data = imageBase64.c_str() + pos + 1;
HGSize base64Size = (HGSize)strlen(base64Data);
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, NULL, &imgSize);
if (0 != imgSize)
{
imgData = new HGByte[imgSize];
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, imgData, &imgSize);
}
if (NULL == imgData)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
bool find = false;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].second == imageIndex)
{
find = true;
break;
}
}
if (!find)
{
delete[] imgData;
return -1;
}
sprintf(sql, "update 'table_%s' set format = '%s', image = ? where idx = '%d'",
m_currBatchId.c_str(), format.c_str(), imageIndex);
sqlite3_stmt* stmt = NULL;
ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_bind_blob(stmt, 1, imgData, (int)imgSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
delete[] imgData;
errInfo.clear();
return 0;
}
int ManagerV2::ModifyImageByLocal(int imageIndex, const std::string& imagePath, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndex < 0 || imagePath.empty())
return -1;
HGUInt imgType = 0;
HGImgFmt_GetImgFmtType(imagePath.c_str(), &imgType);
if (0 == imgType)
return -1;
std::string format;
if (HGIMGFMT_TYPE_JPEG == imgType)
format = "jpg";
else if (HGIMGFMT_TYPE_BMP == imgType)
format = "bmp";
else if (HGIMGFMT_TYPE_PNG == imgType)
format = "png";
else if (HGIMGFMT_TYPE_TIFF == imgType)
format = "tif";
else if (HGIMGFMT_TYPE_PDF == imgType)
format = "pdf";
else if (HGIMGFMT_TYPE_OFD == imgType)
format = "ofd";
if (format.empty())
return -1;
HGByte* imgData = NULL;
HGUInt imgSize = 0;
FILE* file = fopen(imagePath.c_str(), "rb");
if (NULL != file)
{
fseek(file, 0, SEEK_END);
imgSize = ftell(file);
fseek(file, 0, SEEK_SET);
if (imgSize > 0)
{
imgData = new HGByte[imgSize];
HGUInt readLen = (HGUInt)fread(imgData, 1, imgSize, file);
if (readLen != imgSize)
{
delete[] imgData;
imgData = NULL;
imgSize = 0;
}
}
fclose(file);
}
if (NULL == imgData)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
bool find = false;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].second == imageIndex)
{
find = true;
break;
}
}
if (!find)
{
delete[] imgData;
return -1;
}
sprintf(sql, "update 'table_%s' set format = '%s', image = ? where idx = '%d'",
m_currBatchId.c_str(), format.c_str(), imageIndex);
sqlite3_stmt* stmt = NULL;
ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
assert(0 == ret);
ret = sqlite3_bind_blob(stmt, 1, imgData, (int)imgSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
delete[] imgData;
errInfo.clear();
return 0;
}
int ManagerV2::MoveImage(const std::vector<int>& imageIndexList, const std::string& mode, int target, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndexList.empty() || target < 0)
return -1;
if ("pos" != mode && "index" != mode)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
if (tables.empty())
return -1;
if ("pos" == mode && target > tables[tables.size() - 1].second + 1)
return -1;
if ("index" == mode && target > tables[tables.size() - 1].second)
return -1;
bool indexValid = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
bool find = false;
for (int j = 0; j < (int)tables.size(); ++j)
{
if (imageIndexList[i] == tables[j].second)
{
find = true;
break;
}
}
if (!find)
{
indexValid = false;
break;
}
}
if (!indexValid)
return -1;
if ("pos" == mode)
{
int posEx = target;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
int oldIndex = -1;
for (int j = 0; j < (int)tables.size(); ++j)
{
if (imageIndexList[i] == tables[j].second)
{
oldIndex = j;
break;
}
}
assert(-1 != oldIndex);
std::pair<int, int> pr = tables[oldIndex];
if (oldIndex < posEx)
--posEx;
tables.erase(tables.begin() + oldIndex);
if (posEx != (int)tables.size())
tables.insert(tables.begin() + posEx, pr);
else
tables.push_back(pr);
++posEx;
}
}
else
{
std::vector<std::pair<int, int>> prs;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
int oldIndex = -1;
for (int j = 0; j < (int)tables.size(); ++j)
{
if (imageIndexList[i] == tables[j].second)
{
oldIndex = j;
break;
}
}
assert(-1 != oldIndex);
std::pair<int, int> pr = tables[oldIndex];
tables.erase(tables.begin() + oldIndex);
prs.push_back(pr);
}
if (target < (int)tables.size())
{
int indexEx = target;
for (int i = 0; i < (int)prs.size(); ++i)
{
tables.insert(tables.begin() + indexEx, prs[i]);
++indexEx;
}
}
else
{
for (int i = 0; i < (int)prs.size(); ++i)
{
tables.push_back(prs[i]);
}
}
}
for (int i = 0; i < (int)tables.size(); ++i)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), i, tables[i].first);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
errInfo.clear();
return 0;
}
int ManagerV2::ImageBookSort(std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<std::pair<int, int>> tables;
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx from 'table_%s'", m_currBatchId.c_str());
int rows, cols;
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
assert(0 == ret);
for (int i = 0; i < rows; i++)
{
std::pair<int, int> pr;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
pr.first = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
pr.second = atoi(result[(i + 1) * cols + j]);
}
}
tables.push_back(pr);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
std::list<std::pair<int, int>> prs1, prs2;
for (int i = 0; i < (int)tables.size(); ++i)
{
std::pair<int, int> pr = tables[i];
if (0 == i % 2)
prs1.push_back(pr);
else
prs2.push_front(pr);
}
tables.clear();
std::list<std::pair<int, int>>::const_iterator iter;
for (iter = prs1.begin(); iter != prs1.end(); ++iter)
tables.push_back(*iter);
for (iter = prs2.begin(); iter != prs2.end(); ++iter)
tables.push_back(*iter);
for (int i = 0; i < (int)tables.size(); ++i)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), i, tables[i].first);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
errInfo.clear();
return 0;
}
int ManagerV2::MergeImage(const std::vector<int>& imageIndexList, const std::string& mode,
const std::string& align, int interval, std::string& outImagePath, std::string& errInfo)
{
return -1;
}
int ManagerV2::MakeMultiImage(const std::vector<int>& imageIndexList, const std::string& format,
const std::string& tiffCompression, int tiffJpegQuality, std::string& outImagePath, std::string& errInfo)
{
return -1;
}
int ManagerV2::SplitImage(int imageIndex, const std::string& mode, int location, std::vector<std::string>& outImagePathList,
std::string& errInfo)
{
return -1;
}
int ManagerV2::MakeZipFile(const std::vector<int>& imageIndexList, std::string& outZipPath, std::string& errInfo)
{
return -1;
}
int ManagerV2::ImageDeskew(int imageIndex, std::string& outImagePath, std::string& errInfo)
{
return -1;
}
std::string ManagerV2::GetCfgStringValue(const std::string& app, const std::string& key, const std::string& def)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "config2.ini");
HGChar val[256] = { 0 };
HGBase_GetProfileString(cfgPath, app.c_str(), key.c_str(), def.c_str(), val, 256);
return val;
}
int ManagerV2::GetCfgIntValue(const std::string& app, const std::string& key, int def)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "config2.ini");
HGInt val = 0;
HGBase_GetProfileInt(cfgPath, app.c_str(), key.c_str(), def, &val);
return val;
}
double ManagerV2::GetCfgDoubleValue(const std::string& app, const std::string& key, double def)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "config2.ini");
char defStr[32];
sprintf(defStr, "%f", def);
HGChar val[256] = { 0 };
HGBase_GetProfileString(cfgPath, app.c_str(), key.c_str(), defStr, val, 256);
return atof(val);
}
bool ManagerV2::GetCfgBoolValue(const std::string& app, const std::string& key, bool def)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
strcat(cfgPath, "config2.ini");
HGInt val = 0;
HGBase_GetProfileInt(cfgPath, app.c_str(), key.c_str(), (HGInt)def, &val);
return (bool)val;
}
bool ManagerV2::SetCfgStringValue(const std::string& app, const std::string& key, const std::string& val)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
strcat(cfgPath, "config2.ini");
return (HGBASE_ERR_OK == HGBase_SetProfileString(cfgPath, app.c_str(), key.c_str(), val.c_str()));
}
bool ManagerV2::SetCfgIntValue(const std::string& app, const std::string& key, int val)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
strcat(cfgPath, "config2.ini");
return (HGBASE_ERR_OK == HGBase_SetProfileInt(cfgPath, app.c_str(), key.c_str(), val));
}
bool ManagerV2::SetCfgDoubleValue(const std::string& app, const std::string& key, double val)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
strcat(cfgPath, "config2.ini");
char valStr[32];
sprintf(valStr, "%f", val);
return (HGBASE_ERR_OK == HGBase_SetProfileString(cfgPath, app.c_str(), key.c_str(), valStr));
}
bool ManagerV2::SetCfgBoolValue(const std::string& app, const std::string& key, bool val)
{
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
strcat(cfgPath, "config2.ini");
return (HGBASE_ERR_OK == HGBase_SetProfileInt(cfgPath, app.c_str(), key.c_str(), (HGInt)val));
}
int ManagerV2::LoadBase64(const std::string& fileName, std::string& base64)
{
base64.clear();
int ret = -1;
FILE* file = fopen(fileName.c_str(), "rb");
if (NULL != file)
{
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
if (size > 0)
{
HGByte* data = new HGByte[size];
long readLen = (long)fread(data, 1, size, file);
if (readLen == size)
{
HGSize base64Size = 0;
HGBase_Base64Encode(data, size, NULL, &base64Size);
uint8_t* base64Data = new uint8_t[base64Size + 1];
HGBase_Base64Encode(data, size, base64Data, &base64Size);
base64Data[base64Size] = 0;
base64 = (const char*)base64Data;
delete[] base64Data;
ret = 0;
}
delete[] data;
}
fclose(file);
}
return ret;
}
int ManagerV2::SaveBase64(const std::string& base64, const std::string& fileName)
{
if (base64.empty())
return -1;
const char* base64Data = base64.c_str();
size_t base64Size = base64.size();
int ret = -1;
FILE* file = fopen(fileName.c_str(), "wb");
if (NULL != file)
{
HGSize size = 0;
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, NULL, &size);
uint8_t* data = new HGByte[size];
HGBase_Base64Decode((const HGByte*)base64Data, (HGSize)base64Size, data, &size);
size_t writeLen = fwrite(data, 1, size, file);
if (writeLen == (size_t)size)
ret = 0;
delete[] data;
fclose(file);
}
if (0 != ret)
HGBase_DeleteFile(fileName.c_str());
return ret;
}
int ManagerV2::HttpUpload(const std::string& host, int port, const std::string& path,
const std::string& filePath, const std::string& remoteFilePath)
{
return -1;
}
static size_t read_callback(char* ptr, size_t size, size_t nmemb, void* stream)
{
unsigned long nread;
/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */
size_t retcode = fread(ptr, size, nmemb, (FILE*)stream);
if (retcode > 0)
{
nread = (unsigned long)retcode;
//fprintf(stderr, "*** We read %lu bytes from file\n", nread);
}
return retcode;
}
int ManagerV2::FtpUpload(const std::string& user, const std::string& password, const std::string& host, int port,
const std::string& filePath, const std::string& remoteFilePath)
{
FILE* file = fopen(filePath.c_str(), "rb");
if (NULL == file)
{
return -1;
}
int ret = -1;
fseek(file, 0, SEEK_END);
long fsize = ftell(file);
fseek(file, 0, SEEK_SET);
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
CURL* curl = curl_easy_init();
if (NULL != curl)
{
char tmpName[256];
HGBase_GetUuid(tmpName, 256);
char remotePath[256];
HGBase_GetFilePath(remoteFilePath.c_str(), remotePath, 256);
char remoteName[256];
HGBase_GetFileName(remoteFilePath.c_str(), remoteName, 256);
char ftp_rnfr[512];
sprintf(ftp_rnfr, "RNFR %s", tmpName);
char ftp_rnto[512];
sprintf(ftp_rnto, "RNTO %s", remoteName);
struct curl_slist* headerlist = NULL;
headerlist = curl_slist_append(headerlist, ftp_rnfr);
headerlist = curl_slist_append(headerlist, ftp_rnto);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
char url[512];
if (!user.empty() && !password.empty())
{
sprintf(url, "ftp://%s:%s@%s:%d%s%s", user.c_str(), password.c_str(),
host.c_str(), port, remotePath, tmpName);
}
else
{
sprintf(url, "ftp://%s:%d%s%s", host.c_str(), port, remotePath, tmpName);
}
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1);
/* pass in that last of FTP commands to run after the transfer */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_READDATA, file);
/* Set the size of the file to upload (optional). If you give a *_LARGE
option you MUST make sure that the type of the passed-in argument is a
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
make sure that to pass in a type 'long' argument. */
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize);
/* Now run off and do what you have been told! */
CURLcode res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
else
ret = 0;
/* clean up the FTP commands list */
curl_slist_free_all(headerlist);
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(file); /* close the local file */
curl_global_cleanup();
return ret;
}
std::string ManagerV2::GetFilePath(const std::string& suffix)
{
char filePath[256] = { 0 };
if ("random" == m_globalCfg.fileNameMode)
{
HGChar uuid[256];
HGBase_GetUuid(uuid, 256);
sprintf(filePath, "%s%s%s.%s", m_globalCfg.fileSavePath.c_str(), m_globalCfg.fileNamePrefix.c_str(), uuid, suffix.c_str());
}
else
{
HGTimeInfo timeInfo;
HGBase_GetLocalTime(&timeInfo);
sprintf(filePath, "%s%s%04d%02d%02d%02d%02d%02d%03d.%s", m_globalCfg.fileSavePath.c_str(), m_globalCfg.fileNamePrefix.c_str(), timeInfo.year,
timeInfo.month, timeInfo.day, timeInfo.hour, timeInfo.minute, timeInfo.second, timeInfo.milliseconds, suffix.c_str());
}
return filePath;
}
int ManagerV2::SaveImage(HGImage image, std::string& imagePath)
{
assert(NULL != image);
imagePath.clear();
bool ocr = false;
std::string suffix = m_globalCfg.imageFormat;
if ("ocr-pdf" == m_globalCfg.imageFormat)
{
suffix = "pdf";
ocr = true;
}
else if ("ocr-ofd" == m_globalCfg.imageFormat)
{
suffix = "ofd";
ocr = true;
}
std::string imagePath2 = GetFilePath(suffix);
int ret = -1;
if (ocr)
{
HGOCRMgr ocrMgr = NULL;
HGImgProc_CreateOCRMgr(&ocrMgr);
if (NULL != ocrMgr)
{
if (HGBASE_ERR_OK == HGImgProc_ImageOCRToFile(ocrMgr, image, 0, imagePath2.c_str()))
{
ret = 0;
}
HGImgProc_DestroyOCRMgr(ocrMgr);
}
}
else
{
HGImgFmtSaveInfo saveInfo;
saveInfo.jpegQuality = m_globalCfg.imageJpegQuality;
saveInfo.tiffJpegQuality = m_globalCfg.imageTiffJpegQuality;
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_LZW;
if ("none" == m_globalCfg.imageTiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_NONE;
else if ("jpeg" == m_globalCfg.imageTiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_JPEG;
else if ("ccitt-g4" == m_globalCfg.imageTiffCompression)
saveInfo.tiffCompression = HGIMGFMT_TIFFCOMP_CCITTFAX4;
if (HGBASE_ERR_OK == HGImgFmt_SaveImage(image, 0, &saveInfo, imagePath2.c_str()))
{
ret = 0;
}
}
if (0 == ret)
imagePath = imagePath2;
return ret;
}
void ManagerV2::LoadSaveFilePathList(std::vector<std::string>& savePathList)
{
savePathList.clear();
HGChar path[256];
HGBase_GetConfigPath(path, 256);
strcat(path, "saveFilePathList.txt");
FILE* file = fopen(path, "r");
if (NULL != file)
{
while (feof(file) == 0)
{
char lineContent[256] = { 0 };
if (NULL == fgets(lineContent, 256, file) || '\n' == *lineContent)
{
continue;
}
if (lineContent[strlen(lineContent) - 1] == '\n')
lineContent[strlen(lineContent) - 1] = 0;
#if defined(HG_CMP_MSC)
DWORD attr = GetFileAttributesA(lineContent);
if (INVALID_FILE_ATTRIBUTES != attr && 0 == (FILE_ATTRIBUTE_DIRECTORY & attr))
savePathList.push_back(lineContent);
#else
if (0 == access(lineContent, R_OK))
savePathList.push_back(lineContent);
#endif
}
fclose(file);
}
}
void ManagerV2::RestoreSaveFilePathList(const std::vector<std::string>& savePathList)
{
HGChar path[256];
HGBase_GetConfigPath(path, 256);
strcat(path, "saveFilePathList.txt");
FILE* file = fopen(path, "w");
if (NULL != file)
{
for (int i = 0; i < (int)savePathList.size(); ++i)
{
fwrite(savePathList[i].c_str(), 1, savePathList[i].size(), file);
fwrite("\n", 1, strlen("\n"), file);
}
fclose(file);
}
}
void ManagerV2::LoadDeviceParam(const std::string& devName, DeviceParam& devParam)
{
assert(!devName.empty());
devParam.Reset();
devParam.colorMode = StdStringToUtf8(GetCfgStringValue(Utf8ToStdString(devName).c_str(), "colorMode", "24位彩色"));
devParam.pageMode = StdStringToUtf8(GetCfgStringValue(Utf8ToStdString(devName).c_str(), "pageMode", "双面"));
devParam.resolution = GetCfgIntValue(Utf8ToStdString(devName).c_str(), "resolution", 200);
devParam.brightness = GetCfgIntValue(Utf8ToStdString(devName).c_str(), "brightness", 100);
devParam.contrast = GetCfgIntValue(Utf8ToStdString(devName).c_str(), "contrast", 4);
devParam.gamma = GetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "gamma", 1.00f);
devParam.paperSize = StdStringToUtf8(GetCfgStringValue(Utf8ToStdString(devName).c_str(), "paperSize", "匹配原始尺寸"));
devParam.paperCutEnabled = GetCfgBoolValue(Utf8ToStdString(devName).c_str(), "paperCutEnabled", false);
devParam.paperCutLeft = GetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutLeft", 0.0f);
devParam.paperCutTop = GetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutTop", 0.0f);
devParam.paperCutRight = GetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutRight", 0.0f);
devParam.paperCutBottom = GetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutBottom", 0.0f);
devParam.autoCrop = GetCfgBoolValue(Utf8ToStdString(devName).c_str(), "autoCrop", false);
}
void ManagerV2::RestoreDeviceParam(const std::string& devName, const DeviceParam& devParam)
{
assert(!devName.empty());
SetCfgStringValue(Utf8ToStdString(devName).c_str(), "colorMode", Utf8ToStdString(devParam.colorMode));
SetCfgStringValue(Utf8ToStdString(devName).c_str(), "pageMode", Utf8ToStdString(devParam.pageMode));
SetCfgIntValue(Utf8ToStdString(devName).c_str(), "resolution", devParam.resolution);
SetCfgIntValue(Utf8ToStdString(devName).c_str(), "brightness", devParam.brightness);
SetCfgIntValue(Utf8ToStdString(devName).c_str(), "contrast", devParam.contrast);
SetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "gamma", devParam.gamma);
SetCfgStringValue(Utf8ToStdString(devName).c_str(), "paperSize", Utf8ToStdString(devParam.paperSize));
SetCfgBoolValue(Utf8ToStdString(devName).c_str(), "paperCutEnabled", devParam.paperCutEnabled);
SetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutLeft", devParam.paperCutLeft);
SetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutTop", devParam.paperCutTop);
SetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutRight", devParam.paperCutRight);
SetCfgDoubleValue(Utf8ToStdString(devName).c_str(), "paperCutBottom", devParam.paperCutBottom);
SetCfgBoolValue(Utf8ToStdString(devName).c_str(), "autoCrop", devParam.autoCrop);
}
int ManagerV2::SetParamToDevice(SANE_Handle hdev, const DeviceParam& devParam, HGUInt mask)
{
assert(NULL != hdev);
int ret = 0;
SANE_Int num_dev_options = 0;
sane_control_option(hdev, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
for (int i = 1; i < num_dev_options; ++i)
{
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(hdev, i);
if (NULL == desp)
continue;
if (SANE_TYPE_STRING == desp->type)
{
if (0 == strcmp(OPTION_TITLE_YSMS, desp->title) && (mask & DeviceParam::colorModeMask))
{
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, (void*)devParam.colorMode.c_str(), NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_SMYM, desp->title) && (mask & DeviceParam::pageModeMask))
{
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, (void*)devParam.pageMode.c_str(), NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_ZZCC, desp->title) && (mask & DeviceParam::paperSizeMask))
{
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, (void*)devParam.paperSize.c_str(), NULL))
ret = -1;
}
}
else if (SANE_TYPE_INT == desp->type)
{
if (0 == strcmp(OPTION_TITLE_FBL, desp->title) && (mask & DeviceParam::resolutionMask))
{
SANE_Int value = devParam.resolution;
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_LDZ, desp->title) && (mask & DeviceParam::brightnessMask))
{
SANE_Int value = devParam.brightness;
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_DBD, desp->title) && (mask & DeviceParam::contrastMask))
{
SANE_Int value = devParam.contrast;
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
}
else if (SANE_TYPE_FIXED == desp->type)
{
if (0 == strcmp(OPTION_TITLE_JMZ, desp->title) && (mask & DeviceParam::gammaMask))
{
SANE_Fixed value = SANE_FIX(devParam.gamma);
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_SMQYZCmm, desp->title) && (mask & DeviceParam::paperCutLeftMask))
{
SANE_Fixed value = SANE_FIX(devParam.paperCutLeft);
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_SMQYYCmm, desp->title) && (mask & DeviceParam::paperCutRightMask))
{
SANE_Fixed value = SANE_FIX(devParam.paperCutRight);
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_SMQYSCmm, desp->title) && (mask & DeviceParam::paperCutTopMask))
{
SANE_Fixed value = SANE_FIX(devParam.paperCutTop);
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_SMQYXCmm, desp->title) && (mask & DeviceParam::paperCutBottomMask))
{
SANE_Fixed value = SANE_FIX(devParam.paperCutBottom);
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
}
else if (SANE_TYPE_BOOL == desp->type)
{
if (0 == strcmp(OPTION_TITLE_ZDJP, desp->title) && (mask & DeviceParam::autoCropMask))
{
SANE_Bool value = (SANE_Bool)devParam.autoCrop;
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
else if (0 == strcmp(OPTION_TITLE_ZDYSMQY, desp->title) && (mask & DeviceParam::paperCutEnabledMask))
{
SANE_Bool value = (SANE_Bool)devParam.paperCutEnabled;
if (SANE_STATUS_GOOD != sane_control_option(hdev, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = -1;
}
}
}
return ret;
}
int ManagerV2::GetParamFromDevice(SANE_Handle hdev, DeviceParam& devParam)
{
assert(NULL != hdev);
devParam.Reset();
int ret = 0;
SANE_Int num_dev_options = 0;
sane_control_option(hdev, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
for (int i = 1; i < num_dev_options; ++i)
{
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(hdev, i);
if (NULL == desp)
continue;
if (SANE_TYPE_STRING == desp->type)
{
char value[256] = { 0 };
sane_control_option(hdev, i, SANE_ACTION_GET_VALUE, value, NULL);
if (0 == strcmp(OPTION_TITLE_YSMS, desp->title))
{
if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type)
{
const SANE_String_Const* p = desp->constraint.string_list;
while (NULL != *p)
{
devParam.colorModeList.push_back(*p);
++p;
}
}
devParam.colorMode = value;
}
else if (0 == strcmp(OPTION_TITLE_SMYM, desp->title))
{
if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type)
{
const SANE_String_Const* p = desp->constraint.string_list;
while (NULL != *p)
{
devParam.pageModeList.push_back(*p);
++p;
}
}
devParam.pageMode = value;
}
else if (0 == strcmp(OPTION_TITLE_ZZCC, desp->title))
{
if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type)
{
const SANE_String_Const* p = desp->constraint.string_list;
while (NULL != *p)
{
devParam.paperSizeList.push_back(*p);
++p;
}
}
devParam.paperSize = value;
}
}
else if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = 0;
sane_control_option(hdev, i, SANE_ACTION_GET_VALUE, &value, NULL);
if (0 == strcmp(OPTION_TITLE_FBL, desp->title))
{
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
{
const SANE_Word* p = desp->constraint.word_list;
for (SANE_Int i = 0; i < p[0]; ++i)
{
devParam.resolutionList.push_back(p[i + 1]);
}
}
devParam.resolution = value;
}
else if (0 == strcmp(OPTION_TITLE_LDZ, desp->title))
{
if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.brightnessMin = desp->constraint.range->min;
devParam.brightnessMax = desp->constraint.range->max;
}
devParam.brightness = value;
}
else if (0 == strcmp(OPTION_TITLE_DBD, desp->title))
{
if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.contrastMin = desp->constraint.range->min;
devParam.contrastMax = desp->constraint.range->max;
}
devParam.contrast = value;
}
}
else if (SANE_TYPE_FIXED == desp->type)
{
SANE_Word value = 0;
sane_control_option(hdev, i, SANE_ACTION_GET_VALUE, &value, NULL);
if (0 == strcmp(OPTION_TITLE_JMZ, desp->title))
{
if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.gammaMin = SANE_UNFIX(desp->constraint.range->min);
devParam.gammaMax = SANE_UNFIX(desp->constraint.range->max);
}
devParam.gamma = SANE_UNFIX(value);
}
else if (0 == strcmp(OPTION_TITLE_SMQYZCmm, desp->title))
{
devParam.paperCutLeft = SANE_UNFIX(value);
}
else if (0 == strcmp(OPTION_TITLE_SMQYYCmm, desp->title))
{
if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.paperSizeWidth = SANE_UNFIX(desp->constraint.range->max);
}
devParam.paperCutRight = SANE_UNFIX(value);
}
else if (0 == strcmp(OPTION_TITLE_SMQYSCmm, desp->title))
{
devParam.paperCutTop = SANE_UNFIX(value);
}
else if (0 == strcmp(OPTION_TITLE_SMQYXCmm, desp->title))
{
if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.paperSizeHeight = SANE_UNFIX(desp->constraint.range->max);
}
devParam.paperCutBottom = SANE_UNFIX(value);
}
}
else if (SANE_TYPE_BOOL == desp->type)
{
SANE_Bool value = 0;
sane_control_option(hdev, i, SANE_ACTION_GET_VALUE, &value, NULL);
if (0 == strcmp(OPTION_TITLE_ZDJP, desp->title))
{
devParam.autoCrop = (bool)value;
}
else if (0 == strcmp(OPTION_TITLE_ZDYSMQY, desp->title))
{
devParam.paperCutEnabled = (bool)value;
}
}
}
return ret;
}
void ManagerV2::GetBase64(const HGByte* data, HGUInt size, std::string& base64)
{
assert(NULL != data && 0 != size);
base64.clear();
HGSize base64Size = 0;
HGBase_Base64Encode(data, size, NULL, &base64Size);
uint8_t* p = new uint8_t[base64Size + 1];
HGBase_Base64Encode(data, size, p, &base64Size);
p[base64Size] = 0;
base64 = (const char*)p;
delete[] p;
}
int ManagerV2::sane_ex_callback(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param)
{
(void)hdev;
(void)len;
ManagerV2* p = (ManagerV2*)param;
switch (code)
{
case SANE_EVENT_DEVICE_ARRIVED:
{
SANE_Device* sane_dev = (SANE_Device*)data;
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_ARRIVED, name=%s", Utf8ToStdString(sane_dev->name).c_str());
HGBase_EnterLock(p->m_lock);
p->m_devNameList.push_back(sane_dev->name);
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_ARRIVE, sane_dev->name, false, p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_DEVICE_LEFT:
{
SANE_Device* sane_dev = (SANE_Device*)data;
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_LEFT, name=%s", Utf8ToStdString(sane_dev->name).c_str());
CloseDevParam* closeDevParam = new CloseDevParam;
closeDevParam->mgr = p;
closeDevParam->devName = sane_dev->name;
HGMsg msg;
msg.id = MSGID_CLOSE_DEVICE;
msg.data = closeDevParam;
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
{
delete closeDevParam;
}
HGBase_EnterLock(p->m_lock);
for (int i = 0; i < (int)p->m_devNameList.size(); ++i)
{
if (0 == strcmp(sane_dev->name, p->m_devNameList[i].c_str()))
{
p->m_devNameList.erase(p->m_devNameList.begin() + i);
break;
}
}
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_REMOVE, sane_dev->name, false, p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_WORKING:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_WORKING, msg=%s", Utf8ToStdString((char*)data).c_str());
HGBase_EnterLock(p->m_lock);
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_WORKING, (const char*)data, false, p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_SCAN_FINISHED:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_SCAN_FINISHED, msg=%s", Utf8ToStdString((char*)data).c_str());
HGBase_SetEvent(p->m_scanEvent);
ScanFinishParam* scanFinishParam = new ScanFinishParam;
scanFinishParam->mgr = p;
HGMsg msg;
msg.id = MSGID_SCAN_FINISH;
msg.data = scanFinishParam;
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
{
delete scanFinishParam;
}
HGBase_EnterLock(p->m_lock);
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_FINISH, (const char*)data, (0 != *len), p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_STATUS:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_STATUS, msg=%s", Utf8ToStdString((char*)data).c_str());
HGBase_EnterLock(p->m_lock);
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_STATUS, (const char*)data, false, p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_ERROR:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_ERROR, msg=%s", Utf8ToStdString((char*)data).c_str());
HGBase_EnterLock(p->m_lock);
if (NULL != p->m_saneEvent)
p->m_saneEvent(SANEEVENT_ERROR, (const char*)data, (0 != *len), p->m_saneParam);
HGBase_LeaveLock(p->m_lock);
}
break;
case SANE_EVENT_IMAGE_OK:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_IMAGE_OK");
SANE_Image* sane_img = (SANE_Image*)data;
HGUInt imgType = 0;
if (sane_img->header.format == SANE_FRAME_GRAY)
{
if (1 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_BINARY;
else if (8 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_GRAY;
}
else if (sane_img->header.format == SANE_FRAME_RGB)
imgType = HGBASE_IMGTYPE_RGB;
HGByte* data = sane_img->data;
HGImageInfo imgInfo = { (HGUInt)sane_img->header.pixels_per_line, (HGUInt)sane_img->header.lines,
imgType, (HGUInt)sane_img->header.bytes_per_line, HGBASE_IMGORIGIN_TOP };
HGImage img = NULL;
HGBase_CreateImageFromData(data, &imgInfo, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
HGBase_EnterLock(p->m_lock);
std::string imagePath;
int ret = p->SaveImage(img, imagePath);
if (0 == ret)
{
p->m_saveFilePathList.push_back(imagePath);
RestoreSaveFilePathList(p->m_saveFilePathList);
if (NULL != p->m_saneImageCallback)
p->m_saneImageCallback(imagePath.c_str(), p->m_saneImageParam);
}
HGBase_LeaveLock(p->m_lock);
HGBase_DestroyImage(img);
}
}
break;
}
return 0;
}
}