Chromium Code Reviews| Index: content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java |
| diff --git a/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java |
| index 17ff5506fbb5d171d838b16d1d25147d0d52b0c0..a21d1bb03280b40c9441913986b59fe127376bcd 100644 |
| --- a/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java |
| +++ b/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java |
| @@ -5,6 +5,7 @@ |
| package org.chromium.content.browser.shapedetection; |
| import android.graphics.Bitmap; |
| +import android.graphics.Bitmap.Config; |
| import android.graphics.PointF; |
| import android.media.FaceDetector; |
| import android.media.FaceDetector.Face; |
| @@ -12,11 +13,10 @@ import android.media.FaceDetector.Face; |
| import org.chromium.base.Log; |
| import org.chromium.gfx.mojom.RectF; |
| import org.chromium.mojo.system.MojoException; |
| -import org.chromium.mojo.system.SharedBufferHandle; |
| -import org.chromium.mojo.system.SharedBufferHandle.MapFlags; |
| import org.chromium.shape_detection.mojom.FaceDetection; |
| import org.chromium.shape_detection.mojom.FaceDetectionResult; |
| import org.chromium.shape_detection.mojom.FaceDetectorOptions; |
| +import org.chromium.skia.mojom.ColorType; |
| import java.nio.ByteBuffer; |
| @@ -29,53 +29,80 @@ public class FaceDetectionImpl implements FaceDetection { |
| private static final int MAX_FACES = 32; |
| private final boolean mFastMode; |
| private final int mMaxFaces; |
| + private Config mBitmapConfig; |
|
mcasas
2017/01/24 00:52:06
We don't need a member variable, validConfig()
cou
|
| FaceDetectionImpl(FaceDetectorOptions options) { |
| mFastMode = options.fastMode; |
| mMaxFaces = Math.min(options.maxDetectedFaces, MAX_FACES); |
| } |
| + private boolean validConfig(int colorType) { |
| + switch (colorType) { |
| + case ColorType.ALPHA_8: |
| + mBitmapConfig = Config.ALPHA_8; |
| + return true; |
| + case ColorType.RGB_565: |
| + mBitmapConfig = Config.RGB_565; |
| + return true; |
| + case ColorType.ARGB_4444: |
| + mBitmapConfig = Config.ARGB_4444; |
| + return true; |
| + case ColorType.RGBA_8888: |
| + mBitmapConfig = Config.ARGB_8888; |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| @Override |
| - public void detect( |
| - SharedBufferHandle frameData, int width, int height, DetectResponse callback) { |
| + public void detect(org.chromium.skia.mojom.Bitmap bitmapData, DetectResponse callback) { |
| + int width = bitmapData.width; |
| + int height = bitmapData.height; |
| final long numPixels = (long) width * height; |
| // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking. |
| - if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Long.MAX_VALUE / 4)) { |
| + if (bitmapData.pixelData == null || width <= 0 || height <= 0 |
| + || numPixels > (Long.MAX_VALUE / 4) || !validConfig(bitmapData.colorType)) { |
|
mcasas
2017/01/24 00:52:05
Same comments as in Barcode/TextDetectionImpl
rega
|
| Log.d(TAG, "Invalid argument(s)."); |
| callback.call(new FaceDetectionResult()); |
| return; |
| } |
| - ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()); |
| + ByteBuffer imageBuffer = ByteBuffer.wrap(bitmapData.pixelData); |
| if (imageBuffer.capacity() <= 0) { |
| - Log.d(TAG, "Failed to map from SharedBufferHandle."); |
| + Log.d(TAG, "Failed to wrap from Bitmap."); |
| callback.call(new FaceDetectionResult()); |
| return; |
| } |
| - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); |
| - |
| - // An int array is needed to construct a Bitmap. However the Bytebuffer |
| - // we get from |sharedBufferHandle| is directly allocated and does not |
| - // have a supporting array. Therefore we need to copy from |imageBuffer| |
| - // to create this intermediate Bitmap. |
| - // TODO(xianglu): Consider worker pool as appropriate threads. |
| - // http://crbug.com/655814 |
| - bitmap.copyPixelsFromBuffer(imageBuffer); |
| - |
| - // A Bitmap must be in 565 format for findFaces() to work. See |
| - // http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/FaceDetector.java#124 |
| - // |
| - // It turns out that FaceDetector is not able to detect correctly if |
| - // simply using pixmap.setConfig(). The reason might be that findFaces() |
| - // needs non-premultiplied ARGB arrangement, while the alpha type in the |
| - // original image is premultiplied. We can use getPixels() which does |
| - // the unmultiplication while copying to a new array. See |
| - // http://androidxref.com/7.0.0_r1/xref/frameworks/base/graphics/java/android/graphics/Bitmap.java#538 |
| - int[] pixels = new int[width * height]; |
| - bitmap.getPixels(pixels, 0, width, 0, 0, width, height); |
| - Bitmap unPremultipliedBitmap = |
| - Bitmap.createBitmap(pixels, width, height, Bitmap.Config.RGB_565); |
| + Bitmap unPremultipliedBitmap; |
| + if (bitmapData.colorType == ColorType.RGB_565) { |
|
mcasas
2017/01/24 00:52:06
If blink is never sending this format, how could w
|
| + unPremultipliedBitmap = Bitmap.createBitmap(width, height, mBitmapConfig); |
| + |
| + // An int array is needed to construct a Bitmap. However the Bytebuffer |
| + // we get from |Bitmap| is directly allocated and does not have a supporting array. |
|
mcasas
2017/01/24 00:52:06
|| in comments applies to variables, not types, so
|
| + // Therefore we need to copy from |imageBuffer| to create this intermediate Bitmap. |
| + // TODO(xianglu): Consider worker pool as appropriate threads. |
| + // http://crbug.com/655814 |
| + unPremultipliedBitmap.copyPixelsFromBuffer(imageBuffer); |
| + } else { |
| + Bitmap bitmap = Bitmap.createBitmap(width, height, mBitmapConfig); |
| + |
| + bitmap.copyPixelsFromBuffer(imageBuffer); |
| + |
| + // A Bitmap must be in 565 format for findFaces() to work. See |
| + // http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/FaceDetector.java#124 |
| + // |
| + // It turns out that FaceDetector is not able to detect correctly if |
| + // simply using pixmap.setConfig(). The reason might be that findFaces() |
| + // needs non-premultiplied ARGB arrangement, while the alpha type in the |
| + // original image is premultiplied. We can use getPixels() which does |
| + // the unmultiplication while copying to a new array. See |
| + // http://androidxref.com/7.0.0_r1/xref/frameworks/base/graphics/java/android/graphics/Bitmap.java#538 |
| + int[] pixels = new int[width * height]; |
| + bitmap.getPixels(pixels, 0, width, 0, 0, width, height); |
| + unPremultipliedBitmap = |
| + Bitmap.createBitmap(pixels, width, height, Bitmap.Config.RGB_565); |
| + } |
| FaceDetector detector = new FaceDetector(width, height, mMaxFaces); |
| Face[] detectedFaces = new Face[mMaxFaces]; |