diff --git a/docs/sane-opts/hardware.txt b/docs/sane-opts/hardware.txt index 07ebe33..d71ea47 100644 --- a/docs/sane-opts/hardware.txt +++ b/docs/sane-opts/hardware.txt @@ -1,31 +1,47 @@ { - "mode": { + "cis-mode": { "cat": "none", "group": "CIS", - "title": "颜色模式", + "title": "CIS颜色模式", "desc": "选择镜头色彩工作模式", "type": "string", - "fix-id": 34819, "ui-pos": 10, "auth": 0, + "bind": true, "size": 12, - "cur": "彩色", - "default": "彩色", + "default": { + "(mode.enabled&&(mode==256级灰度||mode==黑白)) || (multiout-type.enabled&&multiout-type==灰度+黑白)": "灰度", + "default": "彩色" + }, "range": ["彩色", "灰度"] }, - "resolution": { + "cis-dpi": { "cat": "none", "group": "CIS", - "title": "分辨率", + "title": "CIS分辨率", "desc": "设置镜头工作的分辨率", "type": "int", - "fix-id": 34840, "ui-pos": 11, "auth": 0, + "bind": true, "size": 4, - "cur": 200, - "default": 200, - "range": [200, 300, 600] + "default": { + "resolution>400": 600, + "default": 300 + }, + "range": [300, 600] + }, + "cis-led": { + "cat": "none", + "group": "CIS", + "title": "CIS灯", + "desc": "CIS工作时,是否打开背景灯", + "type": "bool", + "ui-pos": 12, + "auth": 0, + "size": 4, + "cur": true, + "default": true }, "paper": { "cat": "base", @@ -34,7 +50,7 @@ "desc": "设置出图大小", "type": "string", "fix-id": 34831, - "ui-pos": 10, + "ui-pos": 30, "auth": 0, "size": 44, "cur": "匹配原始尺寸", @@ -54,7 +70,7 @@ "desc": "横向放置纸张", "type": "bool", "fix-id": 34924, - "ui-pos": 12, + "ui-pos": 31, "auth": 0, "affect": 6, "visible": 0, @@ -70,7 +86,7 @@ "desc": "以毫米为单位的纸张宽", "type": "float", "fix-id": 34922, - "ui-pos": 13, + "ui-pos": 32, "auth": 0, "unit": "mm", "readonly": true, @@ -88,7 +104,7 @@ "desc": "以毫米为单位的纸张高", "type": "float", "fix-id": 34923, - "ui-pos": 14, + "ui-pos": 33, "auth": 0, "unit": "mm", "readonly": true, @@ -421,11 +437,9 @@ "size": 8, "auto": false, "default": { - "mode==彩色 && resolution==300": 1.000000, - "mode==灰度 && resolution==300": 1.000000, - "mode==灰度 && resolution==200": 1.000000, - "mode==彩色 && resolution==600": 1.000000, - "mode==灰度 && resolution==600": 1.000000, + "cis-mode==灰度 && cis-dpi==300": 1.000000, + "cis-mode==彩色 && cis-dpi==600": 1.000000, + "cis-mode==灰度 && cis-dpi==600": 1.000000, "default": 1.000000 }, "range": { @@ -445,11 +459,9 @@ "size": 8, "auto": false, "default": { - "mode==彩色 && resolution==300": 1.000000, - "mode==灰度 && resolution==300": 1.000000, - "mode==灰度 && resolution==200": 1.000000, - "mode==彩色 && resolution==600": 1.000000, - "mode==灰度 && resolution==600": 1.000000, + "cis-mode==灰度 && cis-dpi==300": 1.000000, + "cis-mode==彩色 && cis-dpi==600": 1.000000, + "cis-mode==灰度 && cis-dpi==600": 1.000000, "default": 1.000000 }, "range": { @@ -466,15 +478,14 @@ "type": "int", "ui-pos": 42, "auth": 0, + "bind": true, "size": 4, "auto": false, "default": { - "mode==彩色 && resolution==300": 878, - "mode==灰度 && resolution==300": 2637, - "mode==灰度 && resolution==200": 2450, - "mode==彩色 && resolution==600": 1531, - "mode==灰度 && resolution==600": 4595, - "default": 816 + "cis-mode==灰度 && cis-dpi==300": 2637, + "cis-mode==彩色 && cis-dpi==600": 1531, + "cis-mode==灰度 && cis-dpi==600": 4595, + "default": 878 } }, "expo-fr": { @@ -488,12 +499,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 313, - "mode==灰度 && resolution==300": 336, - "mode==灰度 && resolution==200": 337, - "mode==彩色 && resolution==600": 622, - "mode==灰度 && resolution==600": 673, - "default": 312 + "cis-mode==灰度 && cis-dpi==300": 336, + "cis-mode==彩色 && cis-dpi==600": 622, + "cis-mode==灰度 && cis-dpi==600": 673, + "default": 313 }, "range": { "min": 1, @@ -512,12 +521,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 306, - "mode==灰度 && resolution==300": 336, - "mode==灰度 && resolution==200": 337, - "mode==彩色 && resolution==600": 611, - "mode==灰度 && resolution==600": 673, - "default": 305 + "cis-mode==灰度 && cis-dpi==300": 336, + "cis-mode==彩色 && cis-dpi==600": 611, + "cis-mode==灰度 && cis-dpi==600": 673, + "default": 306 }, "range": { "min": 1, @@ -536,12 +543,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 297, - "mode==灰度 && resolution==300": 336, - "mode==灰度 && resolution==200": 337, - "mode==彩色 && resolution==600": 590, - "mode==灰度 && resolution==600": 673, - "default": 295 + "cis-mode==灰度 && cis-dpi==300": 336, + "cis-mode==彩色 && cis-dpi==600": 590, + "cis-mode==灰度 && cis-dpi==600": 673, + "default": 297 }, "range": { "min": 1, @@ -560,11 +565,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 360, - "mode==灰度 && resolution==300": 410, - "mode==灰度 && resolution==200": 406, - "mode==彩色 && resolution==600": 713, - "mode==灰度 && resolution==600": 811, + "cis-mode==灰度 && cis-dpi==300": 410, + "cis-mode==彩色 && cis-dpi==600": 713, + "cis-mode==灰度 && cis-dpi==600": 811, "default": 360 }, "range": { @@ -584,12 +587,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 380, - "mode==灰度 && resolution==300": 410, - "mode==灰度 && resolution==200": 406, - "mode==彩色 && resolution==600": 758, - "mode==灰度 && resolution==600": 811, - "default": 379 + "cis-mode==灰度 && cis-dpi==300": 410, + "cis-mode==彩色 && cis-dpi==600": 758, + "cis-mode==灰度 && cis-dpi==600": 811, + "default": 380 }, "range": { "min": 1, @@ -608,12 +609,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 361, - "mode==灰度 && resolution==300": 410, - "mode==灰度 && resolution==200": 406, - "mode==彩色 && resolution==600": 722, - "mode==灰度 && resolution==600": 811, - "default": 360 + "cis-mode==灰度 && cis-dpi==300": 410, + "cis-mode==彩色 && cis-dpi==600": 722, + "cis-mode==灰度 && cis-dpi==600": 811, + "default": 361 }, "range": { "min": 1, @@ -632,11 +631,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -656,11 +653,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -680,11 +675,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -704,11 +697,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -728,11 +719,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -752,11 +741,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -776,11 +763,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -800,11 +785,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -824,11 +807,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -848,11 +829,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -872,11 +851,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -896,11 +873,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 170, - "mode==灰度 && resolution==300": 170, - "mode==灰度 && resolution==200": 170, - "mode==彩色 && resolution==600": 170, - "mode==灰度 && resolution==600": 170, + "cis-mode==灰度 && cis-dpi==300": 170, + "cis-mode==彩色 && cis-dpi==600": 170, + "cis-mode==灰度 && cis-dpi==600": 170, "default": 170 }, "range": { @@ -920,11 +895,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 113, - "mode==灰度 && resolution==300": 116, - "mode==灰度 && resolution==200": 116, - "mode==彩色 && resolution==600": 115, - "mode==灰度 && resolution==600": 116, + "cis-mode==灰度 && cis-dpi==300": 116, + "cis-mode==彩色 && cis-dpi==600": 115, + "cis-mode==灰度 && cis-dpi==600": 116, "default": 113 }, "range": { @@ -944,11 +917,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 118, - "mode==灰度 && resolution==300": 121, - "mode==灰度 && resolution==200": 119, - "mode==彩色 && resolution==600": 119, - "mode==灰度 && resolution==600": 121, + "cis-mode==灰度 && cis-dpi==300": 121, + "cis-mode==彩色 && cis-dpi==600": 119, + "cis-mode==灰度 && cis-dpi==600": 121, "default": 118 }, "range": { @@ -968,11 +939,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 118, - "mode==灰度 && resolution==300": 119, - "mode==灰度 && resolution==200": 121, - "mode==彩色 && resolution==600": 118, - "mode==灰度 && resolution==600": 121, + "cis-mode==灰度 && cis-dpi==300": 119, + "cis-mode==彩色 && cis-dpi==600": 118, + "cis-mode==灰度 && cis-dpi==600": 121, "default": 118 }, "range": { @@ -992,12 +961,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 124, - "mode==灰度 && resolution==300": 128, - "mode==灰度 && resolution==200": 128, - "mode==彩色 && resolution==600": 126, - "mode==灰度 && resolution==600": 129, - "default": 125 + "cis-mode==灰度 && cis-dpi==300": 128, + "cis-mode==彩色 && cis-dpi==600": 126, + "cis-mode==灰度 && cis-dpi==600": 129, + "default": 124 }, "range": { "min": 1, @@ -1016,11 +983,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 126, - "mode==灰度 && resolution==300": 129, - "mode==灰度 && resolution==200": 129, - "mode==彩色 && resolution==600": 127, - "mode==灰度 && resolution==600": 130, + "cis-mode==灰度 && cis-dpi==300": 129, + "cis-mode==彩色 && cis-dpi==600": 127, + "cis-mode==灰度 && cis-dpi==600": 130, "default": 126 }, "range": { @@ -1040,11 +1005,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 125, - "mode==灰度 && resolution==300": 127, - "mode==灰度 && resolution==200": 127, - "mode==彩色 && resolution==600": 125, - "mode==灰度 && resolution==600": 127, + "cis-mode==灰度 && cis-dpi==300": 127, + "cis-mode==彩色 && cis-dpi==600": 125, + "cis-mode==灰度 && cis-dpi==600": 127, "default": 125 }, "range": { @@ -1064,11 +1027,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 109, - "mode==灰度 && resolution==300": 110, - "mode==灰度 && resolution==200": 112, - "mode==彩色 && resolution==600": 109, - "mode==灰度 && resolution==600": 112, + "cis-mode==灰度 && cis-dpi==300": 110, + "cis-mode==彩色 && cis-dpi==600": 109, + "cis-mode==灰度 && cis-dpi==600": 112, "default": 109 }, "range": { @@ -1088,11 +1049,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 118, - "mode==灰度 && resolution==300": 120, - "mode==灰度 && resolution==200": 122, - "mode==彩色 && resolution==600": 120, - "mode==灰度 && resolution==600": 121, + "cis-mode==灰度 && cis-dpi==300": 120, + "cis-mode==彩色 && cis-dpi==600": 120, + "cis-mode==灰度 && cis-dpi==600": 121, "default": 118 }, "range": { @@ -1112,11 +1071,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 114, - "mode==灰度 && resolution==300": 115, - "mode==灰度 && resolution==200": 117, - "mode==彩色 && resolution==600": 114, - "mode==灰度 && resolution==600": 116, + "cis-mode==灰度 && cis-dpi==300": 115, + "cis-mode==彩色 && cis-dpi==600": 114, + "cis-mode==灰度 && cis-dpi==600": 116, "default": 114 }, "range": { @@ -1136,11 +1093,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 117, - "mode==灰度 && resolution==300": 117, - "mode==灰度 && resolution==200": 117, - "mode==彩色 && resolution==600": 117, - "mode==灰度 && resolution==600": 120, + "cis-mode==灰度 && cis-dpi==300": 117, + "cis-mode==彩色 && cis-dpi==600": 117, + "cis-mode==灰度 && cis-dpi==600": 120, "default": 117 }, "range": { @@ -1160,11 +1115,9 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 116, - "mode==灰度 && resolution==300": 118, - "mode==灰度 && resolution==200": 118, - "mode==彩色 && resolution==600": 117, - "mode==灰度 && resolution==600": 119, + "cis-mode==灰度 && cis-dpi==300": 118, + "cis-mode==彩色 && cis-dpi==600": 117, + "cis-mode==灰度 && cis-dpi==600": 119, "default": 116 }, "range": { @@ -1184,12 +1137,10 @@ "bind": true, "size": 4, "default": { - "mode==彩色 && resolution==300": 119, - "mode==灰度 && resolution==300": 121, - "mode==灰度 && resolution==200": 121, - "mode==彩色 && resolution==600": 120, - "mode==灰度 && resolution==600": 123, - "default": 118 + "cis-mode==灰度 && cis-dpi==300": 121, + "cis-mode==彩色 && cis-dpi==600": 120, + "cis-mode==灰度 && cis-dpi==600": 123, + "default": 119 }, "range": { "min": 1, diff --git a/docs/sane-opts/imgprc_mgr.txt b/docs/sane-opts/imgprc_mgr.txt new file mode 100644 index 0000000..9364443 --- /dev/null +++ b/docs/sane-opts/imgprc_mgr.txt @@ -0,0 +1,67 @@ +{ + "is-multiout": { + "cat": "base", + "group": "base", + "title": "多流输出", + "desc": "同时输出多种颜色模式的图像", + "type": "bool", + "fix-id": 34817, + "ui-pos": 10, + "auth": 0, + "size": 4, + "cur": false, + "default": false + }, + "multiout-type": { + "cat": "base", + "group": "base", + "title": "多流输出类型", + "desc": "选择多流输出的类型", + "type": "string", + "fix-id": 34818, + "ui-pos": 11, + "auth": 0, + "enabled": false, + "size": 66, + "cur": "彩色+灰度+黑白", + "default": "彩色+灰度+黑白", + "range": ["彩色+灰度+黑白", "彩色+灰度", "彩色+黑白", "灰度+黑白"], + "depend": "is-multiout==true" + }, + "mode": { + "cat": "base", + "group": "base", + "title": "颜色模式", + "desc": "选择色彩模式", + "type": "string", + "fix-id": 34819, + "ui-pos": 15, + "auth": 0, + "size": 24, + "cur": "24位彩色", + "default": "24位彩色", + "range": ["24位彩色", "256级灰度", "黑白", "颜色自动识别"], + "depend": "is-multiout!=true" + }, + "resolution": { + "cat": "base", + "group": "base", + "title": "分辨率", + "desc": "设置扫描图像的分辨率", + "type": "int", + "fix-id": 34840, + "ui-pos": 20, + "auth": 0, + "size": 4, + "cur": 200, + "default": 200, + "range": { + "min": 100, + "max": { + "default": 600, + "paper==最大扫描尺寸自动裁切 || paper==最大扫描尺寸 || paper==三联试卷": 500 + }, + "step": 1 + } + } +} diff --git a/hardware/cis/FpgaComm.h b/hardware/cis/FpgaComm.h index 2bfccff..f923580 100644 --- a/hardware/cis/FpgaComm.h +++ b/hardware/cis/FpgaComm.h @@ -42,13 +42,6 @@ typedef struct STATUS_FPGA unsigned int reserved : 31; } StatusFpga; -typedef struct Ad_Gain -{ - unsigned short int gain_low8 : 8; - unsigned short int gain_hight : 1; - unsigned int reserved : 23; -} AdGain; - typedef struct CIS_AD_Gain { @@ -62,16 +55,6 @@ typedef struct CIS_AD_Gain unsigned short int ad1_rw : 1; //!< 读写位 1:读, 0:写; } CisAdGain; -typedef struct CIS_LED_RF -{ - unsigned short int ledEnable : 1; - unsigned short int fanMode : 2; - unsigned short int jamEnable : 1; - unsigned short int sample : 9; - unsigned short int reserved : 3; - unsigned short int ledR; -} CisLedRF; - typedef struct CIS_LED_R { unsigned short int ledEnable : 1; @@ -86,6 +69,23 @@ typedef struct CIS_LED_GB unsigned short int ledB; } CisLedGB; +typedef struct Ad_Gain +{ + unsigned short int gain_low8 : 8; + unsigned short int gain_hight : 1; + unsigned int reserved : 23; +} AdGain; + +typedef struct CIS_LED_RF +{ + unsigned short int ledEnable : 1; + unsigned short int fanMode : 2; + unsigned short int jamEnable : 1; + unsigned short int sample : 9; + unsigned short int reserved : 3; + unsigned short int ledR; +} CisLedRF; + typedef struct CIS_LED_UV { unsigned short int ledASide; @@ -126,11 +126,10 @@ enum GRAY_MODE = 0, COLOR_MODE, }; -// 0x01 200dpi 0x02 300dpi 0x03 600dpi + enum { - DPI_200 = 1, - DPI_300, + DPI_300 = 2, DPI_600, }; diff --git a/hardware/hardware.cpp b/hardware/hardware.cpp index b92b006..8ef0490 100644 --- a/hardware/hardware.cpp +++ b/hardware/hardware.cpp @@ -11,9 +11,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////// // scanner_hw static std::string device_opt_json[] = { - "{\"mode\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u955c\\u5934\\u8272\\u5f69\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"ui-pos\":10,\"auth\":0,\"size\":12,\"cur\":\"\\u5f69\\u8272\",\"default\":\"\\u5f69\\u8272\",\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"resolution\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u955c\\u5934\\u5de5\\u4f5c\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"ui-pos\":11,\"auth\":0,\"size\":4,\"cur\":200,\"default\":200,\"range\":[200,300,600]},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"fix-id\":34831,\"ui-pos\":10,\"auth\":0,\"size\":44,\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"16\\u5f00\",\"A5\",\"A6\",\"B4\",\"B5\",\"B6\",\"Letter\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\"},{\"resolution<500\":\"\\u4e09\\u8054\\u8bd5\\u5377\"}]},\"lateral\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u6a2a\\u5411\",\"desc\":\"\\u6a2a\\u5411\\u653e\\u7f6e\\u7eb8\\u5f20\",\"type\":\"bool\",\"fix-id\":34924,\"ui-pos\":12,\"auth\":0,\"affect\":6,\"visible\":0,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper==A4 || paper==16\\u5f00 || paper==A5 || paper==A6 || paper==B5 || paper==B6 || paper==Letter\"},\"paper-w\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5bbd\\u5ea6\",\"desc\":\"\\u4ee5\\u6beb\\u7c73\\u4e3a\\u5355\\u4f4d\\u7684\\u7eb8\\u5f20\\u5bbd\",\"type\":\"float\",\"fix-id\":34922,\"ui-pos\":13,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"visible\":0,\"size\":8,\"auto\":false,\"ownread\":true,\"cur\":210.000000,\"default\":210.000000},\"paper-h\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u9ad8\\u5ea6\",\"desc\":\"\\u4ee5\\u6beb\\u7c73\\u4e3a\\u5355\\u4f4d\\u7684\\u7eb8\\u5f20\\u9ad8\",\"type\":\"float\",\"fix-id\":34923,\"ui-pos\":14,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"visible\":0,\"size\":8,\"auto\":false,\"ownread\":true,\"cur\":297.000000,\"default\":297.000000},\"is-wait-scan\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e\\uff0c\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"fix-id\":34873,\"ui-pos\":12,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"wait-scan-exit\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\\u9000\\u51fa\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u7ed3\\u675f\\u5f85\\u7eb8\\u626b\\u63cf\\u7684\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34920,\"ui-pos\":13,\"auth\":0,\"size\":16,\"cur\":\"60s\",\"default\":\"60s\",\"range\":[\"15s\",\"30s\",\"60s\",\"2min\",\"4min\",\"8min\"],\"depend\":\"is-wait-scan==true\"},\"scan-mode\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"fix-id\":34862,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend\":\"is-wait-scan==false\"},\"scan-count\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"fix-id\":34863,\"ui-pos\":16,\"auth\":0,\"size\":4,\"cur\":-1,\"default\":-1,\"depend\":\"scan-mode.enabled&&scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"},\"is-auto-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"fix-id\":34876,\"ui-pos\":27,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"feed-strength-value\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"fix-id\":34877,\"ui-pos\":28,\"auth\":0,\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend\":\"is-auto-strength==true\"},\"feed-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"fix-id\":34874,\"ui-pos\":30,\"auth\":0,\"size\":12,\"cur\":\"\\u4e00\\u822c\",\"default\":\"\\u4e00\\u822c\",\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"],\"depend\":\"is-auto-strength!=true\"},\"time-to-sleep\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34875,\"ui-pos\":33,\"auth\":0,\"size\":16,\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"baud\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u6ce2\\u7279\\u7387\",\"desc\":\"CIS\\u63a7\\u5236\\u901a\\u4fe1\\u901f\\u7387\",\"type\":\"int\",\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":921600,\"default\":921600,\"range\":[110,300,600,1200,2400,4800,9600,19200,38400,57600,115200,500000,921600,1500000]},\"act-after\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5ef6\\u8fdf\\u54cd\\u5e94\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u63a5\\u53d7\\u547d\\u4ee4\\u540e\\u7684\\u52a8\\u4f5c\\u5ef6\\u8fdf\\u65f6\\u95f4\",\"type\":\"int\",\"ui-pos\":21,\"auth\":0,\"unit\":\"microsec\",\"size\":4,\"cur\":1000,\"default\":1000},\"frame-h\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u6bcf\\u4e00\\u5e27\\u7684\\u91c7\\u96c6\\u9ad8\\u5ea6\",\"type\":\"int\",\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":12,\"default\":12},\"sample\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u91c7\\u6837\\u9891\\u7387\",\"type\":\"int\",\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":256,\"default\":256},\"paper-on\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u7eb8\\u5f20\\u5c31\\u7eea\",\"desc\":\"\\u7eb8\\u5f20\\u5df2\\u7ecf\\u5728\\u8fdb\\u7eb8\\u53f0\\u4e0a\\u653e\\u7f6e\\u597d\",\"type\":\"bool\",\"fix-id\":34912,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":false,\"default\":false},\"double-chk\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u53cc\\u5f20\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u4e24\\u5f20\\u6216\\u8005\\u591a\\u5f20\\u7eb8\\u540c\\u65f6\\u6413\\u8fdb\",\"type\":\"string\",\"ui-pos\":18,\"auth\":0,\"size\":16,\"cur\":\"\\u8d85\\u58f0\\u6ce2\",\"default\":\"\\u8d85\\u58f0\\u6ce2\",\"range\":[\"\\u8d85\\u58f0\\u6ce2\",\"\\u7981\\u7528\"]},\"is-staple\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u8ba2\\u4e66\\u9489\\u5b58\\u5728\",\"type\":\"bool\",\"fix-id\":34861,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"motor-speed\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u8d70\\u7eb8\\u901f\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u8d70\\u7eb8\\u7535\\u673a\\u7684\\u901f\\u5ea6\\uff0c\\u5f20\\/\\u5206\\uff08PPM\\uff09\",\"type\":\"int\",\"ui-pos\":25,\"auth\":0,\"size\":4,\"cur\":100,\"default\":100,\"range\":[{\"dev-model!=G200\":70},{\"dev-model!=G200\":80},{\"dev-model!=G200\":90},100,{\"dev-model==G200\":110},{\"dev-model==G200\":120},{\"dev-model==G200\":130}]},\"is-check-askew\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u8fdb\\u7eb8\\u662f\\u5426\\u6b6a\\u659c\",\"type\":\"bool\",\"fix-id\":34868,\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"askew-range\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34869,\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":3,\"default\":3,\"range\":{\"min\":1,\"max\":7,\"step\":1},\"depend\":\"is-check-askew==true\"},\"motor-ver\":{\"cat\":\"none\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u7535\\u673a\\u9a71\\u52a8\\u7248\\u672c\",\"desc\":\"\\u7535\\u673a\\u677f\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34909,\"ui-pos\":16,\"auth\":0,\"readonly\":true,\"size\":24,\"auto\":false,\"cur\":\"\",\"default\":\"\"},\"fpga-ver\":{\"cat\":\"none\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"CIS\\u63a7\\u5236\\u5668\\u7248\\u672c\",\"desc\":\"\\u955c\\u5934\\u53c2\\u6570\\u63a7\\u5236\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"ui-pos\":17,\"auth\":0,\"readonly\":true,\"size\":24,\"auto\":false,\"cur\":\"\",\"default\":\"\"},\"cis-len\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u955c\\u5934\\u957f\",\"desc\":\"\\u56fe\\u50cf\\u91c7\\u96c6\\u955c\\u5934\\u7684\\u957f\\u5ea6\\uff0c\\u5355\\u4f4d\\u4e3a\\u6beb\\u7c73\\uff08mm\\uff09\",\"type\":\"int\",\"ui-pos\":30,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":3888,\"default\":3888},\"stretch-h\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u6c34\\u5e73\\u62c9\\u4f38\\u73", - "87\",\"desc\":\"\\u4e3a\\u62b5\\u6297\\u5f62\\u53d8\\uff0c\\u5728\\u6c34\\u5e73\\u65b9\\u5411\\u7684\\u62c9\\u4f38\\u7387\",\"type\":\"float\",\"ui-pos\":40,\"auth\":0,\"size\":8,\"auto\":false,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==300\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==200\":1.000000,\"mode==\\u5f69\\u8272 && resolution==600\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==600\":1.000000,\"default\":1.000000},\"range\":{\"min\":0.500000,\"max\":2.000000,\"step\":0.100000}},\"stretch-v\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u5782\\u76f4\\u62c9\\u4f38\\u7387\",\"desc\":\"\\u4e3a\\u62b5\\u6297\\u5f62\\u53d8\\uff0c\\u5728\\u5782\\u76f4\\u65b9\\u5411\\u7684\\u62c9\\u4f38\\u7387\",\"type\":\"float\",\"ui-pos\":41,\"auth\":0,\"size\":8,\"auto\":false,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==300\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==200\":1.000000,\"mode==\\u5f69\\u8272 && resolution==600\":1.000000,\"mode==\\u7070\\u5ea6 && resolution==600\":1.000000,\"default\":1.000000},\"range\":{\"min\":0.500000,\"max\":2.000000,\"step\":0.100000}},\"cis-sp\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u901f\\u73871\",\"desc\":\"FPGA\\u6700\\u4f73\\u901f\\u7387\",\"type\":\"int\",\"ui-pos\":42,\"auth\":0,\"size\":4,\"auto\":false,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":878,\"mode==\\u7070\\u5ea6 && resolution==300\":2637,\"mode==\\u7070\\u5ea6 && resolution==200\":2450,\"mode==\\u5f69\\u8272 && resolution==600\":1531,\"mode==\\u7070\\u5ea6 && resolution==600\":4595,\"default\":816}},\"expo-fr\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":70,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":313,\"mode==\\u7070\\u5ea6 && resolution==300\":336,\"mode==\\u7070\\u5ea6 && resolution==200\":337,\"mode==\\u5f69\\u8272 && resolution==600\":622,\"mode==\\u7070\\u5ea6 && resolution==600\":673,\"default\":312},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-fg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":71,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":306,\"mode==\\u7070\\u5ea6 && resolution==300\":336,\"mode==\\u7070\\u5ea6 && resolution==200\":337,\"mode==\\u5f69\\u8272 && resolution==600\":611,\"mode==\\u7070\\u5ea6 && resolution==600\":673,\"default\":305},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-fb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":72,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":297,\"mode==\\u7070\\u5ea6 && resolution==300\":336,\"mode==\\u7070\\u5ea6 && resolution==200\":337,\"mode==\\u5f69\\u8272 && resolution==600\":590,\"mode==\\u7070\\u5ea6 && resolution==600\":673,\"default\":295},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-br\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":73,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":360,\"mode==\\u7070\\u5ea6 && resolution==300\":410,\"mode==\\u7070\\u5ea6 && resolution==200\":406,\"mode==\\u5f69\\u8272 && resolution==600\":713,\"mode==\\u7070\\u5ea6 && resolution==600\":811,\"default\":360},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-bg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":74,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":380,\"mode==\\u7070\\u5ea6 && resolution==300\":410,\"mode==\\u7070\\u5ea6 && resolution==200\":406,\"mode==\\u5f69\\u8272 && resolution==600\":758,\"mode==\\u7070\\u5ea6 && resolution==600\":811,\"default\":379},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-bb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":75,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":361,\"mode==\\u7070\\u5ea6 && resolution==300\":410,\"mode==\\u7070\\u5ea6 && resolution==200\":406,\"mode==\\u5f69\\u8272 && resolution==600\":722,\"mode==\\u7070\\u5ea6 && resolution==600\":811,\"default\":360},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"gain-f-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":90,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":91,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":92,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":93,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":94,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":95,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":120,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":121,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":122,\"auth\":0,\"bind\":true,\"size\":4,\"defaul", - "t\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":123,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":124,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":125,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==300\":170,\"mode==\\u7070\\u5ea6 && resolution==200\":170,\"mode==\\u5f69\\u8272 && resolution==600\":170,\"mode==\\u7070\\u5ea6 && resolution==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":160,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":113,\"mode==\\u7070\\u5ea6 && resolution==300\":116,\"mode==\\u7070\\u5ea6 && resolution==200\":116,\"mode==\\u5f69\\u8272 && resolution==600\":115,\"mode==\\u7070\\u5ea6 && resolution==600\":116,\"default\":113},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":161,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":118,\"mode==\\u7070\\u5ea6 && resolution==300\":121,\"mode==\\u7070\\u5ea6 && resolution==200\":119,\"mode==\\u5f69\\u8272 && resolution==600\":119,\"mode==\\u7070\\u5ea6 && resolution==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":162,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":118,\"mode==\\u7070\\u5ea6 && resolution==300\":119,\"mode==\\u7070\\u5ea6 && resolution==200\":121,\"mode==\\u5f69\\u8272 && resolution==600\":118,\"mode==\\u7070\\u5ea6 && resolution==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":163,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":124,\"mode==\\u7070\\u5ea6 && resolution==300\":128,\"mode==\\u7070\\u5ea6 && resolution==200\":128,\"mode==\\u5f69\\u8272 && resolution==600\":126,\"mode==\\u7070\\u5ea6 && resolution==600\":129,\"default\":125},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":164,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":126,\"mode==\\u7070\\u5ea6 && resolution==300\":129,\"mode==\\u7070\\u5ea6 && resolution==200\":129,\"mode==\\u5f69\\u8272 && resolution==600\":127,\"mode==\\u7070\\u5ea6 && resolution==600\":130,\"default\":126},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":165,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":125,\"mode==\\u7070\\u5ea6 && resolution==300\":127,\"mode==\\u7070\\u5ea6 && resolution==200\":127,\"mode==\\u5f69\\u8272 && resolution==600\":125,\"mode==\\u7070\\u5ea6 && resolution==600\":127,\"default\":125},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":200,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":109,\"mode==\\u7070\\u5ea6 && resolution==300\":110,\"mode==\\u7070\\u5ea6 && resolution==200\":112,\"mode==\\u5f69\\u8272 && resolution==600\":109,\"mode==\\u7070\\u5ea6 && resolution==600\":112,\"default\":109},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":201,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":118,\"mode==\\u7070\\u5ea6 && resolution==300\":120,\"mode==\\u7070\\u5ea6 && resolution==200\":122,\"mode==\\u5f69\\u8272 && resolution==600\":120,\"mode==\\u7070\\u5ea6 && resolution==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":202,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":114,\"mode==\\u7070\\u5ea6 && resolution==300\":115,\"mode==\\u7070\\u5ea6 && resolution==200\":117,\"mode==\\u5f69\\u8272 && resolution==600\":114,\"mode==\\u7070\\u5ea6 && resolution==600\":116,\"default\":114},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":203,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":117,\"mode==\\u7070\\u5ea6 && resolution==300\":117,\"mode==\\u7070\\u5ea6 && resolution==200\":117,\"mode==\\u5f69\\u8272 && resolution==600\":117,\"mode==\\u7070\\u5ea6 && resolution==600\":120,\"default\":117},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":204,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":116,\"mode==\\u7070\\u5ea6 && resolution==300\":118,\"mode==\\u7070\\u5ea6 && resolution==200\":118,\"mode==\\u5f69\\u8272 && resolution==600\":117,\"mode==\\u7070\\u5ea6 && resolution==600\":119,\"default\":116},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":205,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"mode==\\u5f69\\u8272 && resolution==300\":119,\"mode==\\u7070\\u5ea6 && resolution==300\":121,\"mode==\\u7070\\u5ea6 && resolution==200\":121,\"mode==\\u5f69\\u8272 && resolution==600\":120,\"mode==\\u7070\\u5ea6 && resolution==600\":123,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}}}" + "{\"cis-mode\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"CIS\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u955c\\u5934\\u8272\\u5f69\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"ui-pos\":10,\"auth\":0,\"bind\":true,\"size\":12,\"default\":{\"(mode.enabled&&(mode==256\\u7ea7\\u7070\\u5ea6||mode==\\u9ed1\\u767d)) || (multiout-type.enabled&&multiout-type==\\u7070\\u5ea6+\\u9ed1\\u767d)\":\"\\u7070\\u5ea6\",\"default\":\"\\u5f69\\u8272\"},\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"cis-dpi\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"CIS\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u955c\\u5934\\u5de5\\u4f5c\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"ui-pos\":11,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"resolution>400\":600,\"default\":300},\"range\":[300,600]},\"cis-led\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"CIS\\u706f\",\"desc\":\"CIS\\u5de5\\u4f5c\\u65f6\\uff0c\\u662f\\u5426\\u6253\\u5f00\\u80cc\\u666f\\u706f\",\"type\":\"bool\",\"ui-pos\":12,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"fix-id\":34831,\"ui-pos\":30,\"auth\":0,\"size\":44,\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"16\\u5f00\",\"A5\",\"A6\",\"B4\",\"B5\",\"B6\",\"Letter\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\"},{\"resolution<500\":\"\\u4e09\\u8054\\u8bd5\\u5377\"}]},\"lateral\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u6a2a\\u5411\",\"desc\":\"\\u6a2a\\u5411\\u653e\\u7f6e\\u7eb8\\u5f20\",\"type\":\"bool\",\"fix-id\":34924,\"ui-pos\":31,\"auth\":0,\"affect\":6,\"visible\":0,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper==A4 || paper==16\\u5f00 || paper==A5 || paper==A6 || paper==B5 || paper==B6 || paper==Letter\"},\"paper-w\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5bbd\\u5ea6\",\"desc\":\"\\u4ee5\\u6beb\\u7c73\\u4e3a\\u5355\\u4f4d\\u7684\\u7eb8\\u5f20\\u5bbd\",\"type\":\"float\",\"fix-id\":34922,\"ui-pos\":32,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"visible\":0,\"size\":8,\"auto\":false,\"ownread\":true,\"cur\":210.000000,\"default\":210.000000},\"paper-h\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u9ad8\\u5ea6\",\"desc\":\"\\u4ee5\\u6beb\\u7c73\\u4e3a\\u5355\\u4f4d\\u7684\\u7eb8\\u5f20\\u9ad8\",\"type\":\"float\",\"fix-id\":34923,\"ui-pos\":33,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"visible\":0,\"size\":8,\"auto\":false,\"ownread\":true,\"cur\":297.000000,\"default\":297.000000},\"is-wait-scan\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e\\uff0c\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"fix-id\":34873,\"ui-pos\":12,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"wait-scan-exit\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\\u9000\\u51fa\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u7ed3\\u675f\\u5f85\\u7eb8\\u626b\\u63cf\\u7684\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34920,\"ui-pos\":13,\"auth\":0,\"size\":16,\"cur\":\"60s\",\"default\":\"60s\",\"range\":[\"15s\",\"30s\",\"60s\",\"2min\",\"4min\",\"8min\"],\"depend\":\"is-wait-scan==true\"},\"scan-mode\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"fix-id\":34862,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend\":\"is-wait-scan==false\"},\"scan-count\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"fix-id\":34863,\"ui-pos\":16,\"auth\":0,\"size\":4,\"cur\":-1,\"default\":-1,\"depend\":\"scan-mode.enabled&&scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"},\"is-auto-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"fix-id\":34876,\"ui-pos\":27,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"feed-strength-value\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"fix-id\":34877,\"ui-pos\":28,\"auth\":0,\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend\":\"is-auto-strength==true\"},\"feed-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"fix-id\":34874,\"ui-pos\":30,\"auth\":0,\"size\":12,\"cur\":\"\\u4e00\\u822c\",\"default\":\"\\u4e00\\u822c\",\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"],\"depend\":\"is-auto-strength!=true\"},\"time-to-sleep\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34875,\"ui-pos\":33,\"auth\":0,\"size\":16,\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"baud\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u6ce2\\u7279\\u7387\",\"desc\":\"CIS\\u63a7\\u5236\\u901a\\u4fe1\\u901f\\u7387\",\"type\":\"int\",\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":921600,\"default\":921600,\"range\":[110,300,600,1200,2400,4800,9600,19200,38400,57600,115200,500000,921600,1500000]},\"act-after\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5ef6\\u8fdf\\u54cd\\u5e94\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u63a5\\u53d7\\u547d\\u4ee4\\u540e\\u7684\\u52a8\\u4f5c\\u5ef6\\u8fdf\\u65f6\\u95f4\",\"type\":\"int\",\"ui-pos\":21,\"auth\":0,\"unit\":\"microsec\",\"size\":4,\"cur\":1000,\"default\":1000},\"frame-h\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u6bcf\\u4e00\\u5e27\\u7684\\u91c7\\u96c6\\u9ad8\\u5ea6\",\"type\":\"int\",\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":12,\"default\":12},\"sample\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u91c7\\u6837\\u9891\\u7387\",\"type\":\"int\",\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":256,\"default\":256},\"paper-on\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u7eb8\\u5f20\\u5c31\\u7eea\",\"desc\":\"\\u7eb8\\u5f20\\u5df2\\u7ecf\\u5728\\u8fdb\\u7eb8\\u53f0\\u4e0a\\u653e\\u7f6e\\u597d\",\"type\":\"bool\",\"fix-id\":34912,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":false,\"default\":false},\"double-chk\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u53cc\\u5f20\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u4e24\\u5f20\\u6216\\u8005\\u591a\\u5f20\\u7eb8\\u540c\\u65f6\\u6413\\u8fdb\",\"type\":\"string\",\"ui-pos\":18,\"auth\":0,\"size\":16,\"cur\":\"\\u8d85\\u58f0\\u6ce2\",\"default\":\"\\u8d85\\u58f0\\u6ce2\",\"range\":[\"\\u8d85\\u58f0\\u6ce2\",\"\\u7981\\u7528\"]},\"is-staple\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u8ba2\\u4e66\\u9489\\u5b58\\u5728\",\"type\":\"bool\",\"fix-id\":34861,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"motor-speed\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u8d70\\u7eb8\\u901f\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u8d70\\u7eb8\\u7535\\u673a\\u7684\\u901f\\u5ea6\\uff0c\\u5f20\\/\\u5206\\uff08PPM\\uff09\",\"type\":\"int\",\"ui-pos\":25,\"auth\":0,\"size\":4,\"cur\":100,\"default\":100,\"range\":[{\"dev-model!=G200\":70},{\"dev-model!=G200\":80},{\"dev-model!=G200\":90},100,{\"dev-model==G200\":110},{\"dev-model==G200\":120},{\"dev-model==G200\":130}]},\"is-check-askew\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u8fdb\\u7eb8\\u662f\\u5426\\u6b6a\\u659c\",\"type\":\"bool\",\"fix-id\":34868,\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"askew-range\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34869,\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":3,\"default\":3,\"range\":{\"min\":1,\"max\":7,\"step\":1},\"depend\":\"is-check-askew==true\"},\"motor-ver\":{\"cat\":\"none\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u7535\\u673a\\u9a71\\u52a8\\u7248\\u672c\",\"desc\":\"\\u7535\\u673a\\u677f\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34909,\"ui-pos\":16,\"auth\":0,\"readonly\":true,\"size\":24,\"auto\":false,\"cur\":\"\",\"default\":\"\"},\"fpga-ver\":{\"cat\":\"none\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"CIS\\u63a7\\u5236\\u5668\\u7248\\u672c\",\"desc\":\"\\u955c\\u5934\\u53c2\\u6570\\u63a7\\u5236\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"ui-pos\":17,\"auth\":0,\"readonly\":true,\"size\":24,\"auto\":false,\"cur\":\"\",\"default\":\"\"},\"cis-len\":{\"cat\":\"base\",", + "\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u955c\\u5934\\u957f\",\"desc\":\"\\u56fe\\u50cf\\u91c7\\u96c6\\u955c\\u5934\\u7684\\u957f\\u5ea6\\uff0c\\u5355\\u4f4d\\u4e3a\\u6beb\\u7c73\\uff08mm\\uff09\",\"type\":\"int\",\"ui-pos\":30,\"auth\":0,\"unit\":\"mm\",\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":3888,\"default\":3888},\"stretch-h\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u6c34\\u5e73\\u62c9\\u4f38\\u7387\",\"desc\":\"\\u4e3a\\u62b5\\u6297\\u5f62\\u53d8\\uff0c\\u5728\\u6c34\\u5e73\\u65b9\\u5411\\u7684\\u62c9\\u4f38\\u7387\",\"type\":\"float\",\"ui-pos\":40,\"auth\":0,\"size\":8,\"auto\":false,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":1.000000,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":1.000000,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":1.000000,\"default\":1.000000},\"range\":{\"min\":0.500000,\"max\":2.000000,\"step\":0.100000}},\"stretch-v\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u5782\\u76f4\\u62c9\\u4f38\\u7387\",\"desc\":\"\\u4e3a\\u62b5\\u6297\\u5f62\\u53d8\\uff0c\\u5728\\u5782\\u76f4\\u65b9\\u5411\\u7684\\u62c9\\u4f38\\u7387\",\"type\":\"float\",\"ui-pos\":41,\"auth\":0,\"size\":8,\"auto\":false,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":1.000000,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":1.000000,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":1.000000,\"default\":1.000000},\"range\":{\"min\":0.500000,\"max\":2.000000,\"step\":0.100000}},\"cis-sp\":{\"cat\":\"base\",\"group\":\"CIS\",\"title\":\"\\u901f\\u73871\",\"desc\":\"FPGA\\u6700\\u4f73\\u901f\\u7387\",\"type\":\"int\",\"ui-pos\":42,\"auth\":0,\"bind\":true,\"size\":4,\"auto\":false,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":2637,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":1531,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":4595,\"default\":878}},\"expo-fr\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":70,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":336,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":622,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":673,\"default\":313},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-fg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":71,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":336,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":611,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":673,\"default\":306},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-fb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":72,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":336,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":590,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":673,\"default\":297},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-br\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":73,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":410,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":713,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":811,\"default\":360},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-bg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":74,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":410,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":758,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":811,\"default\":380},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"expo-bb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":75,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":410,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":722,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":811,\"default\":361},\"range\":{\"min\":1,\"max\":1100,\"step\":1}},\"gain-f-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":90,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":91,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":92,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":93,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":94,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-f-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":95,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":120,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":121,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":122,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":123,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"gain-b-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":124,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"ma", + "x\":200,\"step\":1}},\"gain-b-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":125,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":170,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":170,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":170,\"default\":170},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":160,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":116,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":115,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":116,\"default\":113},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":161,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":121,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":119,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":162,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":119,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":118,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":163,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":128,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":126,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":129,\"default\":124},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":164,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":129,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":127,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":130,\"default\":126},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-f-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u6b63\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":165,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":127,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":125,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":127,\"default\":125},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-1\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90531\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90531\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":200,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":110,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":109,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":112,\"default\":109},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-2\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90532\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90532\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":201,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":120,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":120,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":121,\"default\":118},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-3\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90533\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90533\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":202,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":115,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":114,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":116,\"default\":114},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-4\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90534\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90534\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":203,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":117,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":117,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":120,\"default\":117},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-5\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90535\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90535\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":204,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":118,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":117,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":119,\"default\":116},\"range\":{\"min\":1,\"max\":200,\"step\":1}},\"off-b-6\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\u901a\\u90536\\uff09\",\"desc\":\"\\u80cc\\u9762\\u901a\\u90536\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":205,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"cis-mode==\\u7070\\u5ea6 && cis-dpi==300\":121,\"cis-mode==\\u5f69\\u8272 && cis-dpi==600\":120,\"cis-mode==\\u7070\\u5ea6 && cis-dpi==600\":123,\"default\":119},\"range\":{\"min\":1,\"max\":200,\"step\":1}}}" }; @@ -23,6 +23,18 @@ scanner_hw::scanner_hw() : mb_events_("motorboard-event") { set_where("hardware"); mb_events_.enable_wait_log(false); + memset(&img_base_, 0, sizeof(img_base_)); + img_base_.bpp = 8; + img_base_.bppc = 8; + img_base_.channels = 1; + img_base_.format = IMG_FMT_BMP; + img_base_.resolution_x = dpi_; + img_base_.resolution_y = dpi_; + img_base_.width = cis_length_; + img_base_.height = 16380; + img_base_.pos.new_img = true; + img_base_.pos.img_over = true; + img_base_.pos.paper_side = PAPER_SIDE_DSP; CLEAN_ARRAY(exposure_); CLEAN_ARRAY(gain_); @@ -76,10 +88,7 @@ void scanner_hw::init(void) }; auto r = [this](void* value) -> void { - if(*(int*)value <= 200) - dpi_ = 200; - else - dpi_ = 300; + dpi_ = *(int*)value; }; auto b = [this](void* value) -> void { @@ -101,6 +110,10 @@ void scanner_hw::init(void) { sp_ = *(int*)value; }; + auto led = [this](void* value) -> void + { + cis_led_ = *(bool*)value; + }; auto stretch_h = [this](void* value) -> void { stretch_h_ = *(double*)value; @@ -142,8 +155,8 @@ void scanner_hw::init(void) opt_handler_[SANE_FULL_NAME(WAIT_TO_SCAN)] = a; opt_handler_[SANE_FULL_NAME(WAIT_SCAN_EXIT)] = e; - opt_handler_[SANE_FULL_NAME(COLOR_MODE)] = m; - opt_handler_[SANE_FULL_NAME(RESOLUTION)] = r; + opt_handler_[SANE_FULL_NAME(CIS_MODE)] = m; + opt_handler_[SANE_FULL_NAME(CIS_DPI)] = r; opt_handler_[SANE_FULL_NAME(CIS_BAUD)] = b; opt_handler_[SANE_FULL_NAME(CIS_DELAY)] = d; opt_handler_[SANE_FULL_NAME(CIS_FRAME_H)] = f; @@ -310,7 +323,7 @@ void scanner_hw::init_version(std::string& text) } void scanner_hw::thread_image_capture(void) { - PACKIMAGE img; + PACKIMAGE img(img_base_); safe_fifo avail_mem("v4l2-mem"); int used_v4l2_mem = 0, times = 0; std::pair mbev; @@ -324,13 +337,6 @@ void scanner_hw::thread_image_capture(void) }; utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n"); - memset(&img, 0, sizeof(img)); - img.bpp = 8; - img.channels = 3; - img.resolution_x = 200; - img.resolution_y = 200; - img.width = cis_length_; - img.height = 16380; motor_->clear_error(); motor_->start(); if(mb_events_.take(mbev, true)) @@ -404,6 +410,7 @@ void scanner_hw::thread_image_capture(void) utils::to_log(LOG_LEVEL_DEBUG, "scanning thread exited.\n"); scanning_ = false; + img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, 0); } bool scanner_hw::is_scan_fatal(void) { @@ -438,6 +445,7 @@ void scanner_hw::retrieve_v4l2_mem(safe_fifo* mem, int* used) } void scanner_hw::set_gain_value(bool front, bool gain, int sector, int val) { + sector--; if(gain) { if(sector < _countof(gain_[0])) @@ -490,6 +498,20 @@ char* scanner_hw::get_value(const char* name, void* value, size_t* size, int* er if(size) *size = sizeof(double); } + else if(strcmp(name, SANE_FULL_NAME(CIS_MODE)) == 0) + { + ret = (char*)malloc(mode_.length() + 1); + strcpy(ret, mode_.c_str()); + if(size) + *size = mode_.length(); + } + else if(strcmp(name, SANE_FULL_NAME(CIS_DPI)) == 0) + { + ret = (char*)malloc(sizeof(int)); + *(int*)ret = dpi_; + if(size) + *size = sizeof(int); + } else if(err) *err = SCANNER_ERR_DEVICE_NOT_FOUND; @@ -542,6 +564,8 @@ void scanner_hw::enable(const char* name, bool able) // operation ... int scanner_hw::open(std::function image_handler) { + std::string tips(""); + this->close(); int fh = 16380; @@ -553,29 +577,44 @@ int scanner_hw::open(std::function image_handler) if(!img_controller_->is_ok()) return DEV_ERR(HD_001); + img_base_.resolution_x = dpi_; + img_base_.resolution_y = dpi_; + img_controller_->setColorMode(mode_ == "\345\275\251\350\211\262" ? COLOR_MODE : GRAY_MODE); - img_controller_->setDpi((dpi_ + 100) / 200); + img_controller_->setDpi(dpi_ == 300 ? DPI_300 : DPI_600); img_controller_->setDelayTime(delay_); img_controller_->setSample(sample_); img_controller_->setSp(sp_); + img_controller_->enableLed(cis_led_); + utils::to_log(LOG_LEVEL_DEBUG, "FPGA Sp = %d\n", sp_); void(FpgaComm::* exposure[])(int) = {&FpgaComm::setAExposureB, &FpgaComm::setAExposureG , &FpgaComm::setAExposureR, &FpgaComm::setBExposureB, &FpgaComm::setBExposureG, &FpgaComm::setBExposureR}; + tips = "Exposure(BGR): "; for(int i = 0; i < SIDE_COUNT; ++i) { + tips += "\tSide_" + std::to_string(i) + "["; for(int j = 0; j < COLOR_IND_COUNT; ++j) + { (img_controller_.get()->*exposure[i * SIDE_COUNT + j])(exposure_[i][j]); + tips += std::to_string(exposure_[i][j]) + ", "; + } + tips.erase(tips.length() - 2); + tips += "];"; } + utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str()); for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i) + { + tips = "Gain: Sector_" + std::to_string(i + 1) + "[F="; + tips += std::to_string(gain_[SIDE_FRONT][i]) + "x + " + std::to_string(off_[SIDE_FRONT][i]) + "];\t[B=" + + std::to_string(gain_[SIDE_BACK][i]) + "x + " + std::to_string(off_[SIDE_BACK][i]) + "]"; img_controller_->setAGain(i, gain_[SIDE_FRONT][i]); - for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i) img_controller_->setBGain(i, gain_[SIDE_BACK][i]); - - for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i) img_controller_->setAOffset(i, off_[SIDE_FRONT][i]); - for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i) img_controller_->setBOffset(i, off_[SIDE_BACK][i]); + utils::to_log(LOG_LEVEL_DEBUG, "%s\n", tips.c_str()); + } auto cb = [this](int ev, unsigned int data) -> void { @@ -626,16 +665,17 @@ int scanner_hw::open(std::function image_handler) std::this_thread::sleep_for(std::chrono::milliseconds(20)); img_controller_->setFrameHeight(fh / 2 * 3); - if(1) - { - // debug ... - unsigned int vals[] = {0x5ffa, 0x3300c9d, 0x1, 0xaa00aa, 0x340030aa, 0x1380193 - , 0x1270131, 0x340030aa, 0x168000c, 0x168017b, 0, 0x0afa3f - , 0x3e8}; - for(int i = 0; i < _countof(vals); ++i) - img_controller_->write(i, vals[i]); - img_controller_->update(); - } + // if(1) + // { + // // debug ... + // unsigned int vals[] = {0x5ffa, 0x3300c9d, 0x1, 0xaa00aa, 0x340030aa, 0x1380193 + // , 0x1270131, 0x340030aa, 0x168000c, 0x168017b, 0, 0x0afa3f + // , 0x3e8}; + // for(int i = 0; i < _countof(vals); ++i) + // img_controller_->write(i, vals[i]); + // } + // img_controller_->write(1, 0x0330100d); // DPI mode should be revised (only support 2 and 3) ... + img_controller_->update(); return SCANNER_ERR_OK; } diff --git a/hardware/hardware.h b/hardware/hardware.h index 99c34d5..677e742 100644 --- a/hardware/hardware.h +++ b/hardware/hardware.h @@ -18,7 +18,7 @@ // // bool: true - image, dyn_mem_ptr is image data buffer; false - dyn_mem_ptr is an uint32_t code of hardware event // -// LPPACKIMAGE: image information, ignored when bool is false +// LPPACKIMAGE: image information, or uint32_t event data when bool is false #define IMAGE_HANDLER_PROTO void(dyn_mem_ptr, bool, LPPACKIMAGE) #include "./cis/FpgaComm.h" @@ -52,9 +52,11 @@ class scanner_hw : public sane_opt_provider }; std::string mode_; std::string family_ = "G200"; + PACKIMAGE img_base_; volatile bool auto_scan_ = false; int scan_count_ = -1; int cis_length_ = 3888; + bool cis_led_ = true; int dpi_ = 300; int baud_ = 921600; int delay_ = 1000; diff --git a/imgproc/imgprc_mgr.cpp b/imgproc/imgprc_mgr.cpp new file mode 100644 index 0000000..5b167ae --- /dev/null +++ b/imgproc/imgprc_mgr.cpp @@ -0,0 +1,223 @@ +#include "imgprc_mgr.h" + +#include +#include +#include +#include + + +static std::string device_opt_json[] = { + "{\"is-multiout\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34817,\"ui-pos\":10,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"multiout-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"fix-id\":34818,\"ui-pos\":11,\"auth\":0,\"enabled\":false,\"size\":66,\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend\":\"is-multiout==true\"},\"mode\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend\":\"is-multiout!=true\"},\"resolution\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":200,\"default\":200,\"range\":{\"min\":100,\"max\":{\"default\":600,\"paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 || paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8 || paper==\\u4e09\\u8054\\u8bd5\\u5377\":500},\"step\":1}}}" +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// imgproc_mgr + +imgproc_mgr::imgproc_mgr(std::function sender + , device_option* devopts + ) + : img_sender_(sender), opts_(devopts), prc_que_("prcimg") +{ + std::string text(""); + gb_json *jsn = new gb_json(); + + for (auto& v : device_opt_json) + text += v; + + if (jsn->attach_text(&text[0])) + { + text = jsn->to_string(); + } + jsn->release(); + + set_opt_json_text(&text[0]); + + if (opts_) + opts_->add_ref(); + else + opts_ = new device_option(); + + auto thrd = [&](void) -> void + { + thread_worker(); + }; + workers_.start(thrd, "imgproc_mgr::thread_worker", (void*)&imgproc_mgr::thread_worker); +} +imgproc_mgr::~imgproc_mgr() +{ + clear(); + opts_->release(); +} + +bool imgproc_mgr::sort_processor_by_pos(image_processor* l, image_processor* r) +{ + return l->get_position() < r->get_position(); +} +bool imgproc_mgr::sort_image_packet(image_packet_ptr l, image_packet_ptr r) +{ + return l->get_paper_index() < r->get_paper_index(); +} +data_source_ptr imgproc_mgr::scan_finished_packet(uint32_t scanid, uint32_t err) +{ + dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE)); + BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_FINISHED_ROGER, scanid, err); + reply->set_len(sizeof(PACK_BASE)); + + return reply; +} +image_packet_ptr imgproc_mgr::image_sent_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid, void* info, size_t info_l) +{ + image_packet_ptr pimg = new image_packet(head, img, scanid, info, info_l); + + return pimg; +} + +uint32_t imgproc_mgr::add_busy_worker(int inc) +{ + SIMPLE_LOCK(working_cnt_lock_); + working_cnt_ += inc; + + return working_cnt_; +} +void imgproc_mgr::thread_worker(void) +{ + RAWIMG img; + while(prc_que_.take(img, true)) + { + add_busy_worker(); + + process(&img); + if(img.img) + img.data->release(); + + add_busy_worker(-1); + } +} +void imgproc_mgr::process(RAWIMG* img) +{ + if(img->img) + { + std::vector in, out; + PROCIMGINFO ele; + + ele.ext_info = ""; + ele.info = img->info; + ele.img = cv::Mat(ele.info.height, ele.info.width, CV_8UC1, (void*)img->data->ptr(), img->data->get_rest()); + img->data->release(); + in.push_back(ele); + + if(dump_img_) + { + for(auto& v: processors_) + { + send_image(in, false); + v->process(in, out); + in = std::move(out); + } + } + else + { + for(auto& v: processors_) + { + v->process(in, out); + in = std::move(out); + } + } + send_image(in, true); + } + else + { + data_source_ptr ptr = imgproc_mgr::scan_finished_packet(scan_id_, img->info.reserve); + + ptr->set_session_id(session_id_); + img_sender_(ptr); + ptr->release(); + } +} +void imgproc_mgr::send_image(std::vector& imgs, bool clear_after_send) +{ + for(auto& v: imgs) + { + uint32_t size = v.img.total() * v.img.channels(); + dyn_mem_ptr mem(dyn_mem::memory(size)); + mem->put(v.img.data, size); + if(clear_after_send) + v.img.deallocate(); + + image_packet_ptr ptr = imgproc_mgr::image_sent_packet(&v.info, mem, scan_id_, &v.ext_info[0], v.ext_info.length()); + + ptr->set_session_id(session_id_); + img_sender_(ptr); + ptr->release(); + mem->release(); + } +} + +int imgproc_mgr::set_value(const char* name, void* val) +{ + int ret = SCANNER_ERR_OK; + + // ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; + + return ret; +} + +int imgproc_mgr::load_processor(const char* path) +{ + int ret = SCANNER_ERR_OK; + +#define ADD_IMG_PROCESSOR(cls) \ + { \ + cls *obj = new cls(); \ + opts_->add(obj); \ + obj->release(); \ + } + + std::sort(processors_.begin(), processors_.end(), &imgproc_mgr::sort_processor_by_pos); + + return ret; +} +int imgproc_mgr::clear(void) +{ + for (auto& v : processors_) + v->release(); + processors_.clear(); + + return 0; +} + +int imgproc_mgr::process(LPPACKIMAGE info, dyn_mem_ptr data, bool img) +{ + RAWIMG ri; + int ret = SCANNER_ERR_OK; + + ri.data = data; + if(img) + ri.info = *info; + else + ri.info.reserve = (uint32_t)(long)info; + ri.img = img; + prc_que_.save(ri, true); + + return ret; +} + +void imgproc_mgr::stop(void) +{ + run_ = false; + prc_que_.trigger(); + + workers_.stop(nullptr); +} +bool imgproc_mgr::is_busy(void) +{ + SIMPLE_LOCK(working_cnt_lock_); + + return working_cnt_; +} +void imgproc_mgr::start_new_turn(uint32_t scanid, uint32_t sessionid) +{ + scan_id_ = scanid; + sent_ind_ = 0; + session_id_ = sessionid; +} diff --git a/imgproc/imgprc_mgr.h b/imgproc/imgprc_mgr.h new file mode 100644 index 0000000..6daaea1 --- /dev/null +++ b/imgproc/imgprc_mgr.h @@ -0,0 +1,72 @@ +#pragma once + +// image processor +// +// created on 2023-11-07 +// +// ver: 1.0 +// +// NOTE: the interface is for all algorithms are in ONE module + +#include +#include // for refer +#include +#include + +typedef std::shared_ptr> dcptr; + +class device_option; +class imgproc_mgr : public sane_opt_provider +{ + typedef struct _raw_img + { + PACKIMAGE info; + dyn_mem_ptr data; + bool img; + }RAWIMG; + + volatile bool run_ = true; + bool dump_img_ = false; + uint32_t scan_id_ = 0; + uint32_t sent_ind_ = 0; + uint32_t session_id_ = 0; + MUTEX working_cnt_lock_; + uint32_t working_cnt_ = 0; + std::vector processors_; + device_option* opts_; + safe_thread workers_; + safe_fifo prc_que_; + std::function img_sender_; + + static bool sort_processor_by_pos(image_processor* l, image_processor* r); + static bool sort_image_packet(image_packet_ptr l, image_packet_ptr r); + static data_source_ptr scan_finished_packet(uint32_t scanid, uint32_t err = 0); + static image_packet_ptr image_sent_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid, void* info = nullptr, size_t info_l = 0); + + uint32_t add_busy_worker(int inc = 1); + void thread_worker(void); + void process(RAWIMG* img); + void send_image(std::vector& imgs, bool clear_after_send); + +public: + imgproc_mgr(std::function sender, device_option* devopts); + +protected: + virtual ~imgproc_mgr(); + +public: + virtual int set_value(const char* name, void* val) override; + + // process +public: + int load_processor(const char* path); // outer-modules path + int clear(void); + int process(LPPACKIMAGE info, dyn_mem_ptr data, bool img); + + // life +public: + void stop(void); + bool is_busy(void); + void start_new_turn(uint32_t scanid, uint32_t sessionid); +}; + diff --git a/imgproc/xmake.lua b/imgproc/xmake.lua new file mode 100644 index 0000000..e070921 --- /dev/null +++ b/imgproc/xmake.lua @@ -0,0 +1,12 @@ +add_rules("mode.debug", "mode.release") + +target("imgproc") + set_kind("static") + add_syslinks("pthread", "dl", "opencv_imgcodecs", "opencv_core") + add_includedirs("../sdk") + add_files("*.cpp", "./algs/*.c*", "../sdk/base/*.c*", "../sdk/imgprc/*.c*", "../sdk/json/*.c*", "../sdk/sane/*.c*", "../sdk/sane_opt_json/*.c*") + --add_deps("gusb", "applog") + --add_rules("utils.bin2c",{linewidth = 32,extension = {".bin"}}) + --add_files("table.bin") + add_packages("sdk") + \ No newline at end of file diff --git a/scanner/async_scanner.cpp b/scanner/async_scanner.cpp index 2b28dd8..6bc5dfe 100644 --- a/scanner/async_scanner.cpp +++ b/scanner/async_scanner.cpp @@ -16,6 +16,7 @@ #include #include #include +#include @@ -41,8 +42,8 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) if(used) *used = data->get_rest(); - - return handle_bulk_cmd(pack, used, required); + + return handle_bulk_cmd(pack, used, required, data->get_session_id()); }; auto on_connect = [this](bool connected) -> void { @@ -61,6 +62,11 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) utils::log_info(msg, LOG_LEVEL_DEBUG); }; + auto sender = [this](data_source_ptr img) -> void + { + usb_->write_bulk(img); + }; + cfg_mgr_ = new device_option(true, user, on_log); utils::to_log(LOG_LEVEL_DEBUG, "OPT - initializing ...\n"); const_opts_ = new scanner_const_opts(); @@ -70,6 +76,8 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) cis_->set_value(SANE_FULL_NAME(DEVICE_MODEL), &cfg_mgr_->get_option_value(SANE_FULL_NAME(DEVICE_MODEL), SANE_ACTION_GET_VALUE)[0]); cfg_mgr_->add(cis_); cfg_mgr_->add(user_); + img_prcr_ = new imgproc_mgr(sender, cfg_mgr_); + cfg_mgr_->add(img_prcr_); utils::to_log(LOG_LEVEL_DEBUG, "OPT - initialized %u options.\n", cfg_mgr_->count()); usb_ = new async_usb_gadget(bulk_handle, on_connect); @@ -89,6 +97,12 @@ async_scanner::~async_scanner() { usb_->stop(); usb_->release(); + usb_ = nullptr; + } + if(img_prcr_) + { + img_prcr_->release(); + img_prcr_ = nullptr; } if(cfg_mgr_) { @@ -106,7 +120,7 @@ async_scanner::~async_scanner() devui::uninit_ui(); } -dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { dyn_mem_ptr reply = nullptr; LPPACK_BASE pk = nullptr; @@ -129,31 +143,31 @@ dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, pac switch(pack->cmd) { case PACK_CMD_SYNC: - reply = handle_simple_roger(pack, used, required); + reply = handle_simple_roger(pack, used, required, session); break; case PACK_CMD_SETTING_GET_CUR: - reply = handle_get_opt_value(pack, used, required); + reply = handle_get_opt_value(pack, used, required, session); break; case PACK_CMD_SETTING_GET: - reply = handle_get_opt_all(pack, used, required); + reply = handle_get_opt_all(pack, used, required, session); break; case PACK_CMD_SETTING_SET: - reply = handle_set_opt(pack, used, required); + reply = handle_set_opt(pack, used, required, session); break; case PACK_CMD_FILE_WRITE_REQ: - reply = handle_file_receive(pack, used, required); + reply = handle_file_receive(pack, used, required, session); break; case PACK_CMD_FILE_READ_REQ: - reply = handle_file_send(pack, used, required); + reply = handle_file_send(pack, used, required, session); break; case PACK_CMD_FILE_READ_REQ_ROGER: - reply = handle_file_send_roger(pack, used, required); + reply = handle_file_send_roger(pack, used, required, session); break; case PACK_CMD_SCAN_START: - reply = handle_scan_start(pack, used, required); + reply = handle_scan_start(pack, used, required, session); break; case PACK_CMD_SCAN_STOP: - reply = handle_scan_stop(pack, used, required); + reply = handle_scan_stop(pack, used, required, session); break; default: if(used) @@ -198,7 +212,7 @@ bool async_scanner::on_energy_conservation(bool normal) return enable; } -dyn_mem_ptr async_scanner::handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = dyn_mem::memory(base_head_size); @@ -210,7 +224,7 @@ dyn_mem_ptr async_scanner::handle_simple_roger(LPPACK_BASE pack, uint32_t* used, return reply; } -dyn_mem_ptr async_scanner::handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = nullptr; @@ -242,7 +256,7 @@ dyn_mem_ptr async_scanner::handle_get_opt_value(LPPACK_BASE pack, uint32_t* used return reply; } -dyn_mem_ptr async_scanner::handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = nullptr; @@ -263,7 +277,7 @@ dyn_mem_ptr async_scanner::handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, return reply; } -dyn_mem_ptr async_scanner::handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = nullptr; @@ -305,7 +319,7 @@ dyn_mem_ptr async_scanner::handle_set_opt(LPPACK_BASE pack, uint32_t* used, pack return reply; } -dyn_mem_ptr async_scanner::handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = nullptr; @@ -342,7 +356,7 @@ dyn_mem_ptr async_scanner::handle_file_receive(LPPACK_BASE pack, uint32_t* used, return reply; } -dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = dyn_mem::memory(base_head_size); @@ -387,7 +401,7 @@ dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, pa return reply; } -dyn_mem_ptr async_scanner::handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = nullptr; @@ -434,7 +448,7 @@ dyn_mem_ptr async_scanner::handle_file_send_roger(LPPACK_BASE pack, uint32_t* us return reply; } -dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { if(!used) { @@ -452,24 +466,26 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p auto receiver = [this](dyn_mem_ptr data, bool img, LPPACKIMAGE lpinfo) -> void { - if(img) - { - FILE* dst = fopen(("/tmp/scan_" + std::to_string(lpinfo->pos.paper_ind) + ".bmp").c_str(), "wb"); - if(dst) - { - std::string bih(utils::bitmap_info_header(lpinfo->width, lpinfo->height, lpinfo->bpp, lpinfo->resolution_x, lpinfo->resolution_y)), - bfh(utils::bitmap_file_header((BITMAPINFOHEADER*)&bih[0])); - fwrite(bfh.c_str(), 1, bfh.length(), dst); - fwrite(bih.c_str(), 1, bih.length(), dst); - fwrite(data->ptr(), 1, ((BITMAPINFOHEADER*)&bih[0])->biSizeImage, dst); - fclose(dst); - } - data->release(); - } + img_prcr_->process(lpinfo, data, img); + // if(img) + // { + // FILE* dst = fopen(("/tmp/scan_" + std::to_string(lpinfo->pos.paper_ind) + ".bmp").c_str(), "wb"); + // if(dst) + // { + // std::string bih(utils::bitmap_info_header(lpinfo->width, lpinfo->height, lpinfo->bpp, lpinfo->resolution_x, lpinfo->resolution_y)), + // bfh(utils::bitmap_file_header((BITMAPINFOHEADER*)&bih[0])); + // fwrite(bfh.c_str(), 1, bfh.length(), dst); + // fwrite(bih.c_str(), 1, bih.length(), dst); + // fwrite(data->ptr(), 1, ((BITMAPINFOHEADER*)&bih[0])->biSizeImage, dst); + // fclose(dst); + // } + // data->release(); + // } }; *used = base_head_size; reply->set_len(base_head_size); + img_prcr_->start_new_turn(scan_id_, session); scan_err_ = cis_->open(receiver); if(scan_err_ == 0) scan_err_ = cis_->start_scan(); @@ -482,7 +498,7 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p return reply; } -dyn_mem_ptr async_scanner::handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = dyn_mem::memory(base_head_size); @@ -496,7 +512,7 @@ dyn_mem_ptr async_scanner::handle_scan_stop(LPPACK_BASE pack, uint32_t* used, pa return reply; } -dyn_mem_ptr async_scanner::handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required) +dyn_mem_ptr async_scanner::handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session) { uint32_t base_head_size = sizeof(PACK_BASE); dyn_mem_ptr reply = dyn_mem::memory(base_head_size); @@ -512,6 +528,9 @@ dyn_mem_ptr async_scanner::handle_process_cmd(LPPACK_BASE pack, uint32_t* used, uint32_t async_scanner::stop(void) { + if(img_prcr_) + img_prcr_->stop(); + if(usb_) { usb_->stop(); diff --git a/scanner/async_scanner.h b/scanner/async_scanner.h index a7d3ee6..b1939b7 100644 --- a/scanner/async_scanner.h +++ b/scanner/async_scanner.h @@ -18,6 +18,7 @@ class gb_json; class scanner_const_opts; class scanner_hw; class user_priv; +class imgproc_mgr; class async_scanner : public refer { @@ -26,6 +27,7 @@ class async_scanner : public refer scanner_const_opts *const_opts_ = nullptr; scanner_hw *cis_ = nullptr; user_priv *user_ = nullptr; + imgproc_mgr *img_prcr_ = nullptr; MUTEX locker_; volatile bool connected_ = false; @@ -38,20 +40,20 @@ class async_scanner : public refer MUTEX fsender_; std::vector send_files_; - dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); void init(void); bool on_energy_conservation(bool normal/*true - working status; false - go to sleep*/); // return true to enable get into 'normal' status - dyn_mem_ptr handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); - dyn_mem_ptr handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required); + dyn_mem_ptr handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_get_opt_value(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_get_opt_all(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); + dyn_mem_ptr handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session); public: async_scanner(); diff --git a/scanner/scanner_const_opts.cpp b/scanner/scanner_const_opts.cpp index b2b48b5..4d34bbd 100644 --- a/scanner/scanner_const_opts.cpp +++ b/scanner/scanner_const_opts.cpp @@ -35,7 +35,7 @@ scanner_const_opts::scanner_const_opts(const char* dev_path) : root_(dev_path) scanner_const_opts::~scanner_const_opts() {} -std::string scanner_const_opts::get_device_content(const char* path) +std::string scanner_const_opts::get_device_content(const char* path, bool truncate_from_lrn) { FILE *src = fopen((root_ + "/" + path).c_str(), "rb"); char buf[1024] = {0}; @@ -47,6 +47,16 @@ std::string scanner_const_opts::get_device_content(const char* path) while((r = fread(buf, 1, sizeof(buf), src)) > 0) ret += std::string(buf, r); fclose(src); + + if(truncate_from_lrn) + { + size_t pos = ret.find("\n"); + if(pos != std::string::npos) + ret.erase(pos); + pos = ret.find("\r"); + if(pos != std::string::npos) + ret.erase(pos); + } } return std::move(ret); @@ -121,7 +131,7 @@ void scanner_const_opts::init(void) jsn->get_value(SANE_STD_OPT_NAME_DEVICE_SERIAL_NO, child); if(child) { - std::string val(get_device_content("strings/0x409/serialnumber")); + std::string val(get_device_content("strings/0x409/serialnumber", true)); child->set_value("cur", val.c_str()); child->set_value("default", val.c_str()); child->release(); @@ -190,7 +200,7 @@ char* scanner_const_opts::get_value(const char* name, void* value, size_t* size, } else if(strcmp(name, SANE_STD_OPT_NAME_DEVICE_SERIAL_NO) == 0) { - val = get_device_content("strings/0x409/serialnumber"); + val = get_device_content("strings/0x409/serialnumber", true); } else if(strcmp(name, SANE_STD_OPT_NAME_FIRMWARE_VERSION) == 0) { diff --git a/scanner/scanner_const_opts.h b/scanner/scanner_const_opts.h index e2320d9..64778e3 100644 --- a/scanner/scanner_const_opts.h +++ b/scanner/scanner_const_opts.h @@ -10,7 +10,7 @@ class scanner_const_opts : public sane_opt_provider { std::string root_; - std::string get_device_content(const char* path); + std::string get_device_content(const char* path, bool truncate_from_lrn = false); std::string get_ip(void); std::string get_mac(void); diff --git a/scanner/xmake.lua b/scanner/xmake.lua index 2f54ef9..508ed6c 100644 --- a/scanner/xmake.lua +++ b/scanner/xmake.lua @@ -3,11 +3,11 @@ add_rules("mode.debug", "mode.release") target("hgscanner") set_kind("binary") add_syslinks("pthread", "dl") - add_includedirs("../sdk", "../usb", "../sdk/imgprc/3rdsdk/include", "../hardware") + add_includedirs("../sdk", "../usb", "../sdk/imgprc/3rdsdk/include", "../hardware", "../imgproc") add_files("*.cpp", "../sdk/base/*.c*", "../sdk/imgprc/*.c*", "../sdk/json/*.c*", "../sdk/sane_opt_json/*.c*") --add_deps("gusb", "applog") --add_rules("utils.bin2c",{linewidth = 32,extension = {".bin"}}) --add_files("table.bin") add_packages("sdk") add_deps("usb") - add_deps("hardware") \ No newline at end of file + add_deps("hardware", "imgproc") \ No newline at end of file diff --git a/sdk/base/data.cpp b/sdk/base/data.cpp index cbc35a0..292b456 100644 --- a/sdk/base/data.cpp +++ b/sdk/base/data.cpp @@ -829,7 +829,126 @@ uint8_t* file_map::buffer(void) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// +// image_packet +image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid, const void* info, size_t info_size) + : img_(img), offset_(0), info_over_(false) +{ + LPPACK_BASE pack = nullptr; + LPPACKIMAGE pimg = nullptr; + + paper_ind_ = head->pos.paper_ind; + img->add_ref(); + if(info && info_size) + info_ = std::string((const char*)info, info_size); + else + info_ = ""; + + head_ = dyn_mem::memory(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); + pack = (LPPACK_BASE)head_->ptr(); + pimg = (LPPACKIMAGE)pack->payload; + BASE_PACKET_REPLY(*pack, PACK_CMD_SCAN_IMG_ROGER, scanid, 0); + pack->payload_len = sizeof(PACKIMAGE); + + memcpy(pimg, head, sizeof(*pimg)); + pimg->data_size = img->get_rest(); + pimg->info_size = info_size; + + head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE)); + info_over_ = info_.empty(); + + char buf[128] = {0}; + + sprintf(buf, "Image-%04u", head->pos.paper_ind); + pos_str_ = buf; + if(head->pos.paper_side == PAPER_SIDE_FRONT) + pos_str_ += "F_"; + else if(head->pos.paper_side == PAPER_SIDE_BACK) + pos_str_ += "B_"; + else + pos_str_ += "C_"; + pos_str_ += std::to_string(head->pos.split_ind); +} +image_packet::~image_packet() +{ + head_->release(); + img_->release(); +} + +bool image_packet::is_memory_block(void) +{ + return false; +} +uint32_t image_packet::get_rest(void) +{ + return head_->get_rest() + info_.length() + img_->get_rest() - offset_; +} + +// following API valid when is_memory_block() return true +uint8_t* image_packet::ptr(void) +{ + return nullptr; +} + +// following API valid when is_memory_block() return false. return error code +int image_packet::fetch_data(void* buf, uint32_t* size) +{ + if(head_->get_rest()) + { + if(*size < head_->get_rest()) + { + memcpy(buf, head_->ptr(), *size); + } + else + { + memcpy(buf, head_->ptr(), head_->get_rest()); + *size = head_->get_rest(); + } + head_->used(*size); + } + else if(!info_over_) + { + if(*size < info_.length() - offset_) + { + memcpy(buf, info_.c_str() + offset_, *size); + offset_ += *size; + } + else + { + memcpy(buf, info_.c_str() + offset_, info_.length() - offset_); + *size = info_.length() - offset_; + + info_over_ = true; + info_ = ""; + offset_ = 0; + } + } + else + { + if(*size + offset_ >= img_->get_rest()) + { + memcpy(buf, img_->ptr() + offset_, img_->get_rest() - offset_); + *size = img_->get_rest() - offset_; + offset_ = img_->get_rest(); + } + else + { + memcpy(buf, img_->ptr() + offset_, *size); + offset_ += *size; + } + } + + return 0; +} + +uint32_t image_packet::get_paper_index(void) +{ + return paper_ind_; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// dyn_mem_pool dyn_mem_pool::dyn_mem_pool(uint32_t cnt, uint32_t unit) : count_(cnt), unit_(unit) { pool_ = (dyn_mem_ptr*)malloc(cnt * sizeof(dyn_mem_ptr)); diff --git a/sdk/base/data.h b/sdk/base/data.h index 9bf507a..3a42a83 100644 --- a/sdk/base/data.h +++ b/sdk/base/data.h @@ -286,6 +286,35 @@ public: virtual int fetch_data(void* buf, uint32_t* size) override; }; +class image_packet : public data_source +{ + dyn_mem* img_; + dyn_mem* head_; + uint32_t offset_; + uint32_t paper_ind_ = 0; + std::string info_; + bool info_over_; + std::string pos_str_; + +public: + image_packet(LPPACKIMAGE head, dyn_mem* img, uint32_t scanid, const void* info = nullptr, size_t info_size = 0); + +protected: + virtual ~image_packet(); + +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. return error code + virtual int fetch_data(void* buf, uint32_t* size) override; + +public: + uint32_t get_paper_index(void); +}; CLS_PTR(packet_data_base); CLS_PTR(data_holder); @@ -294,6 +323,7 @@ CLS_PTR(data_source); CLS_PTR(dyn_mem); CLS_PTR(dyn_mem_shared); CLS_PTR(file_reader); +CLS_PTR(image_packet); class dyn_mem_pool : public refer diff --git a/sdk/base/packet.h b/sdk/base/packet.h index 87c6853..57a2c51 100644 --- a/sdk/base/packet.h +++ b/sdk/base/packet.h @@ -303,7 +303,8 @@ typedef struct _pack_img 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) + uint64_t prc_stage : 16; // position of image processor, 0 is raw from CIS directly + uint64_t data_size : 48; // 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) diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index c3a96f0..8a2cb6c 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -2125,13 +2125,16 @@ int safe_thread::stop(const char* thread_name) SIMPLE_LOCK(lock_); for(int i = 0; i < threads_.size(); ++i) { - if(threads_[i].name == thread_name) + if(!thread_name || threads_[i].name == thread_name) { if(threads_[i].thread.get() && threads_[i].thread->joinable()) threads_[i].thread->join(); threads_.erase(threads_.begin() + i); ret = 0; - break; + if(thread_name) + break; + else + i--; } } diff --git a/sdk/imgprc/img_processor.cpp b/sdk/imgprc/img_processor.cpp new file mode 100644 index 0000000..6c26902 --- /dev/null +++ b/sdk/imgprc/img_processor.cpp @@ -0,0 +1,48 @@ +#include "img_processor.h" + +#include +#include + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// image_processor +image_processor::image_processor(const char* alg_name) : enabled_(true), ver_(0), pos_(0) +{ + set_where(alg_name); +} +image_processor::~image_processor() +{} + +bool image_processor::set_opt_json_text(char* txt) +{ + gb_json* jsn = new gb_json(); + bool ret = jsn->attach_text(txt); + + if (ret) + { + gb_json* first = jsn->first_child(); + if (first) + { + first->get_value("ver", ver_); + first->get_value("position", pos_); + if (!first->get_value("enabled", enabled_)) + enabled_ = true; + first->release(); + } + } + jsn->release(); + + if (ret) + sane_opt_provider::set_opt_json_text(txt); + + return ret; +} + + + + +int image_processor::process(LPPROCIIM* in, size_t cnt, bool(*result)(LPPROCIIM, void*), void* param) +{ + return SCANNER_ERR_DEVICE_NOT_SUPPORT; +} diff --git a/sdk/imgprc/img_processor.h b/sdk/imgprc/img_processor.h new file mode 100644 index 0000000..038e282 --- /dev/null +++ b/sdk/imgprc/img_processor.h @@ -0,0 +1,58 @@ +#pragma once + +// image processor +// +// created on 2023-11-07 +// +// ver: 1.0 +// +// NOTE: the interface is for all algorithms are in ONE module + +#include +#include +#include + +#pragma pack(push) +#pragma pack(1) + +typedef struct _proc_img_info_ +{ + PACKIMAGE info; + cv::Mat img; + std::string ext_info; // 图片扩展信息(图像处理过程中可以保存各算法间的共有信息;处理完后为向用户提供的扩展信息) +}PROCIMGINFO, *LPPROCIMGINFO; + +typedef struct _proc_img_info_modules // 跨模块参数 +{ + PACKIMAGE info; + uint32_t bytes_per_line; + uint8_t* data; // size = bytes_per_line * height +}PROCIIM, *LPPROCIIM; +#pragma pack(pop) + +class image_processor : public sane_opt_provider +{ +protected: + bool enabled_; + int ver_; + int pos_; + +public: + image_processor(const char* alg_name); + +protected: + virtual ~image_processor(); + + bool set_opt_json_text(char* txt); + +public: + bool is_enable(void) { return enabled_; } + int get_version(void) { return ver_; } + int get_position(void) { return pos_; } + + virtual int process(std::vector& in, std::vector& out) = 0; + + // 跨模块图像处理接口。回调函数返回false,则停止处理;void*参数同 'param'。 + virtual int process(LPPROCIIM* in, size_t cnt, bool(*result)(LPPROCIIM, void*), void* param); +}; + diff --git a/sdk/sane/sane_ex.h b/sdk/sane/sane_ex.h index 6e70a84..1a91652 100644 --- a/sdk/sane/sane_ex.h +++ b/sdk/sane/sane_ex.h @@ -244,6 +244,8 @@ enum opt_visible_level // "visible" field // // PART III: inner option on device +#define SANE_STD_OPT_NAME_CIS_MODE "cis-mode" +#define SANE_STD_OPT_NAME_CIS_DPI "cis-dpi" #define SANE_STD_OPT_NAME_CIS_BAUD "baud" #define SANE_STD_OPT_NAME_CIS_DELAY "act-after" #define SANE_STD_OPT_NAME_CIS_FRAME_H "frame-h" diff --git a/sdk/sane_opt_json/base_opt.cpp b/sdk/sane_opt_json/base_opt.cpp index 13b5380..c840773 100644 --- a/sdk/sane_opt_json/base_opt.cpp +++ b/sdk/sane_opt_json/base_opt.cpp @@ -31,9 +31,10 @@ std::string sane_opt_provider::sane_value_2_text(const char* type, void* value) else return ""; } -void sane_opt_provider::set_opt_value(gb_json* opt, void* value, const char* key) +bool sane_opt_provider::set_opt_value(gb_json* opt, void* value, const char* key) { std::string type(""); + bool ret = true; opt->get_value("type", type); if (!key || *key == 0) @@ -55,6 +56,38 @@ void sane_opt_provider::set_opt_value(gb_json* opt, void* value, const char* key { opt->set_value(key, (char*)value); } + else + { + ret = false; + } + + return ret; +} +bool sane_opt_provider::is_opt_value_equal(gb_json* opt, void* v1, void* v2) +{ + std::string type(""); + bool ret = true; + + opt->get_value("type", type); + + if (type == JSON_SANE_TYPE_BOOL) + { + ret = *(bool*)v1 == *(bool*)v2; + } + else if (type == JSON_SANE_TYPE_INT) + { + ret = *(int*)v1 == *(int*)v2; + } + else if (type == JSON_SANE_TYPE_FIXED) + { + ret = *(double*)v1 == *(double*)v2; + } + else if (type == JSON_SANE_TYPE_STRING) + { + ret = strcmp((char*)v1, (char*)v2) == 0; + } + + return ret; } bool sane_opt_provider::set_opt_json_text(char* txt) diff --git a/sdk/sane_opt_json/base_opt.h b/sdk/sane_opt_json/base_opt.h index 5c93bdf..b1d0c86 100644 --- a/sdk/sane_opt_json/base_opt.h +++ b/sdk/sane_opt_json/base_opt.h @@ -13,7 +13,7 @@ class gb_json; class sane_opt_provider : public refer { - bool is_in_another_module_; + bool is_in_another_module_ = false; std::string opt_jsn_txt_; std::string where_; @@ -25,7 +25,8 @@ public: sane_opt_provider(); static std::string sane_value_2_text(const char* type, void* value); // convert to readable text. e.g. bool to "true" or "false", ... - static void set_opt_value(gb_json* opt, void* value, const char* key = "cur"); + static bool set_opt_value(gb_json* opt, void* value, const char* key = "cur"); + static bool is_opt_value_equal(gb_json* opt, void* v1, void* v2); protected: virtual ~sane_opt_provider(); @@ -43,7 +44,7 @@ public: public: // return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr); - virtual int set_value(const char* name, void* val); + virtual int set_value(const char* name/*nullptr for all options*/, void* val/*nullptr for restore*/); virtual void enable(const char* name, bool able); }; diff --git a/sdk/sane_opt_json/device_opt.cpp b/sdk/sane_opt_json/device_opt.cpp index d32542e..dc59f78 100644 --- a/sdk/sane_opt_json/device_opt.cpp +++ b/sdk/sane_opt_json/device_opt.cpp @@ -1390,48 +1390,17 @@ gb_json* device_option::copy_opt(gb_json* from, bool* changed_cur) apply_cur = false; if (!from->get_value("readonly", rdo)) rdo = false; - to->get_value("type", type); if (changed_cur) *changed_cur = apply_cur; - if (type == JSON_SANE_TYPE_BOOL) + sane_opt_provider::set_opt_value(to, &val[0], "default"); + if (apply_cur) { - to->set_value("default", *(bool*)val.c_str()); - if (apply_cur) - { - to->set_value("cur", *(bool*)val.c_str()); + if (sane_opt_provider::set_opt_value(to, &val[0], "cur")) update_provider_value(to->key().c_str(), &val[0], rdo); - } + else if (changed_cur) + *changed_cur = false; } - else if (type == JSON_SANE_TYPE_INT) - { - to->set_value("default", *(int*)val.c_str()); - if (apply_cur) - { - to->set_value("cur", *(int*)val.c_str()); - update_provider_value(to->key().c_str(), &val[0], rdo); - } - } - else if (type == JSON_SANE_TYPE_FIXED) - { - to->set_value("default", *(double*)val.c_str()); - if (apply_cur) - { - to->set_value("cur", *(double*)val.c_str()); - update_provider_value(to->key().c_str(), &val[0], rdo); - } - } - else if (type == JSON_SANE_TYPE_STRING) - { - to->set_value("default", val.c_str()); - if (apply_cur) - { - to->set_value("cur", val.c_str()); - update_provider_value(to->key().c_str(), &val[0], rdo); - } - } - else if (changed_cur) - *changed_cur = false; } // 4: range value ... @@ -1672,8 +1641,10 @@ bool device_option::to_now(bool init, bool* changed) return now_ != nullptr; } -void device_option::update_provider_value(const char* name, void* value, bool skip_first) +int device_option::update_provider_value(const char* name, void* value, bool skip_first) { + int ret = SCANNER_ERR_OK; + if (src_.count(name)) { sane_opt_provider* opt = nullptr; @@ -1690,13 +1661,65 @@ void device_option::update_provider_value(const char* name, void* value, bool sk while (opt) { - opt->set_value(name, value); + int err = opt->set_value(name, value); + if (err == SCANNER_ERR_RELOAD_OPT_PARAM || + err == SCANNER_ERR_CONFIGURATION_CHANGED) + { + ret = err; + } sane_opt_provider* next = opt->get_following(name); opt->release(); opt = next; } } + + return ret; +} +void device_option::remove_provider(gb_json* root, sane_opt_provider* sop) +{ + if (root) + { + gb_json* child = root->first_child(); + while (child) + { + bool chk_child = src_.count(child->key()) == 0; + if (!chk_child) + { + sane_opt_provider* sp = src_[child->key()], + * next = sp->get_following(child->key().c_str()); + + sp->add_ref(); + while (sp) + { + if (sp == sop) + { + if (next) + src_[child->key()] = next; + else + src_.erase(child->key()); + sp->release(); // release from map: src_ + chk_child = true; + break; + } + sp->release(); // release from get_following + sp = next; + next = sp->get_following(child->key().c_str()); + } + } + if (chk_child && src_.count(child->key()) == 0) + { + utils::to_log(LOG_LEVEL_DEBUG, "remove_provider: Remove option '%s' from '%s'\n", child->key().c_str(), sop->from()); + root->remove(child); + child->release(); + child = root->first_child(); + continue; + } + + child->release(); + child = root->next_child(); + } + } } std::string device_option::option_value(gb_json* jsn, bool def_val) @@ -1824,7 +1847,7 @@ void device_option::clear(void) v.second->release(); src_.clear(); } -bool device_option::add(sane_opt_provider* sop) +bool device_option::add(sane_opt_provider* sop, bool apply_default_val) { bool ret = false; @@ -1833,7 +1856,10 @@ bool device_option::add(sane_opt_provider* sop) { ret = to_now(true, nullptr); if (ret) - restore(nullptr); + { + if(apply_default_val) + restore(nullptr); + } else clear(); } @@ -1844,6 +1870,13 @@ bool device_option::add(sane_opt_provider* sop) return ret; } +bool device_option::remove(sane_opt_provider* sop) +{ + remove_provider(origin_, sop); + remove_provider(now_, sop); + + return true; +} bool device_option::refine_data(const char* name, void* value) { bool refined = false; @@ -1915,8 +1948,7 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne bool changed = false; // pass to sane_opt_provider ... - err = SCANNER_ERR_OK; - update_provider_value(name, value); + err = update_provider_value(name, value); child->get_value("type", type); utils::to_log(LOG_LEVEL_DEBUG, "set option '%s' value to '%s' = %d.\n", name, sane_opt_provider::sane_value_2_text(type.c_str(), value).c_str(), err); @@ -1925,26 +1957,16 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne || err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM || err == SCANNER_ERR_CONFIGURATION_CHANGED) { - if (type == JSON_SANE_TYPE_BOOL) + gb_json* org = nullptr; + + sane_opt_provider::set_opt_value(child, value); + origin_->get_value(name, org); + if (org) { - child->set_value("cur", *(bool*)value); - changed = *(bool*)value != *(bool*)pre.c_str(); - } - else if (type == JSON_SANE_TYPE_INT) - { - child->set_value("cur", *(int*)value); - changed = *(int*)value != *(int*)pre.c_str(); - } - else if (type == JSON_SANE_TYPE_FIXED) - { - child->set_value("cur", *(double*)value); - changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str()); - } - else if (type == JSON_SANE_TYPE_STRING) - { - child->set_value("cur", (char*)value); - changed = pre != (char*)value; + sane_opt_provider::set_opt_value(org, value); + org->release(); } + changed = !sane_opt_provider::is_opt_value_equal(child, &pre[0], value); // set paper-w and paper-h if (strcmp(name, SANE_STD_OPT_NAME_PAPER) == 0 || @@ -2123,7 +2145,10 @@ std::string device_option::get_option_value(const char* name, int type, int* siz { if (!name) { - value = jsn->to_string(); + if (no_grp_ && origin_) + value = origin_->to_string(); + else + value = jsn->to_string(); } else { diff --git a/sdk/sane_opt_json/device_opt.h b/sdk/sane_opt_json/device_opt.h index d38397a..47168a4 100644 --- a/sdk/sane_opt_json/device_opt.h +++ b/sdk/sane_opt_json/device_opt.h @@ -3,6 +3,15 @@ // // Created: 2023-09-07 // +// Design: all option-JSONs should added into device_option object +// +// and all option-logics execute in it; +// +// Exception: if some sane_opt_providers has its own manager object 'device_option' +// +// and I cannot get the origin JSON from the provider, how to resolve this ??? +// +// Solution: return origin JSON if device_option is below other device_option! #pragma once @@ -24,7 +33,7 @@ class device_option : public refer { gb_json* origin_; gb_json* now_; - bool no_grp_ = false; + bool no_grp_ = false; // i am a lower option manager, need not group std::map src_; std::vector master_opts_; // options that value changed will affect others std::map slaver_; @@ -184,7 +193,8 @@ class device_option : public refer gb_json* copy_opt(gb_json* from, bool *changed_cur = nullptr); int visibility(gb_json* jsn); bool to_now(bool init, bool* changed); - void update_provider_value(const char* name, void* value, bool skip_first = false/*readonly value should skip first*/); + int update_provider_value(const char* name, void* value, bool skip_first = false/*readonly value should skip first*/); + void remove_provider(gb_json* root, sane_opt_provider* sop); protected: static std::string option_value(gb_json* jsn, bool def_val); @@ -358,7 +368,8 @@ public: public: void clear(void); - bool add(sane_opt_provider* sop); + bool add(sane_opt_provider* sop, bool apply_default_val = true); + bool remove(sane_opt_provider* sop); bool refine_data(const char* name, void* value); // return true if the 'value' is out of range and refined it in the range int update_data(const char* name, void* value, bool reorder_if_need = true); // return scanner_err. name and value would be null if invoked for language changed int restore(sane_opt_provider* holder); // @@ -373,43 +384,3 @@ public: std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null }; -//{ -// "resolution": { -// "cat": "base", -// "group" : "base", -// "title" : "�ֱ���", -// "desc" : "����ɨ��ͼ��ķֱ���", -// "type" : "int", -// "fix-id" : 34840, -// "size" : 4, -// "cur" : 200, -// "default" : 200, -// "range" : { -// "min": 100, -// "max" : { -// "default": 600, -// "paper==���ɨ��ߴ��Զ����� || paper==���ɨ��ߴ� || paper==�����Ծ�" : 500 -// }, -// "step" : 1 -// } -// }, -// -// "paper": { -// "cat": "base", -// "group" : "base", -// "title" : "ֽ�ųߴ�", -// "desc" : "���ó�ͼ��С", -// "type" : "string", -// "fix-id" : 34831, -// "size" : 44, -// "cur" : "ƥ��ԭʼ�ߴ�", -// "default" : "ƥ��ԭʼ�ߴ�", -// "range" : ["A3", "8��", "A4", "16��", "A5", "A6", "B4", "B5", "B6", "Letter", "Double Letter", "LEGAL", "ƥ��ԭʼ�ߴ�", { -// "resolution<500": "���ɨ��ߴ��Զ�����" -// }, { -// "resolution<500": "���ɨ��ߴ�" -// }, { -// "resolution<500": "�����Ծ�" -// }] -// } -//} diff --git a/xmake.lua b/xmake.lua index 194f472..54dd66c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -60,8 +60,8 @@ add_packagedirs("sdk") add_defines("BUILD_AS_DEVICE") add_defines("VER_MAIN=2") add_defines("VER_FAMILY=200") -add_defines("VER_DATE=20240113") -add_defines("VER_BUILD=4") +add_defines("VER_DATE=20240116") +add_defines("VER_BUILD=11") target("conf") set_kind("phony") @@ -70,7 +70,7 @@ target("conf") add_configfiles("config.h.in", {prefixdir = "header"}) add_includedirs("$(buildir)/config/header", { public = true }) -includes("usb", "hardware", "scanner", "ui") +includes("usb", "hardware", "imgproc", "scanner", "ui")