1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.camera2.utils;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.camera2.CaptureRequest;
import android.util.Rational;
import android.util.Size;
import static com.android.internal.util.Preconditions.*;
/**
* Various assortment of params utilities.
*/
public class ParamsUtils {
/** Arbitrary denominator used to estimate floats as rationals */
private static final int RATIONAL_DENOMINATOR = 1000000; // 1million
/**
* Create a {@link Rect} from a {@code Size} by creating a new rectangle with
* left, top = {@code (0, 0)} and right, bottom = {@code (width, height)}
*
* @param size a non-{@code null} size
*
* @return a {@code non-null} rectangle
*
* @throws NullPointerException if {@code size} was {@code null}
*/
public static Rect createRect(Size size) {
checkNotNull(size, "size must not be null");
return new Rect(/*left*/0, /*top*/0, size.getWidth(), size.getHeight());
}
/**
* Create a {@link Rect} from a {@code RectF} by creating a new rectangle with
* each corner (left, top, right, bottom) rounded towards the nearest integer bounding box.
*
* <p>In particular (left, top) is floored, and (right, bottom) is ceiled.</p>
*
* @param size a non-{@code null} rect
*
* @return a {@code non-null} rectangle
*
* @throws NullPointerException if {@code rect} was {@code null}
*/
public static Rect createRect(RectF rect) {
checkNotNull(rect, "rect must not be null");
Rect r = new Rect();
rect.roundOut(r);
return r;
}
/**
* Map the rectangle in {@code rect} with the transform in {@code transform} into
* a new rectangle, with each corner (left, top, right, bottom) rounded towards the nearest
* integer bounding box.
*
* <p>None of the arguments are mutated.</p>
*
* @param transform a non-{@code null} transformation matrix
* @param rect a non-{@code null} rectangle
* @return a new rectangle that was transformed by {@code transform}
*
* @throws NullPointerException if any of the args were {@code null}
*/
public static Rect mapRect(Matrix transform, Rect rect) {
checkNotNull(transform, "transform must not be null");
checkNotNull(rect, "rect must not be null");
RectF rectF = new RectF(rect);
transform.mapRect(rectF);
return createRect(rectF);
}
/**
* Create a {@link Size} from a {@code Rect} by creating a new size whose width
* and height are the same as the rectangle's width and heights.
*
* @param rect a non-{@code null} rectangle
*
* @return a {@code non-null} size
*
* @throws NullPointerException if {@code rect} was {@code null}
*/
public static Size createSize(Rect rect) {
checkNotNull(rect, "rect must not be null");
return new Size(rect.width(), rect.height());
}
/**
* Create a {@link Rational} value by approximating the float value as a rational.
*
* <p>Floating points too large to be represented as an integer will be converted to
* to {@link Integer#MAX_VALUE}; floating points too small to be represented as an integer
* will be converted to {@link Integer#MIN_VALUE}.</p>
*
* @param value a floating point value
* @return the rational representation of the float
*/
public static Rational createRational(float value) {
if (Float.isNaN(value)) {
return Rational.NaN;
} else if (value == Float.POSITIVE_INFINITY) {
return Rational.POSITIVE_INFINITY;
} else if (value == Float.NEGATIVE_INFINITY) {
return Rational.NEGATIVE_INFINITY;
} else if (value == 0.0f) {
return Rational.ZERO;
}
// normal finite value: approximate it
/*
* Start out trying to approximate with denominator = 1million,
* but if the numerator doesn't fit into an Int then keep making the denominator
* smaller until it does.
*/
int den = RATIONAL_DENOMINATOR;
float numF;
do {
numF = value * den;
if ((numF > Integer.MIN_VALUE && numF < Integer.MAX_VALUE) || (den == 1)) {
break;
}
den /= 10;
} while (true);
/*
* By float -> int narrowing conversion in JLS 5.1.3, this will automatically become
* MIN_VALUE or MAX_VALUE if numF is too small/large to be represented by an integer
*/
int num = (int) numF;
return new Rational(num, den);
}
/**
* Convert an integral rectangle ({@code source}) to a floating point rectangle
* ({@code destination}) in-place.
*
* @param source the originating integer rectangle will be read from here
* @param destination the resulting floating point rectangle will be written out to here
*
* @throws NullPointerException if {@code rect} was {@code null}
*/
public static void convertRectF(Rect source, RectF destination) {
checkNotNull(source, "source must not be null");
checkNotNull(destination, "destination must not be null");
destination.left = source.left;
destination.right = source.right;
destination.bottom = source.bottom;
destination.top = source.top;
}
/**
* Return the value set by the key, or the {@code defaultValue} if no value was set.
*
* @throws NullPointerException if any of the args were {@code null}
*/
public static <T> T getOrDefault(CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue) {
checkNotNull(r, "r must not be null");
checkNotNull(key, "key must not be null");
checkNotNull(defaultValue, "defaultValue must not be null");
T value = r.get(key);
if (value == null) {
return defaultValue;
} else {
return value;
}
}
private ParamsUtils() {
throw new AssertionError();
}
}
|