001/* 002 * Copyright 2008 ZXing authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.itextpdf.text.pdf.qrcode; 018 019 020/** 021 * @author satorux@google.com (Satoru Takabayashi) - creator 022 * @author dswitkin@google.com (Daniel Switkin) - ported from C++ 023 * @since 5.0.2 024 */ 025public final class QRCode { 026 027 public static final int NUM_MASK_PATTERNS = 8; 028 029 private Mode mode; 030 private ErrorCorrectionLevel ecLevel; 031 private int version; 032 private int matrixWidth; 033 private int maskPattern; 034 private int numTotalBytes; 035 private int numDataBytes; 036 private int numECBytes; 037 private int numRSBlocks; 038 private ByteMatrix matrix; 039 040 public QRCode() { 041 mode = null; 042 ecLevel = null; 043 version = -1; 044 matrixWidth = -1; 045 maskPattern = -1; 046 numTotalBytes = -1; 047 numDataBytes = -1; 048 numECBytes = -1; 049 numRSBlocks = -1; 050 matrix = null; 051 } 052 053 // Mode of the QR Code. 054 public Mode getMode() { 055 return mode; 056 } 057 058 // Error correction level of the QR Code. 059 public ErrorCorrectionLevel getECLevel() { 060 return ecLevel; 061 } 062 063 // Version of the QR Code. The bigger size, the bigger version. 064 public int getVersion() { 065 return version; 066 } 067 068 // ByteMatrix width of the QR Code. 069 public int getMatrixWidth() { 070 return matrixWidth; 071 } 072 073 // Mask pattern of the QR Code. 074 public int getMaskPattern() { 075 return maskPattern; 076 } 077 078 // Number of total bytes in the QR Code. 079 public int getNumTotalBytes() { 080 return numTotalBytes; 081 } 082 083 // Number of data bytes in the QR Code. 084 public int getNumDataBytes() { 085 return numDataBytes; 086 } 087 088 // Number of error correction bytes in the QR Code. 089 public int getNumECBytes() { 090 return numECBytes; 091 } 092 093 // Number of Reedsolomon blocks in the QR Code. 094 public int getNumRSBlocks() { 095 return numRSBlocks; 096 } 097 098 // ByteMatrix data of the QR Code. 099 public ByteMatrix getMatrix() { 100 return matrix; 101 } 102 103 104 // Return the value of the module (cell) pointed by "x" and "y" in the matrix of the QR Code. They 105 // call cells in the matrix "modules". 1 represents a black cell, and 0 represents a white cell. 106 public int at(int x, int y) { 107 // The value must be zero or one. 108 int value = matrix.get(x, y); 109 if (!(value == 0 || value == 1)) { 110 // this is really like an assert... not sure what better exception to use? 111 throw new RuntimeException("Bad value"); 112 } 113 return value; 114 } 115 116 // Checks all the member variables are set properly. Returns true on success. Otherwise, returns 117 // false. 118 public boolean isValid() { 119 return 120 // First check if all version are not uninitialized. 121 mode != null && 122 ecLevel != null && 123 version != -1 && 124 matrixWidth != -1 && 125 maskPattern != -1 && 126 numTotalBytes != -1 && 127 numDataBytes != -1 && 128 numECBytes != -1 && 129 numRSBlocks != -1 && 130 // Then check them in other ways.. 131 isValidMaskPattern(maskPattern) && 132 numTotalBytes == numDataBytes + numECBytes && 133 // ByteMatrix stuff. 134 matrix != null && 135 matrixWidth == matrix.getWidth() && 136 // See 7.3.1 of JISX0510:2004 (p.5). 137 matrix.getWidth() == matrix.getHeight(); // Must be square. 138 } 139 140 // Return debug String. 141 public String toString() { 142 StringBuffer result = new StringBuffer(200); 143 result.append("<<\n"); 144 result.append(" mode: "); 145 result.append(mode); 146 result.append("\n ecLevel: "); 147 result.append(ecLevel); 148 result.append("\n version: "); 149 result.append(version); 150 result.append("\n matrixWidth: "); 151 result.append(matrixWidth); 152 result.append("\n maskPattern: "); 153 result.append(maskPattern); 154 result.append("\n numTotalBytes: "); 155 result.append(numTotalBytes); 156 result.append("\n numDataBytes: "); 157 result.append(numDataBytes); 158 result.append("\n numECBytes: "); 159 result.append(numECBytes); 160 result.append("\n numRSBlocks: "); 161 result.append(numRSBlocks); 162 if (matrix == null) { 163 result.append("\n matrix: null\n"); 164 } else { 165 result.append("\n matrix:\n"); 166 result.append(matrix.toString()); 167 } 168 result.append(">>\n"); 169 return result.toString(); 170 } 171 172 public void setMode(Mode value) { 173 mode = value; 174 } 175 176 public void setECLevel(ErrorCorrectionLevel value) { 177 ecLevel = value; 178 } 179 180 public void setVersion(int value) { 181 version = value; 182 } 183 184 public void setMatrixWidth(int value) { 185 matrixWidth = value; 186 } 187 188 public void setMaskPattern(int value) { 189 maskPattern = value; 190 } 191 192 public void setNumTotalBytes(int value) { 193 numTotalBytes = value; 194 } 195 196 public void setNumDataBytes(int value) { 197 numDataBytes = value; 198 } 199 200 public void setNumECBytes(int value) { 201 numECBytes = value; 202 } 203 204 public void setNumRSBlocks(int value) { 205 numRSBlocks = value; 206 } 207 208 // This takes ownership of the 2D array. 209 public void setMatrix(ByteMatrix value) { 210 matrix = value; 211 } 212 213 // Check if "mask_pattern" is valid. 214 public static boolean isValidMaskPattern(int maskPattern) { 215 return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS; 216 } 217 218 // Return true if the all values in the matrix are binary numbers. 219 // 220 // JAVAPORT: This is going to be super expensive and unnecessary, we should not call this in 221 // production. I'm leaving it because it may be useful for testing. It should be removed entirely 222 // if ByteMatrix is changed never to contain a -1. 223 /* 224 private static boolean EverythingIsBinary(final ByteMatrix matrix) { 225 for (int y = 0; y < matrix.height(); ++y) { 226 for (int x = 0; x < matrix.width(); ++x) { 227 int value = matrix.get(y, x); 228 if (!(value == 0 || value == 1)) { 229 // Found non zero/one value. 230 return false; 231 } 232 } 233 } 234 return true; 235 } 236 */ 237 238}