A pile of changes from proper static analysis for nullability issues, with full annotations.

git-svn-id: https://zxing.googlecode.com/svn/trunk@1937 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2011-09-26 19:09:45 +00:00
parent e76c5785c7
commit 303ed2e6a0
75 changed files with 343 additions and 354 deletions

View file

@ -114,6 +114,8 @@ public final class ViewfinderView extends View {
List<ResultPoint> currentPossible = possibleResultPoints;
List<ResultPoint> currentLast = lastPossibleResultPoints;
int frameLeft = frame.left;
int frameTop = frame.top;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
@ -123,8 +125,8 @@ public final class ViewfinderView extends View {
paint.setColor(resultPointColor);
synchronized (currentPossible) {
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frame.left + (int) (point.getX() * scaleX),
frame.top + (int) (point.getY() * scaleY),
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
6.0f, paint);
}
}
@ -134,8 +136,8 @@ public final class ViewfinderView extends View {
paint.setColor(resultPointColor);
synchronized (currentLast) {
for (ResultPoint point : currentLast) {
canvas.drawCircle(frame.left + (int) (point.getX() * scaleX),
frame.top + (int) (point.getY() * scaleY),
canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),
frameTop + (int) (point.getY() * scaleY),
3.0f, paint);
}
}

View file

@ -27,6 +27,8 @@ import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
/**
* A list item which displays the page number and snippet of this search result.
*
@ -56,8 +58,8 @@ public final class SearchBookContentsListItem extends LinearLayout {
String snippet = result.getSnippet();
if (snippet.length() > 0) {
if (result.getValidSnippet()) {
String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase();
String lowerSnippet = snippet.toLowerCase();
String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase(Locale.getDefault());
String lowerSnippet = snippet.toLowerCase(Locale.getDefault());
Spannable styledSnippet = new SpannableString(snippet);
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
int queryLength = lowerQuery.length();

View file

@ -73,7 +73,6 @@ public final class CameraManager {
private final boolean useOneShotPreviewCallback;
private int requestedFramingRectWidth;
private int requestedFramingRectHeight;
/**
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
* clear the handler so it will only receive one message.
@ -125,23 +124,25 @@ public final class CameraManager {
* @throws IOException Indicates the camera driver failed to open.
*/
public void openDriver(SurfaceHolder holder) throws IOException {
if (camera == null) {
camera = Camera.open();
if (camera == null) {
Camera theCamera = camera;
if (theCamera == null) {
theCamera = Camera.open();
if (theCamera == null) {
throw new IOException();
}
camera = theCamera;
}
camera.setPreviewDisplay(holder);
theCamera.setPreviewDisplay(holder);
if (!initialized) {
initialized = true;
configManager.initFromCameraParameters(camera);
configManager.initFromCameraParameters(theCamera);
if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);
requestedFramingRectWidth = 0;
requestedFramingRectHeight = 0;
}
}
configManager.setDesiredCameraParameters(camera);
configManager.setDesiredCameraParameters(theCamera);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
reverseImage = prefs.getBoolean(PreferencesActivity.KEY_REVERSE_IMAGE, false);
@ -170,8 +171,9 @@ public final class CameraManager {
* Asks the camera hardware to begin drawing preview frames to the screen.
*/
public void startPreview() {
if (camera != null && !previewing) {
camera.startPreview();
Camera theCamera = camera;
if (theCamera != null && !previewing) {
theCamera.startPreview();
previewing = true;
}
}
@ -200,12 +202,13 @@ public final class CameraManager {
* @param message The what field of the message to be sent.
*/
public void requestPreviewFrame(Handler handler, int message) {
if (camera != null && previewing) {
Camera theCamera = camera;
if (theCamera != null && previewing) {
previewCallback.setHandler(handler, message);
if (useOneShotPreviewCallback) {
camera.setOneShotPreviewCallback(previewCallback);
theCamera.setOneShotPreviewCallback(previewCallback);
} else {
camera.setPreviewCallback(previewCallback);
theCamera.setPreviewCallback(previewCallback);
}
}
}
@ -313,6 +316,9 @@ public final class CameraManager {
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
Rect rect = getFramingRectInPreview();
if (rect == null) {
throw new IllegalStateException();
}
int previewFormat = configManager.getPreviewFormat();
String previewFormatString = configManager.getPreviewFormatString();

View file

@ -46,8 +46,9 @@ final class PreviewCallback implements Camera.PreviewCallback {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
if (previewHandler != null) {
Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,
Handler thePreviewHandler = previewHandler;
if (thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;

View file

@ -79,15 +79,21 @@ public final class EncodeActivity extends Activity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (qrCodeEncoder == null) { // Odd
QRCodeEncoder encoder = qrCodeEncoder;
if (encoder == null) { // Odd
Log.w(TAG, "No existing barcode to send?");
return true;
}
String contents = encoder.getContents();
if (contents == null) {
Log.w(TAG, "No existing barcode to send?");
return true;
}
String contents = qrCodeEncoder.getContents();
Bitmap bitmap;
try {
bitmap = qrCodeEncoder.encodeAsBitmap();
bitmap = encoder.encodeAsBitmap();
} catch (WriterException we) {
Log.w(TAG, we);
return true;
@ -121,9 +127,8 @@ public final class EncodeActivity extends Activity {
}
Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " +
qrCodeEncoder.getTitle());
intent.putExtra(Intent.EXTRA_TEXT, qrCodeEncoder.getContents());
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name) + " - " + encoder.getTitle());
intent.putExtra(Intent.EXTRA_TEXT, encoder.getContents());
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + barcodeFile.getAbsolutePath()));
intent.setType("image/png");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
@ -157,6 +162,9 @@ public final class EncodeActivity extends Activity {
smallerDimension = smallerDimension * 7 / 8;
Intent intent = getIntent();
if (intent == null) {
return;
}
try {
qrCodeEncoder = new QRCodeEncoder(this, intent, smallerDimension);
setTitle(getString(R.string.app_name) + " - " + qrCodeEncoder.getTitle());

View file

@ -67,10 +67,6 @@ final class QRCodeEncoder {
QRCodeEncoder(Activity activity, Intent intent, int dimension) {
this.activity = activity;
if (intent == null) {
throw new IllegalArgumentException("No valid data to encode.");
}
String action = intent.getAction();
if (action.equals(Intents.Encode.ACTION)) {
if (!encodeContentsFromZXingIntent(intent)) {
@ -138,16 +134,17 @@ final class QRCodeEncoder {
private boolean encodeContentsFromShareIntentPlainText(Intent intent) {
// Notice: Google Maps shares both URL and details in one text, bummer!
contents = intent.getStringExtra(Intent.EXTRA_TEXT);
String theContents = intent.getStringExtra(Intent.EXTRA_TEXT);
// We only support non-empty and non-blank texts.
// Trim text to avoid URL breaking.
if (contents == null) {
if (theContents == null) {
return false;
}
contents = contents.trim();
if (contents.length() == 0) {
theContents = theContents.trim();
if (theContents.length() == 0) {
return false;
}
contents = theContents;
// We only do QR code.
format = BarcodeFormat.QR_CODE;
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
@ -420,8 +417,8 @@ final class QRCodeEncoder {
if (s == null) {
return null;
}
s = s.trim();
return s.length() == 0 ? null : s;
String result = s.trim();
return result.length() == 0 ? null : result;
}
private static String escapeMECARD(String input) {

View file

@ -43,10 +43,7 @@ import android.view.View;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.*;
/**
* A base class for the Android-specific barcode handlers. These allow the app to polymorphically
@ -354,7 +351,7 @@ public abstract class ResultHandler {
}
for (int i = 0; i < types.length; i++) {
String type = types[i];
if (typeString.startsWith(type) || typeString.startsWith(type.toUpperCase())) {
if (typeString.startsWith(type) || typeString.startsWith(type.toUpperCase(Locale.ENGLISH))) {
return values[i];
}
}
@ -545,6 +542,9 @@ public abstract class ResultHandler {
}
String fillInCustomSearchURL(String text) {
if (customProductSearch == null) {
return text; // ?
}
String url = customProductSearch.replace("%s", text);
if (rawResult != null) {
url = url.replace("%f", rawResult.getBarcodeFormat().toString());

View file

@ -23,6 +23,8 @@ import com.google.zxing.client.result.URIParsedResult;
import android.app.Activity;
import java.util.Locale;
/**
* Offers appropriate actions for URLS.
*
@ -31,7 +33,7 @@ import android.app.Activity;
public final class URIResultHandler extends ResultHandler {
// URIs beginning with entries in this array will not be saved to history or copied to the
// clipboard for security.
private static final String[] SECURE_PROTOCOLS = new String[] {
private static final String[] SECURE_PROTOCOLS = {
"otpauth:"
};
@ -87,7 +89,7 @@ public final class URIResultHandler extends ResultHandler {
@Override
public boolean areContentsSecure() {
URIParsedResult uriResult = (URIParsedResult) getResult();
String uri = uriResult.getURI().toLowerCase();
String uri = uriResult.getURI().toLowerCase(Locale.ENGLISH);
for (String secure : SECURE_PROTOCOLS) {
if (uri.startsWith(secure)) {
return true;

View file

@ -59,9 +59,6 @@ public final class WifiResultHandler extends ResultHandler {
WifiParsedResult wifiResult = (WifiParsedResult) getResult();
if (index == 0) {
String ssid = wifiResult.getSsid();
if (ssid == null || ssid.length() == 0) {
return;
}
String password = wifiResult.getPassword();
String networkType = wifiResult.getNetworkEncryption();
WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);

View file

@ -66,7 +66,7 @@ public final class BookResultInfoRetriever extends SupplementalInfoRetriever {
String title;
String pages;
Collection<String> authors;
Collection<String> authors = null;
try {
@ -84,9 +84,9 @@ public final class BookResultInfoRetriever extends SupplementalInfoRetriever {
title = volumeInfo.optString("title");
pages = volumeInfo.optString("pageCount");
authors = new ArrayList<String>();
JSONArray authorsArray = volumeInfo.optJSONArray("authors");
if (authorsArray != null && !authorsArray.isNull(0)) {
authors = new ArrayList<String>();
for (int i = 0; i < authorsArray.length(); i++) {
authors.add(authorsArray.getString(i));
}

View file

@ -23,6 +23,9 @@ enum NetworkType {
NO_PASSWORD;
static NetworkType forIntentValue(String networkTypeString) {
if (networkTypeString == null) {
return NO_PASSWORD;
}
if ("WPA".equals(networkTypeString)) {
return WPA;
}

View file

@ -34,32 +34,23 @@ public final class WifiConfigManager {
}
public static void configure(WifiManager wifiManager, String ssid, String password, String networkTypeString) {
// If the SSID is empty, throw an error and return
if (ssid == null || ssid.length() == 0) {
throw new IllegalArgumentException();
}
NetworkType networkType;
if (password == null || password.length() == 0 || networkTypeString == null) {
networkType = NetworkType.NO_PASSWORD;
} else {
networkType = NetworkType.forIntentValue(networkTypeString);
}
// Start WiFi, otherwise nothing will work
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
switch (networkType) {
case WEP:
NetworkType networkType = NetworkType.forIntentValue(networkTypeString);
if (networkType == NetworkType.NO_PASSWORD) {
changeNetworkUnEncrypted(wifiManager, ssid);
} else {
if (password == null || password.length() == 0) {
throw new IllegalArgumentException();
}
if (networkType == NetworkType.WEP) {
changeNetworkWEP(wifiManager, ssid, password);
break;
case WPA:
} else if (networkType == NetworkType.WPA) {
changeNetworkWPA(wifiManager, ssid, password);
break;
case NO_PASSWORD:
changeNetworkUnEncrypted(wifiManager, ssid);
break;
}
}
}

View file

@ -32,9 +32,6 @@ public abstract class Binarizer {
private final LuminanceSource source;
protected Binarizer(LuminanceSource source) {
if (source == null) {
throw new IllegalArgumentException("Source must be non-null.");
}
this.source = source;
}

View file

@ -36,7 +36,7 @@ import java.util.Vector;
public final class MultiFormatReader implements Reader {
private Hashtable hints;
private Vector readers;
private final Vector readers = new Vector();
/**
* This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
@ -75,7 +75,7 @@ public final class MultiFormatReader implements Reader {
*/
public Result decodeWithState(BinaryBitmap image) throws NotFoundException {
// Make sure to set up the default state so we don't crash
if (readers == null) {
if (readers.isEmpty()) {
setHints(null);
}
return decodeInternal(image);
@ -93,7 +93,7 @@ public final class MultiFormatReader implements Reader {
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
Vector formats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
readers = new Vector();
readers.clear();
if (formats != null) {
boolean addOneDReader =
formats.contains(BarcodeFormat.UPC_A) ||

View file

@ -45,9 +45,6 @@ public final class Result {
ResultPoint[] resultPoints,
BarcodeFormat format,
long timestamp) {
if (text == null && rawBytes == null) {
throw new IllegalArgumentException("Text and bytes are null");
}
this.text = text;
this.rawBytes = rawBytes;
this.resultPoints = resultPoints;
@ -57,7 +54,7 @@ public final class Result {
}
/**
* @return raw text encoded by the barcode, if applicable, otherwise <code>null</code>
* @return raw text encoded by the barcode
*/
public String getText() {
return text;
@ -118,12 +115,13 @@ public final class Result {
}
public void addResultPoints(ResultPoint[] newPoints) {
if (resultPoints == null) {
ResultPoint[] oldResultPoints = resultPoints;
if (oldResultPoints == null) {
resultPoints = newPoints;
} else if (newPoints != null && newPoints.length > 0) {
ResultPoint[] allPoints = new ResultPoint[resultPoints.length + newPoints.length];
System.arraycopy(resultPoints, 0, allPoints, 0, resultPoints.length);
System.arraycopy(newPoints, 0, allPoints, resultPoints.length, newPoints.length);
ResultPoint[] allPoints = new ResultPoint[oldResultPoints.length + newPoints.length];
System.arraycopy(oldResultPoints, 0, allPoints, 0, oldResultPoints.length);
System.arraycopy(newPoints, 0, allPoints, oldResultPoints.length, newPoints.length);
resultPoints = allPoints;
}
}
@ -133,11 +131,7 @@ public final class Result {
}
public String toString() {
if (text == null) {
return "[" + rawBytes.length + " bytes]";
} else {
return text;
}
return text;
}
}

View file

@ -32,6 +32,7 @@ import com.google.zxing.aztec.decoder.Decoder;
import com.google.zxing.aztec.detector.Detector;
import java.util.Hashtable;
import java.util.Vector;
/**
* This implementation can detect and decode Aztec codes in an image.
@ -58,11 +59,11 @@ public final class AztecReader implements Reader {
AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();
ResultPoint[] points = detectorResult.getPoints();
if (hints != null && detectorResult.getPoints() != null) {
if (hints != null) {
ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
if (rpcb != null) {
for (int i = 0; i < detectorResult.getPoints().length; i++) {
rpcb.foundPossibleResultPoint(detectorResult.getPoints()[i]);
for (int i = 0; i < points.length; i++) {
rpcb.foundPossibleResultPoint(points[i]);
}
}
}
@ -71,11 +72,13 @@ public final class AztecReader implements Reader {
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);
if (decoderResult.getByteSegments() != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
Vector byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
}
if (decoderResult.getECLevel() != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel().toString());
String ecLevel = decoderResult.getECLevel();
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
return result;

View file

@ -55,10 +55,10 @@ public final class Detector {
public AztecDetectorResult detect() throws NotFoundException {
// 1. Get the center of the aztec matrix
Point pCenter = getMatrixCenter();
Point pCenter = getMatrixCenter();
// 2. Get the corners of the center bull's eye
Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
// 3. Get the size of the matrix from the bull's eye
extractParameters(bullEyeCornerPoints);
@ -514,19 +514,19 @@ public final class Detector {
int c = getColor(p1, p2);
if (c!=cInit || c == 0) {
if (c != cInit) {
return false;
}
c = getColor(p2, p3);
if (c!=cInit || c == 0) {
if (c != cInit) {
return false;
}
c = getColor(p3, p4);
return c == cInit && c != 0;
return c == cInit;
}

View file

@ -33,7 +33,7 @@ final class AddressBookAUResultParser extends ResultParser {
public static AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
if (rawText == null || rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
if (rawText.indexOf("MEMORY") < 0 || rawText.indexOf("\r\n") < 0) {
return null;
}
@ -63,8 +63,10 @@ final class AddressBookAUResultParser extends ResultParser {
null);
}
private static String[] matchMultipleValuePrefix(String prefix, int max, String rawText,
boolean trim) {
private static String[] matchMultipleValuePrefix(String prefix,
int max,
String rawText,
boolean trim) {
Vector values = null;
for (int i = 1; i <= max; i++) {
String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', trim);

View file

@ -37,7 +37,7 @@ final class AddressBookDoCoMoResultParser extends AbstractDoCoMoResultParser {
public static AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("MECARD:")) {
if (!rawText.startsWith("MECARD:")) {
return null;
}
String[] rawName = matchDoCoMoPrefixedField("N:", rawText, true);

View file

@ -35,7 +35,7 @@ final class BizcardResultParser extends AbstractDoCoMoResultParser {
public static AddressBookParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("BIZCARD:")) {
if (!rawText.startsWith("BIZCARD:")) {
return null;
}
String firstName = matchSingleDoCoMoPrefixedField("N:", rawText, true);

View file

@ -28,7 +28,7 @@ final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {
public static URIParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("MEBKM:")) {
if (!rawText.startsWith("MEBKM:")) {
return null;
}
String title = matchSingleDoCoMoPrefixedField("TITLE:", rawText, true);

View file

@ -48,10 +48,6 @@ public final class CalendarParsedResult extends ParsedResult {
double latitude,
double longitude) {
super(ParsedResultType.CALENDAR);
// Start is required, end is not
if (start == null) {
throw new IllegalArgumentException();
}
validateDate(start);
if (end == null) {
end = start;

View file

@ -30,9 +30,6 @@ final class EmailAddressResultParser extends ResultParser {
public static EmailAddressParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null) {
return null;
}
String emailAddress;
if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) {
// If it starts with mailto:, assume it is definitely trying to be an email address

View file

@ -32,7 +32,7 @@ final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {
public static EmailAddressParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("MATMSG:")) {
if (!rawText.startsWith("MATMSG:")) {
return null;
}
String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText, true);

View file

@ -189,6 +189,6 @@ public class ExpandedProductParsedResult extends ParsedResult {
}
public String getDisplayResult() {
return productID;
return String.valueOf(productID);
}
}

View file

@ -37,9 +37,6 @@ public class ISBNResultParser extends ResultParser {
return null;
}
String rawText = result.getText();
if (rawText == null) {
return null;
}
int length = rawText.length();
if (length != 13) {
return null;

View file

@ -37,12 +37,7 @@ final class ProductResultParser extends ResultParser {
BarcodeFormat.EAN_8.equals(format) || BarcodeFormat.EAN_13.equals(format))) {
return null;
}
// Really neither of these should happen:
String rawText = result.getText();
if (rawText == null) {
return null;
}
int length = rawText.length();
for (int x = 0; x < length; x++) {
char c = rawText.charAt(x);

View file

@ -104,26 +104,24 @@ public abstract class ResultParser {
}
protected static String unescapeBackslash(String escaped) {
if (escaped != null) {
int backslash = escaped.indexOf((int) '\\');
if (backslash >= 0) {
int max = escaped.length();
StringBuffer unescaped = new StringBuffer(max - 1);
unescaped.append(escaped.toCharArray(), 0, backslash);
boolean nextIsEscaped = false;
for (int i = backslash; i < max; i++) {
char c = escaped.charAt(i);
if (nextIsEscaped || c != '\\') {
unescaped.append(c);
nextIsEscaped = false;
} else {
nextIsEscaped = true;
}
}
return unescaped.toString();
int backslash = escaped.indexOf((int) '\\');
if (backslash < 0) {
return escaped;
}
int max = escaped.length();
StringBuffer unescaped = new StringBuffer(max - 1);
unescaped.append(escaped.toCharArray(), 0, backslash);
boolean nextIsEscaped = false;
for (int i = backslash; i < max; i++) {
char c = escaped.charAt(i);
if (nextIsEscaped || c != '\\') {
unescaped.append(c);
nextIsEscaped = false;
} else {
nextIsEscaped = true;
}
}
return escaped;
return unescaped.toString();
}
private static String urlDecode(String escaped) {

View file

@ -43,9 +43,6 @@ final class SMSMMSResultParser extends ResultParser {
public static SMSParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null) {
return null;
}
if (!(rawText.startsWith("sms:") || rawText.startsWith("SMS:") ||
rawText.startsWith("mms:") || rawText.startsWith("MMS:"))) {
return null;

View file

@ -53,7 +53,7 @@ public final class SMSParsedResult extends ParsedResult {
result.append(',');
}
result.append(numbers[i]);
if (vias[i] != null) {
if (vias != null && vias[i] != null) {
result.append(";via=");
result.append(vias[i]);
}

View file

@ -35,9 +35,6 @@ final class SMSTOMMSTOResultParser extends ResultParser {
public static SMSParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null) {
return null;
}
if (!(rawText.startsWith("smsto:") || rawText.startsWith("SMSTO:") ||
rawText.startsWith("mmsto:") || rawText.startsWith("MMSTO:"))) {
return null;

View file

@ -33,9 +33,6 @@ final class SMTPResultParser {
public static EmailAddressParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null) {
return null;
}
if (!(rawText.startsWith("smtp:") || rawText.startsWith("SMTP:"))) {
return null;
}

View file

@ -30,7 +30,7 @@ final class TelResultParser extends ResultParser {
public static TelParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || (!rawText.startsWith("tel:") && !rawText.startsWith("TEL:"))) {
if (!rawText.startsWith("tel:") && !rawText.startsWith("TEL:")) {
return null;
}
// Normalize "TEL:" to "tel:"

View file

@ -31,12 +31,10 @@ final class URIResultParser extends ResultParser {
public static URIParsedResult parse(Result result) {
String rawText = result.getText();
// We specifically handle the odd "URL" scheme here for simplicity
if (rawText != null && rawText.startsWith("URL:")) {
if (rawText.startsWith("URL:")) {
rawText = rawText.substring(4);
}
if (rawText != null) {
rawText = rawText.trim();
}
rawText = rawText.trim();
if (!isBasicallyValidURI(rawText)) {
return null;
}

View file

@ -32,7 +32,7 @@ final class URLTOResultParser {
public static URIParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || (!rawText.startsWith("urlto:") && !rawText.startsWith("URLTO:"))) {
if (!rawText.startsWith("urlto:") && !rawText.startsWith("URLTO:")) {
return null;
}
int titleEnd = rawText.indexOf(':', 6);

View file

@ -38,7 +38,7 @@ final class VCardResultParser extends ResultParser {
// to throw out everything else we parsed just because this was omitted. In fact, Eclair
// is doing just that, and we can't parse its contacts without this leniency.
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("BEGIN:VCARD")) {
if (!rawText.startsWith("BEGIN:VCARD")) {
return null;
}
Vector names = matchVCardPrefixedField("FN", rawText, true);

View file

@ -43,6 +43,9 @@ final class VEventResultParser extends ResultParser {
String summary = matchSingleVCardPrefixedField("SUMMARY", rawText, true);
String start = matchSingleVCardPrefixedField("DTSTART", rawText, true);
if (start == null) {
return null;
}
String end = matchSingleVCardPrefixedField("DTEND", rawText, true);
String location = matchSingleVCardPrefixedField("LOCATION", rawText, true);
String description = matchSingleVCardPrefixedField("DESCRIPTION", rawText, true);
@ -69,9 +72,9 @@ final class VEventResultParser extends ResultParser {
}
}
static String matchSingleVCardPrefixedField(String prefix,
String rawText,
boolean trim) {
private static String matchSingleVCardPrefixedField(String prefix,
String rawText,
boolean trim) {
Vector values = VCardResultParser.matchSingleVCardPrefixedField(prefix, rawText, trim);
return values == null || values.isEmpty() ? null : (String) values.elementAt(0);
}

View file

@ -35,15 +35,20 @@ final class WifiResultParser extends ResultParser {
public static WifiParsedResult parse(Result result) {
String rawText = result.getText();
if (rawText == null || !rawText.startsWith("WIFI:")) {
if (!rawText.startsWith("WIFI:")) {
return null;
}
// Don't remove leading or trailing whitespace
boolean trim = false;
String ssid = matchSinglePrefixedField("S:", rawText, ';', trim);
if (ssid == null || ssid.length() == 0) {
return null;
}
String pass = matchSinglePrefixedField("P:", rawText, ';', trim);
String type = matchSinglePrefixedField("T:", rawText, ';', trim);
if (type == null) {
type = "nopass";
}
return new WifiParsedResult(type, ssid, pass);
}

View file

@ -26,10 +26,9 @@ import java.util.Hashtable;
*/
public final class CharacterSetECI extends ECI {
private static Hashtable VALUE_TO_ECI;
private static Hashtable NAME_TO_ECI;
private static void initialize() {
private static final Hashtable VALUE_TO_ECI;
private static final Hashtable NAME_TO_ECI;
static {
VALUE_TO_ECI = new Hashtable(29);
NAME_TO_ECI = new Hashtable(29);
// TODO figure out if these values are even right!
@ -86,9 +85,6 @@ public final class CharacterSetECI extends ECI {
* @throws IllegalArgumentException if ECI value is invalid
*/
public static CharacterSetECI getCharacterSetECIByValue(int value) {
if (VALUE_TO_ECI == null) {
initialize();
}
if (value < 0 || value >= 900) {
throw new IllegalArgumentException("Bad ECI value: " + value);
}
@ -101,9 +97,6 @@ public final class CharacterSetECI extends ECI {
* but unsupported
*/
public static CharacterSetECI getCharacterSetECIByName(String name) {
if (NAME_TO_ECI == null) {
initialize();
}
return (CharacterSetECI) NAME_TO_ECI.get(name);
}

View file

@ -33,9 +33,6 @@ public final class DecoderResult {
private final String ecLevel;
public DecoderResult(byte[] rawBytes, String text, Vector byteSegments, String ecLevel) {
if (rawBytes == null && text == null) {
throw new IllegalArgumentException();
}
this.rawBytes = rawBytes;
this.text = text;
this.byteSegments = byteSegments;

View file

@ -38,7 +38,7 @@ public class GlobalHistogramBinarizer extends Binarizer {
private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
private byte[] luminances = null;
private int[] buckets = null;
private final int[] buckets = new int[LUMINANCE_BUCKETS];
public GlobalHistogramBinarizer(LuminanceSource source) {
super(source);
@ -125,12 +125,8 @@ public class GlobalHistogramBinarizer extends Binarizer {
if (luminances == null || luminances.length < luminanceSize) {
luminances = new byte[luminanceSize];
}
if (buckets == null) {
buckets = new int[LUMINANCE_BUCKETS];
} else {
for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
buckets[x] = 0;
}
for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
buckets[x] = 0;
}
}

View file

@ -45,9 +45,6 @@ public abstract class GridSampler {
* @param newGridSampler The platform-specific object to install.
*/
public static void setGridSampler(GridSampler newGridSampler) {
if (newGridSampler == null) {
throw new IllegalArgumentException();
}
gridSampler = newGridSampler;
}

View file

@ -50,7 +50,34 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer {
}
public BitMatrix getBlackMatrix() throws NotFoundException {
binarizeEntireImage();
// Calculates the final BitMatrix once for all requests. This could be called once from the
// constructor instead, but there are some advantages to doing it lazily, such as making
// profiling easier, and not doing heavy lifting when callers don't expect it.
if (matrix != null) {
return matrix;
}
LuminanceSource source = getLuminanceSource();
if (source.getWidth() >= MINIMUM_DIMENSION && source.getHeight() >= MINIMUM_DIMENSION) {
byte[] luminances = source.getMatrix();
int width = source.getWidth();
int height = source.getHeight();
int subWidth = width >> 3;
if ((width & 0x07) != 0) {
subWidth++;
}
int subHeight = height >> 3;
if ((height & 0x07) != 0) {
subHeight++;
}
int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
BitMatrix newMatrix = new BitMatrix(width, height);
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);
matrix = newMatrix;
} else {
// If the image is too small, fall back to the global histogram approach.
matrix = super.getBlackMatrix();
}
return matrix;
}
@ -58,35 +85,6 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer {
return new HybridBinarizer(source);
}
// Calculates the final BitMatrix once for all requests. This could be called once from the
// constructor instead, but there are some advantages to doing it lazily, such as making
// profiling easier, and not doing heavy lifting when callers don't expect it.
private void binarizeEntireImage() throws NotFoundException {
if (matrix == null) {
LuminanceSource source = getLuminanceSource();
if (source.getWidth() >= MINIMUM_DIMENSION && source.getHeight() >= MINIMUM_DIMENSION) {
byte[] luminances = source.getMatrix();
int width = source.getWidth();
int height = source.getHeight();
int subWidth = width >> 3;
if ((width & 0x07) != 0) {
subWidth++;
}
int subHeight = height >> 3;
if ((height & 0x07) != 0) {
subHeight++;
}
int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);
matrix = new BitMatrix(width, height);
calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, matrix);
} else {
// If the image is too small, fall back to the global histogram approach.
matrix = super.getBlackMatrix();
}
}
}
// For each 8x8 block in the image, calculate the average black point using a 5x5 grid
// of the blocks around it. Also handles the corner cases (fractional blocks are computed based
// on the last 8 pixels in the row/column which are also used in the previous block).

View file

@ -40,7 +40,7 @@ final class GenericGFPoly {
* constant polynomial (that is, it is not the monomial "0")
*/
GenericGFPoly(GenericGF field, int[] coefficients) {
if (coefficients == null || coefficients.length == 0) {
if (coefficients.length == 0) {
throw new IllegalArgumentException();
}
this.field = field;

View file

@ -239,16 +239,17 @@ public final class Detector {
ResultPoint c2 = new ResultPoint(topRight.getX()+corr*cos, topRight.getY()+corr*sin);
if (!isValid(c1)){
if (isValid(c2)){
return c2;
}
return null;
} else if (!isValid(c2)){
return c1;
}
int l1 = Math.abs(dimensionTop - transitionsBetween(topLeft, c1).getTransitions()) +
if (!isValid(c1)) {
if (isValid(c2)) {
return c2;
}
return null;
}
if (!isValid(c2)){
return c1;
}
int l1 = Math.abs(dimensionTop - transitionsBetween(topLeft, c1).getTransitions()) +
Math.abs(dimensionRight - transitionsBetween(bottomRight, c1).getTransitions());
int l2 = Math.abs(dimensionTop - transitionsBetween(topLeft, c2).getTransitions()) +
Math.abs(dimensionRight - transitionsBetween(bottomRight, c2).getTransitions());
@ -284,16 +285,17 @@ public final class Detector {
ResultPoint c2 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);
if (!isValid(c1)) {
if (isValid(c2)) {
return c2;
}
return null;
} else if (!isValid(c2)) {
return c1;
}
int l1 = Math.abs(transitionsBetween(topLeft, c1).getTransitions() -
if (!isValid(c1)) {
if (isValid(c2)) {
return c2;
}
return null;
}
if (!isValid(c2)) {
return c1;
}
int l1 = Math.abs(transitionsBetween(topLeft, c1).getTransitions() -
transitionsBetween(bottomRight, c1).getTransitions());
int l2 = Math.abs(transitionsBetween(topLeft, c2).getTransitions() -
transitionsBetween(bottomRight, c2).getTransitions());
@ -313,7 +315,7 @@ public final class Detector {
return (int) (d + 0.5f);
}
// L2 distance
// L2 distance
private static int distance(ResultPoint a, ResultPoint b) {
return round((float) Math.sqrt((a.getX() - b.getX())
* (a.getX() - b.getX()) + (a.getY() - b.getY())
@ -415,10 +417,10 @@ public final class Detector {
this.to = to;
this.transitions = transitions;
}
public ResultPoint getFrom() {
ResultPoint getFrom() {
return from;
}
public ResultPoint getTo() {
ResultPoint getTo() {
return to;
}
public int getTransitions() {

View file

@ -144,6 +144,9 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader
private static Result translateResultPoints(Result result, int xOffset, int yOffset) {
ResultPoint[] oldResultPoints = result.getResultPoints();
if (oldResultPoints == null) {
return result;
}
ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length];
for (int i = 0; i < oldResultPoints.length; i++) {
ResultPoint oldPoint = oldResultPoints[i];

View file

@ -55,11 +55,13 @@ public final class QRCodeMultiReader extends QRCodeReader implements MultipleBar
ResultPoint[] points = detectorResult[i].getPoints();
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points,
BarcodeFormat.QR_CODE);
if (decoderResult.getByteSegments() != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
Vector byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
}
if (decoderResult.getECLevel() != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel().toString());
String ecLevel = decoderResult.getECLevel();
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
results.addElement(result);
} catch (ReaderException re) {

View file

@ -46,7 +46,7 @@ public final class MultiDetector extends Detector {
MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image);
FinderPatternInfo[] info = finder.findMulti(hints);
if (info == null || info.length == 0) {
if (info.length == 0) {
throw NotFoundException.getNotFoundInstance();
}

View file

@ -67,9 +67,11 @@ public abstract class OneDReader implements Reader {
result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(orientation));
// Update result points
ResultPoint[] points = result.getResultPoints();
int height = rotatedImage.getHeight();
for (int i = 0; i < points.length; i++) {
points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());
if (points != null) {
int height = rotatedImage.getHeight();
for (int i = 0; i < points.length; i++) {
points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());
}
}
return result;
} else {
@ -159,8 +161,10 @@ public abstract class OneDReader implements Reader {
result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {

View file

@ -53,7 +53,7 @@ public abstract class OneDimensionalCodeWriter implements Writer {
int width,
int height,
Hashtable hints) throws WriterException {
if (contents == null || contents.length() == 0) {
if (contents.length() == 0) {
throw new IllegalArgumentException("Found empty contents");
}

View file

@ -173,10 +173,12 @@ final class UPCEANExtensionSupport {
if ("90000".equals(raw)) {
// No suggested retail price
return null;
} else if ("99991".equals(raw)) {
}
if ("99991".equals(raw)) {
// Complementary
return "0.00";
} else if ("99990".equals(raw)) {
}
if ("99990".equals(raw)) {
return "Used";
}
// Otherwise... unknown currency?

View file

@ -98,7 +98,7 @@ public final class RSSUtils {
return val;
}
static int combins(int n, int r) {
private static int combins(int n, int r) {
int maxDenom;
int minDenom;
if (n - r > r) {

View file

@ -156,7 +156,7 @@ public final class RSSExpandedReader extends AbstractRSSReader{
);
}
private boolean checkChecksum(){
private boolean checkChecksum() {
ExpandedPair firstPair = (ExpandedPair)this.pairs.elementAt(0);
DataCharacter checkCharacter = firstPair.getLeftChar();
DataCharacter firstCharacter = firstPair.getRightChar();
@ -168,8 +168,9 @@ public final class RSSExpandedReader extends AbstractRSSReader{
ExpandedPair currentPair = (ExpandedPair)this.pairs.elementAt(i);
checksum += currentPair.getLeftChar().getChecksumPortion();
S++;
if(currentPair.getRightChar() != null){
checksum += currentPair.getRightChar().getChecksumPortion();
DataCharacter currentRightChar = currentPair.getRightChar();
if (currentRightChar != null) {
checksum += currentRightChar.getChecksumPortion();
S++;
}
}

View file

@ -48,7 +48,8 @@ public abstract class AbstractExpandedDecoder {
public static AbstractExpandedDecoder createDecoder(BitArray information){
if (information.get(1)) {
return new AI01AndOtherAIs(information);
} else if (!information.get(2)) {
}
if (!information.get(2)) {
return new AnyAIDecoder(information);
}

View file

@ -73,7 +73,7 @@ public final class Decoder {
// Construct a parser to read the data codewords and error-correction level
BitMatrixParser parser = new BitMatrixParser(bits);
int[] codewords = parser.readCodewords();
if (codewords == null || codewords.length == 0) {
if (codewords.length == 0) {
throw FormatException.getFormatInstance();
}
@ -126,7 +126,7 @@ public final class Decoder {
* @throws ChecksumException if error correction fails
*/
private static int correctErrors(int[] codewords, int[] erasures, int numECCodewords) throws FormatException {
if ((erasures != null && erasures.length > numECCodewords / 2 + MAX_ERRORS) ||
if (erasures.length > numECCodewords / 2 + MAX_ERRORS ||
numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) {
// Too many errors or EC Codewords is corrupted
throw FormatException.getFormatInstance();
@ -134,15 +134,13 @@ public final class Decoder {
// Try to correct the errors
// TODO enable error correction
int result = 0; // rsDecoder.correctErrors(codewords, numECCodewords);
if (erasures != null) {
int numErasures = erasures.length;
if (result > 0) {
numErasures -= result;
}
if (numErasures > MAX_ERRORS) {
// Still too many errors
throw FormatException.getFormatInstance();
}
int numErasures = erasures.length;
if (result > 0) {
numErasures -= result;
}
if (numErasures > MAX_ERRORS) {
// Still too many errors
throw FormatException.getFormatInstance();
}
return result;
}

View file

@ -77,8 +77,8 @@ final class BarcodeRow {
*/
byte[] getScaledRow(int scale) {
byte[] output = new byte[row.length * scale];
for (int ii = 0; ii < row.length * scale; ii++) {
output[ii] = row[ii / scale];
for (int i = 0; i < output.length; i++) {
output[i] = row[i / scale];
}
return output;
}

View file

@ -506,6 +506,7 @@ final class PDF417 {
0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2,
0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea}};
public static final float PREFERRED_RATIO = 3.0f;
private static final float DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm
private static final float HEIGHT = 2.0f; //mm
@ -689,10 +690,6 @@ final class PDF417 {
int[] dimension = determineDimensions(sourceCodeWords);
if (dimension == null) {
throw new WriterException("Unable to fit message in columns");
}
int cols = dimension[0];
int rows = dimension[1];
@ -729,7 +726,7 @@ final class PDF417 {
* @param sourceCodeWords number of code words
* @return dimension object containing cols as width and rows as height
*/
int[] determineDimensions(int sourceCodeWords) {
int[] determineDimensions(int sourceCodeWords) throws WriterException {
float ratio = 0.0f;
int[] dimension = null;
@ -750,8 +747,7 @@ final class PDF417 {
float newRatio = ((17 * cols + 69) * DEFAULT_MODULE_WIDTH) / (rows * HEIGHT);
// ignore if previous ratio is closer to preferred ratio
float preferredRatio = 3.0f;
if (dimension != null && Math.abs(newRatio - preferredRatio) > Math.abs(ratio - preferredRatio)) {
if (dimension != null && Math.abs(newRatio - PREFERRED_RATIO) > Math.abs(ratio - PREFERRED_RATIO)) {
continue;
}
@ -759,6 +755,9 @@ final class PDF417 {
dimension = new int[] {cols, rows};
}
if (dimension == null) {
throw new WriterException("Unable to fit message in columns");
}
return dimension;
}

View file

@ -171,14 +171,17 @@ final class PDF417HighLevelEncoder {
if (b == 0) {
b = 1;
}
if (b == 1 && encodingMode == TEXT_COMPACTION) {
// I don't see how this ever takes value TEXT_COMPACTION?
//if (b == 1 && encodingMode == TEXT_COMPACTION) {
if (b == 1) {
//Switch for one byte (instead of latch)
encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);
} else {
//Mode latch performed by encodeBinary()
encodeBinary(bytes, p, b, encodingMode, sb);
encodingMode = BYTE_COMPACTION;
textSubMode = SUBMODE_ALPHA; //Reset after latch
// ... so this is redundant?
//encodingMode = BYTE_COMPACTION;
//textSubMode = SUBMODE_ALPHA; //Reset after latch
}
p += b;
}

View file

@ -33,6 +33,7 @@ import com.google.zxing.qrcode.decoder.Decoder;
import com.google.zxing.qrcode.detector.Detector;
import java.util.Hashtable;
import java.util.Vector;
/**
* This implementation can detect and decode QR Codes in an image.
@ -76,11 +77,13 @@ public class QRCodeReader implements Reader {
}
Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);
if (decoderResult.getByteSegments() != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult.getByteSegments());
Vector byteSegments = decoderResult.getByteSegments();
if (byteSegments != null) {
result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
}
if (decoderResult.getECLevel() != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.getECLevel().toString());
String ecLevel = decoderResult.getECLevel();
if (ecLevel != null) {
result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
}
return result;
}

View file

@ -46,7 +46,7 @@ public final class QRCodeWriter implements Writer {
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height,
Hashtable hints) throws WriterException {
if (contents == null || contents.length() == 0) {
if (contents.length() == 0) {
throw new IllegalArgumentException("Found empty contents");
}
@ -76,6 +76,9 @@ public final class QRCodeWriter implements Writer {
// 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).
private static BitMatrix renderResult(QRCode code, int width, int height) {
ByteMatrix input = code.getMatrix();
if (input == null) {
throw new IllegalStateException();
}
int inputWidth = input.getWidth();
int inputHeight = input.getHeight();
int qrWidth = inputWidth + (QUIET_ZONE_SIZE << 1);

View file

@ -114,9 +114,10 @@ final class BitMatrixParser {
}
}
parsedVersion = Version.decodeVersionInformation(versionBits);
if (parsedVersion != null && parsedVersion.getDimensionForVersion() == dimension) {
return parsedVersion;
Version theParsedVersion = Version.decodeVersionInformation(versionBits);
if (theParsedVersion != null && theParsedVersion.getDimensionForVersion() == dimension) {
parsedVersion = theParsedVersion;
return theParsedVersion;
}
// Hmm, failed. Try bottom left: 6 wide by 3 tall
@ -127,9 +128,10 @@ final class BitMatrixParser {
}
}
parsedVersion = Version.decodeVersionInformation(versionBits);
if (parsedVersion != null && parsedVersion.getDimensionForVersion() == dimension) {
return parsedVersion;
theParsedVersion = Version.decodeVersionInformation(versionBits);
if (theParsedVersion != null && theParsedVersion.getDimensionForVersion() == dimension) {
parsedVersion = theParsedVersion;
return theParsedVersion;
}
throw FormatException.getFormatInstance();
}

View file

@ -316,11 +316,13 @@ final class DecodedBitStreamParser {
if ((firstByte & 0x80) == 0) {
// just one byte
return firstByte & 0x7F;
} else if ((firstByte & 0xC0) == 0x80) {
}
if ((firstByte & 0xC0) == 0x80) {
// two bytes
int secondByte = bits.readBits(8);
return ((firstByte & 0x3F) << 8) | secondByte;
} else if ((firstByte & 0xE0) == 0xC0) {
}
if ((firstByte & 0xE0) == 0xC0) {
// three bytes
int secondThirdBytes = bits.readBits(16);
return ((firstByte & 0x1F) << 16) | secondThirdBytes;

View file

@ -87,9 +87,6 @@ public final class Mode {
* count of characters that will follow encoded in this Mode
*/
public int getCharacterCountBits(Version version) {
if (characterCountBitsForVersions == null) {
throw new IllegalArgumentException("Character count doesn't apply to this mode");
}
int number = version.getVersionNumber();
int offset;
if (number <= 9) {

View file

@ -124,12 +124,10 @@ public final class Encoder {
// Step 7: Choose the mask pattern and set to "qrCode".
ByteMatrix matrix = new ByteMatrix(qrCode.getMatrixWidth(), qrCode.getMatrixWidth());
qrCode.setMaskPattern(chooseMaskPattern(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
matrix));
qrCode.setMaskPattern(chooseMaskPattern(finalBits, qrCode.getECLevel(), qrCode.getVersion(), matrix));
// Step 8. Build the matrix and set it to "qrCode".
MatrixUtil.buildMatrix(finalBits, qrCode.getECLevel(), qrCode.getVersion(),
qrCode.getMaskPattern(), matrix);
MatrixUtil.buildMatrix(finalBits, qrCode.getECLevel(), qrCode.getVersion(), qrCode.getMaskPattern(), matrix);
qrCode.setMatrix(matrix);
// Step 9. Make sure we have a valid QR Code.
if (!qrCode.isValid()) {
@ -156,7 +154,7 @@ public final class Encoder {
* Choose the best mode by examining the content. Note that 'encoding' is used as a hint;
* if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.
*/
public static Mode chooseMode(String content, String encoding) {
private static Mode chooseMode(String content, String encoding) {
if ("Shift_JIS".equals(encoding)) {
// Choose Kanji mode if all input are double-byte characters
return isOnlyDoubleByteKanji(content) ? Mode.KANJI : Mode.BYTE;
@ -175,7 +173,8 @@ public final class Encoder {
}
if (hasAlphanumeric) {
return Mode.ALPHANUMERIC;
} else if (hasNumeric) {
}
if (hasNumeric) {
return Mode.NUMERIC;
}
return Mode.BYTE;

View file

@ -20,7 +20,7 @@ package com.google.zxing.qrcode.encoder;
* @author satorux@google.com (Satoru Takabayashi) - creator
* @author dswitkin@google.com (Daniel Switkin) - ported from C++
*/
public final class MaskUtil {
final class MaskUtil {
private MaskUtil() {
// do nothing
@ -28,13 +28,13 @@ public final class MaskUtil {
// Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
// give penalty to them. Example: 00000 or 11111.
public static int applyMaskPenaltyRule1(ByteMatrix matrix) {
static int applyMaskPenaltyRule1(ByteMatrix matrix) {
return applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false);
}
// Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
// penalty to them.
public static int applyMaskPenaltyRule2(ByteMatrix matrix) {
static int applyMaskPenaltyRule2(ByteMatrix matrix) {
int penalty = 0;
byte[][] array = matrix.getArray();
int width = matrix.getWidth();
@ -53,7 +53,7 @@ public final class MaskUtil {
// Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or
// 10111010000, and give penalty to them. If we find patterns like 000010111010000, we give
// penalties twice (i.e. 40 * 2).
public static int applyMaskPenaltyRule3(ByteMatrix matrix) {
static int applyMaskPenaltyRule3(ByteMatrix matrix) {
int penalty = 0;
byte[][] array = matrix.getArray();
int width = matrix.getWidth();
@ -115,7 +115,7 @@ public final class MaskUtil {
// - 55% => 10
// - 55% => 20
// - 100% => 100
public static int applyMaskPenaltyRule4(ByteMatrix matrix) {
static int applyMaskPenaltyRule4(ByteMatrix matrix) {
int numDarkCells = 0;
byte[][] array = matrix.getArray();
int width = matrix.getWidth();
@ -134,7 +134,7 @@ public final class MaskUtil {
// Return the mask bit for "getMaskPattern" at "x" and "y". See 8.8 of JISX0510:2004 for mask
// pattern conditions.
public static boolean getDataMaskBit(int maskPattern, int x, int y) {
static boolean getDataMaskBit(int maskPattern, int x, int y) {
if (!QRCode.isValidMaskPattern(maskPattern)) {
throw new IllegalArgumentException("Invalid mask pattern");
}

View file

@ -24,7 +24,7 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
* @author satorux@google.com (Satoru Takabayashi) - creator
* @author dswitkin@google.com (Daniel Switkin) - ported from C++
*/
public final class MatrixUtil {
final class MatrixUtil {
private MatrixUtil() {
// do nothing
@ -130,14 +130,17 @@ public final class MatrixUtil {
//
// JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding
// with the ByteMatrix initialized all to zero.
public static void clearMatrix(ByteMatrix matrix) {
static void clearMatrix(ByteMatrix matrix) {
matrix.clear((byte) -1);
}
// Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
// success, store the result in "matrix" and return true.
public static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, int version,
int maskPattern, ByteMatrix matrix) throws WriterException {
static void buildMatrix(BitArray dataBits,
ErrorCorrectionLevel ecLevel,
int version,
int maskPattern,
ByteMatrix matrix) throws WriterException {
clearMatrix(matrix);
embedBasicPatterns(version, matrix);
// Type information appear with any version.
@ -154,7 +157,7 @@ public final class MatrixUtil {
// - Timing patterns
// - Dark dot at the left bottom corner
// - Position adjustment patterns, if need be
public static void embedBasicPatterns(int version, ByteMatrix matrix) throws WriterException {
static void embedBasicPatterns(int version, ByteMatrix matrix) throws WriterException {
// Let's get started with embedding big squares at corners.
embedPositionDetectionPatternsAndSeparators(matrix);
// Then, embed the dark dot at the left bottom corner.
@ -167,7 +170,7 @@ public final class MatrixUtil {
}
// Embed type information. On success, modify the matrix.
public static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)
static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)
throws WriterException {
BitArray typeInfoBits = new BitArray();
makeTypeInfoBits(ecLevel, maskPattern, typeInfoBits);
@ -198,7 +201,7 @@ public final class MatrixUtil {
// Embed version information if need be. On success, modify the matrix and return true.
// See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
public static void maybeEmbedVersionInfo(int version, ByteMatrix matrix) throws WriterException {
static void maybeEmbedVersionInfo(int version, ByteMatrix matrix) throws WriterException {
if (version < 7) { // Version info is necessary if version >= 7.
return; // Don't need version info.
}
@ -222,7 +225,7 @@ public final class MatrixUtil {
// Embed "dataBits" using "getMaskPattern". On success, modify the matrix and return true.
// For debugging purposes, it skips masking process if "getMaskPattern" is -1.
// See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
public static void embedDataBits(BitArray dataBits, int maskPattern, ByteMatrix matrix)
static void embedDataBits(BitArray dataBits, int maskPattern, ByteMatrix matrix)
throws WriterException {
int bitIndex = 0;
int direction = -1;
@ -276,7 +279,7 @@ public final class MatrixUtil {
// - findMSBSet(0) => 0
// - findMSBSet(1) => 1
// - findMSBSet(255) => 8
public static int findMSBSet(int value) {
static int findMSBSet(int value) {
int numDigits = 0;
while (value != 0) {
value >>>= 1;
@ -310,7 +313,7 @@ public final class MatrixUtil {
//
// Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit
// operations. We don't care if cofficients are positive or negative.
public static int calculateBCHCode(int value, int poly) {
static int calculateBCHCode(int value, int poly) {
// If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1
// from 13 to make it 12.
int msbSetInPoly = findMSBSet(poly);
@ -326,7 +329,7 @@ public final class MatrixUtil {
// Make bit vector of type information. On success, store the result in "bits" and return true.
// Encode error correction level and mask pattern. See 8.9 of
// JISX0510:2004 (p.45) for details.
public static void makeTypeInfoBits(ErrorCorrectionLevel ecLevel, int maskPattern, BitArray bits)
static void makeTypeInfoBits(ErrorCorrectionLevel ecLevel, int maskPattern, BitArray bits)
throws WriterException {
if (!QRCode.isValidMaskPattern(maskPattern)) {
throw new WriterException("Invalid mask pattern");
@ -348,7 +351,7 @@ public final class MatrixUtil {
// Make bit vector of version information. On success, store the result in "bits" and return true.
// See 8.10 of JISX0510:2004 (p.45) for details.
public static void makeVersionInfoBits(int version, BitArray bits) throws WriterException {
static void makeVersionInfoBits(int version, BitArray bits) throws WriterException {
bits.appendBits(version, 6);
int bchCode = calculateBCHCode(version, VERSION_INFO_POLY);
bits.appendBits(bchCode, 12);

View file

@ -216,24 +216,4 @@ public final class QRCode {
return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
}
// Return true if the all values in the matrix are binary numbers.
//
// JAVAPORT: This is going to be super expensive and unnecessary, we should not call this in
// production. I'm leaving it because it may be useful for testing. It should be removed entirely
// if ByteMatrix is changed never to contain a -1.
/*
private static boolean EverythingIsBinary(final ByteMatrix matrix) {
for (int y = 0; y < matrix.height(); ++y) {
for (int x = 0; x < matrix.width(); ++x) {
int value = matrix.get(y, x);
if (!(value == 0 || value == 1)) {
// Found non zero/one value.
return false;
}
}
}
return true;
}
*/
}

View file

@ -60,6 +60,7 @@ public final class ExpandedProductParsedResultTestCase extends Assert {
Result result = new Result(text, null, null, BarcodeFormat.RSS_EXPANDED);
ExpandedProductParsedResult o = ExpandedProductResultParser.parse(result);
assertNotNull(o);
assertEquals(productID, o.getProductID());
assertEquals(sscc, o.getSscc());
assertEquals(lotNumber, o.getLotNumber());

View file

@ -316,7 +316,7 @@ public final class ParsedReaderResultTestCase extends Assert {
*/
private static void doTestResult(String contents, String goldenResult, ParsedResultType type) {
doTestResult(contents, goldenResult, type, null);
doTestResult(contents, goldenResult, type, BarcodeFormat.QR_CODE); // QR code is arbitrary
}
private static void doTestResult(String contents, String goldenResult, ParsedResultType type,

View file

@ -45,9 +45,10 @@ public final class ReedSolomonEncoderQRCodeTestCase extends AbstractReedSolomonT
ReedSolomonEncoder encoder = new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256);
ReedSolomonDecoder decoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);
for (int i = 0; i < 100; i++) {
int size = random.nextInt(1000);
int size = 1 + random.nextInt(1000);
int[] toEncode = new int[size];
int ecBytes = 1 + random.nextInt(2 * (1 + size / 8));
ecBytes = Math.min(ecBytes, size - 1);
int dataBytes = size - ecBytes;
for (int j = 0; j < dataBytes; j++) {
toEncode[j] = random.nextInt(256);

View file

@ -68,17 +68,23 @@ public final class RSSExpandedInternalTestCase extends Assert {
ExpandedPair pair1 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
previousPairs.add(pair1);
assertEquals(0, pair1.getFinderPattern().getValue());
FinderPattern finderPattern = pair1.getFinderPattern();
assertNotNull(finderPattern);
assertEquals(0, finderPattern.getValue());
assertFalse(pair1.mayBeLast());
ExpandedPair pair2 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
previousPairs.add(pair2);
assertEquals(1, pair2.getFinderPattern().getValue());
finderPattern = pair2.getFinderPattern();
assertNotNull(finderPattern);
assertEquals(1, finderPattern.getValue());
assertFalse(pair2.mayBeLast());
ExpandedPair pair3 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
previousPairs.add(pair3);
assertEquals(1, pair3.getFinderPattern().getValue());
finderPattern = pair3.getFinderPattern();
assertNotNull(finderPattern);
assertEquals(1, finderPattern.getValue());
assertTrue(pair3.mayBeLast());
try{
@ -109,12 +115,16 @@ public final class RSSExpandedInternalTestCase extends Assert {
ExpandedPair pair1 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
previousPairs.add(pair1);
assertEquals(0, pair1.getFinderPattern().getValue());
FinderPattern finderPattern = pair1.getFinderPattern();
assertNotNull(finderPattern);
assertEquals(0, finderPattern.getValue());
assertFalse(pair1.mayBeLast());
ExpandedPair pair2 = rssExpandedReader.retrieveNextPair(row, previousPairs, rowNumber);
previousPairs.add(pair2);
assertEquals(0, pair2.getFinderPattern().getValue());
finderPattern = pair2.getFinderPattern();
assertNotNull(finderPattern);
assertEquals(0, finderPattern.getValue());
assertTrue(pair2.mayBeLast());
}

View file

@ -40,6 +40,7 @@ public final class FormatInformationTestCase extends Assert {
// Normal case
FormatInformation expected =
FormatInformation.decodeFormatInformation(MASKED_TEST_FORMAT_INFO, MASKED_TEST_FORMAT_INFO);
assertNotNull(expected);
assertEquals((byte) 0x07, expected.getDataMask());
assertSame(ErrorCorrectionLevel.Q, expected.getErrorCorrectionLevel());
// where the code forgot the mask!

View file

@ -62,12 +62,18 @@ public final class VersionTestCase extends Assert {
@Test
public void testDecodeVersionInformation() {
// Spot check
assertEquals(7, Version.decodeVersionInformation(0x07C94).getVersionNumber());
assertEquals(12, Version.decodeVersionInformation(0x0C762).getVersionNumber());
assertEquals(17, Version.decodeVersionInformation(0x1145D).getVersionNumber());
assertEquals(22, Version.decodeVersionInformation(0x168C9).getVersionNumber());
assertEquals(27, Version.decodeVersionInformation(0x1B08E).getVersionNumber());
assertEquals(32, Version.decodeVersionInformation(0x209D5).getVersionNumber());
doTestVersion(7, 0x07C94);
doTestVersion(12, 0x0C762);
doTestVersion(17, 0x1145D);
doTestVersion(22, 0x168C9);
doTestVersion(27, 0x1B08E);
doTestVersion(32, 0x209D5);
}
private static void doTestVersion(int expectedVersion, int mask) {
Version version = Version.decodeVersionInformation(mask);
assertNotNull(version);
assertEquals(expectedVersion, version.getVersionNumber());
}
}

View file

@ -68,7 +68,7 @@ public final class CommandLineRunner {
} else if (arg.startsWith("--crop")) {
int[] crop = new int[4];
String[] tokens = arg.substring(7).split(",");
for (int i = 0; i < config.getCrop().length; i++) {
for (int i = 0; i < crop.length; i++) {
crop[i] = Integer.parseInt(tokens[i]);
}
config.setCrop(crop);

View file

@ -102,7 +102,7 @@ public final class GUIRunner extends JFrame {
} catch (ReaderException re) {
return re.toString();
}
return result.getText();
return String.valueOf(result.getText());
}
}