Standardize and update all copyright statements to name "ZXing authors" as suggested...
[zxing.git] / cpp / core / src / 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 "DataMask.h"
22 #include "../../common/IllegalArgumentException.h"
23
24 namespace qrcode {
25   namespace decoder {
26     
27     
28     vector<DataMask*> DataMask::DATA_MASKS;
29     static int N_DATA_MASKS = DataMask::buildDataMasks();
30     
31     DataMask &DataMask::forReference(int reference) {
32       if (reference < 0 || reference > 7) {
33         throw new IllegalArgumentException("reference must be between 0 and 7");
34       }
35       return *DATA_MASKS[reference];
36     }
37     
38     
39     class DataMask000 : public DataMask {
40     private:
41       static unsigned int BITMASK;
42     public:
43       DataMask000() { }
44       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
45                                    int dimension) {
46         size_t max = bits.size();
47         for (size_t i = 0; i < max; i++) {
48           bits[i] ^= BITMASK;
49         }
50       }
51     };
52     unsigned int DataMask000::BITMASK = 0x55555555U;    
53     
54     class DataMask001 : public DataMask {
55     public:
56       DataMask001() { }
57       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
58                                    int dimension) {
59         unsigned int bitMask = 0;
60         int count = 0;
61         int offset = 0;
62         for (int j = 0; j < dimension; j++) {
63           for (int i = 0; i < dimension; i++) {
64             if ((i & 0x01) == 0) {
65               bitMask |= 1 << count;
66             }
67             if (++count == 32) {
68               bits[offset++] ^= bitMask;
69               count = 0;
70               bitMask = 0;
71             }
72           }
73         }
74         bits[offset] ^= bitMask;
75       }
76     };
77     
78     
79     class DataMask010 : public DataMask {
80     public:
81       DataMask010() { }
82       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
83                                    int dimension) {
84         unsigned bitMask = 0;
85         int count = 0;
86         int offset = 0;
87         for (int j = 0; j < dimension; j++) {
88           bool columnMasked = j % 3 == 0;
89           for (int i = 0; i < dimension; i++) {
90             if (columnMasked) {
91               bitMask |= 1 << count;
92             }
93             if (++count == 32) {
94               bits[offset++] ^= bitMask;
95               count = 0;
96               bitMask = 0;
97             }
98           }
99         }
100         bits[offset] ^= bitMask;
101       }
102     };
103     
104     
105     class DataMask011 : public DataMask {
106     public:
107       DataMask011() { }
108       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
109                                    int dimension) {
110         unsigned int bitMask = 0;
111         int count = 0;
112         int offset = 0;
113         for (int j = 0; j < dimension; j++) {
114           for (int i = 0; i < dimension; i++) {
115             if ((i + j) % 3 == 0) {
116               bitMask |= 1 << count;
117             }
118             if (++count == 32) {
119               bits[offset++] ^= bitMask;
120               count = 0;
121               bitMask = 0;
122             }
123           }
124         }
125         bits[offset] ^= bitMask;
126       }
127     };
128     
129     
130     class DataMask100 : public DataMask {
131     public:
132       DataMask100() { }
133       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
134                                    int dimension) {
135         unsigned int bitMask = 0;
136         int count = 0;
137         int offset = 0;
138         for (int j = 0; j < dimension; j++) {
139           int jComponentParity = (j / 3) & 0x01;
140           for (int i = 0; i < dimension; i++) {
141             if (((i >> 1) & 0x01) == jComponentParity) {
142               bitMask |= 1 << count;
143             }
144             if (++count == 32) {
145               bits[offset++] ^= bitMask;
146               count = 0;
147               bitMask = 0;
148             }
149           }
150         }
151         bits[offset] ^= bitMask;
152       }
153     };
154     
155     
156     class DataMask101 : public DataMask {
157     public:
158       DataMask101() { }
159       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
160                                    int dimension) {
161         unsigned int bitMask = 0;
162         int count = 0;
163         int offset = 0;
164         for (int j = 0; j < dimension; j++) {
165           for (int i = 0; i < dimension; i++) {
166             int product = i * j;
167             if (((product & 0x01) == 0) && product % 3 == 0) {
168               bitMask |= 1 << count;
169             }
170             if (++count == 32) {
171               bits[offset++] ^= bitMask;
172               count = 0;
173               bitMask = 0;
174             }
175           }
176         }
177         bits[offset] ^= bitMask;
178       }
179     };
180     
181     
182     class DataMask110 : public DataMask {
183     public:
184       DataMask110() { }
185       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
186                                    int dimension) {
187         unsigned int bitMask = 0;
188         int count = 0;
189         int offset = 0;
190         for (int j = 0; j < dimension; j++) {
191           for (int i = 0; i < dimension; i++) {
192             int product = i * j;
193             if ((((product & 0x01) + product % 3) & 0x01) == 0) {
194               bitMask |= 1 << count;
195             }
196             if (++count == 32) {
197               bits[offset++] ^= bitMask;
198               count = 0;
199               bitMask = 0;
200             }
201           }
202         }
203         bits[offset] ^= bitMask;
204       }
205     };
206     
207     
208     class DataMask111 : public DataMask {
209     public:
210       DataMask111() { }
211       virtual void unmaskBitMatrix(valarray<unsigned int> &bits, 
212                                    int dimension) {
213         unsigned int bitMask = 0;
214         int count = 0;
215         int offset = 0;
216         for (int j = 0; j < dimension; j++) {
217           for (int i = 0; i < dimension; i++) {
218             if (((((i + j) & 0x01) + (i * j) % 3) & 0x01) == 0) {
219               bitMask |= 1 << count;
220             }
221             if (++count == 32) {
222               bits[offset++] ^= bitMask;
223               count = 0;
224               bitMask = 0;
225             }
226           }
227         }
228         bits[offset] ^= bitMask;
229       }
230     };
231     
232     int DataMask::buildDataMasks() {
233       DATA_MASKS.push_back(new DataMask000());
234       DATA_MASKS.push_back(new DataMask001());
235       DATA_MASKS.push_back(new DataMask010());
236       DATA_MASKS.push_back(new DataMask011());
237       DATA_MASKS.push_back(new DataMask100());
238       DATA_MASKS.push_back(new DataMask101());
239       DATA_MASKS.push_back(new DataMask110());
240       DATA_MASKS.push_back(new DataMask111());
241       return DATA_MASKS.size();
242     }    
243     
244   }
245 }