#include "datafiledst.h" DataFileDst::DataFileDst() { m_colorNum = 0;//颜色数 m_pColor = NULL;//颜色rgb值 } DataFileDst::~DataFileDst() { } void DataFileDst::initColor(int cnum, QRgb *pColor) { m_colorNum = cnum;//颜色数 m_pColor = pColor;//颜色rgb值 qDebug()<<"m_colorNum"<itemNums; } int DataFileDst::getColorNums() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->colorNumber; } //测试fileid用,目前这个函数没用到 int DataFileDst::getFileid() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->fileid; } int DataFileDst::getDatWidth() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return (pDstHead->maxX - pDstHead->minX); } int DataFileDst::getDatHeight() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return (pDstHead->maxY - pDstHead->minY); } int DataFileDst::getMaxX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->maxX; } int DataFileDst::getMinX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->minX; } int DataFileDst::getMaxY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->maxY; } int DataFileDst::getMinY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); return pDstHead->minY; } int DataFileDst::getAnchorX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); int x = pDstHead->anchorX; return x; } int DataFileDst::getAnchorY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); int y = pDstHead->anchorY; return y; } int DataFileDst::getBeginX() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); int x = pDstHead->beginX; return x; } int DataFileDst::getBeginY() { if(m_embAbsData.size() <= 0) { return 0; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); int y = pDstHead->beginY; return y; } int DataFileDst::getBeginXYAndAnchorXY(QString path, int &beginX, int &beginY, int &anchorX, int &anchorY) { QFileInfo file(path); if (!file.exists() || !file.isFile()) { return -1; } QFile rdfile(path); if(!rdfile.open(QIODevice::ReadOnly)) { return -1; } QByteArray fileData = rdfile.readAll(); rdfile.close(); int size = fileData.size(); if (size <= (int)(sizeof(DstHead))) { return -1; } DstHead * pDstHead = (DstHead *)((fileData.data())); beginX = pDstHead->startX; beginY = pDstHead->startY; anchorX = pDstHead->anchorX; anchorY = pDstHead->anchorY; return 0; } void DataFileDst::getSwitchTable(u8 *table) { if(m_embAbsData.size() <= 0) { return; } DataDs16FileHead * pDstHead = (DataDs16FileHead *)((m_embAbsData.data())); memcpy(table,pDstHead->switchTable,sizeof(pDstHead->switchTable)); } // 检查并设置默认换色表 int DataFileDst::checkDefaultSwitchTable(int colornum) { //loadFile(); // 如果数据未读取,重新读取 int size = m_fileData.size(); if (size <= (int)(sizeof(DstHead))) { qDebug("dst size less then headsize"); return -1; } size -= sizeof(DstHead); int stepsize = size/sizeof(DstStep); if (stepsize <= 0) { qDebug("dst data size err"); return -1; } DstHead * pDstHead = (DstHead *)((m_fileData.data())); int i; if (colornum < 1) { colornum = 1; } if (colornum > BF_SW_ND) { colornum = BF_SW_ND; } for (i = 0; i < colornum; i++) { if (pDstHead->switchTable[i] != 0x20) { break; } } if (i < colornum) // 不全部是0x20, 可能设置过色序 { for (i = 0; i < colornum; i++) { if (pDstHead->switchTable[i] != 0x00) { break; } } } if (i >= colornum && colornum > 1) // 全部是0x20 或 全部是0, 未设置过色序 { for (i = 0; i < colornum; i++) { pDstHead->switchTable[i] = i; // 默认色序 } saveFile(); // 保存文件 } return 0; } // 转换为绝对坐标数据,同时得到最大最小值 void DataFileDst::convertDataToAbs() { QByteArray ds4Data;//相对坐标 m_embAbsData.clear(); loadFile(); // 如果数据未读取,重新读取 int size = m_fileData.size(); if (size <= (int)(sizeof(DstHead))) { qDebug("dst size less then headsize"); return; } // int dstHeadSize = sizeof(DstHead); // qDebug()<<"dstHeadSize"<= 0) { if(ctrl == DATA_JUMP) { jumpNeedleNum++; } if (ctrl == DATA_CHGND) // 换色 { colornum++; } memcpy(&(pData[stepidx]), &ds4Item, sizeof(Ds4Item)); stepidx++; } dstDataPtr++; i++; } else { break; } }while(1); //qDebug()<<"Ds4Item end"; //再将相对坐标转换为绝对坐标---开始 ds4Data.append((char *)pData, stepidx*sizeof(Ds4Item));//相对坐标字节数组 u32 fileID = 0; fileID = calcCheckSum32((u8 *)(ds4Data.data()) , ds4Data.length()); // 原始数据累加校验和 QByteArray absItemAry; absItemAry.clear(); DsAbsItem absItem; memset(&absItem,0,sizeof(DsAbsItem)); u8 ctrlByte; u8 attrByte; int ddx, ddy; m_maxX = S32_MIN; m_maxY = S32_MIN; m_minY = S32_MAX; m_minX = S32_MAX; Ds4Item * pDs4Data = (Ds4Item *)(ds4Data.data()); Ds4Item * ds4DataPtr = pDs4Data; int begX = pDstHead->startX;//起始点 int begY = pDstHead->startY; int begR = 0; int anchorX = pDstHead->anchorX;//定位点 int anchorY = pDstHead->anchorY; s32 ax = 0;//起始点 s32 ay = 0; s32 ar = 0; Ds4Item * ds4DataTemp = (Ds4Item *)(ds4Data.data()); // ljs int ds4StepSize = ds4Data.size()/sizeof(Ds4Item); int runflag = 0; for (int i = 0; i < ds4StepSize; i++) { // 读入一个针步数据 ctrlByte = ds4DataPtr->ctrl; attrByte = ds4DataPtr->attr; ddx = ds4DataPtr->dx * DATAFACTOR; ddy = ds4DataPtr->dy * DATAFACTOR; if ((attrByte & 0x80) != 0) { ddx *= -1; } if ((attrByte & 0x40) != 0) { ddy *= -1; } ddx *= DST_DATADIRX; ddy *= DST_DATADIRY; ax += ddx; ay += ddy; //ar = atan2(ddy,ddx) * 10000; double tar = atan2(ddy,ddx); ar = (tar * 10000+0.5*(tar>0?1:-1)); if(ctrlByte == DATA_JUMP) { if (runflag == 0) { runflag = 1; } runflag++; } else if(ctrlByte == DATA_EMB || ctrlByte == DATA_PUNCH || ctrlByte == DATA_SEWING)//第一针不转换为跳针 { if ((runflag == 0 || runflag > 3) && (i >= 0)) // 第一个运针是入针 { ds4DataPtr++; u8 ctl = ds4DataPtr->ctrl; if(ctl == DATA_EMB || ctl == DATA_PUNCH || ctl == DATA_SEWING)//下一针还为绣花针步时才转换为跳针 { ctrlByte = DATA_JUMP; } ds4DataPtr--; runflag = 1; } //else if (i == 0 && ddx == 0 && ddy == 0) // 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs else if (i == 0) // 20230511 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs { int count = 0; do { ds4DataTemp++; if (ds4DataTemp->ctrl == DATA_JUMP) { count++; if (ds4DataTemp->dx == 0 && ds4DataTemp->dy == 0) // 空跳,直接变成跳针 { count += 2; } } else { break; } }while(1); if (count >= 3) { ctrlByte = DATA_JUMP; runflag = 2; } else { runflag = 1; } } else { runflag = 1; } } else if (ctrlByte == DATA_CHGND) // 换色 { runflag = 10; } else { runflag = 0; } //第一针后面如果为大位移就将第二针下针转换为跳针 if(i == 0) { ds4DataPtr++; int cddx = ds4DataPtr->dx * DATAFACTOR; int cddy = ds4DataPtr->dy * DATAFACTOR; int len = sqrt(cddx*cddx+cddy*cddy); if(len >= 600)//6毫米为界限 { runflag = 3; } ds4DataPtr--; } //第一针空针转换为跳针,为了避免第一针锁针添加失败 if(i == 0 && ddx == 0 && ddy == 0) { ctrlByte = DATA_JUMP; } //中间数据 absItem.ctrl = ctrlByte; absItem.attr = attrByte & ~(0x80|0x40); absItem.ax = ax; absItem.ay = ay; absItem.ar = ar; if (ax > m_maxX) { m_maxX = ax; } if (ax < m_minX) { m_minX = ax; } if (ay > m_maxY) { m_maxY = ay; } if (ay < m_minY) { m_minY = ay; } absItemAry.append((char*)&absItem,sizeof(DsAbsItem)); ds4DataPtr++; } //int newstepnum = ds4StepSize; // 转换后的数据长度 int newstepnum = ds4StepSize; // 转换后的数据长度 ljs //qDebug()<<"DsAbsItem end"; //再将相对坐标转换为绝对坐标---结束 //qDebug()<<"dhead begin"; // 文件头转换 QString name = getFileFullName(); int namelen = name.size(); if (namelen > HEAD_NAME_STR_LEN) { namelen = HEAD_NAME_STR_LEN; } QByteArray array = name.toLocal8Bit().data(); memcpy(dhead.fileName, array, namelen); // 文件名称 dhead.dataSize = newstepnum*sizeof(DsAbsItem); // 数据字节数 dhead.itemNums = newstepnum; // 数据项个数 dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 dhead.bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小 dhead.dataChecksum = calcCheckSum32((u8 *)(absItemAry.data()) , dhead.dataSize); // 数据累加校验和 dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) dhead.fileid = fileID; //qDebug()<<"dhead 1"; dhead.anchorX = anchorX; // 定位点坐标X dhead.anchorY = anchorY; // 定位点坐标Y dhead.beginX = begX; // 数据起点坐标X dhead.beginY = begY; // 数据起点坐标Y, dhead.beginR = begR; // 数据起点坐标R, dhead.minX = m_minX; dhead.maxX = m_maxX; dhead.minY = m_minY; dhead.maxY = m_maxY; // 轮廓范围,使用重新计算之后的值 dhead.colorNumber = colornum; // 颜色数 //dhead.jumpNeedleNum = jumpNeedleNum;// 跳针数 dhead.offsetX = pDstHead->offsetX; dhead.offsetY = pDstHead->offsetY; //dst的花版 //dhead.patternType = 1; //qDebug()<<"m_maxX"<switchTable, BF_SW_ND); //qDebug()<<"dhead 3"; // 保存文件头到数组中 m_embAbsData.append((char *)(&dhead), sizeof(DataDs16FileHead)); //qDebug()<<"dhead 4"; // 保存数据到数组中 //qDebug()<<"newstepnum"<startX = x; pDstHead->startY = y; } else { pDstHead->anchorX = x; pDstHead->anchorY = y; } QFile wfile(m_fileFullPathName); if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } wfile.write(m_fileData); wfile.close(); } //将fcg里的 偏移点XY写在dst头文件里 void DataFileDst::writeOffsetXYMoveToFile(s32 offsetX,s32 offsetY) { if(m_fileData.size() <= 0) { return; } DstHead * pDstHead = (DstHead *)((m_fileData.data())); pDstHead->offsetX = offsetX; pDstHead->offsetY = offsetY; QFile wfile(m_fileFullPathName); if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qDebug() << "open file fail when read, path =" << m_fileFullPathName; return; } wfile.write(m_fileData); #ifdef Q_OS_LINUX system("sync"); #endif wfile.close(); } int DataFileDst::checkDstFile() { loadFile(); // 如果数据未读取,重新读取 int size = m_fileData.size(); if (size <= (int)(sizeof(DstHead))) { qDebug("dsr size less then headsize"); return -1; } size -= sizeof(DstHead); int stepsize = size/sizeof(DstStep); if (stepsize <= 0) { qDebug("dst data size err"); return -1; } if (stepsize > PATTERN_LARGE_NEEDLES)//128万针 { qDebug("dsr data size big"); return -2; } return stepsize; } //----------------------------------------------------------------------- // 生成预览文件 int DataFileDst::createPreviewImage(QImage * pImg, int saveflag, int penwidth, int reDraw) { #if(1) if(reDraw == 0)//图片存在则不重画 { // 图片是否存在,存在则返回 QString previewPath = getFileFullPathName() + ".preview.png"; QFile imageFile(previewPath); if (imageFile.exists()) { return 0; } } #endif int newimgflag = 0; QImage * pImage; int width, height; if (pImg == NULL) { width = DST_PREVIEW_WIDTH; height = DST_PREVIEW_HEIGHT; pImage = new QImage(width, height, IMAGE_TYPE); newimgflag = 1; } else { pImage = pImg; } width = pImage->width(); height = pImage->height(); if (width <= DST_PREVIEW_SIDE*2 || height <= DST_PREVIEW_SIDE*2) { if (pImage != NULL && newimgflag == 1) { delete pImage; } qDebug("preview img too small"); return -1; } memset(pImage->bits(), 0x00, pImage->byteCount()); QPainter painter(pImage); QColor backcolor(255, 255, 255, 0); // 透明背景 // 背景 QPen pen; pen.setWidth(penwidth); pen.setColor(backcolor); painter.setPen(pen); painter.setBrush(backcolor); painter.drawRect(0, 0, width, height); QColor color = QColor(Qt::blue); pen.setColor(color); painter.setPen(pen); // 图形 //qDebug()<<"convertDataToAbs defore"; convertDataToAbs(); // 转换为绝对坐标数据 //qDebug()<<"convertDataToAbs end"; // absdat数据 int size = m_embAbsData.size(); if (size <= (int)sizeof(DataDs16FileHead)) { qDebug("2 data less then head size"); return -1; } DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_embAbsData.data()); int datasize = size - sizeof(DataDs16FileHead); if (datasize <= 0) { qDebug("absdat dataBegin err"); return -1; } int stepsize = datasize/sizeof(DsAbsItem); if (stepsize <= 0) { qDebug("absdat data size err"); return -1; } DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)); DsAbsItem * absDataPtr = pData; //-------- // 图形显示区域 int dpminx = DST_PREVIEW_SIDE; int dpmaxx = width - DST_PREVIEW_SIDE; int dpminy = DST_PREVIEW_SIDE; int dpmaxy = height - DST_PREVIEW_SIDE; // 计算缩放系数 double factor, temp; if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) { return -1; } factor = (double)(fabs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 temp = (double)(fabs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按x计算的缩放系数 if (temp >= factor) // 使用较大的缩放系数 { factor = temp; } // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); // 显示花样图形 u8 ctrlByte; int dx; int dy; int colorIdx; int oldcolor; colorIdx = 0; oldcolor = -1; double datposx, datposy; int curx, cury, prex, prey; datposx = pAbsHead->beginX; datposy = pAbsHead->beginY; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (DST_SHOWDIRX == -1) { curx = (width)-curx; } if (DST_SHOWDIRY == -1) { cury = (height)-cury; } absDataPtr = pData; for (int i = 0; i < stepsize; i++) { // 读入一个针步数据 ctrlByte = absDataPtr->ctrl; if ( ctrlByte == DATA_EMB || ctrlByte == DATA_SEWING || ctrlByte == DATA_PUNCH || 0 ) { prex = curx; prey = cury; dx = absDataPtr->ax; dy = absDataPtr->ay; datposx = dx; datposy = dy; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (DST_SHOWDIRX == -1) { curx = (width)-curx; } if (DST_SHOWDIRY == -1) { cury = (height)-cury; } if (oldcolor != colorIdx) { int cidx = pAbsHead->switchTable[colorIdx % BF_SW_ND]; int cnum = m_colorNum; cnum /= sizeof(QRgb); if (cnum > BF_SW_ND) { cnum = BF_SW_ND; } QColor embcolor; if (cnum != 0) { cidx %= cnum; QRgb * pColor = m_pColor; if(pColor != NULL) { embcolor.setRgb(pColor[cidx]); } else { embcolor = QColor(Qt::green); } } else { embcolor = QColor(Qt::green); } pen.setColor(embcolor); painter.setPen(pen); oldcolor = colorIdx; } if(i != 0) { painter.drawLine(prex, prey, curx, cury); } } //如果连续两步都是跳针,则过滤掉 else if (ctrlByte == DATA_JUMP) { DsAbsItem * JumpAbsDataPtr = pData; JumpAbsDataPtr = absDataPtr - 1; u8 beforectrlByte = JumpAbsDataPtr->ctrl; JumpAbsDataPtr = absDataPtr + 2; u8 nextctrlByte = JumpAbsDataPtr->ctrl; prex = curx; prey = cury; dx = absDataPtr->ax; dy = absDataPtr->ay; datposx = dx; datposy = dy; curx = (datposx) / factor + dpx; cury = (datposy) / factor + dpy; if (DST_SHOWDIRX == -1) { curx = (width)-curx; } if (DST_SHOWDIRY == -1) { cury = (height)-cury; } if (oldcolor != colorIdx) { int cidx = pAbsHead->switchTable[colorIdx % BF_SW_ND]; int cnum = m_colorNum; cnum /= sizeof(QRgb); if (cnum > BF_SW_ND) { cnum = BF_SW_ND; } QColor embcolor; if (cnum != 0) { cidx %= cnum; QRgb * pColor = m_pColor; if(pColor != NULL) { embcolor.setRgb(pColor[cidx]); } else { embcolor = QColor(Qt::green); } } else { embcolor = QColor(Qt::green); } pen.setColor(embcolor); painter.setPen(pen); oldcolor = colorIdx; } if(beforectrlByte == DATA_JUMP || nextctrlByte == DATA_JUMP) { //该针上下两针都是跳针则不画线 } else { if(i != 0) { painter.drawLine(prex, prey, curx, cury); } } } //// absDataPtr++; } // 保存成文件 QString preview = getFileFullPathName(); if (saveflag != 0 && preview.isEmpty() == false) { #if (1) preview += ".preview.png"; pImage->save(preview, "png"); #endif } if (pImage != NULL && newimgflag == 1) { delete pImage; } return 0; } #define DST_DAT_DIRX (-1) // X向DST数据坐标和绝对数据坐标的差异 #define DST_DAT_DIRY (1) // Y向DST数据坐标和绝对数据坐标的差异 // 针步转换 int DataFileDst::changeDstStep(DstStep * pDststep, Ds4Item & ds4step) { int dx, dy; u8 c1, c2, c3; u8 ctrl, attr; if (pDststep == NULL) { return -1; } c1 = pDststep->c1; c2 = pDststep->c2; c3 = pDststep->c3; dx = 0; dy = 0; if ((c1&0x08) != 0) { dx -= 9; } if ((c1&0x04) != 0) { dx += 9; } if ((c1&0x02) != 0) { dx -= 1; } if ((c1&0x01) != 0) { dx += 1; } if ((c2&0x08) != 0) { dx -= 27; } if ((c2&0x04) != 0) { dx += 27; } if ((c2&0x02) != 0) { dx -= 3; } if ((c2&0x01) != 0) { dx += 3; } if ((c3&0x08) != 0) { dx -= 81; } if ((c3&0x04) != 0) { dx += 81; } if ((c1&0x10) != 0) { dy -= 9; } if ((c1&0x20) != 0) { dy += 9; } if ((c1&0x40) != 0) { dy -= 1; } if ((c1&0x80) != 0) { dy += 1; } if ((c2&0x10) != 0) { dy -= 27; } if ((c2&0x20) != 0) { dy += 27; } if ((c2&0x40) != 0) { dy -= 3; } if ((c2&0x80) != 0) { dy += 3; } if ((c3&0x10) != 0) { dy -= 81; } if ((c3&0x20) != 0) { dy += 81; } if (c3 == 0xF3 && dx == 0 && dy == 0) { ctrl = DATA_END; // 结束 } else if ((c3&0xc3) == 0x03) // 运针 { ctrl = DATA_PUNCH; } else if ((c3&0xc3) == 0x83) // 跳针 { ctrl = DATA_JUMP; } else if ((c3&0xc3) == 0xC3) // 换色 { ctrl = DATA_CHGND; } else if ((c3&0xc3) == 0x43) // 开关亮片码 { qDebug("Sequin switch, not support, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST return -2; } else { qDebug("not know dst step, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST return -3; } // 添加针步 attr = 0; dx *= DST_DAT_DIRX; // X向显示坐标和数据坐标的差异 dy *= DST_DAT_DIRY; // Y向显示坐标和数据坐标的差异 if (dx < 0) { attr |= 0x80; } if (dy < 0) { attr |= 0x40; } ds4step.ctrl = ctrl; ds4step.attr = attr; ds4step.dx = abs(dx); ds4step.dy = abs(dy); return 0; }