完善收图流程
This commit is contained in:
parent
5dd444b458
commit
bfe7f47b5c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
};
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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"
|
Loading…
Reference in New Issue