Biiig standardization of whitespace. 2 space indents now, no tabs.

git-svn-id: https://zxing.googlecode.com/svn/trunk@191 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2008-02-14 20:25:54 +00:00
parent c36a3b64cc
commit eb2fa80eaf
71 changed files with 700 additions and 521 deletions

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.zxing.client.android"> package="com.google.zxing.client.android">
<application android:icon="@drawable/icon"> <application android:icon="@drawable/icon">
<activity class=".BarcodeReaderCaptureActivity" android:label="@string/app_name"> <activity class=".BarcodeReaderCaptureActivity" android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:value="android.intent.action.MAIN" /> <action android:value="android.intent.action.MAIN"/>
<category android:value="android.intent.category.LAUNCHER" /> <category android:value="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
</application> </application>
<uses-permission id="android.permission.READ_CONTACTS" /> <uses-permission id="android.permission.READ_CONTACTS"/>
<uses-permission id="android.permission.WRITE_CONTACTS" /> <uses-permission id="android.permission.WRITE_CONTACTS"/>
</manifest> </manifest>

View file

@ -65,7 +65,7 @@
</not> </not>
</condition> </condition>
</fail> </fail>
<fail message="Please build 'core' first"> <fail message="Please build 'core' first">
<condition> <condition>
<not> <not>
<available file="../core/core.jar" type="file"/> <available file="../core/core.jar" type="file"/>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
</LinearLayout> </LinearLayout>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Barcode Reader</string> <string name="app_name">Barcode Reader</string>
<string name="button_no">No</string> <string name="button_no">No</string>
<string name="button_ok">OK</string> <string name="button_ok">OK</string>
<string name="button_yes">Yes</string> <string name="button_yes">Yes</string>
<string name="menu_about">About...</string> <string name="menu_about">About...</string>

View file

@ -34,18 +34,18 @@ import com.google.zxing.client.result.ParsedReaderResultType;
/** /**
* The barcode reader activity itself. This is loosely based on the CameraPreview * The barcode reader activity itself. This is loosely based on the CameraPreview
* example included in the Android SDK. * example included in the Android SDK.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
* @author Android Team (for CameraPreview example) * @author Android Team (for CameraPreview example)
*/ */
public final class BarcodeReaderCaptureActivity extends Activity { public final class BarcodeReaderCaptureActivity extends Activity {
private CameraManager cameraManager; private CameraManager cameraManager;
private CameraSurfaceView surfaceView; private CameraSurfaceView surfaceView;
private WorkerThread workerThread; private WorkerThread workerThread;
private static final int ABOUT_ID = Menu.FIRST; private static final int ABOUT_ID = Menu.FIRST;
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
@ -64,7 +64,7 @@ public final class BarcodeReaderCaptureActivity extends Activity {
workerThread.requestPreviewLoop(); workerThread.requestPreviewLoop();
workerThread.start(); workerThread.start();
} }
@Override @Override
protected boolean isFullscreenOpaque() { protected boolean isFullscreenOpaque() {
// Our main window is set to translucent, but we know that we will // Our main window is set to translucent, but we know that we will
@ -103,14 +103,14 @@ public final class BarcodeReaderCaptureActivity extends Activity {
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
} }
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
menu.add(0, ABOUT_ID, R.string.menu_about); menu.add(0, ABOUT_ID, R.string.menu_about);
return true; return true;
} }
@Override @Override
public boolean onOptionsItemSelected(Menu.Item item) { public boolean onOptionsItemSelected(Menu.Item item) {
switch (item.getId()) { switch (item.getId()) {
@ -120,31 +120,31 @@ public final class BarcodeReaderCaptureActivity extends Activity {
context.getString(R.string.msg_about), context.getString(R.string.msg_about),
context.getString(R.string.button_ok), null, true, null); context.getString(R.string.button_ok), null, true, null);
break; break;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
Handler messageHandler = new Handler() { private final Handler messageHandler = new Handler() {
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
switch (message.what) { switch (message.what) {
case R.id.decoding_succeeded_message: case R.id.decoding_succeeded_message:
handleDecode((Result)message.obj); handleDecode((Result) message.obj);
break; break;
case R.id.decoding_failed_message: case R.id.decoding_failed_message:
Context context = getApplication(); Context context = getApplication();
showAlert(context.getString(R.string.title_no_barcode_detected), showAlert(context.getString(R.string.title_no_barcode_detected),
context.getString(R.string.msg_no_barcode_detected), context.getString(R.string.msg_no_barcode_detected),
context.getString(R.string.button_ok), null, true, null); context.getString(R.string.button_ok), null, true, null);
break; break;
} }
} }
}; };
public void restartPreview() { public void restartPreview() {
workerThread.requestPreviewLoop(); workerThread.requestPreviewLoop();
} }
// TODO(dswitkin): These deprecated showAlert calls need to be updated. // TODO(dswitkin): These deprecated showAlert calls need to be updated.
private void handleDecode(Result rawResult) { private void handleDecode(Result rawResult) {
ResultPoint[] points = rawResult.getResultPoints(); ResultPoint[] points = rawResult.getResultPoints();
@ -191,5 +191,5 @@ public final class BarcodeReaderCaptureActivity extends Activity {
return R.string.title_barcode_detected; return R.string.title_barcode_detected;
} }
} }
} }

View file

@ -16,8 +16,6 @@
package com.google.zxing.client.android; package com.google.zxing.client.android;
import com.google.zxing.ResultPoint;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
@ -27,18 +25,19 @@ import android.hardware.CameraDevice;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.WindowManager; import android.view.WindowManager;
import com.google.zxing.ResultPoint;
/** /**
* This object wraps the CameraDevice and expects to be the only one talking to it. The * This object wraps the CameraDevice and expects to be the only one talking to it. The
* implementation encapsulates the steps needed to take preview-sized images and well as high * implementation encapsulates the steps needed to take preview-sized images and well as high
* resolution stills. * resolution stills.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
*/ */
final class CameraManager { final class CameraManager {
private static final String TAG = "CameraManager"; private static final String TAG = "CameraManager";
private Context context; private Context context;
private Point cameraResolution; private Point cameraResolution;
private Point stillResolution; private Point stillResolution;
@ -49,7 +48,7 @@ final class CameraManager {
private CameraDevice camera; private CameraDevice camera;
private CameraDevice.CaptureParams params; private CameraDevice.CaptureParams params;
private boolean previewMode; private boolean previewMode;
CameraManager(Context context) { CameraManager(Context context) {
this.context = context; this.context = context;
calculateStillResolution(); calculateStillResolution();
@ -60,38 +59,38 @@ final class CameraManager {
previewMode = false; previewMode = false;
setPreviewMode(true); setPreviewMode(true);
} }
public void openDriver() { public void openDriver() {
if (camera == null) { if (camera == null) {
camera = CameraDevice.open(); camera = CameraDevice.open();
} }
} }
public void closeDriver() { public void closeDriver() {
if (camera != null) { if (camera != null) {
camera.close(); camera.close();
camera = null; camera = null;
} }
} }
public void capturePreview(Canvas canvas) { public void capturePreview(Canvas canvas) {
setPreviewMode(true); setPreviewMode(true);
camera.capture(canvas); camera.capture(canvas);
} }
public Bitmap captureStill() { public Bitmap captureStill() {
setPreviewMode(false); setPreviewMode(false);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
camera.capture(canvas); camera.capture(canvas);
return bitmap; return bitmap;
} }
/** /**
* Calculates the framing rect which the UI should draw to show the user where to place the * Calculates the framing rect which the UI should draw to show the user where to place the
* barcode. The actual captured image should be a bit larger than indicated because they might * barcode. The actual captured image should be a bit larger than indicated because they might
* frame the shot too tightly. This target helps with alignment as well as forces the user to hold * frame the shot too tightly. This target helps with alignment as well as forces the user to hold
* the device far enough away to ensure the image will be in focus. * the device far enough away to ensure the image will be in focus.
* *
* @return The rectangle to draw on screen in window coordinates. * @return The rectangle to draw on screen in window coordinates.
*/ */
public Rect getFramingRect() { public Rect getFramingRect() {
@ -103,10 +102,10 @@ final class CameraManager {
} }
return framingRect; return framingRect;
} }
/** /**
* Converts the result points from still resolution coordinates to screen coordinates. * Converts the result points from still resolution coordinates to screen coordinates.
* *
* @param points The points returned by the Reader subclass through Result.getResultPoints(). * @param points The points returned by the Reader subclass through Result.getResultPoints().
* @return An array of Points scaled to the size of the framing rect and offset appropriately * @return An array of Points scaled to the size of the framing rect and offset appropriately
* so they can be drawn in screen coordinates. * so they can be drawn in screen coordinates.
@ -118,25 +117,25 @@ final class CameraManager {
Point[] output = new Point[count]; Point[] output = new Point[count];
for (int x = 0; x < count; x++) { for (int x = 0; x < count; x++) {
output[x] = new Point(); output[x] = new Point();
output[x].x = frame.left + (int)(points[x].getX() * frameSize / stillResolution.x + 0.5f); output[x].x = frame.left + (int) (points[x].getX() * frameSize / stillResolution.x + 0.5f);
output[x].y = frame.top + (int)(points[x].getY() * frameSize / stillResolution.y + 0.5f); output[x].y = frame.top + (int) (points[x].getY() * frameSize / stillResolution.y + 0.5f);
} }
return output; return output;
} }
/** /**
* Images for the live preview are taken at low resolution in RGB. The final stills for the * Images for the live preview are taken at low resolution in RGB. The final stills for the
* decoding step are taken in YUV, since we only need the luminance channel. Other code depends * decoding step are taken in YUV, since we only need the luminance channel. Other code depends
* on the ability to call this method for free if the correct mode is already set. * on the ability to call this method for free if the correct mode is already set.
* *
* @param on Setting on true will engage preview mode, setting it false will request still mode. * @param on Setting on true will engage preview mode, setting it false will request still mode.
*/ */
private void setPreviewMode(boolean on) { private void setPreviewMode(boolean on) {
if (on != previewMode) { if (on != previewMode) {
if (on) { if (on) {
params.type = 1; // preview params.type = 1; // preview
if (cameraResolution.x / (float)cameraResolution.y < if (cameraResolution.x / (float) cameraResolution.y <
screenResolution.x / (float)screenResolution.y) { screenResolution.x / (float) screenResolution.y) {
params.srcWidth = cameraResolution.x; params.srcWidth = cameraResolution.x;
params.srcHeight = cameraResolution.x * screenResolution.y / screenResolution.x; params.srcHeight = cameraResolution.x * screenResolution.y / screenResolution.x;
params.leftPixel = 0; params.leftPixel = 0;
@ -169,7 +168,7 @@ final class CameraManager {
previewMode = on; previewMode = on;
} }
} }
/** /**
* This method determines how to take the highest quality image (i.e. the one which has the best * This method determines how to take the highest quality image (i.e. the one which has the best
* chance of being decoded) given the capabilities of the camera. It is a balancing act between * chance of being decoded) given the capabilities of the camera. It is a balancing act between
@ -183,65 +182,65 @@ final class CameraManager {
cameraResolution = getMaximumCameraResolution(); cameraResolution = getMaximumCameraResolution();
int minDimension = (cameraResolution.x < cameraResolution.y) ? cameraResolution.x : int minDimension = (cameraResolution.x < cameraResolution.y) ? cameraResolution.x :
cameraResolution.y; cameraResolution.y;
int diagonalResolution = (int)Math.sqrt(cameraResolution.x * cameraResolution.x + int diagonalResolution = (int) Math.sqrt(cameraResolution.x * cameraResolution.x +
cameraResolution.y * cameraResolution.y); cameraResolution.y * cameraResolution.y);
float diagonalFov = getFieldOfView(); float diagonalFov = getFieldOfView();
// Determine the field of view in the smaller dimension, then calculate how large an object // Determine the field of view in the smaller dimension, then calculate how large an object
// would be at the minimum focus distance. // would be at the minimum focus distance.
float fov = diagonalFov * minDimension / diagonalResolution; float fov = diagonalFov * minDimension / diagonalResolution;
double objectSize = Math.tan(Math.toRadians(fov / 2.0)) * getMinimumFocusDistance() * 2; double objectSize = Math.tan(Math.toRadians(fov / 2.0)) * getMinimumFocusDistance() * 2;
// Let's assume the largest barcode we might photograph at this distance is 3 inches across. By // Let's assume the largest barcode we might photograph at this distance is 3 inches across. By
// cropping to this size, we can avoid processing surrounding pixels, which helps with speed and // cropping to this size, we can avoid processing surrounding pixels, which helps with speed and
// accuracy. // accuracy.
// TODO(dswitkin): Handle a device with a great macro mode where objectSize < 4 inches. // TODO(dswitkin): Handle a device with a great macro mode where objectSize < 4 inches.
double crop = 3.0 / objectSize; double crop = 3.0 / objectSize;
int nativeResolution = (int)(minDimension * crop); int nativeResolution = (int) (minDimension * crop);
// The camera driver can only capture images which are a multiple of eight, so it's necessary to // The camera driver can only capture images which are a multiple of eight, so it's necessary to
// round up. // round up.
nativeResolution = (nativeResolution + 7) / 8 * 8; nativeResolution = (nativeResolution + 7) / 8 * 8;
if (nativeResolution > minDimension) { if (nativeResolution > minDimension) {
nativeResolution = minDimension; nativeResolution = minDimension;
} }
// There's no point in capturing too much detail, so ask the driver to downsample. I haven't // There's no point in capturing too much detail, so ask the driver to downsample. I haven't
// tried a non-integer multiple, but it seems unlikely to work. // tried a non-integer multiple, but it seems unlikely to work.
double dpi = nativeResolution / objectSize; double dpi = nativeResolution / objectSize;
stillMultiplier = 1; stillMultiplier = 1;
if (dpi > 200) { if (dpi > 200) {
stillMultiplier = (int)(dpi / 200 + 1); stillMultiplier = (int) (dpi / 200 + 1);
} }
stillResolution = new Point(nativeResolution, nativeResolution); stillResolution = new Point(nativeResolution, nativeResolution);
Log.v(TAG, "FOV " + fov + " objectSize " + objectSize + " crop " + crop + " dpi " + dpi + Log.v(TAG, "FOV " + fov + " objectSize " + objectSize + " crop " + crop + " dpi " + dpi +
" nativeResolution " + nativeResolution + " stillMultiplier " + stillMultiplier); " nativeResolution " + nativeResolution + " stillMultiplier " + stillMultiplier);
} }
// FIXME(dswitkin): These three methods have temporary constants until the new Camera API can // FIXME(dswitkin): These three methods have temporary constants until the new Camera API can
// provide the real values for the current device. // provide the real values for the current device.
// Temporary: the camera's maximum resolution in pixels. // Temporary: the camera's maximum resolution in pixels.
private static Point getMaximumCameraResolution() { private static Point getMaximumCameraResolution() {
return new Point(1280, 1024); return new Point(1280, 1024);
} }
// Temporary: the diagonal field of view in degrees. // Temporary: the diagonal field of view in degrees.
private static float getFieldOfView() { private static float getFieldOfView() {
return 60.0f; return 60.0f;
} }
// Temporary: the minimum focus distance in inches. // Temporary: the minimum focus distance in inches.
private static float getMinimumFocusDistance() { private static float getMinimumFocusDistance() {
return 12.0f; return 12.0f;
} }
private Point getScreenResolution() { private Point getScreenResolution() {
if (screenResolution == null) { if (screenResolution == null) {
WindowManager manager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay(); Display display = manager.getDefaultDisplay();
screenResolution = new Point(display.getWidth(), display.getHeight()); screenResolution = new Point(display.getWidth(), display.getHeight());
} }
return screenResolution; return screenResolution;
} }
} }

View file

@ -16,8 +16,6 @@
package com.google.zxing.client.android; package com.google.zxing.client.android;
import com.google.zxing.ResultPoint;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
@ -26,66 +24,67 @@ import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.view.SurfaceHolder; import android.view.SurfaceHolder;
import android.view.SurfaceView; import android.view.SurfaceView;
import com.google.zxing.ResultPoint;
/** /**
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
*/ */
final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback { final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static int[] SCANNER_ALPHA = { 0, 64, 128, 192, 255, 192, 128, 64 }; private static int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
private CameraManager cameraManager; private CameraManager cameraManager;
private SurfaceHolder surfaceHolder; private SurfaceHolder surfaceHolder;
private boolean hasSurface; private boolean hasSurface;
private int scannerAlpha; private int scannerAlpha;
CameraSurfaceView(Context context, CameraManager cameraManager) {
super(context);
this.cameraManager = cameraManager;
// Install a SurfaceHolder.Callback so we get notified when the underlying surface is created CameraSurfaceView(Context context, CameraManager cameraManager) {
// and destroyed. super(context);
surfaceHolder = getHolder(); this.cameraManager = cameraManager;
surfaceHolder.setCallback(this);
hasSurface = false;
scannerAlpha = 0;
// FIXME(dswitkin): This resolution needs to be made dynamic to handle different devices and // Install a SurfaceHolder.Callback so we get notified when the underlying surface is created
// orientations. // and destroyed.
surfaceHolder.setFixedSize(320, 240); surfaceHolder = getHolder();
} surfaceHolder.setCallback(this);
hasSurface = false;
scannerAlpha = 0;
public boolean surfaceCreated(SurfaceHolder holder) { // FIXME(dswitkin): This resolution needs to be made dynamic to handle different devices and
hasSurface = true; // orientations.
surfaceHolder.setFixedSize(320, 240);
}
// Tell the system that we filled the surface in this call. This is a lie to prevent the system public boolean surfaceCreated(SurfaceHolder holder) {
// from filling the surface for us automatically. THIS IS REQUIRED because otherwise we'll hasSurface = true;
// access the Surface object from 2 different threads which is not allowed.
return true;
}
public void surfaceDestroyed(SurfaceHolder holder) { // Tell the system that we filled the surface in this call. This is a lie to prevent the system
// FIXME(dswitkin): The docs say this surface will be destroyed when this method returns. In // from filling the surface for us automatically. THIS IS REQUIRED because otherwise we'll
// practice this has not been a problem so far. I need to investigate. // access the Surface object from 2 different threads which is not allowed.
hasSurface = false; return true;
} }
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { public void surfaceDestroyed(SurfaceHolder holder) {
// Surface size or format has changed. This won't happen because of the setFixedSize() call. // FIXME(dswitkin): The docs say this surface will be destroyed when this method returns. In
} // practice this has not been a problem so far. I need to investigate.
hasSurface = false;
/** }
* This method is only called from the WorkerThread. It's job is to grab the next preview frame
* from the camera, draw the framing rectangle, and blit everything to the screen. public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
*/ // Surface size or format has changed. This won't happen because of the setFixedSize() call.
public void capturePreviewAndDraw() { }
/**
* This method is only called from the WorkerThread. It's job is to grab the next preview frame
* from the camera, draw the framing rectangle, and blit everything to the screen.
*/
public void capturePreviewAndDraw() {
if (hasSurface) { if (hasSurface) {
Canvas canvas = surfaceHolder.lockCanvas(); Canvas canvas = surfaceHolder.lockCanvas();
cameraManager.capturePreview(canvas); cameraManager.capturePreview(canvas);
Rect frame = cameraManager.getFramingRect(); Rect frame = cameraManager.getFramingRect();
int width = canvas.getBitmapWidth(); int width = canvas.getBitmapWidth();
int height = canvas.getBitmapHeight(); int height = canvas.getBitmapHeight();
// Draw the exterior (i.e. outside the framing rect) as half darkened // Draw the exterior (i.e. outside the framing rect) as half darkened
Paint paint = new Paint(); Paint paint = new Paint();
paint.setColor(Color.BLACK); paint.setColor(Color.BLACK);
@ -98,7 +97,7 @@ final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callb
canvas.drawRect(box, paint); canvas.drawRect(box, paint);
box.set(0, frame.bottom + 1, width, height); box.set(0, frame.bottom + 1, width, height);
canvas.drawRect(box, paint); canvas.drawRect(box, paint);
// Draw a two pixel solid black border inside the framing rect // Draw a two pixel solid black border inside the framing rect
paint.setAlpha(255); paint.setAlpha(255);
box.set(frame.left, frame.top, frame.right + 1, frame.top + 2); box.set(frame.left, frame.top, frame.right + 1, frame.top + 2);
@ -109,38 +108,38 @@ final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callb
canvas.drawRect(box, paint); canvas.drawRect(box, paint);
box.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1); box.set(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1);
canvas.drawRect(box, paint); canvas.drawRect(box, paint);
// Draw a red "laser scanner" line through the middle // Draw a red "laser scanner" line through the middle
paint.setColor(Color.RED); paint.setColor(Color.RED);
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]); paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
int middle = frame.height() / 2 + frame.top; int middle = frame.height() / 2 + frame.top;
box.set(frame.left + 2, middle - 1, frame.right - 1, middle + 2); box.set(frame.left + 2, middle - 1, frame.right - 1, middle + 2);
canvas.drawRect(box, paint); canvas.drawRect(box, paint);
surfaceHolder.unlockCanvasAndPost(canvas); surfaceHolder.unlockCanvasAndPost(canvas);
// This cheap animation is tied to the rate at which we pull previews from the camera. // This cheap animation is tied to the rate at which we pull previews from the camera.
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length; scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
} }
} }
/** /**
* Draw a line for 1D barcodes (which return two points) or otherwise a set of points returned * Draw a line for 1D barcodes (which return two points) or otherwise a set of points returned
* from the decoder to indicate what we found. * from the decoder to indicate what we found.
* TODO(dswitkin): It might be nice to clear the framing rect and zoom in on the actual still that * TODO(dswitkin): It might be nice to clear the framing rect and zoom in on the actual still that
* was captured, then paint the green points on it. This would also clear the red scanner line * was captured, then paint the green points on it. This would also clear the red scanner line
* which doesn't make sense after the capture. * which doesn't make sense after the capture.
* *
* @param resultPoints An array of points from the decoder, whose coordinates are expressed * @param resultPoints An array of points from the decoder, whose coordinates are expressed
* relative to the still image from the camera. * relative to the still image from the camera.
*/ */
public void drawResultPoints(ResultPoint[] resultPoints) { public void drawResultPoints(ResultPoint[] resultPoints) {
if (hasSurface) { if (hasSurface) {
Canvas canvas = surfaceHolder.lockCanvas(); Canvas canvas = surfaceHolder.lockCanvas();
Paint paint = new Paint(); Paint paint = new Paint();
paint.setColor(Color.GREEN); paint.setColor(Color.GREEN);
paint.setAlpha(128); paint.setAlpha(128);
Point[] points = cameraManager.convertResultPoints(resultPoints); Point[] points = cameraManager.convertResultPoints(resultPoints);
if (points.length == 2) { if (points.length == 2) {
paint.setStrokeWidth(4); paint.setStrokeWidth(4);
@ -151,7 +150,7 @@ final class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callb
canvas.drawPoint(points[x].x, points[x].y, paint); canvas.drawPoint(points[x].x, points[x].y, paint);
} }
} }
surfaceHolder.unlockCanvasAndPost(canvas); surfaceHolder.unlockCanvasAndPost(canvas);
} }
} }

View file

@ -55,7 +55,7 @@ final class ResultHandler extends Handler {
Intent intent = null; Intent intent = null;
ParsedReaderResultType type = result.getType(); ParsedReaderResultType type = result.getType();
if (type == ParsedReaderResultType.ADDRESSBOOK) { if (type == ParsedReaderResultType.ADDRESSBOOK) {
AddressBookDoCoMoResult addressResult = (AddressBookDoCoMoResult)result; AddressBookDoCoMoResult addressResult = (AddressBookDoCoMoResult) result;
intent = new Intent(Contacts.Intents.Insert.ACTION, Contacts.People.CONTENT_URI); intent = new Intent(Contacts.Intents.Insert.ACTION, Contacts.People.CONTENT_URI);
putExtra(intent, Contacts.Intents.Insert.NAME, addressResult.getName()); putExtra(intent, Contacts.Intents.Insert.NAME, addressResult.getName());
putExtra(intent, Contacts.Intents.Insert.PHONE, addressResult.getPhoneNumbers()[0]); putExtra(intent, Contacts.Intents.Insert.PHONE, addressResult.getPhoneNumbers()[0]);
@ -66,12 +66,12 @@ final class ResultHandler extends Handler {
// For now, we can only open the browser, and not actually add a bookmark // For now, we can only open the browser, and not actually add a bookmark
try { try {
intent = new Intent(Intent.VIEW_ACTION, intent = new Intent(Intent.VIEW_ACTION,
new ContentURI(((BookmarkDoCoMoResult)result).getURI())); new ContentURI(((BookmarkDoCoMoResult) result).getURI()));
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
return; return;
} }
} else if (type == ParsedReaderResultType.EMAIL) { } else if (type == ParsedReaderResultType.EMAIL) {
EmailDoCoMoResult emailResult = (EmailDoCoMoResult)result; EmailDoCoMoResult emailResult = (EmailDoCoMoResult) result;
try { try {
intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getTo())); intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getTo()));
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
@ -80,14 +80,14 @@ final class ResultHandler extends Handler {
putExtra(intent, "subject", emailResult.getSubject()); putExtra(intent, "subject", emailResult.getSubject());
putExtra(intent, "body", emailResult.getBody()); putExtra(intent, "body", emailResult.getBody());
} else if (type == ParsedReaderResultType.EMAIL_ADDRESS) { } else if (type == ParsedReaderResultType.EMAIL_ADDRESS) {
EmailAddressResult emailResult = (EmailAddressResult)result; EmailAddressResult emailResult = (EmailAddressResult) result;
try { try {
intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getEmailAddress())); intent = new Intent(Intent.SENDTO_ACTION, new ContentURI(emailResult.getEmailAddress()));
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
return; return;
} }
} else if (type == ParsedReaderResultType.UPC) { } else if (type == ParsedReaderResultType.UPC) {
UPCParsedResult upcResult = (UPCParsedResult)result; UPCParsedResult upcResult = (UPCParsedResult) result;
try { try {
ContentURI uri = new ContentURI("http://www.upcdatabase.com/item.asp?upc=" + ContentURI uri = new ContentURI("http://www.upcdatabase.com/item.asp?upc=" +
upcResult.getUPC()); upcResult.getUPC());
@ -96,7 +96,7 @@ final class ResultHandler extends Handler {
return; return;
} }
} else if (type == ParsedReaderResultType.URI) { } else if (type == ParsedReaderResultType.URI) {
URIParsedResult uriResult = (URIParsedResult)result; URIParsedResult uriResult = (URIParsedResult) result;
try { try {
intent = new Intent(Intent.VIEW_ACTION, new ContentURI(uriResult.getURI())); intent = new Intent(Intent.VIEW_ACTION, new ContentURI(uriResult.getURI()));
} catch (URISyntaxException e) { } catch (URISyntaxException e) {

View file

@ -16,41 +16,42 @@
package com.google.zxing.client.android; package com.google.zxing.client.android;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import com.google.zxing.MonochromeBitmapSource; import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatReader;
import com.google.zxing.ReaderException; import com.google.zxing.ReaderException;
import com.google.zxing.Result; import com.google.zxing.Result;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
/** /**
* This thread does all the heavy lifting, both during preview and for the final capture and * This thread does all the heavy lifting, both during preview and for the final capture and
* decoding. That leaves the main thread free to handle UI tasks. * decoding. That leaves the main thread free to handle UI tasks.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
*/ */
final class WorkerThread extends Thread { final class WorkerThread extends Thread {
private CameraSurfaceView surfaceView; private CameraSurfaceView surfaceView;
private CameraManager cameraManager; private CameraManager cameraManager;
private Handler handler; private Handler handler;
private enum State { private enum State {
IDLE, IDLE,
PREVIEW_LOOP, PREVIEW_LOOP,
STILL_AND_DECODE, STILL_AND_DECODE,
DONE DONE
} }
private State state; private State state;
WorkerThread(CameraSurfaceView surfaceView, CameraManager cameraManager, Handler handler) { WorkerThread(CameraSurfaceView surfaceView, CameraManager cameraManager, Handler handler) {
this.surfaceView = surfaceView; this.surfaceView = surfaceView;
this.cameraManager = cameraManager; this.cameraManager = cameraManager;
this.handler = handler; this.handler = handler;
state = State.IDLE; state = State.IDLE;
} }
@Override @Override
public void run() { public void run() {
while (true) { while (true) {
@ -58,7 +59,8 @@ final class WorkerThread extends Thread {
case IDLE: case IDLE:
try { try {
sleep(50); sleep(50);
} catch (InterruptedException e) { } } catch (InterruptedException e) {
}
break; break;
case PREVIEW_LOOP: case PREVIEW_LOOP:
surfaceView.capturePreviewAndDraw(); surfaceView.capturePreviewAndDraw();
@ -84,15 +86,15 @@ final class WorkerThread extends Thread {
} }
} }
} }
public void requestPreviewLoop() { public void requestPreviewLoop() {
state = State.PREVIEW_LOOP; state = State.PREVIEW_LOOP;
} }
public void requestStillAndDecode() { public void requestStillAndDecode() {
state = State.STILL_AND_DECODE; state = State.STILL_AND_DECODE;
} }
public void requestExitAndWait() { public void requestExitAndWait() {
state = State.DONE; state = State.DONE;
try { try {
@ -100,5 +102,5 @@ final class WorkerThread extends Thread {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }

View file

@ -16,19 +16,18 @@
package com.google.zxing.client.android; package com.google.zxing.client.android;
import com.google.zxing.MonochromeBitmapSource; import android.graphics.Bitmap;
import com.google.zxing.BlackPointEstimationMethod; import com.google.zxing.BlackPointEstimationMethod;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.BlackPointEstimator; import com.google.zxing.common.BlackPointEstimator;
import android.graphics.Bitmap;
/** /**
* This object implements MonochromeBitmapSource around an Android Bitmap. Rather than capturing an * This object implements MonochromeBitmapSource around an Android Bitmap. Rather than capturing an
* RGB image and calculating the grey value at each pixel, we ask the camera driver for YUV data and * RGB image and calculating the grey value at each pixel, we ask the camera driver for YUV data and
* strip out the luminance channel directly. This should be faster but provides fewer bits, i.e. * strip out the luminance channel directly. This should be faster but provides fewer bits, i.e.
* fewer grey levels. * fewer grey levels.
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
@ -41,7 +40,7 @@ final class YUVMonochromeBitmapSource implements MonochromeBitmapSource {
private int blackPoint; private int blackPoint;
private BlackPointEstimationMethod lastMethod; private BlackPointEstimationMethod lastMethod;
private int lastArgument; private int lastArgument;
private static final int LUMINANCE_BITS = 5; private static final int LUMINANCE_BITS = 5;
private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;

View file

@ -25,11 +25,11 @@
<ant dir="javame" target="build"/> <ant dir="javame" target="build"/>
<ant dir="javase" target="build"/> <ant dir="javase" target="build"/>
</target> </target>
<target name="buildwithoutj2me"> <target name="buildwithoutj2me">
<ant dir="core" target="build"/> <ant dir="core" target="build"/>
<ant dir="javase" target="build"/> <ant dir="javase" target="build"/>
</target> </target>
<target name="clean"> <target name="clean">
<ant dir="core" target="clean"/> <ant dir="core" target="clean"/>
@ -61,7 +61,8 @@
<target name="javadoc"> <target name="javadoc">
<mkdir dir="docs/javadoc"/> <mkdir dir="docs/javadoc"/>
<javadoc destdir="docs/javadoc" footer="&lt;script src=&quot;http://www.google-analytics.com/urchin.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt;_uacct = &quot;UA-788492-5&quot;; urchinTracker();&lt;/script&gt;"> <javadoc destdir="docs/javadoc"
footer="&lt;script src=&quot;http://www.google-analytics.com/urchin.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt;_uacct = &quot;UA-788492-5&quot;; urchinTracker();&lt;/script&gt;">
<sourcepath> <sourcepath>
<pathelement location="core/src"/> <pathelement location="core/src"/>
<pathelement location="javame/src"/> <pathelement location="javame/src"/>
@ -71,7 +72,7 @@
<pathelement location="${WTK-home}/lib/cldcapi11.jar"/> <pathelement location="${WTK-home}/lib/cldcapi11.jar"/>
<pathelement location="${WTK-home}/lib/midpapi20.jar"/> <pathelement location="${WTK-home}/lib/midpapi20.jar"/>
<pathelement location="${WTK-home}/lib/mmapi.jar"/> <pathelement location="${WTK-home}/lib/mmapi.jar"/>
<pathelement location="${WTK-home}/lib/jsr234.jar"/> <pathelement location="${WTK-home}/lib/jsr234.jar"/>
</classpath> </classpath>
</javadoc> </javadoc>
</target> </target>

View file

@ -79,7 +79,7 @@
<batchtest> <batchtest>
<fileset dir="test/src"> <fileset dir="test/src">
<include name="**/*TestCase.java"/> <include name="**/*TestCase.java"/>
<exclude name="com/google/zxing/common/AbstractBlackBoxTestCase.java"/> <exclude name="com/google/zxing/common/AbstractBlackBoxTestCase.java"/>
</fileset> </fileset>
</batchtest> </batchtest>
</junit> </junit>

View file

@ -1,123 +1,260 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML> <HTML>
<HEAD> <HEAD>
<TITLE>Common Public License - v 1.0</TITLE> <TITLE>Common Public License - v 1.0</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</HEAD> </HEAD>
<BODY BGCOLOR="#FFFFFF" VLINK="#800000"> <BODY BGCOLOR="#FFFFFF" VLINK="#800000">
<P ALIGN="CENTER"><B>Common Public License - v 1.0</B> <P ALIGN="CENTER"><B>Common Public License - v 1.0</B>
<P><B></B><FONT SIZE="3"></FONT> <P><B></B><FONT SIZE="3"></FONT>
<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</FONT>
<P><FONT SIZE="3"></FONT><FONT SIZE="2">THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
AGREEMENT.</FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"><B>1. DEFINITIONS</B></FONT>
<P><FONT SIZE="2"><B>1. DEFINITIONS</B></FONT>
<P><FONT SIZE="2">"Contribution" means:</FONT> <P><FONT SIZE="2">"Contribution" means:</FONT>
<UL><FONT SIZE="2">a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and<BR CLEAR="LEFT"> <UL><FONT SIZE="2">a) in the case of the initial Contributor, the initial code and documentation distributed under this
b) in the case of each subsequent Contributor:</FONT></UL> Agreement, and<BR CLEAR="LEFT">
b) in the case of each subsequent Contributor:</FONT></UL>
<UL><FONT SIZE="2">i) changes to the Program, and</FONT></UL> <UL><FONT SIZE="2">i) changes to the Program, and</FONT></UL>
<UL><FONT SIZE="2">ii) additions to the Program;</FONT></UL> <UL><FONT SIZE="2">ii) additions to the Program;</FONT></UL>
<UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. </FONT><FONT SIZE="2">A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. </FONT><FONT SIZE="2">Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. </FONT></UL> <UL><FONT SIZE="2">where such changes and/or additions to the Program originate from and are distributed by that
particular Contributor. </FONT><FONT SIZE="2">A Contribution 'originates' from a Contributor if it was added to the
Program by such Contributor itself or anyone acting on such Contributor's behalf. </FONT><FONT SIZE="2">Contributions
do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with
the Program under their own license agreement, and (ii) are not derivative works of the Program. </FONT></UL>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT> <P><FONT SIZE="2">"Contributor" means any person or entity that distributes the Program.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. </FONT>
<P><FONT SIZE="2">"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by
the use or sale of its Contribution alone or when combined with the Program. </FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this Agreement.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">"Program" means the Contributions distributed in accordance with this
Agreement.</FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</FONT>
<P><FONT SIZE="2">"Recipient" means anyone who receives the Program under this Agreement, including all
Contributors.</FONT>
<P><FONT SIZE="2"><B></B></FONT> <P><FONT SIZE="2"><B></B></FONT>
<P><FONT SIZE="2"><B>2. GRANT OF RIGHTS</B></FONT>
<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a) </FONT><FONT SIZE="2">Subject to the terms of this Agreement, each Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.</FONT></UL> <P><FONT SIZE="2"><B>2. GRANT OF RIGHTS</B></FONT>
<UL><FONT SIZE="2"></FONT><FONT SIZE="2">a) </FONT><FONT SIZE="2">Subject to the terms of this Agreement, each
Contributor hereby grants</FONT><FONT SIZE="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license
to</FONT><FONT SIZE="2" COLOR="#FF0000"> </FONT><FONT SIZE="2">reproduce, prepare derivative works of, publicly
display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative
works, in source code and object code form.</FONT></UL>
<UL><FONT SIZE="2"></FONT></UL> <UL><FONT SIZE="2"></FONT></UL>
<UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) Subject to the terms of this Agreement, each Contributor hereby grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT SIZE="2">royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. </FONT></UL> <UL><FONT SIZE="2"></FONT><FONT SIZE="2">b) Subject to the terms of this Agreement, each Contributor hereby
grants </FONT><FONT SIZE="2">Recipient a non-exclusive, worldwide,</FONT><FONT SIZE="2" COLOR="#008000"> </FONT><FONT
SIZE="2">royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall
apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the
Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The
patent license shall not apply to any other combinations which include the Contribution. No hardware per se is
licensed hereunder. </FONT></UL>
<UL><FONT SIZE="2"></FONT></UL> <UL><FONT SIZE="2"></FONT></UL>
<UL><FONT SIZE="2">c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.</FONT></UL> <UL><FONT SIZE="2">c) Recipient understands that although each Contributor grants the licenses to its Contributions set
forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims
brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to
exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any
other intellectual property rights needed, if any. For example, if a third party patent license is required to allow
Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the
Program.</FONT></UL>
<UL><FONT SIZE="2"></FONT></UL> <UL><FONT SIZE="2"></FONT></UL>
<UL><FONT SIZE="2">d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. </FONT></UL> <UL><FONT SIZE="2">d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its
Contribution, if any, to grant the copyright license set forth in this Agreement. </FONT></UL>
<UL><FONT SIZE="2"></FONT></UL> <UL><FONT SIZE="2"></FONT></UL>
<P><FONT SIZE="2"><B>3. REQUIREMENTS</B></FONT> <P><FONT SIZE="2"><B>3. REQUIREMENTS</B></FONT>
<P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</FONT>
<UL><FONT SIZE="2">a) it complies with the terms and conditions of this Agreement; and</FONT></UL> <P><FONT SIZE="2"><B></B>A Contributor may choose to distribute the Program in object code form under its own license
agreement, provided that:</FONT>
<UL><FONT SIZE="2">a) it complies with the terms and conditions of this Agreement; and</FONT></UL>
<UL><FONT SIZE="2">b) its license agreement:</FONT></UL> <UL><FONT SIZE="2">b) its license agreement:</FONT></UL>
<UL><FONT SIZE="2">i) effectively disclaims</FONT><FONT SIZE="2"> on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; </FONT></UL> <UL><FONT SIZE="2">i) effectively disclaims</FONT><FONT SIZE="2"> on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title and non-infringement, and implied
warranties or conditions of merchantability and fitness for a particular purpose; </FONT></UL>
<UL><FONT SIZE="2">ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL> <UL><FONT SIZE="2">ii) effectively excludes on behalf of all Contributors all liability for damages, including direct,
indirect, special, incidental and consequential damages, such as lost profits; </FONT></UL>
<UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2"> states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and</FONT></UL> <UL><FONT SIZE="2">iii)</FONT><FONT SIZE="2"> states that any provisions which differ from this Agreement are offered by
that Contributor alone and not by any other party; and</FONT></UL>
<UL><FONT SIZE="2">iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.</FONT><FONT SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL> <UL><FONT SIZE="2">iv) states that source code for the Program is available from such Contributor, and informs licensees
how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.</FONT><FONT
SIZE="2" COLOR="#0000FF"> </FONT><FONT SIZE="2" COLOR="#FF0000"></FONT></UL>
<UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL> <UL><FONT SIZE="2" COLOR="#FF0000"></FONT><FONT SIZE="2"></FONT></UL>
<P><FONT SIZE="2">When the Program is made available in source code form:</FONT> <P><FONT SIZE="2">When the Program is made available in source code form:</FONT>
<UL><FONT SIZE="2">a) it must be made available under this Agreement; and </FONT></UL> <UL><FONT SIZE="2">a) it must be made available under this Agreement; and </FONT></UL>
<UL><FONT SIZE="2">b) a copy of this Agreement must be included with each copy of the Program. </FONT></UL> <UL><FONT SIZE="2">b) a copy of this Agreement must be included with each copy of the Program. </FONT></UL>
<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT>
<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any copyright notices contained within the Program. </FONT>
<P><FONT SIZE="2" COLOR="#0000FF"><STRIKE></STRIKE></FONT><FONT SIZE="2">Contributors may not remove or alter any
copyright notices contained within the Program. </FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. </FONT>
<P><FONT SIZE="2">Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that
reasonably allows subsequent Recipients to identify the originator of the Contribution. </FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"><B>4. COMMERCIAL DISTRIBUTION</B></FONT>
<P><FONT SIZE="2">Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.</FONT> <P><FONT SIZE="2"><B>4. COMMERCIAL DISTRIBUTION</B></FONT>
<P><FONT SIZE="2">Commercial distributors of software may accept certain responsibilities with respect to end users,
business partners and the like. While this license is intended to facilitate the commercial use of the Program, the
Contributor who includes the Program in a commercial product offering should do so in a manner which does not create
potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product
offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor
("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims,
lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by
the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a
commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any
actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a)
promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to
control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The
Indemnified Contributor may participate in any such claim at its own expense.</FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.</FONT>
<P><FONT SIZE="2">For example, a Contributor might include the Program in a commercial product offering, Product X. That
Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are such Commercial Contributor's
responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay
any damages as a result, the Commercial Contributor must pay those damages.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2" COLOR="#0000FF"></FONT>
<P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5. NO WARRANTY</B></FONT>
<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or interruption of operations</FONT><FONT SIZE="2">. </FONT><FONT SIZE="2"></FONT> <P><FONT SIZE="2" COLOR="#0000FF"></FONT><FONT SIZE="2"><B>5. NO WARRANTY</B></FONT>
<P><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient
is</FONT><FONT SIZE="2"> solely responsible for determining the appropriateness of using and distributing </FONT><FONT
SIZE="2">the Program</FONT><FONT SIZE="2"> and assumes all risks associated with its exercise of rights under this
Agreement</FONT><FONT SIZE="2">, including but not limited to the risks and costs of program errors, compliance with
applicable laws, damage to or loss of data, </FONT><FONT SIZE="2">programs or equipment, and unavailability or
interruption of operations</FONT><FONT SIZE="2">. </FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6. DISCLAIMER OF LIABILITY</B></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2"><B>6. DISCLAIMER OF LIABILITY</B></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES </FONT><FONT SIZE="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</FONT><FONT SIZE="2"> HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGES.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"><B>7. GENERAL</B></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.</FONT> <P><FONT SIZE="2"><B>7. GENERAL</B></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">If any provision of this Agreement is invalid or unenforceable under applicable
law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without
further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.</FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. </FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to
software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor
to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if
Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit)
alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes
such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date
such litigation is filed. </FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. </FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the
material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after
becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to
cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under
this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. </FONT><FONT
SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to </FONT><FONT SIZE="2">publish new versions (including revisions) of this Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. </FONT><FONT SIZE="2">Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new </FONT><FONT SIZE="2">version. </FONT><FONT SIZE="2">Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, </FONT><FONT SIZE="2">by implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2"> All rights in the Program not expressly granted under this Agreement are reserved.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2">Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The
Agreement Steward reserves the right to </FONT><FONT SIZE="2">publish new versions (including revisions) of this
Agreement from time to </FONT><FONT SIZE="2">time. No one other than the Agreement Steward has the right to modify
this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement
Steward to a suitable separate entity. </FONT><FONT SIZE="2">Each new version of the Agreement will be given a
distinguishing version number. The Program (including Contributions) may always be distributed subject to the version
of the Agreement under which it was received. In addition, after a new version of the Agreement is published,
Contributor may elect to distribute the Program (including its Contributions) under the new </FONT><FONT SIZE="2">version. </FONT><FONT
SIZE="2">Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the
intellectual property of any Contributor under this Agreement, whether expressly, </FONT><FONT SIZE="2">by
implication, estoppel or otherwise</FONT><FONT SIZE="2">.</FONT><FONT SIZE="2"> All rights in the Program not
expressly granted under this Agreement are reserved.</FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
<P><FONT SIZE="2">This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.</FONT>
<P><FONT SIZE="2">This Agreement is governed by the laws of the State of New York and the intellectual property laws of
the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one
year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.</FONT>
<P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT><FONT SIZE="2"></FONT>
<P><FONT SIZE="2"></FONT> <P><FONT SIZE="2"></FONT>
</BODY> </BODY>

View file

@ -25,13 +25,20 @@ public final class BarcodeFormat {
// No, we can't use an enum here. J2ME doesn't support it. // No, we can't use an enum here. J2ME doesn't support it.
/** 1D barcode format family. */ /**
* 1D barcode format family.
*/
public static final BarcodeFormat ONED = new BarcodeFormat(); public static final BarcodeFormat ONED = new BarcodeFormat();
/** QR Code 2D barcode format */ /**
* QR Code 2D barcode format
*/
public static final BarcodeFormat QR_CODE = new BarcodeFormat(); public static final BarcodeFormat QR_CODE = new BarcodeFormat();
/** DataMatrix 2D barcode format */ /**
* DataMatrix 2D barcode format
*/
public static final BarcodeFormat DATAMATRIX = new BarcodeFormat(); public static final BarcodeFormat DATAMATRIX = new BarcodeFormat();
private BarcodeFormat() {} private BarcodeFormat() {
}
} }

View file

@ -18,14 +18,18 @@ package com.google.zxing;
/** /**
* <p>Enumerates different methods of sampling an imagine to estimate a black point.</p> * <p>Enumerates different methods of sampling an imagine to estimate a black point.</p>
* *
* @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin) * @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin)
*/ */
public final class BlackPointEstimationMethod { public final class BlackPointEstimationMethod {
/** Method probably most suitable for use with 2D barcdoe format. */ /**
* Method probably most suitable for use with 2D barcdoe format.
*/
public static final BlackPointEstimationMethod TWO_D_SAMPLING = new BlackPointEstimationMethod(); public static final BlackPointEstimationMethod TWO_D_SAMPLING = new BlackPointEstimationMethod();
/** Method probably most suitable for 1D barcode decoding, where one row at a time is sampled. */ /**
* Method probably most suitable for 1D barcode decoding, where one row at a time is sampled.
*/
public static final BlackPointEstimationMethod ROW_SAMPLING = new BlackPointEstimationMethod(); public static final BlackPointEstimationMethod ROW_SAMPLING = new BlackPointEstimationMethod();
private BlackPointEstimationMethod() { private BlackPointEstimationMethod() {

View file

@ -28,9 +28,13 @@ public final class DecodeHintType {
// No, we can't use an enum here. J2ME doesn't support it. // No, we can't use an enum here. J2ME doesn't support it.
/** Unspecified, application-specific hint. */ /**
* Unspecified, application-specific hint.
*/
public static final DecodeHintType OTHER = new DecodeHintType(); public static final DecodeHintType OTHER = new DecodeHintType();
/** Image is a pure monochrome image of a barcode. */ /**
* Image is a pure monochrome image of a barcode.
*/
public static final DecodeHintType PURE_BARCODE = new DecodeHintType(); public static final DecodeHintType PURE_BARCODE = new DecodeHintType();
/** /**
* Image is known to be of one of a few possible formats. * Image is known to be of one of a few possible formats.
@ -38,6 +42,7 @@ public final class DecodeHintType {
*/ */
public static final DecodeHintType POSSIBLE_FORMATS = new DecodeHintType(); public static final DecodeHintType POSSIBLE_FORMATS = new DecodeHintType();
private DecodeHintType() {} private DecodeHintType() {
}
} }

View file

@ -40,11 +40,11 @@ public interface MonochromeBitmapSource {
* *
* @param y vertical offset, from top, of the row of pixels * @param y vertical offset, from top, of the row of pixels
* @param row if not null, {@link BitArray} to write pixels into. If null, a new {@link BitArray} * @param row if not null, {@link BitArray} to write pixels into. If null, a new {@link BitArray}
* is allocated and returned. * is allocated and returned.
* @param startX horizontal offset, from left, from which to start getting pixels * @param startX horizontal offset, from left, from which to start getting pixels
* @param getWidth number of pixels to get from the row * @param getWidth number of pixels to get from the row
* @return {@link BitArray} representing the (subset of the) row of pixels. If row parameter * @return {@link BitArray} representing the (subset of the) row of pixels. If row parameter
* was not null, it is returned. * was not null, it is returned.
*/ */
BitArray getBlackRow(int y, BitArray row, int startX, int getWidth); BitArray getBlackRow(int y, BitArray row, int startX, int getWidth);

View file

@ -58,7 +58,7 @@ public final class MultiFormatReader implements Reader {
} catch (ReaderException re) { } catch (ReaderException re) {
} }
} }
// Then fall through to QR codes. // Then fall through to QR codes.
if (tryQR) { if (tryQR) {
try { try {
@ -66,7 +66,7 @@ public final class MultiFormatReader implements Reader {
} catch (ReaderException re) { } catch (ReaderException re) {
} }
} }
throw new ReaderException("No barcode was detected in this image."); throw new ReaderException("No barcode was detected in this image.");
} }

View file

@ -46,8 +46,8 @@ public interface Reader {
* *
* @param image image of barcode to decode * @param image image of barcode to decode
* @param hints passed as a {@link Hashtable} from {@link DecodeHintType} to aribtrary data. The * @param hints passed as a {@link Hashtable} from {@link DecodeHintType} to aribtrary data. The
* meaning of the data depends upon the hint type. The implementation may or may not do * meaning of the data depends upon the hint type. The implementation may or may not do
* anything with these hints. * anything with these hints.
* @return String which the barcode encodes * @return String which the barcode encodes
* @throws ReaderException if the barcode cannot be located or decoded for any reason * @throws ReaderException if the barcode cannot be located or decoded for any reason
*/ */

View file

@ -20,7 +20,7 @@ package com.google.zxing;
* The general exception class throw when something goes wrong during decoding of a barcode. * The general exception class throw when something goes wrong during decoding of a barcode.
* This includes, but is not limited to, failing checksums / error correction algorithms, being * This includes, but is not limited to, failing checksums / error correction algorithms, being
* unable to locate finder timing patterns, and so on. * unable to locate finder timing patterns, and so on.
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
public final class ReaderException extends Exception { public final class ReaderException extends Exception {

View file

@ -40,8 +40,8 @@ public final class Result {
/** /**
* @return points related to the barcode in the image. These are typically points * @return points related to the barcode in the image. These are typically points
* identifying finder patterns or the corners of the barcode. The exact meaning is * identifying finder patterns or the corners of the barcode. The exact meaning is
* specific to the type of barcode that was decoded. * specific to the type of barcode that was decoded.
*/ */
public ResultPoint[] getResultPoints() { public ResultPoint[] getResultPoints() {
return resultPoints; return resultPoints;

View file

@ -19,12 +19,13 @@ package com.google.zxing;
/** /**
* <p>Encapsulates a point of interest in an image containing a barcode. Typically, this * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
* would be the location of a finder pattern or the corner of the barcode, for example.</p> * would be the location of a finder pattern or the corner of the barcode, for example.</p>
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
public interface ResultPoint { public interface ResultPoint {
float getX(); float getX();
float getY(); float getY();
} }

View file

@ -52,7 +52,7 @@ abstract class AbstractDoCoMoResult extends ParsedReaderResult {
// No terminating semicolon? uh, done. Set i such that loop terminates and break // No terminating semicolon? uh, done. Set i such that loop terminates and break
i = rawText.length(); i = rawText.length();
done = true; done = true;
} else if (rawText.charAt(i-1) == '\\') { } else if (rawText.charAt(i - 1) == '\\') {
// semicolon was escaped so continue // semicolon was escaped so continue
i++; i++;
} else { } else {

View file

@ -19,7 +19,7 @@ package com.google.zxing.client.result;
/** /**
* Represents the type of data encoded by a barcode -- from plain text, to a * Represents the type of data encoded by a barcode -- from plain text, to a
* URI, to an e-mail address, etc. * URI, to an e-mail address, etc.
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
public final class ParsedReaderResultType { public final class ParsedReaderResultType {
@ -27,7 +27,7 @@ public final class ParsedReaderResultType {
public static final ParsedReaderResultType BOOKMARK = new ParsedReaderResultType(); public static final ParsedReaderResultType BOOKMARK = new ParsedReaderResultType();
public static final ParsedReaderResultType ADDRESSBOOK = new ParsedReaderResultType(); public static final ParsedReaderResultType ADDRESSBOOK = new ParsedReaderResultType();
public static final ParsedReaderResultType EMAIL = new ParsedReaderResultType(); public static final ParsedReaderResultType EMAIL = new ParsedReaderResultType();
public static final ParsedReaderResultType EMAIL_ADDRESS = new ParsedReaderResultType(); public static final ParsedReaderResultType EMAIL_ADDRESS = new ParsedReaderResultType();
public static final ParsedReaderResultType UPC = new ParsedReaderResultType(); public static final ParsedReaderResultType UPC = new ParsedReaderResultType();
public static final ParsedReaderResultType URI = new ParsedReaderResultType(); public static final ParsedReaderResultType URI = new ParsedReaderResultType();
public static final ParsedReaderResultType TEXT = new ParsedReaderResultType(); public static final ParsedReaderResultType TEXT = new ParsedReaderResultType();

View file

@ -31,9 +31,9 @@ public final class BitArray {
this.bits = makeArray(size); this.bits = makeArray(size);
} }
public int getSize() { public int getSize() {
return size; return size;
} }
/** /**
* @param i bit to get * @param i bit to get
@ -57,7 +57,7 @@ public final class BitArray {
* *
* @param i first bit to set * @param i first bit to set
* @param newBits the new value of the next 32 bits. Note again that the least-significant bit * @param newBits the new value of the next 32 bits. Note again that the least-significant bit
* corresponds to bit i, the next-least-significant to i+1, and so on. * corresponds to bit i, the next-least-significant to i+1, and so on.
*/ */
public void setBulk(int i, int newBits) { public void setBulk(int i, int newBits) {
bits[i >> 5] = newBits; bits[i >> 5] = newBits;
@ -119,12 +119,12 @@ public final class BitArray {
/** /**
* @return underlying array of ints. The first element holds the first 32 bits, and the least * @return underlying array of ints. The first element holds the first 32 bits, and the least
* significant bit is bit 0. * significant bit is bit 0.
*/ */
public int[] getBitArray() { public int[] getBitArray() {
return bits; return bits;
} }
/** /**
* Reverses all bits in the array. * Reverses all bits in the array.
*/ */
@ -142,7 +142,7 @@ public final class BitArray {
} }
bits = newBits; bits = newBits;
} }
private static int[] makeArray(int size) { private static int[] makeArray(int size) {
int arraySize = size >> 5; int arraySize = size >> 5;
if ((size & 0x1F) != 0) { if ((size & 0x1F) != 0) {

View file

@ -39,16 +39,16 @@ public final class BlackPointEstimator {
* *
* @param histogram an array of <em>counts</em> of luminance values * @param histogram an array of <em>counts</em> of luminance values
* @param biasTowardsWhite values higher than 1.0 suggest that a higher black point is desirable (e.g. * @param biasTowardsWhite values higher than 1.0 suggest that a higher black point is desirable (e.g.
* more values are considered black); less than 1.0 suggests that lower is desirable. Must be greater * more values are considered black); less than 1.0 suggests that lower is desirable. Must be greater
* than 0.0; 1.0 is a good "default" * than 0.0; 1.0 is a good "default"
* @return index within argument of bucket corresponding to brightest values which should be * @return index within argument of bucket corresponding to brightest values which should be
* considered "black" * considered "black"
*/ */
public static int estimate(int[] histogram, float biasTowardsWhite) { public static int estimate(int[] histogram, float biasTowardsWhite) {
if (Float.isNaN(biasTowardsWhite) || biasTowardsWhite <= 0.0f) { if (Float.isNaN(biasTowardsWhite) || biasTowardsWhite <= 0.0f) {
throw new IllegalArgumentException("Illegal biasTowardsWhite: " + biasTowardsWhite); throw new IllegalArgumentException("Illegal biasTowardsWhite: " + biasTowardsWhite);
} }
int numBuckets = histogram.length; int numBuckets = histogram.length;

View file

@ -32,7 +32,7 @@ public final class Collections {
/** /**
* Sorts its argument (destructively) using insert sort; in the context of this package * Sorts its argument (destructively) using insert sort; in the context of this package
* insertion sort is simple and efficient given its relatively small inputs. * insertion sort is simple and efficient given its relatively small inputs.
* *
* @param vector vector to sort * @param vector vector to sort
* @param comparator comparator to define sort ordering * @param comparator comparator to define sort ordering
*/ */

View file

@ -21,7 +21,7 @@ import com.google.zxing.ResultPoint;
/** /**
* <p>Simple implementation of {@link ResultPoint} for applications that don't need * <p>Simple implementation of {@link ResultPoint} for applications that don't need
* to use anything more complex.</p> * to use anything more complex.</p>
* *
* @author dswitkin@google.com (Daniel Switkin) * @author dswitkin@google.com (Daniel Switkin)
*/ */
public final class GenericResultPoint implements ResultPoint { public final class GenericResultPoint implements ResultPoint {

View file

@ -32,6 +32,7 @@ final class GF256 {
private static final int PRIMITIVE = 0x011D; private static final int PRIMITIVE = 0x011D;
private static final int[] exp = new int[256]; private static final int[] exp = new int[256];
private static final int[] log = new int[256]; private static final int[] log = new int[256];
static { static {
int x = 1; int x = 1;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
@ -52,7 +53,7 @@ final class GF256 {
/** /**
* Implements both addition and subtraction -- they are the same in GF(256). * Implements both addition and subtraction -- they are the same in GF(256).
* *
* @return sum/difference of a and b * @return sum/difference of a and b
*/ */
static int addOrSubtract(int a, int b) { static int addOrSubtract(int a, int b) {
@ -87,7 +88,6 @@ final class GF256 {
} }
/** /**
*
* @param a * @param a
* @param b * @param b
* @return product of a and b in GF(256) * @return product of a and b in GF(256)

View file

@ -27,19 +27,23 @@ package com.google.zxing.common.reedsolomon;
*/ */
final class GF256Poly { final class GF256Poly {
/** Polynimal representing the monomial 0. */ /**
static final GF256Poly ZERO = new GF256Poly(new int[] { 0 }); * Polynimal representing the monomial 0.
/** Polynimal representing the monomial 1. */ */
static final GF256Poly ONE = new GF256Poly(new int[] { 1 }); static final GF256Poly ZERO = new GF256Poly(new int[]{0});
/**
* Polynimal representing the monomial 1.
*/
static final GF256Poly ONE = new GF256Poly(new int[]{1});
private final int[] coefficients; private final int[] coefficients;
/** /**
* @param coefficients coefficients as ints representing elements of GF(256), arranged * @param coefficients coefficients as ints representing elements of GF(256), arranged
* from most significant (highest-power term) coefficient to least significant * from most significant (highest-power term) coefficient to least significant
* @throws IllegalArgumentException if argument is null or empty, * @throws IllegalArgumentException if argument is null or empty,
* or if leading coefficient is 0 and this is not a * or if leading coefficient is 0 and this is not a
* constant polynomial (that is, it is not the monomial "0") * constant polynomial (that is, it is not the monomial "0")
*/ */
GF256Poly(int[] coefficients) { GF256Poly(int[] coefficients) {
if (coefficients == null || coefficients.length == 0) { if (coefficients == null || coefficients.length == 0) {
@ -56,10 +60,10 @@ final class GF256Poly {
} else { } else {
this.coefficients = new int[coefficients.length - firstNonZero]; this.coefficients = new int[coefficients.length - firstNonZero];
System.arraycopy(coefficients, System.arraycopy(coefficients,
firstNonZero, firstNonZero,
this.coefficients, this.coefficients,
0, 0,
this.coefficients.length); this.coefficients.length);
} }
} else { } else {
this.coefficients = coefficients; this.coefficients = coefficients;
@ -183,7 +187,7 @@ final class GF256Poly {
int aCoeff = aCoefficients[i]; int aCoeff = aCoefficients[i];
for (int j = 0; j < bLength; j++) { for (int j = 0; j < bLength; j++) {
product[i + j] = GF256.addOrSubtract(product[i + j], product[i + j] = GF256.addOrSubtract(product[i + j],
GF256.multiply(aCoeff, bCoefficients[j])); GF256.multiply(aCoeff, bCoefficients[j]));
} }
} }
return new GF256Poly(product); return new GF256Poly(product);
@ -212,7 +216,7 @@ final class GF256Poly {
if (coefficient == 0) { if (coefficient == 0) {
return ZERO; return ZERO;
} }
int size = coefficients.length; int size = coefficients.length;
int[] product = new int[size + degree]; int[] product = new int[size + degree];
System.arraycopy(coefficients, 0, product, 0, size); System.arraycopy(coefficients, 0, product, 0, size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {

View file

@ -26,8 +26,8 @@ import java.util.Vector;
* *
* <ul> * <ul>
* <li>Bruce Maggs. * <li>Bruce Maggs.
* <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps"> * <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps">
* "Decoding Reed-Solomon Codes"</a> (see discussion of Forney's Formula)</li> * "Decoding Reed-Solomon Codes"</a> (see discussion of Forney's Formula)</li>
* <li>J.I. Hall. <a href="www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf"> * <li>J.I. Hall. <a href="www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf">
* "Chapter 5. Generalized Reed-Solomon Codes"</a> * "Chapter 5. Generalized Reed-Solomon Codes"</a>
* (see discussion of Euclidean algorithm)</li> * (see discussion of Euclidean algorithm)</li>
@ -40,7 +40,7 @@ import java.util.Vector;
* @author William Rucklidge * @author William Rucklidge
*/ */
public final class ReedSolomonDecoder { public final class ReedSolomonDecoder {
private ReedSolomonDecoder() { private ReedSolomonDecoder() {
} }
@ -125,7 +125,7 @@ public final class ReedSolomonDecoder {
int inverse = GF256.inverse(sigmaTildeAtZero); int inverse = GF256.inverse(sigmaTildeAtZero);
GF256Poly sigma = t.multiply(inverse); GF256Poly sigma = t.multiply(inverse);
GF256Poly omega = r.multiply(inverse); GF256Poly omega = r.multiply(inverse);
return new GF256Poly[] { sigma, omega }; return new GF256Poly[]{sigma, omega};
} }
private static int[] findErrorLocations(GF256Poly errorLocator) private static int[] findErrorLocations(GF256Poly errorLocator)
@ -162,7 +162,7 @@ public final class ReedSolomonDecoder {
} }
} }
result[i] = GF256.multiply(errorEvaluator.evaluateAt(xiInverse), result[i] = GF256.multiply(errorEvaluator.evaluateAt(xiInverse),
GF256.inverse(denominator)); GF256.inverse(denominator));
} }
return result; return result;
} }

View file

@ -19,7 +19,7 @@ package com.google.zxing.common.reedsolomon;
/** /**
* <p>Thrown when an exception occurs during Reed-Solomon decoding, such as when * <p>Thrown when an exception occurs during Reed-Solomon decoding, such as when
* there are too many errors to correct.</p> * there are too many errors to correct.</p>
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
public final class ReedSolomonException extends Exception { public final class ReedSolomonException extends Exception {

View file

@ -16,9 +16,9 @@
package com.google.zxing.oned; package com.google.zxing.oned;
import com.google.zxing.ReaderException;
import com.google.zxing.Result; import com.google.zxing.Result;
import com.google.zxing.ResultPoint; import com.google.zxing.ResultPoint;
import com.google.zxing.ReaderException;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.GenericResultPoint; import com.google.zxing.common.GenericResultPoint;
@ -34,13 +34,19 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
private static final float MAX_VARIANCE = 0.4f; private static final float MAX_VARIANCE = 0.4f;
/** Start/end guard pattern. */ /**
* Start/end guard pattern.
*/
protected static final int[] START_END_PATTERN = {1, 1, 1,}; protected static final int[] START_END_PATTERN = {1, 1, 1,};
/** Pattern marking the middle of a UPC/EAN pattern, separating the two halves. */ /**
* Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
*/
protected static final int[] MIDDLE_PATTERN = {1, 1, 1, 1, 1}; protected static final int[] MIDDLE_PATTERN = {1, 1, 1, 1, 1};
/** "Odd", or "L" patterns used to encode UPC/EAN digits. */ /**
* "Odd", or "L" patterns used to encode UPC/EAN digits.
*/
protected static final int[][] L_PATTERNS = { protected static final int[][] L_PATTERNS = {
{3, 2, 1, 1}, // 0 {3, 2, 1, 1}, // 0
{2, 2, 2, 1}, // 1 {2, 2, 2, 1}, // 1
@ -54,7 +60,9 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
{3, 1, 1, 2} // 9 {3, 1, 1, 2} // 9
}; };
/** As above but also including the "even", or "G" patterns used to encode UPC/EAN digits. */ /**
* As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
*/
protected static final int[][] L_AND_G_PATTERNS; protected static final int[][] L_AND_G_PATTERNS;
static { static {
@ -164,9 +172,9 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
* @param row row of black/white values to search * @param row row of black/white values to search
* @param rowOffset position to start search * @param rowOffset position to start search
* @param whiteFirst if true, indicates that the pattern specifies white/black/white/... * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
* pixel counts, otherwise, it is interpreted as black/white/black/... * pixel counts, otherwise, it is interpreted as black/white/black/...
* @param pattern pattern of counts of number of black and white pixels that are being * @param pattern pattern of counts of number of black and white pixels that are being
* searched for as a pattern * searched for as a pattern
* @return start/end horizontal offset of guard pattern, as an array of two ints * @return start/end horizontal offset of guard pattern, as an array of two ints
* @throws ReaderException if pattern is not found * @throws ReaderException if pattern is not found
*/ */
@ -193,7 +201,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
} else { } else {
if (counterPosition == patternLength - 1) { if (counterPosition == patternLength - 1) {
if (patternMatchVariance(counters, pattern) < MAX_VARIANCE) { if (patternMatchVariance(counters, pattern) < MAX_VARIANCE) {
return new int[] {patternStart, x}; return new int[]{patternStart, x};
} }
patternStart += counters[0] + counters[1]; patternStart += counters[0] + counters[1];
for (int y = 2; y < patternLength; y++) { for (int y = 2; y < patternLength; y++) {
@ -217,8 +225,8 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
* @param counters the counts of runs of observed black/white/black/... values * @param counters the counts of runs of observed black/white/black/... values
* @param rowOffset horizontal offset to start decoding from * @param rowOffset horizontal offset to start decoding from
* @param patterns the set of patterns to use to decode -- sometimes different encodings * @param patterns the set of patterns to use to decode -- sometimes different encodings
* for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should * for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should
* be used * be used
* @return horizontal offset of first pixel beyond the decoded digit * @return horizontal offset of first pixel beyond the decoded digit
* @throws ReaderException if digit cannot be decoded * @throws ReaderException if digit cannot be decoded
*/ */

View file

@ -16,8 +16,8 @@
package com.google.zxing.oned; package com.google.zxing.oned;
import com.google.zxing.Result;
import com.google.zxing.ReaderException; import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint; import com.google.zxing.ResultPoint;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.GenericResultPoint; import com.google.zxing.common.GenericResultPoint;
@ -182,7 +182,7 @@ public final class Code128Reader extends AbstractOneDReader {
if (counterPosition == patternLength - 1) { if (counterPosition == patternLength - 1) {
for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) { for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {
if (patternMatchVariance(counters, CODE_PATTERNS[startCode]) < MAX_VARIANCE) { if (patternMatchVariance(counters, CODE_PATTERNS[startCode]) < MAX_VARIANCE) {
return new int[] {patternStart, i, startCode}; return new int[]{patternStart, i, startCode};
} }
} }
patternStart += counters[0] + counters[1]; patternStart += counters[0] + counters[1];

View file

@ -56,7 +56,7 @@ public final class Code39Reader extends AbstractOneDReader {
* Creates a reader that can be configured to check the last character as a check digit. * Creates a reader that can be configured to check the last character as a check digit.
* *
* @param usingCheckDigit if true, treat the last data character as a check digit, not * @param usingCheckDigit if true, treat the last data character as a check digit, not
* data, and verify that the checksum passes * data, and verify that the checksum passes
*/ */
public Code39Reader(boolean usingCheckDigit) { public Code39Reader(boolean usingCheckDigit) {
this.usingCheckDigit = usingCheckDigit; this.usingCheckDigit = usingCheckDigit;
@ -138,7 +138,7 @@ public final class Code39Reader extends AbstractOneDReader {
if (counterPosition == patternLength - 1) { if (counterPosition == patternLength - 1) {
try { try {
if (toNarrowWidePattern(counters) == ASTERISK_ENCODING) { if (toNarrowWidePattern(counters) == ASTERISK_ENCODING) {
return new int[] {patternStart, i}; return new int[]{patternStart, i};
} }
} catch (ReaderException re) { } catch (ReaderException re) {
// no match, continue // no match, continue

View file

@ -102,7 +102,7 @@ public final class EAN13Reader extends AbstractUPCEANReader {
* *
* @param resultString string to insert decoded first digit into * @param resultString string to insert decoded first digit into
* @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to
* encode digits * encode digits
* @throws ReaderException if first digit cannot be determined * @throws ReaderException if first digit cannot be determined
*/ */
private static void determineFirstDigit(StringBuffer resultString, int lgPatternFound) throws ReaderException { private static void determineFirstDigit(StringBuffer resultString, int lgPatternFound) throws ReaderException {

View file

@ -33,7 +33,7 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader {
* Reader implementations to which this implementation delegates, in the order * Reader implementations to which this implementation delegates, in the order
* they will be attempted. Order is important. * they will be attempted. Order is important.
*/ */
private final UPCEANReader[] readers = new UPCEANReader[] { private final UPCEANReader[] readers = new UPCEANReader[]{
new EAN13Reader(), new UPCAReader(), new EAN8Reader(), new UPCEReader() new EAN13Reader(), new UPCAReader(), new EAN8Reader(), new UPCEReader()
}; };

View file

@ -34,7 +34,7 @@ public interface OneDReader extends Reader {
* an image.</p> * an image.</p>
* *
* @param rowNumber row number from top of the row * @param rowNumber row number from top of the row
* @param row the black/white pixel data of the row * @param row the black/white pixel data of the row
* @return {@link Result} containing encoded string and start/end of barcode * @return {@link Result} containing encoded string and start/end of barcode
* @throws ReaderException if an error occurs or barcode cannot be found * @throws ReaderException if an error occurs or barcode cannot be found
*/ */

View file

@ -45,7 +45,7 @@ final class BitMatrixParser {
* *
* @return {@link FormatInformation} encapsulating the QR Code's format info * @return {@link FormatInformation} encapsulating the QR Code's format info
* @throws ReaderException if both format information locations cannot be parsed as * @throws ReaderException if both format information locations cannot be parsed as
* the valid encoding of format information * the valid encoding of format information
*/ */
FormatInformation readFormatInformation() throws ReaderException { FormatInformation readFormatInformation() throws ReaderException {
@ -95,7 +95,7 @@ final class BitMatrixParser {
* *
* @return {@link Version} encapsulating the QR Code's version * @return {@link Version} encapsulating the QR Code's version
* @throws ReaderException if both version information locations cannot be parsed as * @throws ReaderException if both version information locations cannot be parsed as
* the valid encoding of version information * the valid encoding of version information
*/ */
Version readVersion() throws ReaderException { Version readVersion() throws ReaderException {

View file

@ -32,7 +32,7 @@ final class BitSource {
/** /**
* @param bytes bytes from which this will read bits. Bits will be read from the first byte first. * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
* Bits are read within a byte from most-significant to least-significant bit. * Bits are read within a byte from most-significant to least-significant bit.
*/ */
BitSource(byte[] bytes) { BitSource(byte[] bytes) {
this.bytes = bytes; this.bytes = bytes;
@ -41,7 +41,7 @@ final class BitSource {
/** /**
* @param numBits number of bits to read * @param numBits number of bits to read
* @return int representing the bits read. The bits will appear as the least-significant * @return int representing the bits read. The bits will appear as the least-significant
* bits of the int * bits of the int
* @throws IllegalArgumentException if numBits isn't in [1,32] * @throws IllegalArgumentException if numBits isn't in [1,32]
*/ */
int readBits(int numBits) { int readBits(int numBits) {

View file

@ -42,7 +42,7 @@ final class DataBlock {
* @param version version of the QR Code * @param version version of the QR Code
* @param ecLevel error-correction level of the QR Code * @param ecLevel error-correction level of the QR Code
* @return {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the * @return {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the
* QR Code * QR Code
*/ */
static DataBlock[] getDataBlocks(byte[] rawCodewords, static DataBlock[] getDataBlocks(byte[] rawCodewords,
Version version, Version version,

View file

@ -57,7 +57,7 @@ abstract class DataMask {
/** /**
* @param reference a value between 0 and 7 indicating one of the eight possible * @param reference a value between 0 and 7 indicating one of the eight possible
* data mask patterns a QR Code may use * data mask patterns a QR Code may use
* @return {@link DataMask} encapsulating the data mask pattern * @return {@link DataMask} encapsulating the data mask pattern
*/ */
static DataMask forReference(int reference) { static DataMask forReference(int reference) {

View file

@ -26,16 +26,24 @@ final class ErrorCorrectionLevel {
// No, we can't use an enum here. J2ME doesn't support it. // No, we can't use an enum here. J2ME doesn't support it.
/** L = ~7% correction */ /**
* L = ~7% correction
*/
static final ErrorCorrectionLevel L = new ErrorCorrectionLevel(0); static final ErrorCorrectionLevel L = new ErrorCorrectionLevel(0);
/** M = ~15% correction */ /**
* M = ~15% correction
*/
static final ErrorCorrectionLevel M = new ErrorCorrectionLevel(1); static final ErrorCorrectionLevel M = new ErrorCorrectionLevel(1);
/** Q = ~25% correction */ /**
* Q = ~25% correction
*/
static final ErrorCorrectionLevel Q = new ErrorCorrectionLevel(2); static final ErrorCorrectionLevel Q = new ErrorCorrectionLevel(2);
/** H = ~30% correction */ /**
* H = ~30% correction
*/
static final ErrorCorrectionLevel H = new ErrorCorrectionLevel(3); static final ErrorCorrectionLevel H = new ErrorCorrectionLevel(3);
private static final ErrorCorrectionLevel[] FOR_BITS = new ErrorCorrectionLevel[] { M, L, H, Q }; private static final ErrorCorrectionLevel[] FOR_BITS = new ErrorCorrectionLevel[]{M, L, H, Q};
private final int ordinal; private final int ordinal;

View file

@ -66,7 +66,9 @@ final class FormatInformation {
{0x2BED, 0x1F}, {0x2BED, 0x1F},
}; };
/** Offset i holds the number of 1 bits in the binary representation of i */ /**
* Offset i holds the number of 1 bits in the binary representation of i
*/
private static final int[] BITS_SET_IN_HALF_BYTE = private static final int[] BITS_SET_IN_HALF_BYTE =
new int[]{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; new int[]{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
@ -83,18 +85,17 @@ final class FormatInformation {
static int numBitsDiffering(int a, int b) { static int numBitsDiffering(int a, int b) {
a ^= b; // a now has a 1 bit exactly where its bit differs with b's a ^= b; // a now has a 1 bit exactly where its bit differs with b's
// Count bits set quickly with a series of lookups: // Count bits set quickly with a series of lookups:
return BITS_SET_IN_HALF_BYTE[a & 0x0F] + return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
BITS_SET_IN_HALF_BYTE[(a >>> 4 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 4 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 8 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 8 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 12 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 12 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 16 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 16 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 20 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 20 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 24 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >>> 24 & 0x0F)] +
BITS_SET_IN_HALF_BYTE[(a >>> 28 & 0x0F)]; BITS_SET_IN_HALF_BYTE[(a >>> 28 & 0x0F)];
} }
/** /**
*
* @param rawFormatInfo * @param rawFormatInfo
* @return * @return
*/ */

View file

@ -27,12 +27,12 @@ import com.google.zxing.ReaderException;
final class Mode { final class Mode {
// No, we can't use an enum here. J2ME doesn't support it. // No, we can't use an enum here. J2ME doesn't support it.
static final Mode TERMINATOR = new Mode(new int[] {0, 0, 0}); // Not really a mode... static final Mode TERMINATOR = new Mode(new int[]{0, 0, 0}); // Not really a mode...
static final Mode NUMERIC = new Mode(new int[] {10, 12, 14}); static final Mode NUMERIC = new Mode(new int[]{10, 12, 14});
static final Mode ALPHANUMERIC = new Mode(new int[] {9, 11, 13}); static final Mode ALPHANUMERIC = new Mode(new int[]{9, 11, 13});
static final Mode BYTE = new Mode(new int[] {8, 16, 16}); static final Mode BYTE = new Mode(new int[]{8, 16, 16});
static final Mode KANJI = new Mode(new int[] {8, 10, 12}); static final Mode KANJI = new Mode(new int[]{8, 10, 12});
private int[] characterCountBitsForVersions; private int[] characterCountBitsForVersions;
@ -65,7 +65,7 @@ final class Mode {
/** /**
* @param version version in question * @param version version in question
* @return number of bits used, in this QR Code symbol {@link Version}, to encode the * @return number of bits used, in this QR Code symbol {@link Version}, to encode the
* count of characters that will follow encoded in this {@link Mode} * count of characters that will follow encoded in this {@link Mode}
*/ */
int getCharacterCountBits(Version version) { int getCharacterCountBits(Version version) {
int number = version.getVersionNumber(); int number = version.getVersionNumber();

View file

@ -55,7 +55,7 @@ public final class Version {
ECBlocks ecBlocks4) { ECBlocks ecBlocks4) {
this.versionNumber = versionNumber; this.versionNumber = versionNumber;
this.alignmentPatternCenters = alignmentPatternCenters; this.alignmentPatternCenters = alignmentPatternCenters;
this.ecBlocks = new ECBlocks[] { ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4 }; this.ecBlocks = new ECBlocks[]{ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4};
int total = 0; int total = 0;
ECBlocks levelLECBlocks = ecBlocks1; // L,M,Q,H -- all the same total ECBlocks levelLECBlocks = ecBlocks1; // L,M,Q,H -- all the same total
int ecCodewords = levelLECBlocks.ecCodewords; int ecCodewords = levelLECBlocks.ecCodewords;
@ -187,12 +187,12 @@ public final class Version {
private ECBlocks(int ecCodewords, ECB ecBlocks) { private ECBlocks(int ecCodewords, ECB ecBlocks) {
this.ecCodewords = ecCodewords; this.ecCodewords = ecCodewords;
this.ecBlocks = new ECB[] { ecBlocks }; this.ecBlocks = new ECB[]{ecBlocks};
} }
private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) { private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {
this.ecCodewords = ecCodewords; this.ecCodewords = ecCodewords;
this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 }; this.ecBlocks = new ECB[]{ecBlocks1, ecBlocks2};
} }
int getECCodewords() { int getECCodewords() {

View file

@ -55,9 +55,9 @@ public final class AlignmentPattern implements ResultPoint {
boolean aboutEquals(float moduleSize, float i, float j) { boolean aboutEquals(float moduleSize, float i, float j) {
return return
Math.abs(i - posY) <= moduleSize && Math.abs(i - posY) <= moduleSize &&
Math.abs(j - posX) <= moduleSize && Math.abs(j - posX) <= moduleSize &&
(Math.abs(moduleSize - estimatedModuleSize) <= 1.0f || (Math.abs(moduleSize - estimatedModuleSize) <= 1.0f ||
Math.abs(moduleSize - estimatedModuleSize) / estimatedModuleSize <= 0.1f); Math.abs(moduleSize - estimatedModuleSize) / estimatedModuleSize <= 0.1f);
} }
} }

View file

@ -160,7 +160,7 @@ final class AlignmentPatternFinder {
/** /**
* @param stateCount count of black/white/black pixels just read * @param stateCount count of black/white/black pixels just read
* @return true iff the proportions of the counts is close enough to the 1/1/1 ratios * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios
* used by alignment patterns to be considered a match * used by alignment patterns to be considered a match
*/ */
private boolean foundPatternCross(int[] stateCount) { private boolean foundPatternCross(int[] stateCount) {
float moduleSize = this.moduleSize; float moduleSize = this.moduleSize;
@ -181,7 +181,7 @@ final class AlignmentPatternFinder {
* @param startI row where an alignment pattern was detected * @param startI row where an alignment pattern was detected
* @param centerJ center of the section that appears to cross an alignment pattern * @param centerJ center of the section that appears to cross an alignment pattern
* @param maxCount maximum reasonable number of modules that should be * @param maxCount maximum reasonable number of modules that should be
* observed in any reading state, based on the results of the horizontal scan * observed in any reading state, based on the results of the horizontal scan
* @return vertical center of alignment pattern, or {@link Float#NaN} if not found * @return vertical center of alignment pattern, or {@link Float#NaN} if not found
*/ */
private float crossCheckVertical(int startI, int centerJ, int maxCount) { private float crossCheckVertical(int startI, int centerJ, int maxCount) {

View file

@ -37,12 +37,12 @@ public final class Detector {
this.image = image; this.image = image;
} }
/** /**
* <p>Detects a QR Code in an image, simply.</p> * <p>Detects a QR Code in an image, simply.</p>
* *
* @return {@link DetectorResult} encapsulating results of detecting a QR Code * @return {@link DetectorResult} encapsulating results of detecting a QR Code
* @throws ReaderException if no QR Code can be found * @throws ReaderException if no QR Code can be found
*/ */
public DetectorResult detect() throws ReaderException { public DetectorResult detect() throws ReaderException {
MonochromeBitmapSource image = this.image; MonochromeBitmapSource image = this.image;
@ -99,9 +99,9 @@ public final class Detector {
ResultPoint[] points; ResultPoint[] points;
if (alignmentPattern == null) { if (alignmentPattern == null) {
points = new ResultPoint[] { bottomLeft, topLeft, topRight }; points = new ResultPoint[]{bottomLeft, topLeft, topRight};
} else { } else {
points = new ResultPoint[] { bottomLeft, topLeft, topRight, alignmentPattern }; points = new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern};
} }
return new DetectorResult(bits, points); return new DetectorResult(bits, points);
} }
@ -121,7 +121,7 @@ public final class Detector {
case 0: case 0:
dimension++; dimension++;
break; break;
// 1? do nothing // 1? do nothing
case 2: case 2:
dimension--; dimension--;
break; break;
@ -138,23 +138,23 @@ public final class Detector {
private float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft) { private float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft) {
// Take the average // Take the average
return (calculateModuleSizeOneWay(topLeft, topRight) + return (calculateModuleSizeOneWay(topLeft, topRight) +
calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f; calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
} }
/** /**
* <p>Estimates module size based on two finder patterns -- it uses * <p>Estimates module size based on two finder patterns -- it uses
* {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the
* width of each, measuring along the axis between their centers.</p> * width of each, measuring along the axis between their centers.</p>
*/ */
private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern) { private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern) {
float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.getX(), float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.getX(),
(int) pattern.getY(), (int) pattern.getY(),
(int) otherPattern.getX(), (int) otherPattern.getX(),
(int) otherPattern.getY()); (int) otherPattern.getY());
float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.getX(), float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.getX(),
(int) otherPattern.getY(), (int) otherPattern.getY(),
(int) pattern.getX(), (int) pattern.getX(),
(int) pattern.getY()); (int) pattern.getY());
if (Float.isNaN(moduleSizeEst1)) { if (Float.isNaN(moduleSizeEst1)) {
return moduleSizeEst2; return moduleSizeEst2;
} }

View file

@ -65,8 +65,8 @@ public final class FinderPattern implements ResultPoint {
*/ */
boolean aboutEquals(float moduleSize, float i, float j) { boolean aboutEquals(float moduleSize, float i, float j) {
return Math.abs(i - posY) <= moduleSize && return Math.abs(i - posY) <= moduleSize &&
Math.abs(j - posX) <= moduleSize && Math.abs(j - posX) <= moduleSize &&
(Math.abs(moduleSize - estimatedModuleSize) <= 1.0f || (Math.abs(moduleSize - estimatedModuleSize) <= 1.0f ||
Math.abs(moduleSize - estimatedModuleSize) / estimatedModuleSize <= 0.1f); Math.abs(moduleSize - estimatedModuleSize) / estimatedModuleSize <= 0.1f);
} }

View file

@ -165,7 +165,7 @@ final class FinderPatternFinder {
/** /**
* @param stateCount count of black/white/black/white/black pixels just read * @param stateCount count of black/white/black/white/black pixels just read
* @return true iff the proportions of the counts is close enough to the 1/13/1/1 ratios * @return true iff the proportions of the counts is close enough to the 1/13/1/1 ratios
* used by finder patterns to be considered a match * used by finder patterns to be considered a match
*/ */
private static boolean foundPatternCross(int[] stateCount) { private static boolean foundPatternCross(int[] stateCount) {
int totalModuleSize = 0; int totalModuleSize = 0;
@ -181,11 +181,11 @@ final class FinderPatternFinder {
float moduleSize = (float) totalModuleSize / 7.0f; float moduleSize = (float) totalModuleSize / 7.0f;
float maxVariance = moduleSize / 2.5f; float maxVariance = moduleSize / 2.5f;
// Allow less than 40% variance from 1-1-3-1-1 proportions // Allow less than 40% variance from 1-1-3-1-1 proportions
return Math.abs(moduleSize - stateCount[0]) < maxVariance && return Math.abs(moduleSize - stateCount[0]) < maxVariance &&
Math.abs(moduleSize - stateCount[1]) < maxVariance && Math.abs(moduleSize - stateCount[1]) < maxVariance &&
Math.abs(3.0f * moduleSize - stateCount[2]) < 3.0f * maxVariance && Math.abs(3.0f * moduleSize - stateCount[2]) < 3.0f * maxVariance &&
Math.abs(moduleSize - stateCount[3]) < maxVariance && Math.abs(moduleSize - stateCount[3]) < maxVariance &&
Math.abs(moduleSize - stateCount[4]) < maxVariance; Math.abs(moduleSize - stateCount[4]) < maxVariance;
} }
/** /**
@ -196,7 +196,7 @@ final class FinderPatternFinder {
* @param startI row where a finder pattern was detected * @param startI row where a finder pattern was detected
* @param centerJ center of the section that appears to cross a finder pattern * @param centerJ center of the section that appears to cross a finder pattern
* @param maxCount maximum reasonable number of modules that should be * @param maxCount maximum reasonable number of modules that should be
* observed in any reading state, based on the results of the horizontal scan * observed in any reading state, based on the results of the horizontal scan
* @return vertical center of finder pattern, or {@link Float#NaN} if not found * @return vertical center of finder pattern, or {@link Float#NaN} if not found
*/ */
private float crossCheckVertical(int startI, int centerJ, int maxCount) { private float crossCheckVertical(int startI, int centerJ, int maxCount) {
@ -343,7 +343,7 @@ final class FinderPatternFinder {
centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2]); centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2]);
if (!Float.isNaN(centerJ)) { if (!Float.isNaN(centerJ)) {
float estimatedModuleSize = float estimatedModuleSize =
(float) (stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]) / 7.0f; (float) (stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]) / 7.0f;
boolean found = false; boolean found = false;
int max = possibleCenters.size(); int max = possibleCenters.size();
for (int index = 0; index < max; index++) { for (int index = 0; index < max; index++) {
@ -366,9 +366,9 @@ final class FinderPatternFinder {
/** /**
* @return number of rows we could safely skip during scanning, based on the first * @return number of rows we could safely skip during scanning, based on the first
* two finder patterns that have been located. In some cases their position will * two finder patterns that have been located. In some cases their position will
* allow us to infer that the third pattern must lie below a certain point farther * allow us to infer that the third pattern must lie below a certain point farther
* down in the image. * down in the image.
*/ */
private int findRowSkip() { private int findRowSkip() {
int max = possibleCenters.size(); int max = possibleCenters.size();
@ -389,7 +389,7 @@ final class FinderPatternFinder {
// This is the case where you find top left first. Draw it out. // This is the case where you find top left first. Draw it out.
hasSkipped = true; hasSkipped = true;
return (int) Math.abs(Math.abs(firstConfirmedCenter.getX() - center.getX()) - return (int) Math.abs(Math.abs(firstConfirmedCenter.getX() - center.getX()) -
Math.abs(firstConfirmedCenter.getY() - center.getY())); Math.abs(firstConfirmedCenter.getY() - center.getY()));
} }
} }
} }
@ -398,7 +398,7 @@ final class FinderPatternFinder {
/** /**
* @return true iff we have found at least 3 finder patterns that have been detected * @return true iff we have found at least 3 finder patterns that have been detected
* at least {@link #CENTER_QUORUM} times each * at least {@link #CENTER_QUORUM} times each
*/ */
private boolean haveMulitplyConfirmedCenters() { private boolean haveMulitplyConfirmedCenters() {
int count = 0; int count = 0;
@ -415,8 +415,8 @@ final class FinderPatternFinder {
/** /**
* @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are * @return the 3 best {@link FinderPattern}s from our list of candidates. The "best" are
* those that have been detected at least {@link #CENTER_QUORUM} times, and whose module * those that have been detected at least {@link #CENTER_QUORUM} times, and whose module
* size differs from the average among those patterns the least * size differs from the average among those patterns the least
* @throws ReaderException if 3 such finder patterns do not exist * @throws ReaderException if 3 such finder patterns do not exist
*/ */
private FinderPattern[] selectBestPatterns() throws ReaderException { private FinderPattern[] selectBestPatterns() throws ReaderException {
@ -437,10 +437,10 @@ final class FinderPatternFinder {
if (size == 3) { if (size == 3) {
// Found just enough -- hope these are good! // Found just enough -- hope these are good!
return new FinderPattern[] { return new FinderPattern[]{
(FinderPattern) possibleCenters.elementAt(0), (FinderPattern) possibleCenters.elementAt(0),
(FinderPattern) possibleCenters.elementAt(1), (FinderPattern) possibleCenters.elementAt(1),
(FinderPattern) possibleCenters.elementAt(2) (FinderPattern) possibleCenters.elementAt(2)
}; };
} }
@ -458,10 +458,10 @@ final class FinderPatternFinder {
// We don't have java.util.Collections in J2ME // We don't have java.util.Collections in J2ME
Collections.insertionSort(possibleCenters, new ClosestToAverageComparator(averageModuleSize)); Collections.insertionSort(possibleCenters, new ClosestToAverageComparator(averageModuleSize));
return new FinderPattern[] { return new FinderPattern[]{
(FinderPattern) possibleCenters.elementAt(0), (FinderPattern) possibleCenters.elementAt(0),
(FinderPattern) possibleCenters.elementAt(1), (FinderPattern) possibleCenters.elementAt(1),
(FinderPattern) possibleCenters.elementAt(2) (FinderPattern) possibleCenters.elementAt(2)
}; };
} }
@ -510,7 +510,7 @@ final class FinderPatternFinder {
bottomLeft = temp; bottomLeft = temp;
} }
return new FinderPattern[] {bottomLeft, topLeft, topRight}; return new FinderPattern[]{bottomLeft, topLeft, topRight};
} }
/** /**
@ -536,14 +536,16 @@ final class FinderPatternFinder {
*/ */
private static class ClosestToAverageComparator implements Comparator { private static class ClosestToAverageComparator implements Comparator {
private final float averageModuleSize; private final float averageModuleSize;
private ClosestToAverageComparator(float averageModuleSize) { private ClosestToAverageComparator(float averageModuleSize) {
this.averageModuleSize = averageModuleSize; this.averageModuleSize = averageModuleSize;
} }
public int compare(Object center1, Object center2) { public int compare(Object center1, Object center2) {
return Math.abs(((FinderPattern) center1).getEstimatedModuleSize() - averageModuleSize) < return Math.abs(((FinderPattern) center1).getEstimatedModuleSize() - averageModuleSize) <
Math.abs(((FinderPattern) center2).getEstimatedModuleSize() - averageModuleSize) ? Math.abs(((FinderPattern) center2).getEstimatedModuleSize() - averageModuleSize) ?
-1 : -1 :
1; 1;
} }
} }

View file

@ -19,7 +19,7 @@ package com.google.zxing.qrcode.detector;
/** /**
* <p>Encapsulates information about finder patterns in an image, including the location of * <p>Encapsulates information about finder patterns in an image, including the location of
* the three finder patterns, and their estimated module size.</p> * the three finder patterns, and their estimated module size.</p>
* *
* @author srowen@google.com (Sean Owen) * @author srowen@google.com (Sean Owen)
*/ */
final class FinderPatternInfo { final class FinderPatternInfo {

View file

@ -55,8 +55,8 @@ public abstract class GridSampler {
/** /**
* @return the current implementation of {@link GridSampler}, instantiating one if one does * @return the current implementation of {@link GridSampler}, instantiating one if one does
* not already exist. The class which is instantied may be set by * not already exist. The class which is instantied may be set by
* {@link #setGridSamplerClassName(String)} * {@link #setGridSamplerClassName(String)}
*/ */
public static GridSampler getInstance() { public static GridSampler getInstance() {
if (gridSampler == null) { if (gridSampler == null) {
@ -92,7 +92,7 @@ public abstract class GridSampler {
* @param dimension dimension of QR Code * @param dimension dimension of QR Code
* @return {@link BitMatrix} representing QR Code's modules * @return {@link BitMatrix} representing QR Code's modules
* @throws ReaderException if QR Code cannot be reasonably sampled -- for example if the location * @throws ReaderException if QR Code cannot be reasonably sampled -- for example if the location
* of the finder patterns imply a transformation that would require sampling off the image * of the finder patterns imply a transformation that would require sampling off the image
*/ */
protected abstract BitMatrix sampleGrid(MonochromeBitmapSource image, protected abstract BitMatrix sampleGrid(MonochromeBitmapSource image,
FinderPattern topLeft, FinderPattern topLeft,

View file

@ -64,73 +64,73 @@ final class PerspectiveTransform {
float a21 = this.a21; float a21 = this.a21;
float a22 = this.a22; float a22 = this.a22;
float a23 = this.a23; float a23 = this.a23;
float a31 = this.a31; float a31 = this.a31;
float a32 = this.a32; float a32 = this.a32;
float a33 = this.a33; float a33 = this.a33;
for (int i = 0; i < max; i += 2) { for (int i = 0; i < max; i += 2) {
float x = points[i]; float x = points[i];
float y = points[i+1]; float y = points[i + 1];
float denominator = a13*x + a23*y + a33; float denominator = a13 * x + a23 * y + a33;
points[i] = (a11*x + a21*y + a31) / denominator; points[i] = (a11 * x + a21 * y + a31) / denominator;
points[i+1] = (a12*x + a22*y + a32) / denominator; points[i + 1] = (a12 * x + a22 * y + a32) / denominator;
} }
} }
static PerspectiveTransform squareToQuadrilateral(float x0, float y0, static PerspectiveTransform squareToQuadrilateral(float x0, float y0,
float x1, float y1, float x1, float y1,
float x2, float y2, float x2, float y2,
float x3, float y3) { float x3, float y3) {
float dy2 = y3 - y2; float dy2 = y3 - y2;
float dy3 = y0 - y1 + y2 - y3; float dy3 = y0 - y1 + y2 - y3;
if (dy2 == 0.0f && dy3 == 0.0f) { if (dy2 == 0.0f && dy3 == 0.0f) {
return new PerspectiveTransform(x1 - x0, x2 - x1, x0, return new PerspectiveTransform(x1 - x0, x2 - x1, x0,
y1 - y0, y2 - y1, y0, y1 - y0, y2 - y1, y0,
0.0f, 0.0f, 1.0f); 0.0f, 0.0f, 1.0f);
} else { } else {
float dx1 = x1 - x2; float dx1 = x1 - x2;
float dx2 = x3 - x2; float dx2 = x3 - x2;
float dx3 = x0 - x1 + x2 - x3; float dx3 = x0 - x1 + x2 - x3;
float dy1 = y1 - y2; float dy1 = y1 - y2;
float denominator = dx1*dy2 - dx2*dy1; float denominator = dx1 * dy2 - dx2 * dy1;
float a13 = (dx3*dy2 - dx2*dy3) / denominator; float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
float a23 = (dx1*dy3 - dx3*dy1) / denominator; float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
return new PerspectiveTransform(x1 - x0 + a13*x1, x3 - x0 + a23*x3, x0, return new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0,
y1 - y0 + a13*y1, y3 - y0 + a23*y3, y0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0,
a13, a23, 1.0f); a13, a23, 1.0f);
} }
} }
static PerspectiveTransform quadrilateralToSquare(float x0, float y0, static PerspectiveTransform quadrilateralToSquare(float x0, float y0,
float x1, float y1, float x1, float y1,
float x2, float y2, float x2, float y2,
float x3, float y3) { float x3, float y3) {
// Here, the adjoint serves as the inverse: // Here, the adjoint serves as the inverse:
return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint(); return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();
} }
PerspectiveTransform buildAdjoint() { PerspectiveTransform buildAdjoint() {
// Adjoint is the transpose of the cofactor matrix: // Adjoint is the transpose of the cofactor matrix:
return new PerspectiveTransform(a22*a33 - a23*a32, return new PerspectiveTransform(a22 * a33 - a23 * a32,
a23*a31 - a21*a33, a23 * a31 - a21 * a33,
a21*a32 - a22*a31, a21 * a32 - a22 * a31,
a13*a32 - a12*a33, a13 * a32 - a12 * a33,
a11*a33 - a13*a31, a11 * a33 - a13 * a31,
a12*a31 - a11*a32, a12 * a31 - a11 * a32,
a12*a23 - a13*a22, a12 * a23 - a13 * a22,
a13*a21 - a11*a23, a13 * a21 - a11 * a23,
a11*a22 - a12*a21); a11 * a22 - a12 * a21);
} }
PerspectiveTransform times(PerspectiveTransform other) { PerspectiveTransform times(PerspectiveTransform other) {
return new PerspectiveTransform(a11*other.a11 + a21*other.a12 + a31*other.a13, return new PerspectiveTransform(a11 * other.a11 + a21 * other.a12 + a31 * other.a13,
a11*other.a21 + a21*other.a22 + a31*other.a23, a11 * other.a21 + a21 * other.a22 + a31 * other.a23,
a11*other.a31 + a21*other.a32 + a31*other.a33, a11 * other.a31 + a21 * other.a32 + a31 * other.a33,
a12*other.a11 + a22*other.a12 + a32*other.a13, a12 * other.a11 + a22 * other.a12 + a32 * other.a13,
a12*other.a21 + a22*other.a22 + a32*other.a23, a12 * other.a21 + a22 * other.a22 + a32 * other.a23,
a12*other.a31 + a22*other.a32 + a32*other.a33, a12 * other.a31 + a22 * other.a32 + a32 * other.a33,
a13*other.a11 + a23*other.a12 + a33*other.a13, a13 * other.a11 + a23 * other.a12 + a33 * other.a13,
a13*other.a21 + a23*other.a22 + a33*other.a23, a13 * other.a21 + a23 * other.a22 + a33 * other.a23,
a13*other.a31 + a23*other.a32 + a33*other.a33); a13 * other.a31 + a23 * other.a32 + a33 * other.a33);
} }

View file

@ -44,7 +44,7 @@ public final class ParsedReaderResultTestCase extends TestCase {
doTestResult("MATMSG:TO:srowen@example.org;SUB:Stuff;;", ParsedReaderResultType.EMAIL); doTestResult("MATMSG:TO:srowen@example.org;SUB:Stuff;;", ParsedReaderResultType.EMAIL);
doTestResult("MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", ParsedReaderResultType.EMAIL); doTestResult("MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", ParsedReaderResultType.EMAIL);
doTestResult("MATMSG:SUB:Stuff;BODY:This is some text;TO:srowen@example.org;;", ParsedReaderResultType.EMAIL); doTestResult("MATMSG:SUB:Stuff;BODY:This is some text;TO:srowen@example.org;;", ParsedReaderResultType.EMAIL);
doTestResult("TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", ParsedReaderResultType.TEXT); doTestResult("TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", ParsedReaderResultType.TEXT);
} }
public void testEmailAddressType() { public void testEmailAddressType() {
@ -59,7 +59,7 @@ public final class ParsedReaderResultTestCase extends TestCase {
doTestResult("MECARD:N:Sean Owen;;", ParsedReaderResultType.ADDRESSBOOK); doTestResult("MECARD:N:Sean Owen;;", ParsedReaderResultType.ADDRESSBOOK);
doTestResult("MECARD:TEL:+12125551212;N:Sean Owen;;", ParsedReaderResultType.ADDRESSBOOK); doTestResult("MECARD:TEL:+12125551212;N:Sean Owen;;", ParsedReaderResultType.ADDRESSBOOK);
doTestResult("MECARD:TEL:+12125551212;N:Sean Owen;URL:google.com;;", ParsedReaderResultType.ADDRESSBOOK); doTestResult("MECARD:TEL:+12125551212;N:Sean Owen;URL:google.com;;", ParsedReaderResultType.ADDRESSBOOK);
doTestResult("TEL:+12125551212;N:Sean Owen;;", ParsedReaderResultType.TEXT); doTestResult("TEL:+12125551212;N:Sean Owen;;", ParsedReaderResultType.TEXT);
} }
public void testUPC() { public void testUPC() {
@ -75,7 +75,7 @@ public final class ParsedReaderResultTestCase extends TestCase {
doTestResult("HTTP://google.com", ParsedReaderResultType.URI); doTestResult("HTTP://google.com", ParsedReaderResultType.URI);
doTestResult("http://google.com/foobar", ParsedReaderResultType.URI); doTestResult("http://google.com/foobar", ParsedReaderResultType.URI);
doTestResult("https://google.com:443/foobar", ParsedReaderResultType.URI); doTestResult("https://google.com:443/foobar", ParsedReaderResultType.URI);
doTestResult("google.com:443/foobar", ParsedReaderResultType.URI); doTestResult("google.com:443/foobar", ParsedReaderResultType.URI);
} }
private static void doTestResult(String text, ParsedReaderResultType type) { private static void doTestResult(String text, ParsedReaderResultType type) {

View file

@ -42,19 +42,19 @@ public abstract class AbstractBlackBoxTestCase extends TestCase {
String lowerCase = name.toLowerCase(); String lowerCase = name.toLowerCase();
return return
lowerCase.endsWith(".jpg") || lowerCase.endsWith(".jpeg") || lowerCase.endsWith(".jpg") || lowerCase.endsWith(".jpeg") ||
lowerCase.endsWith(".gif") || lowerCase.endsWith(".png") || lowerCase.endsWith(".gif") || lowerCase.endsWith(".png") ||
lowerCase.endsWith(".url"); lowerCase.endsWith(".url");
} }
}; };
private final File testBase; private final File testBase;
private final Reader barcodeReader; private final Reader barcodeReader;
private final double passPercent; private final double passPercent;
protected AbstractBlackBoxTestCase(File testBase, Reader barcodeReader, double passPercent) { protected AbstractBlackBoxTestCase(File testBase, Reader barcodeReader, double passPercent) {
this.testBase = testBase; this.testBase = testBase;
this.barcodeReader = barcodeReader; this.barcodeReader = barcodeReader;
this.passPercent = passPercent; this.passPercent = passPercent;
} }
public void testBlackBox() throws IOException { public void testBlackBox() throws IOException {
@ -66,13 +66,13 @@ public abstract class AbstractBlackBoxTestCase extends TestCase {
for (File testImage : imageFiles) { for (File testImage : imageFiles) {
System.out.println("Starting " + testImage.getAbsolutePath()); System.out.println("Starting " + testImage.getAbsolutePath());
BufferedImage image; BufferedImage image;
if (testImage.getName().endsWith(".url")) { if (testImage.getName().endsWith(".url")) {
String urlString = readFileAsString(testImage); String urlString = readFileAsString(testImage);
image = ImageIO.read(new URL(urlString)); image = ImageIO.read(new URL(urlString));
} else { } else {
image = ImageIO.read(testImage); image = ImageIO.read(testImage);
} }
MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image); MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(image);
Result result; Result result;
try { try {

View file

@ -38,8 +38,8 @@ public final class CollectionsTestCase extends TestCase {
} }
}); });
for (int i = 1; i < 100; i++) { for (int i = 1; i < 100; i++) {
assertTrue("Element " + i, ((Integer) v.elementAt(i-1)).intValue() <= assertTrue("Element " + i, ((Integer) v.elementAt(i - 1)).intValue() <=
((Integer) v.elementAt(i)).intValue()); ((Integer) v.elementAt(i)).intValue());
} }
} }

View file

@ -16,8 +16,8 @@
package com.google.zxing.oned; package com.google.zxing.oned;
import com.google.zxing.common.AbstractBlackBoxTestCase;
import com.google.zxing.MultiFormatReader; import com.google.zxing.MultiFormatReader;
import com.google.zxing.common.AbstractBlackBoxTestCase;
import java.io.File; import java.io.File;

View file

@ -24,7 +24,7 @@ import junit.framework.TestCase;
public final class BitSourceTestCase extends TestCase { public final class BitSourceTestCase extends TestCase {
public void testSource() { public void testSource() {
byte[] bytes = new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 }; byte[] bytes = new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5};
BitSource source = new BitSource(bytes); BitSource source = new BitSource(bytes);
assertEquals(40, source.available()); assertEquals(40, source.available());
assertEquals(0, source.readBits(1)); assertEquals(0, source.readBits(1));

View file

@ -59,7 +59,7 @@ public final class DataMaskTestCase extends TestCase {
public void testMask4() { public void testMask4() {
testMaskAcrossDimensions(4, new MaskCondition() { testMaskAcrossDimensions(4, new MaskCondition() {
public boolean isMasked(int i, int j) { public boolean isMasked(int i, int j) {
return (i/2 + j/3) % 2 == 0; return (i / 2 + j / 3) % 2 == 0;
} }
}); });
} }
@ -67,7 +67,7 @@ public final class DataMaskTestCase extends TestCase {
public void testMask5() { public void testMask5() {
testMaskAcrossDimensions(5, new MaskCondition() { testMaskAcrossDimensions(5, new MaskCondition() {
public boolean isMasked(int i, int j) { public boolean isMasked(int i, int j) {
return (i*j) % 2 + (i*j) % 3 == 0; return (i * j) % 2 + (i * j) % 3 == 0;
} }
}); });
} }
@ -75,7 +75,7 @@ public final class DataMaskTestCase extends TestCase {
public void testMask6() { public void testMask6() {
testMaskAcrossDimensions(6, new MaskCondition() { testMaskAcrossDimensions(6, new MaskCondition() {
public boolean isMasked(int i, int j) { public boolean isMasked(int i, int j) {
return ((i*j) % 2 + (i*j) % 3) % 2 == 0; return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
} }
}); });
} }
@ -83,7 +83,7 @@ public final class DataMaskTestCase extends TestCase {
public void testMask7() { public void testMask7() {
testMaskAcrossDimensions(7, new MaskCondition() { testMaskAcrossDimensions(7, new MaskCondition() {
public boolean isMasked(int i, int j) { public boolean isMasked(int i, int j) {
return ((i+j) % 2 + (i*j) % 3) % 2 == 0; return ((i + j) % 2 + (i * j) % 3) % 2 == 0;
} }
}); });
} }
@ -92,7 +92,7 @@ public final class DataMaskTestCase extends TestCase {
MaskCondition condition) { MaskCondition condition) {
DataMask mask = DataMask.forReference(reference); DataMask mask = DataMask.forReference(reference);
for (int version = 1; version <= 40; version++) { for (int version = 1; version <= 40; version++) {
int dimension = 17 + 4*version; int dimension = 17 + 4 * version;
testMask(mask, dimension, condition); testMask(mask, dimension, condition);
} }
} }
@ -103,7 +103,7 @@ public final class DataMaskTestCase extends TestCase {
for (int i = 0; i < dimension; i++) { for (int i = 0; i < dimension; i++) {
for (int j = 0; j < dimension; j++) { for (int j = 0; j < dimension; j++) {
assertEquals( assertEquals(
"(" + i + ',' + j + ')', "(" + i + ',' + j + ')',
condition.isMasked(i, j), condition.isMasked(i, j),
bits.get(i, j)); bits.get(i, j));
} }

View file

@ -27,7 +27,7 @@ public final class FormatInformationTestCase extends TestCase {
assertEquals(0, FormatInformation.numBitsDiffering(1, 1)); assertEquals(0, FormatInformation.numBitsDiffering(1, 1));
assertEquals(1, FormatInformation.numBitsDiffering(0, 2)); assertEquals(1, FormatInformation.numBitsDiffering(0, 2));
assertEquals(2, FormatInformation.numBitsDiffering(1, 2)); assertEquals(2, FormatInformation.numBitsDiffering(1, 2));
assertEquals(32, FormatInformation.numBitsDiffering(-1,0)); assertEquals(32, FormatInformation.numBitsDiffering(-1, 0));
} }
public void testDecode() { public void testDecode() {

View file

@ -45,11 +45,11 @@ public final class PerspectiveTransformTestCase extends TestCase {
assertPointEquals(290.0f, 270.0f, 16.0f, 15.0f, pt); assertPointEquals(290.0f, 270.0f, 16.0f, 15.0f, pt);
assertPointEquals(150.0f, 280.0f, 4.0f, 9.0f, pt); assertPointEquals(150.0f, 280.0f, 4.0f, 9.0f, pt);
assertPointEquals(7.1516876f, -64.60185f, 0.5f, 0.5f, pt); assertPointEquals(7.1516876f, -64.60185f, 0.5f, 0.5f, pt);
assertPointEquals(328.09116f, 334.16385f,50.0f, 50.0f, pt); assertPointEquals(328.09116f, 334.16385f, 50.0f, 50.0f, pt);
} }
private static void assertPointEquals(float expectedX, float expectedY, float sourceX, float sourceY, PerspectiveTransform pt) { private static void assertPointEquals(float expectedX, float expectedY, float sourceX, float sourceY, PerspectiveTransform pt) {
float[] points = new float[] { sourceX, sourceY }; float[] points = new float[]{sourceX, sourceY};
pt.transformPoints(points); pt.transformPoints(points);
assertEquals(expectedX, points[0], EPSILON); assertEquals(expectedX, points[0], EPSILON);
assertEquals(expectedY, points[1], EPSILON); assertEquals(expectedY, points[1], EPSILON);

View file

@ -56,7 +56,7 @@
</not> </not>
</condition> </condition>
</fail> </fail>
<fail message="Please build 'core' first"> <fail message="Please build 'core' first">
<condition> <condition>
<not> <not>
<available file="../core/core.jar" type="file"/> <available file="../core/core.jar" type="file"/>
@ -93,7 +93,7 @@
debug="true" debug="true"
deprecation="true" deprecation="true"
fork="true"> fork="true">
<classpath refid="wtk-build-path"/> <classpath refid="wtk-build-path"/>
</javac> </javac>
<javac srcdir="src" <javac srcdir="src"
destdir="build" destdir="build"
@ -123,14 +123,16 @@
</fileset> </fileset>
</copy> </copy>
<copy file="src/com/google/zxing/client/j2me/MANIFEST.MF.template" tofile="src/com/google/zxing/client/j2me/MANIFEST.MF" overwrite="true"> <copy file="src/com/google/zxing/client/j2me/MANIFEST.MF.template"
tofile="src/com/google/zxing/client/j2me/MANIFEST.MF" overwrite="true">
<filterset> <filterset>
<filter token="APP_NAME" value="${jar-name}"/> <filter token="APP_NAME" value="${jar-name}"/>
<filter token="VERSION" value="${version}"/> <filter token="VERSION" value="${version}"/>
</filterset> </filterset>
</copy> </copy>
<jar jarfile="${jar-name}.jar" basedir="build-j2me" manifest="src/com/google/zxing/client/j2me/MANIFEST.MF" level="9"/> <jar jarfile="${jar-name}.jar" basedir="build-j2me" manifest="src/com/google/zxing/client/j2me/MANIFEST.MF"
level="9"/>
<move file="${jar-name}.jar" tofile="temp.jar"/> <move file="${jar-name}.jar" tofile="temp.jar"/>
<java jar="${WTK-home}/bin/proguard.jar" fork="true" failonerror="true"> <java jar="${WTK-home}/bin/proguard.jar" fork="true" failonerror="true">

View file

@ -30,7 +30,7 @@ import javax.microedition.media.MediaException;
* JSR-234 methods. The other does nothing. The build script creates two build products then * JSR-234 methods. The other does nothing. The build script creates two build products then
* one compiled with this class and one with other, to create both the JSR-234 version * one compiled with this class and one with other, to create both the JSR-234 version
* and the "basic" non-JSR-234 version.</p> * and the "basic" non-JSR-234 version.</p>
* *
* @author Sean Owen (srowen@google.com) * @author Sean Owen (srowen@google.com)
*/ */
final class AdvancedMultimediaManager { final class AdvancedMultimediaManager {
@ -45,7 +45,7 @@ final class AdvancedMultimediaManager {
static void setFocus(Controllable player) throws MediaException, InterruptedException { static void setFocus(Controllable player) throws MediaException, InterruptedException {
FocusControl focusControl = (FocusControl) FocusControl focusControl = (FocusControl)
player.getControl("javax.microedition.amms.control.camera.FocusControl"); player.getControl("javax.microedition.amms.control.camera.FocusControl");
if (focusControl != null) { if (focusControl != null) {
if (focusControl.isMacroSupported() && !focusControl.getMacro()) { if (focusControl.isMacroSupported() && !focusControl.getMacro()) {
focusControl.setMacro(true); focusControl.setMacro(true);

View file

@ -16,8 +16,8 @@
package com.google.zxing.client.j2me; package com.google.zxing.client.j2me;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.BlackPointEstimationMethod; import com.google.zxing.BlackPointEstimationMethod;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.BlackPointEstimator; import com.google.zxing.common.BlackPointEstimator;
@ -25,7 +25,7 @@ import javax.microedition.lcdui.Image;
/** /**
* <p>An implementation based on Java ME's {@link Image} representation.</p> * <p>An implementation based on Java ME's {@link Image} representation.</p>
* *
* @author Sean Owen (srowen@google.com), Daniel Switkin (dswitkin@google.com) * @author Sean Owen (srowen@google.com), Daniel Switkin (dswitkin@google.com)
*/ */
public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapSource { public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapSource {
@ -36,7 +36,7 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
private int blackPoint; private int blackPoint;
private BlackPointEstimationMethod lastMethod; private BlackPointEstimationMethod lastMethod;
private int lastArgument; private int lastArgument;
private static final int LUMINANCE_BITS = 5; private static final int LUMINANCE_BITS = 5;
private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
@ -80,7 +80,7 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) { public void estimateBlackPoint(BlackPointEstimationMethod method, int argument) {
if (!method.equals(lastMethod) || argument != lastArgument) { if (!method.equals(lastMethod) || argument != lastArgument) {
int[] histogram = new int[LUMINANCE_BUCKETS]; int[] histogram = new int[LUMINANCE_BUCKETS];
float biasTowardsWhite = 1.0f; float biasTowardsWhite = 1.0f;
if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) { if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) {
int minDimension = width < height ? width : height; int minDimension = width < height ? width : height;
for (int n = 0, offset = 0; n < minDimension; n++, offset += width + 1) { for (int n = 0, offset = 0; n < minDimension; n++, offset += width + 1) {
@ -90,7 +90,7 @@ public final class LCDUIImageMonochromeBitmapSource implements MonochromeBitmapS
if (argument < 0 || argument >= height) { if (argument < 0 || argument >= height) {
throw new IllegalArgumentException("Row is not within the image: " + argument); throw new IllegalArgumentException("Row is not within the image: " + argument);
} }
biasTowardsWhite = 2.0f; biasTowardsWhite = 2.0f;
int offset = argument * width; int offset = argument * width;
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
histogram[computeRGBLuminance(rgbPixels[offset + x]) >> LUMINANCE_SHIFT]++; histogram[computeRGBLuminance(rgbPixels[offset + x]) >> LUMINANCE_SHIFT]++;

View file

@ -51,49 +51,49 @@ final class SnapshotThread extends Thread {
Player player = zXingMIDlet.getPlayer(); Player player = zXingMIDlet.getPlayer();
try { try {
AdvancedMultimediaManager.setFocus(player); AdvancedMultimediaManager.setFocus(player);
try { try {
player.stop(); player.stop();
} catch (MediaException me) { } catch (MediaException me) {
// continue // continue
} }
byte[] snapshot = takeSnapshot(); byte[] snapshot = takeSnapshot();
Image capturedImage = Image.createImage(snapshot, 0, snapshot.length); Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage); MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);
Reader reader = new MultiFormatReader(); Reader reader = new MultiFormatReader();
Result result = reader.decode(source); Result result = reader.decode(source);
zXingMIDlet.handleDecodedText(result.getText()); zXingMIDlet.handleDecodedText(result.getText());
} catch (ReaderException re) { } catch (ReaderException re) {
// Show a friendlier message on a mere failure to read the barcode // Show a friendlier message on a mere failure to read the barcode
zXingMIDlet.showError("Sorry, no barcode was found."); zXingMIDlet.showError("Sorry, no barcode was found.");
} catch (Throwable t) { } catch (Throwable t) {
zXingMIDlet.showError(t); zXingMIDlet.showError(t);
} finally { } finally {
try { try {
player.start(); player.start();
} catch (MediaException me) { } catch (MediaException me) {
// continue // continue
} }
currentThread = null; currentThread = null;
} }
} }
private byte[] takeSnapshot() throws MediaException { private byte[] takeSnapshot() throws MediaException {
VideoControl videoControl = zXingMIDlet.getVideoControl(); VideoControl videoControl = zXingMIDlet.getVideoControl();
byte[] snapshot = null; byte[] snapshot = null;
try { try {
snapshot = videoControl.getSnapshot(null); snapshot = videoControl.getSnapshot(null);
} catch (MediaException me) { } catch (MediaException me) {
} }
if (snapshot == null) { if (snapshot == null) {
// Fall back on JPEG; seems that some cameras default to PNG even // Fall back on JPEG; seems that some cameras default to PNG even
// when PNG isn't supported! // when PNG isn't supported!
snapshot = videoControl.getSnapshot("encoding=jpeg"); snapshot = videoControl.getSnapshot("encoding=jpeg");
if (snapshot == null) { if (snapshot == null) {
throw new MediaException("Can't obtain a snapshot"); throw new MediaException("Can't obtain a snapshot");
} }
} }
return snapshot; return snapshot;
} }
} }

View file

@ -80,25 +80,25 @@ public final class ZXingMIDlet extends MIDlet {
} }
} }
private static Player createPlayer() throws IOException, MediaException { private static Player createPlayer() throws IOException, MediaException {
// Try a workaround for Nokias, which want to use capture://image in some cases // Try a workaround for Nokias, which want to use capture://image in some cases
Player player = null; Player player = null;
String platform = System.getProperty("microedition.platform"); String platform = System.getProperty("microedition.platform");
if (platform != null && platform.indexOf("Nokia") >= 0) { if (platform != null && platform.indexOf("Nokia") >= 0) {
try { try {
player = Manager.createPlayer("capture://image"); player = Manager.createPlayer("capture://image");
} catch (MediaException me) { } catch (MediaException me) {
// if this fails, just continue with capture://video // if this fails, just continue with capture://video
} catch (Error e) { } catch (Error e) {
// Ugly, but, it seems the Nokia N70 throws "java.lang.Error: 136" here // Ugly, but, it seems the Nokia N70 throws "java.lang.Error: 136" here
// We should still try to continue // We should still try to continue
} }
} }
if (player == null) { if (player == null) {
player = Manager.createPlayer("capture://video"); player = Manager.createPlayer("capture://video");
} }
return player; return player;
} }
protected void pauseApp() { protected void pauseApp() {
if (player != null) { if (player != null) {
@ -106,14 +106,14 @@ public final class ZXingMIDlet extends MIDlet {
player.stop(); player.stop();
} catch (MediaException me) { } catch (MediaException me) {
// continue? // continue?
showError(me); showError(me);
} }
} }
} }
protected void destroyApp(boolean unconditional) { protected void destroyApp(boolean unconditional) {
if (player != null) { if (player != null) {
videoControl = null; videoControl = null;
try { try {
player.stop(); player.stop();
} catch (MediaException me) { } catch (MediaException me) {
@ -135,7 +135,7 @@ public final class ZXingMIDlet extends MIDlet {
private void showOpenURL(String title, final String display, final String uri) { private void showOpenURL(String title, final String display, final String uri) {
Alert alert = new Alert(title, display, null, AlertType.CONFIRMATION); Alert alert = new Alert(title, display, null, AlertType.CONFIRMATION);
alert.setTimeout(Alert.FOREVER); alert.setTimeout(Alert.FOREVER);
Command yes = new Command("Yes", Command.OK, 1); Command yes = new Command("Yes", Command.OK, 1);
alert.addCommand(yes); alert.addCommand(yes);
Command no = new Command("No", Command.CANCEL, 1); Command no = new Command("No", Command.CANCEL, 1);
alert.addCommand(no); alert.addCommand(no);
@ -174,9 +174,9 @@ public final class ZXingMIDlet extends MIDlet {
} }
} }
void showError(String message) { void showError(String message) {
showAlert(new Alert("Error", message, null, AlertType.ERROR)); showAlert(new Alert("Error", message, null, AlertType.ERROR));
} }
private void showAlert(Alert alert) { private void showAlert(Alert alert) {
Display display = Display.getDisplay(this); Display display = Display.getDisplay(this);
@ -199,9 +199,9 @@ public final class ZXingMIDlet extends MIDlet {
String email = ((EmailAddressResult) result).getEmailAddress(); String email = ((EmailAddressResult) result).getEmailAddress();
showOpenURL("Compose E-mail?", email, "mailto:" + email); showOpenURL("Compose E-mail?", email, "mailto:" + email);
} else if (type.equals(ParsedReaderResultType.UPC)) { } else if (type.equals(ParsedReaderResultType.UPC)) {
String upc = ((UPCParsedResult) result).getUPC(); String upc = ((UPCParsedResult) result).getUPC();
String uri = "http://www.upcdatabase.com/item.asp?upc=" + upc; String uri = "http://www.upcdatabase.com/item.asp?upc=" + upc;
showOpenURL("Look Up Barcode Online?", upc, uri); showOpenURL("Look Up Barcode Online?", upc, uri);
} else { } else {
showAlert("Barcode Detected", result.getDisplayResult()); showAlert("Barcode Detected", result.getDisplayResult());
} }

View file

@ -20,7 +20,7 @@
<target name="init"> <target name="init">
<tstamp/> <tstamp/>
<fail message="Please build 'core' first"> <fail message="Please build 'core' first">
<condition> <condition>
<not> <not>
<available file="../core/core.jar" type="file"/> <available file="../core/core.jar" type="file"/>

View file

@ -16,8 +16,8 @@
package com.google.zxing.client.j2se; package com.google.zxing.client.j2se;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.BlackPointEstimationMethod; import com.google.zxing.BlackPointEstimationMethod;
import com.google.zxing.MonochromeBitmapSource;
import com.google.zxing.common.BitArray; import com.google.zxing.common.BitArray;
import com.google.zxing.common.BlackPointEstimator; import com.google.zxing.common.BlackPointEstimator;
@ -27,7 +27,7 @@ import java.awt.image.BufferedImage;
* <p>An implementation based upon {@link BufferedImage}. This provides access to the * <p>An implementation based upon {@link BufferedImage}. This provides access to the
* underlying image as if it were a monochrome image. Behind the scenes, it is evaluating * underlying image as if it were a monochrome image. Behind the scenes, it is evaluating
* the luminance of the underlying image by retrieving its pixels' RGB values.</p> * the luminance of the underlying image by retrieving its pixels' RGB values.</p>
* *
* @author srowen@google.com (Sean Owen), Daniel Switkin (dswitkin@google.com) * @author srowen@google.com (Sean Owen), Daniel Switkin (dswitkin@google.com)
*/ */
public final class BufferedImageMonochromeBitmapSource implements MonochromeBitmapSource { public final class BufferedImageMonochromeBitmapSource implements MonochromeBitmapSource {
@ -36,7 +36,7 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
private int blackPoint; private int blackPoint;
private BlackPointEstimationMethod lastMethod; private BlackPointEstimationMethod lastMethod;
private int lastArgument; private int lastArgument;
private static final int LUMINANCE_BITS = 5; private static final int LUMINANCE_BITS = 5;
private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS; private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS; private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
@ -80,7 +80,7 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
int width = image.getWidth(); int width = image.getWidth();
int height = image.getHeight(); int height = image.getHeight();
int[] histogram = new int[LUMINANCE_BUCKETS]; int[] histogram = new int[LUMINANCE_BUCKETS];
float biasTowardsWhite = 1.0f; float biasTowardsWhite = 1.0f;
if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) { if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) {
int minDimension = width < height ? width : height; int minDimension = width < height ? width : height;
int startI = height == minDimension ? 0 : (height - width) >> 1; int startI = height == minDimension ? 0 : (height - width) >> 1;
@ -93,7 +93,7 @@ public final class BufferedImageMonochromeBitmapSource implements MonochromeBitm
if (argument < 0 || argument >= height) { if (argument < 0 || argument >= height) {
throw new IllegalArgumentException("Row is not within the image: " + argument); throw new IllegalArgumentException("Row is not within the image: " + argument);
} }
biasTowardsWhite = 2.0f; biasTowardsWhite = 2.0f;
int[] rgbArray = new int[width]; int[] rgbArray = new int[width];
image.getRGB(0, argument, width, 1, rgbArray, 0, width); image.getRGB(0, argument, width, 1, rgbArray, 0, width);
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {

View file

@ -27,7 +27,7 @@ import java.net.URI;
/** /**
* Utility application for evaluating the effectiveness of the * Utility application for evaluating the effectiveness of the
* MonochromeBitmapSource. Given a set of images on the command line, * MonochromeBitmapSource. Given a set of images on the command line,
* converts each to a black-and-white GIF. The result is placed in * converts each to a black-and-white GIF. The result is placed in
* a file based on the input name, with "_converted" appended. * a file based on the input name, with "_converted" appended.
* *
* @author alasdair@google.com (Alasdair Mackintosh) * @author alasdair@google.com (Alasdair Mackintosh)
@ -65,11 +65,11 @@ public final class ImageConverter {
MonochromeBitmapSource src = new BufferedImageMonochromeBitmapSource(image); MonochromeBitmapSource src = new BufferedImageMonochromeBitmapSource(image);
int width = src.getWidth(); int width = src.getWidth();
int height = src.getHeight(); int height = src.getHeight();
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
for (int i = 0; i < width; i++) { for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++) {
result.setRGB(i, j, src.isBlack(i,j) ? BLACK : WHITE); result.setRGB(i, j, src.isBlack(i, j) ? BLACK : WHITE);
} }
} }
@ -82,9 +82,9 @@ public final class ImageConverter {
String name = uri.getPath(); String name = uri.getPath();
int slashPos = name.lastIndexOf((int) '/'); int slashPos = name.lastIndexOf((int) '/');
String parent, basename; String parent, basename;
if (slashPos != -1 && slashPos != name.length()-1) { if (slashPos != -1 && slashPos != name.length() - 1) {
parent = name.substring(0, slashPos); parent = name.substring(0, slashPos);
basename = name.substring(slashPos+1); basename = name.substring(slashPos + 1);
} else { } else {
parent = "."; parent = ".";
basename = name; basename = name;
@ -94,7 +94,7 @@ public final class ImageConverter {
return null; return null;
} }
File baseFile = new File(parent,basename); File baseFile = new File(parent, basename);
if (!baseFile.exists()) { if (!baseFile.exists()) {
return null; return null;
} }

View file

@ -29,7 +29,7 @@
</not> </not>
</condition> </condition>
</fail> </fail>
<fail message="Please build target 'build-basic' in 'javame' first"> <fail message="Please build target 'build-basic' in 'javame' first">
<condition> <condition>
<not> <not>
<available file="../javame/ZXingReaderBasic.jar" type="file"/> <available file="../javame/ZXingReaderBasic.jar" type="file"/>