www.pudn.com > pdf417.rar > StdDataObject.cpp
// StdDataObject.cpp: implementation of the CStdDataObject class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "pdf417.h" #include "StdDataObject.h" #include "Afx.h" #include "data.h" #include "MainFrm.h" #include#define ERRORLIMIT 10 //错误范围限制 #define EMPTYLIMIT 4 #define JUDGETIMES 10 //条码组合模式 #define TEXTMODE 1 //文本压缩模式 #define BYTEMODE 2 //字节压缩模式 #define NUMBERMODE 3 //数字压缩模式 //文本压缩子模式 #define ALPHA 1 //大写字母子模式 #define LOWERCASE 2 //小写字母子模式 #define MIXED 3 //混合子模式 #define PUNCTUATION 4 //标点子模式 //文本压缩子模式锁定/转移码 #define LL 2 //锁定为小定字母型子模式 #define PS 4 //转移为标点型子模式 #define ML 5 //锁定为混合型子模式 #define AL 6 //锁定为大写字母型子模式 #define PL 7 //锁定为标点型子模式 #define AS 8 //转移为大写字母型子模式 #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CStdDataObject::CStdDataObject() { } CStdDataObject::~CStdDataObject() { } //从一个BMP对象中得到数据,并化为标准格式后存入类的pArrayMemory中 //标准化格式为:一个字节存放一个像素点 void CStdDataObject::GetStdData(CBmpObject* pObj) { //设定图像高度,宽度,行长 dImageWidth = pObj->dImageWidth; dImageHeight = pObj->dImageHeight; //每行所需要的字节数目 dBytesPerLine = dImageWidth; //每个像素对应于一个字节 //为像素点阵申请内存空间 pArrayMemory = new UCHAR[dBytesPerLine*dImageHeight]; //矩阵内存空间初始化为0 ::memset(pArrayMemory,0,dBytesPerLine*dImageHeight); //根据点像素来设置矩阵数据 for(UINT H=0;H < dImageHeight;H++) { for(UINT W=0;W < dImageWidth;W++) { if(pObj->IsBlack(W,H)) pArrayMemory[dBytesPerLine*H+W] = 1; } } } //判断像素点是否为黑色 inline BOOL CStdDataObject::StdIsBlack(UINT x, UINT y) { return pArrayMemory[dBytesPerLine*y+x]; } //转换像素点为白色 inline void CStdDataObject::Whitten(UINT x, UINT y) { pArrayMemory[dBytesPerLine*y+x] = 0; } //得到所有包括Cell的区域,并存入到类的RegionList中 void CStdDataObject::FindAllCell(Cell* pCell,CList & RegionList) { UINT dCIAWidth=0,dCIAHeight=0; UINT tmp1,i,W,H; BOOL bIsOk; Region tmp; //申请空间以保存原始数据 UCHAR* tmpbuffer=new UCHAR[dBytesPerLine*dImageHeight]; memcpy(tmpbuffer,pArrayMemory,dBytesPerLine*dImageHeight); //得到Cell数组的高度和宽度于dCIAWidth,dCIAHeight中 for(i=0;i CellItemCount;i++) { if((tmp1=pCell->CellArray[i].x)>dCIAWidth) dCIAWidth=tmp1; if((tmp1=pCell->CellArray[i].y)>dCIAHeight) dCIAHeight=tmp1; } dCIAWidth++; dCIAHeight++; for(H=0;H CellItemCount;i++) { if(!StdIsBlack(W+pCell->CellArray[i].x,H+pCell->CellArray[i].y)) { bIsOk=false; break; } } //如满足,则穷尽此区域,得到区域的上下左右各点坐标,并存入RegionList中 if(bIsOk) { tmp.Left.x = W; tmp.Left.y = H; tmp.Right.x = W; tmp.Right.y = H; tmp.Top.y = H; tmp.Top.x = W; tmp.Root.y = H; tmp.Root.x = W; mleft = mright = W; mroot = mtop = H; EmptyRegionInXY(W,H,&tmp); if(IsRect(tmp)) { if(RegionList.GetCount()==0) RegionList.AddHead(tmp); else RegionList.AddTail(tmp); } } } } //恢复原数据 memcpy(pArrayMemory,tmpbuffer,dBytesPerLine*dImageHeight); delete[] tmpbuffer; } //使用递归运算来穷尽整个区域,并返回区域的坐标值 void CStdDataObject::EmptyRegionInXY(UINT x, UINT y, Region* pRegion) { UINT xx,yy,sx,ex; BOOL flags; xx=x,yy=y; //处理点(x,y)左边的数据 do{ Whitten(xx,yy); }while(xx>=1 && StdIsBlack(--xx,yy)); sx=xx+1; //处理点(x,y)右边的数据 xx=x; while(xx+1 mright) mright=ex; if(yy mroot) mroot=yy; //判断是否为LEFT点 /* if(yy Left.y && abs(sx-pRegion->Left.x)<=2 && pRegion->Left.y-yy>=2) { pRegion->Left.x=sx; pRegion->Left.y=yy; } if(yy>pRegion->Left.y && sx<=pRegion->Left.x-2) { pRegion->Left.x=sx; pRegion->Left.y=yy; } if(yy==pRegion->Left.y) { pRegion->Left.x=sx; pRegion->Right.x=ex; } if(ex==pRegion->Left.x && yy Left.y) { pRegion->Left.x=sx; pRegion->Right.x=ex; } */ if(sx Left.x && (pRegion->Left.x-sx >=2 || pRegion->Left.x-sx>abs(yy-pRegion->Left.y))) { pRegion->Left.x=sx; pRegion->Left.y=yy; } if(abs(sx-mleft)<=1 && yy Left.y) { pRegion->Left.x=sx; pRegion->Left.y=yy; } //判断是否为TOP点 /* if(pRegion->Top.y>=yy+2) { pRegion->Top.y=yy; pRegion->Top.x=ex; } if(pRegion->Top.y>=yy && ex>=pRegion->Top.x) { pRegion->Top.y=yy; pRegion->Top.x=ex; } else if(yy Top.y && abs(pRegion->Top.x-ex)<=EMPTYLIMIT) { pRegion->Top.y=yy; pRegion->Top.x=ex; }; */ if(yy Top.y) { pRegion->Top.y=yy; pRegion->Top.x=ex; } if(abs(mtop-yy)<=1 && ex>pRegion->Top.x) { pRegion->Top.y=yy; pRegion->Top.x=ex; } //判断是否为RIGHT点 if(ex>pRegion->Right.x) { pRegion->Right.x=ex; pRegion->Right.y=yy; } if(yy> pRegion->Right.y && abs(ex-mright)<=1) { pRegion->Right.x=ex; pRegion->Right.y=yy; } //判断是否为ROOT点 if(yy>pRegion->Root.y) { pRegion->Root.y=y; pRegion->Root.x=sx; } if(abs(mroot-yy)<=1 && sx Root.x) { pRegion->Root.y=y; pRegion->Root.x=sx; } //处理上一行 if(y>0) { for(xx=sx;xx<=ex;xx++) { if(StdIsBlack(xx,yy-1)) { EmptyRegionInXY(xx,yy-1,pRegion); flags=false; } } } //处理下一行 if(y+1 ERRORLIMIT) return false; if(abs((int)(r.Left.y-r.Top.y-r.Root.y+r.Right.y))>ERRORLIMIT) return false; //判断两对角线是否相等 double tmp1=sqrt((r.Top.x-r.Left.x)*(r.Top.x-r.Left.x)+ (r.Root.y-r.Top.y)*(r.Root.y-r.Top.y)); double tmp2=sqrt((r.Right.x-r.Left.x)*(r.Right.x-r.Left.x)+ (r.Right.y-r.Left.y)*(r.Right.y-r.Left.y)); // if(abs(tmp1-tmp2)> tmp1>1000?10*ERRORLIMIT:ERRORLIMIT) // return false; return true; } BOOL CStdDataObject::IsBarHeader(Region* pReg) { Region tmpreg,reg; UCHAR HeaderShape[]={8,1,1,1,1,1,1,3}; //此变量进行两个方向的判断 BOOL firstjudge=true; UPOINT* PointArray; UCHAR BWArray[1000]; //把原矩形化为可供判断的标准矩形 reg = *pReg; tmpreg = reg; if((reg.Top.x-reg.Left.x)*(reg.Top.x-reg.Left.x)+(reg.Left.y-reg.Top.y)*(reg.Left.y-reg.Top.y) > (reg.Right.x-reg.Top.x)*(reg.Right.x-reg.Top.x)+(reg.Right.y-reg.Top.y)*(reg.Right.y-reg.Top.y)) { tmpreg.Left=reg.Top; tmpreg.Root=reg.Left; tmpreg.Top=reg.Right; tmpreg.Right=reg.Root; } loop: if(!firstjudge) { //进行第二次判断时,改变方向 Region tmpreg1 = tmpreg; tmpreg.Top = tmpreg1.Root; tmpreg.Left = tmpreg1.Right; tmpreg.Right = tmpreg1.Left; tmpreg.Root = tmpreg1.Top; } //计算点的总数 int _height = (int)(sqrt((tmpreg.Left.x-tmpreg.Root.x)*(tmpreg.Left.x-tmpreg.Root.x)+ (tmpreg.Left.y-tmpreg.Root.y)*(tmpreg.Left.y-tmpreg.Root.y))+1.5); //申请一空间以存入纵向的点(起始点) PointArray = new UPOINT[_height]; int rheight = GetLineDataA(tmpreg.Left.x,tmpreg.Left.y,tmpreg.Root.x,tmpreg.Root.y,PointArray); //确定dx,dy值 int tx=tmpreg.Top.x,ty=tmpreg.Top.y,lx=tmpreg.Left.x,ly=tmpreg.Left.y,z; z=(tx>lx)?1:-1; int dx=(int)((tx==lx)?0:(18*(tx-lx+z)/7+0.5)); z=(ty>ly)?1:-1; int dy=(int)((ty==ly)?0:(18*(ty-ly+z)/7+0.5)); //申请空间以存放横向的点(一行数据),宽度为_width int _width = (int)(sqrt(dx*dx+dy*dy)+1.5); if(_width>1000) //如一条模宽度大于1000,则认为数据出错 { delete PointArray; return false; } int dj=(int)(rheight/JUDGETIMES+0.5); if(dj<1) dj=1; for(int i=rheight/(2*JUDGETIMES),rightnum=0;i dImageWidth-1) tx=dImageWidth-1; if(ty<0) ty=0; if(ty>dImageHeight-1) ty=dImageHeight-1; int rwidth=GetLineDataB(PointArray[i].x,PointArray[i].y,tx,ty,BWArray); //得到起始符位置 for(int k=0;k 8) break; //得出一个模块宽 double onewidth = (double)(BWArray[k]+1)/8; rwidth=(rwidth>8?8:rwidth); for(int j=k;j =1) break; } if(j==rwidth&&rwidth>=8) rightnum++; //如果满足要求,则加一 if(rightnum > JUDGETIMES/2) break; } delete[] PointArray; if(rightnum > JUDGETIMES/2) //如果正确的数据超过总判断数的1/2,则认为正确 { *pReg = tmpreg; return true; } else if(firstjudge) { firstjudge = false; goto loop; } else return false; } //BWArray以BWBWBWBW的序列存放,如第一点不为B,则存入0 //所返回的数组中的每一元素均代表B/W的数目 UINT CStdDataObject::GetLineDataB(UINT xa, UINT ya, UINT xb, UINT yb, UCHAR* BWArray) { int num=0; int dx=abs(xa-xb),dy=abs(ya-yb); int p=2*dy-dx; int pp=2*dx-dy; //++ int twody=2*dy,twody_dx=2*(dy-dx); int twodx=2*dx,twodx_dy=2*(dx-dy); //++ int x,y,xend,yend; int count=0,flags='B',ArrNum=0; //ArrNum指示当前数组中所用元素的位置 //count指示当前计数的B/W的数目 //flags指示当前对什么进行计数B/W x=xa;y=ya; xend=xb;yend=yb; if(StdIsBlack(x,y)) count++; else { flags='W'; BWArray[ArrNum++]=count; count=1; } num++; if(dy>dx) { while(y>yend?y>yend:y yend) y--; else y++; if(pp<0) pp+=twodx; else{ if(xb>xa) x++; else x--; pp+=twodx_dy; } if(StdIsBlack(x,y)) { if(flags=='B') count++; //如果当前标志为B,则继续计数 else{ flags='B'; //否则改变标志,并把数据存入; BWArray[ArrNum++]=count; count=1; } } else { if(flags=='W')count++; else{ flags='W'; BWArray[ArrNum++]=count; count=1; } } num++; } } else { while(x>xend?x>xend:x xend) x--; else x++; if(p<0) p+=twody; else{ if(yb>ya) y++; else y--; p+=twody_dx; } if(StdIsBlack(x,y)) { if(flags=='B') count++; //如果当前标志为B,则继续计数 else{ flags='B'; //否则改变标志,并把数据存入; BWArray[ArrNum++]=count; count=1; } } else { if(flags=='W')count++; else{ flags='W'; BWArray[ArrNum++]=count; count=1; } } num++; } } BWArray[ArrNum]=count; BWArray[ArrNum+1]='\0'; return ArrNum+1; } BOOL CStdDataObject::IsBarTail(Region* pReg) { Region tmpreg,reg; UCHAR TailShape[]={7,1,1,3,1,1,1,2,1}; //此变量进行两个方向的判断 BOOL firstjudge=true; UPOINT* PointArray; UCHAR BWArray[1000]; //把原矩形化为可供判断的标准矩形 reg = *pReg; tmpreg = reg; if((reg.Top.x-reg.Left.x)*(reg.Top.x-reg.Left.x)+(reg.Left.y-reg.Top.y)*(reg.Left.y-reg.Top.y) > (reg.Right.x-reg.Top.x)*(reg.Right.x-reg.Top.x)+(reg.Right.y-reg.Top.y)*(reg.Right.y-reg.Top.y)) { tmpreg.Left=reg.Top; tmpreg.Root=reg.Left; tmpreg.Top=reg.Right; tmpreg.Right=reg.Root; } loop: if(!firstjudge) { //进行第二次判断时,改变方向 Region tmpreg1 = tmpreg; tmpreg.Top = tmpreg1.Root; tmpreg.Left = tmpreg1.Right; tmpreg.Right = tmpreg1.Left; tmpreg.Root = tmpreg1.Top; } //计算点的总数 int _height = (int)(sqrt((tmpreg.Left.x-tmpreg.Root.x)*(tmpreg.Left.x-tmpreg.Root.x)+ (tmpreg.Left.y-tmpreg.Root.y)*(tmpreg.Left.y-tmpreg.Root.y))+1.5); //申请一空间以存入纵向的点(起始点) PointArray = new UPOINT[_height]; int rheight = GetLineDataA(tmpreg.Left.x,tmpreg.Left.y,tmpreg.Root.x,tmpreg.Root.y,PointArray); //确定dx,dy值 int tx=tmpreg.Top.x,ty=tmpreg.Top.y,lx=tmpreg.Left.x,ly=tmpreg.Left.y,z; z=(tx>lx)?1:-1; int dx=(int)((tx==lx)?0:(19*(tx-lx+z)/7+0.5)); z=(ty>ly)?1:-1; int dy=(int)((ty==ly)?0:(19*(ty-ly+z)/7+0.5)); //申请空间以存放横向的点(一行数据),宽度为_width int _width = (int)(sqrt(dx*dx+dy*dy)+1.5); if(_width>1000) //如一条模宽度大于1000,则认为数据出错 { delete PointArray; return false; } int dj=(int)(rheight/JUDGETIMES+0.5); if(dj<1) dj=1; for(int i=rheight/(2*JUDGETIMES),rightnum=0;i dImageWidth-1) tx=dImageWidth-1; if(ty<0) ty=0; if(ty>dImageHeight-1) ty=dImageHeight-1; int rwidth=GetLineDataB(PointArray[i].x,PointArray[i].y,tx,ty,BWArray); //得到起始符位置 for(int k=0;k 8) break; //得出一个模块宽 double onewidth = (double)(BWArray[k]+1)/8; rwidth=(rwidth>9?9:rwidth); for(int j=k;j =1) break; } if(j==rwidth&&rwidth>=9) rightnum++; //如果满足要求,则加一 if(rightnum > JUDGETIMES/2) break; } delete[] PointArray; if(rightnum > JUDGETIMES/2) //如果正确的数据超过总判断数的1/2,则认为正确 { *pReg = tmpreg; return true; } else if(firstjudge) { firstjudge = false; goto loop; } else return false; } //把从点(xa,ya)到点(xb,yb)的直线段上所有的点均存入数组,并返回点的数目 UINT CStdDataObject::GetLineDataA(UINT xa, UINT ya, UINT xb, UINT yb, UPOINT* PointArray) { int num=0; int dx=abs(xa-xb),dy=abs(ya-yb); int p=2*dy-dx; int pp=2*dx-dy; int twody=2*dy,twody_dx=2*(dy-dx); int twodx=2*dx,twodx_dy=2*(dx-dy); int x,y,xend,yend; x=xa;y=ya; xend=xb;yend=yb; PointArray[num].x=x; PointArray[num].y=y; num++; if(dy>dx) { while(y>yend?y>yend:y yend) y--; else y++; if(pp<0) pp+=twodx; else{ if(xb>xa) x++; else x--; pp+=twodx_dy; } PointArray[num].x=x; PointArray[num].y=y; num++; } } else { while(x>xend?x>xend:x xend) x--; else x++; if(p<0) p+=twody; else{ if(yb>ya) y++; else y--; p+=twody_dx; } PointArray[num].x=x; PointArray[num].y=y; num++; } } return num-1; } //执行数据分析操作 //1.定义Cell,调用FindAllCell来找出所有匹配的区域,存入类成员RegionList; //2.根据找出的每一个区域,进行判断 BOOL CStdDataObject::Act() { //定义Cell(8*8矩阵) Cell m_cell; CellItem CellItems[] = {{0,0},{1,0},{2,0},{3,0},{4,0},{5,0},{6,0},{7,0}, {0,7},{1,7},{2,7},{3,7},{4,7},{5,7},{6,7},{7,7}, {0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7}, {7,1},{7,2},{7,3},{7,4},{7,5},{7,6},{7,7}}; m_cell.CellArray=CellItems; m_cell.CellItemCount=30; //调用成员函数来找出所有包含m_cell的区域于RegionList中 CList RegionList; FindAllCell(&m_cell,RegionList); //判断是否有数据,如无则退出 if(RegionList.IsEmpty()) return false; //遍历对列,找出条码起始,结束符,并删除无用数据顶 POSITION tmppos,pos; Region tmpreg,reg; //用于临时存储变量 pos = RegionList.GetHeadPosition(); //得到对列头 do { reg = RegionList.GetAt(pos); tmppos = pos; //保存对列指针 RegionList.GetNext(tmppos); //保存下一数据POSITION if(IsBarHeader(®)) //判断是否为条码起始符 { RegionList.GetAt(pos) = reg; RegionList.GetAt(pos).RegionType='H'; //区域类型为HEADER } else if(IsBarTail(®)) //判断是否为条码结束符 { RegionList.GetAt(pos) = reg; RegionList.GetAt(pos).RegionType='T'; //区域类型为TAIL } else RegionList.RemoveAt(pos); //无效数据则删除 pos = tmppos; }while(pos!=NULL); //判断对列中是否有数据,如无则退出 if(RegionList.IsEmpty()) return false; //再次遍历对列,找出相匹配的HEAD和TAIL,如匹配,则译出数据,并返回true BOOL bHaveOneBar=false; for(pos=RegionList.GetHeadPosition();pos!=NULL;RegionList.GetNext(pos)) { reg = RegionList.GetAt(pos); if(reg.RegionType == 'H') { for(tmppos=RegionList.GetHeadPosition();tmppos!=NULL;RegionList.GetNext(tmppos)) { tmpreg = RegionList.GetAt(tmppos); //查看两者是否匹配,如匹配,则返回数据于列表中 if(tmpreg.RegionType=='T'&&IsMatch(reg,tmpreg)) { //如果已匹配,则设置标志为'O' RegionList.GetAt(pos).RegionType = 'O'; RegionList.GetAt(tmppos).RegionType = 'O'; //得到一个数据后就返回true; bHaveOneBar=true; return true; //目前只处理一个图形数据 } } } } //删除数列 if(RegionList.GetCount() != 0) RegionList.RemoveAll(); return bHaveOneBar; } //根据两区域的Top,Left,Right,Root的坐标以及由两者的组合区域是否为一矩阵 //来查看两区域(条码起始符/条码结束符)是否匹配 BOOL CStdDataObject::IsMatch(Region reg1, Region reg2) { Region reg; int arraylen,tmp; //合并两矩形 reg.Left = reg1.Left; reg.Root = reg1.Root; reg.Top = reg2.Top; reg.Right = reg2.Right; //判断组合区域是否为一矩阵 if(IsRect(reg)) { CClientDC dc(((CMainFrame*)(AfxGetMainWnd()->GetActiveWindow()))->m_wndSplitter.GetPane(0,0)); dc.MoveTo(reg.Left.x,reg.Left.y); dc.LineTo(reg.Top.x,reg.Top.y); //计算纵向点的总数 int _height = (int)(sqrt((reg.Left.x-reg.Root.x)*(reg.Left.x-reg.Root.x)+ (reg.Left.y-reg.Root.y)*(reg.Left.y-reg.Root.y))+1.5); //得到每一行的起始点坐标,PointArray用于存放此点数组 UPOINT* PointArray = new UPOINT[_height]; int rheight = GetLineDataA(reg.Left.x,reg.Left.y,reg.Root.x,reg.Root.y,PointArray); //tx,ty为每一行的目标点坐标 //dx,dy为起始与目标点的坐标差 int tx=reg.Top.x,ty=reg.Top.y,lx=reg.Left.x,ly=reg.Left.y,z; z=(tx>lx)?1:-1; int dx=(tx==lx)?0:(tx-lx+z); z=(ty>ly)?1:-1; int dy=(ty==ly)?0:(ty-ly+z); int _width = (int)(sqrt(dx*dx+dy*dy)+1.5); //用于存放每一条/空的点数,经IsValidData判断后,存放每一条/空的模块数 UCHAR* BWArray = new UCHAR[_width]; //用于保存刚进行判断的数据,以防止存入两相同的行 UCHAR *tmpCurArray = new UCHAR[_width]; //对应条码的当前行 int CurrentRow=0; //对条码的每一行进行判断 for(int i=0,rightnum=0;i dImageWidth-1) tx=dImageWidth-1; if(ty<0) ty=0; if(ty>dImageHeight-1) ty=dImageHeight-1; int rwidth=GetLineDataB(PointArray[i].x,PointArray[i].y,tx,ty,BWArray); //判断是否为正确数据,如是,则对其转换 if(IsValidData(BWArray,rwidth,CurrentRow)) { i+=2; //比较两行数据是否相同 tmp = strcmp((char*)BWArray,(char*)tmpCurArray); if(tmp!=0) { if(BarDataList.GetCount() == 0) arraylen = strlen((char*)BWArray); if(arraylen == strlen((char*)BWArray)) { //如不同,则存入对象的BarDataList中 UCHAR* tmparray = new UCHAR[rwidth]; memcpy(tmparray,BWArray,rwidth); if(BarDataList.GetCount() == 0) { BarDataList.AddHead(tmparray); arraylen = strlen((char*)tmparray); } else BarDataList.AddTail(tmparray); memcpy(tmpCurArray,BWArray,rwidth); i+=2; CurrentRow++; } } } else memset(tmpCurArray,0,_width); } delete[] PointArray; delete[] BWArray; delete[] tmpCurArray; } //根据列表是否为空,返回true/false if(BarDataList.IsEmpty()) return false; else return true; } //判断数据是否有效 //入口: //pStr---指向条/空信息串,每一个数据表示对应的条/空为多少点数 //len ---信息串长度 //返回: // true:表示数据正确,pStr中的数据改为条/空的模块数(已不含条码起始和结束符) // false:数据不符合 BOOL CStdDataObject::IsValidData(UCHAR *pStr, UINT len,int CurrentRow) { UINT j,ii; UCHAR HeaderShape[]={8,1,1,1,1,1,1,3}; double onewidth,tmpsum,tmpsum1; if(len<8) return false; //找第一个大于8的数(头标志),如无,则返回false for(UINT i=0;i =8) break; //如果无数据,则返回false if(i==len) return false; ii=i; //申请一变量用于存放 UCHAR* tmpstr = new UCHAR[8]; while(ii+7 = 8) return false; //如果数据正确,则化为标准ASCII码 pStr[ii]='\0'; //ii=i+8:除去条码起始符 for(ii=i+8,j=0;pStr[ii]!='\0';ii++,j++) { pStr[j]=pStr[ii]; pStr[j]+=48; //化为ASCII码 } pStr[j]='\0'; return true; } //把条码的条空信息转换成条码的数据值,如“31231121”转换成其对的数据127等 //入口数据:类成员数据BarDataList; //返回: 类成员数据p417Data中; BOOL CStdDataObject::BarTo417Data() { POSITION pos= BarDataList.GetHeadPosition(); char* str = (char*)(BarDataList.GetNext(pos)); int w = strlen(str)/8,h=BarDataList.GetCount(),dCount=0; int i,tmp,hno=0; char tmpstr[10]; //为p417Data申请数据空间 p417Data = new UINT[w*h]; //得到条码矩阵的长度和宽度 this->Height = h; this->Width = w; //为每一个条空信息调用FindData来查找数据 pos= BarDataList.GetHeadPosition(); while(pos!=NULL) { str = (char*)(BarDataList.GetNext(pos)); hno++; for(i=0;i 10?no-10:0;i<=no+10 && i<928;i++) { if(pArray[i][0] == sum) return pArray[i][1]; } return 0; } BOOL CStdDataObject::D417ToEnd() { int w,h,dCount,dSourcePoint,dTargetPoint,tmpmode,tmpsum; UINT tmp,tmp1; int CurSubMode=AL,CurSubChgMode=0,CurMode=ALPHA,CurChgMode=0; //临时数据,用于存储去了左右标志字节的数据 //数据数目保存在dCount中 UINT* tmpdata = new UINT[Height*(Width-2)]; for(h=0,dCount=0;h Height*(Width-2)) tmpsum = Height*(Width-2); while(dSourcePoint < tmpsum) { tmp = tmpdata[dSourcePoint]; switch(tmp) { case 900: CurMode = TEXTMODE; CurSubMode=AL; CurSubChgMode=0; break; case 901: CurMode = BYTEMODE; break; case 924: CurMode = BYTEMODE; break; case 902: CurMode = NUMBERMODE; break; case 913: CurChgMode = BYTEMODE; break; default: tmpmode = CurMode; if(CurChgMode) {CurMode = CurChgMode; CurChgMode = 0;} if(CurMode == TEXTMODE) { tmp1 = TextModeTrans(tmp/30,&CurSubMode,&CurSubChgMode); if(tmp1) pEndData[dTargetPoint++] = tmp1; tmp1 = TextModeTrans(tmp%30,&CurSubMode,&CurSubChgMode); if(tmp1) pEndData[dTargetPoint++] = tmp1; } if(CurMode == BYTEMODE) { UCHAR targetdata[7]; int i=0,tmp; do{ tmp=tmpdata[dSourcePoint+i]; if(tmp>=900) break; i++; }while(i<5 && dSourcePoint+i 0) ByteModeTrans(&tmpdata[dSourcePoint],targetdata,i); dSourcePoint+=i-1; for(i=0;i =0;i--) pEndData[dTargetPoint++]=target[i]; } CurMode = tmpmode; } dSourcePoint++; } pEndData[dTargetPoint]='\0'; delete[] tmpdata; return true; } //字符模式下转换 //入口: // data---数据 // cursubmode---当前子模式 // cursubchgmode---当前转移子模式 int CStdDataObject::TextModeTrans(int data, int *cursubmode, int *cursubchgmode) { int tmpmode,retcode; UCHAR Alpha[]={' ',LL,ML,PS}; UCHAR LowerCase[]={' ',AS,ML,PS}; UCHAR Mixed[]={38,13,9,44,58,35,45,46,36,47,43,37,42,61,94,PL,32,LL,AL,PS}; UCHAR Punctuation[]={59,60,62,64,91,92,93,95,96,126,33,13,9,44,58,10,45,46,36,47,34,124,42,40,41,63,123,125,39,AL}; tmpmode = *cursubmode; if(*cursubchgmode == PS) { *cursubmode = PL; *cursubchgmode = 0; } if(*cursubchgmode == AS) { *cursubmode = AL; *cursubchgmode = 0; } switch(*cursubmode) { case AL: if(data>25) retcode=Alpha[data-26]; else retcode=65+data; break; case LL: if(data>25) retcode=LowerCase[data-26]; else retcode=97+data; break; case ML: if(data<=9) retcode=48+data; else retcode=Mixed[data-10]; break; case PL: retcode=Punctuation[data]; break; } if(retcode==LL || retcode==ML || retcode==AL || retcode==PL) { tmpmode = retcode; retcode = 0; } else if(retcode==PS || retcode==AS) { *cursubchgmode=retcode; retcode = 0; } *cursubmode = tmpmode; return retcode; } void CStdDataObject::NumberModeTrans(UINT *sourcedata, char *targetdata, int num) { int i,j,tmp,d,l; //把数据初始化为0 for(i=0;i<46;i++) targetdata[i]=0; for(i=0;i =2;j--) targetdata[j] = targetdata[j-2]; targetdata[0]=0; targetdata[1]=0; //数据*9 tmp=0; for(j=2;j<44;j++) { d=targetdata[j]*9+tmp; targetdata[j]=d%10; tmp=d/10; } } //加上最后一位数据 d=sourcedata[num-1]; j=0; tmp=0; while(d || tmp) { l=targetdata[j]+d%10+tmp; targetdata[j]=l%10; tmp=l/10; d/=10; j++; } //变成ASCII字符 tmp=0; for(j=45;j>=0;j--) { if(targetdata[j]) tmp=0x30; targetdata[j]+=tmp; } } void CStdDataObject::ByteModeTrans(UINT *sourcedata, UCHAR *targetdata,int len) { //位数不足五位 if(len!=5) { for(int i=0;i