#include "bwbmp.h" #include #include 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 | 连续10个数据0的个数 | -------------------------------------------------- | 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()<> (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()< 64) { nums = 64; } else { nums = count1; } psta = 0x40; tgtdat = psta; tgtdat |= (nums & 0x3f); m_prDdat.append(tgtdat); // 添加 //qDebug()<= 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()<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"<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()<