From d4fa615534505950d639630e3406d7550a1076c2 Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Thu, 29 Feb 2024 15:45:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E5=83=8F=E5=8C=85=E5=A4=B4=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=BB=8E=E9=87=87=E9=9B=86=E6=8C=87=E4=BB=A4=E5=88=B0?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E8=BE=93=E5=87=BA=E7=9A=84=E6=80=BB=E6=97=B6?= =?UTF-8?q?=E9=97=B4=EF=BC=9B=E4=BC=98=E5=8C=96=E4=B8=AD=E9=97=B4=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=AD=98=E5=82=A8=E5=90=8D=E7=A7=B0=EF=BC=9B=E5=BB=B6?= =?UTF-8?q?=E9=95=BF=E5=8D=87=E9=99=8D=E5=8F=B0=E7=AD=89=E5=BE=85=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=8F=8A=E5=87=BA=E7=BA=B8=E6=97=B6=E9=97=B4=E7=AD=89?= =?UTF-8?q?=E5=BE=85=EF=BC=9BCIS=E7=BC=93=E5=86=B2=E5=8C=BA=E5=B0=8F?= =?UTF-8?q?=E4=BA=8E3=E7=9A=84=E6=97=B6=E5=80=99=E7=AD=89=E5=BE=85?= =?UTF-8?q?=EF=BC=9B=E5=9B=BE=E5=83=8F=E7=BA=BF=E7=A8=8B=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=88=B04=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/sane-opts/auto_crop.txt | 16 ++++++- hardware/hardware.cpp | 6 ++- hardware/hardware.h | 4 +- imgproc/algs/auto_crop.cpp | 9 +++- imgproc/algs/image_encoder.cpp | 13 +----- imgproc/imgprc_mgr.cpp | 78 +++++++++++++++++----------------- scanner/async_scanner.cpp | 4 +- sdk/base/data.cpp | 9 +++- sdk/base/packet.h | 1 + sdk/base/utils.cpp | 6 +++ sdk/base/utils.h | 4 +- sdk/sane/sane_name.h | 1 + 12 files changed, 89 insertions(+), 62 deletions(-) diff --git a/docs/sane-opts/auto_crop.txt b/docs/sane-opts/auto_crop.txt index fd62bd0..bb0d8cb 100644 --- a/docs/sane-opts/auto_crop.txt +++ b/docs/sane-opts/auto_crop.txt @@ -1,11 +1,25 @@ { + "crop": { + "cat": "imgp", + "group": "imgp", + "title": "裁切", + "desc": "按图片大小裁切", + "type": "bool", + "pos": 30, + "ui-pos": -1, + "auth": 0, + "size": 4, + "cur": true, + "default": true, + "depend": "page!=对折" + }, "is-anti-skew": { "cat": "imgp", "group": "imgp", "title": "自动纠偏", "desc": "自动纠正歪斜送入的文稿图像", "type": "bool", - "pos": 30, + "pos": 33, "fix-id": 34844, "ui-pos": -1, "auth": 0, diff --git a/hardware/hardware.cpp b/hardware/hardware.cpp index 8ebf84f..8c5a0b2 100644 --- a/hardware/hardware.cpp +++ b/hardware/hardware.cpp @@ -11,7 +11,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////// // scanner_hw -#define TEST_1 +// #define TEST_1 #ifdef TEST_1 static std::string device_opt_json[] = { "{\"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]},\"y-dpi\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u8d70\\u7eb8\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8d70\\u7eb8\\u65b9\\u5411\\u7684\\u56fe\\u50cf\\u91c7\\u96c6\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"ui-pos\":13,\"auth\":0,\"bind\":true,\"size\":4,\"default\":{\"resolution>200 && resolution<400\":300,\"resolution>=400\":600,\"default\":200},\"range\":[200,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\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\",\"default\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\",\"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,\"default\":{\"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\":201,\"default\":201},\"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,\"a", @@ -510,6 +510,7 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo* cism, int* cism_c if(mbstopped) *mbstopped = false; + img->life = chronograph::from_process_born(); while(scanning_) { if(!motor_->wait_paper_out(to_paper_out_)) @@ -598,6 +599,7 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo* cism, int* cism_c // should check paper ready ? watch.reset(); motor_->pick_paper(); + img->life = chronograph::from_process_born(); } else { @@ -631,7 +633,7 @@ void scanner_hw::retrieve_v4l2_mem(safe_fifo* mem, int* used) int u = *used, ind = 0; - while(u >= camera_->get_mem_count()) + while(u >= camera_->get_mem_count() - 2) { if(mem->size()) { diff --git a/hardware/hardware.h b/hardware/hardware.h index f56bdab..1bbea81 100644 --- a/hardware/hardware.h +++ b/hardware/hardware.h @@ -94,8 +94,8 @@ class scanner_hw : public sane_opt_provider std::map> opt_handler_; - int to_lifter_ = 5000; // timeout in ms of lifter arrived - int to_paper_out_ = 3000; // timeout in ms of paper passed + int to_lifter_ = 10000; // timeout in ms of lifter arrived + int to_paper_out_ = 5000; // timeout in ms of paper passed int to_stream_ = 5000; // timeout in ms of frame data can be read void init(void); diff --git a/imgproc/algs/auto_crop.cpp b/imgproc/algs/auto_crop.cpp index 2bca010..fa06a08 100644 --- a/imgproc/algs/auto_crop.cpp +++ b/imgproc/algs/auto_crop.cpp @@ -16,7 +16,7 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // static std::string device_opt_json[] = { - "{\"is-anti-skew\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u81ea\\u52a8\\u7ea0\\u504f\",\"desc\":\"\\u81ea\\u52a8\\u7ea0\\u6b63\\u6b6a\\u659c\\u9001\\u5165\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\",\"type\":\"bool\",\"pos\":30,\"fix-id\":34844,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true,\"depend\":\"page!=\\u5bf9\\u6298\"},\"is-erase-black-frame\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u6d88\\u9664\\u9ed1\\u6846\",\"desc\":\"\\u6d88\\u9664\\u6587\\u7a3f\\u8303\\u56f4\\u5916\\u7684\\u9ed1\\u8272\\u80cc\\u666f\",\"type\":\"bool\",\"pos\":35,\"fix-id\":34849,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"bkg-fill-mode\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"type\":\"string\",\"pos\":36,\"fix-id\":34854,\"ui-pos\":-1,\"auth\":0,\"size\":16,\"cur\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"default\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"range\":[\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"\\u51f9\\u591a\\u8fb9\\u5f62\"],\"depend\":\"is-erase-black-frame==true\"},\"threshold\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u9608\\u503c\",\"desc\":\"\\u6587\\u7a3f\\u5e95\\u8272\\u4e0e\\u9ed1\\u8272\\u80cc\\u666f\\u7070\\u5ea6\\u503c\\u7684\\u5dee\\u503c\\u5927\\u4e8e\\u8be5\\u503c\\uff0c\\u624d\\u4f1a\\u88ab\\u8bc6\\u522b\\u4e3a\\u6587\\u7a3f\",\"type\":\"int\",\"pos\":37,\"fix-id\":34851,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":40,\"default\":40,\"range\":{\"min\":30,\"max\":50,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"anti-noise-level\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u6297\\u566a\\u7b49\\u7ea7\",\"desc\":\"\\u80fd\\u591f\\u5bb9\\u5fcd\\u7684\\u80cc\\u666f\\u6742\\u8272\\u6761\\u7eb9\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"pos\":38,\"fix-id\":34852,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":8,\"default\":8,\"range\":{\"min\":2,\"max\":20,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"margin\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"desc\":\"\\u5bfb\\u627e\\u6587\\u7a3f\\u8fb9\\u7f18\\u65f6\\u5bf9\\u8fb9\\u7f18\\u7684\\u4fb5\\u5165\\u7a0b\\u5ea6\",\"type\":\"int\",\"pos\":40,\"fix-id\":34853,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":5,\"default\":5,\"range\":{\"min\":2,\"max\":30,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"pos\":1000,\"fix-id\":34831,\"ui-pos\":-1,\"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\",\"pos\":1000,\"fix-id\":34924,\"ui-pos\":-1,\"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\"}}" + "{\"crop\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u88c1\\u5207\",\"desc\":\"\\u6309\\u56fe\\u7247\\u5927\\u5c0f\\u88c1\\u5207\",\"type\":\"bool\",\"pos\":30,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true,\"depend\":\"page!=\\u5bf9\\u6298\"},\"is-anti-skew\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u81ea\\u52a8\\u7ea0\\u504f\",\"desc\":\"\\u81ea\\u52a8\\u7ea0\\u6b63\\u6b6a\\u659c\\u9001\\u5165\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\",\"type\":\"bool\",\"pos\":33,\"fix-id\":34844,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true,\"depend\":\"page!=\\u5bf9\\u6298\"},\"is-erase-black-frame\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u6d88\\u9664\\u9ed1\\u6846\",\"desc\":\"\\u6d88\\u9664\\u6587\\u7a3f\\u8303\\u56f4\\u5916\\u7684\\u9ed1\\u8272\\u80cc\\u666f\",\"type\":\"bool\",\"pos\":35,\"fix-id\":34849,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"bkg-fill-mode\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"type\":\"string\",\"pos\":36,\"fix-id\":34854,\"ui-pos\":-1,\"auth\":0,\"size\":16,\"cur\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"default\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"range\":[\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"\\u51f9\\u591a\\u8fb9\\u5f62\"],\"depend\":\"is-erase-black-frame==true\"},\"threshold\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u9608\\u503c\",\"desc\":\"\\u6587\\u7a3f\\u5e95\\u8272\\u4e0e\\u9ed1\\u8272\\u80cc\\u666f\\u7070\\u5ea6\\u503c\\u7684\\u5dee\\u503c\\u5927\\u4e8e\\u8be5\\u503c\\uff0c\\u624d\\u4f1a\\u88ab\\u8bc6\\u522b\\u4e3a\\u6587\\u7a3f\",\"type\":\"int\",\"pos\":37,\"fix-id\":34851,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":40,\"default\":40,\"range\":{\"min\":30,\"max\":50,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"anti-noise-level\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u6297\\u566a\\u7b49\\u7ea7\",\"desc\":\"\\u80fd\\u591f\\u5bb9\\u5fcd\\u7684\\u80cc\\u666f\\u6742\\u8272\\u6761\\u7eb9\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"pos\":38,\"fix-id\":34852,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":8,\"default\":8,\"range\":{\"min\":2,\"max\":20,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"margin\":{\"cat\":\"imgp\",\"group\":\"imgp\",\"title\":\"\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"desc\":\"\\u5bfb\\u627e\\u6587\\u7a3f\\u8fb9\\u7f18\\u65f6\\u5bf9\\u8fb9\\u7f18\\u7684\\u4fb5\\u5165\\u7a0b\\u5ea6\",\"type\":\"int\",\"pos\":40,\"fix-id\":34853,\"ui-pos\":-1,\"auth\":0,\"size\":4,\"cur\":5,\"default\":5,\"range\":{\"min\":2,\"max\":30,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"pos\":1000,\"fix-id\":34831,\"ui-pos\":-1,\"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\",\"pos\":1000,\"fix-id\":34924,\"ui-pos\":-1,\"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\"}}" }; static void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue) @@ -66,9 +66,13 @@ auto_crop::~auto_crop() void auto_crop::init(void) { + OPTION_FUNC(crop) + { + enabled_ = *(bool*)val; + }; OPTION_FUNC(deskew) { - enabled_ = deskew_ = *(bool*)val; + deskew_ = *(bool*)val; }; OPTION_FUNC(bg) { @@ -110,6 +114,7 @@ void auto_crop::init(void) lateral_ = *(bool*)val; }; + opt_handler_[SANE_OPT_NAME(CROP)] = crop; opt_handler_[SANE_OPT_NAME(ANTI_SKEW)] = deskew; opt_handler_[SANE_OPT_NAME(ERASE_BLACK_FRAME)] = bg; opt_handler_[SANE_OPT_NAME(FILL_BKG_MODE)] = bgm; diff --git a/imgproc/algs/image_encoder.cpp b/imgproc/algs/image_encoder.cpp index 2199d78..f63db26 100644 --- a/imgproc/algs/image_encoder.cpp +++ b/imgproc/algs/image_encoder.cpp @@ -15,15 +15,7 @@ static std::string device_opt_json[] = { img_encoder::img_encoder() : image_processor("img_encoder") { ADD_THIS_JSON(); - // if (!bwimg) - // { - // compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); - // compression_params.push_back(100); - // } - // else{ - // compression_params.push_back(CV_IMWRITE_PNG_STRATEGY); - // compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED); - // } + param_.push_back(cv::IMWRITE_JPEG_QUALITY); param_.push_back(jpeg_quality_); } @@ -101,12 +93,11 @@ std::shared_ptr> img_encoder::encode(LPPACKIMAGE head, cv::Ma { cv::Mat out; - cv::flip(mat, out, 0); + cv::flip(mat, out, 0); // 0 - flip around x-axis; >0 - flip around y-axis; <0 - flip both x and y ptr.reset(new std::vector()); head->format = fmt_ == ".jpg" ? IMG_FMT_JPEG : IMG_FMT_PNG; cv::imencode(fmt_.c_str(), out, *ptr, param_); head->prc_time = watch.elapse_ms(); - printf("encode to '%s' in %ums: %u\n", fmt_.c_str(), head->prc_time, ptr->size()); } return ptr; diff --git a/imgproc/imgprc_mgr.cpp b/imgproc/imgprc_mgr.cpp index 1de655e..45375e0 100644 --- a/imgproc/imgprc_mgr.cpp +++ b/imgproc/imgprc_mgr.cpp @@ -77,7 +77,10 @@ imgproc_mgr::imgproc_mgr(std::function sender workers_.start(thrd, SIZE_MB(0), "imgproc_mgr::thread_worker", (void*)&imgproc_mgr::thread_worker); }; workers_.set_exception_handler(restart); - workers_.start(thrd, SIZE_MB(0), "imgproc_mgr::thread_worker", (void*)&imgproc_mgr::thread_worker); + workers_.start(thrd, SIZE_MB(0), "thread_worker1", (void*)&imgproc_mgr::thread_worker); + workers_.start(thrd, SIZE_MB(0), "thread_worker2", (void*)&imgproc_mgr::thread_worker); + workers_.start(thrd, SIZE_MB(0), "thread_worker3", (void*)&imgproc_mgr::thread_worker); + workers_.start(thrd, SIZE_MB(0), "thread_worker4", (void*)&imgproc_mgr::thread_worker); } imgproc_mgr::~imgproc_mgr() { @@ -144,11 +147,30 @@ void imgproc_mgr::process(RAWIMG* img) { std::vector in, out, *src = &in, *dst = &out, *swp = nullptr; chronograph watch; + auto realdump = [this](std::vector* arr, LPPACKIMAGE info, cv::Mat* mat, char* infoex, size_t infexl, bool last) -> void + { + if(arr) + send_image(*arr, last); + else + send_image(info, *mat, infoex, infexl, last); + }; + auto emptydump = [this](std::vector* arr, LPPACKIMAGE info, cv::Mat* mat, char* infoex, size_t infexl, bool last) -> void + {}; + std::function* arr, LPPACKIMAGE info, cv::Mat* mat, char* infoex, size_t infexl, bool last)> dump = realdump; + + if(dump_img_) + { + cv::Mat mat(img->info.width, img->info.height, CV_8UC1, img->data->ptr()); + send_image(&img->info, mat, nullptr, 0, false); + } + else + dump = emptydump; if(do_rebuild_) { first_->do_rebuild(&img->info, img->data->ptr(), in); utils::to_log(LOG_LEVEL_ALL, "Rebuild paper %d spend %llu milliseconds.\n", img->info.pos.paper_ind, watch.elapse_ms()); + dump(&in, nullptr, nullptr, nullptr, 0, false); } else { @@ -157,47 +179,21 @@ void imgproc_mgr::process(RAWIMG* img) i.img = cv::Mat(img->info.width, img->info.height, CV_8UC1, img->data->ptr()); in.push_back(i); } + img->data->release(); - if(dump_img_) - { + for(auto& v: processors_) + { + if(v->is_enable()) { - cv::Mat mat(img->info.width, img->info.height, CV_8UC1, img->data->ptr()); - send_image(&img->info, mat, nullptr, 0, false); - } - img->data->release(); - - for(auto& v: processors_) - { - send_image(*src, false); - if(v->is_enable()) - { - process(v, src, dst); - src->clear(); - swp = src; - src = dst; - dst = swp; - } + process(v, src, dst); + src->clear(); + swp = src; + src = dst; + dst = swp; + dump(src, nullptr, nullptr, nullptr, 0, false); } } - else - { - img->data->release(); - for(auto& v: processors_) - { - if(v->is_enable()) - { - process(v, src, dst); - src->clear(); - swp = src; - src = dst; - dst = swp; - } - } - uint32_t t = watch.elapse_ms(); - for(auto& v: in) - v.info.prc_time = t; - } - + send_image(*src, true); } else @@ -250,7 +246,11 @@ void imgproc_mgr::send_image(LPPACKIMAGE head, cv::Mat& mat, void* info, size_t std::shared_ptr> compd(last_->encode(&h, mat)); image_packet_ptr ptr = nullptr; - if(!last) + if(last) + { + h.life = chronograph::from_process_born() - h.life; + } + else { h.prc_stage = head->prc_stage; h.prc_time = head->prc_time; diff --git a/scanner/async_scanner.cpp b/scanner/async_scanner.cpp index 311b863..eb9a162 100644 --- a/scanner/async_scanner.cpp +++ b/scanner/async_scanner.cpp @@ -158,7 +158,7 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0) { cis_->close(); res_mgr_->stop(); - utils::print_memory_usage("Memory usage when finished scanning", false); + utils::print_memory_usage("Memory usage when finished scanning", true); system("sudo cpufreq-set -g ondemand"); } @@ -603,7 +603,7 @@ dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, p return res_mgr_->is_resource_enable((enum _task)task, wait, to_ms); }; - utils::print_memory_usage("Memory usage before scanning", false); + utils::print_memory_usage("Memory usage before scanning", true); *used = base_head_size; img_prcr_->start_new_turn(scan_id_, session); scan_err_ = cis_->open(receiver, res, &config); diff --git a/sdk/base/data.cpp b/sdk/base/data.cpp index 5b3b732..70a0272 100644 --- a/sdk/base/data.cpp +++ b/sdk/base/data.cpp @@ -144,7 +144,7 @@ int image_holder::save_2_file(const char* root_dir, int alg_ind, const char* alg bool bmp = false; file += PATH_SEPARATOR; - sprintf(buf, "%04d_%04x", (uint32_t)head_.pos.paper_ind, alg_ind); + sprintf(buf, "%04d_%04d", (int32_t)head_.pos.paper_ind, alg_ind); file += buf; if (head_.pos.paper_side == PAPER_SIDE_FRONT) file += "_Front"; @@ -156,6 +156,8 @@ int image_holder::save_2_file(const char* root_dir, int alg_ind, const char* alg file += buf; if (alg && *alg) file += std::string("_") + alg; + else + alg = ""; if (head_.format == IMG_FMT_PNG) file += ".png"; else if (head_.format == IMG_FMT_JPEG) @@ -194,7 +196,10 @@ int image_holder::save_2_file(const char* root_dir, int alg_ind, const char* alg if (dst) fclose(dst); - utils::to_log(LOG_LEVEL_ALL, "Image-Process of file '%s' is %ums.\n", file.c_str(), head_.prc_time); + if(strcmp(alg, "img-fmt") == 0) + utils::to_log(LOG_LEVEL_ALL, "Image-Process %s of file '%s' is %ums, total %ums.\n", alg, file.c_str(), head_.prc_time, (int)head_.life); + else + utils::to_log(LOG_LEVEL_ALL, "Image-Process %s of file '%s' is %ums.\n", alg, file.c_str(), head_.prc_time); return err; } diff --git a/sdk/base/packet.h b/sdk/base/packet.h index a39ce0a..457a9d8 100644 --- a/sdk/base/packet.h +++ b/sdk/base/packet.h @@ -309,6 +309,7 @@ typedef struct _img_pos typedef struct _pack_img { IMGPOS pos; // image pos info ... + uint64_t life; // milliseconds from capturer to final output uint32_t width; // image width in pixel. (image-collector set) uint32_t height; // image height in pixel. (image-collector set) uint32_t resolution_x; // image horizontal reolution. (image-collector set) diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index 700f817..7e2a034 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -1970,6 +1970,8 @@ int32_t refer::release(void) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // util +chronograph chronograph::process_born_; + chronograph::chronograph() { reset(); @@ -2022,6 +2024,10 @@ std::string chronograph::now(bool with_ms/*whether with milliseconds*/) return buf; } +uint64_t chronograph::from_process_born(void) +{ + return chronograph::process_born_.elapse_ms(); +} uint64_t chronograph::elapse_s(void) { diff --git a/sdk/base/utils.h b/sdk/base/utils.h index 0565f5e..a39ce64 100644 --- a/sdk/base/utils.h +++ b/sdk/base/utils.h @@ -308,6 +308,7 @@ public: class chronograph { TIMEV bgn_; + static chronograph process_born_; public: chronograph(); @@ -316,7 +317,8 @@ public: static bool now(TIMEV* tv); static bool now(uint64_t* seconds, uint64_t* u_seconds); static std::string now(bool with_ms = true/*whether with milliseconds*/); // return '2022-11-30 10:38:42.123', no '.123' if with_ms was false - + static uint64_t from_process_born(void); + public: uint64_t elapse_s(void); uint64_t elapse_ms(void); diff --git a/sdk/sane/sane_name.h b/sdk/sane/sane_name.h index b096cca..b66eb9b 100644 --- a/sdk/sane/sane_name.h +++ b/sdk/sane/sane_name.h @@ -189,6 +189,7 @@ #define SANE_STD_OPT_NAME_PHASE_BACK "phase-b" #define SANE_STD_OPT_NAME_OUT_FORMAT "img-fmt" #define SANE_STD_OPT_NAME_JPEG_QUALITY "jpeg-quality" +#define SANE_STD_OPT_NAME_CROP "crop"