添加G402图像处理

This commit is contained in:
gb 2022-07-14 14:21:53 +08:00
parent eb50f63e64
commit 9962ac5d7d
3 changed files with 343 additions and 91 deletions

View File

@ -460,7 +460,11 @@ std::string hg_scanner_402::control_fetch(int addr, int val, int size)
data.resize(size + 2); data.resize(size + 2);
bzero(&data[0], size + 2); bzero(&data[0], size + 2);
ret = io_->read_bulk(&data[0], &l); ret = io_->read_bulk(&data[0], &l);
if (ret) if (ret == SCANNER_ERR_OK)
{
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "control_fetch(%d, %d) - read_bulk %d bytes\n", addr, val, l);
}
else
{ {
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "control_fetch(%d, %d) - read_bulk = %s\n", addr, val, hg_scanner_err_name(ret)); VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "control_fetch(%d, %d) - read_bulk = %s\n", addr, val, hg_scanner_err_name(ret));
data.clear(); data.clear();
@ -669,6 +673,159 @@ void hg_scanner_402::image_process(std::shared_ptr<tiny_buffer>& buff)
err = hg_imgproc::load_buffer(handle, buff); err = hg_imgproc::load_buffer(handle, buff);
err = hg_imgproc::decode(handle,pid_); err = hg_imgproc::decode(handle,pid_);
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "Image process parameter: 0x%x%08x, multi out: %s\n", ((unsigned int*)&image_prc_param_.value)[1], ((unsigned int*)&image_prc_param_.value)[0], is_multiout ? "true" : "false");
if (img_conf_.fillhole.is_fillhole)
{
err = hg_imgproc::fillhole(handle);
//printf("填穿孔开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "填穿孔开启:%s\n",hg_scanner_err_name(ret));
}
/////////////////////////////////////111111111111111111111111111//////////////////////////////////
err = hg_imgproc::auto_crop(handle);
if (img_conf_.is_autodiscradblank_normal || img_conf_.is_autodiscradblank_vince)
{
err = hg_imgproc::discardBlank(handle);
printf("丢弃空白页开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "丢弃空白页开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.fadeback)
{
hg_imgproc::fadeback(handle, img_conf_.fadebackrange, param.double_side);
//printf("背景除色开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "背景除色开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.resolution_dst != img_conf_.resolution_native)
{
hg_imgproc::resolution_change(handle);
//printf("dpi改变开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "dpi改变开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.cropRect.enable && !img_conf_.is_autocrop)
{
hg_imgproc::croprect(handle);
//printf("手动裁图开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "手动裁图开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.filter != ColorFilter::FILTER_NONE && (img_conf_.pixtype == COLOR_MODE_BLACK_WHITE || img_conf_.pixtype == COLOR_MODE_256_GRAY))
{
printf("除色开启\r\n");
hg_imgproc::channel(handle);
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "除色开启:%s\n",hg_scanner_err_name(ret));
}
/////////////////////////////////////2222222222222222222222222222222222222//////////////////////////////////
int tableLength;//= sizeof(custom_gamma_val_->table)/sizeof(custom_gamma_val_->table[0]);
unsigned char buffer1[256 * 3];
if (img_conf_.pixtype == COLOR_MODE_BLACK_WHITE || img_conf_.pixtype == COLOR_MODE_256_GRAY)
tableLength = 256;
else
{
tableLength = 768;
int index = 0;
const int buffersize = 256;
unsigned char buf_01[buffersize];
memcpy(buf_01, custom_gamma_val_->table + index, buffersize);
index += buffersize;
unsigned char buf_02[buffersize];
memcpy(buf_02, custom_gamma_val_->table + index, buffersize);
index += buffersize;
unsigned char buf_03[buffersize];
memcpy(buf_03, custom_gamma_val_->table + index, buffersize);
index += buffersize;
int j = 0;
for (size_t i = 0; i < buffersize; i++)
{
memcpy(buffer1 + j, buf_01 + i, 1);
memcpy(buffer1 + (++j), buf_02 + i, 1);
memcpy(buffer1 + (++j), buf_03 + i, 1);
++j;
}
}
hg_imgproc::customgamma(handle, custom_gamma_, buffer1, tableLength);
if (img_conf_.pixtype == COLOR_MODE_24_BITS && img_conf_.hsvcorrect)
{
hg_imgproc::answerSheetFilterRed(handle);
//printf("答题卡出红开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "答题卡出红开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.refuseInflow)
{
int lv = 5;
if (image_prc_param_.bits.is_permeate_lv_ == 0)
lv = 5;
else if (image_prc_param_.bits.is_permeate_lv_ == 1)
lv = 15;
else if (image_prc_param_.bits.is_permeate_lv_ == 2)
lv = 25;
else if (image_prc_param_.bits.is_permeate_lv_ == 3)
lv = 35;
else if (image_prc_param_.bits.is_permeate_lv_ == 4)
lv = 45;
hg_imgproc::antiInflow(handle, lv);
}
if (img_conf_.colorCorrection && img_conf_.pixtype != COLOR_MODE_BLACK_WHITE)
{
hg_imgproc::colorCorrection(handle);
//printf("颜色校正开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "颜色校正开启:%s\n",hg_scanner_err_name(ret));
}
if ((img_conf_.imageRotateDegree != TEXT_DIRECTION_0 || img_conf_.is_backrotate180) && (!img_conf_.is_autotext))
{
printf("手动旋转开启\r\n");
hg_imgproc::orentation(handle);
}
if (img_conf_.removeMorr)
{
hg_imgproc::textureRemove(handle);
//printf("除摩尔纹开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "除摩尔纹开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.detachnoise.is_detachnoise)
{
hg_imgproc::nosieDetach(handle);
//printf("噪点优化开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "噪点优化开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.pixtype == COLOR_MODE_BLACK_WHITE)
{
hg_imgproc::errorextention(handle);
//printf("黑白图处理开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "黑白图处理开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.en_fold)
{
hg_imgproc::fold(handle);
//printf("对折开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "对折开启:%s\n",hg_scanner_err_name(ret));
}
///////////////////////////////////
if (image_prc_param_.bits.rid_red && img_conf_.pixtype == COLOR_MODE_24_BITS)
{
err = hg_imgproc::multi_out_red(handle);
//printf("多流出红开启\r\n");
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "多流出红开启:%s\n",hg_scanner_err_name(ret));
}
if (img_conf_.sharpen)
{
hg_imgproc::sharpenType(handle);
}
if(image_prc_param_.bits.erase_bakground && !user_cancel_) if(image_prc_param_.bits.erase_bakground && !user_cancel_)
{ {
err = hg_imgproc::fadeback(handle,img_conf_.fadebackrange,img_conf_.is_duplex); err = hg_imgproc::fadeback(handle,img_conf_.fadebackrange,img_conf_.is_duplex);
@ -781,58 +938,59 @@ int hg_scanner_402::writedown_device_configuration(HGSCANCONF *dev_conf)
int hg_scanner_402::writedown_image_configuration(void) int hg_scanner_402::writedown_image_configuration(void)
{ {
int ret = write_register(SR_CONFIF_IMGPROCPARAM, sizeof(SCANCONF)); //int ret = write_register(SR_CONFIF_IMGPROCPARAM, sizeof(SCANCONF));
if (ret != SCANNER_ERR_OK) //if (ret != SCANNER_ERR_OK)
return ret; // return ret;
int ret = SCANNER_ERR_OK;
SCANCONF ic; SCANCONF ic;
int len = sizeof(ic); int len = sizeof(ic);
bzero(&ic, len); bzero(&ic, len);
ic.papertype = paper_size_; ic.papertype = paper_size_;
if (is_lateral(image_prc_param_.bits.paper)) if (is_lateral(image_prc_param_.bits.paper))
ic.paperAlign = Rot270; ic.paperAlign = Rot270;
// else if (image_prc_param_.bits.text_direction == TEXT_DIRECTION_AUTO) // else if (image_prc_param_.bits.text_direction == TEXT_DIRECTION_AUTO)
// ic.paperAlign = AutoTextOrientation; // ic.paperAlign = AutoTextOrientation;
else else
ic.paperAlign = Rot0; ic.paperAlign = Rot0;
ic.en_sizecheck = dev_conf_.g200params.enable_sizecheck; ic.en_sizecheck = dev_conf_.g200params.enable_sizecheck;
if (image_prc_param_.bits.text_direction != TEXT_DIRECTION_AUTO) if (image_prc_param_.bits.text_direction != TEXT_DIRECTION_AUTO)
ic.imageRotateDegree = (float)image_prc_param_.bits.text_direction; ic.imageRotateDegree = (float)image_prc_param_.bits.text_direction;
else else
ic.imageRotateDegree = 0; ic.imageRotateDegree = 0;
ic.imageRotateDegree *= 90.0f; ic.imageRotateDegree *= 90.0f;
ic.is_duplex = (image_prc_param_.bits.page == PAGE_DOUBLE ic.is_duplex = (image_prc_param_.bits.page == PAGE_DOUBLE
|| image_prc_param_.bits.page == PAGE_OMIT_EMPTY || image_prc_param_.bits.page == PAGE_OMIT_EMPTY
|| image_prc_param_.bits.page == PAGE_OMIT_EMPTY_RECEIPT || image_prc_param_.bits.page == PAGE_OMIT_EMPTY_RECEIPT
|| image_prc_param_.bits.page ==PAGE_FOLIO); || image_prc_param_.bits.page ==PAGE_FOLIO);
ic.en_fold = (image_prc_param_.bits.page == PAGE_FOLIO); ic.en_fold = (image_prc_param_.bits.page == PAGE_FOLIO);
ic.pixtype = image_prc_param_.bits.color_mode == COLOR_MODE_AUTO_MATCH ? 2 : image_prc_param_.bits.color_mode; ic.pixtype = image_prc_param_.bits.color_mode == COLOR_MODE_AUTO_MATCH ? 2 : image_prc_param_.bits.color_mode;
ic.automaticcolor = is_auto_matic_color; ic.automaticcolor = is_auto_matic_color;
ic.automaticcolortype = 1;// ic.pixtype; //存疑 ic.automaticcolortype = 1;// ic.pixtype; //存疑
if (resolution_ >= 300) if (resolution_ >= 300)
{
if(is_quality_ == IMG_SPEED)
{ {
ic.resolution_dst = 200; if(is_quality_ == IMG_SPEED)
{
ic.resolution_dst = 200;
}
else if(is_quality_ ==IMG_QUALITY)
{
ic.resolution_dst = resolution_;
}
} }
else if(is_quality_ ==IMG_QUALITY) else
{ {
ic.resolution_dst = resolution_; ic.resolution_dst = resolution_;
} }
}
else
{
ic.resolution_dst = resolution_;
}
ic.resolution_native = 200.0f; ic.resolution_native = 200.0f;
ic.gamma = (float)gamma_; ic.gamma = (float)gamma_;
@ -956,14 +1114,14 @@ else
ic.cropRect.enable = false; ic.cropRect.enable = false;
} }
{ //{
std::lock_guard<std::mutex> lock(io_lock_); // std::lock_guard<std::mutex> lock(io_lock_);
//
ret = io_->write_bulk(&ic, &len); // ret = io_->write_bulk(&ic, &len);
//
this_thread::sleep_for(chrono::milliseconds(500)); // this_thread::sleep_for(chrono::milliseconds(500));
io_->set_timeout(2000);//必要延时 // io_->set_timeout(2000);//必要延时
} //}
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Write-down 0x%x bytes image process parameters\n", len); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Write-down 0x%x bytes image process parameters\n", len);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"\n ic.pixtype=%d", ic.pixtype); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"\n ic.pixtype=%d", ic.pixtype);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"\n ic.papertype=%d", ic.papertype); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO,"\n ic.papertype=%d", ic.papertype);
@ -1037,6 +1195,7 @@ int hg_scanner_402::read_one_image_from_usb(void)
off = 0, off = 0,
ret = SCANNER_ERR_OK; ret = SCANNER_ERR_OK;
VLOG_MINI_1(LOG_LEVEL_ALL, "New image size: %u\n", total);
if (!waiting_for_memory_enough(total)) if (!waiting_for_memory_enough(total))
{ {
status_ = SCANNER_ERR_INSUFFICIENT_MEMORY; status_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
@ -1063,63 +1222,45 @@ int hg_scanner_402::read_one_image_from_usb(void)
r = total; r = total;
{ {
std::lock_guard<std::mutex> lock(io_lock_); std::lock_guard<std::mutex> lock(io_lock_);
void* buff = buf->data(off, (unsigned int*)&r);
unsigned int size = r; ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
void* buff = buf->data(off, &size); while (buff)
int block = 0;
if (!buff)
{ {
VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_); ret = io_->read_bulk(buff, &r);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY; if (ret != SCANNER_ERR_OK)
} break;
else
{
r = size;
while (r > 0)
{
block = 512 * 1024;
if (r < block)
block = r;
unsigned int size = block; off += r;
void* buff = buf->data(off, &size); if (off >= total)
if (!buf) break;
{
//VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_);
ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
block = size;
ret = io_->read_bulk(buff, &block);
if (ret != SCANNER_ERR_OK)
break;
off += block; r = total - off;
r -= block; buff = buf->data(off, (unsigned int*)&r);
}
} }
} }
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read image from USB = %s\n", hg_scanner_err_name(ret));
if (ret == SCANNER_ERR_OK) if (ret == SCANNER_ERR_OK)
{ {
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read image from USB = %s\n", hg_scanner_err_name(ret));
ret = save_usb_data(buf); ret = save_usb_data(buf);
if (ret == SCANNER_ERR_OK) if (ret == SCANNER_ERR_OK)
{ {
pop_first_image(); pop_first_image();
//if(image_prc_param_.bits.page == PAGE_SINGLE) }
// pop_first_image(); else
{
VLOG_MINI_1(LOG_LEVEL_FATAL, "save usb data failed: %s\n", hg_scanner_err_name(ret));
} }
} }
else else
{ {
char msg[128]; VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read image data from USB err: %s\n", hg_scanner_err_name(ret));
sprintf(msg, "Read image data from USB err: %s\n", hg_scanner_err_name(ret));
LOG_INFO(LOG_LEVEL_DEBUG_INFO, msg);
notify_ui_working_status(msg);
notify_ui_working_status(STATU_DESC_SCANNER_ERR_TIMEOUT, SANE_EVENT_ERROR);
} }
} }
else
{
VLOG_MINI_1(LOG_LEVEL_FATAL, "write command SR_IM_TX failed: %s\n", hg_scanner_err_name(ret));
}
} }
return ret; return ret;
@ -1428,8 +1569,8 @@ void hg_scanner_402::thread_handle_usb_read(void)
ret = io_->read_interrupt(buf, &size); ret = io_->read_interrupt(buf, &size);
io_->set_timeout(1000); io_->set_timeout(1000);
} }
VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "read-INT = %s: From(%d), Code(%d), Index(%d)\n", hg_scanner_err_name(ret), VLOG_MINI_5(LOG_LEVEL_DEBUG_INFO, "read-INT = %s: From(%d), Code(%d), Index(%d), size = %d\n", hg_scanner_err_name(ret),
info->From, info->Code, info->Img_Index); info->From, info->Code, info->Img_Index, size);
if (ret != SCANNER_ERR_OK) if (ret != SCANNER_ERR_OK)
{ {
if (ret == SCANNER_ERR_TIMEOUT) if (ret == SCANNER_ERR_TIMEOUT)
@ -1437,11 +1578,13 @@ void hg_scanner_402::thread_handle_usb_read(void)
if (to_cnt++ < 30) if (to_cnt++ < 30)
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::this_thread::sleep_for(std::chrono::milliseconds(500));
if ((get_status() & 0x03) == 0) //int statu = get_status();
{ //if ((statu & 0x03) == 0)
status_ = SCANNER_ERR_OK; //{
break; // VLOG_MINI_1(LOG_LEVEL_FATAL, "USB thread over with status: 0x%x\n", statu);
} // status_ = SCANNER_ERR_OK;
// break;
//}
continue; continue;
} }
} }
@ -1459,6 +1602,10 @@ void hg_scanner_402::thread_handle_usb_read(void)
{ {
read_one_image_from_usb(); read_one_image_from_usb();
} }
else
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "receive IMG event but no image count(%d)!", get_image_count());
}
break; break;
case V4L2: case V4L2:
VLOG_MINI_1(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code); VLOG_MINI_1(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code);
@ -1469,9 +1616,35 @@ void hg_scanner_402::thread_handle_usb_read(void)
go = false; go = false;
} }
break; break;
case STOPSCAN:
go = false;
LOG_INFO(LOG_LEVEL_ALL, "Received STOPSCAN event ...\n");
std::this_thread::sleep_for(std::chrono::milliseconds(500));
{
std::lock_guard<std::mutex> lock(io_lock_);
size = sizeof(buf);
ret = io_->read_interrupt(buf, &size);
io_->set_timeout(1000);
if (ret == SCANNER_ERR_OK && info->From == IMG)
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (get_image_count() > 0)
{
read_one_image_from_usb();
}
else
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "receive IMG event but no image count(%d) after STOPSCAN!", get_image_count());
}
}
}
break;
default: default:
break; break;
} }
if (!go)
break;
} }
else else
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "read %d bytes, sizeof(buf) = %d\n", size, sizeof(buf)); VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "read %d bytes, sizeof(buf) = %d\n", size, sizeof(buf));
@ -1502,6 +1675,7 @@ int hg_scanner_402::start(void)
get_roller_num(); get_roller_num();
notify_ui_working_status(STATU_DESC_REWRITE_CONFIGURATION); notify_ui_working_status(STATU_DESC_REWRITE_CONFIGURATION);
writedown_device_configuration(); writedown_device_configuration();
writedown_image_configuration();
ret = read_register(/*SR_GET_ANDROID_STATE*/0x1001, &val); ret = read_register(/*SR_GET_ANDROID_STATE*/0x1001, &val);
if (val) if (val)
{ {
@ -1514,6 +1688,7 @@ int hg_scanner_402::start(void)
else else
ret = status_ = SCANNER_ERR_IO; ret = status_ = SCANNER_ERR_IO;
VLOG_MINI_1(LOG_LEVEL_WARNING, "SR_GET_ANDROID_STATE result: %s\n", hg_scanner_err_name(ret));
return ret; return ret;
} }
write_register(0x1000, scan_count_); write_register(0x1000, scan_count_);

View File

@ -5,6 +5,8 @@
#include <string.h> #include <string.h>
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#pragma pack(push)
#pragma pack(1)
typedef struct BITMAPFILEHEADER typedef struct BITMAPFILEHEADER
{ {
u_int16_t bfType; u_int16_t bfType;
@ -28,6 +30,11 @@ typedef struct BITMAPINFOHEADER
u_int32_t biClrUsed; u_int32_t biClrUsed;
u_int32_t biClrImportant; u_int32_t biClrImportant;
}BITMAPINFODEADER; }BITMAPINFODEADER;
#pragma pack(pop)
#define BI_RGB 0
#define MAKEWORD(a, b) (((a) & 0x0ff) | (((b) & 0x0ff) << 8))
#define MAKELONG(a, b) (((a) & 0x0ffff) | (((b) & 0x0ffff) << 16))
#define _countof(a) (sizeof(a) / sizeof((a)[0]))
#else #else
#include <Windows.h> #include <Windows.h>
#include <shlobj.h> #include <shlobj.h>
@ -611,7 +618,7 @@ namespace hg_imgproc
#endif #endif
return ret; return ret;
} }
//除网<EFBFBD>? //除网ï¿?
int textureRemove() int textureRemove()
{ {
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
@ -701,7 +708,7 @@ namespace hg_imgproc
} }
return ret; return ret;
} }
//答题卡出<EFBFBD>? //答题å<EFBFBD>¡å‡ºï¿?
int answerSheetFilterRed() int answerSheetFilterRed()
{ {
int ret = SCANNER_ERR_OK; int ret = SCANNER_ERR_OK;
@ -1199,7 +1206,76 @@ namespace hg_imgproc
} }
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
int save_2_bmp_file(const char* bmp_file, LPIMGHEAD head, void* buf, int resolution)
{
BITMAPINFOHEADER bih = { 0 };
BITMAPFILEHEADER fh = { 0 };
int pal_size = 0, line_len = (head->channels * head->bits * head->width + 31) / 32 * 4;
FILE *dst = fopen(bmp_file, "wb");
if (!dst)
return errno;
bih.biSize = sizeof(bih);
bih.biWidth = head->width;
bih.biBitCount = head->channels * head->bits;
bih.biSizeImage = head->height * line_len;
bih.biPlanes = 1;
bih.biHeight = head->height;
bih.biCompression = BI_RGB;
bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f;
if (bih.biBitCount == 1)
pal_size = 2 * sizeof(int);
else if (bih.biBitCount == 8)
pal_size = 256 * sizeof(int);
fh.bfType = MAKEWORD('B', 'M');
fh.bfSize = sizeof(fh) + bih.biSizeImage + sizeof(bih);
fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size;
fwrite(&fh, sizeof(fh), 1, dst);
fwrite(&bih, sizeof(bih), 1, dst);
if (bih.biBitCount == 1)
{
int pal[] = { 0, 0x0ffffff };
fwrite(pal, sizeof(pal), 1, dst);
}
else if (bih.biBitCount == 8)
{
static unsigned int g_bmp8_pallete[256] = { 0 };
if (g_bmp8_pallete[1] == 0)
{
for (int i = 1; i < _countof(g_bmp8_pallete); ++i)
g_bmp8_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0));
}
fwrite(g_bmp8_pallete, sizeof(g_bmp8_pallete), 1, dst);
}
if (line_len == head->line_bytes)
fwrite(buf, 1, head->total_bytes, dst);
else
{
unsigned char* ptr = (unsigned char*)buf;
unsigned int pad = 0;
int pad_l = 4 - (head->line_bytes % 4), step = head->line_bytes;
if (1)
{
ptr += head->total_bytes - head->line_bytes;
step *= -1;
}
for (int i = 0; i < head->height; ++i)
{
fwrite(ptr, head->line_bytes, 1, dst);
fwrite(&pad, 1, pad_l, dst);
ptr += step;
}
}
fclose(dst);
return 0;
}
} }

View File

@ -214,4 +214,5 @@ namespace hg_imgproc
// seperate utilites ... // seperate utilites ...
int convert_image_file(SANE_ImageFormatConvert* conv); int convert_image_file(SANE_ImageFormatConvert* conv);
int save_2_bmp_file(const char* bmp_file, LPIMGHEAD head, void* buf, int resolution);
} }