Spell checker fixes, narrowed scope / made less visible where possible. Little stuff
[zxing.git] / core / src / com / google / zxing / pdf417 / detector / Detector.java
index 8a483fb..dabdce8 100644 (file)
 
 package com.google.zxing.pdf417.detector;
 
-import com.google.zxing.BlackPointEstimationMethod;
-import com.google.zxing.MonochromeBitmapSource;
+import com.google.zxing.BinaryBitmap;
 import com.google.zxing.ReaderException;
 import com.google.zxing.ResultPoint;
-import com.google.zxing.common.BitArray;
 import com.google.zxing.common.BitMatrix;
 import com.google.zxing.common.DetectorResult;
 import com.google.zxing.common.GridSampler;
@@ -28,41 +26,42 @@ import com.google.zxing.common.GridSampler;
 import java.util.Hashtable;
 
 /**
- * <p>
- * Encapsulates logic that can detect a PDF417 Code in an image, even if the
- * PDF417 Code is rotated or skewed, or partially obscured.
- * </p>
+ * <p>Encapsulates logic that can detect a PDF417 Code in an image, even if the
+ * PDF417 Code is rotated or skewed, or partially obscured.</p>
  *
  * @author SITA Lab (kevin.osullivan@sita.aero)
+ * @author dswitkin@google.com (Daniel Switkin)
  */
 public final class Detector {
 
-  public static final int MAX_AVG_VARIANCE = (int) ((1 << 8) * 0.42f);
-  public static final int MAX_INDIVIDUAL_VARIANCE = (int) ((1 << 8) * 0.8f);
+  private static final int MAX_AVG_VARIANCE = (int) ((1 << 8) * 0.42f);
+  private static final int MAX_INDIVIDUAL_VARIANCE = (int) ((1 << 8) * 0.8f);
+  private static final int SKEW_THRESHOLD = 2;
+
   // B S B S B S B S Bar/Space pattern
-  private static final int[] START_PATTERN = {8, 1, 1, 1, 1, 1, 1, 3}; // 11111111
-  // 0 1
-  // 0 1
-  // 0 1
-  // 000
+  // 11111111 0 1 0 1 0 1 000
+  private static final int[] START_PATTERN = {8, 1, 1, 1, 1, 1, 1, 3};
+
+  // 11111111 0 1 0 1 0 1 000
+  private static final int[] START_PATTERN_REVERSE = {3, 1, 1, 1, 1, 1, 1, 8};
+
+  // 1111111 0 1 000 1 0 1 00 1
+  private static final int[] STOP_PATTERN = {7, 1, 1, 3, 1, 1, 1, 2, 1};
 
   // B S B S B S B S B Bar/Space pattern
-  private static final int[] STOP_PATTERN_REVERSE = {1, 2, 1, 1, 1, 3, 1, 1,
-      7}; // 1111111 0 1 000 1 0 1 00 1
+  // 1111111 0 1 000 1 0 1 00 1
+  private static final int[] STOP_PATTERN_REVERSE = {1, 2, 1, 1, 1, 3, 1, 1, 7};
 
-  private final MonochromeBitmapSource image;
+  private final BinaryBitmap image;
 
-  public Detector(MonochromeBitmapSource image) {
+  public Detector(BinaryBitmap image) {
     this.image = image;
   }
 
   /**
-   * <p>
-   * Detects a PDF417 Code in an image, simply.
-   * </p>
+   * <p>Detects a PDF417 Code in an image, simply.</p>
    *
-   * @return {@link DetectorResult} encapsulating results of detecting a PDF417
-   *         Code
+   * @return {@link DetectorResult} encapsulating results of detecting a PDF417 Code
    * @throws ReaderException if no QR Code can be found
    */
   public DetectorResult detect() throws ReaderException {
@@ -70,34 +69,28 @@ public final class Detector {
   }
 
   /**
-   * <p>
-   * Detects a PDF417 Code in an image, simply.
-   * </p>
+   * <p>Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.</p>
    *
    * @param hints optional hints to detector
-   * @return {@link DetectorResult} encapsulating results of detecting a PDF417
-   *         Code
+   * @return {@link DetectorResult} encapsulating results of detecting a PDF417 Code
    * @throws ReaderException if no PDF417 Code can be found
    */
   public DetectorResult detect(Hashtable hints) throws ReaderException {
-    if (!BlackPointEstimationMethod.TWO_D_SAMPLING.equals(image
-        .getLastEstimationMethod())) {
-      image.estimateBlackPoint(BlackPointEstimationMethod.TWO_D_SAMPLING, 0);
-    }
+    // Fetch the 1 bit matrix once up front.
+    BitMatrix matrix = image.getBlackMatrix();
 
-    ResultPoint[] vertices = findVertices(image);
-    if (vertices == null) { // Couldn't find the vertices
+    // Try to find the vertices assuming the image is upright.
+    ResultPoint[] vertices = findVertices(matrix);
+    if (vertices == null) {
       // Maybe the image is rotated 180 degrees?
-      vertices = findVertices180(image);
-      /*
-      * // Don't need this because the PDF417 code won't fit into // the
-      * camera view finder when it is rotated. if (vertices == null) { //
-      * Couldn't find the vertices // Maybe the image is rotated 90 degrees?
-      * vertices = findVertices90(image); if (vertices == null) { //
-      * Couldn't find the vertices // Maybe the image is rotated 270
-      * degrees? vertices = findVertices270(image); } }
-      */
+      vertices = findVertices180(matrix);
+      if (vertices != null) {
+        correctCodeWordVertices(vertices, true);
+      }
+    } else {
+      correctCodeWordVertices(vertices, false);
     }
+
     if (vertices != null) {
       float moduleWidth = computeModuleWidth(vertices);
       if (moduleWidth < 1.0f) {
@@ -107,10 +100,9 @@ public final class Detector {
       int dimension = computeDimension(vertices[4], vertices[6],
           vertices[5], vertices[7], moduleWidth);
 
-      // Deskew and sample image
-      BitMatrix bits = sampleGrid(image, vertices[4], vertices[5],
+      // Deskew and sample image.
+      BitMatrix bits = sampleGrid(matrix, vertices[4], vertices[5],
           vertices[6], vertices[7], dimension);
-      //bits.setModuleWidth(moduleWidth);
       return new DetectorResult(bits, new ResultPoint[]{vertices[4],
           vertices[5], vertices[6], vertices[7]});
     } else {
@@ -120,29 +112,33 @@ public final class Detector {
 
   /**
    * Locate the vertices and the codewords area of a black blob using the Start
-   * and Stop patterns as locators.
+   * and Stop patterns as locators. Assumes that the barcode begins in the left half
+   * of the image, and ends in the right half.
+   * TODO: Fix this assumption, allowing the barcode to be anywhere in the image.
+   * TODO: Scanning every row is very expensive. We should only do this for TRY_HARDER.
    *
-   * @param image the scanned barcode image.
-   * @return the an array containing the vertices. vertices[0] x, y top left
-   *         barcode vertices[1] x, y bottom left barcode vertices[2] x, y top
-   *         right barcode vertices[3] x, y bottom right barcode vertices[4] x,
-   *         y top left codeword area vertices[5] x, y bottom left codeword
-   *         area vertices[6] x, y top right codeword area vertices[7] x, y
-   *         bottom right codeword area
+   * @param matrix the scanned barcode image.
+   * @return an array containing the vertices:
+   *           vertices[0] x, y top left barcode
+   *           vertices[1] x, y bottom left barcode
+   *           vertices[2] x, y top right barcode
+   *           vertices[3] x, y bottom right barcode
+   *           vertices[4] x, y top left codeword area
+   *           vertices[5] x, y bottom left codeword area
+   *           vertices[6] x, y top right codeword area
+   *           vertices[7] x, y bottom right codeword area
    */
-  private static ResultPoint[] findVertices(MonochromeBitmapSource image) {
-    int height = image.getHeight();
-    int width = image.getWidth();
+  private static ResultPoint[] findVertices(BitMatrix matrix) {
+    int height = matrix.getHeight();
+    int width = matrix.getWidth();
+    int halfWidth = width >> 1;
 
     ResultPoint[] result = new ResultPoint[8];
-    BitArray row = null;
     boolean found = false;
 
-    int[] loc = null;
     // Top Left
     for (int i = 0; i < height; i++) {
-      row = image.getBlackRow(i, null, 0, width / 4);
-      loc = findGuardPattern(row, 0, START_PATTERN);
+      int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, START_PATTERN);
       if (loc != null) {
         result[0] = new ResultPoint(loc[0], i);
         result[4] = new ResultPoint(loc[1], i);
@@ -154,8 +150,7 @@ public final class Detector {
     if (found) { // Found the Top Left vertex
       found = false;
       for (int i = height - 1; i > 0; i--) {
-        row = image.getBlackRow(i, null, 0, width / 4);
-        loc = findGuardPattern(row, 0, START_PATTERN);
+        int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, START_PATTERN);
         if (loc != null) {
           result[1] = new ResultPoint(loc[0], i);
           result[5] = new ResultPoint(loc[1], i);
@@ -168,12 +163,10 @@ public final class Detector {
     if (found) { // Found the Bottom Left vertex
       found = false;
       for (int i = 0; i < height; i++) {
-        row = image.getBlackRow(i, null, (width * 3) / 4, width / 4);
-        row.reverse();
-        loc = findGuardPattern(row, 0, STOP_PATTERN_REVERSE);
+        int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, false, STOP_PATTERN);
         if (loc != null) {
-          result[2] = new ResultPoint(width - loc[0], i);
-          result[6] = new ResultPoint(width - loc[1], i);
+          result[2] = new ResultPoint(loc[1], i);
+          result[6] = new ResultPoint(loc[0], i);
           found = true;
           break;
         }
@@ -183,12 +176,10 @@ public final class Detector {
     if (found) { // Found the Top right vertex
       found = false;
       for (int i = height - 1; i > 0; i--) {
-        row = image.getBlackRow(i, null, (width * 3) / 4, width / 4);
-        row.reverse();
-        loc = findGuardPattern(row, 0, STOP_PATTERN_REVERSE);
+        int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, false, STOP_PATTERN);
         if (loc != null) {
-          result[3] = new ResultPoint(width - loc[0], i);
-          result[7] = new ResultPoint(width - loc[1], i);
+          result[3] = new ResultPoint(loc[1], i);
+          result[7] = new ResultPoint(loc[0], i);
           found = true;
           break;
         }
@@ -202,32 +193,34 @@ public final class Detector {
    * and Stop patterns as locators. This assumes that the image is rotated 180
    * degrees and if it locates the start and stop patterns at it will re-map
    * the vertices for a 0 degree rotation.
+   * TODO: Change assumption about barcode location.
+   * TODO: Scanning every row is very expensive. We should only do this for TRY_HARDER.
    *
-   * @param image the scanned barcode image.
-   * @return the an array containing the vertices. vertices[0] x, y top left
-   *         barcode vertices[1] x, y bottom left barcode vertices[2] x, y top
-   *         right barcode vertices[3] x, y bottom right barcode vertices[4] x,
-   *         y top left codeword area vertices[5] x, y bottom left codeword
-   *         area vertices[6] x, y top right codeword area vertices[7] x, y
-   *         bottom right codeword area
+   * @param matrix the scanned barcode image.
+   * @return an array containing the vertices:
+   *           vertices[0] x, y top left barcode
+   *           vertices[1] x, y bottom left barcode
+   *           vertices[2] x, y top right barcode
+   *           vertices[3] x, y bottom right barcode
+   *           vertices[4] x, y top left codeword area
+   *           vertices[5] x, y bottom left codeword area
+   *           vertices[6] x, y top right codeword area
+   *           vertices[7] x, y bottom right codeword area
    */
-  private static ResultPoint[] findVertices180(MonochromeBitmapSource image) {
-    int height = image.getHeight();
-    int width = image.getWidth();
+  private static ResultPoint[] findVertices180(BitMatrix matrix) {
+    int height = matrix.getHeight();
+    int width = matrix.getWidth();
+    int halfWidth = width >> 1;
 
     ResultPoint[] result = new ResultPoint[8];
-    BitArray row = null;
     boolean found = false;
 
-    int[] loc = null;
     // Top Left
     for (int i = height - 1; i > 0; i--) {
-      row = image.getBlackRow(i, null, 0, width / 4);
-      row.reverse();
-      loc = findGuardPattern(row, 0, START_PATTERN);
+      int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
       if (loc != null) {
-        result[0] = new ResultPoint(width - loc[0], i);
-        result[4] = new ResultPoint(width - loc[1], i);
+        result[0] = new ResultPoint(loc[1], i);
+        result[4] = new ResultPoint(loc[0], i);
         found = true;
         break;
       }
@@ -236,12 +229,10 @@ public final class Detector {
     if (found) { // Found the Top Left vertex
       found = false;
       for (int i = 0; i < height; i++) {
-        row = image.getBlackRow(i, null, 0, width / 4);
-        row.reverse();
-        loc = findGuardPattern(row, 0, START_PATTERN);
+        int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE);
         if (loc != null) {
-          result[1] = new ResultPoint(width - loc[0], i);
-          result[5] = new ResultPoint(width - loc[1], i);
+          result[1] = new ResultPoint(loc[1], i);
+          result[5] = new ResultPoint(loc[0], i);
           found = true;
           break;
         }
@@ -251,8 +242,7 @@ public final class Detector {
     if (found) { // Found the Bottom Left vertex
       found = false;
       for (int i = height - 1; i > 0; i--) {
-        row = image.getBlackRow(i, null, (width * 3) / 4, width / 4);
-        loc = findGuardPattern(row, 0, STOP_PATTERN_REVERSE);
+        int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
         if (loc != null) {
           result[2] = new ResultPoint(loc[0], i);
           result[6] = new ResultPoint(loc[1], i);
@@ -265,8 +255,7 @@ public final class Detector {
     if (found) { // Found the Top Right vertex
       found = false;
       for (int i = 0; i < height; i++) {
-        row = image.getBlackRow(i, null, (width * 3) / 4, width / 4);
-        loc = findGuardPattern(row, 0, STOP_PATTERN_REVERSE);
+        int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE);
         if (loc != null) {
           result[3] = new ResultPoint(loc[0], i);
           result[7] = new ResultPoint(loc[1], i);
@@ -275,23 +264,72 @@ public final class Detector {
         }
       }
     }
-    if (found) {
-      return result;
-    } else {
-      return null;
+    return found ? result : null;
+  }
+
+  /**
+   * Because we scan horizontally to detect the start and stop patterns, the vertical component of
+   * the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.
+   * This method moves those points back onto the edges of the theoretically perfect bounding
+   * quadrilateral if needed.
+   *
+   * @param vertices The eight vertices located by findVertices().
+   */
+  private static void correctCodeWordVertices(ResultPoint[] vertices, boolean upsideDown) {
+    float skew = vertices[4].getY() - vertices[6].getY();
+    if (upsideDown) {
+      skew = -skew;
+    }
+    if (skew > SKEW_THRESHOLD) {
+      // Fix v4
+      float length = vertices[4].getX() - vertices[0].getX();
+      float deltax = vertices[6].getX() - vertices[0].getX();
+      float deltay = vertices[6].getY() - vertices[0].getY();
+      float correction = length * deltay / deltax;
+      vertices[4] = new ResultPoint(vertices[4].getX(), vertices[4].getY() + correction);
+    } else if (-skew > SKEW_THRESHOLD) {
+      // Fix v6
+      float length = vertices[2].getX() - vertices[6].getX();
+      float deltax = vertices[2].getX() - vertices[4].getX();
+      float deltay = vertices[2].getY() - vertices[4].getY();
+      float correction = length * deltay / deltax;
+      vertices[6] = new ResultPoint(vertices[6].getX(), vertices[6].getY() - correction);
+    }
+
+    skew = vertices[7].getY() - vertices[5].getY();
+    if (upsideDown) {
+      skew = -skew;
+    }
+    if (skew > SKEW_THRESHOLD) {
+      // Fix v5
+      float length = vertices[5].getX() - vertices[1].getX();
+      float deltax = vertices[7].getX() - vertices[1].getX();
+      float deltay = vertices[7].getY() - vertices[1].getY();
+      float correction = length * deltay / deltax;
+      vertices[5] = new ResultPoint(vertices[5].getX(), vertices[5].getY() + correction);
+    } else if (-skew > SKEW_THRESHOLD) {
+      // Fix v7
+      float length = vertices[3].getX() - vertices[7].getX();
+      float deltax = vertices[3].getX() - vertices[5].getX();
+      float deltay = vertices[3].getY() - vertices[5].getY();
+      float correction = length * deltay / deltax;
+      vertices[7] = new ResultPoint(vertices[7].getX(), vertices[7].getY() - correction);
     }
   }
 
   /**
-   * <p>
-   * Estimates module size (pixels in a module) based on the Start and End
+   * <p>Estimates module size (pixels in a module) based on the Start and End
    * finder patterns.</p>
    *
-   * @param vertices [] vertices[0] x, y top left barcode vertices[1] x, y bottom
-   *                 left barcode vertices[2] x, y top right barcode vertices[3] x, y
-   *                 bottom right barcode vertices[4] x, y top left Codeword area
-   *                 vertices[5] x, y bottom left Codeword area vertices[6] x, y top
-   *                 right Codeword area vertices[7] x, y bottom right Codeword area
+   * @param vertices an array of vertices:
+   *           vertices[0] x, y top left barcode
+   *           vertices[1] x, y bottom left barcode
+   *           vertices[2] x, y top right barcode
+   *           vertices[3] x, y bottom right barcode
+   *           vertices[4] x, y top left codeword area
+   *           vertices[5] x, y bottom left codeword area
+   *           vertices[6] x, y top right codeword area
+   *           vertices[7] x, y bottom right codeword area
    * @return the module size.
    */
   private static float computeModuleWidth(ResultPoint[] vertices) {
@@ -315,16 +353,10 @@ public final class Detector {
    * @param moduleWidth estimated module size
    * @return the number of modules in a row.
    */
-  private static int computeDimension(ResultPoint topLeft,
-                                      ResultPoint topRight, ResultPoint bottomLeft, ResultPoint bottomRight,
-                                      float moduleWidth) {
-
-    int topRowDimension = round(ResultPoint
-        .distance(topLeft, topRight)
-        / moduleWidth);
-    int bottomRowDimension = round(ResultPoint.distance(bottomLeft,
-        bottomRight)
-        / moduleWidth);
+  private static int computeDimension(ResultPoint topLeft, ResultPoint topRight,
+      ResultPoint bottomLeft, ResultPoint bottomRight, float moduleWidth) {
+    int topRowDimension = round(ResultPoint.distance(topLeft, topRight) / moduleWidth);
+    int bottomRowDimension = round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth);
     return ((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17;
     /*
     * int topRowDimension = round(ResultPoint.distance(topLeft,
@@ -337,15 +369,15 @@ public final class Detector {
     */
   }
 
-  private static BitMatrix sampleGrid(MonochromeBitmapSource image,
-                                      ResultPoint topLeft, ResultPoint bottomLeft, ResultPoint topRight,
-                                      ResultPoint bottomRight, int dimension) throws ReaderException {
+  private static BitMatrix sampleGrid(BitMatrix matrix, ResultPoint topLeft,
+      ResultPoint bottomLeft, ResultPoint topRight, ResultPoint bottomRight, int dimension)
+      throws ReaderException {
 
-    // Note that unlike in the QR Code sampler, we didn't find the center of
-    // modules, but the
+    // Note that unlike the QR Code sampler, we didn't find the center of modules, but the
     // very corners. So there is no 0.5f here; 0.0f is right.
     GridSampler sampler = GridSampler.getInstance();
-    return sampler.sampleGrid(image, dimension, 0.0f, // p1ToX
+
+    return sampler.sampleGrid(matrix, dimension, 0.0f, // p1ToX
         0.0f, // p1ToY
         dimension, // p2ToX
         0.0f, // p2ToY
@@ -361,7 +393,6 @@ public final class Detector {
         bottomRight.getY(), // p3FromY
         bottomLeft.getX(), // p4FromX
         bottomLeft.getY()); // p4FromY
-
   }
 
   /**
@@ -373,29 +404,31 @@ public final class Detector {
   }
 
   /**
-   * @param row       row of black/white values to search
-   * @param rowOffset position to start search
-   * @param pattern   pattern of counts of number of black and white pixels that are
-   *                  being searched for as a pattern
-   * @return start/end horizontal offset of guard pattern, as an array of two
-   *         ints.
+   * @param matrix row of black/white values to search
+   * @param column x position to start search
+   * @param row y position to start search
+   * @param width the number of pixels to search on this row
+   * @param pattern pattern of counts of number of black and white pixels that are
+   *                 being searched for as a pattern
+   * @return start/end horizontal offset of guard pattern, as an array of two ints.
    */
-  static int[] findGuardPattern(BitArray row, int rowOffset, int[] pattern) {
+  private static int[] findGuardPattern(BitMatrix matrix, int column, int row, int width,
+      boolean whiteFirst, int[] pattern) {
     int patternLength = pattern.length;
+    // TODO: Find a way to cache this array, as this method is called hundreds of times
+    // per image, and we want to allocate as seldom as possible.
     int[] counters = new int[patternLength];
-    int width = row.getSize();
-    boolean isWhite = false;
+    boolean isWhite = whiteFirst;
 
     int counterPosition = 0;
-    int patternStart = rowOffset;
-    for (int x = rowOffset; x < width; x++) {
-      boolean pixel = row.get(x);
+    int patternStart = column;
+    for (int x = column; x < column + width; x++) {
+      boolean pixel = matrix.get(x, row);
       if (pixel ^ isWhite) {
         counters[counterPosition]++;
       } else {
         if (counterPosition == patternLength - 1) {
-          if (patternMatchVariance(counters, pattern,
-              MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
+          if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
             return new int[]{patternStart, x};
           }
           patternStart += counters[0] + counters[1];
@@ -421,8 +454,8 @@ public final class Detector {
    * the total variance from the expected pattern proportions across all
    * pattern elements, to the length of the pattern.
    *
-   * @param counters              observed counters
-   * @param pattern               expected pattern
+   * @param counters observed counters
+   * @param pattern expected pattern
    * @param maxIndividualVariance The most any counter can differ before we give up
    * @return ratio of total variance between counters and pattern compared to
    *         total pattern size, where the ratio has been multiplied by 256.
@@ -430,8 +463,7 @@ public final class Detector {
    *         variance between counters and patterns equals the pattern length,
    *         higher values mean even more variance
    */
-  public static int patternMatchVariance(int[] counters, int[] pattern,
-                                         int maxIndividualVariance) {
+  private static int patternMatchVariance(int[] counters, int[] pattern, int maxIndividualVariance) {
     int numCounters = counters.length;
     int total = 0;
     int patternLength = 0;
@@ -441,15 +473,12 @@ public final class Detector {
     }
     if (total < patternLength) {
       // If we don't even have one pixel per unit of bar width, assume this
-      // is too small
-      // to reliably match, so fail:
+      // is too small to reliably match, so fail:
       return Integer.MAX_VALUE;
     }
-    // We're going to fake floating-point math in integers. We just need to
-    // use more bits.
-    // Scale up patternLength so that intermediate values below like
-    // scaledCounter will have
-    // more "significant digits"
+    // We're going to fake floating-point math in integers. We just need to use more bits.
+    // Scale up patternLength so that intermediate values below like scaledCounter will have
+    // more "significant digits".
     int unitBarWidth = (total << 8) / patternLength;
     maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> 8;
 
@@ -457,8 +486,7 @@ public final class Detector {
     for (int x = 0; x < numCounters; x++) {
       int counter = counters[x] << 8;
       int scaledPattern = pattern[x] * unitBarWidth;
-      int variance = counter > scaledPattern ? counter - scaledPattern
-          : scaledPattern - counter;
+      int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
       if (variance > maxIndividualVariance) {
         return Integer.MAX_VALUE;
       }