diff --git a/bug/build.xml b/bug/build.xml
new file mode 100644
index 000000000..417a98aff
--- /dev/null
+++ b/bug/build.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
An implementation based on AWT's {@link Image} representation. + * This can be used on CDC devices or other devices that do not have access to the + * Mobile Information Device Profile and thus do not have access to + * javax.microedition.lcdui.Image.
+ * + * @author David Albert + * @author Sean Owen + */ +public final class AWTImageMonochromeBitmapSource extends BaseMonochromeBitmapSource { + + private final int height; + private final int width; + private final int[] pixels; + + public AWTImageMonochromeBitmapSource(Image image) throws ReaderException { + height = image.getHeight(null); + width = image.getWidth(null); + pixels = new int[height * width]; + // Seems best in this situation to grab all pixels upfront. Grabbing any individual pixel + // entails creating a relatively expensive object and calling through several methods. + PixelGrabber grabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width); + try { + grabber.grabPixels(); + } catch (InterruptedException ie) { + throw new ReaderException("Interrupted while reading pixels"); + } + } + + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } + + /** + * Seecom.google.zxing.client.j2me.LCDUIImageMonochromeBitmapSource
for more explanation
+ * of the computation used in this method.
+ */
+ public int getLuminance(int x, int y) {
+ int pixel = pixels[x * width + y];
+ return (((pixel & 0x00FF0000) >> 16) +
+ ((pixel & 0x0000FF00) >> 7) +
+ (pixel & 0x000000FF )) >> 2;
+ }
+
+ public void cacheRowForLuminance(int y) {
+ // do nothing; we are already forced to cache all pixels
+ }
+
+}
diff --git a/bug/src/com/google/zxing/client/bug/Activator.java b/bug/src/com/google/zxing/client/bug/Activator.java
new file mode 100644
index 000000000..7d262c10f
--- /dev/null
+++ b/bug/src/com/google/zxing/client/bug/Activator.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.bug;
+
+import com.buglabs.util.ServiceFilterGenerator;
+import com.google.zxing.client.bug.servicetracker.BugBarcodeServiceTracker;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * BundleActivator for BugBarcode.
+ *
+ * @author David Albert
+ */
+public final class Activator implements BundleActivator {
+
+ private BugBarcodeServiceTracker barcodeServiceTracker;
+ private ServiceTracker serviceTracker;
+
+ public void start(BundleContext context) throws InvalidSyntaxException {
+ barcodeServiceTracker = new BugBarcodeServiceTracker(context);
+ Filter filter =
+ context.createFilter(ServiceFilterGenerator.generateServiceFilter(barcodeServiceTracker.getServices()));
+ serviceTracker = new ServiceTracker(context, filter, barcodeServiceTracker);
+ serviceTracker.open();
+ }
+
+ public void stop(BundleContext context) {
+ barcodeServiceTracker.stop();
+ serviceTracker.close();
+ }
+}
diff --git a/bug/src/com/google/zxing/client/bug/ImageCanvas.java b/bug/src/com/google/zxing/client/bug/ImageCanvas.java
new file mode 100644
index 000000000..23e410a4c
--- /dev/null
+++ b/bug/src/com/google/zxing/client/bug/ImageCanvas.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.bug;
+
+import java.awt.Canvas;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+
+/**
+ * @author John Connolly
+ */
+public final class ImageCanvas extends Canvas {
+
+ private Image image;
+
+ public ImageCanvas(Image image) {
+ this.image = image;
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ g.drawImage(image, 0, 0, this);
+ }
+
+ @Override
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ @Override
+ public Dimension getMinimumSize() {
+ return getPreferredSize();
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ int width;
+ do {
+ width = image.getWidth(this);
+ } while (width < 0);
+
+ int height;
+ do {
+ height = image.getHeight(this);
+ } while (height < 0);
+
+ return new Dimension(width, height);
+ }
+
+ public Image getImage() {
+ return image;
+ }
+
+ public void setImage(Image image) {
+ this.image = image;
+ }
+
+}
diff --git a/bug/src/com/google/zxing/client/bug/app/BugBarcodeApp.java b/bug/src/com/google/zxing/client/bug/app/BugBarcodeApp.java
new file mode 100644
index 000000000..d017211a7
--- /dev/null
+++ b/bug/src/com/google/zxing/client/bug/app/BugBarcodeApp.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.bug.app;
+
+import com.buglabs.bug.module.camera.pub.ICameraDevice;
+import com.buglabs.bug.module.camera.pub.ICameraModuleControl;
+import com.buglabs.device.ButtonEvent;
+import com.buglabs.device.IButtonEventListener;
+import com.buglabs.device.IButtonEventProvider;
+import com.google.zxing.MonochromeBitmapSource;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.Reader;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.client.bug.AWTImageMonochromeBitmapSource;
+import com.google.zxing.client.bug.ImageCanvas;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Frame;
+import java.awt.Image;
+import java.awt.Label;
+import java.awt.Toolkit;
+import java.awt.image.ImageObserver;
+import java.io.IOException;
+
+/**
+ * @author David Albert
+ */
+public final class BugBarcodeApp implements IButtonEventListener, ImageObserver {
+
+ private ICameraDevice camera;
+ private ICameraModuleControl cameraControl;
+ private Frame frame;
+ private Image image;
+ private ImageCanvas imageCanvas;
+ private Label barcodeLabel;
+ private boolean pictureTaken;
+ private final Reader reader;
+
+ public BugBarcodeApp(Frame frame,
+ ICameraDevice camera,
+ ICameraModuleControl cameraControl,
+ IButtonEventProvider buttonProvider) {
+ this.frame = frame;
+ this.camera = camera;
+ this.reader = new MultiFormatReader();
+ this.cameraControl = cameraControl;
+ pictureTaken = false;
+ buttonProvider.addListener(this);
+ createUI();
+ }
+
+ private void createUI() {
+ frame.setTitle("BugBarcode");
+ frame.setBackground(Color.WHITE);
+ frame.setLayout(new BorderLayout());
+ barcodeLabel = new Label("Take a picture of a barcode!", Label.CENTER);
+ frame.add(barcodeLabel, BorderLayout.SOUTH);
+ imageCanvas = new ImageCanvas(null);
+ frame.setVisible(true);
+ }
+
+ private void shoot() throws IOException {
+ // get image from camera for use with physical bug
+ cameraControl.setLEDFlash(true);
+ image = Toolkit.getDefaultToolkit().createImage(camera.getImage()).getScaledInstance(400, 300, Image.SCALE_FAST);
+ cameraControl.setLEDFlash(false);
+ if (Toolkit.getDefaultToolkit().prepareImage(image, -1, -1, this)) {
+ drawAndScan();
+ }
+ }
+
+ private void drawAndScan() {
+ imageCanvas.setImage(image.getScaledInstance(216, 150, Image.SCALE_FAST));
+ if (!pictureTaken) {
+ frame.add(imageCanvas, BorderLayout.CENTER);
+ pictureTaken = true;
+ frame.setVisible(true);
+ }
+ imageCanvas.repaint();
+ try {
+ MonochromeBitmapSource source = new AWTImageMonochromeBitmapSource(image);
+ Result result = reader.decode(source);
+ barcodeLabel.setText(result.getText());
+ } catch (ReaderException re) {
+ barcodeLabel.setText("I can't find a barcode here");
+ }
+ }
+
+ public void buttonEvent(ButtonEvent event) {
+ if (event.getButton() == ButtonEvent.BUTTON_HOTKEY_1 && event.getAction() == 0) {
+ try {
+ shoot();
+ } catch (IOException ioe) {
+ // continue
+ }
+ }
+ }
+
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+ if ((infoflags & ALLBITS) != 0) {
+ drawAndScan();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/bug/src/com/google/zxing/client/bug/servicetracker/BugBarcodeServiceTracker.java b/bug/src/com/google/zxing/client/bug/servicetracker/BugBarcodeServiceTracker.java
new file mode 100644
index 000000000..2ec286878
--- /dev/null
+++ b/bug/src/com/google/zxing/client/bug/servicetracker/BugBarcodeServiceTracker.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.client.bug.servicetracker;
+
+import com.buglabs.application.AbstractServiceTracker;
+import com.buglabs.bug.module.camera.pub.ICameraDevice;
+import com.buglabs.bug.module.camera.pub.ICameraModuleControl;
+import com.buglabs.bug.module.lcd.pub.IModuleDisplay;
+import com.buglabs.device.IButtonEventProvider;
+import com.google.zxing.client.bug.app.BugBarcodeApp;
+import org.osgi.framework.BundleContext;
+
+import java.awt.Frame;
+import java.util.Collection;
+
+/**
+ * Service tracker for the BugApp Bundle
+ *
+ * @author David Albert
+ */
+public final class BugBarcodeServiceTracker extends AbstractServiceTracker {
+
+ private IButtonEventProvider buttonEventProvider;
+ private Frame frame;
+ private BugBarcodeApp app;
+
+ public BugBarcodeServiceTracker(BundleContext context) {
+ super(context);
+ }
+
+ @Override
+ public void doStart() {
+ IModuleDisplay display = (IModuleDisplay) getService(IModuleDisplay.class);
+ ICameraDevice camera = (ICameraDevice) getService(ICameraDevice.class);
+ ICameraModuleControl cameraControl = (ICameraModuleControl) getService(ICameraModuleControl.class);
+ buttonEventProvider = (IButtonEventProvider) getService(IButtonEventProvider.class);
+ frame = display.getFrame();
+ app = new BugBarcodeApp(frame, camera, cameraControl, buttonEventProvider);
+ }
+
+ /**
+ * Called when a service that this application depends is unregistered.
+ */
+ @Override
+ public void doStop() {
+ buttonEventProvider.removeListener(app);
+ frame.dispose();
+ }
+
+ /**
+ * Allows the user to set the service dependencies by
+ * adding them to services list returned by getServices().
+ * i.e.nl getServices().add(MyService.class.getName());
+ */
+ @Override
+ public void initServices() {
+ Collection