re-construct

This commit is contained in:
gb 2023-11-20 14:31:14 +08:00
parent 47e802669c
commit 8901ca1fdf
62 changed files with 4457 additions and 18342 deletions

View File

@ -1,245 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.2, 2022-04-19T20:59:13. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{7ffe135c-9a6a-47fd-aa17-30ca7cc38f36}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">桌面</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">桌面</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{dd7642b7-8b16-4d2a-a3db-a41203cb41bc}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<valuelist type="QVariantList" key="CMake.Configuration">
<value type="QString">CMAKE_BUILD_TYPE:STRING=Debug</value>
</valuelist>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/huagao/Desktop/3.22code/sane-driver-rewrite/sane-driver-rewrite/hgdriver/build-hgdev-unknown-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<valuelist type="QVariantList" key="CMake.Configuration">
<value type="QString">CMAKE_BUILD_TYPE:STRING=Release</value>
</valuelist>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/huagao/Desktop/3.22code/sane-driver-rewrite/sane-driver-rewrite/hgdriver/build-hgdev-unknown-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">CMake Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Executable</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">20</value>
</data>
<data>
<variable>Version</variable>
<value type="int">20</value>
</data>
</qtcreator>

View File

@ -1,196 +0,0 @@
#ifndef ICONFIG_H
#define ICONFIG_H
// !ICONFIG_H
#include "predefine.h"
#include <map>
#include "PaperSize.h"
#ifndef unix
//typedef char byte;
#endif
enum G400_PaperSize {
G400_A3 = 0,
G400_A4,
G400_A4R,
G400_A5,
G400_A5R,
G400_A6,
G400_A6R,
G400_B4,
G400_B5,
G400_B5R,
G400_B6,
G400_B6R,
G400_DOUBLELETTER,
G400_LEGAL,
G400_LETTER,
G400_LETTERR,
G400_LONGLETTER,
G400_MAXSIZE
};
enum G400_DPI {
G400_D300 = 0,
G400_D200,
G400_D600
};
static std::map<unsigned short, unsigned int> SupPixelTypes = {
{0, 0},//bw
{1, 0},//gray
{2, 1}//color
};
static std::map<float, unsigned int> SupResolutions = {
{300.0f, 0},
{200.0f, 1},
{600.0f, 2}
};
static std::map<byte, byte> secrewMaps = {
{1,0},
{2,1},
{3,2},
{4,3},
{5,4}
};
typedef union Config_Param {
unsigned int value;
struct {
unsigned int paper : 5;
unsigned int color : 1;
unsigned int dpi : 2;
unsigned int double_feed_enbale : 1;
unsigned int stable_enbale : 1;
unsigned int screw_detect_enable : 1;
unsigned int screw_detect_level : 3;
unsigned int unused_one : 6;
unsigned int pc_correct : 1;
unsigned int unused_two : 11;
};
} ConfigParam;
static std::map<PaperStatus, unsigned int> SupPaperTyps_G100
{
{{TwSS::A3,PaperAlign::Rot0},0},
{{TwSS::A4,PaperAlign::Rot0},1},
{{TwSS::A4,PaperAlign::Rot270},2},
{{TwSS::A5,PaperAlign::Rot0 },2},
{{TwSS::A5,PaperAlign::Rot270},2},
{{TwSS::A6,PaperAlign::Rot0},2},
{{TwSS::A6,PaperAlign::Rot270},2},
{{TwSS::B4,PaperAlign::Rot0},0},
{{TwSS::B5,PaperAlign::Rot0},0},
{{TwSS::B5,PaperAlign::Rot270},1},
{{TwSS::B6,PaperAlign::Rot0},2},
{{TwSS::B6,PaperAlign::Rot270},2},
{{TwSS::USLetter,PaperAlign::Rot0},1},
{{TwSS::USLetter,PaperAlign::Rot270},2},
{{TwSS::USLedger,PaperAlign::Rot0},0},
{{TwSS::USLegal,PaperAlign::Rot0},0},
{{TwSS::None,PaperAlign::Rot0},0},
{{TwSS::USStatement,PaperAlign::Rot0},16},
{{TwSS::MaxSize,PaperAlign::Rot0},16}
};
static std::map<PaperStatus, unsigned int> SupPaperTyps_G300
{
{{TwSS::A4,PaperAlign::Rot270},G400_A4R},
{{TwSS::A5,PaperAlign::Rot0 },G400_A5},
{{TwSS::A5,PaperAlign::Rot270},G400_A5R},
{{TwSS::A6,PaperAlign::Rot0},G400_A6},
{{TwSS::A6,PaperAlign::Rot270},G400_A6R},
{{TwSS::B5,PaperAlign::Rot0},G400_B5},
{{TwSS::B5,PaperAlign::Rot270},G400_B5R},
{{TwSS::B6,PaperAlign::Rot0},G400_B6},
{{TwSS::B6,PaperAlign::Rot270},G400_B6R},
{{TwSS::USLetter,PaperAlign::Rot0},G400_LETTER},
{{TwSS::USLetter,PaperAlign::Rot270},G400_LETTERR},
{{TwSS::USLegal,PaperAlign::Rot0},G400_LEGAL},
{{TwSS::None,PaperAlign::Rot0},G400_A4},
};
static std::map<PaperStatus, unsigned int> SupPaperTyps_G400
{
{{TwSS::A3,PaperAlign::Rot0},G400_A3},
{{TwSS::A4,PaperAlign::Rot0},G400_A4},
{{TwSS::A4,PaperAlign::Rot270},G400_A4R},
{{TwSS::A5,PaperAlign::Rot0 },G400_A5},
{{TwSS::A5,PaperAlign::Rot270},G400_A5R},
{{TwSS::A6,PaperAlign::Rot0},G400_A6},
{{TwSS::A6,PaperAlign::Rot270},G400_A6R},
{{TwSS::B4,PaperAlign::Rot0},G400_B4},
{{TwSS::B5,PaperAlign::Rot0},G400_B5},
{{TwSS::B5,PaperAlign::Rot270},G400_B5R},
{{TwSS::B6,PaperAlign::Rot0},G400_B6},
{{TwSS::B6,PaperAlign::Rot270},G400_B6R},
{{TwSS::USLetter,PaperAlign::Rot0},G400_LETTER},
{{TwSS::USLetter,PaperAlign::Rot270},G400_LETTERR},
{{TwSS::USLedger,PaperAlign::Rot0},G400_DOUBLELETTER},
{{TwSS::USLegal,PaperAlign::Rot0},G400_LEGAL},
{{TwSS::None,PaperAlign::Rot0},G400_A3},
{{TwSS::MaxSize,PaperAlign::Rot0},G400_MAXSIZE},
{{TwSS::USStatement,PaperAlign::Rot0},G400_MAXSIZE}
};
// static std::map<PaperStatus, unsigned int> SupPaperTyps = {
// #ifdef G200SCANNER
// {{TwSS::A3,PaperAlign::Rot0},0},
// {{TwSS::A4,PaperAlign::Rot0},1},
// {{TwSS::A4,PaperAlign::Rot270},2},
// {{TwSS::A5,PaperAlign::Rot0 },2},
// {{TwSS::A5,PaperAlign::Rot270},2},
// {{TwSS::A6,PaperAlign::Rot0},2},
// {{TwSS::A6,PaperAlign::Rot270},2},
// {{TwSS::B4,PaperAlign::Rot0},0},
// {{TwSS::B5,PaperAlign::Rot0},0},
// {{TwSS::B5,PaperAlign::Rot270},1},
// {{TwSS::B6,PaperAlign::Rot0},2},
// {{TwSS::B6,PaperAlign::Rot270},2},
// {{TwSS::USLetter,PaperAlign::Rot0},1},
// {{TwSS::USLetter,PaperAlign::Rot270},2},
// {{TwSS::USLedger,PaperAlign::Rot0},0},
// {{TwSS::USLegal,PaperAlign::Rot0},0},
// {{TwSS::None,PaperAlign::Rot0},0},
// {{TwSS::USStatement,PaperAlign::Rot0},16},
// {{TwSS::MaxSize,PaperAlign::Rot0},16}
// #else
// {{TwSS::A3,PaperAlign::Rot0},G400_A3},
// {{TwSS::A4,PaperAlign::Rot0},G400_A4},
// {{TwSS::A4,PaperAlign::Rot270},G400_A4R},
// {{TwSS::A5,PaperAlign::Rot0 },G400_A5},
// {{TwSS::A5,PaperAlign::Rot270},G400_A5R},
// {{TwSS::A6,PaperAlign::Rot0},G400_A6},
// {{TwSS::A6,PaperAlign::Rot270},G400_A6R},
// {{TwSS::B4,PaperAlign::Rot0},G400_B4},
// {{TwSS::B5,PaperAlign::Rot0},G400_B5},
// {{TwSS::B5,PaperAlign::Rot270},G400_B5R},
// {{TwSS::B6,PaperAlign::Rot0},G400_B6},
// {{TwSS::B6,PaperAlign::Rot270},G400_B6R},
// {{TwSS::USLetter,PaperAlign::Rot0},G400_LETTER},
// {{TwSS::USLetter,PaperAlign::Rot270},G400_LETTERR},
// {{TwSS::USLedger,PaperAlign::Rot0},G400_DOUBLELETTER},
// {{TwSS::USLegal,PaperAlign::Rot0},G400_LEGAL},
// #ifdef G300SCANNER
// {{TwSS::None,PaperAlign::Rot0},G400_A4},
// #else // G300
// {{TwSS::None,PaperAlign::Rot0},G400_A3},
// #endif
// {{TwSS::MaxSize,PaperAlign::Rot0},G400_MAXSIZE},
// {{TwSS::USStatement,PaperAlign::Rot0},G400_MAXSIZE}
// #endif
// };
class IConfig
{
public:
IConfig(void) {};
virtual ~IConfig(void) {};
virtual unsigned int GetData() { return m_param.value; }
protected:
ConfigParam m_param;
};
#endif

View File

@ -1,59 +0,0 @@
#include "ImageMultiOutput.h"
ImageMultiOutput::ImageMultiOutput(void)
{
}
ImageMultiOutput::~ImageMultiOutput(void)
{
}
//void ImageMultiOutput::apply(cv::Mat& pDib,int side)
//{
// //throw std::logic_error("The method or operation is not implemented.");
//}
cv::Mat ImageMultiOutput::GetMultiFilterMat(cv::Mat &src,int channel)
{
return FilterColor(src,channel);
}
cv::Mat ImageMultiOutput::FilterColor(cv::Mat image,short channel)
{
cv::Mat dstImage(image.rows,image.cols,CV_8UC1);
//int pixelSize = image.depth();
int channels = image.channels();
if(channel > channels -1){
return dstImage;
}
if ( ( channel == 3 ) && ( channels != 4 ) && ( channels != 8 ))
{
return dstImage;
}
if ( channels <= 4 )
{
int srcOffset = image.step - image.cols* channels ;
int dstOffset = dstImage.step - dstImage.cols;
unsigned char* src = image.data;
unsigned char* dst = dstImage.data;
src += channel;
for ( int y = 0; y < image.rows; y++ )
{
for ( int x = 0; x < image.cols; x++, src += channels , dst++ )
{
unsigned short pix = *src;
if(pix >=130){
pix = 255;
}
*dst = pix;
}
src += srcOffset;
dst += dstOffset;
}
}
return dstImage;
}

View File

@ -1,18 +0,0 @@
#ifndef IMAGE_MULTI_OUTPUT
#define IMAGE_MULTI_OUTPUT
#include "../ImageProcess/ImageApply.h"
class ImageMultiOutput
{
public:
ImageMultiOutput(void);
~ImageMultiOutput(void);
cv::Mat GetMultiFilterMat(cv::Mat &src,int channel);
private:
cv::Mat FilterColor(cv::Mat image,short channel);
};
#endif

View File

@ -1,64 +0,0 @@
#include "PaperSize.h"
using namespace std;
namespace Device {
PaperSize::PaperSize(int pid):pid_(pid)
{
InitPaperMap();
}
void PaperSize::InitPaperMap()
{
papersize.insert({ A3,SIZE{297,420} });
papersize.insert({ A4,SIZE{210,297} });
papersize.insert({ A5,SIZE{148,210} });
papersize.insert({ A6,SIZE{105,148} });
papersize.insert({ B4,SIZE{250,353} });
papersize.insert({ B5,SIZE{176,250} });
papersize.insert({ B6,SIZE{125,176} });
if(pid_ == 0x400 || pid_ == 0x402)
papersize.insert({ MaxSize,SIZE{297,(long)(420 * 1.5)} });
else if(pid_ == 0x300)
papersize.insert({ MaxSize,SIZE{210,297 * 2} });
else
papersize.insert({ MaxSize,SIZE{297,420 * 2} });
if(pid_ == 0x300)
papersize.insert({ USStatement,SIZE{210,(long)(297 * 1.5)} });
else
papersize.insert({ USStatement,SIZE{297,(long)(420 * 1.5)} });
papersize.insert({ USLetter,SIZE{216,279} });
papersize.insert({ USLegal,SIZE{216,356} });
papersize.insert({ USLedger,SIZE{297,432} });
papersize.insert({ None,SIZE{297,420} });
papersize.insert({ K8,SIZE{270,390} });
papersize.insert({ K16,SIZE{190,270} });
papersize.insert({ Trigeminy,SIZE{270,560} });
}
SIZE PaperSize::GetPaperSize(DWORD paperType, float dpi,int orentation)
{
if (papersize.find((TwSS)paperType) != papersize.end() && (dpi > 99 && dpi < 601))
{
SIZE resize{2338,3307};
long cx = papersize[(TwSS)paperType].cx * dpi / 25.4;
long cy = papersize[(TwSS)paperType].cy * dpi / 25.4;
if (orentation == 0)
{
resize.cx = cx;
resize.cy = cy;
}
else
{
resize.cx = cy;
resize.cy = cx;
}
return resize;
}
return SIZE{2338, 3307};
}
}

View File

@ -1,47 +0,0 @@
#ifndef PAPER_SIZE_H
#define PAPER_SIZE_H
#include <map>
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
#endif
#include "common_setting.h"
#ifdef __linux__
typedef CSSIZE Size;
typedef CSSIZE SIZE;
#endif
typedef struct Paper_Status {
unsigned int Paper;
unsigned int Orentate;
friend bool operator<(const struct Paper_Status& a, const struct Paper_Status& b) {
if (a.Paper < b.Paper ||
(a.Paper == b.Paper && a.Orentate < b.Orentate)) {
return true;
}
return false;
}
}PaperStatus;
namespace Device {
class PaperSize
{
public:
PaperSize(int pid);
private:
void InitPaperMap();
std::map<TwSS, SIZE> papersize;
std::map<std::pair<TwSS, float>, SIZE> dpiDct;
std::map<TwSS, SIZE> dpiDct_100;
std::map<TwSS, SIZE> dpiDct_400;
std::map<TwSS, SIZE> dpiDct_300;
int pid_;
public:
SIZE GetPaperSize(DWORD paperType, float dpi, int orentation);
};
}
#endif

View File

@ -1,561 +0,0 @@
#include "common_setting.h"
#include "sane/sane_option_definitions.h"
#include <lang/app_language.h>
#define MAKE_ID_AND_STR(l936) l936
static struct _fixed_option
{
std::string str;
int enum_val;
}
g_color_mode[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_YSMS_HB), COLOR_MODE_BLACK_WHITE },
{MAKE_ID_AND_STR(OPTION_VALUE_YSMS_256JHD), COLOR_MODE_256_GRAY},
{MAKE_ID_AND_STR(OPTION_VALUE_YSMS_24WCS), COLOR_MODE_24_BITS},
{MAKE_ID_AND_STR(OPTION_VALUE_YSMS_YSZDSB), COLOR_MODE_AUTO_MATCH}
},
g_multi_out[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_DLSCLX_CS_HD_HB), MULTI_OUT_ALL},
{MAKE_ID_AND_STR(OPTION_VALUE_DLSCLX_CS_HD), MULTI_COLOR_AND_GRAY},
{MAKE_ID_AND_STR(OPTION_VALUE_DLSCLX_CS_HB), MULTI_COLOR_AND_BW},
{MAKE_ID_AND_STR(OPTION_VALUE_DLSCLX_HD_HB), MULTI_GRAY_AND_BW}
},
g_rid_color[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_BCS), RID_COLOR_NONE},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_CHS), RID_COLOR_RID_RED},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_CLS), RID_COLOR_RID_GREEN},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_CHULANSE), RID_COLOR_RID_BLUE},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_HSZQ), RID_COLOR_ENHANCE_RED},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_LSZQ), RID_COLOR_ENHANCE_GREEN},
{MAKE_ID_AND_STR(OPTION_VALUE_HDHHBTX_CSYZQ_LANSEZENGQIANG), RID_COLOR_ENHANCE_BLUE}
},
g_paper[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A3), PAPER_A3},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A4), PAPER_A4},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A5), PAPER_A5},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A6), PAPER_A6},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_B4), PAPER_B4},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_B5), PAPER_B5},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_B6), PAPER_B6},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_8K), PAPER_8K},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_16K), PAPER_16K},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_Letter), PAPER_LETTER},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A4HX), PAPER_A4_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A5HX), PAPER_A5_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_A6HX), PAPER_A6_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_B5HX), PAPER_B5_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_B6HX), PAPER_B6_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_16KHX), PAPER_16K_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_LetterHX), PAPER_LETTER_LATERAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_DoubleLetter), PAPER_DOUBLE_LETTER},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_LEGAL), PAPER_LEGAL},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_PPYSCC), PAPER_AUTO_MATCH},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_ZDSMCC), PAPER_MAX_SIZE},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_ZDSMCCZDCQ), PAPER_MAX_SIZE_CLIP},
{MAKE_ID_AND_STR(OPTION_VALUE_ZZCC_SLSJ), PAPER_TRIGEMINY}
},
g_page[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_SMYM_DM), PAGE_SINGLE},
{MAKE_ID_AND_STR(OPTION_VALUE_SMYM_SM), PAGE_DOUBLE},
{MAKE_ID_AND_STR(OPTION_VALUE_SMYM_TGKBYTY), PAGE_OMIT_EMPTY},
{MAKE_ID_AND_STR(OPTION_VALUE_SMYM_TGKBYFPZ), PAGE_OMIT_EMPTY_RECEIPT},
{MAKE_ID_AND_STR(OPTION_VALUE_SMYM_DZ), PAGE_FOLIO}
},
g_sharpen[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_RHYMH_W), SHARPEN_NONE},
{MAKE_ID_AND_STR(OPTION_VALUE_RHYMH_RH), SHARPEN_SHARPEN},
{MAKE_ID_AND_STR(OPTION_VALUE_RHYMH_JYBRH), SHARPEN_SHARPEN_MORE},
{MAKE_ID_AND_STR(OPTION_VALUE_RHYMH_MH), SHARPEN_HAZY},
{MAKE_ID_AND_STR(OPTION_VALUE_RHYMH_JYBMH), SHARPEN_HAZY_MORE}
},
g_fill_bkg[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_BJTCFS_TDBX), FILL_BKG_CONVEX_POLYGON},
{MAKE_ID_AND_STR(OPTION_VALUE_BJTCFS_ADBX), FILL_BKG_CONCAVE_POLYGON}
},
g_scan_mode[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_SMZS_LXSM), SCAN_MODE_CONTINUOUS},
{MAKE_ID_AND_STR(OPTION_VALUE_SMZS_SMZDZS), SCAN_MODE_GIVEN_COUNT}
},
g_text_direction[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_WGFX_0), TEXT_DIRECTION_0},
{MAKE_ID_AND_STR(OPTION_VALUE_WGFX_90), TEXT_DIRECTION_90},
{MAKE_ID_AND_STR(OPTION_VALUE_WGFX_180), TEXT_DIRECTION_180},
{MAKE_ID_AND_STR(OPTION_VALUE_WGFX__90), TEXT_DIRECTION_270},
{MAKE_ID_AND_STR(OPTION_VALUE_WGFX_ZDWBFXSB), TEXT_DIRECTION_AUTO}
},
g_permeate_lv[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_FZSTDJ_JR), PERMAEATE_WEAKER},
{MAKE_ID_AND_STR(OPTION_VALUE_FZSTDJ_R), PERMAEATE_WEAK},
{MAKE_ID_AND_STR(OPTION_VALUE_FZSTDJ_YB), PERMAEATE_ORDINARY},
{MAKE_ID_AND_STR(OPTION_VALUE_FZSTDJ_Q), PERMAEATE_STRONG},
{MAKE_ID_AND_STR(OPTION_VALUE_FZSTDJ_JQ), PERMAEATE_STRONGER}
},
g_img_quality[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_HZ_W), IMG_NONE},
{MAKE_ID_AND_STR(OPTION_VALUE_HZ_SDYX), IMG_SPEED},
{MAKE_ID_AND_STR(OPTION_VALUE_HZ_HZYX), IMG_QUALITY}
},
g_paper_strenght[]=
{
{MAKE_ID_AND_STR(OPTION_VALUE_FZQD_R),PAPER_WEAK},
{MAKE_ID_AND_STR(OPTION_VALUE_FZQD_YB),PAPER_AVERAGE},
{MAKE_ID_AND_STR(OPTION_VALUE_FZQD_Q),PAPER_STRONG}
},
g_sleep_time[]=
{
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_BXM),SLEEP_TIME_0MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_WFZ),SLEEP_TIME_5MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_SFZ),SLEEP_TIME_10MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_BXS),SLEEP_TIME_30MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_YXS),SLEEP_TIME_60MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_LXS),SLEEP_TIME_120MIN},
{MAKE_ID_AND_STR(OPTION_VALUE_XMSJ_SXS),SLEEP_TIME_240MIN},
},
g_fold_type[] =
{
{MAKE_ID_AND_STR(OPTION_VALUE_ZYDZ),FOLD_TYPE_LEFT_RIGHT},
{MAKE_ID_AND_STR(OPTION_VALUE_SXDZ),FOLD_TYPE_UP_DOWN},
{MAKE_ID_AND_STR(OPTION_VALUE_ZDDZ),FOLD_TYPE_AUTO}
};
int g_paper_hx[] = { PAPER_A4, PAPER_A4_LATERAL
, PAPER_A5, PAPER_A5_LATERAL
, PAPER_A6, PAPER_A6_LATERAL
, PAPER_B5, PAPER_B5_LATERAL
, PAPER_B6, PAPER_B6_LATERAL
, PAPER_16K,PAPER_16K_LATERAL
, PAPER_LETTER, PAPER_LETTER_LATERAL
};
static struct paper_size
{
int paper;
SIZE size;
}g_paper_size[] =
{
{PAPER_A3, {297, 420}},
{PAPER_A4, {210, 297}},
{PAPER_A5, {148, 210}},
{PAPER_A6, {105, 148}},
{PAPER_B4, {257, 364}},
{PAPER_B5, {176, 250}}, // {PAPER_B5, {182, 257}},
{PAPER_B6, {125, 176}},
{PAPER_8K, {297, 420}},
{PAPER_16K, {210, 285}}, // {PAPER_16K, {185, 260}}
{PAPER_A4_LATERAL, {297, 210}},
{PAPER_A5_LATERAL, {210, 148}},
{PAPER_A6_LATERAL, {148, 105}},
{PAPER_B5_LATERAL, {250, 176}}, // {PAPER_B5, {182, 257}},
{PAPER_B6_LATERAL, {176, 125}}
};
// Custom 纸张的大小由用户定义.
// Letter Letter 纸216 毫米 × 279 毫米).
// Legal Legal 纸216 毫米 × 356 毫米).
// A4 A4 纸210 毫米 × 297 毫米).
// CSheet C 纸432 毫米 × 559 毫米).
// DSheet D 纸559 毫米 × 864 毫米).
// ESheet E 纸864 毫米 × 1118 毫米).
// LetterSmall Letter small 纸216 毫米 × 279 毫米).
// Tabloid Tabloid 纸279 毫米 × 432 毫米).
// Ledger Ledger 纸432 毫米 × 279 毫米).
// Statement Statement 纸140 毫米 × 216 毫米).
// Executive Executive 纸184 毫米 × 267 毫米).
// A3 A3 纸297 毫米 × 420 毫米).
// A4Small A4 small 纸210 毫米 × 297 毫米).
// A5 A5 纸148 毫米 × 210 毫米).
// B4 B4 纸250 × 353 毫米).
// B5 B5 纸176 毫米 × 250 毫米).
// Folio Folio 纸216 毫米 × 330 毫米).
// Quarto Quarto 纸215 毫米 × 275 毫米).
// Standard10x14 Standard 纸254 毫米 × 356 毫米).
// Standard11x17 Standard 纸279 毫米 × 432 毫米).
// Note Note 纸216 毫米 × 279 毫米).
// Number9Envelope #9 envelope98 毫米 × 225 毫米).
// Number10Envelope #10 envelope105 毫米 × 241 毫米).
// Number11Envelope #11 envelope114 毫米 × 263 毫米).
// Number12Envelope #12 envelope120 毫米 × 279 毫米).
// Number14Envelope #14 envelope127 毫米 × 292 毫米).
// DLEnvelope DL 信封110 毫米 × 220 毫米).
// C5Envelope C5 信封162 毫米 × 229 毫米).
// C3Envelope C3 信封324 毫米 × 458 毫米).
// C4Envelope C4 信封229 毫米 × 324 毫米).
// C6Envelope C6 信封114 毫米 × 162 毫米).
// C65Envelope C65 信封114 毫米 × 229 毫米).
// B4Envelope B4 信封250 × 353 毫米).
// B5Envelope B5 信封176 毫米 × 250 毫米).
// B6Envelope B6 信封176 毫米 × 125 毫米).
// ItalyEnvelope Italy envelope110 毫米 × 230 毫米).
// MonarchEnvelope Monarch envelope98 毫米 × 191 毫米).
// PersonalEnvelope 6 3 / 4 envelope92 毫米 × 165 毫米).
// USStandardFanfold US standard fanfold378 毫米 × 279 毫米).
// GermanStandardFanfold German standard fanfold216 毫米 × 305 毫米).
// GermanLegalFanfold German legal fanfold216 毫米 × 330 毫米).
// IsoB4 ISO B4250 毫米 × 353 毫米).
// JapanesePostcard Japanese postcard100 毫米 × 148 毫米).
// Standard9x11 Standard 纸229 毫米 × 279 毫米).
// Standard10x11 Standard 纸254 毫米 × 279 毫米).
// Standard15x11 Standard 纸381 毫米 × 279 毫米).
// InviteEnvelope 邀请函信封220 毫米 × 220 毫米).
// LetterExtra Letter extra 纸236 毫米 × 305 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张.
// LegalExtra Legal extra 纸236 毫米 × 381 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张.
// TabloidExtra Tabloid extra 纸297 毫米 × 457 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张.
// A4Extra A4 extra 纸236 毫米 × 322 毫米).该值是针对 PostScript 驱动程序的, 仅供 Linotronic 打印机使用以节省纸张.
// LetterTransverse Letter transverse 纸210 毫米 × 279 毫米).
// A4Transverse A4 transverse 纸210 毫米 × 297 毫米).
// LetterExtraTransverse Letter extra transverse 纸236 毫米 × 305 毫米).
// APlus SuperA / SuperA / A4 纸227 毫米 × 356 毫米).
// BPlus SuperB / SuperB / A3 纸305 毫米 × 487 毫米).
// LetterPlus Letter plus 纸216 毫米 × 322 毫米).
// A4Plus A4 plus 纸210 毫米 × 330 毫米).
// A5Transverse A5 transverse 纸148 毫米 × 210 毫米).
// B5Transverse JIS B5 transverse 纸182 毫米 × 257 毫米).
// A3Extra A3 extra 纸322 毫米 × 445 毫米).
// A5Extra A5 extra 纸174 毫米 × 235 毫米).
// B5Extra ISO B5 extra 纸201 毫米 × 276 毫米).
// A2 A2 纸420 毫米 × 594 毫米).
// A3Transverse A3 transverse 纸297 毫米 × 420 毫米).
// A3ExtraTransverse A3 extra transverse 纸322 毫米 × 445 毫米).
static int match_best(struct _fixed_option* arr, size_t num, std::string& val, bool& exact)
{
exact = true;
for (size_t i = 0; i < num; ++i)
{
if (val == from_default_language(arr[i].str.c_str()))
return arr[i].enum_val;
}
exact = false;
return -1;
}
static std::string get_str(struct _fixed_option* arr, int num, int enm, int default_v = 0)
{
if (enm >= 0 && enm < num)
return from_default_language(arr[enm].str.c_str());
else
return from_default_language(arr[default_v].str.c_str());
}
#define INVOKE_MATCH(arr, val, yes) match_best(arr, ARRAY_SIZE(arr), val, yes)
#define INVOKE_STR(arr, val, def) get_str(arr, ARRAY_SIZE(arr), val, def)
#define SET_DEFAULT_ON_FAIL(map_array, ind, val, def) \
if(ind == -1) \
{ \
ind = def; \
val = INVOKE_STR(map_array, def, def); \
}
int match_best_color_mode(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_color_mode, val, yes);
SET_DEFAULT_ON_FAIL(g_color_mode, ind, val, COLOR_MODE_24_BITS);
if (exact)
*exact = yes;
return ind;
}
int match_best_multi_out(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_multi_out, val, yes);
SET_DEFAULT_ON_FAIL(g_multi_out, ind, val, MULTI_OUT_ALL);
if (exact)
*exact = yes;
return ind;
}
int match_best_rid_color(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_rid_color, val, yes);
SET_DEFAULT_ON_FAIL(g_rid_color, ind, val, RID_COLOR_NONE);
if (exact)
*exact = yes;
return ind;
}
SIZE paper_size(int paper)
{
for (size_t i = 0; i < ARRAY_SIZE(g_paper_size); ++i)
{
if (g_paper_size[i].paper == paper)
return g_paper_size[i].size;
}
//return SIZE{ 2338, 3307 };
return SIZE{ 297, 420 }; // A3
}
int match_best_paper(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_paper, val, yes);
SET_DEFAULT_ON_FAIL(g_paper, ind, val, PAPER_A4);
if (exact)
*exact = yes;
return ind;
}
int match_best_page(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_page, val, yes);
SET_DEFAULT_ON_FAIL(g_page, ind, val, PAGE_DOUBLE);
if (exact)
*exact = yes;
return ind;
}
int match_best_sharpen(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_sharpen, val, yes);
SET_DEFAULT_ON_FAIL(g_sharpen, ind, val, SHARPEN_NONE);
if (exact)
*exact = yes;
return ind;
}
int match_best_fill_background(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_fill_bkg, val, yes);
SET_DEFAULT_ON_FAIL(g_fill_bkg, ind, val, FILL_BKG_CONVEX_POLYGON);
if (exact)
*exact = yes;
return ind;
}
int match_best_scan_mode(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_scan_mode, val, yes);
SET_DEFAULT_ON_FAIL(g_scan_mode, ind, val, SCAN_MODE_CONTINUOUS);
if (exact)
*exact = yes;
return ind;
}
int match_best_text_direction(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_text_direction, val, yes);
SET_DEFAULT_ON_FAIL(g_text_direction, ind, val, TEXT_DIRECTION_0);
if (exact)
*exact = yes;
return ind;
}
int match_best_permaeate_lv(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_permeate_lv, val, yes);
SET_DEFAULT_ON_FAIL(g_permeate_lv, ind, val, TEXT_DIRECTION_0);
if (exact)
*exact = yes;
return ind;
}
int match_best_img_quality(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_img_quality, val, yes);
SET_DEFAULT_ON_FAIL(g_img_quality, ind, val, IMG_SPEED);
if (exact)
*exact = yes;
return ind;
}
int match_best_paper_strength(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_paper_strenght, val, yes);
SET_DEFAULT_ON_FAIL(g_paper_strenght, ind, val, PAPER_WEAK);
if (exact)
*exact = yes;
return ind;
}
int match_best_sleep_time(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_sleep_time, val, yes);
SET_DEFAULT_ON_FAIL(g_sleep_time, ind, val, SLEEP_TIME_0MIN);
if (exact)
*exact = yes;
return ind;
}
int match_best_fold_type(std::string& val, bool* exact)
{
bool yes = true;
int ind = INVOKE_MATCH(g_fold_type, val, yes);
SET_DEFAULT_ON_FAIL(g_fold_type, ind, val, FOLD_TYPE_AUTO);
if (exact)
*exact = yes;
return ind;
}
std::string color_mode_string(int clr_mode)
{
return INVOKE_STR(g_color_mode, clr_mode, 0);
}
std::string multi_out_string(int multi_out)
{
return INVOKE_STR(g_multi_out, multi_out, 0);
}
std::string rid_color_string(int rid_color)
{
return INVOKE_STR(g_rid_color, rid_color, 0);
}
std::string paper_string(int paper)
{
return INVOKE_STR(g_paper, paper, 1);
}
bool is_lateral(int paper)
{
for (int i = 1; i < _countof(g_paper_hx); i += 2)
{
if (paper == g_paper_hx[i])
return true;
}
return false;
}
int switch_lateral(int paper, bool lateral)
{
for (int i = !lateral; i < _countof(g_paper_hx); i += 2)
{
if (g_paper_hx[i] == paper)
{
i += lateral ? 1 : -1;
paper = g_paper_hx[i];
break;
}
}
return paper;
}
std::string page_string(int page)
{
return INVOKE_STR(g_page, page, 1);
}
std::string sharpen_string(int sharpen)
{
return INVOKE_STR(g_sharpen, sharpen, 0);
}
std::string fill_background_string(int fill)
{
return INVOKE_STR(g_fill_bkg, fill, 0);
}
std::string scan_mode_string(int mode)
{
return INVOKE_STR(g_scan_mode, mode, 0);
}
std::string text_direction_string(int text_dir)
{
return INVOKE_STR(g_text_direction, text_dir, 0);
}
std::string is_permaeate_string(int permaeate_lv)
{
return INVOKE_STR(g_permeate_lv, permaeate_lv, 0);
}
std::string is_img_quality(int is_quakuty)
{
return INVOKE_STR(g_img_quality, is_quakuty + 1/*start from -1*/, 0);
}
std::string is_paper_strength(int strength)
{
return INVOKE_STR(g_paper_strenght, strength, 0);
}
std::string is_sleep_time(int sleep_time)
{
return INVOKE_STR(g_sleep_time, sleep_time, 0);
}
std::string is_fold_type(int fold_type)
{
return INVOKE_STR(g_fold_type, fold_type, 0);
}
int double_paper_flag_from_option_value(std::string& opt_val, bool* exact)
{
if (exact)
*exact = true;
if (opt_val == from_default_language(OPTION_VALUE_SZTPCL_SCTXBJXSM, nullptr))
return DOUBLE_PAPER_CONTINUE | DOUBLE_PAPER_SAVE_IMG;
else if (opt_val == from_default_language(OPTION_VALUE_SZTPCL_SCTXBTZSM, nullptr))
return DOUBLE_PAPER_SAVE_IMG;
else if (opt_val == from_default_language(OPTION_VALUE_SZTPCL_DQTXBJXSM, nullptr))
return DOUBLE_PAPER_CONTINUE;
else
{
if (exact)
*exact = opt_val == from_default_language(OPTION_VALUE_SZTPCL_DQTXBTZSM, nullptr);
}
return 0;
}
std::string double_paper_flag_to_option_value(int flag)
{
if (is_continue_when_double_paper(flag))
{
if (is_save_img_when_double_paper(flag))
return from_default_language(OPTION_VALUE_SZTPCL_SCTXBJXSM, nullptr);
else
return from_default_language(OPTION_VALUE_SZTPCL_DQTXBJXSM, nullptr);
}
else if (is_save_img_when_double_paper(flag))
return from_default_language(OPTION_VALUE_SZTPCL_SCTXBTZSM, nullptr);
else
return from_default_language(OPTION_VALUE_SZTPCL_DQTXBTZSM, nullptr);
}
bool is_continue_when_double_paper(int flag)
{
return flag & DOUBLE_PAPER_CONTINUE;
}
bool is_save_img_when_double_paper(int flag)
{
return flag& DOUBLE_PAPER_SAVE_IMG;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
#ifndef FILE_TOOLS_H
#define FILE_TOOLS_H
#if defined(WIN32) || defined(_WIN64)
#include <vector>
#include <io.h>
#include <fstream>
#include <time.h>
class FileTools
{
public:
static std::vector<std::string> getFiles(std::string path)
{
std::vector<std::string> files;
getFiles(path, files);
return files;
}
static void write_log(std::string filename, std::string log)
{
std::string savepath;
std::string str = "D:";
savepath = str+"\\"+filename;
std::ofstream ofs(savepath, std::ios::app);
time_t timp;
struct tm* p;
time(&timp);
p=localtime(&timp);
ofs << p->tm_year << "/" << p->tm_mon << "/" << p->tm_mday << " " << p->tm_hour << ":" << p->tm_min << ":" << p->tm_sec << " "<<log << std::endl;
}
private:
static void getFiles(std::string path, std::vector<std::string>& files)
{
//文件句柄
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo))!=-1)
{
do
{
//如果是目录,迭代之
//如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
getFiles(p.assign(path).append("\\").append(fileinfo.name), files);
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
};
#endif
#endif

View File

@ -1,891 +0,0 @@
#include "hg_ipc.h"
#include "huagao/hgscanner_error.h"
#include "../../sdk/hginclude/utils.h"
#if defined(WIN32) || defined(_WIN64)
//#include "scanner_manager.h"
#else
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory management ...
void* allocate_memory(size_t bytes, const char* log_msg)
{
bytes += 7;
bytes /= 8;
bytes *= 8;
return new char[bytes];
}
void free_memory(void* ptr)
{
if (ptr)
delete[] ptr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// windows event ...
#if defined(WIN32) || defined(_WIN64)
int __stdcall sem_init(sem_t* handle, int, int)
{
if (!handle)
{
errno = EINVAL;
return -1;
}
*handle = CreateEvent(NULL, TRUE, FALSE, NULL);
if (*handle)
return 0;
else
{
errno = GetLastError();
return -1;
}
}
void __stdcall sem_destroy(sem_t* handle)
{
if (*handle)
{
CloseHandle(*handle);
*handle = NULL;
}
}
int __stdcall sem_trywait(sem_t* handle)
{
return WaitForSingleObject(*handle, 1) == WAIT_TIMEOUT ? -1 : 0;
}
void __stdcall sem_wait(sem_t* handle)
{
if(WaitForSingleObject(*handle, INFINITE) == WAIT_OBJECT_0)
ResetEvent(*handle);
}
int __stdcall sem_timedwait(sem_t* handle, struct timespec* to)
{
DWORD elapse = to->tv_sec * 1000;
elapse += to->tv_nsec / (1000 * 1000);
int ret = WaitForSingleObject(*handle, elapse) == WAIT_TIMEOUT ? -1 : 0;
if(ret == 0)
ResetEvent(*handle);
return ret;
}
void __stdcall sem_post(sem_t* handle)
{
SetEvent(*handle);
}
#define pid_t int
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// platform_event (base on semaphore)
platform_event::platform_event() : waiting_(false), dbg_info_("")
{
int err = sem_init(&sem_, 0, 0);
if (err == -1)
{
err = errno;
utils::to_log(LOG_LEVEL_FATAL, "(%p)sem_init failed: %d\n", this, err);
}
}
platform_event::~platform_event()
{
sem_destroy(&sem_);
}
bool platform_event::try_wait(void)
{
return sem_trywait(&sem_) == 0;
}
bool platform_event::wait(unsigned timeout)
{
bool waited = true;
utils::to_log(LOG_LEVEL_DEBUG, "platform_event(%p - %s) --> waiting...\n", this, dbg_info_.c_str());
waiting_ = true;
if (timeout == USB_TIMEOUT_INFINITE)
sem_wait(&sem_);
else
{
struct timespec to;
to.tv_sec = timeout / 1000;
to.tv_nsec = (long)((timeout % 1000) * 1000 * 1000);
waited = sem_timedwait(&sem_, &to) == 0;
}
utils::to_log(LOG_LEVEL_DEBUG, "platform_event(%p - %s) --> %s.\n", this, dbg_info_.c_str(), waited ? "waited" : "wait timeout");
waiting_ = false;
return waited;
}
void platform_event::notify(void)
{
sem_post(&sem_);
}
bool platform_event::is_waiting(void)
{
return waiting_;
}
void platform_event::set_debug_info(const char* info)
{
dbg_info_ = info ? info : "";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// shared_memory
shared_memory::shared_memory(unsigned long long key, size_t size) : key_(key), obj_((void*)-1), first_(true), bytes_(size), len_(0)
{
unsigned int* ptr = (unsigned int*)&key_;
utils::to_log(LOG_LEVEL_DEBUG, "shared memory key = 0x%x%08x\n", ptr[1], ptr[0]);
init();
}
shared_memory::~shared_memory()
{
clear();
}
void shared_memory::init(void)
{
#if defined(WIN32) || defined(_WIN64)
char name[40] = { 0 };
DWORD* key = (DWORD*)&key_;
HANDLE h = NULL;
sprintf(name, "scanner_0x%08x-%08x", key[1], key[0]);
h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, bytes_, name);
if (h == NULL)
return;
first_ = !(GetLastError() == ERROR_ALREADY_EXISTS);
obj_ = (void*)h;
#else
int obj = shmget(key_, bytes_, IPC_EXCL | IPC_CREAT | 0666);
if (obj < 0)
{
unsigned int* v = (unsigned int*)&key_;
if (errno == EEXIST)
{
first_ = false;
obj = shmget(key_, bytes_, 0600);
if(obj == -1)
obj = shmget(key_, bytes_, 0);
utils::to_log(LOG_LEVEL_DEBUG, "open existing: shmget(0x%x%08x) = %d\n", v[1], v[0], obj);
obj_ = (void*)obj;
std::string prev(read()), proc("");
utils::to_log(LOG_LEVEL_DEBUG, "shared memory content: %s\n", prev.c_str());
if(prev.length())
{
proc = prev;
size_t pos = proc.find("pid: ");
if (pos != std::string::npos)
proc.erase(0, pos + 5);
pos = proc.find(")");
if (pos != std::string::npos)
proc.erase(pos);
proc = shared_memory::get_proc_name_by_pid(atoi(proc.c_str()));
if (proc.length())
{
pos = prev.find("(");
if (pos == std::string::npos)
pos = prev.length();
if (strcasecmp(proc.c_str(), prev.substr(0, pos).c_str()))
proc = "";
}
}
if (proc.empty())
{
first_ = true;
clear();
obj = shmget(key_, bytes_, IPC_EXCL | IPC_CREAT | 0600);
utils::to_log(LOG_LEVEL_DEBUG, "%s is not existing and reopen it\n", prev.c_str());
}
}
else
{
utils::to_log(LOG_LEVEL_DEBUG, "shmget(0x%x%08x) = %d\n", v[1], v[0], errno);
return;
}
}
obj_ = (void*)obj;
utils::to_log(LOG_LEVEL_DEBUG, "shared memory id = %d[%s], \n", obj, first_ ? "created" : "opened");
#endif
if(first_)
{
pid_t pid = getpid();
std::string me(utils::get_module_full_path());
char buf[40] = { 0 };
unsigned int* pn = (unsigned int*)&pid;
if (sizeof(pid) > 4 && pn[1])
sprintf(buf, "(pid: 0x%x%08x)", pn[1], pn[0]);
else
sprintf(buf, "(pid: %u)", pn[0]);
size_t pos = me.rfind(PATH_SEPARATOR[0]);
if(pos++ != std::string::npos)
me.erase(0, pos);
me += buf;
write(me.c_str(), me.length());
}
}
void shared_memory::clear(void)
{
if (obj_ != (void*)-1)
#if defined(WIN32) || defined(_WIN64)
CloseHandle((HANDLE)obj_);
#else
{
if (first_)
{
struct shmid_ds ds = { 0 };
int* h = (int*)&obj_;
shmctl(*h, IPC_RMID, &ds);
}
}
#endif
obj_ = (void*)-1;
}
char* shared_memory::get_buf(void)
{
#if defined(WIN32) || defined(_WIN64)
char* buf = (char*)MapViewOfFile((HANDLE)obj_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (!buf)
buf = (char*)-1;
#else
int* h = (int*)&obj_;
char* buf = (char*)shmat(*h, 0, 0);
utils::to_log(LOG_LEVEL_DEBUG, "shared memory %d buffer = %p, error = %d\n", *h, buf, errno);
#endif
return buf;
}
void shared_memory::release_buf(void* buf)
{
#if defined(WIN32) || defined(_WIN64)
UnmapViewOfFile(buf);
#else
shmdt(buf);
#endif
}
#if !defined(WIN32) && !defined(_WIN64)
std::string shared_memory::get_proc_name_by_pid(pid_t pid)
{
char path[512] = { 0 };
unsigned int* v = (unsigned int*)&pid;
std::string ret("");
if (sizeof(pid) > 4 && v[1])
sprintf(path, "/proc/%lld/status", pid);
else
sprintf(path, "/proc/%u/status", pid);
FILE* src = fopen(path, "rb");
if (src)
{
char val[512] = { 0 };
memset(path, 0, sizeof(path));
fgets(path, sizeof(path) - 1, src);
fclose(src);
sscanf(path, "%*s %s", val);
ret = val;
}
if (sizeof(pid) > 4 && v[1])
{
utils::to_log(LOG_LEVEL_DEBUG, "PID(%lld) name is: %s\n", pid, ret.c_str());
}
else
{
utils::to_log(LOG_LEVEL_DEBUG, "PID(%u) name is: %s\n", pid, ret.c_str());
}
return ret;
}
#endif
bool shared_memory::is_ok(void)
{
return obj_ != (void*)-1;
}
bool shared_memory::is_first(void)
{
return is_ok() && first_;
}
std::string shared_memory::read(void)
{
if (obj_ == (void*)-1)
return "";
char* buf = get_buf();
if (buf == (char*)-1)
return "";
std::string ret("");
size_t len = 0;
int off = 4; // sizeof(size_t);
memcpy(&len, buf, off);
ret = std::string(buf + off, len);
release_buf(buf);
return ret;
}
int shared_memory::write(const char* data, size_t len)
{
if (len > bytes_)
return SCANNER_ERR_INSUFFICIENT_MEMORY;
char* buf = get_buf();
int off = 4; // sizeof(len);
if (buf == (char*)-1)
return errno;
memcpy(buf, &len, off);
memcpy(buf + off, data, len);
len_ = len;
release_buf(buf);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// tiny_file_map ...
tiny_file_map::tiny_file_map() : size_(0), map_(INVALID_HANDLE_NAME), buf_(nullptr), file_(""), keep_f_(false)
, map_off_(0), map_bytes_(0), page_size_(utils::get_page_size())
{
utils::get_page_size(&page_size_);
}
tiny_file_map::~tiny_file_map()
{
close();
}
HANDLE_NAME tiny_file_map::open_file_for_mapping(const char* file, unsigned* bytes, bool create)
{
HANDLE_NAME ret = INVALID_HANDLE_NAME;
#if defined(WIN32) || defined(_WIN64)
HANDLE f = INVALID_HANDLE_VALUE;
if (create)
{
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f != INVALID_HANDLE_VALUE)
{
DWORD wrote = SetFilePointer(f, *bytes - 1, NULL, FILE_BEGIN);
if (wrote != *bytes - 1 || !WriteFile(f, "\0", 1, &wrote, NULL))
{
CloseHandle(f);
f = INVALID_HANDLE_VALUE;
}
}
}
else
{
f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (f != INVALID_HANDLE_VALUE)
*bytes = GetFileSize(f, NULL);
}
if (f != INVALID_HANDLE_VALUE)
{
ret = CreateFileMapping(f, NULL, PAGE_READWRITE, 0, *bytes, NULL);
CloseHandle(f);
}
#else
if (create)
{
ret = ::open(file, O_CREAT | O_RDWR,0777);
if (ret != INVALID_HANDLE_NAME)
{
if (lseek(ret, *bytes - 1, SEEK_SET) < 0)
{
utils::to_log(LOG_LEVEL_DEBUG, "set file size to %u - 1 bytes failed: %d\n", *bytes, errno);
::close(ret);
remove(file);
ret = INVALID_HANDLE_NAME;
}
if (write(ret, "0", 1) < 0)
{
utils::to_log(LOG_LEVEL_DEBUG, "set file size to %u bytes failed: %d\n", *bytes, errno);
::close(ret);
remove(file);
ret = INVALID_HANDLE_NAME;
}
}
}
else
{
ret = ::open(file, O_RDWR);
if (ret != INVALID_HANDLE_NAME)
{
struct stat fsize;
if (fstat(ret, &fsize) >= 0)
*bytes = fsize.st_size;
}
}
#endif
return ret;
}
void tiny_file_map::close_handle_name(HANDLE_NAME h)
{
#if defined(WIN32) || defined(_WIN64)
CloseHandle(h);
#else
::close(h);
#endif
}
void* tiny_file_map::sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err)
{
void* mem = nullptr;
#if defined(WIN32) || defined(_WIN64)
mem = MapViewOfFile(h, access, 0, off, size);
if (err)
{
if (mem)
*err = SCANNER_ERR_OK;
else
{
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY)
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
else
*err = SCANNER_ERR_OUT_OF_RANGE;
}
}
#else
mem = mmap(nullptr, size, access, MAP_SHARED, h, off);
if (mem == MAP_FAILED)
{
mem = nullptr;
if (errno == ENOMEM)
*err = SCANNER_ERR_INSUFFICIENT_MEMORY;
else
*err = SCANNER_ERR_OUT_OF_RANGE;
}
else if(err)
*err = SCANNER_ERR_OK;
#endif
return mem;
}
void tiny_file_map::sys_unmap_api(void* buf, size_t size)
{
#if defined(WIN32) || defined(_WIN64)
UnmapViewOfFile(buf);
#else
munmap(buf, size);
#endif
}
int tiny_file_map::map_to_mem(unsigned int off)
{
int err = SCANNER_ERR_OUT_OF_RANGE;
#if defined(WIN32) || defined(_WIN64)
int acc = FILE_MAP_READ | FILE_MAP_WRITE;
#else
int acc = PROT_READ | PROT_WRITE;
#endif
if (off < size_)
{
unsigned int bytes = size_ - off;
if (off >= map_off_ && off + bytes <= map_off_ + map_bytes_)
err = SCANNER_ERR_OK;
else
{
if (buf_)
tiny_file_map::sys_unmap_api(buf_, map_bytes_);
off /= page_size_;
off *= page_size_;
map_bytes_ = bytes;
map_off_ = off;
buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err); // MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, off, map_bytes_);
if (err != SCANNER_ERR_OK)
{
map_bytes_ /= page_size_;
map_bytes_ *= page_size_;
while (map_bytes_ >= page_size_
&& !(buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err))
&& err == SCANNER_ERR_INSUFFICIENT_MEMORY)
map_bytes_ -= page_size_;
}
}
}
return err;
}
int tiny_file_map::open(const char* file, bool existing, unsigned int size)
{
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
close();
map_ = tiny_file_map::open_file_for_mapping(file, &size, !existing);
if (map_ != INVALID_HANDLE_NAME)
{
ret = SCANNER_ERR_OK;
size_ = size;
}
utils::to_log(LOG_LEVEL_DEBUG, "map([%s]%s) = %d\n", existing ? "existing" : "new", file, ret);
if (ret == SCANNER_ERR_OK)
file_ = file;
return ret;
}
void tiny_file_map::close(void)
{
if (buf_)
{
tiny_file_map::sys_unmap_api(buf_, size_);
buf_ = nullptr;
}
if (map_ != INVALID_HANDLE_NAME)
{
close_handle_name(map_);
map_ = INVALID_HANDLE_NAME;
}
if (!keep_f_ && !file_.empty())
remove(file_.c_str());
size_ = 0;
file_ = "";
keep_f_ = false;
map_off_ = map_bytes_ = 0;
}
void tiny_file_map::keep_file(bool keep)
{
keep_f_ = keep;
}
unsigned char* tiny_file_map::mapping_buffer(unsigned int off, unsigned int* bytes)
{
unsigned int len = bytes ? *bytes : size_;
unsigned char* buf = nullptr;
if (off >= size_)
{
return buf;
}
if (!buf_ && map_to_mem(off) != SCANNER_ERR_OK)
{
return buf;
}
if (off >= map_off_ && off + len <= map_off_ + map_bytes_)
{
buf = buf_ + off - map_off_;
return buf;
}
if (off < map_off_ || off >= map_off_ + map_bytes_)
{
if (map_to_mem(off) == SCANNER_ERR_OK)
{
buf = buf_ + off - map_off_;
if (bytes)
*bytes = map_bytes_ - (off - map_off_);
}
return buf;
}
//
buf = buf_ + off - map_off_;
if (bytes)
*bytes = map_bytes_ - (off - map_off_);
return buf;
}
std::string tiny_file_map::file(void)
{
return file_;
}
unsigned int tiny_file_map::size(void)
{
return size_;
}
bool tiny_file_map::swap(void)
{
bool ret = true;
tiny_file_map::sys_unmap_api(buf_, size_);
buf_ = nullptr;
return ret;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory or file mapping ...
tiny_buffer::tiny_buffer(unsigned int size
, const char* tmp_path
, const char* name_leading
, const char* ext
, unsigned int uniq_id)
: size_(size), buf_(nullptr), img_statu_(IMG_STATUS_OK)
{
init(tmp_path, name_leading, ext, uniq_id);
}
tiny_buffer::tiny_buffer(const char* src_file) : size_(0), buf_(nullptr)
{
fmap_.open(src_file);
size_ = fmap_.size();
unsigned int len = size_;
buf_ = fmap_.mapping_buffer(0, &len);
}
tiny_buffer::~tiny_buffer()
{
if (buf_)
{
if (fmap_.file().empty())
delete[] buf_;
else
fmap_.close();
}
}
void tiny_buffer::init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id)
{
try
{
buf_ = new unsigned char[size_];
memset(buf_, 0, size_);
}
catch (...)
{
if (tmp_path && *tmp_path)
{
std::string f(tmp_path);
char buf[128] = { 0 };
f += PATH_SEPARATOR;
f += name_leading ? name_leading : "mapf";
sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp");
f += buf;
unsigned int bytes = size_;
fmap_.open(f.c_str(), false, size_);
buf_ = fmap_.mapping_buffer(0, &bytes);
}
}
}
unsigned int tiny_buffer::size(void)
{
return size_;
}
unsigned char* tiny_buffer::data(unsigned int off, unsigned int* bytes)
{
if (off >= size_)
return nullptr;
if (fmap_.file().empty())
{
if (size_ - off < *bytes)
*bytes = size_ - off;
return buf_ + off;
}
return fmap_.mapping_buffer(off, bytes);
}
void tiny_buffer::keep_file(bool keep)
{
fmap_.keep_file(keep);
}
std::string tiny_buffer::file(void)
{
return fmap_.file();
}
bool tiny_buffer::swap(void)
{
if (fmap_.file().empty())
return true;
bool ret = fmap_.swap();
unsigned int bytes = size_;
buf_ = fmap_.mapping_buffer(0, &bytes);
return ret;
}
int tiny_buffer::to_file(const char* file)
{
FILE* dst = fopen(file, "wb");
if (!dst)
return errno;
unsigned int off = 0, len = size_;
unsigned char* buf = data(off, &len);
while (buf)
{
fwrite(buf, 1, len, dst);
off += len;
if (off >= size_)
break;
len = size_ - off;
buf = data(off, &len);
}
fclose(dst);
return 0;
}
void tiny_buffer::set_image_statu(int statu)
{
img_statu_ = statu;
}
int tiny_buffer::get_image_statu(void)
{
return img_statu_;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// final_img_queue
final_img_queue::final_img_queue() : mem_usage_(0)
{}
final_img_queue::~final_img_queue()
{}
unsigned long long final_img_queue::mem_usage(void)
{
return mem_usage_;
}
size_t final_img_queue::size(void)
{
std::lock_guard<std::mutex> lck(lock_);
return queue_.size();
}
void final_img_queue::clear(void)
{
std::lock_guard<std::mutex> lck(lock_);
mem_usage_ = 0;
queue_.clear();
}
bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id)
{
IMGDT imgd;
bool ret = false;
unsigned int l = bytes, off = 0;
imgd.header.bits = bpp;
imgd.header.bytes = bytes;
imgd.header.channels = channels;
imgd.header.height = h;
imgd.header.line_bytes = line_bytes;
imgd.header.width = w;
imgd.header.src_id = id;
imgd.offset = 0;
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
unsigned char* buf = imgd.data->data(off, &l),
* src = (unsigned char*)data;
while(buf)
{
memcpy(buf, src, l);
off += l;
if (off >= bytes)
break;
src += l;
l = bytes - off;
buf = imgd.data->data(off, &l);
}
if (off >= bytes && imgd.data->swap())
{
std::lock_guard<std::mutex> lck(lock_);
queue_.push_back(imgd);
mem_usage_ += bytes;
ret = true;
}
else
imgd.data.reset();
return ret;
}
bool final_img_queue::front(IMH* header)
{
std::lock_guard<std::mutex> lck(lock_);
if (queue_.size() == 0)
return false;
memcpy(header, &queue_[0].header, sizeof(*header));
return true;
}
void final_img_queue::fetch_front(void* buf, int* len, bool* over)
{
std::lock_guard<std::mutex> lck(lock_);
if (queue_.size() == 0)
{
if(len)
*len = 0;
if(over)
*over = true;
}
else
{
// for third-apps, we make fake data upto len when re-map file failed here
IMGDT& imgd = queue_[0];
if (imgd.offset == 0)
{
if (!imgd.data->swap())
{
utils::to_log(LOG_LEVEL_FATAL, "Reload final image '%s' failed!\n", imgd.data->file().c_str());
}
}
if (imgd.offset + *len >= imgd.header.bytes)
*len = imgd.header.bytes - imgd.offset;
unsigned char* src = imgd.data->data(imgd.offset, (unsigned int*)len);
if (src)
{
memcpy(buf, src, *len);
}
else
{
utils::to_log(LOG_LEVEL_FATAL, "Remap final image '%s + 0x%08x' failed!\n", imgd.data->file().c_str(), imgd.offset);
}
imgd.offset += *len;
if (imgd.offset >= imgd.header.bytes)
{
mem_usage_ -= imgd.header.bytes;
if (mem_usage_ < 0)
mem_usage_ = 0;
if (over)
*over = true;
queue_.erase(queue_.begin());
}
}
}

View File

@ -1,212 +0,0 @@
#pragma once
// Objects for Inter-Process-Communication
//
// created on 2022-03-01
//
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
#define sem_t HANDLE
#define USB_TIMEOUT_INFINITE -1
#else
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#define USB_TIMEOUT_INFINITE 0
#endif
#include <string>
#include <vector>
#include <mutex>
#include <memory>
#include <hginclude/utils.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory management ...
void* allocate_memory(size_t bytes, const char* log_msg = "");
void free_memory(void* ptr);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class platform_event
{
sem_t sem_;
volatile bool waiting_;
std::string dbg_info_;
public:
platform_event();
~platform_event();
public:
bool try_wait(void);
bool wait(unsigned timeout = USB_TIMEOUT_INFINITE/*ms*/); // USB_TIMEOUT_INFINITE is waiting unfinite, true when watied and false for wait timeout
void notify(void);
bool is_waiting(void);
void set_debug_info(const char* info);
};
template<class T>
class do_when_born_and_dead : public refer
{
T* obj_;
void(T::* dead_)(void*);
void* param_;
public:
do_when_born_and_dead(T* obj, void(T::* born)(void*), void(T::* dead)(void*), void* param)
: obj_(obj), dead_(dead), param_(param)
{
if(born)
(obj_->*born)(param_);
}
protected:
~do_when_born_and_dead()
{
(obj_->*dead_)(param_);
}
};
// mutex object
class shared_memory : public refer
{
unsigned long long key_;
void* obj_;
bool first_;
size_t bytes_;
size_t len_;
void init(void);
void clear(void);
char* get_buf(void);
void release_buf(void* buf);
#if !defined(WIN32) && !defined(_WIN64)
static std::string get_proc_name_by_pid(pid_t pid);
#endif
public:
shared_memory(unsigned long long key, size_t size = 1024);
protected:
~shared_memory();
public:
bool is_ok(void);
bool is_first(void);
std::string read(void);
int write(const char* data, size_t len);
};
// buffer
#if defined(WIN32) || defined(_WIN64)
#define HANDLE_NAME HANDLE
#define INVALID_HANDLE_NAME NULL
#else
#define HANDLE_NAME int
#define INVALID_HANDLE_NAME -1
#endif
class tiny_file_map
{
unsigned int size_;
unsigned int page_size_;
HANDLE_NAME map_;
unsigned char *buf_;
std::string file_;
bool keep_f_;
unsigned int map_off_;
unsigned int map_bytes_;
int map_to_mem(unsigned int off = 0);
public:
tiny_file_map();
~tiny_file_map();
static HANDLE_NAME open_file_for_mapping(const char* file, unsigned* bytes, bool create);
static void close_handle_name(HANDLE_NAME h);
static void* sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err);
static void sys_unmap_api(void* buf, size_t size = 0);
public:
int open(const char* file, bool existing = true, unsigned int size = 0);
void close(void);
void keep_file(bool keep);
unsigned char* mapping_buffer(unsigned int off, unsigned int* bytes);
std::string file(void);
unsigned int size(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
};
class tiny_buffer
{
unsigned int size_;
unsigned char *buf_;
tiny_file_map fmap_;
int img_statu_;
void init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
public:
tiny_buffer(unsigned int size, const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
tiny_buffer(const char* src_file);
~tiny_buffer();
public:
unsigned int size(void);
unsigned char* data(unsigned int off, unsigned int* bytes/*[in] - need bytes, [out] - real bytes*/);
void keep_file(bool keep);
std::string file(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
int to_file(const char* file);
void set_image_statu(int statu);
int get_image_statu(void);
};
typedef struct _img_header
{
int width;
int height;
int bits;
int channels;
int line_bytes;
int statu; // SANE_Image_Statu
unsigned bytes;
uint32_t src_id;
}IMH;
typedef struct _img
{
IMH header;
unsigned offset;
std::shared_ptr<tiny_buffer> data;
}IMGDT;
class final_img_queue
{
mutable std::mutex lock_;
std::vector<IMGDT> queue_;
long long mem_usage_;
public:
final_img_queue();
~final_img_queue();
public:
unsigned long long mem_usage(void);
size_t size(void);
void clear(void);
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
, const char* tmp_path, const char* name_leading, const char* ext, int ind, uint32_t id);
bool front(IMH* header);
void fetch_front(void* buf, int* len, bool* over);
};

File diff suppressed because it is too large Load Diff

View File

@ -1,557 +1,114 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
// scanner business handler
//
// created on 2022-01-30
// created on 2023-03-27
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
//#include <vld.h>
#include "usb_manager.h"
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "../3rdparty/nick/StopWatch.h"
#include "hg_ipc.h"
#include "common_setting.h"
#include "image_process.h"
#include "StopWatch.h"
#include "PaperSize.h"
#include "version/HGVersion.h"
#if defined(WIN32) || defined(_WIN64)
#include <cryptoPP/md5.h> //暂时linux 屏蔽
#include <cryptoPP/files.h>
#include <cryptoPP/aes.h>
#include <cryptoPP/modes.h>
#include <cryptopp/hex.h>
#else
#include <unistd.h>
#include <dlfcn.h>
#endif
#ifndef WIN32
#define __stdcall
#endif
#define MAPPING_FUNCTION_IN_BASE // 定义该标志各子类不必再初始化setting_map_数组
#define SAFE_DELETE(p){ \
if (NULL != (p)) {delete((p)); \
(p) = nullptr; \
}\
}
//#ifdef OEM_HANWANG
//#define hg_scanner hw_scanner
//#elif defined(OEM_LISICHENG)
//#define hg_scanner lsc_scanner
//#elif defined(OEM_CANGTIAN)
//#define hg_scanner cts_scanner
//#endif
#define USB_REQ_GET_FPGA_REGS 0x40
#define USB_REQ_SET_FPGA_REGS 0x41
#define USB_REQ_GET_MOTOR_REGS 0x42
#define USB_REQ_SET_MOTOR_REGS 0x43
#define USB_REQ_GET_DEV_STATUS 0x60
#define USB_REQ_GET_DEV_CONFIGURATION 0x61
#define USB_REQ_SET_DEV_CONFIGURATION 0x62
#define USB_REQ_GET_DEV_REGS 0x63
#define USB_REQ_SET_DEV_REGS 0x64
typedef HGResult(__stdcall* SDKHGVersion_Init_)(HGVersionMgr* mgr);
typedef HGResult(__stdcall* SDKHGVersion_Islock_)(HGVersionMgr mgr, const HGChar* devSN, HGBool* inList);
typedef HGResult(__stdcall* SDKHGVersion_Postlog_)(HGVersionMgr mgr, const HGChar* devName, const HGChar* devSN,
const HGChar* devType, const HGChar* devFW, HGBool isLock);
typedef HGResult(__stdcall* SDKHGVersion_Free_)(HGVersionMgr mgr);
class imgproc_mgr;
#pragma once
#include <sane_opt_json/base_opt.h>
#include <sane/sane_ex.h>
#include <base/data.h>
class hg_scanner;
class imgproc_mgr;
class device_option;
class scanner_handler;
class hguser;
struct libusb_device;
typedef struct _online_scanner
{
int vid;
int pid;
int addr;
libusb_device *dev; // the unique usb device
hg_scanner *scanner;
std::string family;
std::string display_name; // unique. same device name should append sn
bool operator==(const libusb_device* d)
{
return d == dev;
}
bool operator==(const char* name)
{
return display_name == name;
}
bool operator==(const hg_scanner* s)
{
return s == scanner;
}
}ONLNSCANNER;
class img_receiver : public data_holder
{
uint32_t id_;
PACKIMAGE head_;
std::string info_;
uint8_t* buf_ = nullptr;
size_t info_size_ = 0; // image info
size_t size_ = 0; // image data only
size_t wpos_ = 0; // image data only
std::function<void(img_receiver*)> finish_;
public:
img_receiver(LPPACKIMAGE head, size_t info_size, size_t size, std::function<void(img_receiver*)> complete_routine, uint32_t id);
protected:
~img_receiver();
// data_holder
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
public:
uint32_t id(void);
size_t size(void);
uint8_t* data(void);
std::string information(void);
PACKIMAGE head(void);
};
class hg_scanner : public sane_opt_provider
{
HGVersionMgr HGVersion_mgr_;
SDKHGVersion_Init_ HGVersion_Init_;
SDKHGVersion_Islock_ HGVersion_Islock_;
SDKHGVersion_Postlog_ HGVersion_Postlog_;
SDKHGVersion_Free_ HGVersion_Free_;
#ifndef WIN32
void* Dynamicopen_HGVersion_pHandle_;;
#else
HINSTANCE Dynamicopen_HGVersion_pHandle_;
#endif
bool notify_setting_result_;
std::string name_;
std::string family_;
std::string save_multiout; //保存多留输出类型
bool save_sizecheck;
bool read_over_with_no_data_; // 针对第三方调用在最后一段数据时是否返回“SCANNER_ERR_NO_DATA”
int is_color_type_;//保存最后下发到设备的颜色类型
sane_callback ui_ev_cb_;
imgproc_mgr* img_processor_ = nullptr;
do_when_born_and_dead<hg_scanner>* scan_life_;
std::unique_ptr<std::thread> thread_usb_read_;
void thread_handle_usb(void);
std::unique_ptr<std::thread> thread_img_handle_;
void thread_image_handle(void);
std::unique_ptr<std::thread> thread_devslock_handle_;
void thread_devslock_handle(void);
std::unique_ptr<std::thread> thread_read_int_;
void thread_read_int(void);
void(hg_scanner::* dump_img_)(hg_imgproc::HIMGPRC himg, const char* desc);
void dump_image_empty(hg_imgproc::HIMGPRC himg, const char* desc);
void dump_image_real(hg_imgproc::HIMGPRC himg, const char* desc);
void init_setting_func_map(void);
bool is_to_file(void);
void thread_handle_image_process(void);
void working_begin(void*);
void working_done(void*);
void image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id);
public:
// 设置接口
protected:
// 配置序号映射数组各子类必须重载“init_setting_map”方法以初始化该数组 --> 2022-05-09基类中以title自动匹配功能序号子类不必再处理并屏蔽此项工作
// 比如: 某型设备的“颜色模式”功能号为1则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = 1
// 如果设备的“颜色模式”配置逻辑与基类预定义的不同,
// 则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = -1在子类重载的set_setting_value方法中处理
//
// 2022-06-28: 属性处理函数改用map结构存储只须处理set_setting_map函数即可
// int setting_map_[HG_BASE_SETTING_INDEX_MAX];
//virtual void init_setting_map(int* setting_map, int count);
std::map<std::string, int (hg_scanner::*)(void*, long*)> setting_map_;
int invoke_setting_xxx(int(hg_scanner::* func)(void*, long*), void* data, long* len);
int setting_restore(void* data, long* len);
int setting_help(void* data, long* len);
int setting_color_mode(void* data, long* len);
int setting_multi_out(void* data, long* len);
int setting_multi_out_type(void* data, long* len);
int setting_rid_color(void* data, long* len);
int setting_rid_multi_red(void* data, long* len);
int setting_rid_answer_red(void* data, long* len);
int setting_erase_background(void* data, long* len);
int setting_erase_background_range(void* data, long* len);
int setting_noise_optimize(void* data, long* len);
int setting_noise_optimize_range(void* data, long* len);
int setting_paper(void* data, long* len);
int setting_paper_check(void* data, long* len);
int setting_page(void* data, long* len);
int setting_page_omit_empty(void* data, long* len);
int setting_resolution(void* data, long* len);
int setting_exchagnge(void* data, long* len);
int setting_split_image(void* data, long* len);
int setting_automatic_skew(void* data, long* len);
int setting_rid_hole(void* data, long* len);
int setting_rid_hoe_range(void* data, long* len);
int setting_bright(void* data, long* len);
int setting_contrast(void* data, long* len);
int setting_gamma(void* data, long* len);
int setting_sharpen(void* data, long* len);
int setting_dark_sample(void* data, long* len);
int setting_erase_black_frame(void* data, long* len);
int setting_threshold(void* data, long* len);
int setting_anti_noise(void* data, long* len);
int setting_margin(void* data, long* len);
int setting_filling_background(void* data, long* len);
int setting_is_permeate(void* data, long* len);
int setting_is_permeate_lv(void* data, long* len);
int setting_remove_morr(void* data, long* len);
int setting_error_extention(void* data, long* len);
int setting_remove_texture(void* data, long* len);
int setting_ultrasonic_check(void* data, long* len);
int setting_go_on_when_double_checked(void* data, long* len);
int setting_staple_check(void* data, long* len);
int setting_scan_mode(void* data, long* len);
int setting_scan_count(void* data, long* len);
int setting_text_direction(void* data, long* len);
int setting_rotate_bkg_180(void* data, long* len);
int setting_fractate_check(void* data, long* len);
int setting_fractate_check_level(void* data, long* len);
int setting_skew_check(void* data, long* len);
int setting_skew_check_level(void* data, long* len);
int setting_is_custom_gamma(void* data, long* len);
int setting_custom_gamma_data(void* data, long* len);
int setting_is_custom_area(void* data, long* len);
int setting_custom_area_left(void* data, long* len);
int setting_custom_area_top(void* data, long* len);
int setting_custom_area_right(void* data, long* len);
int setting_custom_area_bottom(void* data, long* len);
int setting_img_quality(void* data, long* len);
int setting_color_fill(void* data, long* len);
int setting_keep_watermark(void* data, long* len);
int setting_black_white_threshold(void* data, long* len);
int setting_white_pixel_0(void* data, long* len);
int setting_feedmode(void* data, long* len);
int setting_sleeptime(void* data, long* len);
int setting_auto_pick_paper(void* data, long* len);
int setting_auto_pick_paper_threshold(void* data, long* len);
int setting_auto_paper_scan(void* data, long* len);
int setting_isremove_left_hole(void* data, long* len);
int setting_isremove_right_hole(void* data, long* len);
int setting_isremove_top_hole(void* data, long* len);
int setting_isremove_low_hole(void* data, long* len);
int setting_isremove_left_hole_threshold(void* data, long* len);
int setting_isremove_right_hole_threshold(void* data, long* len);
int setting_isremove_top_hole_threshold(void* data, long* len);
int setting_isremove_low_hole_threshold(void* data, long* len);
int setting_fold_type(void* data, long* len);
int setting_color_correction(void* data, long* len);
int setting_auto_paper_scan_exit_time(void* data, long* len);
int setting_get_dev_vid(void* data, long* len);
int setting_get_dev_pid(void* data, long* len);
int setting_get_dev_family(void* data, long* len);
int setting_get_dev_name(void* data, long* len);
int setting_get_dev_sn(void* data, long* len);
int setting_get_dev_fmver(void* data, long* len);
int setting_get_dev_ip(void* data, long* len);
int setting_get_roller_count(void* data, long* len);
int setting_get_history_count(void* data, long* len);
int setting_get_devs_log(void* data, long* len);
int setting_set_language(void* data, long* len);
int setting_get_motor_ver(void* data, long* len);
int setting_get_initial_boot_time(void* data, long* len);
int setting_set_discardblank(void* data, long* len);
virtual void on_device_reconnected(void);
virtual int on_scanner_closing(bool force);
virtual int on_color_mode_changed(int& color_mode) = 0; // COLOR_MODE_xxx
virtual int on_paper_changed(int& paper) = 0; // PAPER_xxx
virtual int on_paper_check_changed(bool& check)=0;
virtual int on_resolution_changed(int& dpi)=0;
virtual int on_ultrasonic_check_changed(bool& check)=0;
virtual int on_staple_check_changed(bool& check) = 0;
virtual int on_skew_check_changed(bool& check) = 0;
virtual int on_skew_check_level_changed(int& check) = 0;
virtual int on_get_feedmode(int& feedmode) = 0; //获取分纸强度
virtual int on_set_feedmode(int feedmode) = 0; //设置分纸强度
virtual int on_pic_type(bool& pic) = 0; //照片模式或者文本模式
virtual int on_pick_paper(bool autostrength) = 0; //设置搓纸使能
virtual int on_pick_paper_threshold(double threshold) = 0; //设置搓纸阈值
virtual int on_is_auto_paper(bool isautopaper) = 0; //待纸扫描
virtual int on_cis_get_image(bool type) = 0;
protected:
virtual int set_setting_value(const char* name, void* data, long* len);
virtual void thread_handle_usb_read(void) = 0;
virtual void thread_handle_islock_read();
int hg_version_init_handle();
int set_server_blacklist_lock(); // 0:不锁定 1:锁定
void hg_version_free_handle();
// adjust color or apply custom gamma
void adjust_color(hg_imgproc::HIMGPRC handle);
hg_imgproc::IMGPRCPARAM get_image_process_object(int model);
SANE_Image_Statu last_usb_image_statu(int err);
hg_imgproc::HIMGPRC ImagePrc_pHandle_;
protected:
ScannerSerial serial_;
volatile bool is_checksum_strat_scan; //设备锁定时,通过校验码来进行扫描
volatile bool run_;
volatile bool is_read_int;
volatile bool user_cancel_;
platform_event wait_usb_;
platform_event wait_img_;
platform_event wait_usb_result_;
platform_event wait_devsislock_;
platform_event wait_read_int;
usb_io* io_;
std::mutex io_lock_;
std::string firmware_ver_;
bool online_;
int status_;
bool async_io_;
bool cb_mem_;
bool test_1_paper_; // 是否为单张扫描模式
std::vector<string> erase_depend_; //需要删除父依赖项
std::string msg_;
ONLNSCANNER dev_;
device_option *dev_opts_ = nullptr;
imgproc_mgr *imgproc_ = nullptr;
shared_memory *singleton_ = nullptr;
scanner_handler *scanner_ = nullptr;
hguser *user_ = nullptr;
IMGPRCFIXPARAM image_prc_param_;
int erase_bkg_range_; // 背景移除像素范围
int noise_range_; // 噪点优化尺寸
TwSS paper_size_;
int omit_empty_level_; // 跳过空白页灵敏度
int resolution_; // 分辨率
double rid_hole_range_; // 穿孔移除范围
int bright_; // 亮度
int contrast_; // 对比度
double gamma_; // 伽玛
int threshold_; // 阈值
int anti_noise_; // 背景搞噪等级
int margin_; // 边缘缩进
int fractate_level_; // 折角检测复杂度
int scan_count_; // 扫描张数各实例化类在重载set_setting_value中如果发现该设置项对该参数有影响时需要对此值作更改
bool is_auto_matic_color;// 自动颜色识别
int is_quality_; // 画质设置 0 - 速度优先1 - 画质优先
bool is_color_fill; // 色彩填充
bool is_multiout; // 多流输出
volatile bool cancelled_ = false;
volatile bool run_ = true;
safe_fifo<img_receiver*> raw_imgs_;
safe_fifo<img_receiver*> final_imgs_;
std::unique_ptr<std::thread> imgpr_thread_;
bool online_ = true;
int bw_threshold_; // 黑白图像阈值 added on 2022-06-28
int feedmode_; // 分纸强度
int sleeptime_; // 睡眠时间
bool is_auto_paper_scan; // 待纸扫描
bool auto_scan_prev_; // 保留待纸扫描程序改变状态之前的值 - 2023-10-16: 智学网根据扫描张数来打开或关闭待纸扫描
bool auto_scan_restore_; // 是否需要恢复待纸扫描状态 - 2023-10-16: 智学网根据扫描张数来打开或关闭待纸扫描
bool size_check; // 尺寸检测
static shared_memory* create_device_singleton(int vid, int pid, int addr);
bool save_feedmode_type_; //保存分支强度狀態
bool save_sleeptime_type_; //保存休眠時間
void init(void);
void thread_image_processor(void);
bool isremove_left_hole; //设置左边除穿孔
bool isremove_right_hole; //设置右边除穿孔
bool isremove_top_hole; //设置上边除穿孔
bool isremove_low_hole; //设置下边除穿孔
double isremove_left_hole_threshold; //设置左边除穿孔阈值
double isremove_right_hole_threshold; //设置右边除穿孔阈值
double isremove_top_hole_threshold; //设置上边除穿孔阈值
double isremove_low_hole_threshold; //设置下边除穿孔阈值
int fold_type_; //对折类型
bool is_cis_image; //设置cis获取原图
bool is_dpi_color_check; //纵向DPI、色差检测 ,畸变自动计算
float save_dpi_color_check_val; //保存纵向DPI、色差检测 ,畸变自动计算 的值
bool is_auto_falt; //是否进行平场校正
bool color_correction_; //是否色彩校正
int is_auto_paper_scan_exit_time; //待纸扫描退出时间
bool is_auto_feedmode_; //是否启用自动分纸强度
bool is_discardblank; //是否启动跳过空白页
bool lateral_ = false;
public:
hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc = nullptr, hguser* user = nullptr, std::vector<sane_opt_provider*>* constopts = nullptr);
SANE_DISTORTION_VAL distortion_val; //畸变修正结构体保存
int split3399_; //3399设备正面和反面图像是相对的所以对折时反面需要进行特殊处理
int pid_;
/////////不同的固件号版本支持
//bool is_kernelsnap_239_220830_; //此版本支持,手动睡眠唤醒,分纸强度
//bool is_kernelsnap_239_211209_; //获取固件版本号是否是新旧版本
//bool is_kernelsnap_239_221027_; //此版本一下不支持拆分模式 pc实现
//bool is_kernelsnap3288_221106_; //G300 3288 在221106版本支持真实300dpi
//bool is_kernelsnap3288_230210_; //G300 3288 在230210版本支持真实600dpi
//bool is_kernelsnap3288_230303_; //G300 3288 支持清除历史扫描张数
//bool is_kernelsnap_devsislock; //支持设备锁的版本
//bool is_kernelsnap_239_3C_; //支持偏色校正的版本,自适应配置
//bool is_kernelsnap_439_3C0606; //支持偏色校正的版本
//bool is_kernelsnap_239_220500_; //支持双张保留的版本
//bool is_kernelsnap_239_220429_; //第一个安陆版本,支持设备日志导出
//bool is_kernelsnap_239_220430_; //待纸扫描
// bool is_kernelsnap_211227_; //此版本以下不支持真实dpi 只设置1下去
bool firmware_sup_wait_paper_; //固件支持 待纸扫描 139 239-3B0431, 439-3B0629
bool firmware_sup_pick_strength_; //固件支持 分纸强度 139 239-3B0830
bool firmware_sup_log_export_; //固件支持 日志导出 139 239-3B0429
bool firmware_sup_color_corr_; //固件支持 偏色校正 139 239 439-3C
bool firmware_sup_wake_device_; //固件支持 唤醒设备 139 239-3B0830
bool firmware_sup_double_img; //固件支持 双张保留 139 239-3C
bool firmware_sup_devs_lock_; //固件支持 设备锁定 139 239-3b0500, 439-3C, 302_402-2023/3/15
bool firmware_sup_dpi_300; //固件支持 真实DPI300 139 239-21227此版本以下不支持真实dpidpi设置1 //3288 G300 用到
bool firmware_sup_dpi_600; //固件支持 真实DPI600 139 239-21227此版本以下不支持真实dpidpi设置1
bool firmware_sup_auto_speed_; //固件支持 自适应速度 139 239 439 -3C
bool firmware_sup_morr_; //固件支持 摩尔纹 139 239-3C0518
bool firmware_sup_color_fill_; //固件支持 色彩填充 139 239 439 -3C
bool firmware_sup_history_cnt; //固件支持 清除历史张数 3288 G300 220303
SCANCONF img_conf_; //此参数外部不做任何改变请在writedown_image_configuration做修改
std::string img_type_;
std::string dump_usb_path_; // 诊断模式输出USB原始图像
final_img_queue final_imgs_; // JPG ...
unsigned int usb_img_index_;
unsigned int final_img_index_;
std::string final_path_;
unsigned long long memory_size_;
bool isx86_Advan_;
int stop_fatal_;
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
uint32_t fetching_id_; // for sane read image ext info. added on 2023-01-13
void init_settings(const char* json_setting_text);
int init_settings(int pid);
int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作
int try_third_app_handle_start(bool& handled);
int try_third_app_after_start(int err);
std::shared_ptr<tiny_buffer> aquire_memory(int size, bool from_usb = true);
// callback to ui ...
int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = SCANNER_ERR_OK);
bool waiting_for_memory_enough(unsigned need_bytes);
void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels, int bits);
int save_usb_data(std::shared_ptr<tiny_buffer> data);
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1);
void adjust_filling_hole(LPSCANCONF conf);
int wait_one_image_from_start(bool& handled);
////////////////////////////////////////////////////////////////
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
bool custom_gamma_; // 为true时应用custom_gamma_val_阵列调整图像色彩为false时保持原来的处理方式
SANE_Gamma *custom_gamma_val_; // 当为RGB或者彩色时为三组256字节的数据当为黑白或灰度时只有一组256字节
bool custom_area_; // 是否启用自定义区域为true时才使用下列4个数据为false时保持原来的处理方式
double custom_area_lt_x_; // 自定义区域左上角x坐标
double custom_area_lt_y_; // 自定义区域左上角y坐标
double custom_area_br_x_; // 自定义区域右下角x坐标
double custom_area_br_y_; // 自定义区域右下角y坐标
SIZE paper_size_mm_; // 当前纸张尺寸mm
// 新增自定义伽玛曲线及扫描区域属性 - END
////////////////////////////////////////////////////////////////
// 2022-07-23 新增双张之后留图继续扫描
int double_paper_handle_; // 汉王要求出现双张的时候可保留
bool keep_watermark_; // 汉王要求图像处理过程中保留水印 - 是否与背景移除、背景填充相关???
// 2022-08-31 新增黑白图像是否反色输出PNM黑白像素与BMP黑白像素相反
bool is_white_0_; // 是否0代表白色
protected:
virtual ~hg_scanner();
// scanner operation ...
public:
int start(void);
int stop(void);
void set_ui_callback(sane_callback cb, bool enable_async_io);
void set_image_processor(imgproc_mgr* proc);
void set_dev_family(const char* family);
void set_read_over_with_no_data(bool no_data);
int reset_io(usb_io* io);
int io_disconnected(void);
int get_pid(void);
int get_vid(void);
int close(bool force);
int set_setting(const char* name, void* data);
int get_setting(const char* name, char* buf, int* len);
int hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type);
int image_configuration(SCANCONF &ic);
std::string name(void);
int close(void);
int re_connect(void);
int get_image_info(SANE_Parameters* pii);
int read_image_data(uint8_t* buf, size_t* len);
int status(void);
std::string status_message(void);
bool is_online(void);
enum thread_running
{
THREAD_RUNNING_IDLE = 0,
THREAD_RUNNING_USB = 1 << 0,
THREAD_RUNNING_IMAGE = 1 << 1,
device_option* get_device_opt(void);
};
int is_running(void); // return thread_running
public:
virtual int do_start(void) = 0;
virtual int do_stop(void) = 0;
virtual int get_image_info(SANE_Parameters* ii);
virtual int read_image_data(unsigned char* buf, int* len);
virtual int reset(void);
virtual int device_io_control(unsigned long code, void* data, unsigned* len);
virtual int discard_all_images(void) = 0;
virtual int get_roller_life(void); // 获取滚轴最大寿命
public:
hg_scanner(ScannerSerial serial, const char* dev_name, const char* model, usb_io* io,int pid);
virtual ~hg_scanner();
static std::string temporary_file(char* tail = NULL, char* head = NULL);
static int save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std::string* path_file, unsigned int index = 0);
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void);
virtual std::string get_serial_num(void);
virtual std::string get_ip(void);
virtual std::string get_device_model(void);
virtual int set_device_model(string str);
virtual int set_serial_num(string str) = 0; //设置序列号
virtual int set_vid_pid(int data) = 0; //设置vidpid
virtual int get_vid_pid(int& data) = 0; //获取vidpid
/////////////成功返回:SCANNER_ERR_OK /////////////
/////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) = 0; //单张扫描
virtual int get_abuot_info(void); //获取软件关于信息 (基类实现)
virtual int restore_default_setting(void); //恢复默认设置 (基类实现)
virtual int set_final_image_format(SANE_FinalImgFormat* fmt);//设置图像处理最终输出final())的图像数据格式 (基类实现) ***
virtual int get_compression_format(void); //获取支持的压缩格式 不支持
virtual int set_compression_format(void); //设置图像数据最终输出的压缩格式 不支持
virtual int set_auto_color_type(void); //设置自动匹配颜色模式 (基类实现)
virtual int set_clear_roller_num(void) = 0; //清除滚轴计数
virtual int set_clear_history_num(void) = 0; //清除历史张数
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type)=0; //获取设备有无纸张 /*/ type : false无纸不正常状态false true有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) = 0; //获取设备是否休眠当中 /*/ type : false休眠不正常状态false true未休眠*/
virtual int get_sleep_time(int& data) = 0; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) = 0; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_history_scan_count(int &data) = 0; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int &data) = 0; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) = 0; //唤醒设备
virtual int get_device_log(string &log) = 0; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) = 0; //设置设备重启 /*/ data:0 reboot data:1 1进入loader,0普通重启
virtual int set_devshtudown() = 0; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) = 0; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) = 0; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) = 0; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) = 0; //固件升级 /*/ str:文件名路径*/
virtual int set_clean_paper_road() = 0; //清理纸道
virtual int get_dev_islock_file(int &data) = 0; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int set_dev_islock_file(int data) = 0; //设置设备文件 /*/ data:0 未上锁1 上锁*/
virtual int get_scan_mode(bool& type) ; //获取设备是否计数模式 /*/ type:false计数模式 true非计数模式
virtual int set_speed_mode(int data) = 0; //设置速度模式 /*/ 设备不同值不同,详情见子类注释
virtual int get_speed_mode(int &data) = 0; //获取速度模式 /*/ 设备不同值不同,详情见子类注释
virtual int set_distortion_image(bool type); //设置畸变校正图 /*/ 基类处理
virtual int get_distortion_check_val(int &val); //获取自动计算畸变校正值 /*/ 基类处理
virtual int set_devs_distortion_check_val(float data) = 0; //设置畸变矫正值 float;
virtual int get_devs_distortion_check_val(float& data) = 0; //获取设备畸变值 float;
virtual int set_auto_flat(int data) = 0; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
virtual int set_updata0303(void) ;
virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号 //3399设备支持
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
virtual int get_devs_time(string &times); //获取设备时间 //3399设备支持
// sane_opt_provider
public:
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
virtual int set_value(const char* name, void* val) override;
virtual void enable(const char* name, bool able) override;
};
//TEST 测试GIT切换
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NEW

File diff suppressed because one or more lines are too long

View File

@ -1,115 +0,0 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include "hg_scanner.h"
//#ifdef OEM_HANWANG
//#define hg_scanner_200 hw_scanner_200
//#elif defined(OEM_LISICHENG)
//#define hg_scanner_200 lsc_scanner_200
//#endif
class hg_scanner_200 : public hg_scanner
{
void discard_prev(void);
protected:
virtual void thread_handle_usb_read(void) override;
virtual int on_scanner_closing(bool force) override;
virtual int discard_all_images(void) override;
virtual int get_roller_life(void) override;
protected:
virtual int on_color_mode_changed(int& color_mode) override; // COLOR_MODE_xxx
virtual int on_paper_changed(int& paper) override; // PAPER_xxx
virtual int on_paper_check_changed(bool& check) override;
virtual int on_resolution_changed(int& dpi) override;
virtual int on_ultrasonic_check_changed(bool& check) override;
virtual int on_staple_check_changed(bool& check) override;
virtual int on_skew_check_changed(bool& check) override;
virtual int on_skew_check_level_changed(int& check) override;
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic) override; //照片模式或者文本模式
virtual int on_pick_paper(bool autostrength)override; //设置搓纸使能
virtual int on_pick_paper_threshold(double threshold) override; //设置搓纸阈值
virtual int on_is_auto_paper(bool isautopaper) override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //获取cis原图
public:
hg_scanner_200(const char* dev_name, const char* model,int vid, usb_io* io);
~hg_scanner_200();
public:
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int initdevice();
int writeusb(USBCB &usb);
int readusb(USBCB &usb);
int pop_image();
int get_scanner_status(USBCB &usb);
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = IMG_STATUS_OK);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL);
setting_hardware::HGSCANCONF_DSP dsp_config_;
int agreement();
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void)override;
virtual std::string get_serial_num(void)override;
virtual std::string get_ip(void)override;
virtual int set_serial_num(string str) override; //设置序列号
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获取vidpid
/////////////////成功返回:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) override; //单张扫描
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历史张数
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备重启
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
virtual int set_clean_paper_road() override; //清理纸道
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁1 上锁*/
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ 不支持
virtual int get_speed_mode(int &data) override; //设置速度模式 /*/ 不支持
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正
virtual int get_devs_distortion_check_val(float& data) override; //获取设备畸变值
virtual int set_auto_flat(int data); //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
};

File diff suppressed because one or more lines are too long

View File

@ -1,146 +0,0 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <list>
#include "hg_scanner.h"
//#include <vld.h>
//#ifdef OEM_HANWANG
//#define hg_scanner_239 hw_scanner_239
//#elif defined(OEM_LISICHENG)
//#define hg_scanner_239 lsc_scanner_239
//#endif
class hg_scanner_239 : public hg_scanner
{
//BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> final_imgs_; // JPG ...
// image_data final_imgs_; // JPG ..
setting_hardware::HGSCANCONF_3399 dev_conf_;
bool rewrite_conf_;
bool reset_;
bool is_start_status;
std::list<int> svdevs_err_;
std::string control_fetch(int addr, int val, int size);
std::string get_fpga(void);
int get_status(void);
int get_image_count(void);
int get_front_data_size(void);
int read_register(int addr, int* val);
int write_register(int addr, int val);
int write_command(int cmd);
int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在startå†<C3A5>把type置为true,å…¶ä»å<E28093>šè®¾ç½®æ—¶ä¸<C3A4>å<EFBFBD>
int writedown_image_configuration(void);
int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
bool is_dev_image_process_done(void);
bool is_dev_image_keep_last_paper(void);
void init_version(void);
void thread_get_dves_image(void);
void thread_correction(void);
int write_control_device_files(std::string file_path,std::string file_str);
int read_control_device_files(std::string file_path, std::string &file_str);
protected:
virtual void on_device_reconnected(void) override;
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual int discard_all_images(void);
protected:
virtual int on_color_mode_changed(int& color_mode) override; //颜色切æ<E280A1>¢
virtual int on_paper_changed(int& paper) override; //纸张大å°<C3A5>设置
virtual int on_paper_check_changed(bool& check) override; //尺寸检�
virtual int on_resolution_changed(int& dpi) override; //分辨率设�
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检�
virtual int on_staple_check_changed(bool& check) override; //设置订书针检�
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检�
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强�
virtual int on_get_feedmode(int& feedmode) override; //获å<C2B7>分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic)override; //照片模å¼<C3A5>æˆè€…æ‡æœ¬æ¨¡å¼?
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫æ<C2AB><C3A6>
virtual int on_cis_get_image(bool isautopaper) override; //cis 原å¾èŽ·å<C2B7>
public:
hg_scanner_239(const char* dev_name, const char* model, int pid,usb_io* io);
~hg_scanner_239();
public:
//virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
virtual int get_roller_life(void) override;
public:
//////////////åºå®šçš„硬件信æ<C2A1>¯è®¾ç½®æˆèŽ·å<C2B7>//////////////
virtual std::string get_firmware_version(void)override;
virtual std::string get_serial_num(void)override;
virtual std::string get_ip(void)override;
virtual std::string get_device_model(void);
virtual int set_device_model(string str);
virtual int set_serial_num(string str) override; //设置åº<C3A5>列å<E28094>?
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获å<C2B7>vidpid
/////////////////æˆ<C3A6>功返åž:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误�or SCANNER_ERR_DEVICE_NOT_SUPPORT /////////////
virtual int set_leaflet_scan(void) override; //å<>•å¼ æ‰«æ<C2AB><C3A6>
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历å<E280A0>²å¼ æ•°
virtual int get_device_code(void); //获å<C2B7>设备ç¼ç <C3A7> ä¸<C3A4>支æŒ?
virtual int get_scanner_paperon(SANE_Bool& type) override; //获å<C2B7>设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获å<C2B7>设备是å<C2AF>¦ä¼çœ å½“中 /*/ type : 0ä¼çœ  1唤é†çŠ¶æ€?/
virtual int get_sleep_time(int& data) override; //获å<C2B7>功耗模å¼<C3A5>(ä¼çœ ï¼? /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模å¼<C3A5>(ä¼çœ ï¼? /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获å<C2B7>历å<E280A0>²æ‰«æ<C2AB><C3A6>å¼ æ•° /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获å<C2B7>滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获å<C2B7>设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备é‡<C3A9>å<EFBFBD>¯
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是å<C2AF>¦é”<C3A9>定 /*/ type:0解é”<C3A9>ï¼?é”<C3A9>定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获å<C2B7>设备是å<C2AF>¦é”<C3A9>定 /*/ type:0解é”<C3A9>ï¼?é”<C3A9>定*/
virtual int set_scan_lock_check_val(string str) override; //获å<C2B7>设备是å<C2AF>¦é”<C3A9>定 /*/ str:校验ç ?/
virtual int set_firmware_upgrade(std::string str) override; //åºä»¶å<C2B6>‡çº§ /*/ str:æ‡ä»¶å<C2B6><C3A5>è·¯å¾?/
virtual int set_clean_paper_road() override; //清ç<E280A6>†çº¸é<C2B8>
virtual int get_dev_islock_file(int& data) override; //获å<C2B7>设备æ‡ä»¶ /*/ data:0 未上é”<C3A9>,1 上é”<C3A9>ã€?1 未å<C2AA>现é»å<E28098><C3A5>å<EFBFBD>•åˆ—表 -2列表没有信æ<C2A1>¯*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上é”<C3A9>,1 上é”<C3A9>*/
virtual int get_scan_mode(bool& type); //获å<C2B7>是å<C2AF>¦æ˜¯è®¡æ•°æ¨¡å¼? /*/ type : fasle计数模å¼<C3A5> trueé<65>žè®¡æ•?*/
virtual int set_speed_mode(int data) override; //设置速度模å¼<C3A5> /*/ data:100,110,120
virtual int get_speed_mode(int& data)override; //获å<C2B7>速度模å¼<C3A5> /*/ data:100,110,120
virtual int set_devs_distortion_check_val(float data) override; //设置畸å<C2B8>˜çŸ«æ­£å€?
virtual int get_devs_distortion_check_val(float &data) override; //获å<C2B7>畸å<C2B8>˜çŸ«æ­£å€?
virtual int set_auto_flat(int data); //设置自动平场校正
// data:0(ALL) 1(200dpiã€<C3A3>gray) 2(200dpiã€<C3A3>color) 3(300dpiã€<C3A3>gray) 4(300dpiã€<C3A3>color) 5(600dpiã€<C3A3>gray) 6(600dpiã€<C3A3>color)
virtual int get_motor_board_ver(string &ver);
virtual int set_devs_time(string times); //设置设备时间 //3399设备支æŒ<C3A6>
virtual int get_devs_time(string& times); //获å<C2B7>设备时间 //3399设备支æŒ<C3A6>
};

File diff suppressed because one or more lines are too long

View File

@ -1,119 +0,0 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include "hg_scanner.h"
#include "PaperSize.h"
//#ifdef OEM_HANWANG
//#define hg_scanner_300 hw_scanner_300
//#elif defined(OEM_LISICHENG)
//#define hg_scanner_300 lsc_scanner_300
//#endif
class hg_scanner_300 : public hg_scanner
{
protected:
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual int discard_all_images(void) override;
virtual int get_roller_life(void) override;
protected:
virtual int on_color_mode_changed(int& color_mode) override; //颜色切换
virtual int on_paper_changed(int& paper) override; //纸张大小设置
virtual int on_paper_check_changed(bool& check) override; //尺寸检测
virtual int on_resolution_changed(int& dpi) override; //分辨率设置
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测
virtual int on_staple_check_changed(bool& check) override; //设置订书针检测
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
public:
hg_scanner_300(const char* dev_name, const char* model,int pid, usb_io* io);
~hg_scanner_300();
public:
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int set_kernelsnap_ver();
int agreement(TwSS tw,int align);
int initdevice();
int writeusb(USBCB &usb);
int readusb(USBCB &usb);
int pop_image(void);
int get_scanner_status(USBCB &usb);
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
int get_img_data_7010(std::shared_ptr<tiny_buffer>& imagedata);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL);
private:
std::vector<int> savestatus_;
setting_hardware::HGSCANCONF_3288 dsp_config;
Device::PaperSize papersize;
bool is_devs_sleep_;
int index_;
char* pdata;
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void)override;
virtual std::string get_serial_num(void)override;
virtual std::string get_ip(void)override;
virtual int set_serial_num(string str) override; //设置序列号
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获取vidpid
/////////////////成功返回:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) override; //单张扫描
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历史张数 0303固件版本才支持
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备重启
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
virtual int set_clean_paper_road() override; //清理纸道
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁1 上锁*
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:40,50,60,70
virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:40,50,60,70
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正
virtual int get_devs_distortion_check_val(float& data)override;//获取设备畸变值 float to int;
virtual int set_auto_flat(int data)override; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
virtual int set_updata0303(void)override;
};

File diff suppressed because one or more lines are too long

View File

@ -1,135 +0,0 @@
#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include "hg_scanner.h"
//#ifdef OEM_HANWANG
//#define hg_scanner_302 hw_scanner_302
//#elif defined(OEM_LISICHENG)
//#define hg_scanner_302 lsc_scanner_302
//#endif
class hg_scanner_302 : public hg_scanner
{
//BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> final_imgs_; // JPG ...
// image_data final_imgs_; // JPG ..
setting_hardware::HGSCANCONF_3399 dev_conf_;
bool rewrite_conf_;
bool reset_;
int read_register(int addr, int* val);
int write_register(int addr, int val);
int write_command(int cmd);
std::string control_fetch(int addr, int val, int size);
std::string get_fpga(void);
int clr_roller_num(void);
int get_sleep_time(void);
int get_scan_mode(void);
int get_status(void);
bool is_dev_tx(void);
bool is_dev_image_process_done(void);
bool is_dev_image_keep_last_paper(void);
int get_scanned_count(void);
int get_image_count(void);
int get_front_data_size(void);
void init_version(void);
int get_device_sleep_stautus(void);
int get_device_paperon_stautus(void);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3399 *dev_conf = NULL);
int writedown_image_configuration(void);
int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
virtual int discard_all_images();
virtual int get_roller_life(void) override;
protected:
virtual void on_device_reconnected(void) override;
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
protected:
virtual int on_color_mode_changed(int& color_mode) override; //颜色切换
virtual int on_paper_changed(int& paper) override; //纸张大小设置
virtual int on_paper_check_changed(bool& check) override; //尺寸检测
virtual int on_resolution_changed(int& dpi) override; //分辨率设置
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测
virtual int on_staple_check_changed(bool& check) override; //设置订书针检测
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
virtual int on_cis_get_image(bool isautopaper) override; //cis 原图获取
public:
hg_scanner_302(const char* dev_name, const char* model, int pid,usb_io* io);
~hg_scanner_302();
public:
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
public:
//////////////固定的硬件信息设置或获取//////////////
virtual std::string get_firmware_version(void)override;
virtual std::string get_serial_num(void)override;
virtual std::string get_ip(void)override;
virtual int set_serial_num(string str) override; //设置序列号
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获取vidpid
/////////////////成功返回:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误码 /////////////
virtual int set_leaflet_scan(void) override; //单张扫描
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历史张数
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备重启
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
virtual int set_clean_paper_road() override; //清理纸道
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁1 上锁*/
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:40,50,60,70
virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:40,50,60,70
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正
virtual int get_devs_distortion_check_val(float& data) override; //获取设备畸变值
virtual int set_auto_flat(int data) override; //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
};

File diff suppressed because it is too large Load Diff

View File

@ -1,226 +0,0 @@
#pragma once
// API for image process
//
// created on 2022-03-01
//
#include "huagao/hgscanner_error.h"
#include "common_setting.h"
#include <memory>
#include <vector>
#include <sane/sane_ex.h>
#include "../ImageProcess/ImageApplyHeaders.h"
//#include <vld.h>
class tiny_buffer;
namespace hg_imgproc
{
typedef struct _img_data
{
int img_fmt; // 图片格式BMP、PNG……暂时未用
int width; // 行宽度(像素数)
int height; // 高度(像素数)
int line_bytes; // 每行的字节数
int bits; // 每个像素的位深
bool is_bw; // 是否为黑白图片,由图像处理模块设置
unsigned bytes; // 图像数据字节数(buf中的字节数)
void* ip_data; // 图像处理模块的自定义数据,调用者不要随意更改此值!!!
void* buf; // 图像数据信息
}IMGDATA, *LPIMGDATA;
// 用于释放图像处理模块返回的各种动态内存, mem[i] == NULL 时终止,下列相同参数均照此规则
void imgproc_free_memory(LPIMGDATA* mem);
// 所有函数均返回“int”值代表错误代码 0为成功其它错误码由图像处理模块开发者定义
// Function: 用于将原始数据如图像文件内容解码为target_fmt指定的图像格式
//
// Parameters: raw - 原始的图像数据
//
// bytes - raw中数据字节数
//
// bits - 位深
//
// out - 用于接收解码后的图像数据。由图像处理模块分配内存调用者调用imgproc_free_memory释放
//
// Return: 错误码
//
// NOTE: 该函数返回的out结构体中buf为图像处理的中间数据类型如cv::mat*),要想获取最终的图片数据,
// 需要再调用 imgproc_final 函数进行转换
int imgproc_decode(void* buf, unsigned bytes, int bits, LPIMGDATA** out);
// Function: 将倾斜的文本校正
//
// Parameters: raw - [in]: 原始的图像数据,*raw == NULL时终止
//
// [out]: 最终的图像数据
//
// out - 用于接收解码后的图像数据。由图像处理模块分配内存调用者调用imgproc_free_memory释放
//
// dpi - 图片DPI
//
// double_face - 是否双面
//
// Return: 错误码
int imgproc_correct_text(LPIMGDATA** raw, int dpi, bool double_face); // 适用于raw从其它图像处理函数返回的情况
int imgproc_correct_text(LPIMGDATA* raw, LPIMGDATA** out, int dpi, bool double_face); // 适用于raw从文件或者内存中转换而来
// Function: 自动匹配颜色
//
// Parameters: raw - [in]: 原始的图像数据,*raw == NULL时终止
//
// [out]: 最终的图像数据
//
// out - 用于接收解码后的图像数据。由图像处理模块分配内存调用者调用imgproc_free_memory释放
//
// double_face - 是否双面
//
// Return: 错误码
int imgproc_auto_adjust_color(LPIMGDATA** raw, bool double_face); // 适用于raw从其它图像处理函数返回的情况
int imgproc_auto_adjust_color(LPIMGDATA* raw, LPIMGDATA** out, bool double_face); // 适用于raw从文件或者内存中转换而来
// Function: 图像拆分
//
// Parameters: raw - [in]: 原始的图像数据,*raw == NULL时终止
//
// [out]: 最终的图像数据
//
// out - 用于接收解码后的图像数据。由图像处理模块分配内存调用者调用imgproc_free_memory释放
//
// Return: 错误码
int imgproc_split(LPIMGDATA** raw); // 适用于raw从其它图像处理函数返回的情况
int imgproc_split(LPIMGDATA* raw, LPIMGDATA** out); // 适用于raw从文件或者内存中转换而来
// Function: 多流输出
//
// Parameters: raw - [in]: 原始的图像数据,*raw == NULL时终止
//
// out - 用于接收解码后的图像数据。由图像处理模块分配内存调用者调用imgproc_free_memory释放
//
// dpi - 图片DPI
//
// double_face - 是否双面
//
// Return: 错误码
int imgproc_multi_out(LPIMGDATA* raw, LPIMGDATA** out, int dpi, bool double_face);
enum
{
TARGET_FORMAT_GRAY = 1 << 0,
TARGET_FORMAT_BLACK_WHITE = 1 << 1,
TARGET_FORMAT_RGB = 1 << 2,
};
// Function: 用于将图像处理过程的中间态数据,转换为最终的图片数据
//
// Parameters: raw - [in]: 原始的图像数据,*raw == NULL时终止通常该变量是由其它图像处理函数返回的
//
// [out]: 最终的图像数据
//
// target_fmt - 预期解码到的格式TARGET_FORMAT_xxx
//
// Return: 错误码
int imgproc_final(LPIMGDATA** raw, int target_fmt, int dpi);
////////////////////////////////////////////////////////////////////////////////
// NEWflow ...
//
// 1 - call init to initialize an image processing object handle HIMGPRC
//
// 2 - call load_buffer or load_file to load raw data
//
// 3 - call image-processing methods
//
// 4 - repeat step-3
//
// 5 - call final to got outputing data
//
// 6 - call get_final_data to get outputing data, while return SCANNER_ERR_NO_DATA
//
// 7 - call release to free the HIMGPRC handle
//
////////////////////////////////////////////////////////////////////////////////
typedef void* HIMGPRC;
typedef struct _img_proc_param
{
int dpi;
int bits; // 单分量位深
int channels;
int color_mode;
bool double_side;
bool black_white;
bool cis_image; //设置原图
}IMGPRCPARAM, *LPIMGPRCPARAM;
typedef struct _img_header
{
int width; // in pixel
int height; // in pixel
int bits; // per channel
int channels; // RGB - 3; GRAY - 1; ...
int line_bytes; // bytes of ONE line
unsigned total_bytes;// total bytes
SANE_Image_Statu statu; // added on 2022-07-23
}IMGHEAD, *LPIMGHEAD;
HIMGPRC init(int pid, bool isx86Advan_);
int load_buffer(HIMGPRC himg,std::shared_ptr<tiny_buffer> buff);
int load_file(HIMGPRC himg, const char* path_file);
//图像数据转换
int decode(HIMGPRC himg,int pid, LPSCANCONF img_param, LPIMGPRCPARAM param);
int correct_text(HIMGPRC himg);
int init_auto_txt_hanld(HIMGPRC himg);
int free_auto_txt_hanld(HIMGPRC himg);
//拆分
int split(HIMGPRC himg,int split3399);
int fadeback(HIMGPRC himg);
int multi_out(HIMGPRC himg,int out_type);
int multi_out_red(HIMGPRC himg);
int auto_matic_color(HIMGPRC himg,int color_type);
int auto_crop(HIMGPRC himg, float dpi);
int fillhole(HIMGPRC himg, float top, float low, float r, float l);
int resolution_change(HIMGPRC himg,float dpi3288);
int croprect(HIMGPRC himg);
int channel(HIMGPRC himg);
int adjust_color(HIMGPRC himg, unsigned char* table = nullptr, int tableLength = 0/*default value is to adjust color, or apply custom gamma*/);
int antiInflow(HIMGPRC himg,int permeate_lv);
int colorCorrection(HIMGPRC himg);
int orentation(HIMGPRC himg);
int textureRemove(HIMGPRC himg);
int remove_morr(HIMGPRC himg);
int sharpenType(HIMGPRC himg);
int nosieDetach(HIMGPRC himg);
int errorextention(HIMGPRC himg);
int discardBlank(HIMGPRC himg);
int answerSheetFilterRed(HIMGPRC himg);
int imgtypechange(HIMGPRC himg,std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata);
int fold(HIMGPRC himg);
int quality(HIMGPRC himg,int dpi);
int ocr_auto_txtdirect(HIMGPRC himg);
int tesseract_auto_txtdirect(HIMGPRC himg);
int size_detection(HIMGPRC himg);
int cis_test_image(HIMGPRC himg, CISTestImageProcess::CISTestResult& res);
int color_cast_correction(HIMGPRC himg);
int final(HIMGPRC himg);
// pimh must not to be NULL, and pimh->total_bytes indicates the length of 'buf'
//
// if 'buf' was NULL, then return SCANNER_ERR_INSUFFICIENT_MEMORY
//
// index is ZERO-base, if index is valid, fill the 'pimh' first, and copy data to buf if it was not NULL
// return SCANNER_ERR_NO_DATA if it was out of range
//
// return SCANNER_ERR_OK if index has valid image data and buf is large enough
int get_final_data(HIMGPRC himg, LPIMGHEAD pimh, void** buf, int index = 0);
int get_final_data(HIMGPRC himg, LPIMGHEAD pimh, std::vector<unsigned char>* buf, int index);
void dump_2_file(HIMGPRC himg, const char* local_file);
void release(HIMGPRC himg);
// seperate utilites ...
int convert_image_file(SANE_ImageFormatConvert* conv);
int save_2_bmp_file(const char* bmp_file, LPIMGHEAD head, void* buf, int resolution);
std::string bmp8_2_1bit(const unsigned char* data, int w, int h, int line_len, int threshold, bool reverse, bool align);
}

View File

@ -3,7 +3,7 @@
#include <json/gb_json.h>
#include <huagao/hgscanner_error.h>
#include <ImageApplyOutHole.h>
#include <base/packet.h>

View File

@ -0,0 +1,844 @@
#include "async_usb_host.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// async_usb_host
async_usb_host::async_usb_host(std::function<FUNCTION_PROTO_COMMAND_HANDLE> cmd_handler)
: handler_(cmd_handler), usb_dev_(nullptr), usb_handle_(nullptr), run_(true), cancel_write_(false), writing_(false)
, head_enc_type_(ENCRYPT_CMD_NONE), payload_enc_type_(ENCRYPT_NONE), enc_data_(0), buf_coef_(1)
{
memset(&bulk_in_, -1, sizeof(bulk_in_));
memset(&bulk_out_, -1, sizeof(bulk_out_));
bulk_in_.claimed = bulk_out_.claimed = 0;
}
async_usb_host::~async_usb_host()
{
stop();
}
int async_usb_host::enum_usb_endpoints(libusb_device* dev, std::vector<USBEP>& eps)
{
libusb_device_descriptor desc;
libusb_config_descriptor* conf = NULL;
int ret = libusb_get_device_descriptor(dev, &desc);
bool found_ep = false;
for (int i = 0; i < (int)desc.bNumConfigurations; ++i)
{
if (libusb_get_config_descriptor(dev, i, &conf))
continue;
for (int j = 0; j < conf->bNumInterfaces; ++j)
{
for (int k = 0; k < conf->interface[j].num_altsetting; ++k)
{
for (int l = 0; l < conf->interface[j].altsetting[k].bNumEndpoints; ++l)
{
USBEP ep;
ep.iconf = i;
ep.iface = j;
ep.type = conf->interface[j].altsetting[k].endpoint[l].bmAttributes;
ep.port = conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress & (LIBUSB_ENDPOINT_IN | LIBUSB_ENDPOINT_OUT | 3);
ep.claimed = 0;
ep.max_packet = conf->interface[j].altsetting[k].endpoint[l].wMaxPacketSize;
eps.push_back(std::move(ep));
}
}
}
libusb_free_config_descriptor(conf);
}
return ret;
}
dyn_mem_ptr async_usb_host::base_packet(int cmd, uint32_t id, uint32_t encrypt)
{
dyn_mem_ptr data(dyn_mem::memory(sizeof(PACK_BASE))), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
data->set_len(sizeof(PACK_BASE));
BASE_PACKET_REPLY(*pack, cmd, id, 0);
enc = packet_encrypt(data, encrypt);
data->release();
data = enc;
return data;
}
int async_usb_host::start(libusb_device* dev)
{
std::vector<USBEP> eps;
int ret = stop();
if (ret)
return ret;
ret = libusb_open(dev, &usb_handle_);
if (ret)
return ret;
ret = async_usb_host::enum_usb_endpoints(dev, eps);
if (ret)
{
libusb_close(usb_handle_);
return ret;
}
std::sort(eps.begin(), eps.end());
for (auto& v : eps)
{
if (v.type == LIBUSB_TRANSFER_TYPE_BULK)
{
if (v.port & LIBUSB_ENDPOINT_IN)
{
bulk_in_ = v;
}
else
{
bulk_out_ = v;
}
}
}
if (bulk_in_.port == (uint8_t)-1 || bulk_out_.port == (uint8_t)-1)
{
stop();
return ENOENT;
}
ret = libusb_claim_interface(usb_handle_, bulk_in_.iface);
if (ret)
{
stop();
return ret;
}
bulk_in_.claimed = 1;
if (bulk_in_.iface != bulk_out_.iface)
{
ret = libusb_claim_interface(usb_handle_, bulk_out_.iface);
if (ret)
{
stop();
return ret;
}
bulk_out_.claimed = 1;
}
run_ = true;
libusb_ref_device(dev);
usb_dev_ = dev;
create_worker_threads();
return ret;
}
int async_usb_host::stop(void)
{
dyn_mem_ptr data = nullptr;
data_source_ptr out = nullptr;
run_ = false;
stop_worker_threads();
in_que_.trigger();
while (in_que_.take(data))
data->release();
out_que_.trigger();
while (out_que_.take(out))
out->release();
if (usb_handle_)
{
if (bulk_in_.claimed)
libusb_release_interface(usb_handle_, bulk_in_.iface);
if(bulk_out_.claimed)
libusb_release_interface(usb_handle_, bulk_out_.iface);
libusb_close(usb_handle_);
usb_handle_ = nullptr;
}
if (usb_dev_)
{
libusb_unref_device(usb_dev_);
usb_dev_ = nullptr;
}
memset(&bulk_in_, -1, sizeof(bulk_in_));
memset(&bulk_out_, -1, sizeof(bulk_out_));
bulk_in_.claimed = bulk_out_.claimed = 0;
return 0;
}
uint32_t& async_usb_host::encrypt_type_packet_head(void)
{
return head_enc_type_; // = ENCRYPT_CMD_NONE;
}
uint32_t& async_usb_host::encrypt_type_payload(void)
{
return payload_enc_type_;
}
uint8_t& async_usb_host::encrypt_data(void)
{
return enc_data_;
}
void async_usb_host::thread_read_bulk(void)
{
size_t buf_size = buf_coef_ * bulk_in_.max_packet;
dyn_mem_ptr mem = dyn_mem::memory(buf_size);
utils::to_log(LOG_LEVEL_ALL, "thread_read_bulk working ...\r\n");
while (run_)
{
int r = 0,
err = libusb_bulk_transfer(usb_handle_, bulk_in_.port, mem->ptr(), buf_size, &r, -1);
if (err)
{
if (err == LIBUSB_ERROR_TIMEOUT || err == LIBUSB_ERROR_INTERRUPTED)
{
continue;
}
else
{
// handle the error ...
utils::to_log(LOG_LEVEL_FATAL, "thread_read_bulk FATAL error: %d\r\n", err);
break;
}
}
mem->set_len(r);
in_que_.save(mem, true);
buf_size = buf_coef_ * bulk_in_.max_packet;
mem = dyn_mem::memory(buf_size);
}
if (mem)
mem->release();
utils::to_log(LOG_LEVEL_ALL, "thread_read_bulk exited.\r\n");
}
void async_usb_host::thread_write_bulk(void)
{
utils::to_log(LOG_LEVEL_ALL, "thread_write_bulk working ...\r\n");
while (run_)
{
data_source_ptr data = nullptr;
if (out_que_.take(data, true) && data)
{
int err = 0;
if(!cancel_write_)
inner_write_bulk(data, &err);
data->release();
if (err && err != ECANCELED)
{
// handle the error ...
utils::to_log(LOG_LEVEL_FATAL, "thread_write_bulk FATAL error: %d\r\n", err);
break;
}
}
}
utils::to_log(LOG_LEVEL_ALL, "thread_write_bulk exited.\r\n");
}
void async_usb_host::thread_pump_task(void)
{
dyn_mem_ptr prev = nullptr, data = nullptr, reply = nullptr;
bool in_err_statu = false;
uint32_t required = 0, used = 0, restore_err_cnt = 0;
data_holder* dh = nullptr;
LPPACK_BASE pack = nullptr;
utils::to_log(LOG_LEVEL_ALL, "thread_pump_task working ...\r\n");
while (run_)
{
data = nullptr;
if (in_que_.take(data, true) && data)
{
if (prev)
{
*prev += *data;
data->release();
data = prev;
prev = nullptr;
}
do
{
packet_data_base_ptr pack_data = nullptr;
data_source_ptr ds = nullptr;
if (dh == nullptr)
{
if (data->get_rest() < sizeof(PACK_BASE))
break;
else
{
used = data->get_rest();
reply = handle_data_in(data, &used, &pack_data);
if (pack_data)
{
dh = dynamic_cast<data_holder_ptr>(pack_data);
if (!dh)
{
ds = dynamic_cast<data_source_ptr>(pack_data);
if (!ds)
pack_data->release();
}
}
}
}
else
{
uint32_t len = data->get_rest();
int err = dh->put_data(data->ptr(), &len);
if (dh->is_complete() || err)
{
//reply = dyn_mem::memory(sizeof(PACK_BASE));
//pack = (LPPACK_BASE)reply->ptr();
//BASE_PACKET_REPLY(*pack, dh->get_packet_command() + 1, dh->get_packet_id(), err);
//reply->set_len(sizeof(PACK_BASE));
dh->release();
dh = nullptr;
}
used = len;
if (err)
{
in_err_statu = true;
restore_err_cnt = 0;
}
}
// first reply the packet ...
if (reply)
{
post_2_write_bulk_thread(dynamic_cast<data_source_ptr>(reply));
reply->release();
reply = nullptr;
}
// second send appendix data ...
if (ds)
{
post_2_write_bulk_thread(ds);
ds->release();
ds = nullptr;
}
data->used(used);
} while (used && data->get_rest());
if (data->get_rest())
prev = data;
else
data->release();
}
}
if (prev)
prev->release();
if (data)
data->release();
if (reply)
reply->release();
if (dh)
dh->release();
utils::to_log(LOG_LEVEL_ALL, "thread_pump_task exited.\r\n");
}
void async_usb_host::create_worker_threads(void)
{
thread_w_.reset(new std::thread(&async_usb_host::thread_write_bulk, this));
thread_r_.reset(new std::thread(&async_usb_host::thread_read_bulk, this));
thread_p_.reset(new std::thread(&async_usb_host::thread_pump_task, this));
}
void async_usb_host::stop_worker_threads(void)
{
#define WAIT_THREAD(t) \
if(t.get() && t->joinable()) \
t->join();
WAIT_THREAD(thread_w_);
WAIT_THREAD(thread_r_);
WAIT_THREAD(thread_p_);
}
int async_usb_host::bulk_write_buf(uint8_t* buf, int* len)
{
int bulk_size = bulk_out_.max_packet * buf_coef_,
total = 0,
l = bulk_size <= *len ? bulk_size : *len,
s = 0,
err = 0;
do
{
while ((err = libusb_bulk_transfer(usb_handle_, bulk_out_.port, buf, l, &s, 1000)) == 0)
{
if (cancel_write_)
{
err = ECANCELED;
break;
}
total += s;
if (total >= *len)
break;
buf += s;
if (*len - total < bulk_size)
l = *len - total;
else
l = bulk_size;
}
} while (err == LIBUSB_ERROR_INTERRUPTED); // should pay more attention to this error !!!
*len = total;
return err;
}
int async_usb_host::inner_write_bulk(data_source_ptr data, int* err)
{
unsigned char* ptr = data->ptr();
size_t bulk_size = bulk_out_.max_packet * buf_coef_,
total = data->get_rest();
int e = 0, s = 0;
writing_ = true;
if (data->is_memory_block())
{
s = total;
e = bulk_write_buf(ptr, &s);
if (err)
*err = e;
total = s;
}
else
{
dyn_mem_ptr twin[] = { dyn_mem::memory(bulk_size), dyn_mem::memory(bulk_size) },
buf = twin[0];
int ind = 0;
uint32_t len = bulk_size;
if (err)
*err = 0;
total = 0;
while ((e = data->fetch_data(buf->ptr(), &len)) == 0)
{
buf->set_len(len);
if (len == 0)
utils::to_log(LOG_LEVEL_WARNING, "ZERO byte content fetched!\r\n");
do
{
if (e)
utils::to_log(LOG_LEVEL_WARNING, "Write failed at + 0x%08X with error 0x%x, we try again ...\r\n", total, e);
ptr = buf->ptr();
s = len;
e = bulk_write_buf(ptr, &s);
} while (e == LIBUSB_ERROR_INTERRUPTED || e == LIBUSB_ERROR_TIMEOUT);
if (e)
{
utils::to_log(LOG_LEVEL_ALL, "Write failed at +0x%08X with error: 0x%x. (Rest: %u)\r\n", total, e, data->get_rest());
if (err)
*err = e;
break;
}
else
total += s;
if (data->get_rest() == 0)
break;
len = bulk_size;
ind ^= 1;
buf = twin[ind];
}
twin[0]->release();
twin[1]->release();
}
writing_ = false;
return total;
}
void async_usb_host::post_2_write_bulk_thread(data_source_ptr data)
{
data->add_ref();
out_que_.save(data, true);
}
dyn_mem_ptr async_usb_host::handle_data_in(dyn_mem_ptr& data, uint32_t* used, packet_data_base_ptr* more)
{
dyn_mem_ptr decrypt = packet_decrypt(data);
if (decrypt)
{
data->release();
data = decrypt;
return handler_(data, used, more);
}
else
{
*used = data->get_rest();
*more = nullptr;
return nullptr;
}
}
int async_usb_host::get_peer_protocol_version(uint16_t* ver)
{
uint16_t v = 0;
int err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_GET_PROTO_VER, 0, 0
, (unsigned char*)&v, sizeof(v)
, 1000);
if (ver)
*ver = v;
return err == sizeof(v) ? 0 : EFAULT;
}
int async_usb_host::get_peer_status(LPEP0REPLYSTATUS status)
{
return libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_GET_STATUS, 0, 0
, (unsigned char*)status, sizeof(*status)
, 1000) == sizeof(*status) ? 0 : EFAULT;
}
int async_usb_host::restart_peer_bulk(uint32_t timeout)
{
EP0REPLYSTATUS status = { 0 };
chronograph tc;
int ok = 0,
w = 0,
err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_RESET_BULK, 0, 0
, (unsigned char*)&ok, sizeof(ok)
, 1000);
tc.reset();
while ((err = get_peer_status(&status)) == 0 && ok == 0)
{
if (status.in_status == BULK_STATUS_IDLE)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (tc.elapse_ms() > timeout)
{
err = ETIMEDOUT;
break;
}
}
return err ? err : ok;
}
int async_usb_host::reset_io_buffer_size(unsigned short size)
{
libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT
, USB_REQ_EP0_SET_BULK_BUFFER, 0, size
, nullptr, 0
, 1000);
{
buf_coef_ = size;
return 0;
}
return EFAULT;
}
int async_usb_host::get_io_buffer_size(void)
{
return buf_coef_;
}
int async_usb_host::set_gadget_encrypting_method(uint32_t cmd_enc, uint32_t payload_enc, uint8_t enc_data)
{
dyn_mem_ptr ptr(dyn_mem::memory(sizeof(PACK_BASE)));
LPPACK_BASE pack = (LPPACK_BASE)ptr->ptr();
int err = 0;
pack->size = sizeof(*pack);
pack->enc_cmd = cmd_enc;
pack->encrypt = payload_enc;
pack->enc_data = enc_data;
err = libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR, USB_REQ_EP0_SET_ENCRYPT, 0, 0
, (unsigned char*)pack, sizeof(*pack)
, 1000);
ptr->release();
return err;
}
int async_usb_host::send_heart_beat(uint32_t pack_id)
{
dyn_mem_ptr data(async_usb_host::base_packet(PACK_CMD_HEART_BEAT, pack_id, head_enc_type_));
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::get_settings(uint32_t pack_id)
{
dyn_mem_ptr data(async_usb_host::base_packet(PACK_CMD_SETTING_GET, pack_id, head_enc_type_));
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::get_setting_val(uint32_t pack_id, const char* name)
{
dyn_mem_ptr data(dyn_mem::memory(sizeof(PACK_BASE) + strlen(name) + 1)), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
BASE_PACKET_REPLY(*pack, PACK_CMD_SETTING_GET_CUR, pack_id, 0);
pack->payload_len = strlen(name) + 1;
strcpy(pack->payload, name);
data->set_len(sizeof(PACK_BASE) + strlen(name) + 1);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::set_setting(uint32_t pack_id, const char* name, int type, void* val, size_t size, size_t size0)
{
int base = sizeof(PACK_BASE),
datal = sizeof(CFGVAL) + strlen(name) + 1 + size;
dyn_mem_ptr data(dyn_mem::memory(base + datal)), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPCFGVAL param = (LPCFGVAL)pack->payload;
BASE_PACKET_REPLY(*pack, PACK_CMD_SETTING_SET, pack_id, 0);
pack->payload_len = datal;
param->type = type;
param->name_off = 0;
param->max_size = size0;
param->val_size = size;
param->val_off = strlen(name) + 1;
strcpy(param->data, name);
memcpy(param->data + param->val_off, val, size);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::scan_start(uint32_t pack_id)
{
dyn_mem_ptr data(async_usb_host::base_packet(PACK_CMD_SCAN_START, pack_id, head_enc_type_));
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::scan_stop(uint32_t pack_id)
{
dyn_mem_ptr data(async_usb_host::base_packet(PACK_CMD_SCAN_STOP, pack_id, head_enc_type_));
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::file_send(uint32_t pack_id, const char* remote_path, uint64_t size, uint64_t off)
{
int base = sizeof(PACK_BASE),
datal = sizeof(TXFILE) + strlen(remote_path) + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPTXFILE ptxf = (LPTXFILE)pack->payload;
BASE_PACKET_REPLY(*pack, PACK_CMD_FILE_WRITE_REQ, pack_id, 0);
pack->payload_len = datal;
ptxf->offset = off;
ptxf->size = size;
strcpy(ptxf->path, remote_path);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::file_get(uint32_t pack_id, const char* remote_path, uint64_t off)
{
int base = sizeof(PACK_BASE),
datal = sizeof(TXFILE) + strlen(remote_path) + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPTXFILE ptxf = (LPTXFILE)pack->payload;
BASE_PACKET_REPLY(*pack, PACK_CMD_FILE_READ_REQ, pack_id, 0);
pack->payload_len = datal;
ptxf->offset = off;
ptxf->size = 0;
strcpy(ptxf->path, remote_path);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::file_move(uint32_t pack_id, const char* from_path, const char* to_path)
{
int base = sizeof(PACK_BASE),
datal = strlen(from_path) + 1 + strlen(to_path) + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
BASE_PACKET_REPLY(*pack, PACK_CMD_FILE_MOVE, pack_id, 0);
pack->payload_len = datal;
strcpy(pack->payload, from_path);
strcpy(pack->payload + strlen(from_path) + 1, to_path);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::file_remove(uint32_t pack_id, const char* file)
{
int base = sizeof(PACK_BASE),
datal = strlen(file) + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
BASE_PACKET_REPLY(*pack, PACK_CMD_FILE_REMOVE, pack_id, 0);
pack->payload_len = datal;
strcpy(pack->payload, file);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::program_start(uint32_t pack_id, const char* pe_path, const char* param)
{
int base = sizeof(PACK_BASE),
datal = strlen(pe_path) + 1 + strlen(param ? param : "") + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
if (!param)
param = "";
BASE_PACKET_REPLY(*pack, PACK_CMD_PROCESS_START, pack_id, 0);
pack->payload_len = datal;
strcpy(pack->payload, pe_path);
strcpy(pack->payload + strlen(param) + 1, param);
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::program_stop(uint32_t pack_id, uint64_t pid)
{
std::string id(std::to_string(pid));
int base = sizeof(PACK_BASE),
datal = id.length() + 1;
dyn_mem_ptr data = dyn_mem::memory(base + datal), enc = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
BASE_PACKET_REPLY(*pack, PACK_CMD_PROCESS_STOP, pack_id, 0);
pack->payload_len = datal;
strcpy(pack->payload, id.c_str());
data->set_len(base + datal);
enc = packet_encrypt(data, head_enc_type_, payload_enc_type_, enc_data_);
if (enc)
{
data->release();
data = enc;
}
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::program_reboot(uint32_t pack_id)
{
dyn_mem_ptr data(async_usb_host::base_packet(PACK_CMD_PROCESS_REBOOT, pack_id, head_enc_type_));
post_2_write_bulk_thread(data);
data->release();
return 0;
}
int async_usb_host::cancel_write(void)
{
data_source_ptr data = nullptr;
cancel_write_ = true;
while (out_que_.take(data))
data->release();
while (writing_)
std::this_thread::sleep_for(std::chrono::milliseconds(10));
cancel_write_ = false;
return 0;
}
int async_usb_host::raw_control(uint8_t type, uint8_t req, uint16_t ind, uint16_t val, uint16_t len, void* data)
{
return libusb_control_transfer(usb_handle_, type
, req, val, ind
, (unsigned char*)data, len
, 1000);
}
int async_usb_host::send_bulk_raw_data(dyn_mem_ptr data)
{
post_2_write_bulk_thread(data);
return 0;
}

View File

@ -0,0 +1,109 @@
// async_usb_host
//
// created on 2023-03-24
//
#pragma once
#include <base/data.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <libusb-1.0/libusb.h>
#include <base/encrypt.h>
typedef struct _usb_ep
{
uint8_t iconf;
uint8_t iface;
uint8_t type;
uint8_t port;
uint8_t claimed;
uint16_t max_packet;
bool operator<(const struct _usb_ep& r)
{
return iface < r.iface;
}
}USBEP;
class async_usb_host : public refer
{
std::function<FUNCTION_PROTO_COMMAND_HANDLE> handler_;
volatile bool run_;
volatile bool writing_;
volatile bool cancel_write_;
volatile int buf_coef_;
libusb_device_handle* usb_handle_;
libusb_device* usb_dev_;
USBEP bulk_in_;
USBEP bulk_out_;
safe_fifo<dyn_mem_ptr> in_que_;
safe_fifo<data_source_ptr> out_que_;
std::unique_ptr<std::thread> thread_w_;
std::unique_ptr<std::thread> thread_r_;
std::unique_ptr<std::thread> thread_p_;
uint32_t head_enc_type_;
uint32_t payload_enc_type_;
uint8_t enc_data_;
void thread_read_bulk(void);
void thread_write_bulk(void);
void thread_pump_task(void);
void create_worker_threads(void);
void stop_worker_threads(void);
int bulk_write_buf(uint8_t* buf, int* len); // return error code
int inner_write_bulk(data_source_ptr data, int* err);
void post_2_write_bulk_thread(data_source_ptr data);
dyn_mem_ptr handle_data_in(dyn_mem_ptr& data, uint32_t* used, packet_data_base_ptr* more);
public:
async_usb_host(std::function<FUNCTION_PROTO_COMMAND_HANDLE> cmd_handler = std::function<FUNCTION_PROTO_COMMAND_HANDLE>());
protected:
virtual ~async_usb_host();
public:
static int enum_usb_endpoints(libusb_device* dev, std::vector<USBEP>& eps);
static dyn_mem_ptr base_packet(int cmd, uint32_t id, uint32_t encrypt = ENCRYPT_CMD_NONE);
public:
int start(libusb_device* dev);
int stop(void);
uint32_t& encrypt_type_packet_head(void);
uint32_t& encrypt_type_payload(void);
uint8_t& encrypt_data(void);
public:
int get_peer_protocol_version(uint16_t* ver);
int get_peer_status(LPEP0REPLYSTATUS status);
int restart_peer_bulk(uint32_t timeout = 1000/*ms*/);
int reset_io_buffer_size(unsigned short size);
int get_io_buffer_size(void);
int set_gadget_encrypting_method(uint32_t cmd_enc = ENCRYPT_CMD_NONE, uint32_t payload_enc = ENCRYPT_NONE, uint8_t enc_data = 0);
int send_heart_beat(uint32_t pack_id);
int get_settings(uint32_t pack_id);
int get_setting_val(uint32_t pack_id, const char* name);
int set_setting(uint32_t pack_id, const char* name, int type, void* val, size_t size/*value size*/, size_t size0/*max size*/);
int scan_start(uint32_t pack_id);
int scan_stop(uint32_t pack_id);
int file_send(uint32_t pack_id, const char* remote_path, uint64_t size, uint64_t off = 0);
int file_get(uint32_t pack_id, const char* remote_path, uint64_t off = 0);
int file_move(uint32_t pack_id, const char* from_path, const char* to_path);
int file_remove(uint32_t pack_id, const char* file);
int program_start(uint32_t pack_id, const char* pe_path, const char* param);
int program_stop(uint32_t pack_id, uint64_t pid);
int program_reboot(uint32_t pack_id);
int cancel_write(void);
int raw_control(uint8_t type, uint8_t req, uint16_t ind, uint16_t val, uint16_t len, void* data);
int send_bulk_raw_data(dyn_mem_ptr data);
};

View File

@ -0,0 +1,840 @@
#include "scanner_handler.h"
#include "async_usb_host.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmd_result
MUTEX cmd_result::lock_;
uint32_t cmd_result::pack_id_ = 1;
cmd_result::cmd_result(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id)
: wait_(new platform_event("wait_reply")), id_(id == 0 ? cmd_result::gen_pack_id() : id)
, call_(call), clean_(clean), roger_(roger), param_(param), err_(0), to_(1000), over_(false)
{
}
cmd_result::~cmd_result()
{
wait_->release();
}
uint32_t cmd_result::gen_pack_id(void)
{
SIMPLE_LOCK(cmd_result::lock_);
return cmd_result::pack_id_++;
}
uint32_t cmd_result::get_id(void)
{
return id_;
}
uint32_t cmd_result::set_timeout(uint32_t timeout)
{
uint32_t prev = to_;
to_ = timeout;
return prev;
}
void* cmd_result::get_param(void)
{
return param_;
}
void* cmd_result::set_param(void* param)
{
void* r = param_;
param_ = param;
return r;
}
bool cmd_result::wait(void)
{
return wait_->wait(to_);
}
void cmd_result::trigger(void)
{
over_ = true;
wait_->trigger();
}
bool cmd_result::is_over(void)
{
return over_;
}
int cmd_result::get_error_code(void)
{
return err_;
}
void cmd_result::set_error_code(int err)
{
err_ = err;
}
int cmd_result::call(void)
{
int ret = call_(this);
if (ret == 0)
{
if (wait())
{
ret = err_;
}
else
{
ret = ETIMEDOUT;
}
}
return ret;
}
dyn_mem_ptr cmd_result::roger(dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more)
{
SIMPLE_LOCK(locker_);
dyn_mem_ptr ret = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
err_ = pack->data;
ret = roger_(data, used, more, this);
// trigger();
return ret;
}
int cmd_result::clean(void)
{
SIMPLE_LOCK(locker_);
over_ = true;
return clean_(this);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// though all command transferred by BULK are asychronous in transffer level,
// make BLOCKED in this layer
#define WAIT_COMMAND(call, clean, roger, param) \
cmd_result * r = gen_reply(call, clean, roger, param); \
int ret = r->call(); \
r->clean(); \
r->release(); \
return ret;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// scanner_handler
scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_NOT_OPEN)
, img_receiver_(std::function<data_holder_ptr(LPPACKIMAGE, uint64_t)>())
, status_notify_(std::function<void(uint32_t)>())
{
auto on_reply = [&](dyn_mem_ptr reply, uint32_t* used, packet_data_base_ptr* more) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)reply->ptr();
cmd_result* cmd = take_reply(pack->pack_id);
dyn_mem_ptr ret = nullptr;
*used = reply->get_rest();
*more = nullptr;
if (cmd)
{
ret = cmd->roger(reply, used, more);
if (cmd->is_over())
cmd->release();
else if (status_ != SCANNER_STATUS_RESET_BULK)
{
SIMPLE_LOCK(lock_reply_);
reply_.push_back(cmd);
}
}
else if (status_ == SCANNER_STATUS_RESET_BULK)
{
if (pack->size == sizeof(PACK_BASE) &&
pack->cmd == PACK_CMD_SYNC_ROGER &&
pack->payload_len == 0)
status_ = SCANNER_STATUS_READY;
}
else if (pack->size == sizeof(PACK_BASE))
{
if (pack->cmd == PACK_CMD_SCAN_IMG_ROGER)
{
uint32_t off = sizeof(PACK_BASE) + sizeof(PACKIMAGE);
if (*used < off)
{
*used = 0;
}
else
{
LPPACKIMAGE pimg = (LPPACKIMAGE)pack->payload;
data_holder_ptr receiver = nullptr;
if(img_receiver_)
receiver = img_receiver_(pimg, pimg->info_size + pimg->data_size);
if (!receiver)
{
// usb_->cancel_command(pack->cmd, pack->pack_id);
receiver = dynamic_cast<data_holder_ptr>(new empty_holer(pimg->info_size + pimg->data_size));
}
*used = off;
*more = dynamic_cast<packet_data_base_ptr>(receiver);
}
}
else if (pack->cmd == PACK_CMD_SCAN_PAPER_ROGER)
{
if (img_receiver_)
{
data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_PAPER_CNT, pack->data);
if (receiver)
receiver->release();
}
*used = sizeof(PACK_BASE);
}
else if (pack->cmd == PACK_CMD_SCAN_FINISHED_ROGER)
{
if (img_receiver_)
{
data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_FINISHED, pack->data);
if (receiver)
receiver->release();
}
*used = sizeof(PACK_BASE);
status_ = pack->data;
}
else if (pack->cmd == PACK_CMD_STATUS_ROGER)
{
*used = sizeof(PACK_BASE);
status_ = pack->data;
if (status_notify_)
status_notify_(status_);
}
else if (pack->cmd == PACK_CMD_FILE_WRITE_REQ_ROGER)
{
*used = sizeof(PACK_BASE);
utils::to_log(LOG_LEVEL_DEBUG, "Send file finished with error: %d\r\n", pack->data);
}
else
{
// unknown packet ...
uint8_t* ptr = reply->ptr();
utils::to_log(LOG_LEVEL_DEBUG, "Unhandled packet: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X ...\r\n"
, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]
, ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
}
}
else
{
// unknown packet ...
uint8_t* ptr = reply->ptr();
utils::to_log(LOG_LEVEL_DEBUG, "Unknown packet received: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X ...\r\n"
, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]
, ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
}
return ret;
};
usb_ = new async_usb_host(on_reply);
}
scanner_handler::~scanner_handler()
{
usb_->stop();
for (auto& v : reply_)
v->release();
usb_->release();
}
cmd_result* scanner_handler::gen_reply(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id)
{
cmd_result* reply = new cmd_result(call, clean, roger, param, id);
{
SIMPLE_LOCK(lock_reply_);
reply_.push_back(reply);
}
reply->add_ref(); // for reply_ queue storing
return reply;
}
cmd_result* scanner_handler::take_reply(uint32_t id)
{
cmd_result* reply = nullptr;
SIMPLE_LOCK(lock_reply_);
for (size_t i = 0; i < reply_.size(); ++i)
{
if (reply_[i]->get_id() == id)
{
reply = reply_[i];
reply_.erase(reply_.begin() + i);
break;
}
}
return reply;
}
int scanner_handler::wait_result(cmd_result* reply)
{
if (reply->wait())
{
return reply->get_error_code();
}
else
{
cmd_result* q = take_reply(reply->get_id());
if (q)
{
q->release();
}
else
{
// take out by reply just now ? try again ...
reply->set_timeout(500);
if (reply->wait())
return reply->get_error_code();
}
return ETIMEDOUT;
}
}
int scanner_handler::get_protocol_version(uint16_t* ver)
{
if (!is_scanner_available())
return ENODEV;
return usb_->get_peer_protocol_version(ver);
}
int scanner_handler::get_scanner_status(LPEP0REPLYSTATUS status)
{
if (!is_scanner_available())
return ENODEV;
return usb_->get_peer_status(status);
}
int scanner_handler::restart_peer_bulk(uint32_t timeout)
{
if (!is_scanner_available())
return ENODEV;
return usb_->restart_peer_bulk(timeout);
}
int scanner_handler::set_io_buffer_size(unsigned short size)
{
if (!is_scanner_available())
return ENODEV;
return usb_->reset_io_buffer_size(size);
}
int scanner_handler::get_io_buffer_size(void)
{
if (!is_scanner_available())
return 1;
return usb_->get_io_buffer_size();
}
int scanner_handler::option_get_all(std::string& json_opts)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->get_settings(cmd->get_id());
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
std::string *ret = (std::string*)cmd->get_param();
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
if (data->get_rest() < sizeof(PACK_BASE) + pack->payload_len)
*used = 0;
else
{
if(!cmd->is_over())
*(std::string*)cmd->get_param() = std::string(pack->payload, pack->payload_len);
*used = sizeof(*pack) + pack->payload_len;
cmd->trigger();
}
*more = nullptr;
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, &json_opts);
}
int scanner_handler::option_value_get(const char* name, void* buf, uint32_t size)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->get_setting_val(cmd->get_id(), name);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPCFGVAL cfg = (LPCFGVAL)pack->payload;
if (data->get_rest() < sizeof(PACK_BASE) + pack->payload_len)
*used = 0;
else
{
if (!cmd->is_over())
memcpy(cmd->get_param(), cfg->data + cfg->val_off, cfg->val_size);
*used = sizeof(*pack) + pack->payload_len;
cmd->trigger();
}
*more = nullptr;
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, buf);
}
int scanner_handler::option_value_set(const char* name, uint32_t type, void* buf, uint32_t size, uint32_t val_size, uint8_t* after)
{
struct
{
void* buf;
uint8_t* after;
}param;
auto call = [&](cmd_result* cmd) -> int
{
memcpy(&param, cmd->get_param(), sizeof(param));
return usb_->set_setting(cmd->get_id(), name, type, param.buf, val_size, size);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
struct
{
void* buf;
uint8_t* after;
}*result = nullptr;
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPCFGVAL cfg = (LPCFGVAL)pack->payload;
if (data->get_rest() < sizeof(PACK_BASE) + pack->payload_len)
*used = 0;
else
{
if (!cmd->is_over())
{
*(void**)&result = cmd->get_param();
memcpy(result->buf, cfg->data + cfg->val_off, cfg->val_size);
*result->after = cfg->after_do;
}
*used = sizeof(*pack) + pack->payload_len;
cmd->trigger();
}
*more = nullptr;
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
param.buf = buf;
param.after = after;
WAIT_COMMAND(call, clean, roger, &param);
}
int scanner_handler::status_get(void)
{
return status_;
}
void scanner_handler::set_image_receiver(std::function<data_holder_ptr(LPPACKIMAGE, uint64_t)> img)
{
img_receiver_ = img;
}
void scanner_handler::set_status_notifyer(std::function<void(uint32_t)> stntf)
{
status_notify_ = stntf;
}
int scanner_handler::scan_start(void)
{
auto call = [&](cmd_result* cmd) -> int
{
cmd->set_timeout(4000);
return usb_->scan_start(cmd->get_id());
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
*used = sizeof(PACK_BASE);
*more = nullptr;
status_ = SCANNER_STATUS_START_SCANNING;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, nullptr);
}
int scanner_handler::scan_stop(void)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->scan_stop(cmd->get_id());
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
*used = sizeof(PACK_BASE);
*more = nullptr;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, nullptr);
}
int scanner_handler::file_transfer(const char* local_path, const char* remote_path, bool to_device, PROGRESS_NOTIFYER progress, uint64_t local_off, uint64_t remote_off)
{
if (!is_scanner_available())
return ENODEV;
if (to_device)
{
uint64_t size = 0;
FILE *src = fopen(local_path, "rb");
if (!src)
return errno;
FSEEK(src, 0, SEEK_END);
size = FTELL(src);
FSEEK(src, local_off, SEEK_SET);
if (size <= local_off)
{
fclose(src);
return EOVERFLOW;
}
size -= local_off;
utils::to_log(LOG_LEVEL_DEBUG, "Send '%s' to '%s' ...\r\n", local_path, remote_path);
auto call = [&](cmd_result* cmd) -> int
{
return usb_->file_send(cmd->get_id(), remote_path, size, remote_off);
};
auto clean = [&](cmd_result* cmd) -> int
{
FILE* src = (FILE*)cmd->get_param();
if (src)
fclose(src);
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
dyn_mem_ptr ret = nullptr;
*used = sizeof(PACK_BASE);
*more = nullptr;
utils::to_log(LOG_LEVEL_DEBUG, "Send file - Roger of send file result: %d\r\n", pack->data);
if (pack->data == 0)
{
if (cmd->is_over())
{
reset_message_que();
}
else
{
file_reader_ptr freader = new file_reader();
int err = freader->attach((FILE*)cmd->set_param(nullptr));
freader->set_progress_notify(progress);
if (err)
{
// cancel tx-file ...
cmd->set_error_code(err);
freader->release();
reset_message_que();
utils::to_log(LOG_LEVEL_DEBUG, "Send file - Attach to source file failed: %d\r\n", err);
}
else
{
*more = dynamic_cast<packet_data_base_ptr>(freader);
status_ = SCANNER_STATUS_BUSY;
utils::to_log(LOG_LEVEL_DEBUG, "Send file - beginning ...\r\n");
}
}
}
cmd->trigger();
return ret;
};
WAIT_COMMAND(call, clean, roger, src);
}
else
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->file_get(cmd->get_id(), remote_path, remote_off);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
LPTXFILE pfi = (LPTXFILE)pack->payload;
*used = sizeof(PACK_BASE) + pack->payload_len;
*more = nullptr;
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - Roger result: %d\r\n", pack->data);
if (pack->data == 0)
{
if (cmd->is_over())
{
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - timeout, user cancelled\r\n");
reset_message_que();
}
else
{
file_saver* fsaver = new file_saver();
int err = fsaver->open(local_path, pfi->size);
fsaver->set_progress_notify(progress);
if (err)
{
// cancel tx-file ...
cmd->set_error_code(err);
fsaver->release();
reset_message_que();
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - open local file failed: %d\r\n", err);
}
else
{
*more = dynamic_cast<packet_data_base_ptr>(fsaver);
status_ = SCANNER_STATUS_BUSY;
utils::to_log(LOG_LEVEL_DEBUG, "Receive file - beginning ...\r\n");
}
}
}
cmd->trigger();
return nullptr;
};
utils::to_log(LOG_LEVEL_DEBUG, "Receive '%s' to '%s' ...\r\n", remote_path, local_path);
WAIT_COMMAND(call, clean, roger, (void*)local_path);
}
}
int scanner_handler::file_move(const char* rfrom, const char* rto)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->file_move(cmd->get_id(), rfrom, rto);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
*used = sizeof(PACK_BASE);
*more = nullptr;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, nullptr);
}
int scanner_handler::file_delete(const char* remote)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->file_remove(cmd->get_id(), remote);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
*used = sizeof(PACK_BASE);
*more = nullptr;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, nullptr);
}
int scanner_handler::program_start(const char* remote_pe, const char* param, uint64_t* pid)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->program_start(cmd->get_id(), remote_pe, param);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
if (pack->data == 0 && !cmd->is_over())
*(uint64_t*)cmd->get_param() = *(uint64_t*)pack->payload;
*used = sizeof(PACK_BASE) + pack->payload_len;
*more = nullptr;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, pid);
}
int scanner_handler::program_stop(uint64_t pid)
{
auto call = [&](cmd_result* cmd) -> int
{
return usb_->program_stop(cmd->get_id(), pid);
};
auto clean = [&](cmd_result* cmd) -> int
{
return 0;
};
auto roger = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more, cmd_result* cmd) ->dyn_mem_ptr
{
*used = sizeof(PACK_BASE);
*more = nullptr;
cmd->trigger();
return nullptr;
};
if (!is_scanner_available())
return ENODEV;
WAIT_COMMAND(call, clean, roger, nullptr);
}
int scanner_handler::open_usb_scanner(libusb_device* dev)
{
int ret = close();
if (ret == 0)
{
ret = usb_->start(dev);
if(ret == 0)
status_ = SCANNER_STATUS_READY;
//usb_->set_gadget_encrypting_method(ENCRYPT_CMD_XOR_PID);
}
return ret;
}
int scanner_handler::close(void)
{
int ret = usb_->stop();
{
SIMPLE_LOCK(lock_reply_);
for (auto& v : reply_)
v->release();
reply_.clear();
}
if(ret == 0)
status_ = SCANNER_STATUS_NOT_OPEN;
return ret;
}
int scanner_handler::reset_message_que(void)
{
int err = usb_->cancel_write();
status_ = SCANNER_STATUS_RESET_BULK;
utils::to_log(LOG_LEVEL_DEBUG, "reset_message_que - send reset command ...\r\n");
err = usb_->restart_peer_bulk();
utils::to_log(LOG_LEVEL_DEBUG, "reset_message_que - send reset command = %d\r\n", err);
if (err == 0)
{
EP0REPLYSTATUS s;
dyn_mem_ptr raw(dyn_mem::memory(sizeof(PACK_BASE)));
LPPACK_BASE pack = (LPPACK_BASE)raw->ptr();
BASE_PACKET_REPLY(*pack, PACK_CMD_SYNC, 0, 0);
raw->set_len(sizeof(PACK_BASE));
utils::to_log(LOG_LEVEL_DEBUG, "reset_message_que - wait 100ms ...\r\n");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
utils::to_log(LOG_LEVEL_DEBUG, "reset_message_que - send SYNC packet ...\r\n");
usb_->send_bulk_raw_data(raw);
raw->release();
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (status_ == SCANNER_STATUS_RESET_BULK)
err = EFAULT;
utils::to_log(LOG_LEVEL_DEBUG, "reset_message_que - final status = %d\r\n", status_);
}
return err;
}
bool scanner_handler::is_scanner_available(void)
{
return status_ != SCANNER_STATUS_NOT_OPEN
&& status_ != SCANNER_STATUS_LOST_CONNECT
&& status_ != SCANNER_STATUS_RESET_BULK;
}

View File

@ -0,0 +1,133 @@
// scanner business handler
//
// created on 2023-03-27
//
#pragma once
#include <base/utils.h>
#include <base/data.h>
#include <base/packet.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <map>
#define IMG_RECEIVER_FINISHED ((LPPACKIMAGE)NULL)
#define IMG_RECEIVER_PAPER_CNT ((LPPACKIMAGE)1)
class async_usb_host;
struct libusb_device;
class cmd_result : public refer
{
std::function<int(cmd_result*)> call_;
std::function<int(cmd_result*)> clean_;
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger_;
MUTEX locker_;
uint32_t id_;
platform_event *wait_;
void* param_;
int err_;
uint32_t to_;
bool over_;
static MUTEX lock_;
static uint32_t pack_id_;
static uint32_t gen_pack_id(void);
public:
cmd_result(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id = 0);
protected:
~cmd_result();
public:
uint32_t get_id(void);
uint32_t set_timeout(uint32_t timeout = 1000/*WAIT_INFINITE*/); // return previous
void* get_param(void);
void* set_param(void* param); // return previous
bool wait(void);
void trigger(void);
bool is_over(void);
int get_error_code(void);
void set_error_code(int err);
public:
int call(void);
dyn_mem_ptr roger(dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* more);
int clean(void);
};
class scanner_handler : public refer
{
MUTEX lock_reply_;
std::vector<cmd_result*> reply_;
async_usb_host* usb_;
volatile uint32_t status_;
std::function<void(uint32_t)> status_notify_;
std::function<data_holder_ptr(LPPACKIMAGE, uint64_t)> img_receiver_;
cmd_result* gen_reply(std::function<int(cmd_result*)> call,
std::function<int(cmd_result*)> clean,
std::function<dyn_mem_ptr(dyn_mem_ptr, uint32_t*, packet_data_base_ptr*, cmd_result*)> roger,
void* param, uint32_t id = 0);
cmd_result* take_reply(uint32_t id);
int wait_result(cmd_result* reply);
typedef struct _set_opt_result
{
uint32_t err;
uint8_t after_do;
char val[0];
}SORET, *LPSORET;
public:
scanner_handler(void);
protected:
~scanner_handler();
// I/O ...
public:
// following methods transferred by EP0
int get_protocol_version(uint16_t* ver);
int get_scanner_status(LPEP0REPLYSTATUS status);
int restart_peer_bulk(uint32_t timeout = 1000/*ms*/);
int set_io_buffer_size(unsigned short size);
int get_io_buffer_size(void);
// following methods transferred by Bulk, blocked ...
int option_get_all(std::string& json_opts);
int option_value_get(const char* name, void* buf, uint32_t size/*buffer size of 'buf'*/);
int option_value_set(const char* name, uint32_t type, void* buf, uint32_t size/*buffer size of 'buf'*/, uint32_t val_size, uint8_t* after);
int status_get(void);
void set_image_receiver(std::function<data_holder_ptr(LPPACKIMAGE/*NULL when scanning stopped*/, uint64_t/*size in image, error in stopped*/)> img);
void set_status_notifyer(std::function<void(uint32_t)> stntf);
int scan_start(void);
int scan_stop(void);
int file_transfer(const char* local_path, const char* remote_path, bool to_device
, PROGRESS_NOTIFYER progress = PROGRESS_NOTIFYER()
, uint64_t local_off = 0, uint64_t remote_off = 0);
int file_move(const char* rfrom, const char* rto);
int file_delete(const char* remote);
int program_start(const char* remote_pe, const char* param = nullptr, uint64_t* pid = nullptr);
int program_stop(uint64_t pid);
// methods ...
public:
int open_usb_scanner(libusb_device* dev);
int close(void);
int reset_message_que(void);
bool is_scanner_available(void);
};

View File

@ -1,140 +1,32 @@
#include "scanner_manager.h"
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
#include <lang/app_language.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include "../../../sdk/include/huagao/brand.h"
#include <huagao/brand.h>
#include "hg_scanner.h"
#include "user-opt/user.h"
#include "user-opt/offline_opt.h"
#include <sane_opt_json/device_opt.h>
#include <imgprc/imgprc_mgr.h>
#if !defined(WIN32) && !defined(_WIN64)
#endif
// kinds of scanners ...
#define SCAN_PTR(ptr) ((hg_scanner*)ptr)
#include "hg_scanner_200.h"
#include "hg_scanner_239.h"
#include "hg_scanner_300.h"
#include "hg_scanner_302.h"
/// <summary>
/// supporting devices :
///
#define GET_LANG(str,b) from_default_language(str,b)
static struct
static struct _scanner_device
{
uint16_t vid; // vendor ID
uint16_t pid; // product ID
std::string name; // product name - type
std::string family; // product model - family. In the TWAIN protocol, grouping is based on this value
std::string rsc; // USB resource, version-addr. e.g. "USB2.0-1"
hg_scanner* (* create_scanner)(const char*/*name*/, const char*/*model*/, usb_io*, scanner_handle*);
}
g_supporting_devices[] = {
#ifdef OEM_LISICHENG
{0x31c9, 0x8200, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "", &hg_scanner_mgr::create_scanner_g300}
, {0x31c9, 0x8420, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "", &hg_scanner_mgr::create_scanner_g300}
, {0x31c9, 0x8429, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "", &hg_scanner_mgr::create_scanner_empty}
, {0x31c9, 0x8520, PRODUCT_NAME_LSC_G52, PRODUCT_FAMILY_LSC_G52, "", &hg_scanner_mgr::create_scanner_g400}
, {0x31c9, 0x8529, PRODUCT_NAME_LSC_G52, PRODUCT_FAMILY_LSC_G52, "", &hg_scanner_mgr::create_scanner_g439}
, {0x31c9, 0x8620, PRODUCT_NAME_LSC_G62, PRODUCT_FAMILY_LSC_G62, "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, 0x8629, PRODUCT_NAME_LSC_G62, PRODUCT_FAMILY_LSC_G62, "", &hg_scanner_mgr::create_scanner_g239}
, {0x31c9, 0x8730, PRODUCT_NAME_LSC_G73, PRODUCT_FAMILY_LSC_G73, "", &hg_scanner_mgr::create_scanner_g100}
, {0x31c9, 0x8739, PRODUCT_NAME_LSC_G73, PRODUCT_FAMILY_LSC_G73, "", &hg_scanner_mgr::create_scanner_g239}
#elif defined(OEM_HANWANG)
{0x2903, 0x1000, PRODUCT_NAME_HW_G1000, PRODUCT_FAMILY_HW_G1000, "",& hg_scanner_mgr::create_scanner_g300} // "HW-1060A"
, {0x2903, 0x1002, PRODUCT_NAME_HW_G1002, PRODUCT_FAMILY_HW_G1002, "", &hg_scanner_mgr::create_scanner_g302} // "HW-1060A"
, {0x2903, 0x7000, PRODUCT_NAME_HW_G7000, PRODUCT_FAMILY_HW_G7000, "", &hg_scanner_mgr::create_scanner_g400} // "HW-74x0WA"
, {0x2903, 0x7002, PRODUCT_NAME_HW_G7002, PRODUCT_FAMILY_HW_G7002, "", &hg_scanner_mgr::create_scanner_g402} // "HW-7002"
, {0x2903, 0x7039, PRODUCT_NAME_HW_G7039, PRODUCT_FAMILY_HW_G7039, "", &hg_scanner_mgr::create_scanner_g439} // "HW-7039F"
, {0x2903, 0x8000, PRODUCT_NAME_HW_G8000, PRODUCT_FAMILY_HW_G8000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-8090F"
, {0x2903, 0x9000, PRODUCT_NAME_HW_G9000, PRODUCT_FAMILY_HW_G9000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-9110E"
#elif defined(OEM_CANGTIAN)
{0x3072, 0x0303, PRODUCT_NAME_CT_6005, PRODUCT_FAMILY_CT_6005, "", &hg_scanner_mgr::create_scanner_g300}
, {0x3072, 0x0403, PRODUCT_NAME_CT_138, PRODUCT_FAMILY_CT_138, "", &hg_scanner_mgr::create_scanner_g439}
, {0x3072, 0x0138, PRODUCT_NAME_CT_138, PRODUCT_FAMILY_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x0238, PRODUCT_NAME_CT_138, PRODUCT_FAMILY_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0138, PRODUCT_NAME_CT_138, PRODUCT_FAMILY_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0238, PRODUCT_NAME_CT_238, PRODUCT_FAMILY_CT_238, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x6005, PRODUCT_NAME_CT_6005, PRODUCT_FAMILY_CT_6005, "", &hg_scanner_mgr::create_scanner_g300}
, {0x3308, 0x6006, PRODUCT_NAME_CT_6006, PRODUCT_FAMILY_CT_6006, "", &hg_scanner_mgr::create_scanner_g239}
#elif defined(OEM_ZHONGJING)
{0X05DA, 0x9220, PRODUCT_NAME_ZJ_9200, PRODUCT_FAMILY_ZJ_9200, "",& hg_scanner_mgr::create_scanner_g439}
#elif defined(OEM_ZIGUANG)
{0x32ec, 0x0200, PRODUCT_NAME_ZG_200, PRODUCT_FAMILY_ZG_200, "", & hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0210, PRODUCT_NAME_ZG_210, PRODUCT_FAMILY_ZG_210, "", &hg_scanner_mgr::create_scanner_g402}
#elif defined(OEM_NEUTRAL)
{0x3072, 0x100, PRODUCT_NAME_NEU_100, PRODUCT_FAMILY_NEU_100, "",& hg_scanner_mgr::create_scanner_g100}
, {0x3072, 0x139, PRODUCT_NAME_NEU_100, PRODUCT_FAMILY_NEU_100, "",&hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x200, PRODUCT_NAME_NEU_200, PRODUCT_FAMILY_NEU_200, "",&hg_scanner_mgr::create_scanner_g100}
, {0x3072, 0x239, PRODUCT_NAME_NEU_200, PRODUCT_FAMILY_NEU_200, "",&hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x300, PRODUCT_NAME_NEU_300, PRODUCT_FAMILY_NEU_300, "",&hg_scanner_mgr::create_scanner_g300}
, {0x3072, 0x302, PRODUCT_NAME_NEU_300, PRODUCT_FAMILY_NEU_300, "",&hg_scanner_mgr::create_scanner_g302}
, {0x3072, 0x339, PRODUCT_NAME_NEU_300, PRODUCT_FAMILY_NEU_300, "",&hg_scanner_mgr::create_scanner_empty}
, {0x3072, 0x400, PRODUCT_NAME_NEU_400, PRODUCT_FAMILY_NEU_400, "",&hg_scanner_mgr::create_scanner_g400}
, {0x3072, 0x402, PRODUCT_NAME_NEU_400, PRODUCT_FAMILY_NEU_400, "",&hg_scanner_mgr::create_scanner_g402}
, {0x3072, 0x439, PRODUCT_NAME_NEU_400, PRODUCT_FAMILY_NEU_400, "",&hg_scanner_mgr::create_scanner_g439}
, {0x064B, 0x7823, PRODUCT_NAME_NEU_200, PRODUCT_FAMILY_NEU_200, "",& hg_scanner_mgr::create_scanner_g100}
, {0x31c9, 0x8200, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "",& hg_scanner_mgr::create_scanner_g300}
, {0x31c9, 0x8420, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "",& hg_scanner_mgr::create_scanner_g300}
, {0x31c9, 0x8429, PRODUCT_NAME_LSC_G42, PRODUCT_FAMILY_LSC_G42, "",& hg_scanner_mgr::create_scanner_empty}
, {0x31c9, 0x8520, PRODUCT_NAME_LSC_G52, PRODUCT_FAMILY_LSC_G52, "",& hg_scanner_mgr::create_scanner_g400}
, {0x31c9, 0x8529, PRODUCT_NAME_LSC_G52, PRODUCT_FAMILY_LSC_G52, "",& hg_scanner_mgr::create_scanner_g439}
, {0x31c9, 0x8620, PRODUCT_NAME_LSC_G62, PRODUCT_FAMILY_LSC_G62, "",& hg_scanner_mgr::create_scanner_g100}
, {0x31c9, 0x8629, PRODUCT_NAME_LSC_G62, PRODUCT_FAMILY_LSC_G62, "",& hg_scanner_mgr::create_scanner_g239}
, {0x31c9, 0x8730, PRODUCT_NAME_LSC_G73, PRODUCT_FAMILY_LSC_G73, "",& hg_scanner_mgr::create_scanner_g100}
, {0x31c9, 0x8739, PRODUCT_NAME_LSC_G73, PRODUCT_FAMILY_LSC_G73, "", &hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0200, PRODUCT_NAME_ZG_200, PRODUCT_FAMILY_ZG_200, "",& hg_scanner_mgr::create_scanner_g239}
, {0x32ec, 0x0210, PRODUCT_NAME_ZG_210, PRODUCT_FAMILY_ZG_210, "", &hg_scanner_mgr::create_scanner_g402}
, {0X05DA, 0x9220, PRODUCT_NAME_ZJ_9200, PRODUCT_FAMILY_ZJ_9200, "",&hg_scanner_mgr::create_scanner_g439}
, {0x3308, 0x0138, PRODUCT_NAME_CT_138, PRODUCT_FAMILY_CT_138, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3308, 0x0238, PRODUCT_NAME_CT_238, PRODUCT_FAMILY_CT_238, "", &hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x0303, PRODUCT_NAME_CT_6005, PRODUCT_FAMILY_CT_6005, "", &hg_scanner_mgr::create_scanner_g300}
, {0x3308, 0x6005, PRODUCT_NAME_CT_6005, PRODUCT_FAMILY_CT_6005, "", &hg_scanner_mgr::create_scanner_g300}
, {0x3308, 0x6006, PRODUCT_NAME_CT_6006, PRODUCT_FAMILY_CT_6006, "",& hg_scanner_mgr::create_scanner_g239}
#else
{0x3072, 0x100, PRODUCT_NAME_HG_G100, PRODUCT_FAMILY_HG_G100, "",& hg_scanner_mgr::create_scanner_g100}
, {0x3072, 0x139, PRODUCT_NAME_HG_G100, PRODUCT_FAMILY_HG_G100, "",&hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x200, PRODUCT_NAME_HG_G200, PRODUCT_FAMILY_HG_G200, "",&hg_scanner_mgr::create_scanner_g100}
, {0x3072, 0x239, PRODUCT_NAME_HG_G200, PRODUCT_FAMILY_HG_G200, "",&hg_scanner_mgr::create_scanner_g239}
, {0x3072, 0x300, PRODUCT_NAME_HG_G300, PRODUCT_FAMILY_HG_G300, "",&hg_scanner_mgr::create_scanner_g300}
, {0x3072, 0x302, PRODUCT_NAME_HG_G300, PRODUCT_FAMILY_HG_G300, "",&hg_scanner_mgr::create_scanner_g302}
, {0x3072, 0x339, PRODUCT_NAME_HG_G300, PRODUCT_FAMILY_HG_G300, "",&hg_scanner_mgr::create_scanner_empty}
, {0x3072, 0x400, PRODUCT_NAME_HG_G400, PRODUCT_FAMILY_HG_G400, "",&hg_scanner_mgr::create_scanner_g400}
, {0x3072, 0x402, PRODUCT_NAME_HG_G400, PRODUCT_FAMILY_HG_G400, "",&hg_scanner_mgr::create_scanner_g402}
, {0x3072, 0x439, PRODUCT_NAME_HG_G400, PRODUCT_FAMILY_HG_G400, "",& hg_scanner_mgr::create_scanner_g439}
, {0x064B, 0x7823,PRODUCT_NAME_HG_G300, PRODUCT_FAMILY_HG_G300, "",& hg_scanner_mgr::create_scanner_g300}
, {0x064B, 0x7823,PRODUCT_NAME_HG_G200, PRODUCT_FAMILY_HG_G200, "",& hg_scanner_mgr::create_scanner_g100}
, {0x064B, 0x7823,PRODUCT_NAME_HG_G400, PRODUCT_FAMILY_HG_G400, "", &hg_scanner_mgr::create_scanner_g400}
#endif
};
bool islang = false;
//static std::string g_vendor = GET_LANG(COMPANY_NAME, &islang);
#define BRAND_LOGO_SIZE 8 * 1024
#define MOVE_TO_NEXT_STR(str) str += strlen(str) + 1
/// </summary>
int vid;
int pid;
std::string family;
std::string name;
} g_supporting_devices[] = { ALL_FAMILIES };
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// language option ...
@ -250,9 +142,14 @@ hg_scanner_mgr::~hg_scanner_mgr()
std::lock_guard<std::mutex> lock(mutex_dev_);
for (auto& v : online_devices_)
{
if (v.scanner)
{
v.scanner->close();
v.scanner->release();
v.scanner = nullptr;
}
libusb_unref_device(v.dev);
if (v.dev_opts)
v.dev_opts->release();
}
online_devices_.clear();
}
@ -381,76 +278,6 @@ uint32_t hg_scanner_mgr::unique_id(int type)
return -1;
}
hg_scanner* hg_scanner_mgr::create_scanner_empty(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
if (h)
*h = nullptr;
return nullptr;
}
hg_scanner* hg_scanner_mgr::create_scanner_g100(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_200* s = new hg_scanner_200(name, family, 0x100, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g239(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_239* s = new hg_scanner_239(name, family, 0x239, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g300(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_300* s = new hg_scanner_300(name, family, 0x300, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g400(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_300* s = new hg_scanner_300(name, family, 0x400, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g302(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_302* s = new hg_scanner_302(name, family, 0x302, io); // image_process needs PID 402, we should add 302 ...
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g402(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_302* s = new hg_scanner_302(name, family, 0x402, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
hg_scanner* hg_scanner_mgr::create_scanner_g439(const char* name, const char* family, usb_io* io, scanner_handle* h)
{
hg_scanner_239* s = new hg_scanner_239(name, family, 0x439, io);
if (h)
*h = s;
return dynamic_cast<hg_scanner*>(s);
}
void hg_scanner_mgr::usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l
{
hg_scanner_mgr* obj = (hg_scanner_mgr*)user;
@ -463,7 +290,7 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
char model[40],
vendor[40];
SANE_Device_Ex de;
int ev_ui = 0;
int ev_ui = 0, addr = 0;
scanner_handle h = NULL;
unsigned int len = sizeof(de);
std::string name(""), type("");
@ -476,13 +303,13 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
de.family = NULL;
de.vendor = vendor;
de.openned = SANE_FALSE;
addr = libusb_get_device_address(device);
if (ev == USB_EVENT_DEVICE_ARRIVED)
{
int index = -1;
for (int i = 0; i < _countof(g_supporting_devices); ++i)
{
// 064B 澶氬彴璁惧浣跨敤杩欎釜vid锛屾墍浠ュ姞杞芥椂涓嶄細娓呮瑕佹墦寮€鍝竴鍙拌澶囷紝鍙湁閫氳繃澶栭儴杩涜鍔犺浇鏀瑰彉瀹炰<E780B9>?
if (g_supporting_devices[i].vid == vid && g_supporting_devices[i].pid == pid)
{
index = i;
@ -510,20 +337,22 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
size_t i = 0;
for (; i < online_devices_.size(); ++i)
{
if (online_devices_[i].dev == device) // 姝ゅ鍋囧畾鍚屼竴鍙拌澶囬噸鏂拌繛鎺ュ悗锛岃澶囧璞♀€渄evice鈥濅繚鎸佷笉鍙橈紱濡傛灉鍋囪涓嶆垚绔嬶紝浼氬鑷磋澶囬噸杩炴秷鎭笉鑳芥甯告帴鏀讹紝缁戝畾鍒拌璁惧鐨剆canner瀵硅薄寰椾笉鍒伴噴鏀?
if (online_devices_[i].dev == device)
{
online_devices_[i].ind = index;
add = false;
break;
}
}
if (add) // 澶勭悊瀵硅薄鈥渄evice鈥濇敼鍙樼殑鎯呮<E98EAF>?
if (add)
{
i = 0;
for (auto& v : online_devices_)
{
if (v.ind == index &&
(v.scanner && !v.scanner->is_online()))
if (v.scanner && !v.scanner->is_online())
{
add = false;
break;
@ -534,31 +363,30 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
if (add)
{
OLSCANNER ols;
ONLNSCANNER ols;
ols.vid = vid;
ols.pid = pid;
ols.addr = addr;
ols.dev = device;
ols.ind = index;
ols.scanner = NULL;
ols.dev_opts = nullptr;
ols.imgproc = nullptr;
ols.display_name = g_supporting_devices[ols.ind].name;
if (std::find(online_devices_.begin(), online_devices_.end(), ols.ind) != online_devices_.end())
ols.scanner = nullptr;
ols.family = g_supporting_devices[index].family;
ols.display_name = g_supporting_devices[index].name;
if (std::find(online_devices_.begin(), online_devices_.end(), ols.display_name.c_str()) != online_devices_.end())
{
char buf[40];
int sn = 0;
while (std::find(online_devices_.begin(), online_devices_.end(), (ols.display_name + " - " + std::to_string(++sn)).c_str()) != online_devices_.end());
sprintf(buf, " - %u", same_ind_++);
ols.display_name += buf;
ols.display_name += " - " + std::to_string(sn);
}
libusb_ref_device(ols.dev); // ref to the device of queue online_devices_
online_devices_.push_back(ols);
name = ols.display_name;
utils::to_log(LOG_LEVEL_DEBUG, "%s connected.\n", name.c_str());
type = g_supporting_devices[ols.ind].family;
type = g_supporting_devices[index].family;
}
else if (online_devices_[i].scanner && !online_devices_[i].scanner->is_online())
else if (i < online_devices_.size() && online_devices_[i].scanner && !online_devices_[i].scanner->is_online())
{
usb_io* io = NULL;
name = online_devices_[i].display_name;
type = g_supporting_devices[index].family;
if (online_devices_[i].dev)
@ -568,32 +396,29 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
h = online_devices_[i].scanner;
if (pid == 0x300 || pid == 0x400)
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
len = usb_manager::instance()->open(device, &io);
utils::to_log(LOG_LEVEL_WARNING, "[%04x:%04x]%s re-connected.\n", pid, vid, online_devices_[i].display_name.c_str());
//len = usb_manager::instance()->open(device, &io);
utils::to_log(LOG_LEVEL_WARNING, "[%04x:%04x]%s re-connected.\n", vid, pid, online_devices_[i].display_name.c_str());
len = online_devices_[i].scanner->re_connect();
if (len == SCANNER_ERR_OK)
{
online_devices_[i].scanner->reset_io(io);
//online_devices_[i].scanner->reset_io(io);
de.openned = SANE_TRUE;
}
if (io)
io->release();
add = false;
}
}
}
else if (ev == USB_EVENT_DEVICE_LEFT)
{
std::vector<OLSCANNER>::iterator it = std::find(online_devices_.begin(), online_devices_.end(), device);
std::vector<ONLNSCANNER>::iterator it = std::find(online_devices_.begin(), online_devices_.end(), device);
if (it != online_devices_.end())
{
ev_ui = SANE_EVENT_DEVICE_LEFT;
name = it->display_name;
type = g_supporting_devices[it->ind].family;
type = it->family;
h = it->scanner;
utils::to_log(LOG_LEVEL_DEBUG, "%s Dis-connected.\n", name.c_str());
if (it->scanner)
it->scanner->io_disconnected();
else
if (!it->scanner)
{
libusb_unref_device(it->dev); // unref the device of queue online_devices_
online_devices_.erase(it);
@ -608,7 +433,7 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
hg_scanner_mgr::ui_default_callback(h, ev_ui, &de, &len, NULL);
}
}
void hg_scanner_mgr::get_online_devices(std::vector<OLSCANNER>& devs)
void hg_scanner_mgr::get_online_devices(std::vector<ONLNSCANNER>& devs)
{
std::lock_guard<std::mutex> lock(mutex_dev_);
@ -631,181 +456,6 @@ void hg_scanner_mgr::init_debug_config(const char* cfg_file)
}
}
void hg_scanner_mgr::set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url)
{
#ifdef BRAND_DISPLAY_ALL_EXPAND
if (!info || *info == 0)
info = GET_LANG(BRAND_COMMUNICATION_FAIL,&islang);
#endif
if (info && strlen(info))
{
about->appendix[count].key = ptr;
strcpy(ptr, key);
MOVE_TO_NEXT_STR(ptr);
about->appendix[count].content = ptr;
strcpy(ptr, info);
MOVE_TO_NEXT_STR(ptr);
if (url)
{
about->appendix[count++].url = ptr;
strcpy(ptr, url);
MOVE_TO_NEXT_STR(ptr);
}
else
{
about->appendix[count].url = NULL;
count++;
}
}
}
scanner_err hg_scanner_mgr::get_about_info(scanner_handle h, void* data, unsigned* len)
{
hg_scanner* scanner = (hg_scanner*)h;
unsigned bytes = sizeof(SANE_About) + 40;
SANE_About tmp;
size_t append_cnt = 1;
//bytes += sizeof(g_logo);
bytes += strlen(GET_LANG(BRAND_APP_NAME, &islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_VERSION,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_COPYRIGHT,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_COPYRIGHT,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITE_MANUFACTOR,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_URL,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(url_en.c_str(), &islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(url_link_en.c_str(), &islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_TEL,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_COMPANY_TEL,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_ADDRESS,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_COMPANY_ADDRESS,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_TITLE_GPS,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_COMPANY_GPS,&islang)) + 8; append_cnt++;
bytes += strlen(GET_LANG(BRAND_URL_GPS,&islang)) + 8; append_cnt++;
// bytes += 5 * sizeof(tmp.appendix[0]);
#ifndef BRAND_DISPLAY_ALL_EXPAND
if (scanner)
#endif
{
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_SOFTWARE_VERSION, &islang)) + 8;
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_DEVICE_MODEL, &islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_IP,&islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_DEVICE_INITIAL_POWER_ON_TIME, &islang)) + 8; append_cnt++;
bytes += sizeof(tmp.appendix[0]); append_cnt++;
}
if (!data || *len < bytes)
{
*len = bytes;
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
// filling info to flat buffer ...
SANE_About* about = (SANE_About*)data;
std::string info("");
char* ptr = (char*)data + sizeof(SANE_About) + append_cnt * sizeof(about->appendix[0]);
about->title = ptr;
strcpy(ptr, GET_LANG(BRAND_APP_NAME,&islang));
MOVE_TO_NEXT_STR(ptr);
about->version = ptr;
sprintf(ptr, "%d.%d.%d.%d", hg_scanner_mgr::ver_major_, hg_scanner_mgr::ver_minor_, hg_scanner_mgr::ver_build_, hg_scanner_mgr::ver_patch_);
MOVE_TO_NEXT_STR(ptr);
about->copyright = ptr;
std::string s = GET_LANG(BRAND_COPYRIGHT, &islang);
strcpy(ptr, s.c_str());
MOVE_TO_NEXT_STR(ptr);
//about->logo_bytes = sizeof(g_logo);;
//about->logo = ptr;
//memcpy(ptr, g_logo, about->logo_bytes);
ptr += about->logo_bytes + 1;
int count = 0, rolls = 0, ret = SCANNER_ERR_OK;
#ifdef TEST
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_SOFTWARE_VERSION, &islang), BRAND_SOFTWARE_VERSION_TEST, NULL);
#endif
std::string g_vendor = GET_LANG(COMPANY_NAME, &islang);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITE_MANUFACTOR,&islang), g_vendor.c_str(), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_URL,&islang), GET_LANG(url_en.c_str(), &islang), GET_LANG(url_link_en.c_str(), &islang));
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_TEL,&islang), GET_LANG(BRAND_COMPANY_TEL,&islang), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ADDRESS,&islang), GET_LANG(BRAND_COMPANY_ADDRESS,&islang), NULL);
if (strlen(BRAND_TITLE_GPS) > 1)
{
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_GPS, &islang), GET_LANG(BRAND_COMPANY_GPS, &islang), GET_LANG(BRAND_URL_GPS, &islang));
}
if (scanner)
{
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang), scanner->get_firmware_version().c_str(), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang), scanner->get_serial_num().c_str(), NULL);
info = scanner->get_ip();
if (info.length() > 10 && !info.empty())
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_IP,&islang), info.c_str(), NULL);
info.clear();
info = scanner->get_device_model();
if (!info.empty())
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_DEVICE_MODEL, &islang), info.c_str(), NULL);
ret = scanner->get_devs_time(info);
if (ret == SCANNER_ERR_OK && !info.empty())
{
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT, &islang), info.c_str(), NULL);
}
ret = scanner->get_roller_num(rolls);
if (ret == SCANNER_ERR_OK)
{
char buf[40];
sprintf(buf, "%u", rolls);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), buf, NULL);
}
#ifdef BRAND_DISPLAY_ALL_EXPAND
else
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), rolls == -1 ? GET_LANG(BRAND_COMMUNICATION_FAIL,&islang) : GET_LANG(BRAND_DEVICE_NOT_SUPPORT,&islang), NULL);
#endif
ret = scanner->get_history_scan_count(rolls);
if (ret == SCANNER_ERR_OK)
{
char buf[40];
sprintf(buf, "%u", rolls);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), buf, NULL);
}
#ifdef BRAND_DISPLAY_ALL_EXPAND
else
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), rolls == -1 ? GET_LANG(BRAND_COMMUNICATION_FAIL,&islang) : GET_LANG(BRAND_DEVICE_NOT_SUPPORT,&islang), NULL);
#endif
}
#ifdef BRAND_DISPLAY_ALL_EXPAND
else
{
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_IP,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL);
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL);
}
#endif
about->appendix[count].key = NULL;
about->appendix[count].content = NULL;
about->appendix[count].url = NULL;
return SCANNER_ERR_OK;
}
imgproc_mgr* hg_scanner_mgr::create_image_processor(device_option* devopts)
{
imgproc_mgr* proc = new imgproc_mgr(devopts, dump_img_, dump_img_path_.c_str());
@ -825,7 +475,7 @@ imgproc_mgr* hg_scanner_mgr::create_image_processor(device_option* devopts)
scanner_err hg_scanner_mgr::hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only)
{
std::vector<OLSCANNER> devusbuf;
std::vector<ONLNSCANNER> devusbuf;
long size = *count;
scanner_err ret = SCANNER_ERR_OK;
std::string g_vendor(from_default_language(COMPANY_NAME, nullptr));
@ -839,11 +489,10 @@ scanner_err hg_scanner_mgr::hg_scanner_enum(ScannerInfo* scanner_list, long* cou
{
for (size_t i = 0; i < devusbuf.size(); i++)
{
scanner_list->vid = g_supporting_devices[devusbuf[i].ind].vid;
scanner_list->pid = g_supporting_devices[devusbuf[i].ind].pid;
scanner_list->vid = devusbuf[i].vid;
scanner_list->pid = devusbuf[i].pid;
strcpy(scanner_list->name, devusbuf[i].display_name.c_str());
strcpy(scanner_list->model, g_supporting_devices[devusbuf[i].ind].family.c_str());
strcpy(scanner_list->type, g_supporting_devices[devusbuf[i].ind].name.c_str());
strcpy(scanner_list->model, devusbuf[i].family.c_str());
strcpy(scanner_list->vendor, g_vendor.c_str());
scanner_list++;
}
@ -853,68 +502,32 @@ scanner_err hg_scanner_mgr::hg_scanner_enum(ScannerInfo* scanner_list, long* cou
}
scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc)
{
std::vector<OLSCANNER> devs;
std::vector<OLSCANNER>::iterator it;
usb_io* io = NULL;
std::vector<ONLNSCANNER>::iterator it;
scanner_err ret = SCANNER_ERR_DEVICE_NOT_FOUND;
SIMPLE_LOCK(mutex_dev_);
*h = NULL;
get_online_devices(devs);
it = std::find(devs.begin(), devs.end(), name);
if (it != devs.end())
it = std::find(online_devices_.begin(), online_devices_.end(), name);
if (it != online_devices_.end())
{
hg_scanner_mgr::last_open_msg_ = "";
ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_);
if (ret == SCANNER_ERR_OK)
{
hg_scanner* scanner = g_supporting_devices[it->ind].create_scanner(it->display_name.c_str(), g_supporting_devices[it->ind].family.c_str(), io, h);
std::vector<sane_opt_provider*> cnst;
cnst.push_back(offline_);
cnst.push_back(g_language);
if (scanner)
it->scanner = new hg_scanner(&(*it), nullptr, user_, &cnst);
if (it->scanner->status() == SCANNER_ERR_OK)
{
scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_);
scanner->set_dev_family(g_supporting_devices[it->ind].family.c_str());
scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_);
*h = it->scanner;
}
{
std::lock_guard<std::mutex> lock(mutex_dev_);
std::vector<OLSCANNER>::iterator ptr = std::find(online_devices_.begin(), online_devices_.end(), name);
if (ptr != online_devices_.end())
{
if (ptr->scanner)
ptr->scanner->release();
ptr->scanner = (hg_scanner*)*h;
auto userpriv = [this](int priv) -> bool
{
return user_->has_privilege(priv);
};
auto logger = [this](const char* msg) -> void
{
utils::to_log(LOG_LEVEL_DEBUG, "%s", msg);
};
utils::to_log(LOG_LEVEL_DEBUG, "---Initialize device options ...\n");
if (ptr->dev_opts)
ptr->dev_opts->clear();
else
ptr->dev_opts = new device_option(userpriv, logger);
ptr->dev_opts->add(dynamic_cast<sane_opt_provider*>(offline_));
ptr->dev_opts->add(dynamic_cast<sane_opt_provider*>(g_language));
ptr->dev_opts->add(ptr->scanner);
ptr->imgproc = create_image_processor(ptr->dev_opts);
ptr->scanner->set_image_processor(ptr->imgproc);
ptr->dev_opts->add(ptr->imgproc);
utils::to_log(LOG_LEVEL_DEBUG, "---Initialize %d device options OVER.\n", ptr->dev_opts->count());
{
ret = (scanner_err)it->scanner->status();
hg_scanner_mgr::last_open_msg_ = it->scanner->status_message();
it->scanner->close();
it->scanner->release();
it->scanner = nullptr;
}
}
}
else if(hg_scanner_mgr::last_open_msg_.length())
hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr);
if(io)
io->release();
}
return *h ? SCANNER_ERR_OK : ret;
}
@ -926,26 +539,14 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force)
{
if (v.scanner == h)
{
v.scanner->close(/*force*/);
v.scanner->release();
v.scanner = nullptr;
if (v.dev_opts)
{
v.dev_opts->clear();
v.dev_opts->release();
v.dev_opts = nullptr;
}
if (v.imgproc)
v.imgproc->release();
v.imgproc = nullptr;
break;
}
}
}
SCAN_PTR(h)->close(force);
SCAN_PTR(h)->release();
//delete SCAN_PTR(h);
return SCANNER_ERR_OK;
}
scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const char* name, char* data, long* len, int type)
@ -970,9 +571,7 @@ scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const cha
{
if (v.scanner == h)
{
tmp = v.dev_opts;
if (tmp)
tmp->add_ref();
tmp = v.scanner->get_device_opt();
break;
}
}
@ -1033,9 +632,7 @@ scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const cha
{
if (v.scanner == h)
{
tmp = v.dev_opts;
if (tmp)
tmp->add_ref();
tmp = v.scanner->get_device_opt();
break;
}
}
@ -1130,8 +727,8 @@ scanner_err hg_scanner_mgr::hg_scanner_stop(scanner_handle h)
scanner_err err = (scanner_err)SCAN_PTR(h)->stop();
// call from APP, block when all working-threads stopped - added on 2023-10-18 when handled double-feeding in SANE
while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE)
std::this_thread::sleep_for(std::chrono::milliseconds(3));
//while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE)
// std::this_thread::sleep_for(std::chrono::milliseconds(3));
return err;
}
@ -1144,7 +741,7 @@ scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned
if (!len)
return SCANNER_ERR_INVALID_PARAMETER;
int l = *len,
size_t l = *len,
err = SCAN_PTR(h)->read_image_data(data, &l);
*len = l;
@ -1157,34 +754,11 @@ scanner_err hg_scanner_mgr::hg_scanner_get_status(scanner_handle h, int setstuta
}
scanner_err hg_scanner_mgr::hg_scanner_reset(scanner_handle h)
{
return (scanner_err)SCAN_PTR(h)->reset();
return SCANNER_ERR_OK; // (scanner_err)SCAN_PTR(h)->reset();
}
scanner_err hg_scanner_mgr::hg_scanner_control(scanner_handle h, unsigned long code, void* data, unsigned* len)
{
//if (!len && code != IO_CTRL_CODE_TEST_SINGLE)
// return SCANNER_ERR_INVALID_PARAMETER;
if (code == IO_CTRL_CODE_ABOUT_INFO)
return get_about_info(h, data, len);
else if (code == IO_CTRL_CODE_GET_LOG_FILE && len && *len == LOG_FILE_DRIVER)
{
if (!data)
return SCANNER_ERR_INVALID_PARAMETER;
std::string f(utils::temporary_path() + PATH_SEPARATOR + "scanner-tmplog.txt");
int ret = utils::copy_log_file_to(f.c_str());
if (ret)
*((char*)data) = 0;
else
strcpy((char*)data, f.c_str());
return (scanner_err)ret;
}
else if (!h)
return SCANNER_ERR_INVALID_PARAMETER;
else
return (scanner_err)SCAN_PTR(h)->device_io_control(code, data, len);
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
void hg_scanner_mgr::on_language_changed(void)
@ -1192,8 +766,12 @@ void hg_scanner_mgr::on_language_changed(void)
std::lock_guard<std::mutex> lock(mutex_dev_);
for (auto& v: online_devices_)
{
if (v.dev_opts)
v.dev_opts->update_data(nullptr, nullptr, false);
if (v.scanner)
{
device_option* opt = v.scanner->get_device_opt();
opt->update_data(nullptr, nullptr, false);
opt->release();
}
}
}
const char* hg_scanner_mgr::last_open_message(void)

View File

@ -1,6 +1,6 @@
#pragma once
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include <base/huagaoxxx_warraper_ex.h>
#include "usb_manager.h"
#include <string>
#include <vector>
@ -42,32 +42,11 @@ class offline_opts;
class device_option;
class sane_opt_provider;
class imgproc_mgr;
struct _online_scanner;
class hg_scanner_mgr
{
typedef struct _online_scanner
{
libusb_device* dev; // the unique usb device
int ind; // index in supporting scanners queue
hg_scanner* scanner;
device_option* dev_opts;
imgproc_mgr* imgproc;
std::string display_name;
bool operator==(const libusb_device* d)
{
return d == dev;
}
bool operator==(const int& index)
{
return ind == index;
}
bool operator==(const char* name)
{
return display_name == name;
}
}OLSCANNER;
std::vector<OLSCANNER> online_devices_;
std::vector<_online_scanner> online_devices_;
std::mutex mutex_dev_;
unsigned int same_ind_;
@ -98,11 +77,9 @@ class hg_scanner_mgr
static void usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user); // usb_ver_h.usb_ver_l
void on_hgscanner_pnp(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry); // usb_ver_h.usb_ver_l
void get_online_devices(std::vector<OLSCANNER>& devs);
void get_online_devices(std::vector<_online_scanner>& devs);
void init_debug_config(const char* cfg_file);
void set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url);
scanner_err get_about_info(scanner_handle h, void* data, unsigned* len);
imgproc_mgr* create_image_processor(device_option* devopts);
string cf_name;
@ -126,15 +103,6 @@ public:
};
static uint32_t unique_id(int type = UNIQUE_ID_IMG);
static hg_scanner* create_scanner_empty(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g100(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g239(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g300(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g302(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g400(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g402(const char* name, const char* family, usb_io* io, scanner_handle* h);
static hg_scanner* create_scanner_g439(const char* name, const char* family, usb_io* io, scanner_handle* h);
public:
scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only);
scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc);

View File

@ -1,321 +0,0 @@
#include "scanner_setting.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DEFINE ...
#define SSFH_VER_MAIN 1
#define SSFH_VER_MINOR 0
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// base64 util ..
static char base64_default_table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
base64::base64() : padding_char_('=')
{
base64_ind_[0] = base64_char_[0] = 0;
initialize_base64_table(base64_default_table);
}
base64::~base64()
{}
bool base64::is_valid_base64_table(const char* table)
{
bool valid = false;
if (table && strlen(table) >= 64)
{
char repeat[4] = { 0 };
valid = true;
for (int i = 0; i < 63; ++i)
{
repeat[0] = table[i];
if (strstr(table + i + 1, repeat))
{
valid = false;
break;
}
}
}
return valid;
}
bool base64::initialize_base64_table(const char* table)
{
if (!table || strlen(table) < 64)
{
if (memcmp(base64_default_table, base64_char_, 64) == 0)
{
return !table;
}
memcpy(base64_char_, base64_default_table, 64);
}
else
{
if (memcmp(base64_char_, table, 64) == 0)
{
return true;
}
else if (!is_valid_base64_table(table))
return false;
memcpy(base64_char_, table, 64);
}
base64_char_[64] = base64_char_[65] = 0;
// initialize base64_index
memset(base64_ind_, 0, sizeof(base64_ind_));
for (int i = 0; i < 64; ++i)
{
base64_ind_[base64_char_[i]] = i;
}
// padding char
padding_char_ = '=';
if (base64_ind_[padding_char_])
{
for (padding_char_ = 0x21; padding_char_ < 0x7e && base64_ind_[padding_char_] && padding_char_ != base64_char_[0]; ++padding_char_);
}
return padding_char_ < 0x7e;
}
bool base64::set_base64_table(const char* table)
{
return initialize_base64_table(table ? table : base64_default_table);
}
std::string base64::encode(const char* data, size_t bytes, unsigned int line_bytes, bool need_padding)
{
char* str = (char*)malloc(bytes * 2 + 3);
unsigned char c1 = 0, c2 = 0, c3 = 0;
unsigned long line_len = 0;
unsigned long words = bytes / 3;
int rest = bytes % 3,
pos = 0;
std::string ret("");
for (unsigned long i = 0; i < words; ++i)
{
// fetch 3 letters
c1 = *data++;
c2 = *data++;
c3 = *data++;
// encoding into 4-bytes
str[pos++] = base64_char_[c1 >> 2];
str[pos++] = base64_char_[((c1 << 4) | (c2 >> 4)) & 0x3f];
str[pos++] = base64_char_[((c2 << 2) | (c3 >> 6)) & 0x3f];
str[pos++] = base64_char_[c3 & 0x3f];
line_len += 4;
// new line ...
if ((unsigned int)line_len > line_bytes - 4)
{
str[pos++] = '\r';
str[pos++] = '\n';
line_len = 0;
}
}
// rest ...
if (rest == 1)
{
c1 = *data++;
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
str[pos++] = base64_char_[((c1 & 0x03) << 4)];
if (need_padding)
{
str[pos++] = padding_char_;
str[pos++] = padding_char_;
}
}
else if (rest == 2)
{
c1 = *data++;
c2 = *data++;
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
str[pos++] = base64_char_[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
str[pos++] = base64_char_[((c2 & 0x0f) << 2)];
if (need_padding)
{
str[pos++] = padding_char_;
}
}
if (pos > 0)
{
str[pos++] = 0;
ret = std::string(str, pos - 1);
}
free(str);
return ret;
}
std::string base64::decode(const char* data, size_t bytes)
{
char* str = (char*)malloc(bytes + 1);
int pos = 0,
shifts = 18,
value = 0;
std::string ret("");
for (int i = 0; i < (int)bytes; ++i)
{
if (*data != '\r' && *data != '\n')
{
if (*data == padding_char_)
{
break;
}
value += base64_ind_[*data] << shifts;
if (shifts == 0)
{
shifts = 18;
str[pos++] = (value >> 16) & 0x0ff;
str[pos++] = (value >> 8) & 0x0ff;
str[pos++] = (value >> 0) & 0x0ff;
value = 0;
}
else
{
shifts -= 6;
}
}
data++;
}
if (shifts == 12 || shifts == 6)
{
str[pos++] = (value >> 16) & 0x0ff;
}
else if (shifts == 0)
{
str[pos++] = (value >> 16) & 0x0ff;
str[pos++] = (value >> 8) & 0x0ff;
}
if (pos > 0)
{
str[pos++] = 0;
ret = std::string(str, pos - 1);
}
free(str);
return ret;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// check sum ..
unsigned int simple_checksum(const char* data, size_t len)
{
unsigned int chk = -1;
while (len >= sizeof(chk))
{
chk ^= *((unsigned int*)data);
data += sizeof(chk);
len -= sizeof(chk);
}
if (len)
{
unsigned int rest = *((unsigned int*)data), mask = (1 << (len * 8)) - 1;
rest &= mask;
chk ^= rest;
}
return chk;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// exporting ..
int load_scanner_setting(const char* file, std::string& jsn)
{
FILE* src = fopen(file, "rb");
long len = 0;
char* buf = nullptr;
SSFILEH ssfh = { 0 };
if (!src)
return errno;
fseek(src, 0, SEEK_END);
len = ftell(src);
fseek(src, 0, SEEK_SET);
if (len < sizeof(ssfh))
{
fclose(src);
return EBADF;
}
buf = new char[len];
if (!buf)
{
fclose(src);
return ENOMEM;
}
memset(buf, 0, len);
fread(&ssfh, sizeof(ssfh), 1, src);
len -= sizeof(ssfh);
fread(buf, 1, len, src);
fclose(src);
if (ssfh.ver_main != 1 ||
ssfh.ver_sub != 0 ||
simple_checksum(buf, len) != (ssfh.checksum ^ ssfh.timestamp) ||
ssfh.length != len + sizeof(ssfh))
{
delete[] buf;
return EBADF;
}
base64 b64;
jsn = b64.decode(buf, len);
delete[] buf;
return 0;
}
int save_scanner_setting(const char* file, const std::string& jsn)
{
SSFILEH ssfh = { 0 };
base64 b64;
std::string str(b64.encode(jsn.c_str(), jsn.length()));
ssfh.ver_main = SSFH_VER_MAIN;
ssfh.ver_sub = SSFH_VER_MINOR;
ssfh.length = str.length() + sizeof(ssfh);
ssfh.timestamp = time(NULL);
ssfh.checksum = simple_checksum(str.c_str(), str.length());
FILE *dst = fopen(file, "wb");
bool ok = false;
if (!dst)
return ENFILE;
ssfh.checksum ^= ssfh.timestamp;
if (fwrite(&ssfh, sizeof(ssfh), 1, dst) == 1)
ok = fwrite(str.c_str(), 1, str.length(), dst) == str.length();
fclose(dst);
if (!ok)
{
remove(file);
return EFAULT;
}
return 0;
}

View File

@ -1,57 +0,0 @@
#pragma once
// For: check and load scanner configuration json
//
// Date: 2022-08-12
//
// FileName: 0239.hsc
//
// Location: same parent path of scanner component, rel: ./settings
//
// Format: 0: short - 1.2, version of the file format
//
// 2: int - total length of the whole file, include this head
//
// 6: unsigned - checksum of content
//
// 10: BASE64 of the json content
#include <string>
#pragma pack(push)
#pragma pack(1)
typedef struct _scanner_setting_file_head
{
unsigned char ver_main;
unsigned char ver_sub;
unsigned int length; // whole file length, include this head
unsigned int checksum; // checksum of BASE64 content
unsigned int timestamp; // time(NULL)
char base64_content[0];
}SSFILEH, *LPSSFILEH;
#pragma pack(pop)
class base64
{
char base64_ind_[128];
char base64_char_[80];
char padding_char_;
bool is_valid_base64_table(const char* table);
bool initialize_base64_table(const char* table);
public:
base64();
~base64();
public:
bool set_base64_table(const char* table = nullptr);
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
std::string decode(const char* data, size_t bytes);
};
// return 0 for success, otherwise error code
int load_scanner_setting(const char* file, std::string& jsn);
int save_scanner_setting(const char* file, const std::string& jsn);

View File

@ -1,99 +0,0 @@
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>
class ThreadPool {
public:
ThreadPool();
ThreadPool(size_t);
template<class F, class... Args>
auto enqueue(F&& f, Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type>;
~ThreadPool();
private:
// need to keep track of threads so we can join them
std::vector< std::thread > workers;
// the task queue
std::queue< std::function<void()> > tasks;
// synchronization
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};
// the constructor just launches some amount of workers
inline ThreadPool::ThreadPool(size_t threads)
: stop(false)
{
for(size_t i = 0;i<threads;++i)
workers.emplace_back(
[this]
{
for(;;)
{
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock,
[this]{ return this->stop || !this->tasks.empty(); });
if(this->stop && this->tasks.empty())
return;
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
}
);
}
// add new work item to the pool
template<class F, class... Args>
auto ThreadPool::enqueue(F&& f, Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type>
{
using return_type = typename std::result_of<F(Args...)>::type;
auto task = std::make_shared< std::packaged_task<return_type()> >(
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
);
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
// don't allow enqueueing after stopping the pool
if(stop)
throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.emplace([task](){ (*task)(); });
}
condition.notify_one();
return res;
}
// the destructor joins all threads
inline ThreadPool::~ThreadPool()
{
{
std::unique_lock<std::mutex> lock(queue_mutex);
stop = true;
}
condition.notify_all();
for(std::thread &worker: workers)
worker.join();
}
#endif

View File

@ -1,7 +1,6 @@
#include "usb_manager.h"
#include "../../sdk/hginclude/utils.h"
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include <base/huagaoxxx_warraper_ex.h>
#include <lang/app_language.h>
#include <iostream>
@ -46,7 +45,7 @@ usb_manager::usb_manager() : run_(true)
usb_manager::~usb_manager()
{
run_ = false;
wait_pnp_.notify();
wait_pnp_.trigger();
libusb_context* ctx = nullptr;
#if defined(WIN32) || defined(_WIN64)
ctx = context_;
@ -302,7 +301,7 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
if (ms > 1000)
{
pnp_events_.Put(pd, sizeof(pd));
wait_pnp_.notify();
wait_pnp_.trigger();
}
else
{

View File

@ -20,7 +20,7 @@
#include "huagao/hgscanner_error.h"
#include "BlockingQueue.h"
#include "hg_ipc.h"
#include <base/utils.h>
struct usb_dev

View File

@ -6,7 +6,7 @@
#include <huagao/brand.h>
#include <lang/app_language.h>
#include <sane/sane_ex.h>
#include <hginclude/utils.h>
#include <base/utils.h>
#include <string.h>
#include "../scanner_manager.h" // for version
#include "user.h"

View File

@ -1,12 +1,12 @@
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include <base/huagaoxxx_warraper_ex.h>
#include "../../../sdk/include/huagao/brand.h"
#include "../../sdk/hginclude/utils.h"
#include <huagao/brand.h>
#include <base/utils.h>
#include "../hgdev/scanner_manager.h"
#include <iostream>
#include <lang/app_language.h>
#include "../hgdev/common_setting.h"
#include <base/packet.h>
#if defined(WIN32) || defined(_WIN64)
#include <fileapi.h>
@ -161,9 +161,29 @@ extern "C"
}
scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc)
{
//return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc);
try
{
return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc);
}
catch (std::exception& e)
{
if (h)
*h = nullptr;
utils::to_log(LOG_LEVEL_FATAL, "Exception occurs when open '%s': %s.\n", name, e.what());
return SCANNER_ERR_DATA_DAMAGED;
}
catch (...)
{
if (h)
*h = nullptr;
utils::to_log(LOG_LEVEL_FATAL, "Exception occurs when open '%s'!\n", name);
return SCANNER_ERR_DATA_DAMAGED;
}
}
scanner_err hg_scanner_close(scanner_handle h, bool force)
{

View File

@ -1,7 +1,7 @@
#include "sane_hg_mdw.h"
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h" // for log-api
#include "../sdk/hginclude/utils.h" // for log-level
#include <base/huagaoxxx_warraper_ex.h> // for log-api
#include <base/utils.h> // for log-level
/// <summary>
/// SANE API entrance ...

View File

@ -19,12 +19,13 @@
#include <pthread.h>
#endif
#include "../../sdk/include/sane/sane_option_definitions.h"
#include <sane/sane_option_definitions.h>
#include "sane_option.h"
#include <lang/app_language.h>
#include "../sdk/hginclude/utils.h"
#include <base/utils.h>
#include <huagao/brand.h>
#include "../sdk/sane_opt_json/device_opt.h" // for readable_text(SANE_Value_Type type, void* value)
#include <sane_opt_json/device_opt.h> // for readable_text(SANE_Value_Type type, void* value)
#include <huagao/hgscanner_error.h>
#ifndef SIGUSR1
#define SIGUSR1 10

View File

@ -1,7 +1,7 @@
#pragma once
#include "sane/sane_ex.h"
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include <base/huagaoxxx_warraper_ex.h>
#include <vector>
#include <algorithm>

512
sdk/base/data.cpp Normal file
View File

@ -0,0 +1,512 @@
#include "data.h"
#include <string.h>
#if defined(WIN32) || defined(_WIN64)
#include <Windows.h>
namespace sys_util
{
int get_disk_size(const char* path, uint64_t* total, uint64_t* avail, uint64_t* blocksize)
{
std::string disk(path);
size_t pos = disk.find("\\");
DWORD spc = 0, bps = 0, avc = 0, tot = 0;
if (pos++ != std::string::npos)
disk.erase(pos);
if (GetDiskFreeSpaceA(disk.c_str(), &spc, &bps, &avc, &tot))
{
if (total)
{
*total = tot;
*total *= bps * spc;
}
if (avail)
{
*avail = avc;
*avail *= bps * spc;
}
if (blocksize)
{
*blocksize = bps;
*blocksize *= spc;
}
return 0;
}
else
{
return GetLastError();
}
}
}
#else
#include "common/sys_util.h"
#include <sys/fcntl.h>
#include <unistd.h>
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
packet_data_base::packet_data_base() : pack_cmd_(0), pack_id_(0)
, progress_notify_(PROGRESS_NOTIFYER()), user_data_(nullptr)
{}
packet_data_base::~packet_data_base()
{}
int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err)
{
if (progress_notify_)
progress_notify_(total, cur_size, err, user_data_);
else
return ENOENT;
}
void packet_data_base::set_packet_param(uint32_t cmd, uint32_t id)
{
pack_cmd_ = cmd;
pack_id_ = id;
}
int packet_data_base::get_packet_command(void)
{
return pack_cmd_;
}
int packet_data_base::get_packet_id(void)
{
return pack_id_;
}
void packet_data_base::set_progress_notify(PROGRESS_NOTIFYER notify, void* param)
{
progress_notify_ = notify;
user_data_ = param;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
data_holder::data_holder()
{}
data_holder::~data_holder()
{}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
mem_holder::mem_holder(size_t size) : space_(size)
{
buf_ = (uint8_t*)malloc(size);
if (buf_)
memset(buf_, 0, size);
}
mem_holder::~mem_holder()
{
if (buf_)
free(buf_);
buf_ = nullptr;
}
int mem_holder::put_data(const void* data, uint32_t* size)
{
if (*size > space_ - wpos_)
*size = space_ - wpos_;
memcpy(buf_ + wpos_, data, *size);
wpos_ += *size;
return 0;
}
bool mem_holder::is_complete(void)
{
return wpos_ >= space_;
}
uint32_t mem_holder::get_required(void)
{
if (wpos_ >= space_)
return 0;
else
return space_ - wpos_;
}
size_t mem_holder::data_length(void)
{
return wpos_;
}
uint8_t* mem_holder::data(void)
{
return buf_;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
empty_holer::empty_holer(uint64_t size) : size_(size), put_(0)
{}
empty_holer::~empty_holer()
{}
int empty_holer::put_data(const void* data, uint32_t* size)
{
if (*size >= size_ - put_)
{
*size -= size_ - put_;
put_ = size_;
}
else
{
put_ += *size;
}
notify_progress(size_, put_, 0);
return 0;
}
bool empty_holer::is_complete(void)
{
return size_ == put_;
}
uint32_t empty_holer::get_required(void)
{
return size_ - put_;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
file_saver::file_saver(void) : size_(0), wrote_(0), path_(""), check_(""), dst_(nullptr), pack_cmd_(0), pack_id_(0)
{}
file_saver::~file_saver()
{
close();
}
void file_saver::close(void)
{
if(dst_)
fclose(dst_);
dst_ = nullptr;
size_ = wrote_ = pack_cmd_ = pack_id_ = 0;
path_ = check_ = "";
}
int file_saver::open(const char* path, uint64_t size, const char* check)
{
int err = 0;
close();
dst_ = fopen(path, "wb");
if(dst_)
{
uint64_t space = 0;
err = sys_util::get_disk_size(path, nullptr, &space, nullptr);
if (err || space < size * 1.5)
{
fclose(dst_);
dst_ = nullptr;
remove(path);
if (err == 0)
err = ENOSPC;
}
else
{
path_ = path;
size_ = size;
check_ = check ? check : "";
}
}
else
{
err = errno;
}
return err;
}
int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/)
{
if(!dst_)
return ENOENT;
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size,
real_w = fwrite(data, 1, w, dst_), // should handle error here !
err = 0;
*size = real_w;
wrote_ += real_w;
if(wrote_ >= size_)
{
fclose(dst_);
dst_ = nullptr;
}
else if (real_w < w) // what happens ?
{
err = ferror(dst_);
}
notify_progress(size_, wrote_, err);
return 0;
}
bool file_saver::is_complete(void)
{
return wrote_ >= size_;
}
uint32_t file_saver::get_required(void)
{
return size_ - wrote_;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
data_source::data_source()
{}
data_source::~data_source()
{}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// dyn_mem
uint64_t dyn_mem::mem_used_bytes_ = 0;
MUTEX dyn_mem::mem_lock_;
dyn_mem::dyn_mem(size_t size) : buf_(nullptr), len_(0), space_(ALIGN_INT(size, 16))
{
buf_ = (uint8_t*)malloc(space_);
if (buf_)
{
SIMPLE_LOCK(dyn_mem::mem_lock_);
dyn_mem::mem_used_bytes_ += space_;
memset(buf_, 0, space_);
}
}
dyn_mem::dyn_mem(void* buf, size_t size) : buf_((uint8_t*)buf), space_(size), len_(size)
{
}
dyn_mem::~dyn_mem()
{
if (buf_)
{
free(buf_);
{
SIMPLE_LOCK(dyn_mem::mem_lock_);
dyn_mem::mem_used_bytes_ -= space_;
}
}
}
uint64_t dyn_mem::mem_used(void)
{
return dyn_mem::mem_used_bytes_;
}
dyn_mem_ptr dyn_mem::memory(size_t size)
{
return new dyn_mem(size);
}
uint32_t dyn_mem::space(void)
{
return space_;
}
bool dyn_mem::set_len(size_t len)
{
if (len > space_)
return false;
len_ = len;
return true;
}
int dyn_mem::put(const void* data, int len)
{
if (len + len_ > space_)
len = space_ - len;
if (len > 0)
{
memcpy(buf_ + len_, data, len);
len_ += len;
}
else
len = 0;
return len;
}
void* dyn_mem::detach(size_t* size)
{
void* buf = buf_;
if (size)
*size = space_;
space_ = len_ = 0;
buf_ = nullptr;
return buf;
}
size_t dyn_mem::used(size_t len)
{
if (len >= len_)
{
len_ = 0;
}
else if (len)
{
memcpy(buf_, buf_ + len, len_ - len);
len_ -= len;
}
return len_;
}
dyn_mem& dyn_mem::operator+=(dyn_mem& r)
{
if (len_ + r.get_rest() > space_)
{
size_t size = ALIGN_INT(len_ + r.get_rest(), 16);
uint8_t* buf = (uint8_t*)malloc(size);
memcpy(buf, buf_, len_);
free(buf_);
buf_ = buf;
{
SIMPLE_LOCK(dyn_mem::mem_lock_);
dyn_mem::mem_used_bytes_ += size - space_;
}
space_ = size;
}
memcpy(buf_ + len_, r.buf_, r.get_rest());
len_ += r.get_rest();
return *this;
}
bool dyn_mem::is_memory_block(void)
{
return true;
}
uint32_t dyn_mem::get_rest(void)
{
return len_;
}
// following API valid when is_memory_block() return true
uint8_t* dyn_mem::ptr(void)
{
return buf_;
}
// following API valid when is_memory_block() return false
int dyn_mem::fetch_data(void* buf, uint32_t* size)
{
if (*size >= len_)
{
memcpy(buf, buf_, len_);
*size = len_;
len_ = 0;
}
else
{
memcpy(buf, buf_, *size);
used(*size);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
file_reader::file_reader() : len_(0), src_(nullptr), path_(""), consume_(0)
{}
file_reader::~file_reader()
{
if(src_)
fclose(src_);
}
int file_reader::open(const char* file)
{
if(src_)
fclose(src_);
src_ = fopen(file, "rb");
if(!src_)
return errno;
FSEEK(src_, 0, SEEK_END);
len_ = FTELL(src_);
FSEEK(src_, 0, SEEK_SET);
path_ = file;
consume_ = 0;
return 0;
}
int file_reader::attach(FILE* f)
{
if (src_)
{
fclose(src_);
src_ = nullptr;
}
uint64_t cur = FTELL(f);
FSEEK(f, 0, SEEK_END);
len_ = FTELL(f);
FSEEK(f, cur, SEEK_SET);
if (len_ <= cur)
return EINVAL;
src_ = f;
len_ -= cur;
consume_ = 0;
return 0;
}
FILE* file_reader::detach(void)
{
FILE* ret = src_;
src_ = nullptr;
len_ = 0;
path_ = "";
return ret;
}
bool file_reader::is_memory_block(void)
{
return false;
}
uint32_t file_reader::get_rest(void)
{
return len_ - consume_;
}
// following API valid when is_memory_block() return true
uint8_t* file_reader::ptr(void)
{
return nullptr;
}
// following API valid when is_memory_block() return false
int file_reader::fetch_data(void* buf, uint32_t* size)
{
if (!src_)
return ENODATA;
size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!!
consume_ += r;
*size = r;
if (consume_ >= len_)
{
fclose(src_);
src_ = nullptr;
}
notify_progress(len_, consume_, 0);
return 0;
}

260
sdk/base/data.h Normal file
View File

@ -0,0 +1,260 @@
#pragma once
// Objects IO
//
// created on 2023-03-10
#include "utils.h"
#include "packet.h"
#include <string>
#include <functional>
#define CLS_PTR(cls) typedef cls* cls##_ptr;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* packet parameter keeper, parameter of corresponding packet
*/
#define PROGRESS_NOTIFYER std::function<int(uint64_t/*total*/, uint64_t/*cur-size*/, uint32_t/*err*/, void* /*user data*/)>
class packet_data_base : public refer
{
PROGRESS_NOTIFYER progress_notify_;
void* user_data_;
protected:
uint32_t pack_cmd_;
uint32_t pack_id_;
public:
packet_data_base();
protected:
virtual ~packet_data_base();
int notify_progress(uint64_t total, uint64_t cur_size, uint32_t err);
public:
void set_packet_param(uint32_t cmd, uint32_t id);
int get_packet_command(void);
int get_packet_id(void);
void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER(), void* param = nullptr);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* data_holder, used when data is also required for a certain packet
*/
class data_holder : public packet_data_base
{
public:
data_holder();
protected:
virtual ~data_holder();
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) = 0; // return error code
virtual bool is_complete(void) = 0;
virtual uint32_t get_required(void) = 0;
};
class mem_holder : public data_holder
{
uint8_t* buf_ = nullptr;
size_t space_ = 0;
size_t wpos_ = 0;
public:
mem_holder(size_t size);
protected:
~mem_holder();
// data_holder
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
public:
size_t data_length(void);
uint8_t* data(void);
};
class empty_holer : public data_holder
{
uint64_t size_;
uint64_t put_;
public:
empty_holer(uint64_t size);
protected:
~empty_holer();
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override; // return error code
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
};
class file_saver : public data_holder
{
uint64_t size_;
uint64_t wrote_;
std::string path_;
std::string check_;
FILE *dst_;
uint32_t pack_cmd_;
uint32_t pack_id_;
void close(void);
public:
file_saver(void);
protected:
~file_saver();
public:
int open(const char* path, uint64_t size, const char* check = nullptr);
public:
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override;
virtual bool is_complete(void) override;
virtual uint32_t get_required(void) override;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
/* data_source, can be a memory block or STREAM object
*/
class data_source : public packet_data_base
{
uint32_t pack_cmd_;
uint32_t pack_id_;
public:
data_source();
protected:
virtual ~data_source();
public:
virtual bool is_memory_block(void) = 0;
virtual uint32_t get_rest(void) = 0;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) = 0;
// following API valid when is_memory_block() return false. return error code
virtual int fetch_data(void* buf, uint32_t* size) = 0;
};
class dyn_mem : public data_source
{
uint8_t* buf_; // data buf
size_t space_; // occupy space in bytes
size_t len_; // data length in bytes
static MUTEX mem_lock_;
static uint64_t mem_used_bytes_;
public:
dyn_mem(size_t size);
dyn_mem(void* buf, size_t size);
static uint64_t mem_used(void);
static dyn_mem* memory(size_t size);
protected:
~dyn_mem();
public:
uint32_t space(void);
bool set_len(size_t len);
int put(const void* data, int len);
void* detach(size_t* size); // for constructed from dyn_mem(void* buf, size_t size)
size_t used(size_t len); // used len bytes content, move following data to head and set data length, return rest data length
dyn_mem& operator+=(dyn_mem& r);
// data_source
public:
virtual bool is_memory_block(void) override;
virtual uint32_t get_rest(void) override;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) override;
// following API valid when is_memory_block() return false
virtual int fetch_data(void* buf, uint32_t* size) override;
};
class file_reader : public data_source
{
size_t len_;
size_t consume_;
FILE *src_;
std::string path_;
public:
file_reader();
protected:
~file_reader();
public:
int open(const char* file);
int attach(FILE* f);
FILE* detach(void);
public:
virtual bool is_memory_block(void) override;
virtual uint32_t get_rest(void) override;
// following API valid when is_memory_block() return true
virtual uint8_t* ptr(void) override;
// following API valid when is_memory_block() return false
virtual int fetch_data(void* buf, uint32_t* size) override;
};
CLS_PTR(packet_data_base);
CLS_PTR(data_holder);
CLS_PTR(mem_holder);
CLS_PTR(data_source);
CLS_PTR(dyn_mem);
CLS_PTR(file_reader);
// callback proto
//
// parameters: usb_functionfs_event* - the function event ptr
//
// dyn_mem_ptr - the packet buffer, read-only
//
// uint32_t* - to return how many data in bytes the handler consumed, the most high bit is to indicate whether should notify the returned packet has sent
//
// normally, the value should be sizeof(PACK_BASE) + PACK_BASE::payload_len, i.e. the handler consume all data of an entire packet
//
// when invalid packet, suggest use the entire data
//
// packet_data_base_ptr* - return data_holder or data_source or nullptr £¨The number of bytes required for this packet, 0 is over for this packet£©
//
// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file'
//
// data_source: the reply content may be a large data (a large file content)
//
// return value of all routines is the reply packet, nullptr if the packet need not reply
//
// NOTE: when parameter uint32_t* and packet_data_base_ptr* both are nullptr, it is notifying the command reply packet has sent, callback should return nullptr only
//
#define FUNCTION_PROTO_PARAMETERS dyn_mem_ptr, uint32_t*, packet_data_base_ptr*
#define FUNCTION_PROTO_COMMAND_HANDLE dyn_mem_ptr(FUNCTION_PROTO_PARAMETERS)

133
sdk/base/encrypt.cpp Normal file
View File

@ -0,0 +1,133 @@
#include "encrypt.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// exporting api:
dyn_mem_ptr packet_encrypt(dyn_mem_ptr packet, uint32_t cmd_type, uint32_t type, uint8_t enc_data)
{
dyn_mem_ptr ret = packet;
LPPACK_BASE pack = (LPPACK_BASE)packet->ptr();
ret->add_ref();
if (cmd_type == ENCRYPT_CMD_XOR_PID)
pack->cmd ^= pack->pack_id;
else if (cmd_type == ENCRYPT_CMD_ADD_PID)
pack->cmd += pack->pack_id;
else if (cmd_type == ENCRYPT_CMD_SUB_PID)
pack->cmd -= pack->pack_id;
pack->enc_cmd = cmd_type;
if (type != ENCRYPT_NONE)
{
std::string cont("");
if (type == ENCRYPT_BASE64)
{
}
else if (type == ENCRYPT_AES)
{
}
else if (type == ENCRYPT_ZIP)
{
}
if (cont.length())
{
// space is enough ?
if (cont.length() + sizeof(PACK_BASE) > packet->space())
{
ret->release();
ret = dyn_mem::memory(sizeof(PACK_BASE) + cont.length());
memcpy(ret->ptr(), packet->ptr(), sizeof(PACK_BASE));
pack = (LPPACK_BASE)ret->ptr();
}
// copy cipher text and set encrypt type ...
memcpy(pack->payload, cont.c_str(), cont.length());
ret->set_len(sizeof(PACK_BASE) + cont.length());
pack->payload_len = cont.length();
pack->encrypt = type;
pack->enc_data = enc_data;
}
}
return ret;
}
dyn_mem_ptr packet_decrypt(dyn_mem_ptr packet)
{
dyn_mem_ptr ret = packet;
LPPACK_BASE pack = (LPPACK_BASE)packet->ptr();
ret->add_ref();
if (pack->enc_cmd == ENCRYPT_CMD_XOR_PID)
pack->cmd ^= pack->pack_id;
else if (pack->enc_cmd == ENCRYPT_CMD_ADD_PID)
pack->cmd -= pack->pack_id;
else if (pack->enc_cmd == ENCRYPT_CMD_SUB_PID)
pack->cmd += pack->pack_id;
if (pack->encrypt != ENCRYPT_NONE && pack->payload_len && packet->get_rest() >= sizeof(PACK_BASE) + pack->payload_len)
{
std::string cont("");
if (pack->encrypt == ENCRYPT_BASE64)
{
}
else if (pack->encrypt == ENCRYPT_AES)
{
}
else if (pack->encrypt == ENCRYPT_ZIP)
{
}
if (cont.length())
{
// have out-packet data ?
if (packet->get_rest() > sizeof(PACK_BASE) + pack->payload_len)
cont += std::string(pack->payload + pack->payload_len, packet->get_rest() - (sizeof(PACK_BASE) + pack->payload_len));
// space is enough ?
if (cont.length() + sizeof(PACK_BASE) > packet->space())
{
ret->release();
ret = dyn_mem::memory(sizeof(PACK_BASE) + cont.length());
memcpy(ret->ptr(), packet->ptr(), sizeof(PACK_BASE));
pack = (LPPACK_BASE)ret->ptr();
}
// copy plain text and set encrypt type to none ...
memcpy(pack->payload, cont.c_str(), cont.length());
ret->set_len(sizeof(PACK_BASE) + cont.length());
pack->encrypt = ENCRYPT_NONE;
pack->payload_len = cont.length();
}
}
return ret;
}

45
sdk/base/encrypt.h Normal file
View File

@ -0,0 +1,45 @@
#pragma once
// Objects for encrypting/decrypting
//
// created on 2023-04-04
#include "data.h"
enum encryptor
{
ENCRYPT_NONE = 0,
ENCRYPT_BASE64,
ENCRYPT_AES,
ENCRYPT_ZIP,
};
enum encrypt_cmd
{
ENCRYPT_CMD_NONE = 0,
ENCRYPT_CMD_XOR_PID, // cmd ^= pack_id
ENCRYPT_CMD_ADD_PID, // cmd += pack_id
ENCRYPT_CMD_SUB_PID, // cmd -= pack_id
};
// Function: encrypting & decrypting packet
//
// Parameters: packet - pointer to the base packet
//
// data - cipher/plain data
//
// size - [in]: bytes of source 'data';
//
// cmd_type - member 'cmd' encrypting method
//
// type - payload encrypting method
//
// enc_data - encrypting data for payload encrypting method
//
// Return: 'cmd' returned on origin packet, and returning value is for payload only. nullptr on failure
//
// NOTE: nullptr also returned if data was nullptr or size was ZERO
//
dyn_mem_ptr packet_encrypt(dyn_mem_ptr packet, uint32_t cmd_type = ENCRYPT_CMD_NONE, uint32_t type = ENCRYPT_NONE, uint8_t enc_data = 0);
dyn_mem_ptr packet_decrypt(dyn_mem_ptr packet);

View File

@ -167,7 +167,7 @@ typedef struct _device
// 参考命名:名称+资源如“HG200 USB1”
char vendor[MAX_NAME_LEN]; // 设备制造商
char model[MAX_NAME_LEN]; // model name - family
char type[MAX_NAME_LEN]; // device type
//char type[MAX_NAME_LEN]; // device type
}ScannerInfo;
// hg_scanner_control 控制码及参数

379
sdk/base/packet.h Normal file
View File

@ -0,0 +1,379 @@
#pragma once
// packet structures and command
//
// created on 2022-12-06
//
#if !defined(WIN32)
#include <bits/stdint-uintn.h>
#endif
#include <string.h>
#define TEMPORARY_API
///////////////////////////////////////////////////////////////////////////////
// definitions ...
#define CONFIG_NAME_MAX_LEN 32 // max bytes of configuration name
#define FLOAT_PRECISION .000001f
#define IS_FLOAT_EQUAL(x, y) (-FLOAT_PRECISION <= (x) - (y) && (x) - (y) <= FLOAT_PRECISION)
#define MAKE_WORD(b0, b1) (((b0) & 0xff) | (((b1) << 8) & 0x0ff00))
#define MAKE_STR(str) #str
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define ROGER(cmd) cmd##_ROGER
#define PAIR_COMMAND(cmd) \
cmd, \
cmd##_ROGER
#define RETURN_STR_ENUM(v, e) \
if(v == e) \
return #e;
#define STRUCT_CONSTRUCTOR(st_name) \
st_name() \
{ \
memset(this, 0, sizeof(st_name));\
}
// protocol version, The first thing to do after connecting is to check whether the field is compatible !!!
#define PROTOCOL_VER MAKE_WORD(0, 1)
// NOTE: All text transmitted by pack cmd is in UTF-8 format !!!
enum ep0_req
{
USB_REQ_EP0_GET_PROTO_VER = 100, // get protocol version (PROTOCOL_VER), req = me, ind = 0, val = 0, len = 2
USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = 0, len = sizeof(EP0REPLYSTATUS)
USB_REQ_EP0_RESET_BULK, // 关闭并重新打开BULK端点, return error number (uint32_t). req = me, ind = 0, val = 0, len = sizeof(uint32_t)
USB_REQ_EP0_CANCEL_CMD, // 取消当前指令的继续执行(一般用于中止大数据的传输). req = me, ind = 0, val = 0, len = sizeof(uint32_t) * 2 [(uint32_t)cmd + (uint32_t)pack-id]
USB_REQ_EP0_SET_ENCRYPT, // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
USB_REQ_EP0_SET_BULK_BUFFER, // 设置bulk缓冲区大小系数 req = me, ind = coef, val = 0, len = 0
};
enum bulk_status
{
BULK_STATUS_NOT_START = 0, // has not initialized
BULK_STATUS_IDLE, // wait IO
BULK_STATUS_IO, // in reading or writing
BULK_STATUS_ERROR, // error occurs
BULK_STATUS_RESET, // in reset(close and reopen) process
};
enum packet_cmd
{
PACK_CMD_NULL,
PAIR_COMMAND(PACK_CMD_HEART_BEAT), // notify peers you are still alive, receiver should reply the same pack
PAIR_COMMAND(PACK_CMD_INVALID), // reply when received an invalid packet
PAIR_COMMAND(PACK_CMD_SYNC),
// attributes get/set, all content in PACK_BASE::payload should be in JSON style - all readonly attributes move to readonly SANE-options on 2023-03-20
//PACK_CMD_ATTR_SYS_VER_GET = 10, // get system version on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"os":"linux", "ver":"4.4.194", ...}
//PACK_CMD_ATTR_FIRMWARE_VER_GET, // get firmware version, [in]: PACK_BASE, [out] PACK_BASE::payload - {"firmware":"G2393A1234", "CIS":"CIS-123", ...}
//PACK_CMD_ATTR_SERIAL_NUM_GET, // get device serial num, [in]: PACK_BASE, [out] PACK_BASE::payload - {"serial":"20221206001"}
//PACK_CMD_ATTR_SERIAL_NUM_SET, // set device serial num, [in]: PACK_BASE::payload - {"serial":"20221206001"}, [out] PACK_BASE
//PACK_CMD_ATTR_MAC_GET, // get mac address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"mac":"12:34:56:78:9a:bc"}
//PACK_CMD_ATTR_IP_GET, // get ip address, [in]: PACK_BASE, [out] PACK_BASE::payload - {"ipv4":"192.168.1.123", "ipv6":"::1"}
//PACK_CMD_ATTR_HARDWARE_INFO_GET, // get hardwares information on device, [in]: PACK_BASE, [out] PACK_BASE::payload - {"CPU":"ARM x86", "mem":"16GB", ...}
//PACK_CMD_ATTR_HISTORY_COUNT_GET, // get history count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"history-count":12345, ...}
//PACK_CMD_ATTR_ROLLER_COUNT_GET, // get roller count, [in]: PACK_BASE, [out] PACK_BASE::payload - {"roller-count":2345}
//PACK_CMD_ATTR_ROLLER_COUNT_SET, // set roller count, [in]: PACK_BASE::payload - {"roller-count":2345}, [out] PACK_BASE
// configuration get/set
PACK_CMD_STATUS_ROGER = 100, // device -> host. PACK_BASE::result -> status
PAIR_COMMAND(PACK_CMD_SETTING_GET), // get all settings supported by the device, [in]: PACK_BASE, [out]: PACK_BASE::payload - configuration JSON, see SANE-configuration format
PAIR_COMMAND(PACK_CMD_SETTING_GET_CUR), // get current value of given setting, [in]: PACK_BASE::payload - (char*)name, [out]: PACK_BASE::payload - LPCFGVAL
PAIR_COMMAND(PACK_CMD_SETTING_SET), // set value of given setting, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL
PAIR_COMMAND(PACK_CMD_SETTING_RESTORE), // restore given settings, [in]: PACK_BASE::payload - LPCFGVAL, [out]: PACK_BASE::payload - LPCFGVAL
// scan command
PACK_CMD_SCAN_BASE = 200,
PAIR_COMMAND(PACK_CMD_SCAN_START), // start scanning, [in]: PACK_BASE, [out]: PACK_BASE
PAIR_COMMAND(PACK_CMD_SCAN_IMG), // device -> host, PACK_BASE::payload - LPPACKIMAGE
PAIR_COMMAND(PACK_CMD_SCAN_PAPER), // device -> host, ONE paper has passed through the CIS. PACK_BASE::data - index of this paper
PACK_CMD_SCAN_FINISHED_ROGER, // device -> host, PACK_BASE::data is scanner_status
PAIR_COMMAND(PACK_CMD_SCAN_STOP), // stop scanning, [in]: PACK_BASE, [out]: PACK_BASE
//PAIR_COMMAND(PACK_CMD_SCAN_IMAGE_REQ), // get image request, [in]: PACK_BASE, [out] PACK_BASE on error, or PACK_BASE::payload - LPPACKIMAGE
//PAIR_COMMAND(PACK_CMD_SCAN_STATUS), // get scanner status, [in]: PACK_BASE, [out] PACK_BASE::result is status code
// file operation
PACK_CMD_FILE_BASE = 300,
//PAIR_COMMAND(PACK_CMD_FILE_QUERY), // query file information, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE::payload - LPFILEINFO
PAIR_COMMAND(PACK_CMD_FILE_READ_REQ), // read file content, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE::payload - LPTXFILE
PAIR_COMMAND(PACK_CMD_FILE_WRITE_REQ), // write a file, [in]: PACK_BASE::payload - LPTXFILE, [out] PACK_BASE
PAIR_COMMAND(PACK_CMD_FILE_MOVE), // move/rename a file, [in]: PACK_BASE::payload - src\0dst\0\0, [out] PACK_BASE
PAIR_COMMAND(PACK_CMD_FILE_REMOVE), // delete a file, [in]: PACK_BASE::payload - (char*)file-path, [out] PACK_BASE
// process operation
PACK_CMD_PROCESS_BASE = 400,
PAIR_COMMAND(PACK_CMD_PROCESS_START), // start a program [in]: PACK_BASE::payload - (char*)pe\0param\0\0, [out]: PACK_BASE::payload - (uint64_t)process-id on success or PACK_BASE on failure
PAIR_COMMAND(PACK_CMD_PROCESS_STOP), // kill a process [in]: PACK_BASE::payload - (char*)process-id, [out]: PACK_BASE
PAIR_COMMAND(PACK_CMD_PROCESS_REBOOT), // reboot system, [in]: PACK_BASE, [out]: PACK_BASE
//PAIR_COMMAND(PACK_CMD_PROCESS_EXEC_RESULT), // get result of a command, [in]: PACK_BASE::payload - (char*)command string, [out]: PACK_BASE::payload - (char*)execute result. popen(), fgets ...
//PAIR_COMMAND(PACK_CMD_PROCESS_QUERY), // query process information [in]: PACK_BASE::payload - (char*)process-id(-1 for all), [out]: LPPROCINFO
PACK_CMD_TOKEN_GET = 900, // Obtain the token of the required command, [in] PACK_BASE, [out] - PACK_BASE::payload - LPOPERTOKEN
};
enum img_cb_type
{
IMG_CB_IMAGE = 0,
IMG_CB_STATUS,
IMG_CB_STOPPED,
};
enum scanner_status
{
SCANNER_STATUS_READY = 0x10000, // status beginning, avoiding conficts with standards/system error code
SCANNER_STATUS_NOT_OPEN,
SCANNER_STATUS_LOST_CONNECT,
SCANNER_STATUS_RESET_BULK,
SCANNER_STATUS_START_SCANNING, // start ok, but scanning-thread not working
SCANNER_STATUS_SCANNING, // start ok, and scanning-thread is working
SCANNER_STATUS_SCAN_FINISHED, // not a persistance status
SCANNER_STATUS_BUSY, // doing task exclude scanning
SCANNER_STATUS_COVER_OPENNED,
SCANNER_STATUS_COVER_CLOSED,
SCANNER_STATUS_SLEEPING,
SCANNER_STATUS_WAKED_UP,
SCANNER_STATUS_COUNT_MODE,
SCANNER_STATUS_DOUBLE_FEEDED,
SCANNER_STATUS_PAPER_JAMMED,
SCANNER_STATUS_PAPER_ASKEW,
SCANNER_STATUS_FEED_FAILED,
SCANNER_STATUS_NO_PAPER,
SCANNER_STATUS_PAPER_ON,
SCANNER_STATUS_STAPLE_ON,
SCANNER_STATUS_SIZE_ERR,
SCANNER_STATUS_DOGEAR,
SCANNER_STATUS_CFG_CHANGED, // PACK_BASE::payload - LPCFGVAL
};
// option affection if value changed, see SANE_INFO_xxx
enum opt_affect
{
OPT_AFFECT_NONE = 0,
OPT_AFFECT_INEXACT = 1,
OPT_AFFECT_OTHERS = 2,
OPT_AFFECT_IMG_PARAM = 4,
};
enum img_format
{
IMG_FMT_UNKNOWN = 0, // unknown format
IMG_FMT_TIFF,
IMG_FMT_BMP,
IMG_FMT_JPEG,
IMG_FMT_PNG,
IMG_FMT_SVG,
IMG_FMT_WEBP,
IMG_FMT_GIF,
};
enum img_compression
{
IMG_COMPRESSION_NONE = 0,
IMG_COMPRESSION_GROUP4,
IMG_COMPRESSION_RLE4,
IMG_COMPRESSION_RLE8,
IMG_COMPRESSION_LZW,
IMG_COMPRESSION_ZIP,
};
enum img_status
{
IMG_STATUS_OK = 0, // normal
IMG_STATUS_DOUBLE = 1 << 0, // double-feeded paper
IMG_STATUS_JAM = 1 << 1, // jammed paper
IMG_STATUS_STAPLE = 1 << 2, // staples on the paper
IMG_STATUS_SIZE_ERR = 1 << 3, // size check failed
IMG_STATUS_DOGEAR = 1 << 4, // paper has dogear - common
IMG_STATUS_DOGEAR_PARTIAL = 1 << 5, // dogear - scanned partial
IMG_STATUS_BLANK = 1 << 6, // blank image
};
enum data_type
{
DATA_TYPE_BOOL = 0, // (bool*)
DATA_TYPE_INT4, // (uint32_t*)
DATA_TYPE_FLOAT, // (double*)
DATA_TYPE_STRING, // (char*) with max_len space. befor and include me, keep same with SANE_TYPE_BOOL, SANE_TYPE_xxx ...
DATA_TYPE_INT1, // (uint8_t*)
DATA_TYPE_INT2, // (uint16_t*)
DATA_TYPE_INT8, // (uint64_t*)
DATA_TYPE_CUSTOM,
};
enum paper_side
{
PAPER_SIDE_FRONT = 0, // single side, this is front
PAPER_SIDE_BACK, // single side, this is back
PAPER_SIDE_TOP, // VERT-compound sides, and front side is at top
PAPER_SIDE_BOTTOM, // VERT-compound sides, and front side is at bottom
PAPER_SIDE_LEFT, // HORZ-compound sides, and front side is at left
PAPER_SIDE_RIGHT, // HORZ-compound sides, and front side is at right
PAPER_SIDE_DSP, // a special type
};
enum rot_angle
{
ROT_ANGLE_0 = 0,
ROT_ANGLE_90,
ROT_ANGLE_180,
ROT_ANGLE_270,
};
enum clr_channel
{
COLOR_CHANNEL_RGB = 0,
COLOR_CHANNEL_RGBA,
COLOR_CHANNEL_GRAY,
COLOR_CHANNEL_RED,
COLOR_CHANNEL_GREEN,
COLOR_CHANNEL_BLUE,
COLOR_CHANNEL_ALPHA,
};
enum color_mode
{
COLOR_MODE_BW = 0,
COLOR_MODE_GRAY,
COLOR_MODE_RGB,
};
#pragma pack(push)
#pragma pack(1)
typedef struct _ep0_reply
{
uint8_t in_status; // BULK-IN status, enum bulk_statu
uint8_t out_status; // BULK-OUT status, enum bulk_statu
uint16_t in_err; // valid if in_statu == BULK_STATU_ERROR
uint16_t out_err; // valid if out_statu == BULK_STATU_ERROR
uint16_t task_cnt; // tasks in command queue
uint32_t task_cmd; // the cmd of the task thread is doing
uint32_t task_pack_id; // packet id of the cmd
uint32_t task_required_bytes; // required byte of this packet
uint32_t packets_to_sent; // how many packets in sent queue
uint32_t bytes_to_sent; // how many bytes data is waiting for be sent in one replying packet
}EP0REPLYSTATUS, *LPEP0REPLYSTATUS;
typedef struct _pack_base // A piece of data has only one header
{
uint32_t enc_cmd : 2; // encrypting type, for 'cmd'
uint32_t encrypt : 3; // encrypting type, for payload content. the payload must cotains self-check if was encrypted packet
uint32_t enc_data : 5; // data for encrypt
uint32_t size : 6; // bytes of this structure
uint32_t cmd : 16; // packet command
uint32_t data; // simple data in command packet depends 'cmd', or error code in reply packet
uint32_t pack_id; // maintain by the initiator, the reply packet use the same id
uint32_t payload_len; // total bytes of payload of this command packet (the data in the range will sent in ONE 'write'),
// big data can be described in payload and independent communication, and this field should not include them.
// if encrypted packet, this field is the length after encrypting
char payload[0]; // payloads, according to 'cmd'
STRUCT_CONSTRUCTOR(_pack_base)
}PACK_BASE, * LPPACK_BASE;
#define BASE_PACKET_REPLY(reply, command, id, err) \
(reply).encrypt = 0; \
(reply).enc_data = 0; \
(reply).size = sizeof(reply); \
(reply).data = err; \
(reply).cmd = command; \
(reply).pack_id = id; \
(reply).payload_len = 0;
typedef struct _config_val
{
uint8_t type; // same as SANE_Value_Type
uint8_t name_off; // name offset of the option in data, end with '\0'
uint8_t val_off; // option value offset in data
uint8_t after_do; // see SANE_INFO_xxx in sane.h
uint16_t val_size; // real size of value
uint16_t max_size; // max size of this option, this value has given in gb_json::size
char data[0]; // contains value and name. fetch them according name_off and val_off members.
}CFGVAL, *LPCFGVAL;
typedef struct _img_pos
{
uint64_t paper_ind : 32; // paper index in this turn/start, based ZERO. (image-collector set)
uint64_t new_img : 1; // 0 - partial data; 1 - new image data. (image-collector set)
uint64_t img_over : 1; // 0 - has data yet; 1 - END for the image. (image-collector set)
uint64_t paper_side : 3; // enum paper_side. front of paper(When scanning multiple sheets, the paper feeding side is the front side). (image-collector set)
uint64_t back_rot : 2; // back rotation angle, enum rot_angle. (image-collector set)
uint64_t channel_ind : 4; // index of color channel, enum clr_channel. (image-collector set)
uint64_t status : 7; // img_status. (image-collector set)
uint64_t split_ind : 7; // splitting order, from left to right and then top to bottom, based ZERO
uint64_t multiout_ind : 4; // index of multi-out
uint64_t reserved : 3; // reserved
STRUCT_CONSTRUCTOR(_img_pos)
}IMGPOS, * LPIMGPOS;
typedef struct _pack_img
{
IMGPOS pos; // image pos info ...
uint32_t width; // image width in pixel. (image-collector set)
uint32_t height; // image height in pixel. (image-collector set)
uint32_t resolution_x; // image horizontal reolution. (image-collector set)
uint32_t resolution_y; // image vertical reolution. (image-collector set)
uint32_t channels : 6; // image channels per pixel. (image-collector set)
uint32_t format : 6; // image format, see 'img_format'. (image-collector set)
uint32_t bpp : 6; // bits per pixel. (image-collector set)
uint32_t bppc : 6; // bits per pixel in this channel, equal to 'bpp' if pos.channel_ind == 0x0f. (image-collector set)
uint32_t compression : 6; // image data compression, see 'img_compression'. (image-collector set)
uint32_t reserve : 2; // unused now
uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set)
uint64_t data_size; // image data size in 'data' with bytes. (image-collector set)
// char data[0]; // two parts: image info (info_size) + image data (data_size)
STRUCT_CONSTRUCTOR(_pack_img)
}PACKIMAGE, * LPPACKIMAGE;
typedef struct _oper_token
{
uint32_t type; // token type
char data[128]; // token data
}OPERTOKEN, * LPOPERTOKEN;
typedef struct _tx_file
{
uint64_t size; // total size
uint64_t offset; // offset in the file
char path[2]; // file full path-name
}TXFILE, *LPTXFILE;
typedef struct _file_info
{
OPERTOKEN token; // operation token, returned by command PACK_CMD_TOKEN_GET
uint64_t size; // file size
uint16_t name_len; // bytes of file name string
uint16_t create_time_len; // bytes of create time string: '2022-12-07 12:34:56.789', or target file path in command PACK_CMD_FILE_MOVE
uint16_t modify_time_len;
uint16_t version_len; // bytes of version string
char data[0]; // 4 parts: path-file(name_len) + create-time(create_time_len) + modify-time(modify_time_len) + version(version_len)
// or 5 parts in command PACK_CMD_FILE_WRITE, add content at the last part of bytes 'size'
STRUCT_CONSTRUCTOR(_file_info)
}FILEINFO, * LPFILEINFO;
typedef struct _proc_info
{
OPERTOKEN token; // operation token, returned by command PACK_CMD_TOKEN_GET
uint32_t count; // number of elements in array proc
struct _info
{
uint16_t len; // bytes of this element, include this head
uint64_t pid; // process id
uint64_t ppid; // parent process id
uint64_t start; // started time in ns from 1970-01-01 00:00:00
uint64_t mem; // memory usage, in bytes
uint64_t cpu_clk; // cpu clock
char path_name[4];
}proc[1];
STRUCT_CONSTRUCTOR(_proc_info)
}PROCINFO, * LPPROCINFO;
#pragma pack(pop)
////////////////////////////////////////////////////////////////////////////////////////////////
// configurations ...
//
// 1 - App has whole set, group definitions
//
// 2 - device provides sub-set, or a customizing item
//

View File

@ -973,7 +973,7 @@ namespace utils
{
int ret = 0;
#if defined(WIN32) || defined(_WIN64)
#if OS_WIN
ULARGE_INTEGER av = { 0 },
all = { 0 };
if (GetDiskFreeSpaceExA(path, &av, &all, NULL))
@ -1019,7 +1019,7 @@ namespace utils
unsigned int get_page_size(unsigned int* map_unit)
{
unsigned int ps = 1024;
#if defined(WIN32) || defined(_WIN64)
#if OS_WIN
SYSTEM_INFO si = { 0 };
GetSystemInfo(&si);
@ -1123,6 +1123,210 @@ namespace utils
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// base64 util ..
static char base64_default_table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
base64::base64() : padding_char_('=')
{
base64_ind_[0] = base64_char_[0] = 0;
initialize_base64_table(base64_default_table);
}
base64::~base64()
{}
bool base64::is_valid_base64_table(const char* table)
{
bool valid = false;
if (table && strlen(table) >= 64)
{
char repeat[4] = { 0 };
valid = true;
for (int i = 0; i < 63; ++i)
{
repeat[0] = table[i];
if (strstr(table + i + 1, repeat))
{
valid = false;
break;
}
}
}
return valid;
}
bool base64::initialize_base64_table(const char* table)
{
if (!table || strlen(table) < 64)
{
if (memcmp(base64_default_table, base64_char_, 64) == 0)
{
return !table;
}
memcpy(base64_char_, base64_default_table, 64);
}
else
{
if (memcmp(base64_char_, table, 64) == 0)
{
return true;
}
else if (!is_valid_base64_table(table))
return false;
memcpy(base64_char_, table, 64);
}
base64_char_[64] = base64_char_[65] = 0;
// initialize base64_index
memset(base64_ind_, 0, sizeof(base64_ind_));
for (int i = 0; i < 64; ++i)
{
base64_ind_[base64_char_[i]] = i;
}
// padding char
padding_char_ = '=';
if (base64_ind_[padding_char_])
{
for (padding_char_ = 0x21; padding_char_ < 0x7e && base64_ind_[padding_char_] && padding_char_ != base64_char_[0]; ++padding_char_);
}
return padding_char_ < 0x7e;
}
bool base64::set_base64_table(const char* table)
{
return initialize_base64_table(table ? table : base64_default_table);
}
std::string base64::encode(const char* data, size_t bytes, unsigned int line_bytes, bool need_padding)
{
char* str = (char*)malloc(bytes * 2 + 3);
unsigned char c1 = 0, c2 = 0, c3 = 0;
unsigned long line_len = 0;
unsigned long words = bytes / 3;
int rest = bytes % 3,
pos = 0;
std::string ret("");
for (unsigned long i = 0; i < words; ++i)
{
// fetch 3 letters
c1 = *data++;
c2 = *data++;
c3 = *data++;
// encoding into 4-bytes
str[pos++] = base64_char_[c1 >> 2];
str[pos++] = base64_char_[((c1 << 4) | (c2 >> 4)) & 0x3f];
str[pos++] = base64_char_[((c2 << 2) | (c3 >> 6)) & 0x3f];
str[pos++] = base64_char_[c3 & 0x3f];
line_len += 4;
// new line ...
if ((unsigned int)line_len > line_bytes - 4)
{
str[pos++] = '\r';
str[pos++] = '\n';
line_len = 0;
}
}
// rest ...
if (rest == 1)
{
c1 = *data++;
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
str[pos++] = base64_char_[((c1 & 0x03) << 4)];
if (need_padding)
{
str[pos++] = padding_char_;
str[pos++] = padding_char_;
}
}
else if (rest == 2)
{
c1 = *data++;
c2 = *data++;
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
str[pos++] = base64_char_[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
str[pos++] = base64_char_[((c2 & 0x0f) << 2)];
if (need_padding)
{
str[pos++] = padding_char_;
}
}
if (pos > 0)
{
str[pos++] = 0;
ret = std::string(str, pos - 1);
}
free(str);
return ret;
}
std::string base64::decode(const char* data, size_t bytes)
{
char* str = (char*)malloc(bytes + 1);
int pos = 0,
shifts = 18,
value = 0;
std::string ret("");
for (int i = 0; i < (int)bytes; ++i)
{
if (*data != '\r' && *data != '\n')
{
if (*data == padding_char_)
{
break;
}
value += base64_ind_[*data] << shifts;
if (shifts == 0)
{
shifts = 18;
str[pos++] = (value >> 16) & 0x0ff;
str[pos++] = (value >> 8) & 0x0ff;
str[pos++] = (value >> 0) & 0x0ff;
value = 0;
}
else
{
shifts -= 6;
}
}
data++;
}
if (shifts == 12 || shifts == 6)
{
str[pos++] = (value >> 16) & 0x0ff;
}
else if (shifts == 0)
{
str[pos++] = (value >> 16) & 0x0ff;
str[pos++] = (value >> 8) & 0x0ff;
}
if (pos > 0)
{
str[pos++] = 0;
ret = std::string(str, pos - 1);
}
free(str);
return ret;
}
};
@ -1261,3 +1465,346 @@ void chronograph::reset()
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// event
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// windows event ...
#if OS_WIN
int __stdcall sem_init(sem_t* handle, int, int)
{
if (!handle)
{
errno = EINVAL;
return -1;
}
*handle = CreateEvent(NULL, TRUE, FALSE, NULL);
if (*handle)
return 0;
else
{
errno = GetLastError();
return -1;
}
}
void __stdcall sem_destroy(sem_t* handle)
{
if (*handle)
{
CloseHandle(*handle);
*handle = NULL;
}
}
int __stdcall sem_trywait(sem_t* handle)
{
return WaitForSingleObject(*handle, 1) == WAIT_TIMEOUT ? -1 : 0;
}
void __stdcall sem_wait(sem_t* handle)
{
if (WaitForSingleObject(*handle, INFINITE) == WAIT_OBJECT_0)
ResetEvent(*handle);
}
int __stdcall sem_timedwait(sem_t* handle, struct timespec* to)
{
DWORD elapse = to->tv_sec * 1000;
elapse += to->tv_nsec / (1000 * 1000);
int ret = WaitForSingleObject(*handle, elapse) == WAIT_TIMEOUT ? -1 : 0;
if (ret == 0)
ResetEvent(*handle);
return ret;
}
void __stdcall sem_post(sem_t* handle)
{
SetEvent(*handle);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// platform_event (base on semaphore)
platform_event::platform_event(const char* info) : waiting_(false), dbg_info_(info ? info : "")
{
int err = sem_init(&sem_, 0, 0);
if (err == -1)
{
err = errno;
utils::to_log(LOG_LEVEL_FATAL, "(%p)sem_init failed: %d\n", this, err);
}
}
platform_event::~platform_event()
{
sem_destroy(&sem_);
}
bool platform_event::try_wait(void)
{
return sem_trywait(&sem_) == 0;
}
bool platform_event::wait(unsigned timeout)
{
bool waited = true;
utils::to_log(LOG_LEVEL_DEBUG, "platform_event(%p - %s) --> waiting...\n", this, dbg_info_.c_str());
waiting_ = true;
if (timeout == USB_TIMEOUT_INFINITE)
sem_wait(&sem_);
else
{
struct timespec to;
to.tv_sec = timeout / 1000;
to.tv_nsec = (long)((timeout % 1000) * 1000 * 1000);
waited = sem_timedwait(&sem_, &to) == 0;
}
utils::to_log(LOG_LEVEL_DEBUG, "platform_event(%p - %s) --> %s.\n", this, dbg_info_.c_str(), waited ? "waited" : "wait timeout");
waiting_ = false;
return waited;
}
void platform_event::trigger(void)
{
sem_post(&sem_);
}
bool platform_event::is_waiting(void)
{
return waiting_;
}
void platform_event::set_debug_info(const char* info)
{
dbg_info_ = info ? info : "";
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// shared_memory
shared_memory::shared_memory(unsigned long long key, size_t size) : key_(key), obj_((void*)-1), first_(true), bytes_(size), len_(0)
{
unsigned int* ptr = (unsigned int*)&key_;
utils::to_log(LOG_LEVEL_DEBUG, "shared memory key = 0x%x%08x\n", ptr[1], ptr[0]);
init();
}
shared_memory::~shared_memory()
{
clear();
}
void shared_memory::init(void)
{
#if OS_WIN
char name[40] = { 0 };
DWORD* key = (DWORD*)&key_;
HANDLE h = NULL;
sprintf(name, "scanner_0x%08x-%08x", key[1], key[0]);
h = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, bytes_, name);
if (h == NULL)
return;
first_ = !(GetLastError() == ERROR_ALREADY_EXISTS);
obj_ = (void*)h;
#else
int obj = shmget(key_, bytes_, IPC_EXCL | IPC_CREAT | 0666);
if (obj < 0)
{
unsigned int* v = (unsigned int*)&key_;
if (errno == EEXIST)
{
first_ = false;
obj = shmget(key_, bytes_, 0600);
if (obj == -1)
obj = shmget(key_, bytes_, 0);
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "open existing: shmget(0x%x%08x) = %d\n", v[1], v[0], obj);
obj_ = (void*)obj;
std::string prev(read()), proc("");
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "shared memory content: %s\n", prev.c_str());
if (prev.length())
{
proc = prev;
size_t pos = proc.find("pid: ");
if (pos != std::string::npos)
proc.erase(0, pos + 5);
pos = proc.find(")");
if (pos != std::string::npos)
proc.erase(pos);
proc = shared_memory::get_proc_name_by_pid(atoi(proc.c_str()));
if (proc.length())
{
pos = prev.find("(");
if (pos == std::string::npos)
pos = prev.length();
if (strcasecmp(proc.c_str(), prev.substr(0, pos).c_str()))
proc = "";
}
}
if (proc.empty())
{
first_ = true;
clear();
obj = shmget(key_, bytes_, IPC_EXCL | IPC_CREAT | 0600);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s is not existing and reopen it\n", prev.c_str());
}
}
else
{
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shmget(0x%x%08x) = %d\n", v[1], v[0], errno);
return;
}
}
obj_ = (void*)obj;
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "shared memory id = %d[%s], \n", obj, first_ ? "created" : "opened");
#endif
if (first_)
{
pid_t pid = getpid();
std::string me("");
char buf[40] = { 0 };
unsigned int* pn = (unsigned int*)&pid;
if (sizeof(pid) > 4 && pn[1])
sprintf(buf, "(pid: 0x%x%08x)", pn[1], pn[0]);
else
sprintf(buf, "(pid: %u)", pn[0]);
me = utils::get_module_full_path();
pid = me.rfind(PATH_SEPARATOR[0]);
if ((size_t)pid != std::string::npos)
me.erase(0, pid + 1);
me += buf;
write(me.c_str(), me.length());
}
}
void shared_memory::clear(void)
{
if (obj_ != (void*)-1)
#if OS_WIN
CloseHandle((HANDLE)obj_);
#else
{
if (first_)
{
struct shmid_ds ds = { 0 };
int* h = (int*)&obj_;
shmctl(*h, IPC_RMID, &ds);
}
}
#endif
obj_ = (void*)-1;
}
char* shared_memory::get_buf(void)
{
#if OS_WIN
char* buf = (char*)MapViewOfFile((HANDLE)obj_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (!buf)
buf = (char*)-1;
#else
int* h = (int*)&obj_;
char* buf = (char*)shmat(*h, 0, 0);
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shared memory %d buffer = %s, error = %d\n", *h, hg_log::format_ptr(buf).c_str(), errno);
#endif
return buf;
}
void shared_memory::release_buf(void* buf)
{
#if OS_WIN
UnmapViewOfFile(buf);
#else
shmdt(buf);
#endif
}
#if !OS_WIN
std::string shared_memory::get_proc_name_by_pid(pid_t pid)
{
char path[512] = { 0 };
unsigned int* v = (unsigned int*)&pid;
std::string ret("");
if (sizeof(pid) > 4 && v[1])
sprintf(path, "/proc/%lld/status", pid);
else
sprintf(path, "/proc/%u/status", pid);
FILE* src = fopen(path, "rb");
if (src)
{
char val[512] = { 0 };
memset(path, 0, sizeof(path));
fgets(path, sizeof(path) - 1, src);
fclose(src);
sscanf(path, "%*s %s", val);
ret = val;
}
if (sizeof(pid) > 4 && v[1])
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "PID(%lld) name is: %s\n", pid, ret.c_str());
}
else
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "PID(%u) name is: %s\n", pid, ret.c_str());
}
return ret;
}
#endif
bool shared_memory::is_ok(void)
{
return obj_ != (void*)-1;
}
bool shared_memory::is_first(void)
{
return is_ok() && first_;
}
std::string shared_memory::read(void)
{
if (obj_ == (void*)-1)
return "";
char* buf = get_buf();
if (buf == (char*)-1)
return "";
std::string ret("");
size_t len = 0;
int off = 4; // sizeof(size_t);
memcpy(&len, buf, off);
ret = std::string(buf + off, len);
release_buf(buf);
return ret;
}
int shared_memory::write(const char* data, size_t len)
{
if (len > bytes_)
return E2BIG;
char* buf = get_buf();
int off = 4; // sizeof(len);
if (buf == (char*)-1)
return errno;
memcpy(buf, &len, off);
memcpy(buf + off, data, len);
len_ = len;
release_buf(buf);
return 0;
}

View File

@ -9,6 +9,10 @@
#include <string>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>
#include <algorithm>
#include <deque>
enum log_type
{
@ -87,6 +91,40 @@ namespace utils
log_api(buf.get(), (log_level)level);
}
}
template<class T>
T swap_half(T v)
{
T mask = (1 << (sizeof(T) * 4)) - 1,
h = v & mask;
v >>= sizeof(T) * 4;
v &= mask;
h <<= sizeof(T) * 4;
v |= h;
return v;
}
class base64
{
char base64_ind_[128];
char base64_char_[80];
char padding_char_;
bool is_valid_base64_table(const char* table);
bool initialize_base64_table(const char* table);
public:
base64();
~base64();
public:
bool set_base64_table(const char* table = nullptr);
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
std::string decode(const char* data, size_t bytes);
};
};
#if OS_WIN
@ -153,3 +191,125 @@ public:
uint64_t elapse_us(void);
void reset(void);
};
// event
class platform_event : public refer
{
sem_t sem_;
volatile bool waiting_;
std::string dbg_info_;
public:
platform_event(const char* info = "");
~platform_event();
public:
bool try_wait(void);
bool wait(unsigned timeout = USB_TIMEOUT_INFINITE/*ms*/); // USB_TIMEOUT_INFINITE is waiting unfinite, true when watied and false for wait timeout
void trigger(void);
bool is_waiting(void);
void set_debug_info(const char* info);
};
// share memory
class shared_memory : public refer
{
unsigned long long key_;
void* obj_;
bool first_;
size_t bytes_;
size_t len_;
void init(void);
void clear(void);
char* get_buf(void);
void release_buf(void* buf);
#if !defined(WIN32) && !defined(_WIN64)
static std::string get_proc_name_by_pid(pid_t pid);
#endif
public:
shared_memory(unsigned long long key, size_t size = 1024);
protected:
~shared_memory();
public:
bool is_ok(void);
bool is_first(void);
std::string read(void);
int write(const char* data, size_t len);
};
template<class T>
class safe_fifo
{
MUTEX lock_;
std::deque<T> que_;
platform_event* wait_;
public:
safe_fifo() : wait_(new platform_event("fifo"))
{}
~safe_fifo()
{
wait_->release();
}
public:
size_t save(const T& t, bool notify = false)
{
SIMPLE_LOCK(lock_);
size_t cnt = que_.size();
que_.push_back(std::move(t));
if (notify)
wait_->trigger();
return cnt + 1;
}
bool take(T& t, bool wait = false)
{
if (wait && size() == 0)
{
wait_->wait();
}
{
SIMPLE_LOCK(lock_);
if (que_.size())
{
t = std::move(que_.front());
que_.pop_front();
return true;
}
else
{
return false;
}
}
}
size_t size(void)
{
SIMPLE_LOCK(lock_);
return que_.size();
}
void clear(void)
{
SIMPLE_LOCK(lock_);
que_.clear();
}
void trigger(void)
{
wait_->trigger();
}
};

View File

@ -11,32 +11,6 @@
#include <sane_opt_json/base_opt.h>
#include "../../hgdriver/3rdparty/opencv/include/opencv2/opencv.hpp"
enum paper_side
{
PAPER_SIDE_UNKNOWN = 0,
PAPER_SIDE_FRONT, // single side, this is front
PAPER_SIDE_BACK, // single side, this is back
PAPER_SIDE_TOP, // VERT-compound sides, and front side is at top
PAPER_SIDE_BOTTOM, // VERT-compound sides, and front side is at bottom
PAPER_SIDE_LEFT, // HORZ-compound sides, and front side is at left
PAPER_SIDE_RIGHT, // HORZ-compound sides, and front side is at right
PAPER_SIDE_DSP, // G100/200 DSP data
};
/*
enum img_status
{
IMG_STATUS_OK = 0, // normal
IMG_STATUS_DOUBLE = 1 << 0, // double-feeded paper
IMG_STATUS_JAM = 1 << 1, // jammed paper
IMG_STATUS_STAPLE = 1 << 2, // staples on the paper
IMG_STATUS_SIZE_ERR = 1 << 3, // size check failed
IMG_STATUS_DOGEAR = 1 << 4, // paper has dogear - common
IMG_STATUS_DOGEAR_PARTIAL = 1 << 5, // dogear - scanned partial
IMG_STATUS_BLANK = 1 << 6, // blank image
};
*/
#pragma pack(push)
#pragma pack(1)
typedef struct _hg_img_info

View File

@ -3,8 +3,8 @@
#include <json/gb_json.h>
#include <sane_opt_json/device_opt.h>
#include "../../../sdk/include/huagao/hgscanner_error.h"
#include <ImageMatQueue.h>
#include <huagaoxxx_warraper_ex.h>
#include <base/huagaoxxx_warraper_ex.h>
#include <base/packet.h>
#include <imgproc-pak/fill_hole.h>
#include <imgproc-pak/multi_out.h>

View File

@ -9,7 +9,7 @@
// NOTE: the interface is for all algorithms are in ONE module
#include "img_processor.h"
#include <hginclude/utils.h> // for refer
#include <base/utils.h> // for refer
#include <vector>
typedef std::shared_ptr<std::vector<char>> dcptr;

View File

@ -7,8 +7,8 @@
#include <string>
#include <map>
#include <hginclude/utils.h> // for refer
#include "../../../sdk/include/sane/sane_ex.h"
#include <base/utils.h> // for refer
#include <sane/sane_ex.h>
class sane_opt_provider : public refer
{

View File

@ -1,7 +1,7 @@
#include "device_opt.h"
#include <huagao/hgscanner_error.h>
#include <hginclude/huagaoxxx_warraper_ex.h>
#include <base/huagaoxxx_warraper_ex.h>
#include "base_opt.h"
#include <lang/app_language.h>
#include <string.h>

View File

@ -16,7 +16,7 @@
#include "simple_logic.h"
#include <json/gb_json.h>
#include <hginclude/utils.h>
#include <base/utils.h>
class sane_opt_provider;

View File

@ -1002,11 +1002,18 @@ Result huagao_ds::identityOpenDs(const Identity& id)
if (double_check_mode_ == 0)
{
char pe[MAX_PATH] = { 0 }, * name = NULL;
std::string utf8("");
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
name = strrchr(pe, '\\');
if (name++ == NULL)
name = pe;
if (STRICMP(name, "\u597D\u5206\u6570\u9605\u5377\u626B\u63CF\u7AEF.exe") == 0)
#ifdef WIN32
utf8 = utils::ansi2utf8(name);
#else
utf8 = name;
#endif
if (STRICMP(utf8.c_str(), "\345\245\275\345\210\206\346\225\260\351\230\205\345\215\267\346\211\253\346\217\217\347\253\257.exe") == 0)
double_check_mode_ = DOUBLE_CHECK_ULTRASONIC;
else
double_check_mode_ = DOUBLE_CHECK_TWAIN;
@ -1017,11 +1024,18 @@ Result huagao_ds::identityOpenDs(const Identity& id)
if (nobd == -1)
{
char pe[MAX_PATH] = { 0 }, * name = NULL;
std::string utf8("");
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
name = strrchr(pe, '\\');
if (name++ == NULL)
name = pe;
if (STRICMP(name, "\u519B\u961F\u626B\u63CF2.0.exe") == 0) // 军队扫描2.0.exe
#ifdef WIN32
utf8 = utils::ansi2utf8(name);
#else
utf8 = name;
#endif
if (STRICMP(name, "\345\206\233\351\230\237\346\211\253\346\217\2172.0.exe") == 0) // 军队扫描2.0.exe
nobd = 1;
else
nobd = 0;

View File

@ -9,7 +9,7 @@
#include <string>
#include <thread>
#include "twpp.hpp"
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
#include "s2t_api.h"
namespace std {

View File

@ -1,6 +1,6 @@
#include "sane_helper.h"
#include "huagao/brand.h"
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
#include <string.h>

View File

@ -1,7 +1,7 @@
#include "scanned_img.h"
#include "sane_helper.h"
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
#include <string.h>

View File

@ -3,7 +3,7 @@
#include <vector>
#include <mutex>
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
class image_buf

View File

@ -13,7 +13,7 @@
#include <twain_user/twainui.h>
#include <huagao/brand.h>
#include "sane_helper.h"
#include "../../sdk/hginclude/utils.h"
#include <base/utils.h>
#define START_SCAN_IN_THREAD