code_app/sdk/webservice/ManagerV2.cpp

3789 lines
95 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 MainTableInfo& info1, const MainTableInfo& info2)
{
return info1.id < info2.id;
}
static bool BatchTableSort(const BatchTableInfo& info1, const BatchTableInfo& info2)
{
return info1.idx < info2.idx;
}
static bool ImageThumbSort(const ImageThumbInfo& info1, const ImageThumbInfo& info2)
{
return info1.idx < info2.idx;
}
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_devParamValid = false;
m_devParam.Reset();
m_scanning = false;
m_scanEvent = NULL;
HGChar cfgPath[256];
HGBase_GetConfigPath(cfgPath, 256);
HGBase_CreateDir(cfgPath);
char oldDbPath[256];
sprintf(oldDbPath, "%s%s", cfgPath, "imageMgr.db");
HGBase_DeleteFile(oldDbPath);
char newDbPath[256];
sprintf(newDbPath, "%s%s", cfgPath, "imageList.db");
m_sqlite = NULL;
sqlite3_open_v2(newDbPath, &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, thumb 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<MainTableInfo> 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++)
{
MainTableInfo info;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
info.id = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("name", result[j]))
{
info.tableName = result[(i + 1) * cols + j];
}
}
tables.push_back(info);
}
sqlite3_free_table(result);
assert(!tables.empty());
std::sort(tables.begin(), tables.end(), MainTableSort);
m_currBatchId = tables[tables.size() - 1].tableName;
}
m_bindFolder.clear();
m_bindNameMode.clear();
m_bindNameWidth = 0;
m_bindNameBase = 0;
}
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, const std::vector<std::string>& nameList,
std::string& outZipPath, std::string& errInfo)
{
outZipPath.clear();
errInfo = "错误";
if (filePathList.empty())
return -1;
if (!nameList.empty())
{
if (nameList.size() != filePathList.size())
return - 1;
for (int i = 0; i < (int)nameList.size(); ++i)
{
if (nameList[i].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)
{
std::string zipName;
if (!nameList.empty())
{
zipName = nameList[i];
}
else
{
HGChar name[256];
HGBase_GetFileName(filePathList[i].c_str(), name, 256);
zipName = name;
}
if (zip_file_add(z, StdStringToUtf8(zipName).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
if (0 == GetParamFromDevice(dev, m_devParam))
{
m_devParamValid = true;
// 保存到配置文件
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_devParamValid = false;
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
if (0 == GetParamFromDevice(m_devHandle, m_devParam))
{
m_devParamValid = true;
// 保存到配置文件
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 || !m_devParamValid)
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<MainTableInfo> 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++)
{
MainTableInfo info;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
info.id = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("name", result[j]))
{
info.tableName = result[(i + 1) * cols + j];
}
}
tables.push_back(info);
}
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].tableName);
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])
{
if (m_currBatchId != batchId)
{
m_currBatchId = batchId;
if (!m_bindFolder.empty())
{
ClearBindFolder();
UpdateBindFolder();
}
}
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, thumb 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;
if (!m_bindFolder.empty())
{
ClearBindFolder();
UpdateBindFolder();
}
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::BindFolder(const std::string& folder, const std::string& nameMode, int nameWidth, int nameBase, std::string& errInfo)
{
errInfo = "错误";
if (folder.empty())
return -1;
if ("order" != nameMode || nameWidth <= 0 || nameBase < 0)
return -1;
// 需要保证文件夹为空??
if (NULL == m_sqlite)
return -1;
m_bindFolder = folder;
m_bindFolder.push_back('/');
HGChar stdBindFolder[256];
HGBase_StandardiseFileName(m_bindFolder.c_str(), stdBindFolder, 256);
m_bindFolder = stdBindFolder;
m_bindNameMode = nameMode;
m_bindNameWidth = nameWidth;
m_bindNameBase = nameBase;
ClearBindFolder();
UpdateBindFolder();
errInfo.clear();
return 0;
}
int ManagerV2::StopBindFolder(std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
m_bindFolder.clear();
m_bindNameMode.clear();
m_bindNameWidth = 0;
m_bindNameBase = 0;
errInfo.clear();
return 0;
}
int ManagerV2::GetImageThumbnailList(std::vector<ImageThumbInfo>& imageThumbList, std::string& errInfo)
{
imageThumbList.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);
std::string imgFmt = (const char*)sqlite3_column_text(stmt, 2);
std::string imgTag = (const char*)sqlite3_column_text(stmt, 3);
const void* thumbData = sqlite3_column_blob(stmt, 5);
int thumbSize = sqlite3_column_bytes(stmt, 5);
std::string thumbBase64;
SaveToBase64((const HGByte*)thumbData, thumbSize, thumbBase64);
assert(!thumbBase64.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,";
thumbBase64.insert(0, prefix);
ImageThumbInfo thumbInfo;
thumbInfo.idx = idx;
thumbInfo.tag = imgTag;
thumbInfo.thumbBase64 = thumbBase64;
imageThumbList.push_back(thumbInfo);
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
std::sort(imageThumbList.begin(), imageThumbList.end(), ImageThumbSort);
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);
std::string imgTag = (const char*)sqlite3_column_text(stmt, 3);
const void* imgData = sqlite3_column_blob(stmt, 4);
int imgSize = sqlite3_column_bytes(stmt, 4);
if (SaveToBase64((const HGByte*)imgData, imgSize, imageBase64))
{
imageTag = imgTag;
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);
std::string imagePath2 = GetFilePath(imgFmt.c_str());
if (SaveToFile((const HGByte*)imgData, imgSize, imagePath2))
{
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 imgSize = 0;
std::string imgFormat;
HGByte* imgData = LoadImageFromPath(imagePath.c_str(), imgSize, imgFormat);
if (NULL == imgData)
return -1;
HGUInt thumbSize = 0;
HGByte* thumbData = LoadThumbFromPath(imagePath.c_str(), thumbSize);
if (NULL == thumbData)
{
delete[] imgData;
return -1;
}
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
if (tables.empty())
{
if (-1 == insertPos)
insertPos = 0;
else if (0 != insertPos)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
}
else
{
if (-1 == insertPos)
insertPos = tables[tables.size() - 1].idx + 1;
else if (insertPos > tables[tables.size() - 1].idx + 1)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
}
int ret;
char sql[1024];
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx >= insertPos)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), tables[i].idx + 1, tables[i].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image, thumb) values ('%d', '%s', '%s', ?, ?)", m_currBatchId.c_str(),
insertPos, imgFormat.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);
ret = sqlite3_bind_blob(stmt, 2, thumbData, (int)thumbSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
if (!m_bindFolder.empty())
{
InsertBindFolderImage(tables, insertPos, imgFormat, imgData, imgSize);
}
delete[] thumbData;
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;
HGUInt imgSize = 0;
std::string imgFormat;
HGByte* imgData = LoadImageFromBase64(imageBase64.c_str(), imgSize, imgFormat);
if (NULL == imgData)
return -1;
HGUInt thumbSize = 0;
HGByte* thumbData = LoadThumbFromBase64(imageBase64.c_str(), thumbSize);
if (NULL == thumbData)
{
delete[] imgData;
return -1;
}
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
if (tables.empty())
{
if (-1 == insertPos)
insertPos = 0;
else if (0 != insertPos)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
}
else
{
if (-1 == insertPos)
insertPos = tables[tables.size() - 1].idx + 1;
else if (insertPos > tables[tables.size() - 1].idx + 1)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
}
int ret;
char sql[1024];
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx >= insertPos)
{
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), tables[i].idx + 1, tables[i].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image, thumb) values ('%d', '%s', '%s', ?, ?)", m_currBatchId.c_str(),
insertPos, imgFormat.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);
ret = sqlite3_bind_blob(stmt, 2, thumbData, (int)thumbSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
if (!m_bindFolder.empty())
{
InsertBindFolderImage(tables, insertPos, imgFormat, imgData, imgSize);
}
delete[] thumbData;
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<BatchTableInfo> tables;
GetBatchTableInfo(tables);
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].idx)
{
find = true;
break;
}
}
if (!find)
{
indexValid = false;
break;
}
}
if (!indexValid)
return -1;
int ret;
char sql[1024];
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<BatchTableInfo> tables;
GetBatchTableInfo(tables);
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].idx)
{
find = true;
break;
}
}
if (!find)
{
indexValid = false;
break;
}
}
if (!indexValid)
return -1;
int ret;
char sql[1024];
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].idx == 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].idx - value, tables[i].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
}
}
if (!m_bindFolder.empty())
{
DeleteBindFolderImage(tables, imageIndexList);
}
errInfo.clear();
return 0;
}
int ManagerV2::ClearImageList(std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
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);
if (!m_bindFolder.empty())
{
ClearBindFolderImageList(tables);
}
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;
HGUInt imgSize = 0;
std::string imgFormat;
HGByte* imgData = LoadImageFromBase64(imageBase64.c_str(), imgSize, imgFormat);
if (NULL == imgData)
return -1;
HGUInt thumbSize = 0;
HGByte* thumbData = LoadThumbFromBase64(imageBase64.c_str(), thumbSize);
if (NULL == thumbData)
{
delete[] imgData;
return -1;
}
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
bool find = false;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx == imageIndex)
{
find = true;
break;
}
}
if (!find)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
int ret;
char sql[1024];
sprintf(sql, "update 'table_%s' set format = '%s', image = ?, thumb = ? where idx = '%d'",
m_currBatchId.c_str(), imgFormat.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);
ret = sqlite3_bind_blob(stmt, 2, thumbData, (int)thumbSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
if (!m_bindFolder.empty())
{
ModifyBindFolderImage(tables, imageIndex, imgFormat, imgData, imgSize);
}
delete[] thumbData;
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 imgSize = 0;
std::string imgFormat;
HGByte* imgData = LoadImageFromPath(imagePath.c_str(), imgSize, imgFormat);
if (NULL == imgData)
return -1;
HGUInt thumbSize = 0;
HGByte* thumbData = LoadThumbFromPath(imagePath.c_str(), thumbSize);
if (NULL == thumbData)
{
delete[] imgData;
return -1;
}
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
bool find = false;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx == imageIndex)
{
find = true;
break;
}
}
if (!find)
{
delete[] thumbData;
delete[] imgData;
return -1;
}
int ret;
char sql[1024];
sprintf(sql, "update 'table_%s' set format = '%s', image = ?, thumb = ? where idx = '%d'",
m_currBatchId.c_str(), imgFormat.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);
ret = sqlite3_bind_blob(stmt, 2, thumbData, (int)thumbSize, NULL);
assert(0 == ret);
sqlite3_step(stmt);
ret = sqlite3_finalize(stmt);
assert(0 == ret);
if (!m_bindFolder.empty())
{
ModifyBindFolderImage(tables, imageIndex, imgFormat, imgData, imgSize);
}
delete[] thumbData;
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<BatchTableInfo> tables;
GetBatchTableInfo(tables);
if (tables.empty())
return -1;
if ("pos" == mode && target > tables[tables.size() - 1].idx + 1)
return -1;
if ("index" == mode && target > tables[tables.size() - 1].idx)
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].idx)
{
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].idx)
{
oldIndex = j;
break;
}
}
assert(-1 != oldIndex);
BatchTableInfo info = tables[oldIndex];
if (oldIndex < posEx)
--posEx;
tables.erase(tables.begin() + oldIndex);
if (posEx != (int)tables.size())
tables.insert(tables.begin() + posEx, info);
else
tables.push_back(info);
++posEx;
}
}
else
{
std::vector<BatchTableInfo> infos;
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].idx)
{
oldIndex = j;
break;
}
}
assert(-1 != oldIndex);
BatchTableInfo info = tables[oldIndex];
tables.erase(tables.begin() + oldIndex);
infos.push_back(info);
}
if (target < (int)tables.size())
{
int indexEx = target;
for (int i = 0; i < (int)infos.size(); ++i)
{
tables.insert(tables.begin() + indexEx, infos[i]);
++indexEx;
}
}
else
{
for (int i = 0; i < (int)infos.size(); ++i)
{
tables.push_back(infos[i]);
}
}
}
int ret;
char sql[1024];
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].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
if (!m_bindFolder.empty())
{
ClearBindFolderImageList(tables);
UpdateBindFolder();
}
errInfo.clear();
return 0;
}
int ManagerV2::ExchangeImage(int imageIndex1, int imageIndex2, std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite || imageIndex1 == imageIndex2)
return -1;
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
bool find1 = false, find2 = false;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx == imageIndex1)
{
find1 = true;
}
else if (tables[i].idx == imageIndex2)
{
find2 = true;
}
}
if (!find1 || !find2)
return -1;
int ret;
char sql[1024];
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), imageIndex2, tables[imageIndex1].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
m_currBatchId.c_str(), imageIndex1, tables[imageIndex2].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
if (!m_bindFolder.empty())
{
ExchangeBindFolderImage(tables, imageIndex1, imageIndex2);
}
errInfo.clear();
return 0;
}
int ManagerV2::ImageBookSort(std::string& errInfo)
{
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<BatchTableInfo> tables;
GetBatchTableInfo(tables);
std::list<BatchTableInfo> infos1, infos2;
for (int i = 0; i < (int)tables.size(); ++i)
{
BatchTableInfo info = tables[i];
if (0 == i % 2)
infos1.push_back(info);
else
infos2.push_front(info);
}
tables.clear();
std::list<BatchTableInfo>::const_iterator iter;
for (iter = infos1.begin(); iter != infos1.end(); ++iter)
tables.push_back(*iter);
for (iter = infos2.begin(); iter != infos2.end(); ++iter)
tables.push_back(*iter);
int ret;
char sql[1024];
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].id);
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
assert(0 == ret);
}
if (!m_bindFolder.empty())
{
ClearBindFolderImageList(tables);
UpdateBindFolder();
}
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)
{
outImagePath.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<std::string> imagePathList;
bool ok = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
std::string imagePath;
if (0 != SaveImage(imageIndexList[i], imagePath))
{
ok = false;
break;
}
imagePathList.push_back(imagePath);
}
if (!ok)
{
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return -1;
}
int ret = MergeLocalImage(imagePathList, mode, align, interval, outImagePath, errInfo);
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return ret;
}
int ManagerV2::MakeMultiImage(const std::vector<int>& imageIndexList, const std::string& format,
const std::string& tiffCompression, int tiffJpegQuality, std::string& outImagePath, std::string& errInfo)
{
outImagePath.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<std::string> imagePathList;
bool ok = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
std::string imagePath;
if (0 != SaveImage(imageIndexList[i], imagePath))
{
ok = false;
break;
}
imagePathList.push_back(imagePath);
}
if (!ok)
{
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return -1;
}
int ret = LocalMakeMultiImage(imagePathList, format, tiffCompression, tiffJpegQuality, outImagePath, errInfo);
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return ret;
}
int ManagerV2::SplitImage(int imageIndex, const std::string& mode, int location, std::vector<std::string>& outImagePathList,
std::string& errInfo)
{
outImagePathList.clear();
errInfo.clear();
if (NULL == m_sqlite)
return -1;
std::string imagePath;
if (0 != SaveImage(imageIndex, imagePath))
{
return -1;
}
int ret = SplitLocalImage(imagePath, mode, location, outImagePathList, errInfo);
HGBase_DeleteFile(imagePath.c_str());
return ret;
}
int ManagerV2::MakeZipFile(const std::vector<int>& imageIndexList, std::string& outZipPath, std::string& errInfo)
{
outZipPath.clear();
errInfo = "错误";
if (NULL == m_sqlite)
return -1;
std::vector<std::string> imagePathList;
std::vector<std::string> nameList;
bool ok = true;
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
std::string imagePath;
if (0 != SaveImage(imageIndexList[i], imagePath))
{
ok = false;
break;
}
imagePathList.push_back(imagePath);
HGChar suffix[256];
HGBase_GetFileSuffix(imagePath.c_str(), suffix, 256);
char name[256];
sprintf(name, "%d.%s", imageIndexList[i], suffix);
nameList.push_back(name);
}
if (!ok)
{
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return -1;
}
int ret = LocalMakeZipFile(imagePathList, nameList, outZipPath, errInfo);
for (int i = 0; i < (int)imagePathList.size(); ++i)
{
HGBase_DeleteFile(imagePathList[i].c_str());
}
return ret;
}
int ManagerV2::ImageDeskew(int imageIndex, std::string& outImagePath, std::string& errInfo)
{
outImagePath.clear();
errInfo.clear();
if (NULL == m_sqlite)
return -1;
std::string imagePath;
if (0 != SaveImage(imageIndex, imagePath))
{
return -1;
}
int ret = LocalImageDeskew(imagePath, outImagePath, errInfo);
HGBase_DeleteFile(imagePath.c_str());
return ret;
}
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;
}
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::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)
{
HGBase_CreateDir(m_globalCfg.fileSavePath.c_str());
char filePath[256] = { 0 };
while (1)
{
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());
}
#if defined(HG_CMP_MSC)
DWORD attr = GetFileAttributesA(filePath);
if (INVALID_FILE_ATTRIBUTES == attr)
break;
#else
struct stat buf;
int result = stat(lineContent, &buf);
if (0 != result)
break;
#endif
}
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
struct stat buf;
int result = stat(lineContent, &buf);
if (0 == result && 0 == (S_IFDIR & buf.st_mode))
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();
HGUInt mask = 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;
mask |= DeviceParam::colorModeMask;
}
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;
mask |= DeviceParam::pageModeMask;
}
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;
mask |= DeviceParam::paperSizeMask;
}
}
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;
mask |= DeviceParam::resolutionMask;
}
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;
mask |= DeviceParam::brightnessMask;
}
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;
mask |= DeviceParam::contrastMask;
}
}
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);
mask |= DeviceParam::gammaMask;
}
else if (0 == strcmp(OPTION_TITLE_SMQYZCmm, desp->title))
{
devParam.paperCutLeft = SANE_UNFIX(value);
mask |= DeviceParam::paperCutLeftMask;
}
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);
mask |= DeviceParam::paperCutRightMask;
}
else if (0 == strcmp(OPTION_TITLE_SMQYSCmm, desp->title))
{
devParam.paperCutTop = SANE_UNFIX(value);
mask |= DeviceParam::paperCutTopMask;
}
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);
mask |= DeviceParam::paperCutBottomMask;
}
}
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;
mask |= DeviceParam::autoCropMask;
}
else if (0 == strcmp(OPTION_TITLE_ZDYSMQY, desp->title))
{
devParam.paperCutEnabled = (bool)value;
mask |= DeviceParam::paperCutEnabledMask;
}
}
}
HGUInt stdMask = DeviceParam::colorModeMask | DeviceParam::pageModeMask | DeviceParam::resolutionMask | DeviceParam::brightnessMask
| DeviceParam::contrastMask | DeviceParam::gammaMask | DeviceParam::paperSizeMask | DeviceParam::paperCutEnabledMask
| DeviceParam::paperCutLeftMask | DeviceParam::paperCutTopMask | DeviceParam::paperCutRightMask | DeviceParam::paperCutBottomMask
| DeviceParam::autoCropMask;
if (mask != stdMask)
{
return -1;
}
return 0;
}
int ManagerV2::SaveImage(int imageIndex, std::string& imagePath)
{
imagePath.clear();
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);
HGChar tmpPath[256];
HGBase_GetTmpFileName(imgFmt.c_str(), tmpPath, 256);
if (SaveToFile((const HGByte*)imgData, imgSize, tmpPath))
{
imagePath = tmpPath;
rc = 0;
}
break;
}
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
return rc;
}
HGByte* ManagerV2::LoadImageFromPath(const std::string& imagePath, HGUInt& size, std::string& format)
{
size = 0;
format.clear();
HGUInt imgType = 0;
HGImgFmt_GetImgFmtType(imagePath.c_str(), &imgType);
if (0 == imgType)
return NULL;
std::string imgFormat;
if (HGIMGFMT_TYPE_JPEG == imgType)
imgFormat = "jpg";
else if (HGIMGFMT_TYPE_BMP == imgType)
imgFormat = "bmp";
else if (HGIMGFMT_TYPE_PNG == imgType)
imgFormat = "png";
else if (HGIMGFMT_TYPE_TIFF == imgType)
imgFormat = "tif";
else if (HGIMGFMT_TYPE_PDF == imgType)
imgFormat = "pdf";
else if (HGIMGFMT_TYPE_OFD == imgType)
imgFormat = "ofd";
if (imgFormat.empty())
return NULL;
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 NULL;
size = imgSize;
format = imgFormat;
return imgData;
}
HGByte* ManagerV2::LoadImageFromBase64(const std::string& imageBase64, HGUInt& size, std::string& format)
{
size = 0;
format.clear();
size_t pos = imageBase64.find(',');
if (std::string::npos == pos)
return NULL;
std::string imgFormat;
std::string prefix = imageBase64.substr(0, pos + 1);
if ("data:image/jpeg;base64," == prefix)
imgFormat = "jpg";
else if ("data:image/bmp;base64," == prefix)
imgFormat = "bmp";
else if ("data:image/png;base64," == prefix)
imgFormat = "png";
else if ("data:image/tiff;base64," == prefix)
imgFormat = "tif";
else if ("data:image/pdf;base64," == prefix)
imgFormat = "pdf";
else if ("data:image/ofd;base64," == prefix)
imgFormat = "ofd";
if (imgFormat.empty())
return NULL;
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 NULL;
size = imgSize;
format = imgFormat;
return imgData;
}
HGByte* ManagerV2::LoadThumbFromPath(const std::string& imagePath, HGUInt& size)
{
size = 0;
HGUInt imgType = 0;
HGImgFmt_GetImgFmtType(imagePath.c_str(), &imgType);
if (0 == imgType)
return NULL;
HGImage img = NULL;
HGImgFmt_LoadImage(imagePath.c_str(), imgType, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL == img)
return NULL;
HGImageInfo imgInfo;
HGBase_GetImageInfo(img, &imgInfo);
HGUInt width = imgInfo.width;
HGUInt height = imgInfo.height;
if (width >= height)
{
if (width > 240)
{
width = 240;
height = HGMAX((HGUInt)(240.0 * imgInfo.height / imgInfo.width + 0.5), 1);
}
}
else
{
if (height > 240)
{
height = 240;
width = HGMAX((HGUInt)(240.0 * imgInfo.width / imgInfo.height + 0.5), 1);
}
}
HGImage img2 = NULL;
HGBase_CreateImage(width, height, imgInfo.type, HGBASE_IMGORIGIN_TOP, &img2);
if (NULL == img2)
{
HGBase_DestroyImage(img);
return NULL;
}
HGImgProc_ResizeImage(img, img2, HGIMGPROC_INTERPOTYPE_NN);
HGBase_DestroyImage(img);
HGChar tmpName[256];
HGBase_GetTmpFileName(NULL, tmpName, 256);
HGResult ret = HGImgFmt_SaveImage(img2, imgType, NULL, tmpName);
HGBase_DestroyImage(img2);
if (HGBASE_ERR_OK != ret)
{
return NULL;
}
HGByte* imgData = NULL;
HGUInt imgSize = 0;
FILE* file = fopen(tmpName, "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);
}
HGBase_DeleteFile(tmpName);
if (NULL == imgData)
return NULL;
size = imgSize;
return imgData;
}
HGByte* ManagerV2::LoadThumbFromBase64(const std::string& imageBase64, HGUInt& size)
{
size = 0;
size_t pos = imageBase64.find(',');
if (std::string::npos == pos)
return NULL;
HGChar tmpName[256];
HGBase_GetTmpFileName(NULL, tmpName, 256);
if (0 != SaveBase64(imageBase64.c_str() + pos + 1, tmpName))
return NULL;
HGByte* data = LoadThumbFromPath(tmpName, size);
HGBase_DeleteFile(tmpName);
return data;
}
bool ManagerV2::SaveToBase64(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;
return true;
}
bool ManagerV2::SaveToFile(const HGByte* data, HGUInt size, const std::string& filePath)
{
assert(NULL != data && 0 != size);
bool ret = false;
FILE* file = fopen(filePath.c_str(), "wb");
if (NULL != file)
{
size_t writeLen = fwrite(data, 1, size, file);
if (writeLen == (size_t)size)
ret = true;
fclose(file);
}
if (!ret)
HGBase_DeleteFile(filePath.c_str());
return ret;
}
void ManagerV2::GetBatchTableInfo(std::vector<BatchTableInfo>& tables)
{
tables.clear();
char** result = NULL;
char sql[256];
sprintf(sql, "select id, idx, format 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++)
{
BatchTableInfo info;
for (int j = 0; j < cols; j++)
{
if (0 == strcmp("id", result[j]))
{
info.id = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("idx", result[j]))
{
info.idx = atoi(result[(i + 1) * cols + j]);
}
else if (0 == strcmp("format", result[j]))
{
info.format = result[(i + 1) * cols + j];
}
}
tables.push_back(info);
}
sqlite3_free_table(result);
std::sort(tables.begin(), tables.end(), BatchTableSort);
}
void ManagerV2::ClearBindFolder()
{
assert(!m_bindFolder.empty());
char szFind[MAX_PATH];
sprintf(szFind, "%s*.*", m_bindFolder.c_str());
WIN32_FIND_DATAA FindFileData;
HANDLE hFind = FindFirstFileA(szFind, &FindFileData);
if (INVALID_HANDLE_VALUE == hFind)
return;
do
{
if (0 == (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
char fileName[MAX_PATH];
sprintf(fileName, "%s%s", m_bindFolder.c_str(), FindFileData.cFileName);
HGBase_DeleteFile(fileName);
}
} while (FindNextFileA(hFind, &FindFileData));
FindClose(hFind);
}
void ManagerV2::UpdateBindFolder()
{
assert(!m_bindFolder.empty());
if (NULL == m_sqlite)
return;
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);
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);
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
char imagePath[256];
sprintf(imagePath, fmt, m_bindFolder.c_str(), m_bindNameBase + idx, imgFmt.c_str());
HGBase_CreateDir(m_bindFolder.c_str());
SaveToFile((const HGByte*)imgData, imgSize, imagePath);
ret = sqlite3_step(stmt);
}
ret = sqlite3_finalize(stmt);
assert(0 == ret);
}
void ManagerV2::InsertBindFolderImage(const std::vector<BatchTableInfo>& tables, int insertPos, const std::string imgFmt,
const HGByte* imgData, HGUInt imgSize)
{
assert(!m_bindFolder.empty());
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
for (int i = (int)tables.size() - 1; i >= 0; --i)
{
if (tables[i].idx >= insertPos)
{
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[i].idx, tables[i].format.c_str());
char destName[256];
sprintf(destName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[i].idx + 1, tables[i].format.c_str());
MoveFileA(fileName, destName);
}
}
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + insertPos, imgFmt.c_str());
SaveToFile(imgData, imgSize, fileName);
}
void ManagerV2::ModifyBindFolderImage(const std::vector<BatchTableInfo>& tables, int imageIndex, const std::string imgFmt,
const HGByte* imgData, HGUInt imgSize)
{
assert(!m_bindFolder.empty());
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
std::string oldFormat;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx == imageIndex)
{
oldFormat = tables[i].format;
break;
}
}
char oldFileName[256];
sprintf(oldFileName, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex, oldFormat.c_str());
HGBase_DeleteFile(oldFileName);
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex, imgFmt.c_str());
SaveToFile(imgData, imgSize, fileName);
}
void ManagerV2::DeleteBindFolderImage(const std::vector<BatchTableInfo>& tables, const std::vector<int>& imageIndexList)
{
assert(!m_bindFolder.empty());
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
for (int i = 0; i < (int)imageIndexList.size(); ++i)
{
for (int j = 0; j < (int)tables.size(); ++j)
{
if (tables[j].idx == imageIndexList[i])
{
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[j].idx, tables[j].format.c_str());
HGBase_DeleteFile(fileName);
break;
}
}
}
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].idx == imageIndexList[j])
{
find = true;
break;
}
}
if (find)
{
++value;
}
else
{
if (value > 0)
{
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[i].idx, tables[i].format.c_str());
char destName[256];
sprintf(destName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[i].idx - value, tables[i].format.c_str());
MoveFileA(fileName, destName);
}
}
}
}
void ManagerV2::ExchangeBindFolderImage(const std::vector<BatchTableInfo>& tables, int imageIndex1, int imageIndex2)
{
assert(!m_bindFolder.empty());
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
std::string format1, format2;
for (int i = 0; i < (int)tables.size(); ++i)
{
if (tables[i].idx == imageIndex1)
format1 = tables[i].format;
else if (tables[i].idx == imageIndex2)
format2 = tables[i].format;
}
char fileName1[256];
sprintf(fileName1, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex1, format1.c_str());
char TmpFileName[256];
sprintf(TmpFileName, "%sTemp", m_bindFolder.c_str());
MoveFileA(fileName1, TmpFileName);
char fileName2[256];
sprintf(fileName2, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex2, format2.c_str());
char fileName2Dest[256];
sprintf(fileName2Dest, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex1, format2.c_str());
MoveFileA(fileName2, fileName2Dest);
char fileName1Dest[256];
sprintf(fileName1Dest, fmt, m_bindFolder.c_str(), m_bindNameBase + imageIndex2, format1.c_str());
MoveFileA(TmpFileName, fileName1Dest);
}
void ManagerV2::ClearBindFolderImageList(const std::vector<BatchTableInfo>& tables)
{
assert(!m_bindFolder.empty());
char fmt[24];
sprintf(fmt, "%%s%%0%dd.%%s", m_bindNameWidth);
for (int i = 0; i < (int)tables.size(); ++i)
{
char fileName[256];
sprintf(fileName, fmt, m_bindFolder.c_str(), m_bindNameBase + tables[i].idx, tables[i].format.c_str());
HGBase_DeleteFile(fileName);
}
}
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;
}
}