Example #1
0
		private static CodeMatrix GetEncodedMatrix(byte[] data, bool stringData){
			if(data==null)throw new ArgumentNullException("data");
			if(data.Length>7089)throw new ArgumentException("'data' length is too long.");
			bool allnumeric=stringData;
			bool alphanumeric=stringData;
			int version=-1;
			if(stringData){
				for(int i=0;i<data.Length;i++){
					byte d=data[i];
					if(d<0x30 || d>=0x3a){
						allnumeric=false;
					}
					if(d<0x20 || d>=0x60 || CharToValue[d-0x20]==0){
						alphanumeric=false;
					}
				}
			}
			//Console.WriteLine("{0} {1}",alphanumeric,stringData);
			if(allnumeric){
				for(int i=0;i<versionsnumeric.Length;i++){
					if(data.Length<=versionsnumeric[i]){
						version=i;
						break;
					}
				}
			} else if(alphanumeric){
				for(int i=0;i<versionsalphanum.Length;i++){
					if(data.Length<=versionsalphanum[i]){
						version=i;
						break;
					}
				}
			} else {
				for(int i=0;i<versions.Length;i++){
					if(data.Length<=versions[i]){
						version=i;
						break;
					}
				}
			}
			if(version<0){
				throw new ArgumentException("'data' length is too long.");
			}
			BitList bl=new BitList();
			if(allnumeric){
				bl.AddBits((byte)1,4);
				int datacount=10;
				if(version>=9 && version<=25)datacount=12;
				if(version>=26)datacount=14;
				bl.AddBits(data.Length,datacount);
				int runningcount=0;
				int runningdigits=0;
				for(int i=0;i<data.Length;i++){
					runningdigits*=10;
					runningdigits+=((int)data[i]-0x30);
					runningcount++;
					if(runningcount==3){
						bl.AddBits(runningdigits,10);
						runningcount=0;
						runningdigits=0;
					}
				}
				if(runningcount>0){
					bl.AddBits(runningdigits,(runningcount==1) ? 4 : 7);
				}
			} else if(alphanumeric){
				bl.AddBits((byte)2,4);
				int datacount=9;
				if(version>=9 && version<=25)datacount=11;
				if(version>=26)datacount=13;
				bl.AddBits(data.Length,datacount);
				//Console.WriteLine("{0} ver={1}",data.Length,version+1);
				int runningcount=0;
				int runningdigits=0;
				for(int i=0;i<data.Length;i++){
					runningdigits*=45;
					runningdigits+=CharToValue[data[i]-0x20];
					runningcount++;
					if(runningcount==2){
						bl.AddBits(runningdigits,11);
						runningcount=0;
						runningdigits=0;
					}
				}
				if(runningcount>0){
					bl.AddBits(runningdigits,6);
				}
			} else {
				bl.AddBits((byte)4,4);
				bl.AddBits(data.Length,(version<9) ? 8 : 16);
				for(int i=0;i<data.Length;i++){
					bl.AddBits(data[i],8);
				}
			}
			int matrixSize=21+version*4;
			int dataWords=(version<9) ? versions[version]+2 : versions[version]+3;
			bl.PadTo(dataWords);
			//Console.WriteLine(ArrayUtil.ArrayToString(bl.List));
			int rsOffset=version*6;
			int dataOffset=0;
			int ecOffset=0;
			int firstBlockCount=DataBlocks[rsOffset];
			int secondBlockCount=DataBlocks[rsOffset+3];
			int totalBlockCount=firstBlockCount+secondBlockCount;
			// first all data blocks then all error correction blocks
			int[] codewordOffsets=new int[totalBlockCount*2];
			for(int i=0;i<firstBlockCount;i++){
				ReedSolomonEncode(bl.List,dataOffset,
				                  DataBlocks[rsOffset+1],
				                  DataBlocks[rsOffset+2]);
				codewordOffsets[i]=dataOffset;
				codewordOffsets[totalBlockCount+i]=dataWords+ecOffset;
				dataOffset+=DataBlocks[rsOffset+1];
				ecOffset+=DataBlocks[rsOffset+2];
			}
			for(int i=0;i<secondBlockCount;i++){
				ReedSolomonEncode(bl.List,dataOffset,
				                  DataBlocks[rsOffset+4],
				                  DataBlocks[rsOffset+5]);
				codewordOffsets[i+DataBlocks[rsOffset]]=dataOffset;
				codewordOffsets[i+totalBlockCount+DataBlocks[rsOffset]]=dataWords+ecOffset;
				dataOffset+=DataBlocks[rsOffset+4];
			}
			//Console.WriteLine(ArrayUtil.ArrayToString(bl.List));
			CodeMatrix matrix=new CodeMatrix(matrixSize);
			matrix.DrawFinderPattern(0,0);
			matrix.DrawFinderPattern(0,matrixSize-7);
			matrix.DrawFinderPattern(matrixSize-7,0);
			matrix.DrawTimingPatterns();
			matrix.SetFormatInfo(0);
			if(version>=6){
				matrix.SetVersionInfo(0);
			}
			int alignOffset=version*7;
			for(int y=0;y<7;y++){
				for(int x=0;x<7;x++){
					matrix.DrawAlignmentPattern(AlignmentPatterns[alignOffset+x],
					                            AlignmentPatterns[alignOffset+y]);
				}
			}
			// Set data words
			int minSizePerBlock=DataBlocks[rsOffset+1];
			for(int i=0;i<minSizePerBlock;i++){
				for(int j=0;j<totalBlockCount;j++){
					//Console.WriteLine("{0}->{0:X2}",codewordOffsets[j],bl.List[codewordOffsets[j]]);
					int index=codewordOffsets[j];
					matrix.SetNextCodeword(bl.List[index]);
					codewordOffsets[j]++;
				}
			}
			if(secondBlockCount!=0){
				for(int j=0;j<secondBlockCount;j++){
					int index=codewordOffsets[j+firstBlockCount];
					matrix.SetNextCodeword(bl.List[index]);
					codewordOffsets[j+firstBlockCount]++;
				}
			}
			// Set error correction words
			minSizePerBlock=DataBlocks[rsOffset+2];
			for(int i=0;i<minSizePerBlock;i++){
				for(int j=0;j<totalBlockCount;j++){
					int index=codewordOffsets[j+totalBlockCount];
					matrix.SetNextCodeword(bl.List[index]);
					codewordOffsets[j+totalBlockCount]++;
				}
			}
			// Mask the data
			int lowestPenalty=0;
			int bestMask=0;
			for(int i=0;i<8;i++){
				matrix.ApplyMask(i);
				int penalty=matrix.CalculatePenalty();
				if(i==0 || penalty<lowestPenalty){
					bestMask=i;
					lowestPenalty=penalty;
				}
				// Reapply the mask to erase it
				matrix.ApplyMask(i);
			}
			matrix.ApplyMask(bestMask);
			matrix.SetFormatInfo(FormatInfo[bestMask]);
			//Console.WriteLine("format={0}",FormatInfo[bestMask]);
			if(version>=6){
				//	Console.WriteLine("version={0}",version+1);
				//	Console.WriteLine("version={0:X5}",VersionInfo[version-6]);
				matrix.SetVersionInfo(VersionInfo[version-6]);
			}
			return matrix;
		}
Example #2
0
		private static System.Drawing.Bitmap EncodeToBitmap(CodeMatrix matrix){
			int moduleSize=6;
			int pngSize=moduleSize*(matrix.Size+8);
			while(moduleSize>2 && pngSize>=600){
				moduleSize--;
				pngSize=moduleSize*(matrix.Size+8);
			}
			System.Drawing.Bitmap image = new System.Drawing.Bitmap(pngSize,pngSize);
			using(System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(image)){
				g.FillRectangle(System.Drawing.Brushes.White, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));
				for(int y=0;y<matrix.Size;y++){
					for(int x=0;x<matrix.Size;x++){
						int pngx=(4+x)*moduleSize;
						int pngy=(4+y)*moduleSize;
						bool v=matrix[x,y];
						int color=(v ? 1 : 0);
						if(v){
							g.FillRectangle(System.Drawing.Brushes.Black,
							                new System.Drawing.Rectangle(pngx,pngy,moduleSize,moduleSize));
						}
					}
				}
			}
			return image;
		}
Example #3
0
		private static PeterO.Png4BitIndexed Encode(CodeMatrix matrix){
			int moduleSize=6;
			int pngSize=moduleSize*(matrix.Size+8);
			while(moduleSize>2 && pngSize>=600){
				moduleSize--;
				pngSize=moduleSize*(matrix.Size+8);
			}
			PeterO.Png4BitIndexed png=new Png4BitIndexed(pngSize,pngSize);
			png.SetColor(0,new byte[]{255,255,255,255});
			png.SetColor(1,new byte[]{0,0,0,255});
			for(int y=0;y<png.Height;y++){
				for(int x=0;x<png.Width;x++){
					png.SetPixel(x,y,0);
				}
			}
			for(int y=0;y<matrix.Size;y++){
				for(int x=0;x<matrix.Size;x++){
					int pngx=(4+x)*moduleSize;
					int pngy=(4+y)*moduleSize;
					bool v=matrix[x,y];
					int color=(v ? 1 : 0);
					for(int y2=0;y2<moduleSize;y2++){
						for(int x2=0;x2<moduleSize;x2++){
							png.SetPixel(pngx+x2,pngy+y2,color);
						}
					}
				}
			}
			return png;
		}