1 /* 2 * Copyright 2007 ZXing authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.zxing.qrcode.decoder; 18 19 import com.google.zxing.common.BitMatrix; 20 21 /** 22 * <p>Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations 23 * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix, 24 * including areas used for finder patterns, timing patterns, etc. These areas should be unused 25 * after the point they are unmasked anyway.</p> 26 * 27 * <p>Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position 28 * and j is row position. In fact, as the text says, i is row position and j is column position.</p> 29 * 30 * @author Sean Owen 31 */ 32 enum DataMask { 33 34 // See ISO 18004:2006 6.8.1 35 36 /** 37 * 000: mask bits for which (x + y) mod 2 == 0 38 */ DATA_MASK_000()39 DATA_MASK_000() { 40 @Override 41 boolean isMasked(int i, int j) { 42 return ((i + j) & 0x01) == 0; 43 } 44 }, 45 46 /** 47 * 001: mask bits for which x mod 2 == 0 48 */ DATA_MASK_001()49 DATA_MASK_001() { 50 @Override 51 boolean isMasked(int i, int j) { 52 return (i & 0x01) == 0; 53 } 54 }, 55 56 /** 57 * 010: mask bits for which y mod 3 == 0 58 */ DATA_MASK_010()59 DATA_MASK_010() { 60 @Override 61 boolean isMasked(int i, int j) { 62 return j % 3 == 0; 63 } 64 }, 65 66 /** 67 * 011: mask bits for which (x + y) mod 3 == 0 68 */ DATA_MASK_011()69 DATA_MASK_011() { 70 @Override 71 boolean isMasked(int i, int j) { 72 return (i + j) % 3 == 0; 73 } 74 }, 75 76 /** 77 * 100: mask bits for which (x/2 + y/3) mod 2 == 0 78 */ DATA_MASK_100()79 DATA_MASK_100() { 80 @Override 81 boolean isMasked(int i, int j) { 82 return (((i / 2) + (j / 3)) & 0x01) == 0; 83 } 84 }, 85 86 /** 87 * 101: mask bits for which xy mod 2 + xy mod 3 == 0 88 * equivalently, such that xy mod 6 == 0 89 */ DATA_MASK_101()90 DATA_MASK_101() { 91 @Override 92 boolean isMasked(int i, int j) { 93 return (i * j) % 6 == 0; 94 } 95 }, 96 97 /** 98 * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0 99 * equivalently, such that xy mod 6 < 3 100 */ DATA_MASK_110()101 DATA_MASK_110() { 102 @Override 103 boolean isMasked(int i, int j) { 104 return ((i * j) % 6) < 3; 105 } 106 }, 107 108 /** 109 * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0 110 * equivalently, such that (x + y + xy mod 3) mod 2 == 0 111 */ DATA_MASK_111()112 DATA_MASK_111() { 113 @Override 114 boolean isMasked(int i, int j) { 115 return ((i + j + ((i * j) % 3)) & 0x01) == 0; 116 } 117 }; 118 119 // End of enum constants. 120 121 122 /** 123 * <p>Implementations of this method reverse the data masking process applied to a QR Code and 124 * make its bits ready to read.</p> 125 * 126 * @param bits representation of QR Code bits 127 * @param dimension dimension of QR Code, represented by bits, being unmasked 128 */ unmaskBitMatrix(BitMatrix bits, int dimension)129 final void unmaskBitMatrix(BitMatrix bits, int dimension) { 130 for (int i = 0; i < dimension; i++) { 131 for (int j = 0; j < dimension; j++) { 132 if (isMasked(i, j)) { 133 bits.flip(j, i); 134 } 135 } 136 } 137 } 138 isMasked(int i, int j)139 abstract boolean isMasked(int i, int j); 140 141 } 142