mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
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:
parent
e76c5785c7
commit
303ed2e6a0
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -189,6 +189,6 @@ public class ExpandedProductParsedResult extends ParsedResult {
|
|||
}
|
||||
|
||||
public String getDisplayResult() {
|
||||
return productID;
|
||||
return String.valueOf(productID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -102,7 +102,7 @@ public final class GUIRunner extends JFrame {
|
|||
} catch (ReaderException re) {
|
||||
return re.toString();
|
||||
}
|
||||
return result.getText();
|
||||
return String.valueOf(result.getText());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue