Issue 489 update the port
[zxing.git] / cpp / core / src / zxing / qrcode / decoder / DataMask.cpp
1 /*
2  *  DataMask.cpp
3  *  zxing
4  *
5  *  Created by Christian Brunschen on 19/05/2008.
6  *  Copyright 2008 ZXing authors All rights reserved.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <zxing/qrcode/decoder/DataMask.h>
22
23 #include <zxing/common/IllegalArgumentException.h>
24
25 namespace zxing {
26 namespace qrcode {
27
28 using namespace std;
29
30 DataMask::DataMask() {
31 }
32
33 DataMask::~DataMask() {
34 }
35
36 vector<Ref<DataMask> > DataMask::DATA_MASKS;
37 static int N_DATA_MASKS = DataMask::buildDataMasks();
38
39 DataMask &DataMask::forReference(int reference) {
40   if (reference < 0 || reference > 7) {
41     throw IllegalArgumentException("reference must be between 0 and 7");
42   }
43   return *DATA_MASKS[reference];
44 }
45
46 void DataMask::unmaskBitMatrix(BitMatrix& bits, size_t dimension) {
47   for (size_t y = 0; y < dimension; y++) {
48     for (size_t x = 0; x < dimension; x++) {
49       // TODO: check why the coordinates have to be swapped
50       if (isMasked(y, x)) {
51         bits.flip(x, y);
52       }
53     }
54   }
55 }
56
57 /**
58  * 000: mask bits for which (x + y) mod 2 == 0
59  */
60 class DataMask000 : public DataMask {
61 public:
62   bool isMasked(size_t x, size_t y) {
63     //          return ((x + y) & 0x01) == 0;
64     return ((x + y) % 2) == 0;
65   }
66 };
67
68 /**
69  * 001: mask bits for which x mod 2 == 0
70  */
71 class DataMask001 : public DataMask {
72 public:
73   bool isMasked(size_t x, size_t y) {
74     //          return (x & 0x01) == 0;
75     return (x % 2) == 0;
76   }
77 };
78
79 /**
80  * 010: mask bits for which y mod 3 == 0
81  */
82 class DataMask010 : public DataMask {
83 public:
84   bool isMasked(size_t x, size_t y) {
85     return y % 3 == 0;
86   }
87 };
88
89 /**
90  * 011: mask bits for which (x + y) mod 3 == 0
91  */
92 class DataMask011 : public DataMask {
93 public:
94   bool isMasked(size_t x, size_t y) {
95     return (x + y) % 3 == 0;
96   }
97 };
98
99 /**
100  * 100: mask bits for which (x/2 + y/3) mod 2 == 0
101  */
102 class DataMask100 : public DataMask {
103 public:
104   bool isMasked(size_t x, size_t y) {
105     //          return (((x >> 1) + (y / 3)) & 0x01) == 0;
106     return (((x >> 1) + (y / 3)) % 2) == 0;
107   }
108 };
109
110 /**
111  * 101: mask bits for which xy mod 2 + xy mod 3 == 0
112  */
113 class DataMask101 : public DataMask {
114 public:
115   bool isMasked(size_t x, size_t y) {
116     size_t temp = x * y;
117     //          return (temp & 0x01) + (temp % 3) == 0;
118     return (temp % 2) + (temp % 3) == 0;
119
120   }
121 };
122
123 /**
124  * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
125  */
126 class DataMask110 : public DataMask {
127 public:
128   bool isMasked(size_t x, size_t y) {
129     size_t temp = x * y;
130     //          return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
131     return (((temp % 2) + (temp % 3)) % 2) == 0;
132   }
133 };
134
135 /**
136  * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
137  */
138 class DataMask111 : public DataMask {
139 public:
140   bool isMasked(size_t x, size_t y) {
141     //          return ((((x + y) & 0x01) + ((x * y) % 3)) & 0x01) == 0;
142     return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0;
143   }
144 };
145
146 int DataMask::buildDataMasks() {
147   DATA_MASKS.push_back(Ref<DataMask> (new DataMask000()));
148   DATA_MASKS.push_back(Ref<DataMask> (new DataMask001()));
149   DATA_MASKS.push_back(Ref<DataMask> (new DataMask010()));
150   DATA_MASKS.push_back(Ref<DataMask> (new DataMask011()));
151   DATA_MASKS.push_back(Ref<DataMask> (new DataMask100()));
152   DATA_MASKS.push_back(Ref<DataMask> (new DataMask101()));
153   DATA_MASKS.push_back(Ref<DataMask> (new DataMask110()));
154   DATA_MASKS.push_back(Ref<DataMask> (new DataMask111()));
155   return DATA_MASKS.size();
156 }
157
158 }
159 }