Fixed or removed a bunch of TODOs, and enforced the 100 columns limit in a bunch...
[zxing.git] / core / src / com / google / zxing / qrcode / encoder / QRCode.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.common.ByteMatrix;
20 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
21 import com.google.zxing.qrcode.decoder.Mode;
22
23 /**
24  * @author satorux@google.com (Satoru Takabayashi) - creator
25  * @author dswitkin@google.com (Daniel Switkin) - ported from C++
26  */
27 public final class QRCode {
28
29   public static final int NUM_MASK_PATTERNS = 8;
30
31   private Mode mode;
32   private ErrorCorrectionLevel ecLevel;
33   private int version;
34   private int matrixWidth;
35   private int maskPattern;
36   private int numTotalBytes;
37   private int numDataBytes;
38   private int numECBytes;
39   private int numRSBlocks;
40   private ByteMatrix matrix;
41
42   public QRCode() {
43     mode = null;
44     ecLevel = null;
45     version = -1;
46     matrixWidth = -1;
47     maskPattern = -1;
48     numTotalBytes = -1;
49     numDataBytes = -1;
50     numECBytes = -1;
51     numRSBlocks = -1;
52     matrix = null;
53   }
54
55   // Mode of the QR Code.
56   public Mode getMode() {
57     return mode;
58   }
59
60   // Error correction level of the QR Code.
61   public ErrorCorrectionLevel getECLevel() {
62     return ecLevel;
63   }
64
65   // Version of the QR Code.  The bigger size, the bigger version.
66   public int getVersion() {
67     return version;
68   }
69
70   // ByteMatrix width of the QR Code.
71   public int getMatrixWidth() {
72     return matrixWidth;
73   }
74
75   // Mask pattern of the QR Code.
76   public int getMaskPattern() {
77     return maskPattern;
78   }
79
80   // Number of total bytes in the QR Code.
81   public int getNumTotalBytes() {
82     return numTotalBytes;
83   }
84
85   // Number of data bytes in the QR Code.
86   public int getNumDataBytes() {
87     return numDataBytes;
88   }
89
90   // Number of error correction bytes in the QR Code.
91   public int getNumECBytes() {
92     return numECBytes;
93   }
94
95   // Number of Reedsolomon blocks in the QR Code.
96   public int getNumRSBlocks() {
97     return numRSBlocks;
98   }
99
100   // ByteMatrix data of the QR Code.
101   public ByteMatrix getMatrix() {
102     return matrix;
103   }
104   
105
106   // Return the value of the module (cell) pointed by "x" and "y" in the matrix of the QR Code. They
107   // call cells in the matrix "modules". 1 represents a black cell, and 0 represents a white cell.
108   public int at(int x, int y) {
109     // The value must be zero or one.
110     int value = matrix.get(y, x);
111     if (!(value == 0 || value == 1)) {
112       // this is really like an assert... not sure what better exception to use?
113       throw new RuntimeException("Bad value");
114     }
115     return value;
116   }
117
118   // Checks all the member variables are set properly. Returns true on success. Otherwise, returns
119   // false.
120   public boolean isValid() {
121     return
122         // First check if all version are not uninitialized.
123         mode != null &&
124         ecLevel != null &&
125         version != -1 &&
126         matrixWidth != -1 &&
127         maskPattern != -1 &&
128         numTotalBytes != -1 &&
129         numDataBytes != -1 &&
130         numECBytes != -1 &&
131         numRSBlocks != -1 &&
132         // Then check them in other ways..
133         isValidMaskPattern(maskPattern) &&
134         numTotalBytes == numDataBytes + numECBytes &&
135         // ByteMatrix stuff.
136         matrix != null &&
137         matrixWidth == matrix.width() &&
138         // See 7.3.1 of JISX0510:2004 (p.5).
139         matrix.width() == matrix.height(); // Must be square.
140   }
141
142   // Return debug String.
143   public String toString() {
144     StringBuffer result = new StringBuffer(200);
145     result.append("<<\n");
146     result.append(" mode: ");
147     result.append(mode);
148     result.append("\n ecLevel: ");
149     result.append(ecLevel);
150     result.append("\n version: ");
151     result.append(version);
152     result.append("\n matrixWidth: ");
153     result.append(matrixWidth);
154     result.append("\n maskPattern: ");
155     result.append(maskPattern);
156     result.append("\n numTotalBytes: ");
157     result.append(numTotalBytes);
158     result.append("\n numDataBytes: ");
159     result.append(numDataBytes);
160     result.append("\n numECBytes: ");
161     result.append(numECBytes);
162     result.append("\n numRSBlocks: ");
163     result.append(numRSBlocks);
164     if (matrix == null) {
165       result.append("\n matrix: null\n");
166     } else {
167       result.append("\n matrix:\n");
168       result.append(matrix.toString());
169     }
170     result.append(">>\n");
171     return result.toString();
172   }
173
174   public void setMode(Mode value) {
175     mode = value;
176   }
177
178   public void setECLevel(ErrorCorrectionLevel value) {
179     ecLevel = value;
180   }
181
182   public void setVersion(int value) {
183     version = value;
184   }
185
186   public void setMatrixWidth(int value) {
187     matrixWidth = value;
188   }
189
190   public void setMaskPattern(int value) {
191     maskPattern = value;
192   }
193
194   public void setNumTotalBytes(int value) {
195     numTotalBytes = value;
196   }
197
198   public void setNumDataBytes(int value) {
199     numDataBytes = value;
200   }
201
202   public void setNumECBytes(int value) {
203     numECBytes = value;
204   }
205
206   public void setNumRSBlocks(int value) {
207     numRSBlocks = value;
208   }
209
210   // This takes ownership of the 2D array.
211   public void setMatrix(ByteMatrix value) {
212     matrix = value;
213   }
214
215   // Check if "mask_pattern" is valid.
216   public static boolean isValidMaskPattern(int maskPattern) {
217     return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
218   }
219
220   // Return true if the all values in the matrix are binary numbers.
221   //
222   // JAVAPORT: This is going to be super expensive and unnecessary, we should not call this in
223   // production. I'm leaving it because it may be useful for testing. It should be removed entirely
224   // if ByteMatrix is changed never to contain a -1.
225   /*
226   private static boolean EverythingIsBinary(final ByteMatrix matrix) {
227     for (int y = 0; y < matrix.height(); ++y) {
228       for (int x = 0; x < matrix.width(); ++x) {
229         int value = matrix.get(y, x);
230         if (!(value == 0 || value == 1)) {
231           // Found non zero/one value.
232           return false;
233         }
234       }
235     }
236     return true;
237   }
238    */
239
240 }