1ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin/*
2ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * Copyright (C) 2014 The Android Open Source Project
3ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin *
4ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * Licensed under the Apache License, Version 2.0 (the "License");
5ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * you may not use this file except in compliance with the License.
6ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * You may obtain a copy of the License at
7ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin *
8ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin *      http://www.apache.org/licenses/LICENSE-2.0
9ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin *
10ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * Unless required by applicable law or agreed to in writing, software
11ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * distributed under the License is distributed on an "AS IS" BASIS,
12ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * See the License for the specific language governing permissions and
14ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin * limitations under the License.
15ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin */
16ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
173830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberlingpackage com.android.camera.processing.imagebackend;
18ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
19725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Linimport android.graphics.Rect;
20ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Linimport com.android.camera.app.OrientationManager;
21ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Linimport com.android.camera.debug.Log;
22725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Linimport com.android.camera.one.v2.camera2proxy.ImageProxy;
2330ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Linimport com.android.camera.session.CaptureSession;
24ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
25ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Linimport java.util.concurrent.Executor;
26ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
270f0329889f69182648fe8f535335e48978d63cc0I-Jong Linimport javax.annotation.Nullable;
280f0329889f69182648fe8f535335e48978d63cc0I-Jong Lin
29ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin/**
30725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin * TaskImageContainer are the base class of tasks that wish to run with the
31725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin * ImageBackend class. It contains the basic information required to interact
32725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin * with the ImageBackend class and the ability to identify itself to the UI
33725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin * backend for updates on its progress.
34ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin */
35ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Linpublic abstract class TaskImageContainer implements Runnable {
36ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
37ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
38725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * Simple helper class to encapsulate uncompressed payloads. Could be more
39725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * complex in the future.
40ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
41ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    static public class UncompressedPayload {
42725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        final public int[] data;
43725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
44725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        UncompressedPayload(int[] passData) {
45ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            data = passData;
46ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        }
47ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
48ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
49ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
50725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * Simple helper class to encapsulate compressed payloads. Could be more
51725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * complex in the future.
52ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
53ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    static public class CompressedPayload {
54725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        final public byte[] data;
55725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
56725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        CompressedPayload(byte[] passData) {
57ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            data = passData;
58ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        }
59ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
60ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
61ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
62725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * Simple helper class to encapsulate all necessary image information that
63725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * is carried with the data to processing, so that tasks derived off of
64725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * TaskImageContainer can properly coordinate and optimize its computation.
65ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
66ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    static public class TaskImage {
67ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        // Addendum to Android-defined image-format
68ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        public final static int EXTRA_USER_DEFINED_FORMAT_ARGB_8888 = -1;
69ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
70ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        // Minimal required knowledge for the image specification.
7130ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        public final OrientationManager.DeviceOrientation orientation;
72ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
7330ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        public final int height;
7430ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        public final int width;
7530ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        public final int format;
76725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        public final Rect cropApplied;
77ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
78ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        TaskImage(OrientationManager.DeviceOrientation anOrientation, int aWidth, int aHeight,
79725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin                int aFormat, Rect crop) {
80ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            orientation = anOrientation;
813830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling            height = aHeight;
823830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling            width = aWidth;
83ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            format = aFormat;
84725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin            cropApplied = crop;
85ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        }
86ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
87ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
88ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
89ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
90725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * Simple helper class to encapsulate input and resultant image
91725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * specification. TasksImageContainer classes can be uniquely identified by
92725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * triplet of its content (currently, the global timestamp of when the
93725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * object was taken), the image specification of the input and the desired
94725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * output image specification. Added a field to specify the destination of
95725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * the image artifact, since spawn tasks may created multiple un/compressed
96725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * artifacts of different size that need to be routed to different
97725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * components.
98ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
99ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    static public class TaskInfo {
10030ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin
10130ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin        /**
10230ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * A single task graph can often create multiple imaging processing
10330ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * artifacts and the listener needs to distinguish an uncompressed image
10430ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * meant for image destinations. The different destinations are as
10530ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * follows:
10630ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * <ul>
10730ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * <li>FAST_THUMBNAIL: Small image required as soon as possible</li>
10830ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * <li>INTERMEDIATE_THUMBNAIL: Mid-sized image required for filmstrips
10930ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * at approximately 100-500ms latency</li>
11030ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * <li>FINAL_IMAGE: Full-resolution image artifact where latency > 500
11130ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * ms</li>
11230ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         * </ul>
11330ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin         */
11430ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin        public enum Destination {
11530ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin            FAST_THUMBNAIL,
11630ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin            INTERMEDIATE_THUMBNAIL,
11730ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin            FINAL_IMAGE
11830ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin        }
11930ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin
12030ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin        public final Destination destination;
121ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        // The unique Id of the image being processed.
122ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        public final long contentId;
123ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
124ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        public final TaskImage input;
125ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
126ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        public final TaskImage result;
127ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
128725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        TaskInfo(long aContentId, TaskImage inputSpec, TaskImage outputSpec,
129725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin                Destination aDestination) {
130ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            contentId = aContentId;
131ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            input = inputSpec;
132ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin            result = outputSpec;
13330ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin            destination = aDestination;
134ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        }
135ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
136ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
137ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
138ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    public enum ProcessingPriority {
139e1bfecfb5efaa29419705b35706decece4985126I-Jong Lin        FAST, AVERAGE, SLOW
140ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
141ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
142ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    protected final static Log.Tag TAG = new Log.Tag("TaskImgContain");
143ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
1443c7b7ec6aa2e51859718a6d6dead3c12d10ea370I-Jong Lin    final protected ImageTaskManager mImageTaskManager;
145ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
146ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    final protected Executor mExecutor;
147ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
148ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    final protected long mId;
149ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
150ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    final protected ProcessingPriority mProcessingPriority;
151ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
1523830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling    final protected ImageToProcess mImage;
153ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
15430ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin    final protected CaptureSession mSession;
15530ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin
156ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
157ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * Constructor when releasing the image reference.
158ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     *
159ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param otherTask the original task that is spawning this task.
160ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param processingPriority Priority that the derived task will run at.
161ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
162ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    public TaskImageContainer(TaskImageContainer otherTask, ProcessingPriority processingPriority) {
16330ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mId = otherTask.mId;
16430ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mExecutor = otherTask.mExecutor;
1653c7b7ec6aa2e51859718a6d6dead3c12d10ea370I-Jong Lin        mImageTaskManager = otherTask.mImageTaskManager;
16630ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mProcessingPriority = processingPriority;
16730ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mSession = otherTask.mSession;
1683830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling        mImage = null;
169ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
170ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
171ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
172ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * Constructor to use when keeping the image reference.
173ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     *
174ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param image Image reference that needs to be released.
1750f0329889f69182648fe8f535335e48978d63cc0I-Jong Lin     * @param Executor Executor to run the event handling, if required.
176c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param imageTaskManager a reference to the ImageBackend, in case, you
177c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *            need to spawn other tasks
178ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param preferredLane Priority that the derived task will run at
17930ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin     * @param captureSession Session that handles image processing events
180ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
1810f0329889f69182648fe8f535335e48978d63cc0I-Jong Lin    public TaskImageContainer(ImageToProcess image, @Nullable Executor Executor,
182725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin            ImageTaskManager imageTaskManager,
18330ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin            ProcessingPriority preferredLane, CaptureSession captureSession) {
1843830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling        mImage = image;
1853830d419691ef865f01b362fee9618bac2aa8888Sascha Haeberling        mId = mImage.proxy.getTimestamp();
18630ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mExecutor = Executor;
1873c7b7ec6aa2e51859718a6d6dead3c12d10ea370I-Jong Lin        mImageTaskManager = imageTaskManager;
18830ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mProcessingPriority = preferredLane;
18930ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin        mSession = captureSession;
190ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
191ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
192ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
193c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * Returns rotated crop rectangle in terms of absolute sensor crop
194c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *
195c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     */
196c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    protected Rect rotateBoundingBox(Rect box, OrientationManager.DeviceOrientation orientation) {
197c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        if(orientation == OrientationManager.DeviceOrientation.CLOCKWISE_0 ||
198c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin                orientation == OrientationManager.DeviceOrientation.CLOCKWISE_180) {
199c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            return new Rect(box);
200c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        } else {
201c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            // Switch x/y coordinates.
202c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            return new Rect(box.top, box.left, box.bottom, box.right);
203c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        }
204c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    }
205c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
206c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    protected OrientationManager.DeviceOrientation addOrientation(
207c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            OrientationManager.DeviceOrientation orientation1,
208c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            OrientationManager.DeviceOrientation orientation2) {
209c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        return OrientationManager.DeviceOrientation.from(orientation1.getDegrees()
210c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin                + orientation2.getDegrees());
211c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    }
212c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
213c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    /**
214725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * Returns a crop rectangle whose points are a strict subset of the points
215c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * specified by image rectangle. A Null Intersection returns
216c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * Rectangle(0,0,0,0).
217725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     *
218725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * @param image image to be cropped
219725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * @param crop an arbitrary crop rectangle; if null, the crop is assumed to
220725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     *            be set of all points.
221725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     * @return the rectangle produced by the intersection of the image rectangle
222725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     *         with passed-in crop rectangle; a null intersection returns
223725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     *         Rect(0,0,0,0)
224725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin     */
225725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin    public Rect guaranteedSafeCrop(ImageProxy image, @Nullable Rect crop) {
226c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        return guaranteedSafeCrop(image.getWidth(), image.getHeight(), crop);
227c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    }
228c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
229c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    /**
230c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * Returns a crop rectangle whose points are a strict subset of the points
231c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * specified by image rectangle. A Null Intersection returns Rectangle(0,0,0,0).
232c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * Since sometimes the ImageProxy doesn't take into account rotation.  The Image
233c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * is assumed to have its top-left corner at (0,0).
234c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *
235c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param width image width
236c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param height image height
237c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param crop an arbitrary crop rectangle; if null, the crop is assumed to
238c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *            be set of all points.
239c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @return the rectangle produced by the intersection of the image rectangle
240c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *         with passed-in crop rectangle; a null intersection returns
241c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *         Rect(0,0,0,0)
242c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     */
243c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
244c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    public Rect guaranteedSafeCrop(int width, int height, @Nullable Rect crop) {
245725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        if (crop == null) {
246c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            return new Rect(0, 0, width, height);
247725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        }
248725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        Rect safeCrop = new Rect(crop);
249725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        if (crop.top > crop.bottom || crop.left > crop.right || crop.width() <= 0
250725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin                || crop.height() <= 0) {
251725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin            return new Rect(0, 0, 0, 0);
252725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        }
253725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
254725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        safeCrop.left = Math.max(safeCrop.left, 0);
255725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        safeCrop.top = Math.max(safeCrop.top, 0);
256c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        safeCrop.right = Math.max(Math.min(safeCrop.right, width), safeCrop.left);
257c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        safeCrop.bottom = Math.max(Math.min(safeCrop.bottom, height), safeCrop.top);
258725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
259725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        if (safeCrop.width() <= 0 || safeCrop.height() <= 0) {
260725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin            return new Rect(0, 0, 0, 0);
261725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        }
262725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
263725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin        return safeCrop;
264725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin    }
265725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin
266725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin    /**
267c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * Returns whether the crop operation is required.
268c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *
269c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param image Image to be cropped
270c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @param crop Crop region
271c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     * @return whether the image needs any more processing to be cropped
272c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     *         properly.
273c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin     */
274c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    public boolean requiresCropOperation(ImageProxy image, @Nullable Rect crop) {
275c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        if (crop == null) {
276c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin            return false;
277c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        }
278c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
279c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin        return !(crop.equals(new Rect(0, 0, image.getWidth(), image.getHeight())));
280c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    }
281c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin
282c36bcac14302b1bb3d7a316f221685d4d6ad95cbI-Jong Lin    /**
283ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * Basic listener function to signal ImageBackend that task has started.
284ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     *
285ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param id Id for image content
286ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param input Image specification for task input
287ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @param result Image specification for task result
28830ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin     * @param aDestination Purpose of image processing artifact
289ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
290725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin    public void onStart(long id, TaskImage input, TaskImage result,
291725059d4d1ab78b5ffaa99cbba397b2dafc717d2I-Jong Lin            TaskInfo.Destination aDestination) {
29230ef96534cc65c0ba4665f6da2fc36e879edf196I-Jong Lin        TaskInfo job = new TaskInfo(id, input, result, aDestination);
2933c7b7ec6aa2e51859718a6d6dead3c12d10ea370I-Jong Lin        final ImageProcessorListener listener = mImageTaskManager.getProxyListener();
294ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        listener.onStart(job);
295ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
296ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin
297ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    /**
298ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * Getter for Processing Priority
299ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     *
300ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     * @return Processing Priority associated with the task.
301ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin     */
302ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    public ProcessingPriority getProcessingPriority() {
303ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin        return mProcessingPriority;
304ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin    }
305ed68932f91b4b4ad6766e4e38732deb8be772426I-Jong Lin}
306