⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stddataobject.cpp

📁 对位图文件中的点阵数据进行模式判别,找出其中的完整PDF417条码,并按照GB/T 17172-1997规范来解释读出对应的数据.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	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<len;i++)
		if(pStr[i]>=8) break;

	//如果无数据,则返回false
	if(i==len) return false;

	ii=i;
	//申请一变量用于存放
	UCHAR* tmpstr = new UCHAR[8];
	while(ii+7<len)
	{
		//求出一个字符总的点阵数
		for(tmpsum=0,j=0;j<=7;j++)
			tmpsum+=pStr[ii+j];

		//根据总的点阵数,求出一个模块宽
		onewidth = tmpsum/17;

		//求出每一条/空的模块数
		for(j=0;j<=7;j++)
		{
			tmpstr[j]=(UCHAR)(pStr[ii+j]/onewidth+0.5);
			pStr[ii+j]=tmpstr[j];	//拷贝到pStr中
		}

		//求出一个数据的模块总数,如果不为17,则出错
		for(tmpsum1=0,j=0;j<=7;j++)
			tmpsum1+=tmpstr[j];
		if(tmpsum1 != 17) break;
		if(ii!=i && ((CurrentRow%3)*3 != (tmpstr[0]-tmpstr[2]+tmpstr[4]-tmpstr[6]+9)%9))
			break;
		if(ii==i)
		{
			for(j=0;j<=7;j++)
				if(tmpstr[j]!=HeaderShape[j]) break;
			if(j!=8)break;
		}
		ii+=8;
	}
	
	delete[] tmpstr;

	//如果数据出错,则返回false
	if(len-ii >= 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<w;i++)
		{
			memcpy(tmpstr,&str[i*8],8);
			tmpstr[8] = '\0';

			//查找数据,tmpstr为要找的串,((dCount/w)%3)*3为簇号
			//如找不到源串,则返回0
			//找不到串的唯一原因:各簇数据表输入时出错
			tmp = FindData(tmpstr,((dCount/w)%3)*3,c0,c3,c6);

			//如未能找到,则提示用户
			if(tmp == 0)
			{
				CString showerr;
				showerr.Format("在第%3d行,第%3d列,第%3d簇数据查找时,未能找到串 %s ",hno,w,((dCount/w)%3)*3,tmpstr);
				AfxMessageBox(showerr,MB_ICONSTOP);
			//	return false;
			}
			p417Data[dCount++] = tmp-1;
		}
	}
	return true;
}

int CStdDataObject::TransData(int code)
{
	int tmp = code%10;
	switch(code/10+tmp)
	{
	case 2: return 0;
	case 3: return tmp;
	case 4: return tmp+2;
	case 5: return tmp+5;
	case 6: return tmp+9;
	case 7: return tmp+14;
	case 8: return tmp+19;
	case 9: return tmp+23;
	default:return 0;
	}
}

//在三个数据簇表中找出C簇中STR对应的数据
//入口:
//	str:		要找的串,如“31123232”等
//	c:			指示在哪个簇中查找
//	c0,c3,c6:	各簇的数据指针
//返回:
//	所找到的对应数据值
//	如未找到,则返回0
int CStdDataObject::FindData(char *str,int c,UINT c0[][2],UINT c3[][2],UINT c6[][2])
{
	int i,j,l,m,tmp,no;
	UINT sum,(*pArray)[2];
	tmp = (str[1]-0x30)*10+str[2]-0x30;
	tmp = TransData(tmp);
	i = str[3]-0x31;
	j = str[4]-0x31;
	l = str[5]-0x31;
	m = str[6]-0x31;
	sum = tmp*1400+i*216+j*36+l*6+m;
	if(c==0) pArray = c0;
	if(c==3) pArray = c3;
	if(c==6) pArray = c6;
	no = 0;
	while(pArray[no][0]<sum && no<928-10) no+=10;
	for(i=no>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;h++)
		for(w=1;w<Width-1;w++)
			tmpdata[dCount++] = p417Data[h*Width+w];

	//设数据最多压缩3倍
	pEndData = new UCHAR[dCount*3];

	dSourcePoint = 1;
	dTargetPoint = 0;
	tmpsum = tmpdata[0];
	if(tmpsum>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<tmpsum);
					if(i>0)
						ByteModeTrans(&tmpdata[dSourcePoint],targetdata,i);
					dSourcePoint+=i-1;
					for(i=0;i<strlen((char*)targetdata);i++)
						pEndData[dTargetPoint++]=targetdata[i];
				}
				if(CurMode == NUMBERMODE)
				{
					int i=0,tmp;
					char target[46];
					do{
						tmp=tmpdata[dSourcePoint+i];
						i++;
					}while(tmp<900 && i<=15 && dSourcePoint+i<=tmpsum);
					NumberModeTrans(&tmpdata[dSourcePoint],target,i-1);
					dSourcePoint+=i-1;
					for(i=strlen(target)-1;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<num-1;i++)
	{
	//加上一位数据
	d=sourcedata[i];
	j=0;
	tmp=0;
	while(d || tmp)
	{
	l=targetdata[j]+d%10+tmp;
	targetdata[j]=l%10;
	tmp=l/10;
	d/=10;
	j++;
	}

	//移动两位
	for(j=45;j>=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<len;i++)
			targetdata[i] = sourcedata[i];
		targetdata[i] = '\0';
		return;
	}

	UINT e0=0,e1=0,e2=0;
	DWORD tmp,tmp1;
	tmp = (sourcedata[0]*900+sourcedata[1])*900+sourcedata[2];
	e0 = LOWORD(tmp);
	e1 = HIWORD(tmp);
	tmp = e0*900+sourcedata[3];
	e0 = tmp%(256*256);
	tmp1 = e1*900 + (tmp-e0)/(256*256);
	e1 = tmp1%(256*256);
	e2 = (tmp1 - e1)/(256*256);

	tmp = e0*900+sourcedata[4];
	e0 = tmp%(256*256);
	tmp1 = e1*900 + (tmp-e0)/(256*256);
	e1 = tmp1%(256*256);
	e2 = e2*900 + (tmp1 - e1)/(256*256);
	targetdata[6] = '\0';
	targetdata[5] = e0%256;
	targetdata[4] = e0/256;
	targetdata[3] = e1%256;
	targetdata[2] = e1/256;
	targetdata[1] = e2%256;
	targetdata[0] = e2/256;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -