Unify handling of Mode too
[zxing.git] / core / test / src / com / google / zxing / qrcode / encoder / MatrixUtilTestCase.java
1 /*
2  * Copyright 2008 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.encoder;
18
19 import com.google.zxing.WriterException;
20 import com.google.zxing.common.ByteMatrix;
21 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
22 import junit.framework.TestCase;
23
24 /**
25  * @author satorux@google.com (Satoru Takabayashi) - creator
26  * @author mysen@google.com (Chris Mysen) - ported from C++
27  */
28 public final class MatrixUtilTestCase extends TestCase {
29   public void testtoString() {
30     ByteMatrix array = new ByteMatrix(3, 3);
31     array.set(0, 0, 0);
32     array.set(0, 1, 1);
33     array.set(0, 2, 0);
34     array.set(1, 0, 1);
35     array.set(1, 1, 0);
36     array.set(1, 2, 1);
37     array.set(2, 0, -1);
38     array.set(2, 1, -1);
39     array.set(2, 2, -1);
40     String expected = " 0 1 0\n" + " 1 0 1\n" + "      \n";
41     assertEquals(expected, array.toString());
42   }
43
44   public void testClearMatrix() {
45     ByteMatrix matrix = new ByteMatrix(2, 2);
46     MatrixUtil.clearMatrix(matrix);
47     assertEquals(-1, matrix.get(0, 0));
48     assertEquals(-1, matrix.get(0, 1));
49     assertEquals(-1, matrix.get(1, 0));
50     assertEquals(-1, matrix.get(1, 1));
51   }
52
53   public void testEmbedBasicPatterns() throws WriterException {
54     {
55       // Version 1.
56       String expected =
57         " 1 1 1 1 1 1 1 0           0 1 1 1 1 1 1 1\n" +
58         " 1 0 0 0 0 0 1 0           0 1 0 0 0 0 0 1\n" +
59         " 1 0 1 1 1 0 1 0           0 1 0 1 1 1 0 1\n" +
60         " 1 0 1 1 1 0 1 0           0 1 0 1 1 1 0 1\n" +
61         " 1 0 1 1 1 0 1 0           0 1 0 1 1 1 0 1\n" +
62         " 1 0 0 0 0 0 1 0           0 1 0 0 0 0 0 1\n" +
63         " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
64         " 0 0 0 0 0 0 0 0           0 0 0 0 0 0 0 0\n" +
65         "             1                            \n" +
66         "             0                            \n" +
67         "             1                            \n" +
68         "             0                            \n" +
69         "             1                            \n" +
70         " 0 0 0 0 0 0 0 0 1                        \n" +
71         " 1 1 1 1 1 1 1 0                          \n" +
72         " 1 0 0 0 0 0 1 0                          \n" +
73         " 1 0 1 1 1 0 1 0                          \n" +
74         " 1 0 1 1 1 0 1 0                          \n" +
75         " 1 0 1 1 1 0 1 0                          \n" +
76         " 1 0 0 0 0 0 1 0                          \n" +
77         " 1 1 1 1 1 1 1 0                          \n";
78       ByteMatrix matrix = new ByteMatrix(21, 21);
79       MatrixUtil.clearMatrix(matrix);
80       MatrixUtil.embedBasicPatterns(1, matrix);
81       assertEquals(expected, matrix.toString());
82     }
83     {
84       // Version 2.  Position adjustment pattern should apppear at right
85       // bottom corner.
86       String expected =
87         " 1 1 1 1 1 1 1 0                   0 1 1 1 1 1 1 1\n" +
88         " 1 0 0 0 0 0 1 0                   0 1 0 0 0 0 0 1\n" +
89         " 1 0 1 1 1 0 1 0                   0 1 0 1 1 1 0 1\n" +
90         " 1 0 1 1 1 0 1 0                   0 1 0 1 1 1 0 1\n" +
91         " 1 0 1 1 1 0 1 0                   0 1 0 1 1 1 0 1\n" +
92         " 1 0 0 0 0 0 1 0                   0 1 0 0 0 0 0 1\n" +
93         " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
94         " 0 0 0 0 0 0 0 0                   0 0 0 0 0 0 0 0\n" +
95         "             1                                    \n" +
96         "             0                                    \n" +
97         "             1                                    \n" +
98         "             0                                    \n" +
99         "             1                                    \n" +
100         "             0                                    \n" +
101         "             1                                    \n" +
102         "             0                                    \n" +
103         "             1                   1 1 1 1 1        \n" +
104         " 0 0 0 0 0 0 0 0 1               1 0 0 0 1        \n" +
105         " 1 1 1 1 1 1 1 0                 1 0 1 0 1        \n" +
106         " 1 0 0 0 0 0 1 0                 1 0 0 0 1        \n" +
107         " 1 0 1 1 1 0 1 0                 1 1 1 1 1        \n" +
108         " 1 0 1 1 1 0 1 0                                  \n" +
109         " 1 0 1 1 1 0 1 0                                  \n" +
110         " 1 0 0 0 0 0 1 0                                  \n" +
111         " 1 1 1 1 1 1 1 0                                  \n";
112       ByteMatrix matrix = new ByteMatrix(25, 25);
113       MatrixUtil.clearMatrix(matrix);
114       MatrixUtil.embedBasicPatterns(2, matrix);
115       assertEquals(expected, matrix.toString());
116     }
117   }
118
119   public void testEmbedTypeInfo() throws WriterException {
120     // Type info bits = 100000011001110.
121     String expected =
122       "                 0                        \n" +
123       "                 1                        \n" +
124       "                 1                        \n" +
125       "                 1                        \n" +
126       "                 0                        \n" +
127       "                 0                        \n" +
128       "                                          \n" +
129       "                 1                        \n" +
130       " 1 0 0 0 0 0   0 1         1 1 0 0 1 1 1 0\n" +
131       "                                          \n" +
132       "                                          \n" +
133       "                                          \n" +
134       "                                          \n" +
135       "                                          \n" +
136       "                 0                        \n" +
137       "                 0                        \n" +
138       "                 0                        \n" +
139       "                 0                        \n" +
140       "                 0                        \n" +
141       "                 0                        \n" +
142       "                 1                        \n";
143     ByteMatrix matrix = new ByteMatrix(21, 21);
144     MatrixUtil.clearMatrix(matrix);
145     MatrixUtil.embedTypeInfo(ErrorCorrectionLevel.M, 5, matrix);
146     assertEquals(expected, matrix.toString());
147   }
148
149   public void testEmbedVersionInfo() throws WriterException {
150     // Version info bits = 000111 110010 010100
151     String expected =
152       "                     0 0 1                \n" +
153       "                     0 1 0                \n" +
154       "                     0 1 0                \n" +
155       "                     0 1 1                \n" +
156       "                     1 1 1                \n" +
157       "                     0 0 0                \n" +
158       "                                          \n" +
159       "                                          \n" +
160       "                                          \n" +
161       "                                          \n" +
162       " 0 0 0 0 1 0                              \n" +
163       " 0 1 1 1 1 0                              \n" +
164       " 1 0 0 1 1 0                              \n" +
165       "                                          \n" +
166       "                                          \n" +
167       "                                          \n" +
168       "                                          \n" +
169       "                                          \n" +
170       "                                          \n" +
171       "                                          \n" +
172       "                                          \n";
173     // Actually, version 7 QR Code has 45x45 matrix but we use 21x21 here
174     // since 45x45 matrix is too big to depict.
175     ByteMatrix matrix = new ByteMatrix(21, 21);
176     MatrixUtil.clearMatrix(matrix);
177     MatrixUtil.maybeEmbedVersionInfo(7, matrix);
178     assertEquals(expected, matrix.toString());
179   }
180
181   public void testEmbedDataBits() throws WriterException {
182     // Cells other than basic patterns should be filled with zero.
183     String expected =
184       " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n" +
185       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" +
186       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" +
187       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" +
188       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" +
189       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" +
190       " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
191       " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
192       " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
193       " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
194       " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
195       " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
196       " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
197       " 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n" +
198       " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
199       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
200       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
201       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
202       " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
203       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" +
204       " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
205     BitVector bits = new BitVector();
206     ByteMatrix matrix = new ByteMatrix(21, 21);
207     MatrixUtil.clearMatrix(matrix);
208     MatrixUtil.embedBasicPatterns(1, matrix);
209     MatrixUtil.embedDataBits(bits, -1, matrix);
210     assertEquals(expected, matrix.toString());
211   }
212
213   public void testBuildMatrix() throws WriterException {
214     // From http://www.swetake.com/qr/qr7.html
215     String expected =
216       " 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1\n" +
217       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n" +
218       " 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n" +
219       " 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1\n" +
220       " 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1\n" +
221       " 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 1\n" +
222       " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
223       " 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0\n" +
224       " 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0\n" +
225       " 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0\n" +
226       " 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0\n" +
227       " 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0\n" +
228       " 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1\n" +
229       " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1\n" +
230       " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0\n" +
231       " 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0\n" +
232       " 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1\n" +
233       " 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0\n" +
234       " 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0\n" +
235       " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0\n" +
236       " 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0\n";
237     char bytes[] = {32, 65, 205, 69, 41, 220, 46, 128, 236,
238                     42, 159, 74, 221, 244, 169, 239, 150, 138,
239                     70, 237, 85, 224, 96, 74, 219 , 61};
240     BitVector bits = new BitVector();
241     for (char c: bytes) {
242       bits.appendBits(c, 8);
243     }
244     ByteMatrix matrix = new ByteMatrix(21, 21);
245     MatrixUtil.buildMatrix(bits,
246                                               ErrorCorrectionLevel.H,
247                                               1,  // Version 1
248                                               3,  // Mask pattern 3
249                                               matrix);
250   }
251
252   public void testFindMSBSet() {
253     assertEquals(0, MatrixUtil.findMSBSet(0));
254     assertEquals(1, MatrixUtil.findMSBSet(1));
255     assertEquals(8, MatrixUtil.findMSBSet(0x80));
256     assertEquals(32, MatrixUtil.findMSBSet(0x80000000));
257   }
258
259   public void testCalculateBCHCode() {
260     // Encoding of type information.
261     // From Appendix C in JISX0510:2004 (p 65)
262     assertEquals(0xdc, MatrixUtil.calculateBCHCode(5, 0x537));
263     // From http://www.swetake.com/qr/qr6.html
264     assertEquals(0x1c2, MatrixUtil.calculateBCHCode(0x13, 0x537));
265     // From http://www.swetake.com/qr/qr11.html
266     assertEquals(0x214, MatrixUtil.calculateBCHCode(0x1b, 0x537));
267
268     // Encofing of version information.
269     // From Appendix D in JISX0510:2004 (p 68)
270     assertEquals(0xc94, MatrixUtil.calculateBCHCode(7, 0x1f25));
271     assertEquals(0x5bc, MatrixUtil.calculateBCHCode(8, 0x1f25));
272     assertEquals(0xa99, MatrixUtil.calculateBCHCode(9, 0x1f25));
273     assertEquals(0x4d3, MatrixUtil.calculateBCHCode(10, 0x1f25));
274     assertEquals(0x9a6, MatrixUtil.calculateBCHCode(20, 0x1f25));
275     assertEquals(0xd75, MatrixUtil.calculateBCHCode(30, 0x1f25));
276     assertEquals(0xc69, MatrixUtil.calculateBCHCode(40, 0x1f25));
277   }
278
279   // We don't test a lot of cases in this function since we've already
280   // tested them in TEST(calculateBCHCode).
281   public void testMakeVersionInfoBits() throws WriterException {
282     // From Appendix D in JISX0510:2004 (p 68)
283     BitVector bits = new BitVector();
284     MatrixUtil.makeVersionInfoBits(7, bits);
285     assertEquals("000111110010010100", bits.toString());
286   }
287
288   // We don't test a lot of cases in this function since we've already
289   // tested them in TEST(calculateBCHCode).
290   public void testMakeTypeInfoInfoBits() throws WriterException {
291     // From Appendix C in JISX0510:2004 (p 65)
292     BitVector bits = new BitVector();
293     MatrixUtil.makeTypeInfoBits(ErrorCorrectionLevel.M,
294                                                    5, bits);
295     assertEquals("100000011001110", bits.toString());
296   }
297 }