PlotterHMI/machine/bmp/bwbmp.cpp

605 lines
16 KiB
C++
Raw Normal View History

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;
}
int BWBmp::Compress(int dir)
{
/*
300
+
__________________________________________________
| bit7 bit6 | bit5 bit4 bit3 bit2 bit1 bit0 |
--------------------------------------------------
| | |
--------------------------------------------------
| 0 0 | |
--------------------------------------------------
| 0 1 | 1 |
--------------------------------------------------
| 1 0 | 100 |
--------------------------------------------------
| 1 1 | 0 |
--------------------------------------------------
*/
if (dir < 0)
{
dir = -1;
}
else
{
dir = 1;
}
m_prDdat.clear();
if (m_bwDdat.isEmpty() == 1)
{
qDebug() << "bit dat empty";
return -1;
}
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;
}
const unsigned char * pBitDat = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset);
const unsigned char * pTmpDat;
if (dir == -1)
{
pBitDat += widthBytes * (height -1);
}
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;
for (i = 0; i < height; i++) // 行计数
{
pTmpDat = pBitDat;
int countIdx = 0;
count0 = 0;
count1 = 0;
for (j = 0, k = 0; (j < widthBytes) && (k < width); j++) // 行内扫描检测出每段连续0和1的个数
{
tmpdat = *pTmpDat++;
// if(j+i*widthBytes > 12879)
// {
// qDebug()<<j+i*widthBytes<<" "<<tmpdat;
// }
//mod = 0x80;
mod = 0x01;
if((width - k) <= 8)
{
tmpdat = tmpdat >> (8 - (width - k ));
}
//for (mod = 0x80; (mod != 0) && (k < width); k++, mod /= 2)
for (mod = 0x01; (mod != 0) && (k < width); k++, mod *= 2)
{
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;
}
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;
pmod *= 2;
}
if (pcount == 0) // 够一个位图
{
tgtdat &= 0x3f;
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
tgtdat = 0x00;
}
}
}
if (pcount == 0 && count1 != 0) //
{
while (count1 != 0)
{
if (count1 <= 6)
{
psta = 0x00; // 位图模式
tgtdat = psta;
//pmod = 0x20;
pmod = 0x01;
pcount = 6;
break;
}
else
{
if (count1 > 64)
{
nums = 64;
}
else
{
nums = count1;
}
psta = 0x40;
tgtdat = psta;
tgtdat |= (nums & 0x3f);
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
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;
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
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)
else if (count0 >= 64)
{
nums = (int)(count0/10);
muti = 10;
psta = 0x80;
}
else
{
nums = count0;
muti = 1;
psta = 0xC0;
}
tgtdat = psta;
tgtdat |= (nums & 0x3f);
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
count0 -= nums * muti;
}
}
}
}
}
}
if (psta == 0 && pcount != 0) // 不满一个位图的数据(小于6)
{
pcount = 0;
tgtdat &= 0x3f;
m_prDdat.append(tgtdat); // 添加
tgtdat = 0x00;
}
// 下一行
pBitDat += widthBytes * dir;
}
delete []countBuff;
// m_prDdat.append((char*)); // 添加文件头
// int size = m_prDdat.size();
// for(int p = 0; p < size; p++)
// {
// unsigned char ch = m_prDdat[p];
// qDebug()<<p<<" "<<ch;
// }
return 0;
}
int BWBmp::LoadPrBmp(QString filename)
{
m_fileName = filename;
m_rbwDdat.clear();
m_prDdat.clear();
QFile file(filename);
int rslt = file.open(QFile::ReadOnly);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
m_prDdat = file.readAll();
if (m_prDdat.size() <= 0)
{
file.close();
qDebug() << "file size error, size=" << m_prDdat.size();
m_prDdat.clear();
return -2;
}
file.close();
return 0;
}
int BWBmp::Unpress()
{
m_rbwDdat.clear();
QByteArray arrdat;
arrdat.clear();
QByteArray barr;
barr.clear();
QFileInfo file(m_fileName);
QString name = file.filePath().remove("."+file.suffix());
QFile bfile(name);
bfile.open(QFile::ReadOnly);
barr = bfile.readAll();
BitmapHead * pHead = (BitmapHead *)(barr.data());
int widthBytes = (int)((pHead->biWidth + 31) / 32) * 4;
m_rbwDdat.append((char*)pHead,sizeof(BitmapHead));
if (m_prDdat.isEmpty() == 1)
{
qDebug() << "pr dat empty";
return -1;
}
unsigned char sdat = 0;
int count0,count1,flag;
count0 = count1 = 0;
flag = -1;
int size = m_prDdat.size();
for(int i = 0; i < size; i++)
{
// if(i > 3250)
// {
// int a = 0;
// a = 1;
// }
count0 = count1 = 0;
flag = -1;
sdat = m_prDdat[i];
if((sdat & 0xC0) == 0xC0) // 连续0
{
count0 = sdat & 0x3f;
flag = 0;
}
else
{
if((sdat & 0x40) == 0x40) // 连续1
{
count1 = sdat & 0x3f;
flag = 1;
}
else if((sdat & 0x80) == 0x80) // 连续10个0
{
count0 = (sdat & 0x3f ) * 10;
flag = 0;
}
else // 原始数据
{
//每行扫描时最后一个像素为原始数据时原始数据个数
int pcount = 6;
int val = arrdat.size() % pHead->biWidth;
int cnt = pHead->biWidth - val;
int cnt1 = abs(pHead->biWidth - (widthBytes-1) * 8);
if(cnt >= cnt1)
{
pcount = 6;
}
else
{
if(cnt > 6)
{
pcount = 6;
}
else
{
pcount = cnt;
}
}
unsigned char sch = sdat & 0x3f; //够一个位图
unsigned char pmod = 0x01;
while (pcount != 0)
{
if((sch & pmod) != 0) // 为1
{
arrdat.append((char)0x01);
}
else // 为0
{
arrdat.append((char)0x00);
}
pcount--;
pmod *= 2;
}
continue;
}
}
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;
unsigned char abyte = 0;
unsigned int cnt = 0;
for(unsigned int n = 0; n < pHead->biHeight; n++)
{
for(int j = 0; j < widthBytes; j++)
{
abyte = 0;
for(int i = 0; i < 8; i++)
{
int idx = n*pHead->biWidth+j*8+i;
//qDebug()<<"idx"<<idx;
unsigned char ch = arrdat[idx] << i;
//qDebug()<<"ch"<<ch;
cnt = j*8 + i;
if(cnt < pHead->biWidth)
{
abyte |= ch;
}
else if(cnt == pHead->biWidth)
{
abyte = abyte << (8 - i);
}
else if(cnt >= ((pHead->biWidth/8)*8+8))
{
abyte = 0;
}
else
{
continue;
}
}
//if(abyte != 0)
{
//qDebug()<<num<<" "<<abyte;
}
m_rbwDdat.append(abyte);
num++;
}
}
return 0;
}
int BWBmp::SaveBiBmp(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_rbwDdat);
file.close();
return 0;
}
QByteArray BWBmp::getPrBmpDat()
{
return m_prDdat;
}