2 * Copyright 2007 Google Inc.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package com.google.zxing.qrcode.decoder;
\r
20 * Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
\r
21 * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
\r
22 * including areas used for finder patterns, timing patterns, etc. These areas should be unused
\r
23 * after the point they are unmasked anyway.
\r
25 * Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
\r
26 * and j is row position. In fact, as the text says, i is row position and j is column position.
\r
28 * @author srowen@google.com (Sean Owen)
\r
30 abstract class DataMask {
\r
33 * See ISO 18004:2006 6.8.1
\r
35 private static final DataMask[] DATA_MASKS = new DataMask[]{
\r
46 private DataMask() {
\r
49 abstract void unmaskBitMatrix(int[] bits, int dimension);
\r
51 static DataMask forReference(int reference) {
\r
52 if (reference < 0 || reference > 7) {
\r
53 throw new IllegalArgumentException();
\r
55 return DATA_MASKS[reference];
\r
59 * 000: mask bits for which (i + j) mod 2 == 0
\r
61 private static class DataMask000 extends DataMask {
\r
62 private static final int BITMASK = 0x55555555; // = 010101...
\r
64 void unmaskBitMatrix(int[] bits, int dimension) {
\r
65 // This one's easy. Because the dimension of BitMatrix is always odd,
\r
66 // we can merely flip every other bit
\r
67 int max = bits.length;
\r
68 for (int i = 0; i < max; i++) {
\r
75 * 001: mask bits for which j mod 2 == 0
\r
77 private static class DataMask001 extends DataMask {
\r
78 void unmaskBitMatrix(int[] bits, int dimension) {
\r
82 for (int j = 0; j < dimension; j++) {
\r
83 for (int i = 0; i < dimension; i++) {
\r
84 if ((i & 0x01) == 0) {
\r
85 bitMask |= 1 << count;
\r
87 if (++count == 32) {
\r
88 bits[offset++] ^= bitMask;
\r
94 bits[offset] ^= bitMask;
\r
99 * 010: mask bits for which j mod 3 == 0
\r
101 private static class DataMask010 extends DataMask {
\r
102 void unmaskBitMatrix(int[] bits, int dimension) {
\r
106 for (int j = 0; j < dimension; j++) {
\r
107 boolean columnMasked = j % 3 == 0;
\r
108 for (int i = 0; i < dimension; i++) {
\r
109 if (columnMasked) {
\r
110 bitMask |= 1 << count;
\r
112 if (++count == 32) {
\r
113 bits[offset++] ^= bitMask;
\r
119 bits[offset] ^= bitMask;
\r
124 * 011: mask bits for which (i + j) mod 3 == 0
\r
126 private static class DataMask011 extends DataMask {
\r
127 void unmaskBitMatrix(int[] bits, int dimension) {
\r
131 for (int j = 0; j < dimension; j++) {
\r
132 for (int i = 0; i < dimension; i++) {
\r
133 if ((i + j) % 3 == 0) {
\r
134 bitMask |= 1 << count;
\r
136 if (++count == 32) {
\r
137 bits[offset++] ^= bitMask;
\r
143 bits[offset] ^= bitMask;
\r
148 * 100: mask bits for which (i/2 + j/3) mod 2 == 0
\r
150 private static class DataMask100 extends DataMask {
\r
151 void unmaskBitMatrix(int[] bits, int dimension) {
\r
155 for (int j = 0; j < dimension; j++) {
\r
156 int jComponent = j / 3;
\r
157 for (int i = 0; i < dimension; i++) {
\r
158 if (((i >> 1 + jComponent) & 0x01) == 0) {
\r
159 bitMask |= 1 << count;
\r
161 if (++count == 32) {
\r
162 bits[offset++] ^= bitMask;
\r
168 bits[offset] ^= bitMask;
\r
173 * 101: mask bits for which ij mod 2 + ij mod 3 == 0
\r
175 private static class DataMask101 extends DataMask {
\r
176 void unmaskBitMatrix(int[] bits, int dimension) {
\r
180 for (int j = 0; j < dimension; j++) {
\r
181 for (int i = 0; i < dimension; i++) {
\r
182 int product = i * j;
\r
183 if (((product & 0x01) == 0) && product % 3 == 0) {
\r
184 bitMask |= 1 << count;
\r
186 if (++count == 32) {
\r
187 bits[offset++] ^= bitMask;
\r
193 bits[offset] ^= bitMask;
\r
198 * 110: mask bits for which (ij mod 2 + ij mod 3) mod 2 == 0
\r
200 private static class DataMask110 extends DataMask {
\r
201 void unmaskBitMatrix(int[] bits, int dimension) {
\r
205 for (int j = 0; j < dimension; j++) {
\r
206 for (int i = 0; i < dimension; i++) {
\r
207 int product = i * j;
\r
208 if ((((product & 0x01) + product % 3) & 0x01) == 0) {
\r
209 bitMask |= 1 << count;
\r
211 if (++count == 32) {
\r
212 bits[offset++] ^= bitMask;
\r
218 bits[offset] ^= bitMask;
\r
223 * 111: mask bits for which ((i+j)mod 2 + ij mod 3) mod 2 == 0
\r
225 private static class DataMask111 extends DataMask {
\r
226 void unmaskBitMatrix(int[] bits, int dimension) {
\r
230 for (int j = 0; j < dimension; j++) {
\r
231 for (int i = 0; i < dimension; i++) {
\r
232 if (((((i + j) & 0x01) + (i * j) % 3) & 0x01) == 0) {
\r
233 bitMask |= 1 << count;
\r
235 if (++count == 32) {
\r
236 bits[offset++] ^= bitMask;
\r
242 bits[offset] ^= bitMask;
\r