1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/*
2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright 2013 The Android Open Source Project
3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License");
5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License.
6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at
7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *      http://www.apache.org/licenses/LICENSE-2.0
9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks *
10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software
11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS,
12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and
14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License.
15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */
16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw.samples.simplecamera;
18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.content.res.AssetManager;
21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.graphics.Bitmap;
22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.graphics.BitmapFactory;
23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.net.Uri;
24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.provider.MediaStore;
25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.Filter;
27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameImage2D;
28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameType;
29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.FrameValues;
30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.MffContext;
31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport androidx.media.filterfw.MffFilterTestCase;
32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.io.FileNotFoundException;
34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.io.IOException;
35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.concurrent.ExecutionException;
36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.concurrent.TimeoutException;
37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.hardware.Camera;
39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.hardware.Camera.Face;
40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.graphics.Rect;
41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic class FaceSquareFilterTest extends MffFilterTestCase {
44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    private AssetManager assetMgr = null;
46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    @Override
47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    protected Filter createFilter(MffContext mffContext) {
48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        assetMgr = mffContext.getApplicationContext().getAssets();
49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        return new FaceSquareFilter(mffContext, "faceSquareFilter");
50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    public void testFaceSquareFilter() throws Exception{
53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final int INPUT_WIDTH = 1536;
54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final int INPUT_HEIGHT = 2048;
55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        FrameImage2D image =
56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                createFrame(FrameType.image2D(FrameType.ELEMENT_RGBA8888, FrameType.READ_CPU),
57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                        new int[] {INPUT_WIDTH,INPUT_HEIGHT}).asFrameImage2D();
58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        FrameValues facesFrame = createFrame(FrameType.array(Camera.Face.class), new int[] {1,1}).
60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                asFrameValues();
61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Bitmap bitmap = BitmapFactory.decodeStream(assetMgr.open("XZZ019.jpg"));
63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        image.setBitmap(bitmap);
64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        injectInputFrame("image", image);
65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Face face = new Face();
67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Rect faceRect = new Rect();
68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // These are the values for image 141 with 1 face
69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        faceRect.set(-533, -453, 369, 224);
70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        face.rect = faceRect;
71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Face[] faces = new Face[1];
72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        faces[0] = face;
73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        facesFrame.setValue(faces);
74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        injectInputFrame("faces", facesFrame);
75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        process();
76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        // ensure the output image has the rectangle in the right place
78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        FrameImage2D outputImage = getOutputFrame("image").asFrameImage2D();
79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int[] pixels = new int[bitmap.getByteCount()];
80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(),
81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                bitmap.getHeight());
82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final int FACE_X_RANGE = 2000;
84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final int WIDTH_OFFSET = 1000;
85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        final int HEIGHT_OFFSET = 1000;
86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int top = (faceRect.top+HEIGHT_OFFSET)*bitmap.getHeight()/FACE_X_RANGE;
88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int bottom = (faceRect.bottom+HEIGHT_OFFSET)*bitmap.getHeight()/FACE_X_RANGE;
89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int left = (faceRect.left+WIDTH_OFFSET)*bitmap.getWidth()/FACE_X_RANGE;
90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int right = (faceRect.right+WIDTH_OFFSET)*bitmap.getWidth()/FACE_X_RANGE;
91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (top < 0) {
93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            top = 0;
94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (top > bitmap.getHeight()) {
95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            top = bitmap.getHeight();
96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (left < 0) {
98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            left = 0;
99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (left > bitmap.getWidth()) {
100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            left = bitmap.getWidth();
101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (bottom > bitmap.getHeight()) {
103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            bottom = bitmap.getHeight();
104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (bottom < 0) {
105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            bottom = 0;
106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (right > bitmap.getWidth()) {
108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            right = bitmap.getWidth();
109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        } else if (right < 0) {
110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            right = 0;
111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        for (int j = 0; j < (bottom - top); j++) {
114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Left edge
115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (left > 0 && top > 0) {
116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + left) +
117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + left) +
119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + left) +
121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Right edge
125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (right > 0 && top > 0) {
126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + right) +
127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + right) +
129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * (top + j) + right) +
131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        for (int k = 0; k < (right - left); k++) {
136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Top edge
137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (top < bitmap.getHeight()) {
138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * top + left + k) +
139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * top + left + k) +
141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * top + left + k) +
143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Bottom edge
147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (bottom < bitmap.getHeight()) {
148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * bottom + left + k) +
149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.RED_OFFSET] = (byte) ImageConstants.MAX_BYTE;
150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * bottom + left + k) +
151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.GREEN_OFFSET] = (byte) ImageConstants.MAX_BYTE;
152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                pixels[ImageConstants.PIX_CHANNELS * (bitmap.getWidth() * bottom + left + k) +
153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                       ImageConstants.BLUE_OFFSET] = (byte) ImageConstants.MAX_BYTE;
154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            }
155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        Bitmap outputBitmap = outputImage.toBitmap();
158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int[] outputPixels = new int[outputBitmap.getByteCount()];
159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        outputBitmap.getPixels(outputPixels, 0, outputBitmap.getWidth(), 0, 0,
160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                outputBitmap.getWidth(), outputBitmap.getHeight());
161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        int equalCount = 0;
162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        for ( int i = 0; i < outputBitmap.getByteCount(); i++) {
163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            if (pixels[i] == outputPixels[i])
164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks                equalCount++;
165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks
167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        if (equalCount + (0.05f*outputBitmap.getByteCount()) < outputBitmap.getByteCount()) {
168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            // Assertion will fail if condition is true
169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks            assertEquals(equalCount, outputBitmap.getByteCount());
170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks        }
171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks    }
172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks}