| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.shapedetection; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.graphics.Bitmap; |
| 9 import android.graphics.Rect; |
| 10 import android.util.SparseArray; |
| 11 |
| 12 import com.google.android.gms.vision.Frame; |
| 13 import com.google.android.gms.vision.text.TextBlock; |
| 14 import com.google.android.gms.vision.text.TextRecognizer; |
| 15 |
| 16 import org.chromium.base.Log; |
| 17 import org.chromium.blink.mojom.TextDetection; |
| 18 import org.chromium.blink.mojom.TextDetectionResult; |
| 19 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; |
| 20 import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; |
| 21 import org.chromium.gfx.mojom.RectF; |
| 22 import org.chromium.mojo.system.MojoException; |
| 23 import org.chromium.mojo.system.SharedBufferHandle; |
| 24 import org.chromium.mojo.system.SharedBufferHandle.MapFlags; |
| 25 |
| 26 import java.nio.ByteBuffer; |
| 27 |
| 28 /** |
| 29 * Implementation of mojo TextDetection, using Google Play Services vision packa
ge. |
| 30 */ |
| 31 public class TextDetectionImpl implements TextDetection { |
| 32 private static final String TAG = "TextDetectionImpl"; |
| 33 |
| 34 private final Context mContext; |
| 35 private TextRecognizer mTextRecognizer; |
| 36 |
| 37 public TextDetectionImpl(Context context) { |
| 38 mContext = context; |
| 39 mTextRecognizer = new TextRecognizer.Builder(mContext).build(); |
| 40 } |
| 41 |
| 42 @Override |
| 43 public void detect( |
| 44 SharedBufferHandle frameData, int width, int height, DetectResponse
callback) { |
| 45 if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices( |
| 46 mContext, new UserRecoverableErrorHandler.Silent())) { |
| 47 Log.e(TAG, "Google Play Services not available"); |
| 48 callback.call(new TextDetectionResult[0]); |
| 49 return; |
| 50 } |
| 51 // The vision library will be downloaded the first time the API is used |
| 52 // on the device; this happens "fast", but it might have not completed, |
| 53 // bail in this case. Also, the API was disabled between and v.9.0 and |
| 54 // v.9.2, see https://developers.google.com/android/guides/releases. |
| 55 if (!mTextRecognizer.isOperational()) { |
| 56 Log.e(TAG, "TextDetector is not operational"); |
| 57 callback.call(new TextDetectionResult[0]); |
| 58 return; |
| 59 } |
| 60 |
| 61 final long numPixels = (long) width * height; |
| 62 // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking
. |
| 63 if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Lo
ng.MAX_VALUE / 4)) { |
| 64 callback.call(new TextDetectionResult[0]); |
| 65 return; |
| 66 } |
| 67 |
| 68 // Mapping |frameData| will fail if the intended mapped size is larger |
| 69 // than its actual capacity, which is limited by the appropriate |
| 70 // mojo::edk::Configuration entry. |
| 71 ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()
); |
| 72 if (imageBuffer.capacity() <= 0) { |
| 73 callback.call(new TextDetectionResult[0]); |
| 74 return; |
| 75 } |
| 76 |
| 77 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_88
88); |
| 78 bitmap.copyPixelsFromBuffer(imageBuffer); |
| 79 |
| 80 Frame frame = null; |
| 81 try { |
| 82 // This constructor implies a pixel format conversion to YUV. |
| 83 frame = new Frame.Builder().setBitmap(bitmap).build(); |
| 84 } catch (IllegalArgumentException | IllegalStateException ex) { |
| 85 Log.e(TAG, "Frame.Builder().setBitmap() or build(): " + ex); |
| 86 callback.call(new TextDetectionResult[0]); |
| 87 return; |
| 88 } |
| 89 |
| 90 final SparseArray<TextBlock> textBlocks = mTextRecognizer.detect(frame); |
| 91 |
| 92 TextDetectionResult[] detectedTextArray = new TextDetectionResult[textBl
ocks.size()]; |
| 93 for (int i = 0; i < textBlocks.size(); i++) { |
| 94 detectedTextArray[i] = new TextDetectionResult(); |
| 95 detectedTextArray[i].rawValue = textBlocks.valueAt(i).getValue(); |
| 96 final Rect rect = textBlocks.valueAt(i).getBoundingBox(); |
| 97 detectedTextArray[i].boundingBox = new RectF(); |
| 98 detectedTextArray[i].boundingBox.x = rect.left; |
| 99 detectedTextArray[i].boundingBox.y = rect.top; |
| 100 detectedTextArray[i].boundingBox.width = rect.width(); |
| 101 detectedTextArray[i].boundingBox.height = rect.height(); |
| 102 } |
| 103 callback.call(detectedTextArray); |
| 104 } |
| 105 |
| 106 @Override |
| 107 public void close() { |
| 108 mTextRecognizer.release(); |
| 109 } |
| 110 |
| 111 @Override |
| 112 public void onConnectionError(MojoException e) { |
| 113 close(); |
| 114 } |
| 115 } |
| OLD | NEW |