not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
4.0 KiB

  1. /*
  2. Ported to JavaScript by Lazar Laszlo 2011
  3. lazarsoft@gmail.com, www.lazarsoft.info
  4. */
  5. /*
  6. *
  7. * Copyright 2007 ZXing authors
  8. *
  9. * Licensed under the Apache License, Version 2.0 (the "License");
  10. * you may not use this file except in compliance with the License.
  11. * You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing, software
  16. * distributed under the License is distributed on an "AS IS" BASIS,
  17. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. * See the License for the specific language governing permissions and
  19. * limitations under the License.
  20. */
  21. var FORMAT_INFO_MASK_QR = 0x5412;
  22. var FORMAT_INFO_DECODE_LOOKUP = new Array(new Array(0x5412, 0x00), new Array(0x5125, 0x01), new Array(0x5E7C, 0x02), new Array(0x5B4B, 0x03), new Array(0x45F9, 0x04), new Array(0x40CE, 0x05), new Array(0x4F97, 0x06), new Array(0x4AA0, 0x07), new Array(0x77C4, 0x08), new Array(0x72F3, 0x09), new Array(0x7DAA, 0x0A), new Array(0x789D, 0x0B), new Array(0x662F, 0x0C), new Array(0x6318, 0x0D), new Array(0x6C41, 0x0E), new Array(0x6976, 0x0F), new Array(0x1689, 0x10), new Array(0x13BE, 0x11), new Array(0x1CE7, 0x12), new Array(0x19D0, 0x13), new Array(0x0762, 0x14), new Array(0x0255, 0x15), new Array(0x0D0C, 0x16), new Array(0x083B, 0x17), new Array(0x355F, 0x18), new Array(0x3068, 0x19), new Array(0x3F31, 0x1A), new Array(0x3A06, 0x1B), new Array(0x24B4, 0x1C), new Array(0x2183, 0x1D), new Array(0x2EDA, 0x1E), new Array(0x2BED, 0x1F));
  23. var BITS_SET_IN_HALF_BYTE = new Array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
  24. function FormatInformation(formatInfo)
  25. {
  26. this.errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);
  27. this.dataMask = (formatInfo & 0x07);
  28. this.__defineGetter__("ErrorCorrectionLevel", function()
  29. {
  30. return this.errorCorrectionLevel;
  31. });
  32. this.__defineGetter__("DataMask", function()
  33. {
  34. return this.dataMask;
  35. });
  36. this.GetHashCode=function()
  37. {
  38. return (this.errorCorrectionLevel.ordinal() << 3) | this.dataMask;
  39. }
  40. this.Equals=function( o)
  41. {
  42. var other = o;
  43. return this.errorCorrectionLevel == other.errorCorrectionLevel && this.dataMask == other.dataMask;
  44. }
  45. }
  46. FormatInformation.numBitsDiffering=function( a, b)
  47. {
  48. a ^= b; // a now has a 1 bit exactly where its bit differs with b's
  49. // Count bits set quickly with a series of lookups:
  50. return BITS_SET_IN_HALF_BYTE[a & 0x0F] + BITS_SET_IN_HALF_BYTE[(URShift(a, 4) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 8) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 12) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 16) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 20) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 24) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 28) & 0x0F)];
  51. }
  52. FormatInformation.decodeFormatInformation=function( maskedFormatInfo)
  53. {
  54. var formatInfo = FormatInformation.doDecodeFormatInformation(maskedFormatInfo);
  55. if (formatInfo != null)
  56. {
  57. return formatInfo;
  58. }
  59. // Should return null, but, some QR codes apparently
  60. // do not mask this info. Try again by actually masking the pattern
  61. // first
  62. return FormatInformation.doDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
  63. }
  64. FormatInformation.doDecodeFormatInformation=function( maskedFormatInfo)
  65. {
  66. // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
  67. var bestDifference = 0xffffffff;
  68. var bestFormatInfo = 0;
  69. for (var i = 0; i < FORMAT_INFO_DECODE_LOOKUP.length; i++)
  70. {
  71. var decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];
  72. var targetInfo = decodeInfo[0];
  73. if (targetInfo == maskedFormatInfo)
  74. {
  75. // Found an exact match
  76. return new FormatInformation(decodeInfo[1]);
  77. }
  78. var bitsDifference = this.numBitsDiffering(maskedFormatInfo, targetInfo);
  79. if (bitsDifference < bestDifference)
  80. {
  81. bestFormatInfo = decodeInfo[1];
  82. bestDifference = bitsDifference;
  83. }
  84. }
  85. // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
  86. // differing means we found a match
  87. if (bestDifference <= 3)
  88. {
  89. return new FormatInformation(bestFormatInfo);
  90. }
  91. return null;
  92. }