Fix for old logic error in seeking format information -- actually was comparing unmas...
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 14 Sep 2009 10:17:17 +0000 (10:17 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Mon, 14 Sep 2009 10:17:17 +0000 (10:17 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@1052 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/qrcode/decoder/FormatInformation.java
core/test/src/com/google/zxing/qrcode/decoder/FormatInformationTestCase.java

index 299768c..f7980ee 100644 (file)
@@ -96,39 +96,40 @@ final class FormatInformation {
   }
 
   /**
-   * @param rawFormatInfo
-   * @return
+   * @param maskedFormatInfo format info indicator, with mask still applied
+   * @return information about the format it specifies, or <code>null</code>
+   *  if doesn't seem to match any known pattern
    */
-  static FormatInformation decodeFormatInformation(int rawFormatInfo) {
-    FormatInformation formatInfo = doDecodeFormatInformation(rawFormatInfo);
+  static FormatInformation decodeFormatInformation(int maskedFormatInfo) {
+    FormatInformation formatInfo = doDecodeFormatInformation(maskedFormatInfo);
     if (formatInfo != null) {
       return formatInfo;
     }
     // Should return null, but, some QR codes apparently
-    // do not mask this info. Try again, first masking the raw bits so
-    // the function will unmask
-    return doDecodeFormatInformation(rawFormatInfo ^ FORMAT_INFO_MASK_QR);
+    // do not mask this info. Try again by actually masking the pattern
+    // first
+    return doDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
   }
 
-  private static FormatInformation doDecodeFormatInformation(int rawFormatInfo) {
-    // Unmask:
-    int unmaskedFormatInfo = rawFormatInfo ^ FORMAT_INFO_MASK_QR;
+  private static FormatInformation doDecodeFormatInformation(int maskedFormatInfo) {
     // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
     int bestDifference = Integer.MAX_VALUE;
     int bestFormatInfo = 0;
     for (int i = 0; i < FORMAT_INFO_DECODE_LOOKUP.length; i++) {
       int[] decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];
       int targetInfo = decodeInfo[0];
-      if (targetInfo == unmaskedFormatInfo) {
+      if (targetInfo == maskedFormatInfo) {
         // Found an exact match
         return new FormatInformation(decodeInfo[1]);
       }
-      int bitsDifference = numBitsDiffering(unmaskedFormatInfo, targetInfo);
+      int bitsDifference = numBitsDiffering(maskedFormatInfo, targetInfo);
       if (bitsDifference < bestDifference) {
         bestFormatInfo = decodeInfo[1];
         bestDifference = bitsDifference;
       }
     }
+    // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
+    // differing means we found a match
     if (bestDifference <= 3) {
       return new FormatInformation(bestFormatInfo);
     }
index 99acb47..e737993 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.google.zxing.qrcode.decoder;
 
-import com.google.zxing.ReaderException;
 import junit.framework.TestCase;
 
 /**
@@ -24,6 +23,9 @@ import junit.framework.TestCase;
  */
 public final class FormatInformationTestCase extends TestCase {
 
+  private static final int MASKED_TEST_FORMAT_INFO = 0x2BED;
+  private static final int UNMASKED_TEST_FORMAT_INFO = MASKED_TEST_FORMAT_INFO ^ 0x5412;
+
   public void testBitsDiffering() {
     assertEquals(0, FormatInformation.numBitsDiffering(1, 1));
     assertEquals(1, FormatInformation.numBitsDiffering(0, 2));
@@ -31,19 +33,19 @@ public final class FormatInformationTestCase extends TestCase {
     assertEquals(32, FormatInformation.numBitsDiffering(-1, 0));
   }
 
-  public void testDecode() throws ReaderException {
+  public void testDecode() {
     // Normal case
-    FormatInformation expected = FormatInformation.decodeFormatInformation(0x2BED ^ 0x5412);
+    FormatInformation expected = FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO);
     assertEquals((byte) 0x07, expected.getDataMask());
     assertEquals(ErrorCorrectionLevel.Q, expected.getErrorCorrectionLevel());
     // where the code forgot the mask!
-    assertEquals(expected, FormatInformation.decodeFormatInformation(0x2BED));
+    assertEquals(expected, FormatInformation.decodeFormatInformation(UNMASKED_TEST_FORMAT_INFO));
 
     // 1,2,3,4 bits difference
-    assertEquals(expected, FormatInformation.decodeFormatInformation(0x2BEF ^ 0x5412));
-    assertEquals(expected, FormatInformation.decodeFormatInformation(0x2BEE ^ 0x5412));
-    assertEquals(expected, FormatInformation.decodeFormatInformation(0x2BEA ^ 0x5412));
-    assertNull(FormatInformation.decodeFormatInformation(0x2BE2 ^ 0x5412));
+    assertEquals(expected, FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x01));
+    assertEquals(expected, FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x03));
+    assertEquals(expected, FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x07));
+    assertNull(FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO ^ 0x0F));
   }
 
 }
\ No newline at end of file