MeteringRectangle.java revision 72f9f0a96e4476ef231d5001cb30521ad4ce5b1e
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.hardware.camera2.params;
17
18import android.util.Size;
19import static com.android.internal.util.Preconditions.*;
20
21import android.graphics.Point;
22import android.graphics.Rect;
23import android.hardware.camera2.CameraCharacteristics;
24import android.hardware.camera2.CaptureRequest;
25import android.hardware.camera2.utils.HashCodeHelpers;
26
27/**
28 * An immutable class to represent a rectangle {@code (x,y, width, height)} with an
29 * additional weight component.
30 *
31 * </p>The rectangle is defined to be inclusive of the specified coordinates.</p>
32 *
33 * <p>When used with a {@link CaptureRequest}, the coordinate system is based on the active pixel
34 * array, with {@code (0,0)} being the top-left pixel in the
35 * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE active pixel array}, and
36 * {@code (android.sensor.info.activeArraySize.width - 1,
37 * android.sensor.info.activeArraySize.height - 1)}
38 * being the bottom-right pixel in the active pixel array.
39 * </p>
40 *
41 * <p>The metering weight is nonnegative.</p>
42 */
43public final class MeteringRectangle {
44
45    private final int mX;
46    private final int mY;
47    private final int mWidth;
48    private final int mHeight;
49    private final int mWeight;
50
51    /**
52     * Create a new metering rectangle.
53     *
54     * @param x coordinate >= 0
55     * @param y coordinate >= 0
56     * @param width width >= 0
57     * @param height height >= 0
58     * @param meteringWeight weight >= 0
59     *
60     * @throws IllegalArgumentException if any of the parameters were non-negative
61     */
62    public MeteringRectangle(int x, int y, int width, int height, int meteringWeight) {
63        mX = checkArgumentNonnegative(x, "x must be nonnegative");
64        mY = checkArgumentNonnegative(y, "y must be nonnegative");
65        mWidth = checkArgumentNonnegative(width, "width must be nonnegative");
66        mHeight = checkArgumentNonnegative(height, "height must be nonnegative");
67        mWeight = checkArgumentNonnegative(meteringWeight, "meteringWeight must be nonnegative");
68    }
69
70    /**
71     * Create a new metering rectangle.
72     *
73     * @param xy a non-{@code null} {@link Point} with both x,y >= 0
74     * @param dimensions a non-{@code null} {@link android.util.Size Size} with width, height >= 0
75     * @param meteringWeight weight >= 0
76     *
77     * @throws IllegalArgumentException if any of the parameters were non-negative
78     * @throws NullPointerException if any of the arguments were null
79     */
80    public MeteringRectangle(Point xy, Size dimensions, int meteringWeight) {
81        checkNotNull(xy, "xy must not be null");
82        checkNotNull(dimensions, "dimensions must not be null");
83
84        mX = checkArgumentNonnegative(xy.x, "x must be nonnegative");
85        mY = checkArgumentNonnegative(xy.y, "y must be nonnegative");
86        mWidth = checkArgumentNonnegative(dimensions.getWidth(), "width must be nonnegative");
87        mHeight = checkArgumentNonnegative(dimensions.getHeight(), "height must be nonnegative");
88        mWeight = checkArgumentNonnegative(meteringWeight, "meteringWeight must be nonnegative");
89    }
90
91    /**
92     * Create a new metering rectangle.
93     *
94     * @param rect a non-{@code null} rectangle with all x,y,w,h dimensions >= 0
95     * @param meteringWeight weight >= 0
96     *
97     * @throws IllegalArgumentException if any of the parameters were non-negative
98     * @throws NullPointerException if any of the arguments were null
99     */
100    public MeteringRectangle(Rect rect, int meteringWeight) {
101        checkNotNull(rect, "rect must not be null");
102
103        mX = checkArgumentNonnegative(rect.left, "rect.left must be nonnegative");
104        mY = checkArgumentNonnegative(rect.top, "rect.top must be nonnegative");
105        mWidth = checkArgumentNonnegative(rect.width(), "rect.width must be nonnegative");
106        mHeight = checkArgumentNonnegative(rect.height(), "rect.height must be nonnegative");
107        mWeight = checkArgumentNonnegative(meteringWeight, "meteringWeight must be nonnegative");
108    }
109
110    /**
111     * Return the X coordinate of the left side of the rectangle.
112     *
113     * @return x coordinate >= 0
114     */
115    public int getX() {
116        return mX;
117    }
118
119    /**
120     * Return the Y coordinate of the upper side of the rectangle.
121     *
122     * @return y coordinate >= 0
123     */
124    public int getY() {
125        return mY;
126    }
127
128    /**
129     * Return the width of the rectangle.
130     *
131     * @return width >= 0
132     */
133    public int getWidth() {
134        return mWidth;
135    }
136
137    /**
138     * Return the height of the rectangle.
139     *
140     * @return height >= 0
141     */
142    public int getHeight() {
143        return mHeight;
144    }
145
146    /**
147     * Return the metering weight of the rectangle.
148     *
149     * @return weight >= 0
150     */
151    public int getMeteringWeight() {
152        return mWeight;
153    }
154
155    /**
156     * Convenience method to create the upper-left (X,Y) coordinate as a {@link Point}.
157     *
158     * @return {@code (x,y)} point with both x,y >= 0
159     */
160    public Point getUpperLeftPoint() {
161        return new Point(mX, mY);
162    }
163
164    /**
165     * Convenience method to create the size from this metering rectangle.
166     *
167     * <p>This strips away the X,Y,weight from the rectangle.</p>
168     *
169     * @return a Size with non-negative width and height
170     */
171    public Size getSize() {
172        return new Size(mWidth, mHeight);
173    }
174
175    /**
176     * Convenience method to create a {@link Rect} from this metering rectangle.
177     *
178     * <p>This strips away the weight from the rectangle.</p>
179     *
180     * @return a {@link Rect} with non-negative x1, y1, x2, y2
181     */
182    public Rect getRect() {
183        return new Rect(mX, mY, mX + mWidth, mY + mHeight);
184    }
185
186    /**
187     * {@inheritDoc}
188     */
189    @Override
190    public boolean equals(final Object other) {
191        return other instanceof MeteringRectangle && equals((MeteringRectangle)other);
192    }
193
194    /**
195     * Compare two metering rectangles to see if they are equal.
196     *
197     * Two weighted rectangles are only considered equal if each of their components
198     * (x, y, width, height, weight) is respectively equal.
199     *
200     * @param other Another MeteringRectangle
201     *
202     * @return {@code true} if the metering rectangles are equal, {@code false} otherwise
203     */
204    public boolean equals(final MeteringRectangle other) {
205        if (other == null) {
206            return false;
207        }
208
209        return (mX == other.mX
210                && mY == other.mY
211                && mWidth == other.mWidth
212                && mHeight == other.mHeight
213                && mWidth == other.mWidth);
214    }
215
216    /**
217     * {@inheritDoc}
218     */
219    @Override
220    public int hashCode() {
221        return HashCodeHelpers.hashCode(mX, mY, mWidth, mHeight, mWeight);
222    }
223}
224