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; }