| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.shapedetection; | 5 package org.chromium.chrome.browser.shapedetection; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.graphics.Bitmap; | 8 import android.graphics.Bitmap; |
| 9 import android.graphics.Rect; | 9 import android.graphics.Rect; |
| 10 import android.util.SparseArray; | 10 import android.util.SparseArray; |
| 11 | 11 |
| 12 import com.google.android.gms.vision.Frame; | 12 import com.google.android.gms.vision.Frame; |
| 13 import com.google.android.gms.vision.text.TextBlock; | 13 import com.google.android.gms.vision.text.TextBlock; |
| 14 import com.google.android.gms.vision.text.TextRecognizer; | 14 import com.google.android.gms.vision.text.TextRecognizer; |
| 15 | 15 |
| 16 import org.chromium.base.Log; | 16 import org.chromium.base.Log; |
| 17 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; | 17 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; |
| 18 import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; | 18 import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; |
| 19 import org.chromium.gfx.mojom.RectF; | 19 import org.chromium.gfx.mojom.RectF; |
| 20 import org.chromium.mojo.system.MojoException; | 20 import org.chromium.mojo.system.MojoException; |
| 21 import org.chromium.mojo.system.SharedBufferHandle; |
| 22 import org.chromium.mojo.system.SharedBufferHandle.MapFlags; |
| 21 import org.chromium.services.service_manager.InterfaceFactory; | 23 import org.chromium.services.service_manager.InterfaceFactory; |
| 22 import org.chromium.shape_detection.mojom.TextDetection; | 24 import org.chromium.shape_detection.mojom.TextDetection; |
| 23 import org.chromium.shape_detection.mojom.TextDetectionResult; | 25 import org.chromium.shape_detection.mojom.TextDetectionResult; |
| 24 import org.chromium.skia.mojom.ColorType; | |
| 25 | 26 |
| 26 import java.nio.ByteBuffer; | 27 import java.nio.ByteBuffer; |
| 27 | 28 |
| 28 /** | 29 /** |
| 29 * Implementation of mojo TextDetection, using Google Play Services vision packa
ge. | 30 * Implementation of mojo TextDetection, using Google Play Services vision packa
ge. |
| 30 */ | 31 */ |
| 31 public class TextDetectionImpl implements TextDetection { | 32 public class TextDetectionImpl implements TextDetection { |
| 32 private static final String TAG = "TextDetectionImpl"; | 33 private static final String TAG = "TextDetectionImpl"; |
| 33 | 34 |
| 34 private final Context mContext; | 35 private final Context mContext; |
| 35 private TextRecognizer mTextRecognizer; | 36 private TextRecognizer mTextRecognizer; |
| 36 | 37 |
| 37 public TextDetectionImpl(Context context) { | 38 public TextDetectionImpl(Context context) { |
| 38 mContext = context; | 39 mContext = context; |
| 39 mTextRecognizer = new TextRecognizer.Builder(mContext).build(); | 40 mTextRecognizer = new TextRecognizer.Builder(mContext).build(); |
| 40 } | 41 } |
| 41 | 42 |
| 42 @Override | 43 @Override |
| 43 public void detect(org.chromium.skia.mojom.Bitmap bitmapData, DetectResponse
callback) { | 44 public void detect( |
| 45 SharedBufferHandle frameData, int width, int height, DetectResponse
callback) { |
| 44 if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices( | 46 if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices( |
| 45 mContext, new UserRecoverableErrorHandler.Silent())) { | 47 mContext, new UserRecoverableErrorHandler.Silent())) { |
| 46 Log.e(TAG, "Google Play Services not available"); | 48 Log.e(TAG, "Google Play Services not available"); |
| 47 callback.call(new TextDetectionResult[0]); | 49 callback.call(new TextDetectionResult[0]); |
| 48 return; | 50 return; |
| 49 } | 51 } |
| 50 // The vision library will be downloaded the first time the API is used | 52 // The vision library will be downloaded the first time the API is used |
| 51 // on the device; this happens "fast", but it might have not completed, | 53 // on the device; this happens "fast", but it might have not completed, |
| 52 // bail in this case. Also, the API was disabled between and v.9.0 and | 54 // bail in this case. Also, the API was disabled between and v.9.0 and |
| 53 // v.9.2, see https://developers.google.com/android/guides/releases. | 55 // v.9.2, see https://developers.google.com/android/guides/releases. |
| 54 if (!mTextRecognizer.isOperational()) { | 56 if (!mTextRecognizer.isOperational()) { |
| 55 Log.e(TAG, "TextDetector is not operational"); | 57 Log.e(TAG, "TextDetector is not operational"); |
| 56 callback.call(new TextDetectionResult[0]); | 58 callback.call(new TextDetectionResult[0]); |
| 57 return; | 59 return; |
| 58 } | 60 } |
| 59 | 61 |
| 60 // TODO(junwei.fu): Consider supporting other bitmap pixel formats, | 62 final long numPixels = (long) width * height; |
| 61 // https://crbug.com/684921. | 63 // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking
. |
| 62 if (bitmapData.colorType != ColorType.RGBA_8888 | 64 if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Lo
ng.MAX_VALUE / 4)) { |
| 63 && bitmapData.colorType != ColorType.BGRA_8888) { | |
| 64 Log.e(TAG, "Unsupported bitmap pixel format"); | |
| 65 callback.call(new TextDetectionResult[0]); | 65 callback.call(new TextDetectionResult[0]); |
| 66 return; | 66 return; |
| 67 } | 67 } |
| 68 | |
| 69 int width = bitmapData.width; | |
| 70 int height = bitmapData.height; | |
| 71 final long numPixels = (long) width * height; | |
| 72 // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking
. | |
| 73 if (bitmapData.pixelData == null || width <= 0 || height <= 0 | |
| 74 || numPixels > (Long.MAX_VALUE / 4)) { | |
| 75 callback.call(new TextDetectionResult[0]); | |
| 76 return; | |
| 77 } | |
| 78 | 68 |
| 79 // Mapping |frameData| will fail if the intended mapped size is larger | 69 // Mapping |frameData| will fail if the intended mapped size is larger |
| 80 // than its actual capacity, which is limited by the appropriate | 70 // than its actual capacity, which is limited by the appropriate |
| 81 // mojo::edk::Configuration entry. | 71 // mojo::edk::Configuration entry. |
| 82 ByteBuffer imageBuffer = ByteBuffer.wrap(bitmapData.pixelData); | 72 ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()
); |
| 83 if (imageBuffer.capacity() <= 0) { | 73 if (imageBuffer.capacity() <= 0) { |
| 84 callback.call(new TextDetectionResult[0]); | 74 callback.call(new TextDetectionResult[0]); |
| 85 return; | 75 return; |
| 86 } | 76 } |
| 87 | 77 |
| 88 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_88
88); | 78 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_88
88); |
| 89 bitmap.copyPixelsFromBuffer(imageBuffer); | 79 bitmap.copyPixelsFromBuffer(imageBuffer); |
| 90 | 80 |
| 91 Frame frame = null; | 81 Frame frame = null; |
| 92 try { | 82 try { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 public Factory(Context context) { | 123 public Factory(Context context) { |
| 134 mContext = context; | 124 mContext = context; |
| 135 } | 125 } |
| 136 | 126 |
| 137 @Override | 127 @Override |
| 138 public TextDetection createImpl() { | 128 public TextDetection createImpl() { |
| 139 return new TextDetectionImpl(mContext); | 129 return new TextDetectionImpl(mContext); |
| 140 } | 130 } |
| 141 } | 131 } |
| 142 } | 132 } |
| OLD | NEW |