2024-02-06 06:19:53 +00:00
|
|
|
|
#include "bwbmp.h"
|
|
|
|
|
#include <QFile>
|
|
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BWBmp::BWBmp()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BWBmp::LoadBiBmp(QString filename)
|
|
|
|
|
{
|
|
|
|
|
m_bwDdat.clear();
|
|
|
|
|
m_prDdat.clear();
|
|
|
|
|
|
|
|
|
|
QFile file(filename);
|
|
|
|
|
int rslt = file.open(QFile::ReadOnly);
|
|
|
|
|
if (rslt == 0)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "open file error" << filename;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_bwDdat = file.readAll();
|
|
|
|
|
if (m_bwDdat.size() <= (int)sizeof(BitmapHead))
|
|
|
|
|
{
|
|
|
|
|
m_bwDdat.clear();
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
qDebug() << "file size error, size=" << m_bwDdat.size();
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
|
|
|
|
|
|
|
|
|
|
if ( (pHead->identifier != 0x4d42) ||
|
|
|
|
|
(pHead->bitDatOffset != 0x3E) ||
|
|
|
|
|
(pHead->biSize != 0x28) ||
|
|
|
|
|
(pHead->biPlanes != 0x01) ||
|
|
|
|
|
(pHead->biBitPerPixel != 0x01) ||
|
|
|
|
|
(pHead->biCompression != 0x00) ||
|
|
|
|
|
0 )
|
|
|
|
|
{
|
|
|
|
|
m_bwDdat.clear();
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
qDebug() << "not bi bmp";
|
|
|
|
|
return -3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int BWBmp::SavePrBmp(QString filename)
|
|
|
|
|
{
|
|
|
|
|
QFile file(filename);
|
|
|
|
|
int rslt = file.open(QFile::ReadWrite | QFile::Truncate);
|
|
|
|
|
if (rslt == 0)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "open file error" << filename;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
file.write(m_prDdat);
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
/*
|
|
|
|
|
这段C++代码实现了一个名为BWBmp的类的成员函数Compress,该函数的作用是对黑白位图数据进行压缩处理,以便减少喷墨绘图仪的数据传输量。按照注释所描述的压缩算法,算法主要针对的是单个墨盒(假设宽度固定为300像素)的位图数据,其高度可变,最多支持4个墨盒。
|
|
|
|
|
整个函数通过对图像数据进行逐行扫描,统计连续相同颜色像素的数量,并利用特殊的编码规则进行压缩,从而达到减小数据体积的目的。当遇到不适合压缩的情况时,会选择直接复制原始数据,以保证不会因压缩反而增大数据量。
|
|
|
|
|
|
|
|
|
|
为了减少喷墨绘图仪的数据传输量,对黑白位图数据进行压缩。
|
|
|
|
|
压缩算法如下:
|
|
|
|
|
|
|
|
|
|
每个墨盒的位图数据宽度为300像素,高度不确定,墨盒数量支持1--4个
|
|
|
|
|
|
|
|
|
|
每个字节分为两段
|
|
|
|
|
用属性+值 的方式表示
|
|
|
|
|
__________________________________________________
|
|
|
|
|
| bit7 bit6 | bit5 bit4 bit3 bit2 bit1 bit0 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 属性 | 值 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 0 0 | 原始数据 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 0 1 | 连续数据1的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 1 0 | 连续65个数据0的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 1 1 | 连续数据0的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
int BWBmp::Compress(int idx, int dir, int segWidth, int segHeight)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// qint64 startTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
|
|
|
|
// 确保dir参数正确设置为1或-1,表示读取图像数据的方向(从上到下或从下到上)。
|
|
|
|
|
if (dir < 0)
|
|
|
|
|
{
|
|
|
|
|
dir = -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dir = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清理目标压缩数据缓冲区,并检查源位图数据是否为空,若为空则返回错误码-1。
|
|
|
|
|
m_prDdat.clear();
|
|
|
|
|
if (m_bwDdat.isEmpty() == 1)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "bit dat empty";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化临时压缩数据缓冲区tmppr,并从源位图数据中获取图像的基本信息,如宽度、高度、实际占用的字节数(行字节数),并检查这些信息的有效性,如有问题则返回错误码-2。
|
|
|
|
|
|
|
|
|
|
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
|
|
|
|
|
|
|
|
|
|
int width = pHead->biWidth; // 文件宽度
|
|
|
|
|
int height = pHead->biHeight; // 文件高度
|
|
|
|
|
int widthBytes = (int)((width + (32-1)) / 32) * 4; // 文件每行字节数
|
|
|
|
|
|
|
|
|
|
int wsegnum = (int)((width + segWidth - 1) / segWidth); // 宽分块数量
|
|
|
|
|
int hsegnum = (int)((height + segHeight - 1) / segHeight); // 高分块数量
|
|
|
|
|
int fill = (int)((segWidth + (8-1)) / 8) * 8 - segWidth; // 分块后每行补充Bit数
|
|
|
|
|
int msegnum = (segWidth + fill) * segHeight; // 每块字节数
|
|
|
|
|
|
|
|
|
|
if (0)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "Img dir"<<dir;
|
|
|
|
|
qDebug() << "Img width"<<width;
|
|
|
|
|
qDebug() << "Img height"<<height;
|
|
|
|
|
qDebug() << "Img wsegnum"<<wsegnum;
|
|
|
|
|
qDebug() << "Img hsegnum"<<hsegnum;
|
|
|
|
|
qDebug() << "Img msegnum"<<msegnum;
|
|
|
|
|
qDebug() << "Img fill"<<fill;
|
|
|
|
|
qDebug() << "Img widthBytes"<<widthBytes;
|
|
|
|
|
qDebug() << "Img bitDatOffset"<<pHead->bitDatOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (widthBytes <= 0 || height < 1 || width > 0x1000000)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "bit dat error";
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const unsigned char * pBitDatBeg = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset);
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// 读取位图信息,对数组赋值
|
|
|
|
|
unsigned char sta,tmpdat,mod;
|
2024-03-22 07:58:53 +00:00
|
|
|
|
sta = tmpdat = mod = 0;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
const unsigned char * pBitDat;
|
|
|
|
|
int i, j, k, l, m, n;
|
|
|
|
|
int addr;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
//------------------------------------
|
|
|
|
|
int * segdat = new int [msegnum];
|
|
|
|
|
|
|
|
|
|
//------------------------------------
|
2024-03-22 07:58:53 +00:00
|
|
|
|
unsigned char tgtdat = 0;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
QVector<unsigned char> compType(wsegnum); // 本块位图压缩类型, =0, 不压缩; =1, 按字节压缩(分段压缩);
|
|
|
|
|
QVector<unsigned int> compSegOffset(wsegnum); // 分段数据起始位置
|
|
|
|
|
|
|
|
|
|
if (dir < 0) // 反向
|
|
|
|
|
{
|
|
|
|
|
pBitDatBeg += widthBytes * (height -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < wsegnum; i++)
|
|
|
|
|
{// 分块
|
|
|
|
|
addr = m_prDdat.size(); // 压缩前的字节数
|
|
|
|
|
compType[i] = 1; // 按字节压缩(分段压缩);
|
|
|
|
|
compSegOffset[i] = m_prDdat.size(); // 数据地址
|
|
|
|
|
|
|
|
|
|
if (1)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < hsegnum; j++)
|
|
|
|
|
{// 分块
|
|
|
|
|
if (dir > 0) // 正向
|
|
|
|
|
{
|
|
|
|
|
y = j * segHeight; // 起始坐标点 Y
|
|
|
|
|
m = 0; // 分割后数组的索引
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < segHeight; l++,y++)
|
|
|
|
|
{// Y扫描
|
|
|
|
|
|
|
|
|
|
x = i * segWidth; // 起始坐标点 X
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < segWidth; k++,x++)
|
|
|
|
|
{// x扫描赋值
|
|
|
|
|
if ((x < width) && (y < height))
|
|
|
|
|
{// 采集当前点数据
|
|
|
|
|
pBitDat = pBitDatBeg + (widthBytes * (height-y-1)) + (x / 8);
|
|
|
|
|
|
|
|
|
|
tmpdat = *pBitDat;
|
|
|
|
|
mod = 0x80 >> (x % 8);
|
|
|
|
|
if ((tmpdat & mod) == 0)
|
|
|
|
|
{
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sta = 1;
|
|
|
|
|
// qDebug() << "x =" << x << ",y =" << y
|
|
|
|
|
// << ",[i =" << i << ",j =" << j
|
|
|
|
|
// << ",l =" << l << ",k =" << k
|
|
|
|
|
// << ",m =" << m << "]";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{// X,Y超出最大范围后,使用默认值:0
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < fill; k++)
|
|
|
|
|
{// x结尾处 字节对齐
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//if (dir > 0)
|
|
|
|
|
{// 反向
|
|
|
|
|
y = (hsegnum - j) * segHeight - 1; // 起始坐标点 Y
|
|
|
|
|
m = 0; // 分割后数组的索引
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < segHeight; l++,y--)
|
|
|
|
|
{// Y反向扫描
|
|
|
|
|
x = i * segWidth; // 起始坐标点 X
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < segWidth; k++,x++)
|
|
|
|
|
{// x扫描赋值
|
|
|
|
|
if ((x < width) && (y < height))
|
|
|
|
|
{// 采集当前点数据
|
|
|
|
|
pBitDat = pBitDatBeg - (widthBytes * y) + (x / 8);
|
|
|
|
|
|
|
|
|
|
tmpdat = *pBitDat;
|
|
|
|
|
mod = 0x80 >> (x % 8);
|
|
|
|
|
if ((tmpdat & mod) == 0)
|
|
|
|
|
{
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sta = 1;
|
|
|
|
|
// qDebug() << "x =" << x << ",y =" << y
|
|
|
|
|
// << ",[i =" << i << ",j =" << j
|
|
|
|
|
// << ",l =" << l << ",k =" << k
|
|
|
|
|
// << "]";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{// X,Y超出最大范围后,使用默认值:0
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
for (k = 0; k < fill; k++)
|
|
|
|
|
{// x结尾处 字节对齐
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// 对数据进行压缩
|
|
|
|
|
for (k = 0; k < msegnum; k = l)
|
|
|
|
|
{
|
|
|
|
|
n = 0; // 连续的个数
|
|
|
|
|
sta = segdat[k]; // 前一次的状态
|
|
|
|
|
tgtdat = 0;
|
|
|
|
|
|
|
|
|
|
// 求连续相同状态的个数
|
|
|
|
|
for (l = k; l < msegnum; l++)
|
|
|
|
|
{
|
|
|
|
|
n++;
|
|
|
|
|
if (n <= 6)
|
|
|
|
|
{// 预先计算原始数据
|
|
|
|
|
tgtdat <<= 1;
|
|
|
|
|
|
|
|
|
|
if (segdat[l] != 0)
|
|
|
|
|
{
|
|
|
|
|
tgtdat |= 0x01;
|
|
|
|
|
}
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
if (n == 6)
|
|
|
|
|
{// 判断前六个位图是否相同
|
|
|
|
|
if (((sta == 0) && (tgtdat != 0)) ||
|
|
|
|
|
((sta != 0) && (tgtdat != 0x3f)) ||
|
|
|
|
|
0)
|
|
|
|
|
{
|
|
|
|
|
l++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else// if (n > 6)
|
|
|
|
|
{
|
|
|
|
|
if (segdat[l] != sta)
|
|
|
|
|
{
|
|
|
|
|
n--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (sta == 0)
|
|
|
|
|
{// 连续0 (最多 4160)
|
|
|
|
|
if (n == 4160)
|
|
|
|
|
{
|
|
|
|
|
l++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{// 连续1 (最多64)
|
|
|
|
|
if (n == 64)
|
|
|
|
|
{
|
|
|
|
|
l++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( ;n<6;n++)
|
|
|
|
|
{// 原始位图时,如果结尾不足6位,低位补零
|
|
|
|
|
tgtdat <<= 1;
|
|
|
|
|
// qDebug() << "for ( ;n<6;n++) n =" << n << ",l =" << l ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{// 生成压缩数据
|
|
|
|
|
if (n == 6)
|
|
|
|
|
{
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加原始位图数据
|
|
|
|
|
}
|
|
|
|
|
else if (sta == 0)
|
|
|
|
|
{
|
|
|
|
|
if (n <= 64)
|
|
|
|
|
{
|
|
|
|
|
tgtdat = 0xC0 | (n & 0x3f);
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加连续数据0的个数数据
|
|
|
|
|
}
|
|
|
|
|
else if (n == 4160)
|
|
|
|
|
{
|
|
|
|
|
tgtdat = 0x80;
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加连续 65 个数据0的个数数据
|
|
|
|
|
}
|
|
|
|
|
else // (64 < n < 4160)
|
|
|
|
|
{
|
|
|
|
|
tgtdat = 0x80 | (n / 65);
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加连续 65 个数据0的个数数据
|
|
|
|
|
|
|
|
|
|
tgtdat = n % 65;
|
|
|
|
|
if (tgtdat != 0)
|
|
|
|
|
{
|
|
|
|
|
tgtdat = 0xC0 | tgtdat;
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加连续数据0的个数数据
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // if (sta == 1)
|
|
|
|
|
{
|
|
|
|
|
tgtdat = 0x40 | (n & 0x3f);
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加 连续数据1的个数 数据
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // for (j = 0; j < hsegnum; j++)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// 判断压缩后的数据是否比压缩前的小
|
|
|
|
|
if ((m_prDdat.size() - addr) > (msegnum * hsegnum / 7))
|
|
|
|
|
{// 使用原始数据
|
|
|
|
|
m_prDdat.truncate(addr); // 删除当前段的压缩数据
|
|
|
|
|
compType[i] = 0; // 不压缩,使用原始数据;
|
|
|
|
|
|
|
|
|
|
for (j = 0; j < hsegnum; j++)
|
|
|
|
|
{// 分块
|
|
|
|
|
if (dir > 0) // 正向
|
|
|
|
|
{
|
|
|
|
|
y = j * segHeight; // 起始坐标点 Y
|
|
|
|
|
m = 0; // 分割后数组的索引
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < segHeight; l++,y++)
|
|
|
|
|
{// Y扫描
|
|
|
|
|
|
|
|
|
|
x = i * segWidth; // 起始坐标点 X
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < segWidth; k++,x++)
|
|
|
|
|
{// x扫描赋值
|
|
|
|
|
if ((x < width) && (y < height))
|
|
|
|
|
{// 采集当前点数据
|
|
|
|
|
pBitDat = pBitDatBeg + (widthBytes * (height-y-1)) + (x / 8);
|
|
|
|
|
|
|
|
|
|
tmpdat = *pBitDat;
|
|
|
|
|
mod = 0x80 >> (x % 8);
|
|
|
|
|
if ((tmpdat & mod) == 0)
|
|
|
|
|
{
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sta = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{// X,Y超出最大范围后,使用默认值:0
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < fill; k++)
|
|
|
|
|
{// x结尾处 字节对齐
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//if (dir > 0)
|
|
|
|
|
{// 反向
|
|
|
|
|
y = (hsegnum - j) * segHeight - 1; // 起始坐标点 Y
|
|
|
|
|
m = 0; // 分割后数组的索引
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < segHeight; l++,y--)
|
|
|
|
|
{// Y反向扫描
|
|
|
|
|
x = i * segWidth; // 起始坐标点 X
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < segWidth; k++,x++)
|
|
|
|
|
{// x扫描赋值
|
|
|
|
|
if ((x < width) && (y < height))
|
|
|
|
|
{// 采集当前点数据
|
|
|
|
|
pBitDat = pBitDatBeg - (widthBytes * y) + (x / 8);
|
|
|
|
|
|
|
|
|
|
tmpdat = *pBitDat;
|
|
|
|
|
mod = 0x80 >> (x % 8);
|
|
|
|
|
if ((tmpdat & mod) == 0)
|
|
|
|
|
{
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sta = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{// X,Y超出最大范围后,使用默认值:0
|
|
|
|
|
sta = 0;
|
|
|
|
|
}
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < fill; k++)
|
|
|
|
|
{// x结尾处 字节对齐
|
|
|
|
|
segdat[m++] = sta;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成原始数据
|
|
|
|
|
n = 0;
|
|
|
|
|
for (m = 0; m < msegnum; m++)
|
|
|
|
|
{
|
|
|
|
|
tgtdat <<= 1;
|
|
|
|
|
if (segdat[m] != 0)
|
|
|
|
|
{
|
|
|
|
|
tgtdat |= 0x01;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n++;
|
|
|
|
|
if ((n % 8) == 0)
|
|
|
|
|
{
|
|
|
|
|
m_prDdat.append(tgtdat); // 添加 连续数据1的个数 数据
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} // for (i = 0; i < wsegnum; i++)
|
|
|
|
|
|
|
|
|
|
// qint64 time1 = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
|
|
|
|
// qDebug() << "time1:" << time1 - startTime;
|
|
|
|
|
|
|
|
|
|
delete []segdat;
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// 构造压缩位图头部信息CompBmpHead,包含块索引、压缩方向、压缩类型以及压缩后的数据大小等信息。
|
|
|
|
|
// 添加文件头
|
|
|
|
|
CompBmpHead prHead;
|
|
|
|
|
memset(&prHead, 0, sizeof(CompBmpHead));
|
|
|
|
|
|
|
|
|
|
prHead.fileId = 0; // 整个位图文件标识
|
|
|
|
|
prHead.blkIdx = idx; // 当前位图块号(位图分块后的编号)
|
|
|
|
|
prHead.datSize = m_prDdat.size(); // 本块位图数据区的大小(字节数)
|
|
|
|
|
prHead.biHeight = segHeight * hsegnum; // 本块位图有效宽度,以像素为单位
|
|
|
|
|
prHead.biWidth = segWidth * wsegnum; // 本块位图有效高度,以像素为单位
|
|
|
|
|
prHead.dataChecksum = 0; // 本块位图数据累加校验和
|
|
|
|
|
|
|
|
|
|
if (dir < 0) // 本块位图压缩方向, =0, 从上到下; =1, 从下到上;(喷墨方向)
|
|
|
|
|
{
|
|
|
|
|
prHead.compDir = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
prHead.compDir = 0;
|
|
|
|
|
}
|
|
|
|
|
prHead.compSegWidth = segWidth; // 分段宽度(0,默认整个宽度,分段宽度必须能被本块位图有效宽度整除)
|
|
|
|
|
prHead.compSegHeight = segHeight; // 分段高度(0,默认1行的高度)
|
|
|
|
|
prHead.compFillWidth = fill; // 压缩填充位数
|
|
|
|
|
|
|
|
|
|
for (i=0;i<4;i++)
|
|
|
|
|
{
|
|
|
|
|
if (i < wsegnum)
|
|
|
|
|
{
|
|
|
|
|
prHead.compType[i] = compType[i]; // 本块位图压缩类型, =0, 不压缩; =1, 按字节压缩(分段压缩);
|
|
|
|
|
prHead.compSegOffset[i] = compSegOffset[i]; // 分段数据起始位置
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// {// 打印压缩数据
|
|
|
|
|
// j = m_prDdat.size();
|
|
|
|
|
// const unsigned char * pPrint = (unsigned char *)(m_prDdat.data());
|
|
|
|
|
|
|
|
|
|
// for (i=0;i<j;i++)
|
|
|
|
|
// {
|
|
|
|
|
// tmpdat = *pPrint++;
|
|
|
|
|
|
|
|
|
|
// qDebug() << "addr =" << i << ",dat =" << tmpdat;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
m_prDdat.insert(0,(char*)(&prHead),sizeof(CompBmpHead)); // 插入文件头
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray BWBmp::getPrBmpDat()
|
|
|
|
|
{
|
|
|
|
|
return m_prDdat;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
这段C++代码实现了一个名为BWBmp的类的成员函数Compress,该函数的作用是对黑白位图数据进行压缩处理,以便减少喷墨绘图仪的数据传输量。按照注释所描述的压缩算法,算法主要针对的是单个墨盒(假设宽度固定为300像素)的位图数据,其高度可变,最多支持4个墨盒。
|
|
|
|
|
整个函数通过对图像数据进行逐行扫描,统计连续相同颜色像素的数量,并利用特殊的编码规则进行压缩,从而达到减小数据体积的目的。当遇到不适合压缩的情况时,会选择直接复制原始数据,以保证不会因压缩反而增大数据量。
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
为了减少喷墨绘图仪的数据传输量,对黑白位图数据进行压缩。
|
|
|
|
|
压缩算法如下:
|
|
|
|
|
|
|
|
|
|
每个墨盒的位图数据宽度为300像素,高度不确定,墨盒数量支持1--4个
|
|
|
|
|
|
|
|
|
|
每个字节分为两段
|
|
|
|
|
用属性+值 的方式表示
|
|
|
|
|
__________________________________________________
|
|
|
|
|
| bit7 bit6 | bit5 bit4 bit3 bit2 bit1 bit0 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 属性 | 值 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 0 0 | 原始数据 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 0 1 | 连续数据1的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 1 0 | 连续10个数据0的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
| 1 1 | 连续数据0的个数 |
|
|
|
|
|
--------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
int Compress_Bak(int idx, int dir)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 确保dir参数正确设置为1或-1,表示读取图像数据的方向(从上到下或从下到上)。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
if (dir < 0)
|
|
|
|
|
{
|
|
|
|
|
dir = -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dir = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 清理目标压缩数据缓冲区,并检查源位图数据是否为空,若为空则返回错误码-1。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
m_prDdat.clear();
|
|
|
|
|
if (m_bwDdat.isEmpty() == 1)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "bit dat empty";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 初始化临时压缩数据缓冲区tmppr,并从源位图数据中获取图像的基本信息,如宽度、高度、实际占用的字节数(行字节数),并检查这些信息的有效性,如有问题则返回错误码-2。
|
|
|
|
|
QByteArray tmppr;
|
|
|
|
|
tmppr.clear();
|
|
|
|
|
|
2024-02-06 06:19:53 +00:00
|
|
|
|
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
|
|
|
|
|
|
|
|
|
|
int width = pHead->biWidth;
|
|
|
|
|
int height = pHead->biHeight;
|
|
|
|
|
int widthBytes = (int)((width + 31) / 32) * 4;
|
|
|
|
|
|
|
|
|
|
if (widthBytes <= 0 || height < 1 || width > 0x1000000)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "bit dat error";
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
qDebug() << "Img dir"<<dir;
|
|
|
|
|
qDebug() << "Img width"<<width;
|
|
|
|
|
qDebug() << "Img height"<<height;
|
|
|
|
|
qDebug() << "Img widthBytes"<<widthBytes;
|
|
|
|
|
qDebug() << "Img bitDatOffset"<<pHead->bitDatOffset;
|
|
|
|
|
|
|
|
|
|
const unsigned char * pBitDatBeg = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset);
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
|
|
|
|
const unsigned char * pTmpDat;
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 按照给定的dir值定位到位图数据的起始位置。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
if (dir == -1)
|
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
pBitDatBeg += widthBytes * (height -1);
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
const unsigned char * pBitDat = pBitDatBeg;
|
|
|
|
|
|
|
|
|
|
// 使用一个整数数组 countBuff 来记录每行中连续的0和1的个数,初始化各种计数器。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
int * countBuff = new int [width];
|
|
|
|
|
if (countBuff == NULL)
|
|
|
|
|
{
|
|
|
|
|
qDebug() << "no enough memory";
|
|
|
|
|
return -3;
|
|
|
|
|
}
|
|
|
|
|
memset(countBuff, 0, sizeof(int)*width);
|
|
|
|
|
|
|
|
|
|
unsigned char tmpdat, mod;
|
|
|
|
|
int datsta = -1;
|
|
|
|
|
int count0 = 0;
|
|
|
|
|
int count1 = 0;
|
|
|
|
|
|
|
|
|
|
int i, j, k, l;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
|
2024-02-06 06:19:53 +00:00
|
|
|
|
for (i = 0; i < height; i++) // 行计数
|
|
|
|
|
{
|
|
|
|
|
pTmpDat = pBitDat;
|
|
|
|
|
int countIdx = 0;
|
|
|
|
|
count0 = 0;
|
|
|
|
|
count1 = 0;
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 遍历图像的每一行,统计当前行中连续0和1的个数,并将其存入countBuff数组。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
for (j = 0, k = 0; (j < widthBytes) && (k < width); j++) // 行内扫描,检测出每段连续0和1的个数
|
|
|
|
|
{
|
|
|
|
|
tmpdat = *pTmpDat++;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
//qDebug()<<j+i*widthBytes<<" "<<tmpdat;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
mod = 0x80;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
|
|
|
|
if((width - k) <= 8)
|
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// tmpdat = tmpdat >> (8 - (width - k ));
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
for (mod = 0x80; (mod != 0) && (k < width); k++, mod /= 2)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
|
|
|
|
if ((tmpdat & mod) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (datsta == 1)
|
|
|
|
|
{
|
|
|
|
|
count1 |= 0x80000000;
|
|
|
|
|
countBuff[countIdx] = count1;
|
|
|
|
|
countIdx++;
|
|
|
|
|
count1 = 0;
|
|
|
|
|
}
|
|
|
|
|
datsta = 0;
|
|
|
|
|
count0++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (datsta == 0)
|
|
|
|
|
{
|
|
|
|
|
countBuff[countIdx] = count0;
|
|
|
|
|
countIdx++;
|
|
|
|
|
count0 = 0;
|
|
|
|
|
}
|
|
|
|
|
datsta = 1;
|
|
|
|
|
count1++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count0 != 0)
|
|
|
|
|
{
|
|
|
|
|
countBuff[countIdx] = count0;
|
|
|
|
|
countIdx++;
|
|
|
|
|
count0 = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count1 != 0)
|
|
|
|
|
{
|
|
|
|
|
count1 |= 0x80000000;
|
|
|
|
|
countBuff[countIdx] = count1;
|
|
|
|
|
countIdx++;
|
|
|
|
|
count1 = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 对countBuff中的数据进行分析和编码,生成压缩数据并追加到tmppr中。根据算法描述,压缩数据是以每个字节的高两位作为“属性”位,低六位作为“值”位来表示连续0或1的个数,或者直接存放原始数据。
|
2024-02-06 06:19:53 +00:00
|
|
|
|
int psta = 0;
|
|
|
|
|
int pcount = 0;
|
|
|
|
|
unsigned char tgtdat = 0, pmod = 0x20, nums;
|
|
|
|
|
|
|
|
|
|
for (l = 0; l < countIdx; l++) // 分析数据,生成压缩数据
|
|
|
|
|
{
|
|
|
|
|
if ((countBuff[l] & 0x80000000) != 0)
|
|
|
|
|
{
|
|
|
|
|
count1 = countBuff[l] & 0xfffffff;
|
|
|
|
|
|
|
|
|
|
while (count1 != 0)
|
|
|
|
|
{
|
|
|
|
|
if (psta == 0) // 当前状态是原始数据
|
|
|
|
|
{
|
|
|
|
|
if (pcount != 0)
|
|
|
|
|
{
|
|
|
|
|
while (count1 != 0 && pcount != 0)
|
|
|
|
|
{
|
|
|
|
|
tgtdat |= pmod;
|
|
|
|
|
pcount--;
|
|
|
|
|
count1--;
|
|
|
|
|
pmod *= 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pcount == 0) // 够一个位图
|
|
|
|
|
{
|
|
|
|
|
tgtdat &= 0x3f;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
tmppr.append(tgtdat); // 添加
|
2024-02-06 06:19:53 +00:00
|
|
|
|
tgtdat = 0x00;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pcount == 0 && count1 != 0) //
|
|
|
|
|
{
|
|
|
|
|
while (count1 != 0)
|
|
|
|
|
{
|
|
|
|
|
if (count1 <= 6)
|
|
|
|
|
{
|
|
|
|
|
psta = 0x00; // 位图模式
|
|
|
|
|
tgtdat = psta;
|
|
|
|
|
pmod = 0x01;
|
|
|
|
|
pcount = 6;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (count1 > 64)
|
|
|
|
|
{
|
|
|
|
|
nums = 64;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nums = count1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
psta = 0x40;
|
|
|
|
|
tgtdat = psta;
|
|
|
|
|
tgtdat |= (nums & 0x3f);
|
2024-03-08 08:33:05 +00:00
|
|
|
|
tmppr.append(tgtdat); // 添加
|
|
|
|
|
//qDebug()<<tmppr.size()<<tgtdat;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
count1 -= nums;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
count0 = countBuff[l] & 0xfffffff;
|
|
|
|
|
|
|
|
|
|
while (count0 != 0)
|
|
|
|
|
{
|
|
|
|
|
if (psta == 0) // 当前状态是原始数据
|
|
|
|
|
{
|
|
|
|
|
if (pcount != 0)
|
|
|
|
|
{
|
|
|
|
|
while (count0 != 0 && pcount != 0)
|
|
|
|
|
{
|
|
|
|
|
tgtdat &= (~pmod);
|
|
|
|
|
pcount--;
|
|
|
|
|
count0--;
|
|
|
|
|
pmod *= 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pcount == 0) // 够一个位图
|
|
|
|
|
{
|
|
|
|
|
tgtdat &= 0x3f;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
tmppr.append(tgtdat); // 添加
|
|
|
|
|
//qDebug()<<tmppr.size()<<tgtdat;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
tgtdat = 0x00;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pcount == 0 && count0 != 0) //
|
|
|
|
|
{
|
|
|
|
|
while (count0 != 0)
|
|
|
|
|
{
|
|
|
|
|
if (count0 <= 6)
|
|
|
|
|
{
|
|
|
|
|
psta = 0x00; // 位图模式
|
|
|
|
|
tgtdat = psta;
|
|
|
|
|
pmod = 0x01;
|
|
|
|
|
pcount = 6;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int muti = 1;
|
|
|
|
|
if (count0 >= 640)
|
|
|
|
|
{
|
|
|
|
|
nums = 64;
|
|
|
|
|
muti = 10;
|
|
|
|
|
psta = 0x80;
|
|
|
|
|
}
|
|
|
|
|
else if (count0 >= 64)
|
|
|
|
|
{
|
|
|
|
|
nums = (int)(count0/10);
|
|
|
|
|
muti = 10;
|
|
|
|
|
psta = 0x80;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nums = count0;
|
|
|
|
|
muti = 1;
|
|
|
|
|
psta = 0xC0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tgtdat = psta;
|
|
|
|
|
tgtdat |= (nums & 0x3f);
|
2024-03-08 08:33:05 +00:00
|
|
|
|
tmppr.append(tgtdat); // 添加
|
|
|
|
|
//qDebug()<<tmppr.size()<<tgtdat;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
count0 -= nums * muti;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (psta == 0 && pcount != 0) // 不满一个位图的数据(小于6)
|
|
|
|
|
{
|
|
|
|
|
pcount = 0;
|
|
|
|
|
tgtdat &= 0x3f;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
tmppr.append(tgtdat); // 添加
|
2024-02-06 06:19:53 +00:00
|
|
|
|
tgtdat = 0x00;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 下一行
|
|
|
|
|
pBitDat += widthBytes * dir;
|
|
|
|
|
}
|
|
|
|
|
delete []countBuff;
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
// 构造压缩位图头部信息CompBmpHead,包含块索引、压缩方向、压缩类型以及压缩后的数据大小等信息。
|
|
|
|
|
// 添加文件头
|
|
|
|
|
CompBmpHead prHead;
|
|
|
|
|
memset(&prHead, 0, sizeof(CompBmpHead));
|
|
|
|
|
prHead.blkIdx = idx;
|
|
|
|
|
prHead.biHeight = pHead->biHeight;
|
|
|
|
|
prHead.biWidth = pHead->biWidth;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
if (dir < 0)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
prHead.compDir = 1;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
prHead.compDir = 0;
|
|
|
|
|
}
|
|
|
|
|
// 若压缩后数据量(tmppr.size())大于原位图数据量,则放弃压缩,直接复制原数据。
|
|
|
|
|
unsigned int prsize = tmppr.size();
|
|
|
|
|
if (prsize >= pHead->biBitmapDatSize) // 压缩率不足
|
|
|
|
|
{
|
|
|
|
|
prHead.compType = 0; // 不压缩
|
|
|
|
|
prHead.datSize = pHead->biBitmapDatSize;
|
|
|
|
|
|
|
|
|
|
tmppr.clear();
|
|
|
|
|
pBitDat = pBitDatBeg;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
for (i = 0; i < height; i++) // 行计数
|
|
|
|
|
{
|
|
|
|
|
tmppr.append((const char*)pBitDat, widthBytes);
|
|
|
|
|
pBitDat += widthBytes * dir;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
prHead.compType = 1;
|
|
|
|
|
prHead.datSize = prsize;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
m_prDdat.append((char*)(&prHead), sizeof(CompBmpHead));
|
|
|
|
|
m_prDdat.append(tmppr);
|
|
|
|
|
|
2024-02-06 06:19:53 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
#define VAL_OUTBMP 0xff // 位图之外的默认数据
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
m_rbwDdat.append((char*)(&bmpHead), sizeof(BitmapHead));
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
|
|
|
|
unsigned char sdat = 0;
|
|
|
|
|
int count0,count1,flag;
|
|
|
|
|
count0 = count1 = 0;
|
|
|
|
|
flag = -1;
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
count0 = count1 = 0;
|
|
|
|
|
flag = -1;
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
sdat = pPrDdat[i];
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
|
|
|
|
if((sdat & 0xC0) == 0xC0) // 连续0
|
|
|
|
|
{
|
|
|
|
|
count0 = sdat & 0x3f;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
if (count0 == 0)
|
|
|
|
|
{
|
|
|
|
|
count0 = 64;
|
|
|
|
|
}
|
2024-02-06 06:19:53 +00:00
|
|
|
|
flag = 0;
|
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
else if((sdat & 0xC0) == 0x40) // 连续1
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
count1 = sdat & 0x3f;
|
|
|
|
|
if (count1 == 0)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
count1 = 64;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
flag = 1;
|
|
|
|
|
}
|
|
|
|
|
else if((sdat & 0xC0) == 0x80) // 连续10个0
|
|
|
|
|
{
|
|
|
|
|
count0 = (sdat & 0x3f ) * 10;
|
|
|
|
|
if (count0 == 0)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
count0 = 640;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
flag = 0;
|
|
|
|
|
}
|
|
|
|
|
else // 原始数据
|
|
|
|
|
{//每行扫描时最后一个像素为原始数据时原始数据个数
|
|
|
|
|
int pcount = 6;
|
|
|
|
|
int val = arrdat.size() % biWidth;
|
|
|
|
|
int cnt = biWidth - val;
|
|
|
|
|
int cnt1 = abs((int)biWidth - ((int)widthBytes-1) * 8);
|
|
|
|
|
if(cnt >= cnt1)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
pcount = 6;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(cnt > 6)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
|
|
|
|
pcount = 6;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
pcount = cnt;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
}
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
unsigned char sch = sdat & 0x3f; //够一个位图
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
unsigned char pmod = 0x01;
|
|
|
|
|
while (pcount != 0)
|
|
|
|
|
{
|
|
|
|
|
if((sch & pmod) != 0) // 为1
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
arrdat.append((char)0x01);
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
else // 为0
|
|
|
|
|
{
|
|
|
|
|
arrdat.append((char)0x00);
|
|
|
|
|
}
|
|
|
|
|
pcount--;
|
|
|
|
|
pmod *= 2;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
|
|
|
|
|
continue;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
unsigned char ch = 0;
|
|
|
|
|
if(flag == 0)
|
|
|
|
|
{
|
|
|
|
|
count = count0;
|
|
|
|
|
ch = 0;
|
|
|
|
|
}
|
|
|
|
|
else if(flag == 1)
|
|
|
|
|
{
|
|
|
|
|
count = count1;
|
|
|
|
|
ch = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(int j = 0; j < count; j++)
|
|
|
|
|
{
|
|
|
|
|
arrdat.append(ch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int num = 0;
|
2024-03-08 08:33:05 +00:00
|
|
|
|
unsigned int lst = ((biWidth/8)*8+8);
|
|
|
|
|
|
|
|
|
|
for(unsigned int n = 0; n < biHeight; n++)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
|
|
|
|
for(int j = 0; j < widthBytes; j++)
|
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
unsigned int cnt = j*8;
|
|
|
|
|
unsigned char abyte = 0;
|
|
|
|
|
|
|
|
|
|
int idx = n*biWidth+j*8;
|
|
|
|
|
for(int i = 0; i < 8; i++, idx++, cnt++)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
|
|
|
|
//qDebug()<<"idx"<<idx;
|
|
|
|
|
//qDebug()<<"ch"<<ch;
|
|
|
|
|
|
2024-03-08 08:33:05 +00:00
|
|
|
|
if (cnt < biWidth)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
unsigned char ch = arrdat[idx];
|
|
|
|
|
if (ch != 0)
|
|
|
|
|
{
|
|
|
|
|
abyte |= (ch << (7-i));
|
|
|
|
|
}
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
else if(cnt >= lst)
|
2024-02-06 06:19:53 +00:00
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
abyte = VAL_OUTBMP; // 默认值
|
|
|
|
|
break;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-03-08 08:33:05 +00:00
|
|
|
|
abyte |= ((VAL_OUTBMP) >> (i)); // 默认值
|
|
|
|
|
break;
|
2024-02-06 06:19:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if(abyte != 0)
|
|
|
|
|
{
|
|
|
|
|
//qDebug()<<num<<" "<<abyte;
|
|
|
|
|
}
|
|
|
|
|
m_rbwDdat.append(abyte);
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-08 08:33:05 +00:00
|
|
|
|
*/
|
2024-02-06 06:19:53 +00:00
|
|
|
|
|