re-construct
This commit is contained in:
parent
47e802669c
commit
8901ca1fdf
|
@ -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>
|
|
|
@ -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
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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 envelope(98 毫米 × 225 毫米).
|
|
||||||
// Number10Envelope #10 envelope(105 毫米 × 241 毫米).
|
|
||||||
// Number11Envelope #11 envelope(114 毫米 × 263 毫米).
|
|
||||||
// Number12Envelope #12 envelope(120 毫米 × 279 毫米).
|
|
||||||
// Number14Envelope #14 envelope(127 毫米 × 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 envelope(110 毫米 × 230 毫米).
|
|
||||||
// MonarchEnvelope Monarch envelope(98 毫米 × 191 毫米).
|
|
||||||
// PersonalEnvelope 6 3 / 4 envelope(92 毫米 × 165 毫米).
|
|
||||||
// USStandardFanfold US standard fanfold(378 毫米 × 279 毫米).
|
|
||||||
// GermanStandardFanfold German standard fanfold(216 毫米 × 305 毫米).
|
|
||||||
// GermanLegalFanfold German legal fanfold(216 毫米 × 330 毫米).
|
|
||||||
// IsoB4 ISO B4(250 毫米 × 353 毫米).
|
|
||||||
// JapanesePostcard Japanese postcard(100 毫米 × 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
|
@ -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
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
@ -1,557 +1,114 @@
|
||||||
#pragma once
|
// scanner business handler
|
||||||
|
|
||||||
// hg_scanner is the base class of kinds of scanners
|
|
||||||
//
|
//
|
||||||
// created on 2022-01-30
|
// created on 2023-03-27
|
||||||
//
|
//
|
||||||
#include <memory>
|
#pragma once
|
||||||
#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;
|
|
||||||
|
|
||||||
#include <sane_opt_json/base_opt.h>
|
#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
|
class hg_scanner : public sane_opt_provider
|
||||||
{
|
{
|
||||||
HGVersionMgr HGVersion_mgr_;
|
int status_;
|
||||||
SDKHGVersion_Init_ HGVersion_Init_;
|
std::string msg_;
|
||||||
SDKHGVersion_Islock_ HGVersion_Islock_;
|
ONLNSCANNER dev_;
|
||||||
SDKHGVersion_Postlog_ HGVersion_Postlog_;
|
device_option *dev_opts_ = nullptr;
|
||||||
SDKHGVersion_Free_ HGVersion_Free_;
|
imgproc_mgr *imgproc_ = nullptr;
|
||||||
#ifndef WIN32
|
shared_memory *singleton_ = nullptr;
|
||||||
void* Dynamicopen_HGVersion_pHandle_;;
|
scanner_handler *scanner_ = nullptr;
|
||||||
#else
|
hguser *user_ = nullptr;
|
||||||
HINSTANCE Dynamicopen_HGVersion_pHandle_;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool notify_setting_result_;
|
volatile bool cancelled_ = false;
|
||||||
std::string name_;
|
volatile bool run_ = true;
|
||||||
std::string family_;
|
safe_fifo<img_receiver*> raw_imgs_;
|
||||||
std::string save_multiout; //保存多留输出类型
|
safe_fifo<img_receiver*> final_imgs_;
|
||||||
bool save_sizecheck;
|
std::unique_ptr<std::thread> imgpr_thread_;
|
||||||
bool read_over_with_no_data_; // 针对第三方调用,在最后一段数据时是否返回“SCANNER_ERR_NO_DATA”
|
bool online_ = true;
|
||||||
int is_color_type_;//保存最后下发到设备的颜色类型
|
|
||||||
|
|
||||||
|
static shared_memory* create_device_singleton(int vid, int pid, int addr);
|
||||||
|
|
||||||
sane_callback ui_ev_cb_;
|
void init(void);
|
||||||
imgproc_mgr* img_processor_ = nullptr;
|
void thread_image_processor(void);
|
||||||
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:
|
public:
|
||||||
|
hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc = nullptr, hguser* user = nullptr, std::vector<sane_opt_provider*>* constopts = nullptr);
|
||||||
|
|
||||||
|
|
||||||
// 设置接口
|
|
||||||
protected:
|
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_; //需要删除父依赖项
|
|
||||||
|
|
||||||
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; // 多流输出
|
|
||||||
|
|
||||||
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; // 尺寸检测
|
|
||||||
|
|
||||||
bool save_feedmode_type_; //保存分支强度狀態
|
|
||||||
bool save_sleeptime_type_; //保存休眠時間
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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,此版本以下,不支持真实dpi,dpi设置1 //3288 G300 用到
|
|
||||||
bool firmware_sup_dpi_600; //固件支持 真实DPI600 139 239-21227,此版本以下,不支持真实dpi,dpi设置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’代表白色
|
|
||||||
|
|
||||||
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 status(void);
|
|
||||||
bool is_online(void);
|
|
||||||
|
|
||||||
enum thread_running
|
|
||||||
{
|
|
||||||
THREAD_RUNNING_IDLE = 0,
|
|
||||||
THREAD_RUNNING_USB = 1 << 0,
|
|
||||||
THREAD_RUNNING_IMAGE = 1 << 1,
|
|
||||||
};
|
|
||||||
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();
|
virtual ~hg_scanner();
|
||||||
|
|
||||||
static std::string temporary_file(char* tail = NULL, char* head = NULL);
|
// scanner operation ...
|
||||||
static int save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std::string* path_file, unsigned int index = 0);
|
|
||||||
public:
|
public:
|
||||||
|
int start(void);
|
||||||
//////////////固定的硬件信息设置或获取//////////////
|
int stop(void);
|
||||||
virtual std::string get_firmware_version(void);
|
int close(void);
|
||||||
virtual std::string get_serial_num(void);
|
int re_connect(void);
|
||||||
virtual std::string get_ip(void);
|
int get_image_info(SANE_Parameters* pii);
|
||||||
virtual std::string get_device_model(void);
|
int read_image_data(uint8_t* buf, size_t* len);
|
||||||
|
int status(void);
|
||||||
virtual int set_device_model(string str);
|
std::string status_message(void);
|
||||||
virtual int set_serial_num(string str) = 0; //设置序列号
|
bool is_online(void);
|
||||||
virtual int set_vid_pid(int data) = 0; //设置vidpid
|
device_option* get_device_opt(void);
|
||||||
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 ×); //获取设备时间 //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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// NEW,flow ...
|
|
||||||
//
|
|
||||||
// 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);
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <json/gb_json.h>
|
#include <json/gb_json.h>
|
||||||
#include <huagao/hgscanner_error.h>
|
#include <huagao/hgscanner_error.h>
|
||||||
#include <ImageApplyOutHole.h>
|
#include <ImageApplyOutHole.h>
|
||||||
|
#include <base/packet.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
};
|
|
@ -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(¶m, 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, ¶m);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
};
|
|
@ -1,140 +1,32 @@
|
||||||
#include "scanner_manager.h"
|
#include "scanner_manager.h"
|
||||||
|
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string.h>
|
#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/user.h"
|
||||||
#include "user-opt/offline_opt.h"
|
#include "user-opt/offline_opt.h"
|
||||||
#include <sane_opt_json/device_opt.h>
|
#include <sane_opt_json/device_opt.h>
|
||||||
#include <imgprc/imgprc_mgr.h>
|
#include <imgprc/imgprc_mgr.h>
|
||||||
|
|
||||||
|
|
||||||
#if !defined(WIN32) && !defined(_WIN64)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// kinds of scanners ...
|
// kinds of scanners ...
|
||||||
#define SCAN_PTR(ptr) ((hg_scanner*)ptr)
|
#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>
|
static struct _scanner_device
|
||||||
/// supporting devices :
|
|
||||||
///
|
|
||||||
#define GET_LANG(str,b) from_default_language(str,b)
|
|
||||||
static struct
|
|
||||||
{
|
{
|
||||||
uint16_t vid; // vendor ID
|
int vid;
|
||||||
uint16_t pid; // product ID
|
int pid;
|
||||||
std::string name; // product name - type
|
std::string family;
|
||||||
std::string family; // product model - family. In the TWAIN protocol, grouping is based on this value
|
std::string name;
|
||||||
std::string rsc; // USB resource, version-addr. e.g. "USB2.0-1"
|
} g_supporting_devices[] = { ALL_FAMILIES };
|
||||||
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>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// language option ...
|
// language option ...
|
||||||
|
@ -250,9 +142,14 @@ hg_scanner_mgr::~hg_scanner_mgr()
|
||||||
std::lock_guard<std::mutex> lock(mutex_dev_);
|
std::lock_guard<std::mutex> lock(mutex_dev_);
|
||||||
for (auto& v : online_devices_)
|
for (auto& v : online_devices_)
|
||||||
{
|
{
|
||||||
|
if (v.scanner)
|
||||||
|
{
|
||||||
|
v.scanner->close();
|
||||||
|
v.scanner->release();
|
||||||
|
v.scanner = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
libusb_unref_device(v.dev);
|
libusb_unref_device(v.dev);
|
||||||
if (v.dev_opts)
|
|
||||||
v.dev_opts->release();
|
|
||||||
}
|
}
|
||||||
online_devices_.clear();
|
online_devices_.clear();
|
||||||
}
|
}
|
||||||
|
@ -381,76 +278,6 @@ uint32_t hg_scanner_mgr::unique_id(int type)
|
||||||
return -1;
|
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
|
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;
|
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],
|
char model[40],
|
||||||
vendor[40];
|
vendor[40];
|
||||||
SANE_Device_Ex de;
|
SANE_Device_Ex de;
|
||||||
int ev_ui = 0;
|
int ev_ui = 0, addr = 0;
|
||||||
scanner_handle h = NULL;
|
scanner_handle h = NULL;
|
||||||
unsigned int len = sizeof(de);
|
unsigned int len = sizeof(de);
|
||||||
std::string name(""), type("");
|
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.family = NULL;
|
||||||
de.vendor = vendor;
|
de.vendor = vendor;
|
||||||
de.openned = SANE_FALSE;
|
de.openned = SANE_FALSE;
|
||||||
|
addr = libusb_get_device_address(device);
|
||||||
|
|
||||||
if (ev == USB_EVENT_DEVICE_ARRIVED)
|
if (ev == USB_EVENT_DEVICE_ARRIVED)
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1;
|
||||||
for (int i = 0; i < _countof(g_supporting_devices); ++i)
|
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)
|
if (g_supporting_devices[i].vid == vid && g_supporting_devices[i].pid == pid)
|
||||||
{
|
{
|
||||||
index = i;
|
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;
|
size_t i = 0;
|
||||||
for (; i < online_devices_.size(); ++i)
|
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;
|
add = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (add) // 澶勭悊瀵硅薄鈥渄evice鈥濇敼鍙樼殑鎯呮<E98EAF>?
|
if (add)
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto& v : online_devices_)
|
for (auto& v : online_devices_)
|
||||||
{
|
{
|
||||||
if (v.ind == index &&
|
if (v.scanner && !v.scanner->is_online())
|
||||||
(v.scanner && !v.scanner->is_online()))
|
|
||||||
{
|
{
|
||||||
add = false;
|
add = false;
|
||||||
break;
|
break;
|
||||||
|
@ -534,31 +363,30 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
|
||||||
|
|
||||||
if (add)
|
if (add)
|
||||||
{
|
{
|
||||||
OLSCANNER ols;
|
ONLNSCANNER ols;
|
||||||
|
|
||||||
|
ols.vid = vid;
|
||||||
|
ols.pid = pid;
|
||||||
|
ols.addr = addr;
|
||||||
ols.dev = device;
|
ols.dev = device;
|
||||||
ols.ind = index;
|
ols.scanner = nullptr;
|
||||||
ols.scanner = NULL;
|
ols.family = g_supporting_devices[index].family;
|
||||||
ols.dev_opts = nullptr;
|
ols.display_name = g_supporting_devices[index].name;
|
||||||
ols.imgproc = nullptr;
|
if (std::find(online_devices_.begin(), online_devices_.end(), ols.display_name.c_str()) != online_devices_.end())
|
||||||
ols.display_name = g_supporting_devices[ols.ind].name;
|
|
||||||
if (std::find(online_devices_.begin(), online_devices_.end(), ols.ind) != 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_
|
libusb_ref_device(ols.dev); // ref to the device of queue online_devices_
|
||||||
online_devices_.push_back(ols);
|
online_devices_.push_back(ols);
|
||||||
name = ols.display_name;
|
name = ols.display_name;
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "%s connected.\n", name.c_str());
|
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;
|
name = online_devices_[i].display_name;
|
||||||
type = g_supporting_devices[index].family;
|
type = g_supporting_devices[index].family;
|
||||||
if (online_devices_[i].dev)
|
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;
|
h = online_devices_[i].scanner;
|
||||||
if (pid == 0x300 || pid == 0x400)
|
if (pid == 0x300 || pid == 0x400)
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
len = usb_manager::instance()->open(device, &io);
|
//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());
|
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)
|
if (len == SCANNER_ERR_OK)
|
||||||
{
|
{
|
||||||
online_devices_[i].scanner->reset_io(io);
|
//online_devices_[i].scanner->reset_io(io);
|
||||||
de.openned = SANE_TRUE;
|
de.openned = SANE_TRUE;
|
||||||
}
|
}
|
||||||
if (io)
|
|
||||||
io->release();
|
|
||||||
add = false;
|
add = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ev == USB_EVENT_DEVICE_LEFT)
|
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())
|
if (it != online_devices_.end())
|
||||||
{
|
{
|
||||||
ev_ui = SANE_EVENT_DEVICE_LEFT;
|
ev_ui = SANE_EVENT_DEVICE_LEFT;
|
||||||
name = it->display_name;
|
name = it->display_name;
|
||||||
type = g_supporting_devices[it->ind].family;
|
type = it->family;
|
||||||
h = it->scanner;
|
h = it->scanner;
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "%s Dis-connected.\n", name.c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "%s Dis-connected.\n", name.c_str());
|
||||||
if (it->scanner)
|
if (!it->scanner)
|
||||||
it->scanner->io_disconnected();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
libusb_unref_device(it->dev); // unref the device of queue online_devices_
|
libusb_unref_device(it->dev); // unref the device of queue online_devices_
|
||||||
online_devices_.erase(it);
|
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);
|
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_);
|
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* hg_scanner_mgr::create_image_processor(device_option* devopts)
|
||||||
{
|
{
|
||||||
imgproc_mgr* proc = new imgproc_mgr(devopts, dump_img_, dump_img_path_.c_str());
|
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)
|
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;
|
long size = *count;
|
||||||
scanner_err ret = SCANNER_ERR_OK;
|
scanner_err ret = SCANNER_ERR_OK;
|
||||||
std::string g_vendor(from_default_language(COMPANY_NAME, nullptr));
|
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++)
|
for (size_t i = 0; i < devusbuf.size(); i++)
|
||||||
{
|
{
|
||||||
scanner_list->vid = g_supporting_devices[devusbuf[i].ind].vid;
|
scanner_list->vid = devusbuf[i].vid;
|
||||||
scanner_list->pid = g_supporting_devices[devusbuf[i].ind].pid;
|
scanner_list->pid = devusbuf[i].pid;
|
||||||
strcpy(scanner_list->name, devusbuf[i].display_name.c_str());
|
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->model, devusbuf[i].family.c_str());
|
||||||
strcpy(scanner_list->type, g_supporting_devices[devusbuf[i].ind].name.c_str());
|
|
||||||
strcpy(scanner_list->vendor, g_vendor.c_str());
|
strcpy(scanner_list->vendor, g_vendor.c_str());
|
||||||
scanner_list++;
|
scanner_list++;
|
||||||
}
|
}
|
||||||
|
@ -853,67 +502,31 @@ 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)
|
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<ONLNSCANNER>::iterator it;
|
||||||
std::vector<OLSCANNER>::iterator it;
|
|
||||||
usb_io* io = NULL;
|
|
||||||
scanner_err ret = SCANNER_ERR_DEVICE_NOT_FOUND;
|
scanner_err ret = SCANNER_ERR_DEVICE_NOT_FOUND;
|
||||||
|
SIMPLE_LOCK(mutex_dev_);
|
||||||
|
|
||||||
*h = NULL;
|
*h = NULL;
|
||||||
get_online_devices(devs);
|
it = std::find(online_devices_.begin(), online_devices_.end(), name);
|
||||||
it = std::find(devs.begin(), devs.end(), name);
|
if (it != online_devices_.end())
|
||||||
if (it != devs.end())
|
|
||||||
{
|
{
|
||||||
hg_scanner_mgr::last_open_msg_ = "";
|
std::vector<sane_opt_provider*> cnst;
|
||||||
ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_);
|
cnst.push_back(offline_);
|
||||||
if (ret == SCANNER_ERR_OK)
|
cnst.push_back(g_language);
|
||||||
|
|
||||||
|
it->scanner = new hg_scanner(&(*it), nullptr, user_, &cnst);
|
||||||
|
if (it->scanner->status() == 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);
|
*h = it->scanner;
|
||||||
|
}
|
||||||
if (scanner)
|
else
|
||||||
{
|
{
|
||||||
scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_);
|
ret = (scanner_err)it->scanner->status();
|
||||||
scanner->set_dev_family(g_supporting_devices[it->ind].family.c_str());
|
hg_scanner_mgr::last_open_msg_ = it->scanner->status_message();
|
||||||
scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_);
|
it->scanner->close();
|
||||||
}
|
it->scanner->release();
|
||||||
{
|
it->scanner = nullptr;
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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;
|
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)
|
if (v.scanner == h)
|
||||||
{
|
{
|
||||||
|
v.scanner->close(/*force*/);
|
||||||
|
v.scanner->release();
|
||||||
v.scanner = nullptr;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SCAN_PTR(h)->close(force);
|
|
||||||
SCAN_PTR(h)->release();
|
|
||||||
//delete SCAN_PTR(h);
|
|
||||||
|
|
||||||
return SCANNER_ERR_OK;
|
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)
|
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)
|
if (v.scanner == h)
|
||||||
{
|
{
|
||||||
tmp = v.dev_opts;
|
tmp = v.scanner->get_device_opt();
|
||||||
if (tmp)
|
|
||||||
tmp->add_ref();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1033,9 +632,7 @@ scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const cha
|
||||||
{
|
{
|
||||||
if (v.scanner == h)
|
if (v.scanner == h)
|
||||||
{
|
{
|
||||||
tmp = v.dev_opts;
|
tmp = v.scanner->get_device_opt();
|
||||||
if (tmp)
|
|
||||||
tmp->add_ref();
|
|
||||||
break;
|
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();
|
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
|
// 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)
|
//while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE)
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
// std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1144,8 +741,8 @@ scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned
|
||||||
if (!len)
|
if (!len)
|
||||||
return SCANNER_ERR_INVALID_PARAMETER;
|
return SCANNER_ERR_INVALID_PARAMETER;
|
||||||
|
|
||||||
int l = *len,
|
size_t l = *len,
|
||||||
err = SCAN_PTR(h)->read_image_data(data, &l);
|
err = SCAN_PTR(h)->read_image_data(data, &l);
|
||||||
|
|
||||||
*len = 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)
|
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)
|
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_DEVICE_NOT_SUPPORT;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hg_scanner_mgr::on_language_changed(void)
|
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_);
|
std::lock_guard<std::mutex> lock(mutex_dev_);
|
||||||
for (auto& v: online_devices_)
|
for (auto& v: online_devices_)
|
||||||
{
|
{
|
||||||
if (v.dev_opts)
|
if (v.scanner)
|
||||||
v.dev_opts->update_data(nullptr, nullptr, false);
|
{
|
||||||
|
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)
|
const char* hg_scanner_mgr::last_open_message(void)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
#include "usb_manager.h"
|
#include "usb_manager.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -42,32 +42,11 @@ class offline_opts;
|
||||||
class device_option;
|
class device_option;
|
||||||
class sane_opt_provider;
|
class sane_opt_provider;
|
||||||
class imgproc_mgr;
|
class imgproc_mgr;
|
||||||
|
struct _online_scanner;
|
||||||
|
|
||||||
class hg_scanner_mgr
|
class hg_scanner_mgr
|
||||||
{
|
{
|
||||||
typedef struct _online_scanner
|
std::vector<_online_scanner> online_devices_;
|
||||||
{
|
|
||||||
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::mutex mutex_dev_;
|
std::mutex mutex_dev_;
|
||||||
unsigned int same_ind_;
|
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
|
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 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 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);
|
imgproc_mgr* create_image_processor(device_option* devopts);
|
||||||
|
|
||||||
string cf_name;
|
string cf_name;
|
||||||
|
@ -126,15 +103,6 @@ public:
|
||||||
};
|
};
|
||||||
static uint32_t unique_id(int type = UNIQUE_ID_IMG);
|
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:
|
public:
|
||||||
scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only);
|
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);
|
scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
|
@ -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
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "usb_manager.h"
|
#include "usb_manager.h"
|
||||||
|
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ usb_manager::usb_manager() : run_(true)
|
||||||
usb_manager::~usb_manager()
|
usb_manager::~usb_manager()
|
||||||
{
|
{
|
||||||
run_ = false;
|
run_ = false;
|
||||||
wait_pnp_.notify();
|
wait_pnp_.trigger();
|
||||||
libusb_context* ctx = nullptr;
|
libusb_context* ctx = nullptr;
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if defined(WIN32) || defined(_WIN64)
|
||||||
ctx = context_;
|
ctx = context_;
|
||||||
|
@ -302,7 +301,7 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
|
||||||
if (ms > 1000)
|
if (ms > 1000)
|
||||||
{
|
{
|
||||||
pnp_events_.Put(pd, sizeof(pd));
|
pnp_events_.Put(pd, sizeof(pd));
|
||||||
wait_pnp_.notify();
|
wait_pnp_.trigger();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "huagao/hgscanner_error.h"
|
#include "huagao/hgscanner_error.h"
|
||||||
#include "BlockingQueue.h"
|
#include "BlockingQueue.h"
|
||||||
#include "hg_ipc.h"
|
#include <base/utils.h>
|
||||||
|
|
||||||
|
|
||||||
struct usb_dev
|
struct usb_dev
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <huagao/brand.h>
|
#include <huagao/brand.h>
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include <sane/sane_ex.h>
|
#include <sane/sane_ex.h>
|
||||||
#include <hginclude/utils.h>
|
#include <base/utils.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "../scanner_manager.h" // for version
|
#include "../scanner_manager.h" // for version
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
|
|
||||||
#include "../../../sdk/include/huagao/brand.h"
|
#include <huagao/brand.h>
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
#include "../hgdev/scanner_manager.h"
|
#include "../hgdev/scanner_manager.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include "../hgdev/common_setting.h"
|
#include <base/packet.h>
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if defined(WIN32) || defined(_WIN64)
|
||||||
#include <fileapi.h>
|
#include <fileapi.h>
|
||||||
|
@ -162,7 +162,27 @@ 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)
|
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);
|
//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)
|
scanner_err hg_scanner_close(scanner_handle h, bool force)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "sane_hg_mdw.h"
|
#include "sane_hg_mdw.h"
|
||||||
|
|
||||||
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h" // for log-api
|
#include <base/huagaoxxx_warraper_ex.h> // for log-api
|
||||||
#include "../sdk/hginclude/utils.h" // for log-level
|
#include <base/utils.h> // for log-level
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SANE API entrance ...
|
/// SANE API entrance ...
|
||||||
|
|
|
@ -19,12 +19,13 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../../sdk/include/sane/sane_option_definitions.h"
|
#include <sane/sane_option_definitions.h>
|
||||||
#include "sane_option.h"
|
#include "sane_option.h"
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include "../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
#include <huagao/brand.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
|
#ifndef SIGUSR1
|
||||||
#define SIGUSR1 10
|
#define SIGUSR1 10
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sane/sane_ex.h"
|
#include "sane/sane_ex.h"
|
||||||
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
|
@ -167,7 +167,7 @@ typedef struct _device
|
||||||
// 参考命名:名称+资源,如“HG200 USB1”
|
// 参考命名:名称+资源,如“HG200 USB1”
|
||||||
char vendor[MAX_NAME_LEN]; // 设备制造商
|
char vendor[MAX_NAME_LEN]; // 设备制造商
|
||||||
char model[MAX_NAME_LEN]; // model name - family
|
char model[MAX_NAME_LEN]; // model name - family
|
||||||
char type[MAX_NAME_LEN]; // device type
|
//char type[MAX_NAME_LEN]; // device type
|
||||||
}ScannerInfo;
|
}ScannerInfo;
|
||||||
|
|
||||||
// hg_scanner_control 控制码及参数
|
// hg_scanner_control 控制码及参数
|
|
@ -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
|
||||||
|
//
|
|
@ -973,7 +973,7 @@ namespace utils
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if OS_WIN
|
||||||
ULARGE_INTEGER av = { 0 },
|
ULARGE_INTEGER av = { 0 },
|
||||||
all = { 0 };
|
all = { 0 };
|
||||||
if (GetDiskFreeSpaceExA(path, &av, &all, NULL))
|
if (GetDiskFreeSpaceExA(path, &av, &all, NULL))
|
||||||
|
@ -1019,7 +1019,7 @@ namespace utils
|
||||||
unsigned int get_page_size(unsigned int* map_unit)
|
unsigned int get_page_size(unsigned int* map_unit)
|
||||||
{
|
{
|
||||||
unsigned int ps = 1024;
|
unsigned int ps = 1024;
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if OS_WIN
|
||||||
SYSTEM_INFO si = { 0 };
|
SYSTEM_INFO si = { 0 };
|
||||||
|
|
||||||
GetSystemInfo(&si);
|
GetSystemInfo(&si);
|
||||||
|
@ -1123,6 +1123,210 @@ namespace utils
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
enum log_type
|
enum log_type
|
||||||
{
|
{
|
||||||
|
@ -87,6 +91,40 @@ namespace utils
|
||||||
log_api(buf.get(), (log_level)level);
|
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
|
#if OS_WIN
|
||||||
|
@ -153,3 +191,125 @@ public:
|
||||||
uint64_t elapse_us(void);
|
uint64_t elapse_us(void);
|
||||||
void reset(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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,32 +11,6 @@
|
||||||
#include <sane_opt_json/base_opt.h>
|
#include <sane_opt_json/base_opt.h>
|
||||||
#include "../../hgdriver/3rdparty/opencv/include/opencv2/opencv.hpp"
|
#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(push)
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
typedef struct _hg_img_info
|
typedef struct _hg_img_info
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include <json/gb_json.h>
|
#include <json/gb_json.h>
|
||||||
#include <sane_opt_json/device_opt.h>
|
#include <sane_opt_json/device_opt.h>
|
||||||
#include "../../../sdk/include/huagao/hgscanner_error.h"
|
#include "../../../sdk/include/huagao/hgscanner_error.h"
|
||||||
#include <ImageMatQueue.h>
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
#include <huagaoxxx_warraper_ex.h>
|
#include <base/packet.h>
|
||||||
|
|
||||||
#include <imgproc-pak/fill_hole.h>
|
#include <imgproc-pak/fill_hole.h>
|
||||||
#include <imgproc-pak/multi_out.h>
|
#include <imgproc-pak/multi_out.h>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// NOTE: the interface is for all algorithms are in ONE module
|
// NOTE: the interface is for all algorithms are in ONE module
|
||||||
|
|
||||||
#include "img_processor.h"
|
#include "img_processor.h"
|
||||||
#include <hginclude/utils.h> // for refer
|
#include <base/utils.h> // for refer
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef std::shared_ptr<std::vector<char>> dcptr;
|
typedef std::shared_ptr<std::vector<char>> dcptr;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <hginclude/utils.h> // for refer
|
#include <base/utils.h> // for refer
|
||||||
#include "../../../sdk/include/sane/sane_ex.h"
|
#include <sane/sane_ex.h>
|
||||||
|
|
||||||
class sane_opt_provider : public refer
|
class sane_opt_provider : public refer
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "device_opt.h"
|
#include "device_opt.h"
|
||||||
|
|
||||||
#include <huagao/hgscanner_error.h>
|
#include <huagao/hgscanner_error.h>
|
||||||
#include <hginclude/huagaoxxx_warraper_ex.h>
|
#include <base/huagaoxxx_warraper_ex.h>
|
||||||
#include "base_opt.h"
|
#include "base_opt.h"
|
||||||
#include <lang/app_language.h>
|
#include <lang/app_language.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#include "simple_logic.h"
|
#include "simple_logic.h"
|
||||||
#include <json/gb_json.h>
|
#include <json/gb_json.h>
|
||||||
#include <hginclude/utils.h>
|
#include <base/utils.h>
|
||||||
|
|
||||||
class sane_opt_provider;
|
class sane_opt_provider;
|
||||||
|
|
||||||
|
|
|
@ -1001,12 +1001,19 @@ Result huagao_ds::identityOpenDs(const Identity& id)
|
||||||
double_check_mode_ = get_config_number("twain-app", "double-check");
|
double_check_mode_ = get_config_number("twain-app", "double-check");
|
||||||
if (double_check_mode_ == 0)
|
if (double_check_mode_ == 0)
|
||||||
{
|
{
|
||||||
char pe[MAX_PATH] = { 0 }, * name = NULL;
|
char pe[MAX_PATH] = { 0 }, * name = NULL;
|
||||||
|
std::string utf8("");
|
||||||
|
|
||||||
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
|
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
|
||||||
name = strrchr(pe, '\\');
|
name = strrchr(pe, '\\');
|
||||||
if (name++ == NULL)
|
if (name++ == NULL)
|
||||||
name = pe;
|
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;
|
double_check_mode_ = DOUBLE_CHECK_ULTRASONIC;
|
||||||
else
|
else
|
||||||
double_check_mode_ = DOUBLE_CHECK_TWAIN;
|
double_check_mode_ = DOUBLE_CHECK_TWAIN;
|
||||||
|
@ -1017,11 +1024,18 @@ Result huagao_ds::identityOpenDs(const Identity& id)
|
||||||
if (nobd == -1)
|
if (nobd == -1)
|
||||||
{
|
{
|
||||||
char pe[MAX_PATH] = { 0 }, * name = NULL;
|
char pe[MAX_PATH] = { 0 }, * name = NULL;
|
||||||
|
std::string utf8("");
|
||||||
|
|
||||||
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
|
GetModuleFileNameA(NULL, pe, _countof(pe) - 1);
|
||||||
name = strrchr(pe, '\\');
|
name = strrchr(pe, '\\');
|
||||||
if (name++ == NULL)
|
if (name++ == NULL)
|
||||||
name = pe;
|
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;
|
nobd = 1;
|
||||||
else
|
else
|
||||||
nobd = 0;
|
nobd = 0;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "twpp.hpp"
|
#include "twpp.hpp"
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
#include "s2t_api.h"
|
#include "s2t_api.h"
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "sane_helper.h"
|
#include "sane_helper.h"
|
||||||
#include "huagao/brand.h"
|
#include "huagao/brand.h"
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "scanned_img.h"
|
#include "scanned_img.h"
|
||||||
|
|
||||||
#include "sane_helper.h"
|
#include "sane_helper.h"
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
|
|
||||||
|
|
||||||
class image_buf
|
class image_buf
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <twain_user/twainui.h>
|
#include <twain_user/twainui.h>
|
||||||
#include <huagao/brand.h>
|
#include <huagao/brand.h>
|
||||||
#include "sane_helper.h"
|
#include "sane_helper.h"
|
||||||
#include "../../sdk/hginclude/utils.h"
|
#include <base/utils.h>
|
||||||
|
|
||||||
#define START_SCAN_IN_THREAD
|
#define START_SCAN_IN_THREAD
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue