#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 #include #include namespace ver_2 { 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; } ManagerV2::~ManagerV2() { DeinitDevice(); HGBase_DestroyLock(m_lock); m_lock = NULL; } void ManagerV2::CloseDev(const CloseDevParam* param) { assert(NULL != param && this == param->mgr); if (m_devName == param->devName) { CloseDevice(); } } 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) { if ("date_time" != cfg.fileNameMode && "random" != cfg.fileNameMode) return -1; if ("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 (cfg.imageJpegQuality < 0 || cfg.imageJpegQuality > 100) return -1; if ("none" != cfg.imageTiffCompression && "lzw" != cfg.imageTiffCompression && "jpeg" != cfg.imageTiffCompression && "ccitt-g4" != cfg.imageTiffCompression) return -1; if (cfg.imageTiffJpegQuality < 0 || cfg.imageTiffJpegQuality > 100) return -1; HGBase_EnterLock(m_lock); m_globalCfg = cfg; m_globalCfg.fileSavePath.push_back('/'); HGChar stdSavePath[256]; HGBase_StandardiseFileName(m_globalCfg.fileSavePath.c_str(), stdSavePath, 256); m_globalCfg.fileSavePath = stdSavePath; HGBase_LeaveLock(m_lock); SetCfgStringValue("global", "fileSavePath", m_globalCfg.fileSavePath); SetCfgStringValue("global", "fileNamePrefix", m_globalCfg.fileNamePrefix); SetCfgStringValue("global", "fileNameMode", m_globalCfg.fileNameMode); SetCfgStringValue("global", "imageFormat", m_globalCfg.imageFormat); SetCfgIntValue("global", "imageJpegQuality", m_globalCfg.imageJpegQuality); SetCfgStringValue("global", "imageTiffCompression", m_globalCfg.imageTiffCompression); SetCfgIntValue("global", "imageTiffJpegQuality", m_globalCfg.imageTiffJpegQuality); SetCfgStringValue("global", "uploadHttpHost", m_globalCfg.uploadHttpHost); SetCfgIntValue("global", "uploadHttpPort", m_globalCfg.uploadHttpPort); SetCfgStringValue("global", "uploadHttpPath", m_globalCfg.uploadHttpPath); SetCfgStringValue("global", "uploadFtpUser", m_globalCfg.uploadFtpUser); SetCfgStringValue("global", "uploadFtpPassword", m_globalCfg.uploadFtpPassword); SetCfgStringValue("global", "uploadFtpHost", m_globalCfg.uploadFtpHost); SetCfgIntValue("global", "uploadFtpPort", m_globalCfg.uploadFtpPort); return 0; } int ManagerV2::GetGlobalConfig(GlobalConfig& cfg) { cfg = m_globalCfg; return 0; } int ManagerV2::LoadLocalImage(const std::string& imagePath, std::string& imgBase64) { imgBase64.clear(); 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); return 0; } int ManagerV2::SaveLocalImage(const std::string& imgBase64, std::string& imagePath) { imagePath.clear(); 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); return 0; } int ManagerV2::DeleteLocalFile(const std::string& filePath) { int ret = -1; 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); ret = 0; } break; } } RestoreSaveFilePathList(m_saveFilePathList); HGBase_LeaveLock(m_lock); return ret; } int ManagerV2::ClearGlobalFileSavePath() { 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()); return 0; } int ManagerV2::MergeLocalImage(const std::vector& imagePathList, const std::string& mode, const std::string& align, int interval, std::string& outImagePath) { outImagePath.clear(); 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); } HGBase_DestroyImage(outImage); return ret; } int ManagerV2::LocalMakeMultiImage(const std::vector& imagePathList, const std::string& format, const std::string& tiffCompression, int tiffJpegQuality, std::string& outImagePath) { outImagePath.clear(); 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)) { 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& outImagePathList) { outImagePathList.clear(); 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); ret = 0; } HGBase_DestroyImage(img); } HGBase_ResetImageROI(image); } } HGBase_DestroyImage(image); } return ret; } int ManagerV2::LocalMakeZipFile(const std::vector& filePathList, std::string& outZipPath) { outZipPath.clear(); 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) { 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) { outImagePath.clear(); 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); 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) { 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); } return ret; } int ManagerV2::InitDevice() { if (m_initDevice) return -1; SANE_Int version_code = 0; SANE_Status status = sane_init_ex(&version_code, sane_ex_callback, this); assert(SANE_STATUS_GOOD == status); m_initDevice = true; return 0; } int ManagerV2::DeinitDevice() { if (m_initDevice) { CloseDevice(); sane_exit(); m_devNameList.clear(); m_initDevice = false; } return 0; } int ManagerV2::GetDeviceNameList(std::vector& deviceNameList) { deviceNameList.clear(); if (!m_initDevice) return -1; HGBase_EnterLock(m_lock); deviceNameList = m_devNameList; HGBase_LeaveLock(m_lock); return 0; } int ManagerV2::OpenDevice(const std::string& deviceName) { if (!m_initDevice || m_openDevice) return -1; std::string devName = deviceName; HGBase_EnterLock(m_lock); if (devName.empty() && m_devNameList.size() > 0) devName = m_devNameList[0]; HGBase_LeaveLock(m_lock); SANE_Handle dev = NULL; SANE_Status status = sane_open(devName.c_str(), &dev); if (SANE_STATUS_GOOD != status) return -1; m_devHandle = dev; m_devName = devName; // 加载m_devParam,并设置到设备 m_openDevice = true; return 0; } int ManagerV2::CloseDevice() { if (m_openDevice) { StopScan(); sane_close(m_devHandle); m_devHandle = NULL; m_devName.clear(); m_devParam.Reset(); m_openDevice = false; } return 0; } int ManagerV2::SetDeviceParam(const DeviceParam& param) { if (!m_openDevice || m_scanning) return -1; m_devParam = param; // 设置到设备 return 0; } int ManagerV2::GetDeviceParam(DeviceParam& param) { param.Reset(); if (!m_openDevice) return -1; param = m_devParam; return 0; } int ManagerV2::GetCurrDeviceName(std::string& deviceName) { deviceName = m_devName; return 0; } int ManagerV2::StartScan() { if (!m_openDevice || m_scanning) return -1; SANE_Status status = sane_start(m_devHandle); if (SANE_STATUS_GOOD != status) return -1; m_scanning = true; HGBase_CreateEvent(HGFALSE, HGFALSE, &m_scanEvent); assert(NULL != m_scanEvent); return 0; } int ManagerV2::StopScan() { if (m_scanning) { 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; } return 0; } 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; } 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::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& 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& 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); } } 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); 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; } }