修复Memory分段传输的BUG;图像信息可控制在传输的时候再生成以兼容部分不通过XferMech协议设备传输模式的APP,目前构造函数中prepare_data设置为true,以保持和以前版本同样的处理方式。若需要兼容,将该变量改为false就可以。

This commit is contained in:
gb 2023-08-04 17:38:26 +08:00
parent d191476f6c
commit d3af46fefa
4 changed files with 147 additions and 140 deletions

View File

@ -381,77 +381,12 @@ unsigned int mapping_buf::mapped_bytes(void)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// class scanned_img // class scanned_img
scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi
, const wchar_t* tmp_file, twain_xfer xfer
, SANE_FinalImgFormat *fmt) : head_(head), dpi_(dpi), header_size_(0), file_(tmp_file ? tmp_file : L"")
, dev_(dev), status_(SANE_Image_Statu_OK)
{
if (fmt)
fmt_ = *fmt;
else
{
fmt_.img_format = SANE_IMAGE_TYPE_BMP;
fmt_.detail = 0;
}
size_t bytes = line_bytes() * height();
std::string h(file_header(fmt_.img_format, (float)dpi, xfer));
unsigned char* dst = NULL;
bool ok = false;
data_ = new mapping_buf();
header_size_ = h.length();
dst = data_->allocate(tmp_file, bytes + h.length());
if (dst)
{
unsigned long long off = 0, total = 0;
bytes = h.length();
if (data_->save(h.c_str(), &bytes, off))
{
unsigned int len = line_bytes();
unsigned long long line = line_bytes();
if (xfer == TWAIN_XFER_Memory)
line *= -1;
else
off = data_->bytes() - line;
dst = data_->buffer(off, &len);
int want_to_read = head_.bytes_per_line, rcv = 0, dif = line_bytes() - head_.bytes_per_line;
while (dst)
{
int r = want_to_read > (int)(len) - rcv ? (int)(len)- rcv : want_to_read;
int ret = hg_sane_middleware::instance()->read(dev, dst + rcv, &r);
total += r;
if (ret != SANE_STATUS_GOOD)
break;
want_to_read -= r;
rcv += r;
if (want_to_read == 0)
{
want_to_read = head_.bytes_per_line;
off -= line;
len = line_bytes();
rcv = 0;
dst = data_->buffer(off, &len);
total += dif;
}
else
{
len = want_to_read;
dst = data_->buffer(off + rcv, &len);
}
}
ok = total + h.length() + dif == data_->bytes();
}
}
do_result(ok, xfer);
}
scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
, twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0) , twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0)
, file_(tmp_file ? tmp_file : L""), dev_(dev), status_(SANE_Image_Statu_OK) , file_(tmp_file ? tmp_file : L""), dev_(dev), status_(SANE_Image_Statu_OK)
{ {
const bool prepare_data = true;
if (fmt) if (fmt)
fmt_ = *fmt; fmt_ = *fmt;
else else
@ -461,7 +396,7 @@ scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsi
} }
size_t bytes = line_bytes() * head.lines; size_t bytes = line_bytes() * head.lines;
std::string h(file_header(fmt_.img_format, (float)dpi, xfer)); std::string h(file_header(fmt_.img_format, (float)dpi));
unsigned char* dst = NULL, *src = (unsigned char*)data; unsigned char* dst = NULL, *src = (unsigned char*)data;
bool ok = false; bool ok = false;
@ -472,12 +407,15 @@ scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsi
bytes = h.length(); bytes = h.length();
if (dst && data_->save(h.c_str(), &bytes, 0)) if (dst && data_->save(h.c_str(), &bytes, 0))
{ {
unsigned long long off = bytes, line_l = line_bytes(); unsigned long long line_l = line_bytes(), off = data_->bytes() - line_l;
unsigned int buf_len = line_bytes(), row = 0; unsigned int buf_len = line_bytes(), row = 0;
if (xfer == TWAIN_XFER_Memory)
if (prepare_data && xfer == TWAIN_XFER_Memory)
{
line_l *= -1; line_l *= -1;
else off = bytes;
off = data_->bytes() - line_l; }
for (; row < (unsigned int)head.lines; ++row) for (; row < (unsigned int)head.lines; ++row)
{ {
bytes = head.bytes_per_line; bytes = head.bytes_per_line;
@ -488,7 +426,15 @@ scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsi
} }
ok = row == head.lines; ok = row == head.lines;
} }
do_result(ok, xfer);
if (!ok)
{
delete data_;
data_ = NULL;
header_size_ = 0;
}
else if(prepare_data)
do_result(xfer);
} }
scanned_img::~scanned_img() scanned_img::~scanned_img()
{ {
@ -501,11 +447,11 @@ void scanned_img::set_image_status(SANE_Image_Statu status)
status_ = status; status_ = status;
} }
std::string scanned_img::file_header(SANE_ImageType type, float resolution, twain_xfer xfer) std::string scanned_img::file_header(SANE_ImageType type, float resolution)
{ {
std::string h(""); std::string h("");
if (type == SANE_IMAGE_TYPE_BMP /*&& xfer != TWAIN_XFER_Memory*/) if (type == SANE_IMAGE_TYPE_BMP)
{ {
BITMAPINFOHEADER bih = { 0 }; BITMAPINFOHEADER bih = { 0 };
int pal_size = 0; int pal_size = 0;
@ -524,7 +470,6 @@ std::string scanned_img::file_header(SANE_ImageType type, float resolution, twai
else if (bih.biBitCount == 8) else if (bih.biBitCount == 8)
pal_size = 256 * sizeof(int); pal_size = 256 * sizeof(int);
/*if (xfer == TWAIN_XFER_File)*/
{ {
BITMAPFILEHEADER fh = { 0 }; BITMAPFILEHEADER fh = { 0 };
fh.bfType = MAKEWORD('B', 'M'); fh.bfType = MAKEWORD('B', 'M');
@ -555,9 +500,7 @@ std::string scanned_img::file_header(SANE_ImageType type, float resolution, twai
return h; return h;
} }
void scanned_img::do_result(bool ok, twain_xfer xfer) void scanned_img::do_result(twain_xfer xfer)
{
if (ok)
{ {
if (fmt_.img_format == SANE_IMAGE_TYPE_BMP && if (fmt_.img_format == SANE_IMAGE_TYPE_BMP &&
fmt_.compress.compression == SANE_COMPRESSION_GROUP4 && fmt_.compress.compression == SANE_COMPRESSION_GROUP4 &&
@ -571,11 +514,10 @@ void scanned_img::do_result(bool ok, twain_xfer xfer)
if (buf->allocate(file.c_str(), size, true) && if (buf->allocate(file.c_str(), size, true) &&
buf->save(0, data_)) buf->save(0, data_))
{
// if (buf->save(size, data_))
{ {
SANE_ImageFormatConvert conv; SANE_ImageFormatConvert conv;
std::string sf(local_trans::u2a(file.c_str())); std::string sf(local_trans::u2a(file.c_str())), tifff(sf + ".tiff");
bool conv_2_file = false;
buf->unmap(); buf->unmap();
conv.src.data = sf.c_str(); conv.src.data = sf.c_str();
@ -584,13 +526,40 @@ void scanned_img::do_result(bool ok, twain_xfer xfer)
conv.src.fmt.compress.compression = SANE_COMPRESSION_NONE; conv.src.fmt.compress.compression = SANE_COMPRESSION_NONE;
conv.src.is_file = SANE_TRUE; conv.src.is_file = SANE_TRUE;
conv.dst.data = NULL; conv.dst.data = conv_2_file ? tifff.c_str() : nullptr;
conv.dst.data_len = 0; conv.dst.data_len = conv_2_file ? tifff.length() : 0;
conv.dst.fmt.img_format = SANE_IMAGE_TYPE_BMP; conv.dst.fmt.img_format = SANE_IMAGE_TYPE_BMP;
conv.dst.fmt.compress.compression = SANE_COMPRESSION_GROUP4; conv.dst.fmt.compress.compression = SANE_COMPRESSION_GROUP4;
conv.dst.fmt.compress.detail = NULL; conv.dst.fmt.compress.detail = NULL;
conv.dst.is_file = false; conv.dst.is_file = conv_2_file ? SANE_TRUE : SANE_FALSE;
if (hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, &conv, NULL) == SANE_STATUS_GOOD) if (hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, &conv, NULL) == SANE_STATUS_GOOD)
{
if(conv_2_file)
{
FILE* src = fopen(tifff.c_str(), "rb");
if (src)
{
delete data_;
data_ = new mapping_buf();
fseek(src, 0, SEEK_END);
size = ftell(src);
fseek(src, 0, SEEK_SET);
data_->allocate(file_.c_str(), size);
char* mem = new char[size];
fread(mem, 1, size, src);
fclose(src);
data_->save(mem, &size, 0);
delete[] mem;
head_.format = SANE_FRAME_GRAY;
head_.depth = 1;
head_.bytes_per_line = (head_.pixels_per_line + 7) / 8;
fmt_.img_format = SANE_IMAGE_TYPE_TIFF;
}
remove(tifff.c_str());
}
else
{ {
delete data_; delete data_;
data_ = new mapping_buf(); data_ = new mapping_buf();
@ -598,9 +567,11 @@ void scanned_img::do_result(bool ok, twain_xfer xfer)
data_->allocate(file_.c_str(), conv.dst.data_len); data_->allocate(file_.c_str(), conv.dst.data_len);
data_->save(conv.dst.data, &size, 0); data_->save(conv.dst.data, &size, 0);
hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_FREE_MEMORY, (void*)conv.dst.data, &conv.dst.data_len); hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_FREE_MEMORY, (void*)conv.dst.data, &conv.dst.data_len);
head_.format = SANE_FRAME_GRAY; head_.format = SANE_FRAME_GRAY;
head_.depth = 1; head_.depth = 1;
head_.bytes_per_line = (head_.pixels_per_line + 7) / 8; head_.bytes_per_line = (head_.pixels_per_line + 7) / 8;
fmt_.img_format = SANE_IMAGE_TYPE_TIFF;
} }
} }
} }
@ -615,13 +586,7 @@ void scanned_img::do_result(bool ok, twain_xfer xfer)
swap_rgb(); swap_rgb();
} }
data_->unmap(); data_->unmap();
} data_done_ = true;
else
{
delete data_;
data_ = NULL;
header_size_ = 0;
}
} }
void scanned_img::swap_rgb(void) void scanned_img::swap_rgb(void)
{ {
@ -748,6 +713,40 @@ COM_API_IMPLEMENT(scanned_img, size_t, get_bits_offset(void))
return 0; return 0;
} }
void scanned_img::prepare_data_for_transfer(twain_xfer xfer)
{
if (fmt_.img_format != SANE_IMAGE_TYPE_BMP || !data_ || data_done_)
return;
//if ((xfer == TWAIN_XFER_Memory && mem_xfer_data_) ||
// (xfer != TWAIN_XFER_Memory && !mem_xfer_data_))
// return;
//
if (xfer == TWAIN_XFER_Memory)
{
// reverse line
int line_l = line_bytes(),
rows = height();
unsigned char* buf = new unsigned char[line_l],
* buf1 = new unsigned char[line_l];
unsigned long long first = get_bits_offset(),
last = first + (rows - 1) * line_l;
for (int i = 0; i < rows / 2; ++i)
{
size_t want = line_l, want1 = line_l;
data_->read(buf, &want, first);
data_->read(buf1, &want1, last);
data_->save(buf1, &want1, first);
data_->save(buf, &want, last);
first += line_l;
last -= line_l;
}
}
do_result(xfer);
}

View File

@ -65,13 +65,15 @@ class scanned_img : public IScanImg, virtual public refer
SANE_Image_Statu status_; SANE_Image_Statu status_;
std::string file_header(SANE_ImageType type, float resolution, twain_xfer xfer); // 部分APP不会通过XferMech来设置传输模式原来预先准备数据的方法不适合该场合
void do_result(bool ok, twain_xfer xfer); // 为适应该场景增加prepare_data_for_transfer接口在真实读取数据之前调用以准备恰当的数据
bool data_done_ = false;
std::string file_header(SANE_ImageType type, float resolution);
void do_result(twain_xfer xfer);
void swap_rgb(void); void swap_rgb(void);
public: public:
scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi, const wchar_t* tmp_file
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL); , twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
@ -103,6 +105,9 @@ public:
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head)); COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
COM_API_OVERRIDE(int, image_status(void)); COM_API_OVERRIDE(int, image_status(void));
COM_API_OVERRIDE(size_t, get_bits_offset(void)); COM_API_OVERRIDE(size_t, get_bits_offset(void));
public:
void prepare_data_for_transfer(twain_xfer xfer);
}; };
template<class T> template<class T>

View File

@ -87,11 +87,11 @@ namespace callback
int sane_event_callback( // 娉ㄥ唽鍥炶皟鐨勫璞★紝闇€瑕佷繚璇佽鍥炶皟鏄绾跨▼瀹夊叏鐨? int sane_event_callback( // 娉ㄥ唽鍥炶皟鐨勫璞★紝闇€瑕佷繚璇佽鍥炶皟鏄绾跨▼瀹夊叏鐨?
SANE_Handle hdev // 浜х敓浜嬩欢鐨勮澶囧彞鏌? SANE_Handle hdev // 浜х敓浜嬩欢鐨勮澶囧彞鏌?
, int code // 鍥炶皟浜嬩欢浠g爜 , int code // é<EFBFBD>¥ç¶çšŸæµœå¬©æ¬¢æµ ï½‡çˆ?
, void* data // 鍥炶皟浜嬩欢鏁版嵁锛屾牴鎹簨浠朵唬鐮佹湁鎵€涓嶅悓锛屽弬鐓у叿浣撲簨浠跺畾涔? , void* data // 鍥炶皟浜嬩欢鏁版嵁锛屾牴鎹簨浠朵唬鐮佹湁鎵€涓嶅悓锛屽弬鐓у叿浣撲簨浠跺畾涔?
, unsigned int* len // 鏁版嵁闀垮害锛堝瓧鑺傦級锛屾垨鑰卐vent_data鐨勭紦鍐插尯闀垮害锛岃缁嗚鐪嬬浉搴旂殑浜嬩欢浠 , unsigned int* len // 鏁版嵁闀垮害锛堝瓧鑺傦級锛屾垨鑰卐vent_data鐨勭紦鍐插尯闀垮害锛岃缁嗚鐪嬬浉搴旂殑浜嬩欢浠
, void* param // 鐢ㄦ埛鑷畾涔夋暟鎹紝涓庤皟鐢╯ane_init_ex浼犲叆鏃剁殑淇濇寔涓€鑷? , void* param // 鐢ㄦ埛鑷畾涔夋暟鎹紝涓庤皟鐢╯ane_init_ex浼犲叆鏃剁殑淇濇寔涓€鑷?
) // 杩斿洖鍊间緷涓嶅悓鐨勪簨浠朵唬鐮佽€屽畾锛岄€氬父涓衡€?鈥? ) // æ<EFBFBD>©æ¿æ´é<EFBFBD>Šé—´ç··æ¶“嶅æ“é<EFBFBD>¨åªç°¨æµ æœµå”¬é<EFBFBD>®ä½½â¬å±½ç•¾é”岄â¬æ°¬çˆ¶æ¶“è¡¡â¬?éˆ?
{ {
std::lock_guard<std::mutex> lock(cb_lock_); std::lock_guard<std::mutex> lock(cb_lock_);
std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), hdev); std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), hdev);
@ -207,9 +207,9 @@ namespace callback
, {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS} , {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS}
, {SANE_STD_OPT_NAME_COLOR_CORRECTION , OPTION_TITLE_SPJZ} , {SANE_STD_OPT_NAME_COLOR_CORRECTION , OPTION_TITLE_SPJZ}
}, },
g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 榛戠櫧鍥惧儚鍙嶈壊杈撳嚭锛堟甯搁鑹蹭负锛?-榛戣壊锛?-鐧借壊锛? g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // æ¦æˆ æ«§é<EFBFBD>¥æƒ§å„šé<EFBFBD>™å¶ˆå£Šæ<EFBFBD>ˆæ³åš­é”堟甯æ<EFBFBD><EFBFBD>î<EFBFBD>é¹è¹­è´Ÿé”?-榛戣壊锛?-é<>§å€Ÿå£Šé”?
, {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 鐏板害鎴栭粦鐧藉浘鍍?- 闄よ壊 , {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // é<EFBFBD><EFBFBD>æ<EFBFBD>¿å®³éŽ´æ ­ç²¦é<EFBFBD>§è—‰æµ˜é<EFBFBD><EFBFBD>?- 闄よå£?
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 鑷姩鎼撶焊寮哄害 , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // é·î<EFBFBD>„姩鎼æ¶ç„Šå¯®å“„å®?
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 鎼撶焊闃堝€? , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 鎼撶焊闃堝€?
}; };
const char* option_title_2_name(const char* title) const char* option_title_2_name(const char* title)
@ -347,12 +347,12 @@ namespace callback
// SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0 // SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0
static HMODULE hui = NULL; static HMODULE hui = NULL;
int (*choose_scanner)(const std::vector<DEVQUEUI>& devs) = NULL; // blocked. return selected DEVQUE::id or -1 if user cancelled int (*choose_scanner)(const std::vector<DEVQUEUI>& devs) = NULL; // blocked. return selected DEVQUE::id or -1 if user cancelled
char* (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // 搴旂敤璁惧鐨勫綋鍓嶉厤锟? char* (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // æ<EFBFBD>´æ—敤ç<EFBFBD>惧é<EFBFBD>¨å«ç¶é<EFBFBD>“嶉厤é”?
int (*show_setting_ui)(SANE_Handle device, HWND parent, LPSANEAPI api, const char* devname, bool with_scan, std::function<void(ui_result)> callback) = NULL; int (*show_setting_ui)(SANE_Handle device, HWND parent, LPSANEAPI api, const char* devname, bool with_scan, std::function<void(ui_result)> callback) = NULL;
int (*show_progress_ui)(HWND parent, std::function<void(ui_result)> callback, std::function<void(int/*event*/, void*/*msg*/, int/*flag*/)>* notify) = NULL; int (*show_progress_ui)(HWND parent, std::function<void(ui_result)> callback, std::function<void(int/*event*/, void*/*msg*/, int/*flag*/)>* notify) = NULL;
int (*show_messagebox_ui)(HWND parent, int event, void* msg, int flag) = NULL; int (*show_messagebox_ui)(HWND parent, int event, void* msg, int flag) = NULL;
int (*close_ui)(int) = NULL; int (*close_ui)(int) = NULL;
int (*apply_given_config)(const char* content, SANE_Handle device, LPSANEAPI api) = NULL; // 搴旂敤鎸囧畾鐨勯厤缃紝content涓洪厤缃暟鎹祦 int (*apply_given_config)(const char* content, SANE_Handle device, LPSANEAPI api) = NULL; // æ<EFBFBD>´æ—敤鎸å§ç•¾é<EFBFBD>¨å¯åŽ¤ç¼ƒî‡†ç´<EFBFBD>content涓洪厤缃暟鎹ç¥?
char* (*get_config_content)(const char* dev_name, const char* name) = NULL; char* (*get_config_content)(const char* dev_name, const char* name) = NULL;
void (*twain_ui_free)(void* buf) = NULL; void (*twain_ui_free)(void* buf) = NULL;
@ -945,7 +945,7 @@ int scanner::open(void)
{ {
if (callback::show_messagebox_ui) if (callback::show_messagebox_ui)
{ {
// 绾歌疆鎼撶焊娆℃暟宸茶秴杩囪璁′娇鐢ㄨ寖鍥达紝鎵弿杩囩▼涓悡绾稿け璐ャ€佹鏂溿€佹悡澶氬紶绛夊紓甯搁娆″彲鑳戒細鏄庢樉澧炲锛岃娉ㄦ剰鍙婃椂娓呮磥銆佸苟鑱旂郴璁惧渚涘簲鍟嗚喘涔版浛鎹㈢焊杞紒 // 绾歌ç†éŽ¼æ¶ç„Šå¨†â„ƒæšŸå®¸èŒ¶ç§´æ<EFBFBD>©åªî†•ç<EFBFBD>′娇é<EFBFBD>¢ã„¨å¯é<EFBFBD>¥è¾¾ç´<EFBFBD>鎵î£å¼¿æ<EFBFBD>©å©â¼æ¶“î…Ÿæ¡ç»¾ç¨¿ã<EFBFBD>ç<EFBFBD>ャâ¬ä½¹î„£é<EFBFBD>溿â¬ä½¹æ¡æ¾¶æ°¬ç´¶ç»å¤Šç´“甯æ<EFBFBD><EFBFBD>娆″彲é³æˆç´°é<EFBFBD>„庢樉澧ç²î˜¿é”岃娉ㄦ剰é<EFBFBD>™å©ƒæ¤å¨“å®ç£¥éŠ†ä½¸èŸé±æ—郴ç<EFBFBD>惧渚涘簲é<EFBFBD>Ÿå—šå˜æ¶”版æµéŽ¹ãˆ¢ç„Šæ<EFBFBD>žî‡†ç´?
std::wstring roller_msgw(local_trans::lang_trans_between_hz936(L"\u7EB8\u8F6E\u6413\u7EB8\u6B21\u6570\u5DF2\u8D85\u8FC7\u8BBE\u8BA1\u4F7F\u7528\u8303\u56F4\uFF0C\u626B\u63CF\u8FC7\u7A0B\u4E2D\u6413\u7EB8\u5931\u8D25\u3001\u6B6A\u659C\u3001\u6413\u591A\u5F20\u7B49\u5F02\u5E38\u9891\u6B21\u53EF\u80FD\u4F1A\u660E\u663E\u589E\u591A\uFF0C\u8BF7\u6CE8\u610F\u53CA\u65F6\u6E05\u6D01\u3001\u5E76\u8054\u7CFB\u8BBE\u5907\u4F9B\u5E94\u5546\u8D2D\u4E70\u66FF\u6362\u7EB8\u8F6E\uFF01")); std::wstring roller_msgw(local_trans::lang_trans_between_hz936(L"\u7EB8\u8F6E\u6413\u7EB8\u6B21\u6570\u5DF2\u8D85\u8FC7\u8BBE\u8BA1\u4F7F\u7528\u8303\u56F4\uFF0C\u626B\u63CF\u8FC7\u7A0B\u4E2D\u6413\u7EB8\u5931\u8D25\u3001\u6B6A\u659C\u3001\u6413\u591A\u5F20\u7B49\u5F02\u5E38\u9891\u6B21\u53EF\u80FD\u4F1A\u660E\u663E\u589E\u591A\uFF0C\u8BF7\u6CE8\u610F\u53CA\u65F6\u6E05\u6D01\u3001\u5E76\u8054\u7CFB\u8BBE\u5907\u4F9B\u5E94\u5546\u8D2D\u4E70\u66FF\u6362\u7EB8\u8F6E\uFF01"));
std::string roller_msg(local_trans::u2a(roller_msgw.c_str(), CP_UTF8)); std::string roller_msg(local_trans::u2a(roller_msgw.c_str(), CP_UTF8));
app_wnd_ = callback::find_main_wnd(); app_wnd_ = callback::find_main_wnd();
@ -2674,7 +2674,7 @@ COM_API_IMPLEMENT(scanner, IScanImg*, take_first_image(twain_xfer xfer))
if (img) if (img)
{ {
//img->prepare_data_for_transfer(xfer); img->prepare_data_for_transfer(xfer);
img->add_ref(); img->add_ref();
wchar_t msg[128] = { 0 }; wchar_t msg[128] = { 0 };
@ -3511,7 +3511,7 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
log_info(msg, 1); log_info(msg, 1);
} }
} }
//else if (ev_code == SANE_EVENT_ERROR) // 灞忚斀锛屽湪鍋滄鎵弿鏃跺睍绀轰俊鎭?- 2023-05-30 //else if (ev_code == SANE_EVENT_ERROR) // ç<EFBFBD>žå¿šæ€é”屽湪é<EFBFBD>滄î„鎵î£å¼¿é<EFBFBD>ƒè·ºç<EFBFBD><EFBFBD>绀轰俊éŽ?- 2023-05-30
//{ //{
// if (callback::show_messagebox_ui && *len) // if (callback::show_messagebox_ui && *len)
// { // {

View File

@ -1391,8 +1391,11 @@ Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data)
if (rows == 0) if (rows == 0)
return badValue(); return badValue();
else if (rows > img->height()) else if (want_read > img->bytes() - off)
rows = img->height(); {
want_read = img->bytes() - off;
rows = (want_read + line_l - 1) / line_l;
}
if (pending_xfer_.img) if (pending_xfer_.img)
{ {
@ -1407,7 +1410,7 @@ Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data)
data.setColumns(img->width()); data.setColumns(img->width());
data.setRows(rows); data.setRows(rows);
data.setXOffset(0); data.setXOffset(0);
data.setYOffset(UInt32(off / line_l)); data.setYOffset(UInt32((off - img->get_bits_offset())/ line_l));
data.setCompression(m_compression); data.setCompression(m_compression);
if (m_compression != Compression::None) if (m_compression != Compression::None)
{ {
@ -1432,7 +1435,7 @@ Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data)
else if (img->read(dst, &want_read, off) == SCANNER_ERR_OK) else if (img->read(dst, &want_read, off) == SCANNER_ERR_OK)
{ {
want_read /= line_l; want_read /= line_l;
data.setRows(want_read); // data.setRows(want_read);
want_read *= line_l; want_read *= line_l;
data.setBytesWritten(want_read); data.setBytesWritten(want_read);
off += want_read; off += want_read;