X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2FDecodeThread.java;h=75e5bad74da92cb40fa39040d984689c7bdaa28f;hb=b320f70e522f4f2c126cf2e3ff5d8db7b64fb62c;hp=5835ecf5d89efb62e64691f1276675be29d3e50c;hpb=3108287ebe52759d043562a268d103bdf0bd1fe0;p=zxing.git diff --git a/android/src/com/google/zxing/client/android/DecodeThread.java b/android/src/com/google/zxing/client/android/DecodeThread.java index 5835ecf5..75e5bad7 100755 --- a/android/src/com/google/zxing/client/android/DecodeThread.java +++ b/android/src/com/google/zxing/client/android/DecodeThread.java @@ -16,166 +16,81 @@ package com.google.zxing.client.android; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.DecodeHintType; +import com.google.zxing.ResultPointCallback; + import android.content.SharedPreferences; -import android.os.Bundle; import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.preference.PreferenceManager; -import com.google.zxing.BarcodeFormat; -import com.google.zxing.DecodeHintType; -import com.google.zxing.MultiFormatReader; -import com.google.zxing.ReaderException; -import com.google.zxing.Result; import java.util.Hashtable; import java.util.Vector; +import java.util.concurrent.CountDownLatch; /** * This thread does all the heavy lifting of decoding the images. + * + * @author dswitkin@google.com (Daniel Switkin) */ final class DecodeThread extends Thread { public static final String BARCODE_BITMAP = "barcode_bitmap"; - public Handler mHandler; - private final CaptureActivity mActivity; - private final MultiFormatReader mMultiFormatReader; + private final CaptureActivity activity; + private final Hashtable hints; + private Handler handler; + private final CountDownLatch handlerInitLatch; + + DecodeThread(CaptureActivity activity, + Vector decodeFormats, + String characterSet, + ResultPointCallback resultPointCallback) { + + this.activity = activity; + handlerInitLatch = new CountDownLatch(1); - DecodeThread(CaptureActivity activity, String mode) { - mActivity = activity; - mMultiFormatReader = new MultiFormatReader(); + hints = new Hashtable(3); // The prefs can't change while the thread is running, so pick them up once here. - if (mode == null || mode.length() == 0) { + if (decodeFormats == null || decodeFormats.isEmpty()) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); boolean decode1D = prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true); boolean decodeQR = prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true); if (decode1D && decodeQR) { - setDecodeAllMode(); + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.ALL_FORMATS); } else if (decode1D) { - setDecode1DMode(); + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.ONE_D_FORMATS); } else if (decodeQR) { - setDecodeQRMode(); + hints.put(DecodeHintType.POSSIBLE_FORMATS, CaptureActivity.QR_CODE_FORMATS); } } else { - if (mode.equals(Intents.Scan.PRODUCT_MODE)) { - setDecodeProductMode(); - } else if (mode.equals(Intents.Scan.ONE_D_MODE)) { - setDecode1DMode(); - } else if (mode.equals(Intents.Scan.QR_CODE_MODE)) { - setDecodeQRMode(); - } else { - setDecodeAllMode(); - } + hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); } - } - @Override - public void run() { - Looper.prepare(); - mHandler = new Handler() { - @Override - public void handleMessage(Message message) { - switch (message.what) { - case R.id.decode: - decode((byte[]) message.obj, message.arg1, message.arg2); - break; - case R.id.quit: - Looper.myLooper().quit(); - break; - } - } - }; - Looper.loop(); - } - - private void setDecodeProductMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); - } - - // TODO: This is fragile in case we add new formats. It would be better to have a new enum - // value which represented all 1D formats. - private void setDecode1DMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - vector.addElement(BarcodeFormat.CODE_39); - vector.addElement(BarcodeFormat.CODE_128); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); - } - - private void setDecodeQRMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.QR_CODE); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); - } + if (characterSet != null) { + hints.put(DecodeHintType.CHARACTER_SET, characterSet); + } - /** - * Instead of calling setHints(null), which would allow new formats like ITF to sneak in, we - * explicitly set which formats are available. - */ - private void setDecodeAllMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - vector.addElement(BarcodeFormat.CODE_39); - vector.addElement(BarcodeFormat.CODE_128); - vector.addElement(BarcodeFormat.QR_CODE); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); + hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); } - /** - * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, - * reuse the same reader objects from one decode to the next. - * - * @param data The YUV preview frame. - * @param width The width of the preview frame. - * @param height The height of the preview frame. - */ - private void decode(byte[] data, int width, int height) { - long start = System.currentTimeMillis(); - boolean success; - Result rawResult = null; - YUVMonochromeBitmapSource source = new YUVMonochromeBitmapSource(data, width, height, - CameraManager.get().getFramingRect()); + Handler getHandler() { try { - rawResult = mMultiFormatReader.decodeWithState(source); - success = true; - } catch (ReaderException e) { - success = false; - } - long end = System.currentTimeMillis(); - - if (success) { - Message message = Message.obtain(mActivity.mHandler, R.id.decode_succeeded, rawResult); - message.arg1 = (int) (end - start); - Bundle bundle = new Bundle(); - bundle.putParcelable(BARCODE_BITMAP, source.renderToBitmap()); - message.setData(bundle); - message.sendToTarget(); - } else { - Message message = Message.obtain(mActivity.mHandler, R.id.decode_failed); - message.arg1 = (int) (end - start); - message.sendToTarget(); + handlerInitLatch.await(); + } catch (InterruptedException ie) { + // continue? } + return handler; + } + + @Override + public void run() { + Looper.prepare(); + handler = new DecodeHandler(activity, hints); + handlerInitLatch.countDown(); + Looper.loop(); } }