twain3.0/huagao/Device/ImageMatQueue.cpp

678 lines
20 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 "StdAfx.h"
#include "ImageMatQueue.h"
#include "PublicFunc.h"
#include "ImageProcess/ImageApplyHeaders.h"
#include "ImageMultiOutput.h"
#include "filetools.h"
#include <math.h>
#include "StopWatch.h"
using namespace cv;
using namespace std;
#define DECODE_COLOR_BGR 1
#define DECODE_GRAY 6
ImageMatQueue::ImageMatQueue(void)
: bRun(false)
, is_scanning(false)
, fx(1.001)
, fy(1.007)
, DogEar_index(0)
, is_DogEar(false)
, benablecache(false)
{
atm_orgin_image_remains = 0;
m_dogear.reset(new CImageApplyDogEarDetection(40, 1.0, 200));
m_snowflake.init(1, 1);
}
ImageMatQueue::~ImageMatQueue(void)
{
m_rawBuffs.Clear();
m_rawBuffs.ShutDown();
clear_cachefiles();
m_imgCacheinfo.ShutDown();
m_imagedata.Clear();
m_imagedata.ShutDown();
if (m_threadProc.get()) {
bRun = false;
m_threadProc->join();
m_threadProc.reset();
}
if (m_threadcache.get())
{
benablecache = false;
if (m_threadcache->joinable())
{
m_threadcache->join();
m_threadcache.reset();
}
}
}
void ImageMatQueue::run()
{
init_cachethread();
if (!m_threadProc.get()) {
bRun = true;
m_threadProc.reset(new thread(&ImageMatQueue::proc, this));
}
}
bool ImageMatQueue::get_isDogEar()
{
return is_DogEar;
}
void ImageMatQueue::reset_DogEar()
{
is_DogEar = false;
DogEar_index = 0;
}
int ImageMatQueue::orginimgcount()
{
return atm_orgin_image_remains;
}
void ImageMatQueue::updatefixratio(float& hratio, float& vratio)
{
if (hratio > 0.10f && hratio < 3.0f && vratio >0.10f && vratio < 3.0f) {
this->fx = hratio;
this->fy = vratio;
}
else
{
FileTools::writelog(log_ERROR, "error horizental or vertical ratio");
}
}
void ImageMatQueue::SetGetimgnumcall(std::function<void(bool, int)> getimgnumcall)
{
m_Getimagenumber = getimgnumcall;
}
void ImageMatQueue::SetDogEarCallback(std::function<void(int)> dogearcall)
{
m_DogEarDetection_callback = dogearcall;
}
static int paperIndex = 0;
void ImageMatQueue::pushMat(std::shared_ptr<IDecode> data)
{
if (m_Getimagenumber)
{
#ifdef UV
if (scanParam.hardwarecaps.en_uv)
m_Getimagenumber(true, 2);
else
m_Getimagenumber(true, 1);
#else
m_Getimagenumber(true, 1);
#endif
}
m_rawBuffs.Put(data);
atm_orgin_image_remains++;
//string paperindexinfo = "Get the index of "+to_string(++paperIndex)+" Paper";
//FileTools::write_log("D:\\1.txt", paperindexinfo);
}
std::shared_ptr<std::vector<unsigned char>> ImageMatQueue::popBmpdata()
{
return m_imagedata.Take();
}
bool ImageMatQueue::valid()
{
return m_imagedata.Size();
}
void ImageMatQueue::clear()
{
m_rawBuffs.Clear();
clear_cachefiles();
m_imagedata.Clear();
atm_orgin_image_remains = 0;
}
void ImageMatQueue::rawBuffsclear()
{
m_rawBuffs.Clear();
}
void ImageMatQueue::setparam(const GScanCap& param)
{
paperIndex = 0;
ischeck_dogear = param.is_dogeardetection;
//FileTools::write_log("D:\\1.txt", "RESET PAPER COUNT");
scanParam = param;
//scanParam.is_duplex = 0;
//scanParam.imageRotateDegree = 90.0f;
m_iaList.clear();
if (scanParam.fillhole.is_fillhole) {
float ratio = scanParam.fillhole.fillholeratio / 100.0;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageOutHole(200, ratio, 50)));
} //ȷ<><C8B7><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
{
bool islongcustomcrop = param.papertype == TwSS::USStatement;
//bool isautocrop = param.papertype == TwSS::None;
CSize fixedSize;
#ifdef REAL300DPI
fixedSize = papersize.GetPaperSize(param.papertype, param.resolution_dst > 240.0f ? 300.0f : 200.0f, param.paperAlign);
#else // REAL300DPI
fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign);
#endif
bool normalCrop = ((param.autodescrew) || (islongcustomcrop ? islongcustomcrop : param.is_autocrop) || (param.fillbackground)) ? false : param.normalCrop;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop,
param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent, normalCrop)));
/* m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(true, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex, false, param.AutoCrop_threshold, param.noise, param.indent)));
if(!(islongcustomcrop ? islongcustomcrop : param.is_autocrop))
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(fixedSize.cx, fixedSize.cy), 1.0, 1.0)));*/
}
if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) {
//m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank()));
CImageApplyDiscardBlank* disBlank = new CImageApplyDiscardBlank();
//<2F><><EFBFBD><EFBFBD><EFBFBD>հ<EFBFBD>ҳ<EFBFBD><D2B3>ֵ
int area = 200;
int intensity = 15;
int maxHeight = 3307;//A3 height
//ҳ<><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶Ȼ<DFB6>ȡ
if (param.papertype == TwSS::MaxSize)
maxHeight = 6614;
//<2F><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
if (param.discardblank_percent < 10) {
area = 70 + (int)((param.discardblank_percent - 1) * 13.33);
intensity = 8 + param.discardblank_percent / 2;
}
else if (param.discardblank_percent < 20) {
area = 190 + (param.discardblank_percent - 10) * 14;
intensity = 15;
}
else if (param.discardblank_percent < 40) {
area = 400 + (param.discardblank_percent - 20) * 10;
intensity = 20;
}
else if (param.discardblank_percent < 60) {
area = 600 + (param.discardblank_percent - 40) * 20;
intensity = 20;
}
else if (param.discardblank_percent < 80) {
area = 1000 + (param.discardblank_percent - 60) * 55;
intensity = 30;
}
else {
area = 2100 + (param.discardblank_percent - 80) * (maxHeight - 2100) / 20;
intensity = 40;
}
//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>հ<EFBFBD>ҳ<EFBFBD><D2B3>Ʊ
if (param.is_autodiscradblank_vince) {
area *= 1.5;
intensity *= 1.5;
}
//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>ֵ
disBlank->setMinArea(area);
disBlank->setIntensity(intensity);
m_iaList.push_back(shared_ptr<CImageApply>(disBlank));
//m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(param.areanum,param.devnmax)));
}
//filter 0 r 1 g 2 b 3 none enhance color 0 none 1 r 2 g 3 b
if (param.filter != 3 || param.enhance_color) {
int channel = 0; //filter none r g b enhance none r g b
if (param.filter != 3) { channel = param.filter; }
else { channel = param.enhance_color + 4; }
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyChannel(static_cast<CImageApplyChannel::Channel>(channel))));
}
if (param.brightness != 0 || param.contrast != 0 || param.gamma != 1.0) {
double aa = (254 / 2000.0) * param.brightness + 0.5;
int bright = ceil(aa);//[-127,128] 0.128=256.0/2000.0
int contrast = 0.0; //= (int)(param.contrast * 0.036);;//[-36,36] 0.036=72.0/2000.0;
if (param.contrast < 0.0) // <20>ݲ<EFBFBD><DDB2>޸ĶԱȶȣ<C8B6><C8A3><EFBFBD>ɫ<EFBFBD>ĸ<EFBFBD>ɫƫ
contrast = (int)(param.contrast * 0.036);
else
contrast = (int)(param.contrast * 0.018);
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAdjustColors(bright, contrast, param.gamma)));
}
//<2F><><EFBFBD><EFBFBD><E2BFA8><EFBFBD><EFBFBD>
if (scanParam.hsvcorrect)
{
m_iaList.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::Red_Removal)));
}
//<2F><><EFBFBD><EFBFBD>
if (param.sharpen) {
SharpenBlur sb = (SharpenBlur)param.sharpen;
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplySharpen(sb)));
}
//<2F>Զ<EFBFBD><D4B6><EFBFBD>ɫʶ<C9AB><CAB6>
if (param.automaticcolor)
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyColorRecognition(param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono)));
//<2F><><EFBFBD><EFBFBD>
if (param.resolution_dst != param.resolution_native)
{
CImageApplyResize* apply;
bool islongcustomcrop = false;
if (param.papertype == TwSS::USStatement)
islongcustomcrop = true;
if (param.is_autocrop || islongcustomcrop) {
double ratio = param.resolution_dst / 200.0;//
apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio);
}
else {
CSize dSize = papersize.GetPaperSize(param.papertype, param.resolution_dst, param.paperAlign);
apply = new CImageApplyResize(CImageApplyResize::ResizeType::DSIZE, cv::Size(dSize.cx, dSize.cy), 1.0, 1.0);
}
m_iaList.push_back(shared_ptr< CImageApply>(apply));
}
//<2F><>ֵ<EFBFBD><D6B5>
if (param.pixtype == 0) //threshold
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyBWBinaray(CImageApplyBWBinaray::ThresholdType::THRESH_BINARY)));
//<2F>ڰ׽<DAB0><D7BD><EFBFBD><EFBFBD>Ż<EFBFBD>
if (scanParam.detachnoise.is_detachnoise && scanParam.pixtype == 0)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDetachNoise(scanParam.detachnoise.detachnoise)));
}
if (scanParam.en_fold)
{
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyConcatenation(CImageApplyConcatenation::horizontal, cv::Scalar(255, 255, 255))));
}
if (param.imageRotateDegree != 0.0 || param.is_backrotate180 || param.is_autotext)
{
CImageApplyRotation::RotationType type;
if (param.imageRotateDegree > 89.0f && param.imageRotateDegree < 91.0f)
type = CImageApplyRotation::RotationType::Rotate_90_clockwise;
else if (param.imageRotateDegree > 269.0f && param.imageRotateDegree < 271.0f)
type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
else if (param.imageRotateDegree > 179.0f && param.imageRotateDegree < 181.0f)
type = CImageApplyRotation::RotationType::Rotate_180;
else
type = CImageApplyRotation::RotationType::Invalid;
if (param.is_autotext)
type = CImageApplyRotation::RotationType::AutoTextOrientation;
TCHAR szIniFile[MAX_PATH] = { 0 };
SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_WINDOWS, TRUE);
#ifdef LANXUM
_tcscat(szIniFile, _T("\\twain_32\\LANXUMSCAN\\tessdata"));
#else
_tcscat(szIniFile, _T("\\twain_32\\HuaGoScan\\tessdata"));
#endif //
int iLen = WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, NULL, 0, NULL, NULL);
char* chRtn = new char[iLen * sizeof(char)];
WideCharToMultiByte(CP_ACP, 0, szIniFile, -1, chRtn, iLen, NULL, NULL);
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(type, param.is_backrotate180, param.resolution_dst, chRtn)));
delete[] chRtn;
}
}
void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr<std::vector<unsigned char>> bmpdata)
{
m_imagedata.Put(bmpdata);
int aa = 0;
}
void ImageMatQueue::PaniusCount(int count)
{
atm_orgin_image_remains -= count;
#ifdef UV
if (scanParam.hardwarecaps.en_uv)
{
if (m_Getimagenumber)
m_Getimagenumber(false, 2);
}
else
if (m_Getimagenumber)
m_Getimagenumber(false, 1);
#else
if (m_Getimagenumber)
m_Getimagenumber(false, 1);
#endif
}
void ImageMatQueue::init_cachethread()
{
if (!m_threadcache.get())
{
benablecache = true;
m_threadcache.reset(new thread(&ImageMatQueue::cache_run, this));
}
}
static int index = 0;
void ImageMatQueue::cache_run()
{
std::ios::sync_with_stdio(false);
while (benablecache)
{
if (m_rawBuffs.Size() == 0)
{
this_thread::sleep_for(chrono::milliseconds(2));
continue;
}
if (m_rawBuffs.Size() > 0)
{
CacheInfo info;
auto buffs = m_rawBuffs.Take()->getImageBuffs();
buffs.size() == 2 ? info.scannerType = ScannerSerial::G200Serial : info.scannerType = ScannerSerial::G400Serial;
for (auto& buf : buffs)
{
StopWatch sw;
index++;
string path = FileTools::get_appdata_path() + to_string(m_snowflake.nextid()) + ".jpg";
if (!access(path.c_str(), 0))
{
remove(path.c_str());
FileTools::writelog(log_ERROR, "exist file " + path + " maybe lost previous session scanned image");
}
CFile frb;
if (frb.Open(CString(path.c_str()), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
{
if (*(buf->data()) != -1 && *(buf->data() + 1) != -40 && *(buf->data() + 2) != -1 && *(buf->data() + 3) != -32)
{
frb.Write(buf->data() + 12, buf->size() - 12);
FileTools::writelog(log_ERROR, "usb data error -image data");
}
else
frb.Write(buf->data(), buf->size());
frb.Flush();
frb.Close();
info.path = path;
m_imgCacheinfo.Put(info);
}
else
{
FileTools::writelog(log_ERROR, "error while openning cache file :" + path);
}
FileTools::writelog(log_INFO, " <20><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ͼƬ<CDBC><C6AC><EFBFBD>ݺ<EFBFBD>ʱ " + to_string(sw.elapsed_ms()) + " buffer size = " + to_string(buf->size()));
buf->clear();
buf.reset();
sw.reset();
}
}
}
}
void ImageMatQueue::clear_cachefiles()
{
while (m_imgCacheinfo.Size() > 0)
{
auto tpath = m_imgCacheinfo.Take();
if (isFileExist(tpath.path))
remove(tpath.path.c_str());
}
}
bool ImageMatQueue::empty()
{
return m_imgCacheinfo.Size() == 0 && (m_imagedata.Size() == 0) && (m_rawBuffs.Size() == 0) && !is_scanning && atm_orgin_image_remains == 0;
}
bool ImageMatQueue::queuesempty()
{
return atm_orgin_image_remains <= 0 && m_imagedata.Size() == 0;
}
void ImageMatQueue::proc()
{
while (bRun)
{
string msg;
auto info = m_imgCacheinfo.Take();
if (info.path.length() == 0 || !isFileExist(info.path))
{
msg = "error while checking file :" + info.path + " ,file lost";
FileTools::writelog(log_ERROR, msg);
continue;
}
ImreadModes rmc;
if (scanParam.filter != 3 || scanParam.enhance_color || scanParam.hsvcorrect)
rmc = IMREAD_COLOR;
else
rmc = scanParam.pixtype == 2 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
std::vector<cv::Mat> mats;
std::vector<Mat> uvmats;
StopWatch sw;
if (info.scannerType == ScannerSerial::G200Serial)
{
auto back = m_imgCacheinfo.Take();
if (!isFileExist(back.path))
{
msg = "error while reading g200 back image " + back.path + " ,file not exist";
FileTools::writelog(log_ERROR, msg);
}
sw.reset();
auto imgfront = imread(info.path, rmc);
msg = "reading image front time elapsed_ms:" + std::to_string(sw.elapsed_ms());
FileTools::writelog(log_ERROR, msg);
sw.reset();
auto imgback = imread(back.path, rmc);
msg = "reading image back time elapsed_ms:" + std::to_string(sw.elapsed_ms());
FileTools::writelog(log_ERROR, msg);
sw.reset();
if (!imgfront.empty() && !imgback.empty())
{
mats.push_back(scanParam.is_switchfrontback ? imgback : imgfront);
mats.push_back(scanParam.is_switchfrontback ? imgfront : imgback);
remove(info.path.c_str());
remove(back.path.c_str());
}
else
{
msg = "get empty mat! empty ";
msg += (imgfront.empty() ? " front image" : " back image");
FileTools::writelog(log_ERROR, msg);
}
for (size_t i = 0; i < mats.size(); i++)
{
if (!mats[i].empty())
cv::resize(mats[i], mats[i], cv::Size(), fx, fy);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׶<EFBFBD>
}
if (scanParam.en_fold != 0) {
cv::flip(mats[0], mats[0], 1);
cv::flip(mats[0], mats[0], 0);
}
}
else
{
auto mat = imread(info.path, rmc);
if (!mat.empty())
{
Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows));
Mat back = mat(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows));
#ifdef UV
mats.push_back(scanParam.is_switchfrontback ? front : back);
mats.push_back(scanParam.is_switchfrontback ? back : front);
#else
if (scanParam.imageRotateDegree != 0.0 && scanParam.imageRotateDegree != 180.0) {
cv::flip(front, front, 0);
cv::flip(front, front, 1);
}
mats.push_back(back);
mats.push_back(front);
#endif
front.release();
back.release();
remove(info.path.c_str());
}
else
{
msg = "g400 get empty mat! empty ";
FileTools::writelog(log_ERROR, msg);
}
#ifdef UV
if (scanParam.hardwarecaps.en_uv)//EN UV
{
auto uvinfo = m_imgCacheinfo.Take();
auto matuv = imread(uvinfo.path, IMREAD_COLOR);
if (!matuv.empty())
{
Mat front = matuv(Rect(0, 0, mat.cols / 2, mat.rows));
Mat back = matuv(Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows));
uvmats.push_back(scanParam.is_switchfrontback ? front : back);
uvmats.push_back(scanParam.is_switchfrontback ? back : front);
front.release();
back.release();
remove(uvinfo.path.c_str());
}
}
#endif
}//g400 serials
std::vector<cv::RotatedRect> rects;
std::vector<int> angleResults;
bool isDesaskew = false;
sw.reset();
for (int j = 0; j < m_iaList.size(); j++) {
m_iaList[j]->apply(mats, scanParam.is_duplex);
CImageApply* ptr = m_iaList[j].get();
if (typeid(*ptr) == typeid(CImageApplyAutoCrop))
{
rects = dynamic_cast<CImageApplyAutoCrop*>(ptr)->rotatedROIs();
isDesaskew = dynamic_cast<CImageApplyAutoCrop*>(ptr)->isDesaskew();
}
else if (typeid(*ptr) == typeid(CImageApplyRotation))
angleResults = dynamic_cast<CImageApplyRotation*>(ptr)->angleResults();
}
#ifdef UV
if (!uvmats.empty())
{
//ƴ<><C6B4>ԭͼ<D4AD><CDBC>UVͼ
for (int j = 0; j < mats.size(); j++)
{
if (!scanParam.is_duplex && j == 1) {
mats[j].release();
break;
}
cv::Mat mergeOrgin_UV = ImageApplyUV::Apply(mats[j], uvmats[j], rects[j], isDesaskew, angleResults.size() > 0 ? angleResults[j] : 0, scanParam.pixtype);
if (!mergeOrgin_UV.empty())
mats[j] = mergeOrgin_UV;
}
uvmats.clear();
}
#endif
FileTools::writelog(log_INFO, "ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ " + to_string(sw.elapsed_ms()));
sw.reset();
for (int i = 0; i < mats.size(); i++) {
if (!scanParam.is_duplex && i == 1) {
mats[i].release();
break;
}
if (!mats[i].empty()) {
IMat2Bmp idata;
#ifdef UV
if (scanParam.pixtype == 1 && mats[i].channels() == 3)//gray
cv::cvtColor(mats[i], mats[i], COLOR_BGR2GRAY);
#else
if (scanParam.pixtype == 1 && scanParam.hsvcorrect)
if (mats[i].channels() == 3)
cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY);
#endif
idata = (scanParam.pixtype == 0 || (((scanParam.automaticcolortype == 0) && (scanParam.automaticcolor == true)) && (mats[i].channels() == 1))) ? (IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i], scanParam.resolution_dst);
if (!scanParam.multi_output_red)
mats[i].release();
auto data = idata.getBmpDataBuffer();
EnqueueBmpBuffer(data);
data.reset();
}
else
{
FileTools::writelog(log_ERROR, "enqueue image is empty " + std::to_string(index++));
}
}
FileTools::writelog(log_INFO, "ת<EFBFBD><EFBFBD>BMP <20><>ʱ<EFBFBD><CAB1> " + to_string(sw.elapsed_ms()));
sw.reset();
if (scanParam.multi_output_red) {
for (int i = 0; i < mats.size(); i++) {
if (!mats[i].empty()) {
ImageMultiOutput m_mlt;
Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2);
mats[i].release();
if (!ret.empty()) {
if (!scanParam.is_duplex && i == 1) {
ret.release();
break;
}
Mat2Bmp mb(ret, scanParam.resolution_dst);
auto data = mb.getBmpDataBuffer();
ret.release();
EnqueueBmpBuffer(data);
data.reset();
}
}
}
FileTools::writelog(log_INFO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ʱ<EFBFBD><CAB1> " + to_string(sw.elapsed_ms()));
}
mats.clear();
#ifdef UV
PaniusCount(scanParam.hardwarecaps.en_uv ? 2 : 1);
#else
PaniusCount();
#endif
}
}
G400Decode::G400Decode(std::shared_ptr<std::vector<char>> buff)
{
m_buffs.push_back(buff);
}
G200Decode::G200Decode(std::shared_ptr<std::vector<char>> buff)
{
const int int_buffer_size = 1024;
int buffer_size = buff->size();
int b_buffer_size = 0;
int f_buffer_size = 0;
std::shared_ptr<std::vector<char>> buffB(new std::vector<char>(buff->size()));
std::shared_ptr<std::vector<char>> buffF(new std::vector<char>(buff->size()));;
unsigned char* bbuf = (unsigned char*)(buffB->data());
unsigned char* fbuf = (unsigned char*)(buffF->data());
unsigned char* buf = (unsigned char*)(buff->data());
for (int i = 0; i < (buffer_size / int_buffer_size); i++) {
if (buf[(i + 1) * int_buffer_size - 1] == 0) {
memcpy(bbuf + b_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
b_buffer_size += (int_buffer_size - 1);
}
else if (buf[(i + 1) * int_buffer_size - 1] == 255) {
memcpy(fbuf + f_buffer_size, buf + i * int_buffer_size, int_buffer_size - 1);
f_buffer_size += (int_buffer_size - 1);
}
}
buffB->resize(b_buffer_size);
buffF->resize(f_buffer_size);
m_buffs.push_back(buffB);
m_buffs.push_back(buffF);
buff.reset();
}