QRCodeEncoder.cs
上传用户:tjjgrl
上传日期:2019-04-04
资源大小:1010k
文件大小:29k
源码类别:

电子政务应用

开发平台:

C#

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing.Imaging;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Resources;
  8. using ThoughtWorks.QRCode.Properties;
  9. using SystemUtils = ThoughtWorks.QRCode.Codec.Util.SystemUtils;
  10. using QRCodeUtility = ThoughtWorks.QRCode.Codec.Util.QRCodeUtility;
  11. namespace ThoughtWorks.QRCode.Codec
  12. {
  13.     public class QRCodeEncoder
  14.     {
  15.         public enum ENCODE_MODE {ALPHA_NUMERIC,NUMERIC,BYTE};
  16.         
  17.         public enum ERROR_CORRECTION {L, M, Q, H};
  18.         //internal static String DATA_PATH = "qrcode_data";
  19.         //internal static String QRCODE_DATA_PATH = String.Empty;
  20.         internal ERROR_CORRECTION qrcodeErrorCorrect;
  21.         internal ENCODE_MODE qrcodeEncodeMode;
  22. internal int qrcodeVersion;
  23. internal int qrcodeStructureappendN;
  24. internal int qrcodeStructureappendM;
  25. internal int qrcodeStructureappendParity;
  26.         
  27.         internal Color qrCodeBackgroundColor;
  28.         internal Color qrCodeForegroundColor;
  29.         internal int qrCodeScale;
  30. internal String qrcodeStructureappendOriginaldata;
  31.         /// <summary>
  32.         /// Constructor
  33.         /// </summary>
  34.         public QRCodeEncoder()
  35.         {
  36.             qrcodeErrorCorrect = ERROR_CORRECTION.M;
  37.             qrcodeEncodeMode = ENCODE_MODE.BYTE;
  38.             qrcodeVersion = 7;
  39.             qrcodeStructureappendN = 0;
  40.             qrcodeStructureappendM = 0;
  41.             qrcodeStructureappendParity = 0;
  42.             qrcodeStructureappendOriginaldata = "";
  43.             qrCodeScale = 4;
  44.             qrCodeBackgroundColor = Color.White;
  45.             qrCodeForegroundColor = Color.Black;
  46.            
  47.             //QRCODE_DATA_PATH = Environment.CurrentDirectory + @"" + DATA_PATH;
  48.         }
  49.         virtual public ERROR_CORRECTION QRCodeErrorCorrect
  50. {
  51. get
  52. {
  53. return qrcodeErrorCorrect;
  54. }
  55. set
  56. {
  57. qrcodeErrorCorrect = value;
  58. }
  59. }
  60. virtual public int QRCodeVersion
  61. {
  62. get
  63. {
  64. return qrcodeVersion;
  65. }
  66. set
  67. {
  68. if (value >= 0 && value <= 40)
  69. {
  70. qrcodeVersion = value;
  71. }
  72. }
  73. }
  74.         virtual public ENCODE_MODE QRCodeEncodeMode
  75. {
  76. get
  77. {
  78. return qrcodeEncodeMode;
  79. }
  80. set
  81. {
  82. qrcodeEncodeMode = value;
  83. }
  84. }
  85.         virtual public int QRCodeScale
  86.         {
  87.             get
  88.             {
  89.                 return qrCodeScale;
  90.             }
  91.             set
  92.             {
  93.                 qrCodeScale = value;
  94.             }
  95.         }
  96.         virtual public Color QRCodeBackgroundColor
  97.         {
  98.             get
  99.             {
  100.                 return qrCodeBackgroundColor;
  101.             }
  102.             set
  103.             {
  104.                 qrCodeBackgroundColor = value;
  105.             }
  106.         }
  107.         virtual public Color QRCodeForegroundColor
  108.         {
  109.             get
  110.             {
  111.                 return qrCodeForegroundColor;
  112.             }
  113.             set
  114.             {
  115.                 qrCodeForegroundColor = value;
  116.             }
  117.         }
  118. public virtual void  setStructureappend(int m, int n, int p)
  119. {
  120. if (n > 1 && n <= 16 && m > 0 && m <= 16 && p >= 0 && p <= 255)
  121. {
  122. qrcodeStructureappendM = m;
  123. qrcodeStructureappendN = n;
  124. qrcodeStructureappendParity = p;
  125. }
  126. }
  127. public virtual int calStructureappendParity(sbyte[] originaldata)
  128. {
  129. int originaldataLength;
  130. int i = 0;
  131. int structureappendParity = 0;
  132. originaldataLength = originaldata.Length;
  133. if (originaldataLength > 1)
  134. {
  135. structureappendParity = 0;
  136. while (i < originaldataLength)
  137. {
  138. structureappendParity = (structureappendParity ^ (originaldata[i] & 0xFF));
  139. i++;
  140. }
  141. }
  142. else
  143. {
  144. structureappendParity = - 1;
  145. }
  146. return structureappendParity;
  147. }
  148. public virtual bool[][] calQrcode(byte[] qrcodeData)
  149. {
  150. int dataLength;
  151. int dataCounter = 0;
  152. dataLength = qrcodeData.Length;
  153. int[] dataValue = new int[dataLength + 32];
  154. sbyte[] dataBits = new sbyte[dataLength + 32];
  155. if (dataLength <= 0)
  156. {
  157. bool[][] ret = new bool[][]{new bool[]{false}};
  158. return ret;
  159. }
  160. if (qrcodeStructureappendN > 1)
  161. {
  162. dataValue[0] = 3;
  163. dataBits[0] = 4;
  164. dataValue[1] = qrcodeStructureappendM - 1;
  165. dataBits[1] = 4;
  166. dataValue[2] = qrcodeStructureappendN - 1;
  167. dataBits[2] = 4;
  168. dataValue[3] = qrcodeStructureappendParity;
  169. dataBits[3] = 8;
  170. dataCounter = 4;
  171. }
  172. dataBits[dataCounter] = 4;
  173. /*  --- determine encode mode --- */
  174. int[] codewordNumPlus;
  175. int codewordNumCounterValue;
  176. switch (qrcodeEncodeMode)
  177. {
  178. /* ---- alphanumeric mode ---  */
  179.                 case ENCODE_MODE.ALPHA_NUMERIC: 
  180. codewordNumPlus = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
  181. dataValue[dataCounter] = 2;
  182. dataCounter++;
  183. dataValue[dataCounter] = dataLength;
  184. dataBits[dataCounter] = 9;
  185. codewordNumCounterValue = dataCounter;
  186. dataCounter++;
  187. for (int i = 0; i < dataLength; i++)
  188. {
  189. char chr = (char) qrcodeData[i];
  190. sbyte chrValue = 0;
  191. if (chr >= 48 && chr < 58)
  192. {
  193. chrValue = (sbyte) (chr - 48);
  194. }
  195. else
  196. {
  197. if (chr >= 65 && chr < 91)
  198. {
  199. chrValue = (sbyte) (chr - 55);
  200. }
  201. else
  202. {
  203. if (chr == 32)
  204. {
  205. chrValue = 36;
  206. }
  207. if (chr == 36)
  208. {
  209. chrValue = 37;
  210. }
  211. if (chr == 37)
  212. {
  213. chrValue = 38;
  214. }
  215. if (chr == 42)
  216. {
  217. chrValue = 39;
  218. }
  219. if (chr == 43)
  220. {
  221. chrValue = 40;
  222. }
  223. if (chr == 45)
  224. {
  225. chrValue = 41;
  226. }
  227. if (chr == 46)
  228. {
  229. chrValue = 42;
  230. }
  231. if (chr == 47)
  232. {
  233. chrValue = 43;
  234. }
  235. if (chr == 58)
  236. {
  237. chrValue = 44;
  238. }
  239. }
  240. }
  241. if ((i % 2) == 0)
  242. {
  243. dataValue[dataCounter] = chrValue;
  244. dataBits[dataCounter] = 6;
  245. }
  246. else
  247. {
  248. dataValue[dataCounter] = dataValue[dataCounter] * 45 + chrValue;
  249. dataBits[dataCounter] = 11;
  250. if (i < dataLength - 1)
  251. {
  252. dataCounter++;
  253. }
  254. }
  255. }
  256. dataCounter++;
  257. break;
  258. /* ---- numeric mode ---- */
  259.                 case ENCODE_MODE.NUMERIC: 
  260. codewordNumPlus = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
  261. dataValue[dataCounter] = 1;
  262. dataCounter++;
  263. dataValue[dataCounter] = dataLength;
  264. dataBits[dataCounter] = 10; /* #version 1-9*/
  265. codewordNumCounterValue = dataCounter;
  266. dataCounter++;
  267. for (int i = 0; i < dataLength; i++)
  268. {
  269. if ((i % 3) == 0)
  270. {
  271. dataValue[dataCounter] = (int) (qrcodeData[i] - 0x30);
  272. dataBits[dataCounter] = 4;
  273. }
  274. else
  275. {
  276. dataValue[dataCounter] = dataValue[dataCounter] * 10 + (int) (qrcodeData[i] - 0x30);
  277. if ((i % 3) == 1)
  278. {
  279. dataBits[dataCounter] = 7;
  280. }
  281. else
  282. {
  283. dataBits[dataCounter] = 10;
  284. if (i < dataLength - 1)
  285. {
  286. dataCounter++;
  287. }
  288. }
  289. }
  290. }
  291. dataCounter++;
  292. break;
  293. /* ---- 8bit byte ---- */
  294. default: 
  295. codewordNumPlus = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
  296. dataValue[dataCounter] = 4;
  297. dataCounter++;
  298. dataValue[dataCounter] = dataLength;
  299. dataBits[dataCounter] = 8; /* #version 1-9 */
  300. codewordNumCounterValue = dataCounter;
  301. dataCounter++;
  302. for (int i = 0; i < dataLength; i++)
  303. {
  304. dataValue[i + dataCounter] = (qrcodeData[i] & 0xFF);
  305. dataBits[i + dataCounter] = 8;
  306. }
  307. dataCounter += dataLength;
  308. break;
  309. }
  310. int totalDataBits = 0;
  311. for (int i = 0; i < dataCounter; i++)
  312. {
  313. totalDataBits += dataBits[i];
  314. }
  315. int ec;
  316. switch (qrcodeErrorCorrect)
  317. {
  318. case ERROR_CORRECTION.L: 
  319. ec = 1;
  320. break;
  321.                 case ERROR_CORRECTION.Q: 
  322. ec = 3;
  323. break;
  324.                 case ERROR_CORRECTION.H: 
  325. ec = 2;
  326. break;
  327. default: 
  328. ec = 0;
  329. break;
  330. }
  331. int[][] maxDataBitsArray = new int[][]{new int[]{0, 128, 224, 352, 512, 688, 864, 992, 1232, 1456, 1728, 2032, 2320, 2672, 2920, 3320, 3624, 4056, 4504, 5016, 5352, 5712, 6256, 6880, 7312, 8000, 8496, 9024, 9544, 10136, 10984, 11640, 12328, 13048, 13800, 14496, 15312, 15936, 16816, 17728, 18672}, new int[]{0, 152, 272, 440, 640, 864, 1088, 1248, 1552, 1856, 2192, 2592, 2960, 3424, 3688, 4184, 4712, 5176, 5768, 6360, 6888, 7456, 8048, 8752, 9392, 10208, 10960, 11744, 12248, 13048, 13880, 14744, 15640, 16568, 17528, 18448, 19472, 20528, 21616, 22496, 23648}, new int[]{0, 72, 128, 208, 288, 368, 480, 528, 688, 800, 976, 1120, 1264, 1440, 1576, 1784, 2024, 2264, 2504, 2728, 3080, 3248, 3536, 3712, 4112, 4304, 4768, 5024, 5288, 5608, 5960, 6344, 6760, 7208, 7688, 7888, 8432, 8768, 9136, 9776, 10208}, new int[]{0, 104, 176, 272, 384, 496, 608, 704, 880, 1056, 1232, 1440, 1648, 1952, 2088, 2360, 2600, 2936, 3176, 3560, 3880, 4096, 4544, 4912, 5312, 5744, 6032, 6464, 6968, 7288, 7880, 8264, 8920, 9368, 9848, 10288, 10832, 11408, 12016, 12656, 13328}};
  332. int maxDataBits = 0;
  333. if (qrcodeVersion == 0)
  334. {
  335. /* auto version select */
  336. qrcodeVersion = 1;
  337. for (int i = 1; i <= 40; i++)
  338. {
  339. if ((maxDataBitsArray[ec][i]) >= totalDataBits + codewordNumPlus[qrcodeVersion])
  340. {
  341. maxDataBits = maxDataBitsArray[ec][i];
  342. break;
  343. }
  344. qrcodeVersion++;
  345. }
  346. }
  347. else
  348. {
  349. maxDataBits = maxDataBitsArray[ec][qrcodeVersion];
  350. }
  351. totalDataBits += codewordNumPlus[qrcodeVersion];
  352. dataBits[codewordNumCounterValue] = (sbyte) (dataBits[codewordNumCounterValue] + codewordNumPlus[qrcodeVersion]);
  353. int[] maxCodewordsArray = new int[]{0, 26, 44, 70, 100, 134, 172, 196, 242, 292, 346, 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085, 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185, 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706};
  354. int maxCodewords = maxCodewordsArray[qrcodeVersion];
  355. int maxModules1side = 17 + (qrcodeVersion << 2);
  356. int[] matrixRemainBit = new int[]{0, 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0};
  357. /* ---- read version ECC data file */
  358. int byte_num = matrixRemainBit[qrcodeVersion] + (maxCodewords << 3);
  359. sbyte[] matrixX = new sbyte[byte_num];
  360. sbyte[] matrixY = new sbyte[byte_num];
  361. sbyte[] maskArray = new sbyte[byte_num];
  362. sbyte[] formatInformationX2 = new sbyte[15];
  363. sbyte[] formatInformationY2 = new sbyte[15];
  364. sbyte[] rsEccCodewords = new sbyte[1];
  365. sbyte[] rsBlockOrderTemp = new sbyte[128];
  366. try
  367. {
  368. //String filename = QRCODE_DATA_PATH + @"qrv" + System.Convert.ToString(qrcodeVersion) + "_" + System.Convert.ToString(ec) + ".dat";
  369.             //StreamReader reader = new StreamReader(filename);
  370.                 //BufferedStream bis = new BufferedStream(reader.BaseStream);
  371.                                 
  372.                 String fileName = "qrv" + Convert.ToString(qrcodeVersion) + "_" + Convert.ToString(ec);
  373.                 MemoryStream memoryStream = new MemoryStream(Resources.GetResource(fileName));
  374.                 BufferedStream bis = new BufferedStream(memoryStream);
  375.                 
  376.                 SystemUtils.ReadInput(bis, matrixX, 0, matrixX.Length);
  377.                 SystemUtils.ReadInput(bis, matrixY, 0, matrixY.Length);
  378.                 SystemUtils.ReadInput(bis, maskArray, 0, maskArray.Length);
  379.                 SystemUtils.ReadInput(bis, formatInformationX2, 0, formatInformationX2.Length);
  380.                 SystemUtils.ReadInput(bis, formatInformationY2, 0, formatInformationY2.Length);
  381.                 SystemUtils.ReadInput(bis, rsEccCodewords, 0, rsEccCodewords.Length);
  382.                 SystemUtils.ReadInput(bis, rsBlockOrderTemp, 0, rsBlockOrderTemp.Length);
  383.                 bis.Close();
  384.                 memoryStream.Close();
  385.                 // reader.Close();
  386. /*
  387.                 fis.Close();
  388.                 */
  389. }
  390. catch (Exception e)
  391. {
  392. SystemUtils.WriteStackTrace(e, Console.Error);
  393. }
  394. sbyte rsBlockOrderLength = 1;
  395. for (sbyte i = 1; i < 128; i++)
  396. {
  397. if (rsBlockOrderTemp[i] == 0)
  398. {
  399. rsBlockOrderLength = i;
  400. break;
  401. }
  402. }
  403. sbyte[] rsBlockOrder = new sbyte[rsBlockOrderLength];
  404. Array.Copy(rsBlockOrderTemp, 0, rsBlockOrder, 0, (byte) rsBlockOrderLength);
  405. sbyte[] formatInformationX1 = new sbyte[]{0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8};
  406. sbyte[] formatInformationY1 = new sbyte[]{8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0};
  407. int maxDataCodewords = maxDataBits >> 3;
  408. /* -- read frame data  -- */
  409. int modules1Side = 4 * qrcodeVersion + 17;
  410. int matrixTotalBits = modules1Side * modules1Side;
  411. sbyte[] frameData = new sbyte[matrixTotalBits + modules1Side];
  412. try
  413. {
  414. //String filename = QRCODE_DATA_PATH + "/qrvfr" + System.Convert.ToString(qrcodeVersion) + ".dat";
  415.                 //StreamReader reader = new StreamReader(filename);
  416.                 String fileName = "qrvfr" + Convert.ToString(qrcodeVersion);
  417.                 MemoryStream memoryStream = new MemoryStream(Resources.GetResource(fileName));
  418.                 
  419. BufferedStream bis = new BufferedStream(memoryStream);
  420. SystemUtils.ReadInput(bis, frameData, 0, frameData.Length);
  421. bis.Close();
  422.                 memoryStream.Close();
  423.                 //reader.Close();
  424.                 //fis.Close();
  425. }
  426. catch (Exception e)
  427. {
  428. SystemUtils.WriteStackTrace(e, Console.Error);
  429. }
  430. /*  --- set terminator */
  431. if (totalDataBits <= maxDataBits - 4)
  432. {
  433. dataValue[dataCounter] = 0;
  434. dataBits[dataCounter] = 4;
  435. }
  436. else
  437. {
  438. if (totalDataBits < maxDataBits)
  439. {
  440. dataValue[dataCounter] = 0;
  441. dataBits[dataCounter] = (sbyte) (maxDataBits - totalDataBits);
  442. }
  443. else
  444. {
  445. if (totalDataBits > maxDataBits)
  446. {
  447. System.Console.Out.WriteLine("overflow");
  448. }
  449. }
  450. }
  451. sbyte[] dataCodewords = divideDataBy8Bits(dataValue, dataBits, maxDataCodewords);
  452. sbyte[] codewords = calculateRSECC(dataCodewords, rsEccCodewords[0], rsBlockOrder, maxDataCodewords, maxCodewords);
  453. /* ---- flash matrix */
  454. sbyte[][] matrixContent = new sbyte[modules1Side][];
  455. for (int i2 = 0; i2 < modules1Side; i2++)
  456. {
  457. matrixContent[i2] = new sbyte[modules1Side];
  458. }
  459. for (int i = 0; i < modules1Side; i++)
  460. {
  461. for (int j = 0; j < modules1Side; j++)
  462. {
  463. matrixContent[j][i] = 0;
  464. }
  465. }
  466. /* --- attach data */
  467. for (int i = 0; i < maxCodewords; i++)
  468. {
  469. sbyte codeword_i = codewords[i];
  470. for (int j = 7; j >= 0; j--)
  471. {
  472. int codewordBitsNumber = (i * 8) + j;
  473. matrixContent[matrixX[codewordBitsNumber] & 0xFF][matrixY[codewordBitsNumber] & 0xFF] = (sbyte) ((255 * (codeword_i & 1)) ^ maskArray[codewordBitsNumber]);
  474. codeword_i = (sbyte) (SystemUtils.URShift((codeword_i & 0xFF), 1));
  475. }
  476. }
  477. for (int matrixRemain = matrixRemainBit[qrcodeVersion]; matrixRemain > 0; matrixRemain--)
  478. {
  479. int remainBitTemp = matrixRemain + (maxCodewords * 8) - 1;
  480. matrixContent[matrixX[remainBitTemp] & 0xFF][matrixY[remainBitTemp] & 0xFF] = (sbyte) (255 ^ maskArray[remainBitTemp]);
  481. }
  482. /* --- mask select --- */
  483. sbyte maskNumber = selectMask(matrixContent, matrixRemainBit[qrcodeVersion] + maxCodewords * 8);
  484. sbyte maskContent = (sbyte) (1 << maskNumber);
  485. /* --- format information --- */
  486. sbyte formatInformationValue = (sbyte) (ec << 3 | maskNumber);
  487. String[] formatInformationArray = new String[]{"101010000010010", "101000100100101", "101111001111100", "101101101001011", "100010111111001", "100000011001110", "100111110010111", "100101010100000", "111011111000100", "111001011110011", "111110110101010", "111100010011101", "110011000101111", "110001100011000", "110110001000001", "110100101110110", "001011010001001", "001001110111110", "001110011100111", "001100111010000", "000011101100010", "000001001010101", "000110100001100", "000100000111011", "011010101011111", "011000001101000", "011111100110001", "011101000000110", "010010010110100", "010000110000011", "010111011011010", "010101111101101"};
  488. for (int i = 0; i < 15; i++)
  489. {
  490. sbyte content = (sbyte) System.SByte.Parse(formatInformationArray[formatInformationValue].Substring(i, (i + 1) - (i)));
  491. matrixContent[formatInformationX1[i] & 0xFF][formatInformationY1[i] & 0xFF] = (sbyte) (content * 255);
  492. matrixContent[formatInformationX2[i] & 0xFF][formatInformationY2[i] & 0xFF] = (sbyte) (content * 255);
  493. }
  494. bool[][] out_Renamed = new bool[modules1Side][];
  495. for (int i3 = 0; i3 < modules1Side; i3++)
  496. {
  497. out_Renamed[i3] = new bool[modules1Side];
  498. }
  499. int c = 0;
  500. for (int i = 0; i < modules1Side; i++)
  501. {
  502. for (int j = 0; j < modules1Side; j++)
  503. {
  504. if ((matrixContent[j][i] & maskContent) != 0 || frameData[c] == (char) 49)
  505. {
  506. out_Renamed[j][i] = true;
  507. }
  508. else
  509. {
  510. out_Renamed[j][i] = false;
  511. }
  512. c++;
  513. }
  514. c++;
  515. }
  516. return out_Renamed;
  517. }
  518. private static sbyte[] divideDataBy8Bits(int[] data, sbyte[] bits, int maxDataCodewords)
  519. {
  520. /* divide Data By 8bit and add padding char */
  521. int l1 = bits.Length;
  522. int l2;
  523. int codewordsCounter = 0;
  524. int remainingBits = 8;
  525. int max = 0;
  526. int buffer;
  527. int bufferBits;
  528. bool flag;
  529. if (l1 != data.Length)
  530. {
  531. }
  532. for (int i = 0; i < l1; i++)
  533. {
  534. max += bits[i];
  535. }
  536. l2 = (max - 1) / 8 + 1;
  537. sbyte[] codewords = new sbyte[maxDataCodewords];
  538. for (int i = 0; i < l2; i++)
  539. {
  540. codewords[i] = 0;
  541. }
  542. for (int i = 0; i < l1; i++)
  543. {
  544. buffer = data[i];
  545. bufferBits = bits[i];
  546. flag = true;
  547. if (bufferBits == 0)
  548. {
  549. break;
  550. }
  551. while (flag)
  552. {
  553. if (remainingBits > bufferBits)
  554. {
  555. codewords[codewordsCounter] = (sbyte) ((codewords[codewordsCounter] << bufferBits) | buffer);
  556. remainingBits -= bufferBits;
  557. flag = false;
  558. }
  559. else
  560. {
  561. bufferBits -= remainingBits;
  562. codewords[codewordsCounter] = (sbyte) ((codewords[codewordsCounter] << remainingBits) | (buffer >> bufferBits));
  563. if (bufferBits == 0)
  564. {
  565. flag = false;
  566. }
  567. else
  568. {
  569. buffer = (buffer & ((1 << bufferBits) - 1));
  570. flag = true;
  571. }
  572. codewordsCounter++;
  573. remainingBits = 8;
  574. }
  575. }
  576. }
  577. if (remainingBits != 8)
  578. {
  579. codewords[codewordsCounter] = (sbyte) (codewords[codewordsCounter] << remainingBits);
  580. }
  581. else
  582. {
  583. codewordsCounter--;
  584. }
  585. if (codewordsCounter < maxDataCodewords - 1)
  586. {
  587. flag = true;
  588. while (codewordsCounter < maxDataCodewords - 1)
  589. {
  590. codewordsCounter++;
  591. if (flag)
  592. {
  593. codewords[codewordsCounter] = - 20;
  594. }
  595. else
  596. {
  597. codewords[codewordsCounter] = 17;
  598. }
  599. flag = !(flag);
  600. }
  601. }
  602. return codewords;
  603. }
  604. private static sbyte[] calculateRSECC(sbyte[] codewords, sbyte rsEccCodewords, sbyte[] rsBlockOrder, int maxDataCodewords, int maxCodewords)
  605. {
  606. sbyte[][] rsCalTableArray = new sbyte[256][];
  607. for (int i = 0; i < 256; i++)
  608. {
  609. rsCalTableArray[i] = new sbyte[rsEccCodewords];
  610. }
  611. try
  612. {
  613.     //String filename = QRCODE_DATA_PATH + @"rsc" + rsEccCodewords.ToString() + ".dat";
  614.     //StreamReader reader = new StreamReader(filename);
  615.                 String fileName = "rsc" + rsEccCodewords.ToString();
  616.                 MemoryStream memoryStream = new MemoryStream(Resources.GetResource(fileName));
  617.                 BufferedStream bis = new BufferedStream(memoryStream);
  618. for (int i = 0; i < 256; i++)
  619. {
  620. SystemUtils.ReadInput(bis, rsCalTableArray[i], 0, rsCalTableArray[i].Length);
  621. }
  622. bis.Close();
  623. //reader.Close();
  624.                 memoryStream.Close();
  625. }
  626. catch (Exception e)
  627. {
  628. SystemUtils.WriteStackTrace(e, Console.Error);
  629. }
  630. /* ---- RS-ECC prepare */
  631. int i2 = 0;
  632. int j = 0;
  633. int rsBlockNumber = 0;
  634. sbyte[][] rsTemp = new sbyte[rsBlockOrder.Length][];
  635.             /*
  636.             for (int i = 0; i < rsBlockOrder.Length; i++)
  637.             {
  638.                 rsTemp[i] = new sbyte[rsBlockOrder.Length];
  639.             }
  640.             */
  641. sbyte[] res = new sbyte[maxCodewords];
  642. Array.Copy(codewords, 0, res, 0, codewords.Length);
  643. i2 = 0;
  644. while (i2 < rsBlockOrder.Length)
  645. {
  646. rsTemp[i2] = new sbyte[(rsBlockOrder[i2] & 0xFF) - rsEccCodewords];
  647. i2++;
  648. }
  649. i2 = 0;
  650. while (i2 < maxDataCodewords)
  651. {
  652. rsTemp[rsBlockNumber][j] = codewords[i2];
  653. j++;
  654. if (j >= (rsBlockOrder[rsBlockNumber] & 0xFF) - rsEccCodewords)
  655. {
  656. j = 0;
  657. rsBlockNumber++;
  658. }
  659. i2++;
  660. }
  661. /* ---  RS-ECC main --- */
  662. rsBlockNumber = 0;
  663. while (rsBlockNumber < rsBlockOrder.Length)
  664. {
  665. sbyte[] rsTempData;
  666. rsTempData = new sbyte[rsTemp[rsBlockNumber].Length];
  667. rsTemp[rsBlockNumber].CopyTo(rsTempData, 0);
  668. int rsCodewords = (rsBlockOrder[rsBlockNumber] & 0xFF);
  669. int rsDataCodewords = rsCodewords - rsEccCodewords;
  670. j = rsDataCodewords;
  671. while (j > 0)
  672. {
  673. sbyte first = rsTempData[0];
  674. if (first != 0)
  675. {
  676. sbyte[] leftChr = new sbyte[rsTempData.Length - 1];
  677. Array.Copy(rsTempData, 1, leftChr, 0, rsTempData.Length - 1);
  678. sbyte[] cal = rsCalTableArray[(first & 0xFF)];
  679. rsTempData = calculateByteArrayBits(leftChr, cal, "xor");
  680. }
  681. else
  682. {
  683. if (rsEccCodewords < rsTempData.Length)
  684. {
  685. sbyte[] rsTempNew = new sbyte[rsTempData.Length - 1];
  686. Array.Copy(rsTempData, 1, rsTempNew, 0, rsTempData.Length - 1);
  687. rsTempData = new sbyte[rsTempNew.Length];
  688. rsTempNew.CopyTo(rsTempData, 0);
  689. }
  690. else
  691. {
  692. sbyte[] rsTempNew = new sbyte[rsEccCodewords];
  693. Array.Copy(rsTempData, 1, rsTempNew, 0, rsTempData.Length - 1);
  694. rsTempNew[rsEccCodewords - 1] = 0;
  695. rsTempData = new sbyte[rsTempNew.Length];
  696. rsTempNew.CopyTo(rsTempData, 0);
  697. }
  698. }
  699. j--;
  700. }
  701. Array.Copy(rsTempData, 0, res, codewords.Length + rsBlockNumber * rsEccCodewords, (byte) rsEccCodewords);
  702. rsBlockNumber++;
  703. }
  704. return res;
  705. }
  706. private static sbyte[] calculateByteArrayBits(sbyte[] xa, sbyte[] xb, String ind)
  707. {
  708. int ll;
  709. int ls;
  710. sbyte[] res;
  711. sbyte[] xl;
  712. sbyte[] xs;
  713. if (xa.Length > xb.Length)
  714. {
  715. xl = new sbyte[xa.Length];
  716. xa.CopyTo(xl, 0);
  717. xs = new sbyte[xb.Length];
  718. xb.CopyTo(xs, 0);
  719. }
  720. else
  721. {
  722. xl = new sbyte[xb.Length];
  723. xb.CopyTo(xl, 0);
  724. xs = new sbyte[xa.Length];
  725. xa.CopyTo(xs, 0);
  726. }
  727. ll = xl.Length;
  728. ls = xs.Length;
  729. res = new sbyte[ll];
  730. for (int i = 0; i < ll; i++)
  731. {
  732. if (i < ls)
  733. {
  734. if ((System.Object) ind == (System.Object) "xor")
  735. {
  736. res[i] = (sbyte) (xl[i] ^ xs[i]);
  737. }
  738. else
  739. {
  740. res[i] = (sbyte) (xl[i] | xs[i]);
  741. }
  742. }
  743. else
  744. {
  745. res[i] = xl[i];
  746. }
  747. }
  748. return res;
  749. }
  750. private static sbyte selectMask(sbyte[][] matrixContent, int maxCodewordsBitWithRemain)
  751. {
  752. int l = matrixContent.Length;
  753. int[] d1 = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  754. int[] d2 = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  755. int[] d3 = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  756. int[] d4 = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  757. int d2And = 0;
  758. int d2Or = 0;
  759. int[] d4Counter = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  760. for (int y = 0; y < l; y++)
  761. {
  762. int[] xData = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  763. int[] yData = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
  764. bool[] xD1Flag = new bool[]{false, false, false, false, false, false, false, false};
  765. bool[] yD1Flag = new bool[]{false, false, false, false, false, false, false, false};
  766. for (int x = 0; x < l; x++)
  767. {
  768. if (x > 0 && y > 0)
  769. {
  770. d2And = matrixContent[x][y] & matrixContent[x - 1][y] & matrixContent[x][y - 1] & matrixContent[x - 1][y - 1] & 0xFF;
  771. d2Or = (matrixContent[x][y] & 0xFF) | (matrixContent[x - 1][y] & 0xFF) | (matrixContent[x][y - 1] & 0xFF) | (matrixContent[x - 1][y - 1] & 0xFF);
  772. }
  773. for (int maskNumber = 0; maskNumber < 8; maskNumber++)
  774. {
  775. xData[maskNumber] = ((xData[maskNumber] & 63) << 1) | ((SystemUtils.URShift((matrixContent[x][y] & 0xFF), maskNumber)) & 1);
  776. yData[maskNumber] = ((yData[maskNumber] & 63) << 1) | ((SystemUtils.URShift((matrixContent[y][x] & 0xFF), maskNumber)) & 1);
  777. if ((matrixContent[x][y] & (1 << maskNumber)) != 0)
  778. {
  779. d4Counter[maskNumber]++;
  780. }
  781. if (xData[maskNumber] == 93)
  782. {
  783. d3[maskNumber] += 40;
  784. }
  785. if (yData[maskNumber] == 93)
  786. {
  787. d3[maskNumber] += 40;
  788. }
  789. if (x > 0 && y > 0)
  790. {
  791. if (((d2And & 1) != 0) || ((d2Or & 1) == 0))
  792. {
  793. d2[maskNumber] += 3;
  794. }
  795. d2And = d2And >> 1;
  796. d2Or = d2Or >> 1;
  797. }
  798. if (((xData[maskNumber] & 0x1F) == 0) || ((xData[maskNumber] & 0x1F) == 0x1F))
  799. {
  800. if (x > 3)
  801. {
  802. if (xD1Flag[maskNumber])
  803. {
  804. d1[maskNumber]++;
  805. }
  806. else
  807. {
  808. d1[maskNumber] += 3;
  809. xD1Flag[maskNumber] = true;
  810. }
  811. }
  812. }
  813. else
  814. {
  815. xD1Flag[maskNumber] = false;
  816. }
  817. if (((yData[maskNumber] & 0x1F) == 0) || ((yData[maskNumber] & 0x1F) == 0x1F))
  818. {
  819. if (x > 3)
  820. {
  821. if (yD1Flag[maskNumber])
  822. {
  823. d1[maskNumber]++;
  824. }
  825. else
  826. {
  827. d1[maskNumber] += 3;
  828. yD1Flag[maskNumber] = true;
  829. }
  830. }
  831. }
  832. else
  833. {
  834. yD1Flag[maskNumber] = false;
  835. }
  836. }
  837. }
  838. }
  839. int minValue = 0;
  840. sbyte res = 0;
  841. int[] d4Value = new int[]{90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 90};
  842. for (int maskNumber = 0; maskNumber < 8; maskNumber++)
  843. {
  844. d4[maskNumber] = d4Value[(int) ((20 * d4Counter[maskNumber]) / maxCodewordsBitWithRemain)];
  845. int demerit = d1[maskNumber] + d2[maskNumber] + d3[maskNumber] + d4[maskNumber];
  846. if (demerit < minValue || maskNumber == 0)
  847. {
  848. res = (sbyte) maskNumber;
  849. minValue = demerit;
  850. }
  851. }
  852. return res;
  853. }
  854.         /// <summary>
  855.         /// Encode the content using the encoding scheme given
  856.         /// </summary>
  857.         /// <param name="content"></param>
  858.         /// <param name="encoding"></param>
  859.         /// <returns></returns>
  860.         public virtual Bitmap Encode(String content, Encoding encoding)
  861.         {
  862.             bool[][] matrix = calQrcode(encoding.GetBytes(content));
  863.             SolidBrush brush = new SolidBrush(qrCodeBackgroundColor);
  864.             Bitmap image = new Bitmap( (matrix.Length * qrCodeScale) + 1, (matrix.Length * qrCodeScale) + 1);
  865.             Graphics g = Graphics.FromImage(image);
  866.             g.FillRectangle(brush, new Rectangle(0, 0, image.Width, image.Height));
  867.             brush.Color = qrCodeForegroundColor ;
  868.             for (int i = 0; i < matrix.Length; i++)
  869.             {
  870.                 for (int j = 0; j < matrix.Length; j++)
  871.                 {
  872.                     if (matrix[j][i])
  873.                     {
  874.                         g.FillRectangle(brush, j * qrCodeScale, i * qrCodeScale, qrCodeScale, qrCodeScale);
  875.                     }
  876.                 }
  877.             }
  878.             return image;
  879.         }
  880.         /// <summary>
  881.         /// Encode the content using the encoding scheme given
  882.         /// </summary>
  883.         /// <param name="content"></param>
  884.         /// <param name="encoding"></param>
  885.         /// <returns></returns>
  886.         public virtual Bitmap Encode(String content)
  887.         {
  888.             if (QRCodeUtility.IsUniCode(content))
  889.             {
  890.                 return Encode(content, Encoding.Unicode);
  891.             }
  892.             else
  893.             {
  894.                 return Encode(content, Encoding.ASCII);
  895.             }
  896.         }
  897.        
  898.     }
  899. }