/* * 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. * 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.codename1.impl.midp.codescan; import com.google.zxing.*; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; //import com.nvsoft.csk.util.Configuration; import com.codename1.ui.Image; import com.google.zxing.common.GlobalHistogramBinarizer; import java.util.Hashtable; 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 */ final class SnapshotThread implements Runnable { // private static final Logger logger = LoggerFactory.getLogger(SnapshotThread.class); private final BarCodeScanner barCodeScanner; private final Object waitLock; private volatile boolean done; private final MultimediaManager multimediaManager; private String bestEncoding; SnapshotThread(BarCodeScanner barCodeScanner) { this.barCodeScanner = barCodeScanner; waitLock = new Object(); done = false; multimediaManager = BarCodeScanner.buildMultimediaManager(); } void continueRun() { synchronized (waitLock) { waitLock.notifyAll(); } } private void waitForSignal() { synchronized (waitLock) { try { waitLock.wait(); } catch (InterruptedException ie) { // continue } } } void stop() { done = true; continueRun(); } public void run() { do { waitForSignal(); if (done) { break; } BinaryBitmap bitmap = null; try { Player player = barCodeScanner.getPlayer(); if (player == null) { break; } multimediaManager.setFocus(player); byte[] snapshot = takeSnapshot(); if (snapshot == null) { break; } Image capturedImage = Image.createImage(snapshot, 0, snapshot.length); LuminanceSource source = new CN1ImageLuminanceSource(capturedImage); bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result = null; if(barCodeScanner.type == BarCodeScanner.QRCODE){ Reader reader = new QRCodeReader(); result = reader.decode(bitmap); }else{ MultiFormatReader reader = new MultiFormatReader(); result = reader.decodeBarcode(bitmap); } barCodeScanner.handleDecodedText(result); } catch (ReaderException re) { barCodeScanner.showError("Not found!"); } catch (Exception e) { barCodeScanner.showError(e.getMessage()); } } while (!done); } private byte[] takeSnapshot() throws MediaException { String bestEncoding = guessBestEncoding(); VideoControl videoControl = barCodeScanner.getVideoControl(); if (videoControl == null) { throw new MediaException("Can't obtain video control"); } byte[] snapshot = null; try { snapshot = videoControl.getSnapshot("".equals(bestEncoding) ? null : bestEncoding); } 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; } private synchronized String guessBestEncoding() throws MediaException { if (bestEncoding == null) { // Check this property, present on some Nokias? String supportsVideoCapture = System.getProperty("supports.video.capture"); if ("false".equals(supportsVideoCapture)) { throw new MediaException("supports.video.capture is false"); } bestEncoding = ""; String videoSnapshotEncodings = System.getProperty("video.snapshot.encodings"); if (videoSnapshotEncodings != null) { // We know explicitly what the camera supports; see if PNG is among them since // Image.createImage() should always support it int pngEncodingStart = videoSnapshotEncodings.indexOf("encoding=png"); if (pngEncodingStart >= 0) { int space = videoSnapshotEncodings.indexOf(' ', pngEncodingStart); bestEncoding = space >= 0 ? videoSnapshotEncodings.substring(pngEncodingStart, space) : videoSnapshotEncodings.substring(pngEncodingStart); } } } return bestEncoding; } }