1 /* 2 * Copyright (C) 2010 ZXing authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.zxing.client.android; 18 19 import com.google.zxing.BinaryBitmap; 20 import com.google.zxing.DecodeHintType; 21 import com.google.zxing.MultiFormatReader; 22 import com.google.zxing.ReaderException; 23 import com.google.zxing.Result; 24 import com.google.zxing.common.HybridBinarizer; 25 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Looper; 29 import android.os.Message; 30 import android.util.Log; 31 32 import java.util.Hashtable; 33 34 final class DecodeHandler extends Handler { 35 36 private static final String TAG = DecodeHandler.class.getSimpleName(); 37 38 private final CaptureActivity activity; 39 private final MultiFormatReader multiFormatReader; 40 private boolean running = true; 41 DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType,Object> hints)42 DecodeHandler(CaptureActivity activity, Hashtable<DecodeHintType,Object> hints) { 43 multiFormatReader = new MultiFormatReader(); 44 multiFormatReader.setHints(hints); 45 this.activity = activity; 46 } 47 48 @Override handleMessage(Message message)49 public void handleMessage(Message message) { 50 if (!running) { 51 return; 52 } 53 if (message.what == R.id.decode) { 54 decode((byte[]) message.obj, message.arg1, message.arg2); 55 } else if (message.what == R.id.quit) { 56 running = false; 57 Looper.myLooper().quit(); 58 } 59 } 60 61 /** 62 * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency, 63 * reuse the same reader objects from one decode to the next. 64 * 65 * @param data The YUV preview frame. 66 * @param width The width of the preview frame. 67 * @param height The height of the preview frame. 68 */ decode(byte[] data, int width, int height)69 private void decode(byte[] data, int width, int height) { 70 long start = System.currentTimeMillis(); 71 Result rawResult = null; 72 PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height); 73 if (source != null) { 74 BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); 75 try { 76 rawResult = multiFormatReader.decodeWithState(bitmap); 77 } catch (ReaderException re) { 78 // continue 79 } finally { 80 multiFormatReader.reset(); 81 } 82 } 83 84 Handler handler = activity.getHandler(); 85 if (rawResult != null) { 86 // Don't log the barcode contents for security. 87 long end = System.currentTimeMillis(); 88 Log.d(TAG, "Found barcode in " + (end - start) + " ms"); 89 if (handler != null) { 90 Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult); 91 Bundle bundle = new Bundle(); 92 bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap()); 93 message.setData(bundle); 94 message.sendToTarget(); 95 } 96 } else { 97 if (handler != null) { 98 Message message = Message.obtain(handler, R.id.decode_failed); 99 message.sendToTarget(); 100 } 101 } 102 } 103 104 } 105