完善收图流程

This commit is contained in:
gb 2024-01-27 17:56:48 +08:00
parent 5dd444b458
commit bfe7f47b5c
11 changed files with 313 additions and 65 deletions

View File

@ -7,7 +7,7 @@
#include <lang/app_language.h>
#include "./scanner/scanner_handler.h"
#include "user-opt/user.h"
#include <base/paper.h>
@ -146,11 +146,11 @@ void hg_scanner::init(void)
tx_prg_ = cur_size;
tx_prg_ /= total;
if (total != cur_size)
if (total != cur_size || total == FINAL_NOTIFY)
return 0;
raw_imgs_.save(pimg, true);
pimg->add_ref();
raw_imgs_.save(pimg, true);
return 0;
};
@ -249,25 +249,51 @@ void hg_scanner::thread_image_processor(void)
//processor->add_ref();
while (raw_imgs_.take(raw, true))
{
dump_image(raw);
process_image(raw);
raw->release();
}
//processor->release();
}
void hg_scanner::dump_image(image_holder_ptr img)
void hg_scanner::process_image(image_holder_ptr img)
{
if (dump_path_.empty())
return;
PACKIMAGE h;
int stage = img->get_info()->prc_stage;
char alg[128] = { 0 };
h.prc_stage = -1;
if (!dump_path_.empty() && img->get_info()->prc_stage != h.prc_stage)
{
int stage = img->get_info()->prc_stage;
char alg[128] = { 0 };
if (img_prc_name_.count(stage))
sprintf(alg, "%04X_%s", stage, img_prc_name_[stage].c_str());
else
sprintf(alg, "%04X_Unk", stage);
img->save_2_file(dump_path_.c_str(), alg);
if (img_prc_name_.count(stage))
sprintf(alg, "%04X_%s", stage, img_prc_name_[stage].c_str());
else
sprintf(alg, "%04X_Unk", stage);
img->save_2_file(dump_path_.c_str(), alg);
}
if (img->get_info()->prc_stage == h.prc_stage)
{
img->add_ref();
final_imgs_.save(img, true);
}
}
image_holder_ptr hg_scanner::wait_image(void)
{
image_holder_ptr ptr = nullptr;
if (final_imgs_.size() == 0)
{
while (status_ == SCANNER_ERR_DEVICE_BUSY)
{
std::this_thread::sleep_for(std::chrono::milliseconds(3));
if (final_imgs_.size())
break;
}
}
if (final_imgs_.size())
ptr = final_imgs_.front();
return ptr;
}
char* hg_scanner::get_value(const char* name, void* value, size_t* size, int* err)
@ -297,7 +323,10 @@ char* hg_scanner::get_value(const char* name, void* value, size_t* size, int* er
{
uint32_t len = 0;
int result = 0;
size_t l = 0;
if (!size)
size = &l;
dev_opts_->get_option_value_type(name, size);
len = *size;
ret = (char*)malloc(len);
@ -325,6 +354,9 @@ int hg_scanner::set_value(const char* name, void* val)
std::string t(dev_opts_->get_option_value_type(name, &size));
uint16_t after = 0;
if (strcmp(SANE_FULL_NAME(RESOLUTION), name) == 0)
dpi_ = *(int*)val;
if (strcmp(name, SANE_FULL_NAME(DUMP_IMG)) == 0)
{
if (*(bool*)val && dump_path_.empty())
@ -379,6 +411,7 @@ int hg_scanner::start(std::string* devcfg, std::function<void(int)> over_cb)
int ret = SCANNER_ERR_OK;
cancelled_ = false;
clear_images();
if (scanner_)
{
ret = scanner_->scan_start(devcfg);
@ -447,11 +480,99 @@ int hg_scanner::re_connect(void)
}
int hg_scanner::get_image_info(SANE_Parameters* pii)
{
image_holder_ptr ptr = wait_image();
if (ptr)
{
pii->bytes_per_line = (ptr->get_info()->bpp * ptr->get_info()->width * ptr->get_info()->channels + 7) / 8; // no 4-bytes align
pii->depth = ptr->get_info()->bpp; // 此处指每一个颜色分量的位深我们的扫描仪固定为“8”
pii->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”所以也为true
pii->format = ptr->get_info()->channels == 3 ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
pii->lines = ptr->get_info()->height;
pii->pixels_per_line = ptr->get_info()->width;
}
else
{
// default ...
double *w = (double*)get_value(SANE_FULL_NAME(PAPER_W), nullptr, nullptr),
*h = (double*)get_value(SANE_FULL_NAME(PAPER_H), nullptr, nullptr);
int res = dpi_;
SIZE size(paper::size("A3"));
if (w)
{
size.cx = *w;
free(w);
}
if (h)
{
size.cy = *h;
free(h);
}
pii->pixels_per_line = utils::mm_2_pixel(size.cx, res);
pii->lines = utils::mm_2_pixel(size.cy, res);
pii->bytes_per_line = pii->pixels_per_line * 3; // no 4-bytes align
pii->depth = 8; // 此处指每一个颜色分量的位深我们的扫描仪固定为“8”
pii->last_frame = SANE_TRUE; // 一幅图片如果各个分量相互分离则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”所以也为true
pii->format = SANE_FRAME_RGB;
}
return SCANNER_ERR_OK;
}
int hg_scanner::read_image_data(uint8_t* buf, size_t* len)
{
return SCANNER_ERR_OK;
int ret = SCANNER_ERR_INVALID_PARAMETER;
if (len)
{
image_holder_ptr ptr = wait_image();
size_t bufl = *len;
*len = 0;
ret = SCANNER_ERR_NO_DATA;
if (ptr)
{
if (cur_img_pos_ == 0)
cur_img_pos_ = ptr->get_info()->info_size;
if (buf)
{
if (bufl >= ptr->data_length() - cur_img_pos_)
{
*len = ptr->data_length() - cur_img_pos_;
memcpy(buf, ptr->data() + cur_img_pos_, *len);
cur_img_pos_ = 0;
final_imgs_.pop_front();
ptr->release();
}
else
{
memcpy(buf, ptr->data() + cur_img_pos_, bufl);
*len = bufl;
cur_img_pos_ += *len;
ret = SCANNER_ERR_OK;
}
}
else
{
*len = ptr->get_info()->data_size;
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
}
}
}
return ret;
}
int hg_scanner::get_resolution(void)
{
return dpi_;
}
void hg_scanner::clear_images(void)
{
image_holder_ptr img = nullptr;
while (final_imgs_.take(img))
img->release();
cur_img_pos_ = 0;
}
int hg_scanner::status(EP0REPLYSTATUS* ds, bool en_dev_log)
{

View File

@ -59,6 +59,9 @@ class hg_scanner : public sane_opt_provider
volatile bool run_ = true;
safe_fifo<image_holder*> raw_imgs_;
safe_fifo<image_holder*> final_imgs_;
uint32_t cur_img_pos_ = 0; // transmission position of front image
uint32_t dpi_ = 200;
#ifdef USE_SAFE_THREAD
safe_thread imgpr_thread_;
#else
@ -71,7 +74,8 @@ class hg_scanner : public sane_opt_provider
void init(void);
void thread_image_processor(void);
void dump_image(image_holder_ptr img);
void process_image(image_holder_ptr img);
image_holder_ptr wait_image(void);
public:
hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc = nullptr, hguser* user = nullptr, std::vector<sane_opt_provider*>* constopts = nullptr);
@ -92,6 +96,8 @@ public:
int re_connect(void);
int get_image_info(SANE_Parameters* pii);
int read_image_data(uint8_t* buf, size_t* len);
int get_resolution(void);
void clear_images(void);
int status(EP0REPLYSTATUS* ds = nullptr, bool en_dev_log = false/*enable device write log of this status*/);
std::string status_message(void);
bool is_online(void);

View File

@ -656,7 +656,7 @@ int async_usb_host::get_peer_status(LPEP0REPLYSTATUS status, bool en_dev_log)
SIMPLE_LOCK(io_lock_);
return libusb_control_transfer(usb_handle_, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN
, USB_REQ_EP0_GET_STATUS, 0, en_dev_log
, USB_REQ_EP0_GET_STATUS, en_dev_log, 0
, (unsigned char*)status, sizeof(*status)
, 1000) == sizeof(*status) ? 0 : EFAULT;
}

View File

@ -18,7 +18,9 @@ packet_data_base::packet_data_base() : pack_cmd_(0), pack_id_(0)
set_progress_notify();
}
packet_data_base::~packet_data_base()
{}
{
notify_progress(FINAL_NOTIFY, FINAL_NOTIFY, 0);
}
void packet_data_base::set_packet_param(uint32_t cmd, uint32_t id)
{
@ -399,7 +401,6 @@ dyn_mem::dyn_mem(void* buf, size_t size)
dyn_mem::~dyn_mem()
{
notify_progress(space_, len_, 0);
if (buf_)
{
free(buf_);

View File

@ -17,6 +17,7 @@
//
/* packet parameter keeper, parameter of corresponding packet
*/
static const uint64_t FINAL_NOTIFY = -1;
#define PROGRESS_NOTIFYER std::function<int(uint64_t/*total*/, uint64_t/*cur-size*/, uint32_t/*err*/, void* /*user data*/)>
class packet_data_base : public refer

71
sdk/base/paper.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "paper.h"
#include <string>
#include <map>
namespace paper
{
class paper_init
{
std::map<std::string, SIZE> papers_;
public:
paper_init()
{
papers_["A3"] = {297, 420};
papers_["A4"] = {210, 297};
papers_["A5"] = {148, 210};
papers_["A6"] = {105, 148};
papers_["B4"] = {250, 352};
papers_["B5"] = {176, 250};
papers_["B6"] = {125, 176};
papers_["8\345\274\200"] = {285, 420}; // 8开
papers_["16\345\274\200"] = {210, 285}; // 16开
papers_["Letter"] = {216, 322}; // Letter+
papers_["Double Letter"] = {322, 432};
papers_["LEGAL"] = {236, 381}; // Legal+
// 匹配原始尺寸
papers_["\345\214\271\351\205\215\345\216\237\345\247\213\345\260\272\345\257\270"] = papers_["A3"];
// 最大扫描尺寸
papers_["\346\234\200\345\244\247\346\211\253\346\217\217\345\260\272\345\257\270"] = papers_["A3"];
// 最大扫描尺寸自动裁切
papers_["\346\234\200\345\244\247\346\211\253\346\217\217\345\260\272\345\257\270\350\207\252\345\212\250\350\243\201\345\210\207"] = papers_["A3"];
// 三联试卷
papers_["\344\270\211\350\201\224\350\257\225\345\215\267"] = {216, 356};
}
~paper_init()
{
papers_.clear();
}
public:
SIZE size(const char* name)
{
if(papers_.count(name))
return papers_[name];
return {0, 0};
}
};
static paper_init paperi;
// get known paper size in mm
SIZE size(const char* name)
{
return paperi.size(name);
}
void swap_size(SIZE& s)
{
s.cx ^= s.cy;
s.cy ^= s.cx;
s.cx ^= s.cy;
}
};

13
sdk/base/paper.h Normal file
View File

@ -0,0 +1,13 @@
// include paper types info
//
// Date: 2024-01-11
#pragma once
#include "plat_types.h"
namespace paper
{
// get known paper size in mm
SIZE size(const char* name);
void swap_size(SIZE& s);
};

View File

@ -42,7 +42,7 @@ typedef struct BITMAPFILEHEADER
u_int16_t bfReserved1;
u_int16_t bfReserved2;
u_int32_t bfOffBits;
}BITMAPFILEHEADER;
}BITMAPFILEHEADER, *LPBITMAPFILEHEADER;
typedef struct BITMAPINFOHEADER
{
@ -57,7 +57,7 @@ typedef struct BITMAPINFOHEADER
u_int32_t biYPelsPerMeter;
u_int32_t biClrUsed;
u_int32_t biClrImportant;
}BITMAPINFOHEADER;
}BITMAPINFOHEADER, *LPBITMAPINFOHEADER;
typedef struct _size
{
@ -137,3 +137,6 @@ extern uint64_t GetCurrentThreadId(void);
#define pid_t int
#endif
#include "words.h"

View File

@ -861,69 +861,75 @@ namespace utils
return str.c_str();
}
bool from_hex_string(const char* hex, uint8_t* val)
static bool hex_str_2_num(char hex, uint8_t* v)
{
*val = 0;
if(*hex >= '0' && *hex <= '9')
*val = *hex - '0';
else if(*hex >= 'a' && *hex <= 'f')
*val = *hex - 'a' + 10;
else if(*hex >= 'A' && *hex <= 'F')
*val = *hex - 'A' + 10;
*v = 0;
if(hex >= '0' && hex <= '9')
*v = hex - '0';
else if(hex >= 'a' && hex <= 'f')
*v = hex - 'a' + 10;
else if(hex >= 'A' && hex <= 'F')
*v = hex - 'A' + 10;
else
return *hex == 0;
hex++;
if(*hex)
{
*val <<= 4;
if(*hex >= '0' && *hex <= '9')
*val += *hex - '0';
else if(*hex >= 'a' && *hex <= 'f')
*val += *hex - 'a' + 10;
else if(*hex >= 'A' && *hex <= 'F')
*val += *hex - 'A' + 10;
else
return false;
}
return hex == 0;
return true;
}
bool from_hex_string(const char* hex, uint8_t* val)
{
uint8_t t = 0;
bool ret = true;
*val = 0;
for(int i = 0; i < 2 && *hex && (ret = hex_str_2_num(*hex++, &t)); ++i)
{
*val <<= 4;
*val += t;
}
return ret;
}
bool from_hex_string(const char* hex, uint16_t* val)
{
if(from_hex_string(hex, (uint8_t*)val))
{
hex += 2;
*val = swap_half(*val);
uint8_t t = 0;
bool ret = true;
return from_hex_string(hex, (uint8_t*)val);
*val = 0;
for(int i = 0; i < 4 && *hex && (ret = hex_str_2_num(*hex++, &t)); ++i)
{
*val <<= 4;
*val += t;
}
else
return false;
return ret;
}
bool from_hex_string(const char* hex, uint32_t* val)
{
if(from_hex_string(hex, (uint16_t*)val))
uint8_t t = 0;
bool ret = true;
*val = 0;
for(int i = 0; i < 8 && *hex && (ret = hex_str_2_num(*hex++, &t)); ++i)
{
hex += 4;
*val = swap_half(*val);
return from_hex_string(hex, (uint16_t*)val);
*val <<= 4;
*val += t;
}
else
return false;
return ret;
}
bool from_hex_string(const char* hex, uint64_t* val)
{
if(from_hex_string(hex, (uint32_t*)val))
uint8_t t = 0;
bool ret = true;
*val = 0;
for(int i = 0; i < 16 && *hex && (ret = hex_str_2_num(*hex++, &t)); ++i)
{
hex += 8;
*val = swap_half(*val);
return from_hex_string(hex, (uint32_t*)val);
*val <<= 4;
*val += t;
}
else
return false;
return ret;
}

View File

@ -396,6 +396,16 @@ public:
}
}
}
T front(void)
{
SIMPLE_LOCK(lock_);
return que_.front();
}
void pop_front(void)
{
SIMPLE_LOCK(lock_);
que_.pop_front();
}
size_t size(void)
{
SIMPLE_LOCK(lock_);

16
sdk/base/words.h Normal file
View File

@ -0,0 +1,16 @@
// const multi-bytes-words definition
//
// Date: 2024-01-24
#pragma once
#define WORDS_COLOR_COLOR "\345\275\251\350\211\262"
#define WORDS_COLOR_GRAY "\347\201\260\345\272\246"
#define WORDS_PAPER_ORIGIN_SIZE "\345\214\271\351\205\215\345\216\237\345\247\213\345\260\272\345\257\270"
#define WORDS_PAPER_MAX_SIZE_CROP "\346\234\200\345\244\247\346\211\253\346\217\217\345\260\272\345\257\270\350\207\252\345\212\250\350\243\201\345\210\207"
#define WORDS_FORBIDDEN "\347\246\201\347\224\250"
#define WORDS_SCAN_CONTINUOUS "\350\277\236\347\273\255\346\211\253\346\217\217"
#define WORDS_FILLBG_CONVEX "\345\207\270\345\244\232\350\276\271\345\275\242"