修复非彩色位图文件转换其它格式时的错误;修复黑白图像反色输出初始化值不准确的错误

This commit is contained in:
gb 2022-09-14 09:52:49 +08:00
parent a2ddc057c0
commit a389b4d37b
2 changed files with 106 additions and 20 deletions

View File

@ -2092,14 +2092,7 @@ void hg_scanner::init_settings(const char* json_setting_text)
}
else if (val == "bool")
{
std::string name(""); // is_white_0_
bool v = false;
setting_jsn_.at(key).at("name").get_to(name);
if (name == SANE_STD_OPT_NAME_REVERSE_01)
{
setting_jsn_.at(key).at("default") = is_white_0_;
setting_jsn_.at(key).at("cur") = is_white_0_;
}
setting_jsn_.at(key).at("default").get_to(v);
set_setting(sn, (char*)&v, sizeof(v));
}
@ -2646,6 +2639,11 @@ int hg_scanner::get_setting(int setting_no, char* json_txt_buf, int* len)
//text = setting_jsn_.at(sn).dump();
}
}
else if (name == OPTION_TITLE_HBTXFSSC)
{
setting_jsn_.at(sn).at("cur") = is_white_0_;
text = setting_jsn_.at(sn).dump();
}
if (*len <= text.length() + add)
{

View File

@ -74,6 +74,53 @@ using namespace std;
namespace hg_imgproc
{
typedef union
{
unsigned char ch;
struct
{
unsigned char bit0 : 1;
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char bit3 : 1;
unsigned char bit4 : 1;
unsigned char bit5 : 1;
unsigned char bit6 : 1;
unsigned char bit7 : 1;
}bits;
}BITS;
class bit_stream
{
unsigned char* byte_stream_;
bool lsb_first_; // whether the Lowest_bit is first pop ...
int offset_;
public:
bit_stream(unsigned char* data, bool lsb_first = true) : byte_stream_(data), lsb_first_(lsb_first)
, offset_(0)
{}
~bit_stream()
{}
public:
void reset(int off = 0)
{
offset_ = off;
}
unsigned char get(void)
{
unsigned char ret = 0;
if (lsb_first_)
ret = (byte_stream_[offset_ / 8] >> (offset_ % 8)) & 1;
else
ret = (byte_stream_[offset_ / 8] >> (7 - (offset_ % 8))) & 1;
offset_++;
return ret;
}
};
class imgproc
{
std::string my_path_;
@ -1136,7 +1183,7 @@ namespace hg_imgproc
// seperate utilites ...
#include <opencv2/imgcodecs.hpp>
#define CV_MAT_DEPTH_SET(flags, depth) (((flags) & ~(CV_MAT_DEPTH_MASK)) | (depth & CV_MAT_DEPTH_MASK))
static cv::Mat from_bmp_file_bits(const BITMAPINFOHEADER& bih, unsigned char* data, bool tiff)
static cv::Mat from_bmp_file_bits(const BITMAPINFOHEADER& bih, unsigned char* data, bool line_reverse, bool bw_reverse)
{
cv::Mat m;
int bytes = 0, align = 0;
@ -1144,19 +1191,47 @@ namespace hg_imgproc
m.create(bih.biHeight, bih.biWidth, bih.biBitCount > 8 ? CV_8UC3 : CV_8UC1);
dst = m.ptr();
bytes = (bih.biBitCount + 7) / 8;
bytes *= bih.biWidth;
bytes = (bih.biBitCount * bih.biWidth + 7) / 8;
align = (bytes + 3) / 4 * 4;
if (tiff)
if (line_reverse)
{
data += align * (bih.biHeight - 1);
align *= -1;
}
for (int i = 0; i < bih.biHeight; ++i)
if (bih.biBitCount >= 8)
{
memcpy(dst, data, bytes);
dst += bytes;
data += align;
if (bih.biBitCount == 8 && bw_reverse)
{
for (int i = 0; i < bih.biHeight; ++i)
{
for (int j = 0; j < bytes; ++j)
dst[j] = data[j] ^ 0x0ff;
dst += bytes;
data += align;
}
}
else
{
for (int i = 0; i < bih.biHeight; ++i)
{
memcpy(dst, data, bytes);
dst += bytes;
data += align;
}
}
}
else // if (bih.biBitCount == 1)
{
unsigned char bw[] = { !bw_reverse - 1, bw_reverse - 1};
bytes = bih.biWidth;
for (int i = 0; i < bih.biHeight; ++i)
{
bit_stream bs(data, false);
for (int j = 0; j < bih.biWidth; ++j)
dst[j] = bw[bs.get()];
dst += bytes;
data += align;
}
}
return m;
@ -1179,6 +1254,7 @@ namespace hg_imgproc
if (conv->src.is_file)
{
BITMAPFILEHEADER bfh = { 0 };
FILE* src = fopen(conv->src.data, "rb");
long len = 0;
if (!src)
@ -1193,9 +1269,19 @@ namespace hg_imgproc
return SCANNER_ERR_DATA_DAMAGED;
}
fseek(src, fh, SEEK_SET);
fseek(src, 0, SEEK_SET);
fread(&bfh, sizeof(bfh), 1, src);
fread(&bih, sizeof(bih), 1, src);
len -= sizeof(bih);
if (len < bfh.bfOffBits)
{
fclose(src);
return SCANNER_ERR_DATA_DAMAGED;
}
// we consider pallete as gray, discard pallete here ...
fseek(src, bfh.bfOffBits, SEEK_SET);
len -= bfh.bfOffBits;
data.reset(new std::vector<unsigned char>(len));
fread(&(*data.get())[0], 1, len, src);
fclose(src);
@ -1204,13 +1290,13 @@ namespace hg_imgproc
else
{
memcpy(&bih, conv->src.data + fh, sizeof(bih));
bits = (unsigned char*)conv->src.data + fh + sizeof(bih);
bits = (unsigned char*)conv->src.data + ((LPBITMAPFILEHEADER)conv->src.data)->bfOffBits;
}
bool tiff = conv->dst.fmt.img_format == SANE_IMAGE_TYPE_TIFF;
int resolution = bih.biXPelsPerMeter / 39.37f + .5f,
threshold = (int)(long)conv->dst.fmt.compress.detail;
cv::Mat imsg = from_bmp_file_bits(bih, data->data(), tiff);
cv::Mat imsg = from_bmp_file_bits(bih, data->data(), tiff || conv->dst.fmt.img_format == SANE_IMAGE_TYPE_JFIF, tiff);
data.reset();
if (tiff)
{
@ -1251,6 +1337,8 @@ namespace hg_imgproc
std::vector<int> cpr;
cpr.push_back(CV_IMWRITE_JPEG_QUALITY);
cpr.push_back((int)(long)conv->dst.fmt.detail);
cpr.push_back(CV_IMWRITE_JPEG_RST_INTERVAL);
cpr.push_back(resolution);
if (conv->dst.is_file)
cv::imwrite(conv->dst.data, imsg, cpr);
else
@ -1310,8 +1398,8 @@ namespace hg_imgproc
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;
fh.bfSize = fh.bfOffBits + bih.biSizeImage;
fwrite(&fh, sizeof(fh), 1, dst);
fwrite(&bih, sizeof(bih), 1, dst);