--- /dev/null
+/*\r
+ * Copyright 2007 Google Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package com.google.zxing.qrcode.decoder;\r
+\r
+/**\r
+ * Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations\r
+ * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,\r
+ * including areas used for finder patterns, timing patterns, etc. These areas should be unused\r
+ * after the point they are unmasked anyway.\r
+ *\r
+ * Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position\r
+ * and j is row position. In fact, as the text says, i is row position and j is column position.\r
+ *\r
+ * @author srowen@google.com (Sean Owen)\r
+ */\r
+abstract class DataMask {\r
+\r
+ /**\r
+ * See ISO 18004:2006 6.8.1\r
+ */\r
+ private static final DataMask[] DATA_MASKS = new DataMask[]{\r
+ new DataMask000(),\r
+ new DataMask001(),\r
+ new DataMask010(),\r
+ new DataMask011(),\r
+ new DataMask100(),\r
+ new DataMask101(),\r
+ new DataMask110(),\r
+ new DataMask111(),\r
+ };\r
+\r
+ private DataMask() {\r
+ }\r
+\r
+ abstract void unmaskBitMatrix(int[] bits, int dimension);\r
+\r
+ static DataMask forReference(int reference) {\r
+ if (reference < 0 || reference > 7) {\r
+ throw new IllegalArgumentException();\r
+ }\r
+ return DATA_MASKS[reference];\r
+ }\r
+\r
+ /**\r
+ * 000: mask bits for which (i + j) mod 2 == 0\r
+ */\r
+ private static class DataMask000 extends DataMask {\r
+ private static final int BITMASK = 0x55555555; // = 010101...\r
+\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ // This one's easy. Because the dimension of BitMatrix is always odd,\r
+ // we can merely flip every other bit\r
+ int max = bits.length;\r
+ for (int i = 0; i < max; i++) {\r
+ bits[i] ^= BITMASK;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 001: mask bits for which j mod 2 == 0\r
+ */\r
+ private static class DataMask001 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ for (int i = 0; i < dimension; i++) {\r
+ if ((i & 0x01) == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 010: mask bits for which j mod 3 == 0\r
+ */\r
+ private static class DataMask010 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ boolean columnMasked = j % 3 == 0;\r
+ for (int i = 0; i < dimension; i++) {\r
+ if (columnMasked) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 011: mask bits for which (i + j) mod 3 == 0\r
+ */\r
+ private static class DataMask011 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ for (int i = 0; i < dimension; i++) {\r
+ if ((i + j) % 3 == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 100: mask bits for which (i/2 + j/3) mod 2 == 0\r
+ */\r
+ private static class DataMask100 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ int jComponent = j / 3;\r
+ for (int i = 0; i < dimension; i++) {\r
+ if (((i >> 1 + jComponent) & 0x01) == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 101: mask bits for which ij mod 2 + ij mod 3 == 0\r
+ */\r
+ private static class DataMask101 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ for (int i = 0; i < dimension; i++) {\r
+ int product = i * j;\r
+ if (((product & 0x01) == 0) && product % 3 == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 110: mask bits for which (ij mod 2 + ij mod 3) mod 2 == 0\r
+ */\r
+ private static class DataMask110 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ for (int i = 0; i < dimension; i++) {\r
+ int product = i * j;\r
+ if ((((product & 0x01) + product % 3) & 0x01) == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * 111: mask bits for which ((i+j)mod 2 + ij mod 3) mod 2 == 0\r
+ */\r
+ private static class DataMask111 extends DataMask {\r
+ void unmaskBitMatrix(int[] bits, int dimension) {\r
+ int bitMask = 0;\r
+ int count = 0;\r
+ int offset = 0;\r
+ for (int j = 0; j < dimension; j++) {\r
+ for (int i = 0; i < dimension; i++) {\r
+ if (((((i + j) & 0x01) + (i * j) % 3) & 0x01) == 0) {\r
+ bitMask |= 1 << count;\r
+ }\r
+ if (++count == 32) {\r
+ bits[offset++] ^= bitMask;\r
+ count = 0;\r
+ bitMask = 0;\r
+ }\r
+ }\r
+ }\r
+ bits[offset] ^= bitMask;\r
+ }\r
+ }\r
+}\r