#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 idx, 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; } QByteArray tmppr; tmppr.clear(); 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 * pBitDatBeg = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset); const unsigned char * pTmpDat; if (dir == -1) { pBitDatBeg += widthBytes * (height -1); } const unsigned char * pBitDat = pBitDatBeg; 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++; //qDebug()<> (8 - (width - k )); } for (mod = 0x80; (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; } if (pcount == 0) // 够一个位图 { tgtdat &= 0x3f; tmppr.append(tgtdat); // 添加 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); tmppr.append(tgtdat); // 添加 //qDebug()<= 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); tmppr.append(tgtdat); // 添加 //qDebug()<biHeight; prHead.biWidth = pHead->biWidth; if (dir < 0) { prHead.compDir = 1; } else { prHead.compDir = 0; } unsigned int prsize = tmppr.size(); if (prsize >= pHead->biBitmapDatSize) // 压缩率不足 { prHead.compType = 0; // 不压缩 prHead.datSize = pHead->biBitmapDatSize; tmppr.clear(); pBitDat = pBitDatBeg; for (i = 0; i < height; i++) // 行计数 { tmppr.append((const char*)pBitDat, widthBytes); pBitDat += widthBytes * dir; } } else { prHead.compType = 1; prHead.datSize = prsize; } m_prDdat.append((char*)(&prHead), sizeof(CompBmpHead)); m_prDdat.append(tmppr); 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(); int size = m_prDdat.size(); if (size < (int)sizeof(CompBmpHead)) { qDebug() << "pr dat empty"; return -1; } CompBmpHead * pPrHead = (CompBmpHead *)(m_prDdat.data()); const unsigned char * pPrDdat = (unsigned char *)(m_prDdat.data() + sizeof(CompBmpHead)); size -= sizeof(CompBmpHead); unsigned int biWidth = pPrHead->biWidth; unsigned int biHeight = pPrHead->biHeight; int widthBytes = (int)((biWidth + 31) / 32) * 4; BitmapHead bmpHead; memset(&bmpHead, 0, sizeof(BitmapHead)); bmpHead.identifier = 0x4d42; // BM bmpHead.bitDatOffset = 0x3E; bmpHead.biSize = 0x28; bmpHead.biPlanes = 1; bmpHead.biBitPerPixel = 1; bmpHead.biCompression = 0; bmpHead.biHResolution = 3780; // 水平分辨率, 像素/米 bmpHead.biVResolution = 3780; // 垂直分辨率, 像素/米 bmpHead.biColors = 2; // 颜色数 bmpHead.biImpColors = 2; // 重要颜色数 bmpHead.palette[0].color = 0x00ffffff; bmpHead.palette[1].color = 0x00000000; bmpHead.biWidth = biWidth; // 位图宽度,以像素为单位 bmpHead.biHeight = biHeight; // 位图高度,以像素为单位 bmpHead.biBitmapDatSize = widthBytes*biHeight; // 位图数据区的大小(字节数), 必须是4的整数倍 bmpHead.fileSize = bmpHead.bitDatOffset + bmpHead.biBitmapDatSize; #define VAL_OUTBMP 0xff // 位图之外的默认数据 m_rbwDdat.append((char*)(&bmpHead), sizeof(BitmapHead)); 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; sdat = pPrDdat[i]; if((sdat & 0xC0) == 0xC0) // 连续0 { count0 = sdat & 0x3f; if (count0 == 0) { count0 = 64; } flag = 0; } else { if((sdat & 0x40) == 0x40) // 连续1 { count1 = sdat & 0x3f; if (count1 == 0) { count1 = 64; } flag = 1; } else if((sdat & 0x80) == 0x80) // 连续10个0 { count0 = (sdat & 0x3f ) * 10; if (count0 == 0) { count0 = 640; } 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) { 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 int lst = ((biWidth/8)*8+8); for(unsigned int n = 0; n < biHeight; n++) { for(int j = 0; j < widthBytes; j++) { unsigned int cnt = j*8; unsigned char abyte = 0; int idx = n*biWidth+j*8; for(int i = 0; i < 8; i++, idx++, cnt++) { //qDebug()<<"idx"<= lst) { abyte = VAL_OUTBMP; // 默认值 break; } else { abyte |= ((VAL_OUTBMP) >> (i)); // 默认值 break; } } //if(abyte != 0) { //qDebug()<