Implemented Paul's solution to the basic/regular build problem -- a sort of pseudo...
[zxing.git] / javame / src / com / google / zxing / client / j2me / SnapshotThread.java
index a4aa526..b6c3e39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2007 ZXing authors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,53 +25,87 @@ import com.google.zxing.Result;
 import javax.microedition.lcdui.Image;
 import javax.microedition.media.MediaException;
 import javax.microedition.media.Player;
+import javax.microedition.media.control.VideoControl;
 
 /**
+ * Thread which does the work of capturing a frame and decoding it.
+ *
  * @author Sean Owen (srowen@google.com)
  */
-final class SnapshotThread extends Thread {
-
-  private static SnapshotThread currentThread;
+final class SnapshotThread implements Runnable {
 
   private final ZXingMIDlet zXingMIDlet;
+  private final Object waitLock;
+  private boolean done;
+  private final MultimediaManager multimediaManager;
 
   SnapshotThread(ZXingMIDlet zXingMIDlet) {
     this.zXingMIDlet = zXingMIDlet;
+    waitLock = new Object();
+    done = false;
+    multimediaManager = new DefaultMultimediaManager();
+  }
+
+  void continueRun() {
+    synchronized (waitLock) {
+      waitLock.notifyAll();
+    }
   }
 
-  static synchronized void startThread(ZXingMIDlet zXingMIDlet) {
-    if (currentThread == null) {
-      currentThread = new SnapshotThread(zXingMIDlet);
-      currentThread.start();
+  private void waitForSignal() {
+    synchronized (waitLock) {
+      try {
+        waitLock.wait();
+      } catch (InterruptedException ie) {
+        // continue
+      }
     }
   }
 
+  void stop() {
+    done = true;
+    continueRun();
+  }
+
   public void run() {
     Player player = zXingMIDlet.getPlayer();
-    try {
-      AdvancedMultimediaManager.setFocus(player);
-      player.stop();
-      byte[] snapshot = zXingMIDlet.getVideoControl().getSnapshot(null);
-      Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
-      MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);
-      Reader reader = new MultiFormatReader();
-      Result result = reader.decode(source);
-      zXingMIDlet.handleDecodedText(result.getText());
-    } catch (ReaderException re) {
-           // Show a friendlier message on a mere failure to read the barcode
-           zXingMIDlet.showError("No barcode was detected in this image. Try again.");
-    } catch (Throwable t) {
-      zXingMIDlet.showError(t);
-    } finally {
+    do {
+      waitForSignal();
       try {
-        player.start();
+        multimediaManager.setFocus(player);
+        byte[] snapshot = takeSnapshot();
+        Image capturedImage = Image.createImage(snapshot, 0, snapshot.length);
+        MonochromeBitmapSource source = new LCDUIImageMonochromeBitmapSource(capturedImage);
+        Reader reader = new MultiFormatReader();
+        Result result = reader.decode(source);
+        zXingMIDlet.handleDecodedText(result);
+      } catch (ReaderException re) {
+        // Show a friendlier message on a mere failure to read the barcode
+        zXingMIDlet.showError("Sorry, no barcode was found.");
       } catch (MediaException me) {
-        // continue?
         zXingMIDlet.showError(me);
+      } catch (RuntimeException re) {
+        zXingMIDlet.showError(re);
       }
-      currentThread = null;
-    }
+    } while (!done);
+  }
 
+  private byte[] takeSnapshot() throws MediaException {
+    VideoControl videoControl = zXingMIDlet.getVideoControl();
+    byte[] snapshot = null;
+    try {
+      snapshot = videoControl.getSnapshot(null);
+    } catch (MediaException me) {
+    }
+    if (snapshot == null) {
+      // Fall back on JPEG; seems that some cameras default to PNG even
+      // when PNG isn't supported!
+      snapshot = videoControl.getSnapshot("encoding=jpeg");
+      if (snapshot == null) {
+        throw new MediaException("Can't obtain a snapshot");
+      }
+    }
+    return snapshot;
   }
 
 }