use of android.util.Size in project android_frameworks_base by DirtyUnicorns.
the class CameraTestUtils method getSupportedSizeForFormat.
/**
* Get the available output sizes for the user-defined {@code format}.
*
* <p>Note that implementation-defined/hidden formats are not supported.</p>
*/
public static Size[] getSupportedSizeForFormat(int format, String cameraId, CameraManager cameraManager) throws CameraAccessException {
CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
assertNotNull("Can't get camera characteristics!", properties);
if (VERBOSE) {
Log.v(TAG, "get camera characteristics for camera: " + cameraId);
}
StreamConfigurationMap configMap = properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] availableSizes = configMap.getOutputSizes(format);
assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for format: " + format);
Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(format);
if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
System.arraycopy(availableSizes, 0, allSizes, 0, availableSizes.length);
System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length, highResAvailableSizes.length);
availableSizes = allSizes;
}
if (VERBOSE)
Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
return availableSizes;
}
use of android.util.Size in project android_frameworks_base by DirtyUnicorns.
the class CameraTestUtils method verifyJpegExifExtraTags.
/**
* Verify extra tags in JPEG EXIF
*/
private static void verifyJpegExifExtraTags(ExifInterface exif, Size jpegSize, CaptureResult result, StaticMetadata staticInfo, CameraErrorCollector collector) throws ParseException {
/**
* TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH and TAG_ORIENTATION.
* Orientation and exif width/height need to be tested carefully, two cases:
*
* 1. Device rotate the image buffer physically, then exif width/height may not match
* the requested still capture size, we need swap them to check.
*
* 2. Device use the exif tag to record the image orientation, it doesn't rotate
* the jpeg image buffer itself. In this case, the exif width/height should always match
* the requested still capture size, and the exif orientation should always match the
* requested orientation.
*
*/
int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, /*defaultValue*/
0);
int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, /*defaultValue*/
0);
Size exifSize = new Size(exifWidth, exifHeight);
// Orientation could be missing, which is ok, default to 0.
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, /*defaultValue*/
-1);
// Get requested orientation from result, because they should be same.
if (collector.expectKeyValueNotNull(result, CaptureResult.JPEG_ORIENTATION) != null) {
int requestedOrientation = result.get(CaptureResult.JPEG_ORIENTATION);
final int ORIENTATION_MIN = ExifInterface.ORIENTATION_UNDEFINED;
final int ORIENTATION_MAX = ExifInterface.ORIENTATION_ROTATE_270;
boolean orientationValid = collector.expectTrue(String.format("Exif orientation must be in range of [%d, %d]", ORIENTATION_MIN, ORIENTATION_MAX), exifOrientation >= ORIENTATION_MIN && exifOrientation <= ORIENTATION_MAX);
if (orientationValid) {
/**
* Device captured image doesn't respect the requested orientation,
* which means it rotates the image buffer physically. Then we
* should swap the exif width/height accordingly to compare.
*/
boolean deviceRotatedImage = exifOrientation == ExifInterface.ORIENTATION_UNDEFINED;
if (deviceRotatedImage) {
// Case 1.
boolean needSwap = (requestedOrientation % 180 == 90);
if (needSwap) {
exifSize = new Size(exifHeight, exifWidth);
}
} else {
// Case 2.
collector.expectEquals("Exif orientaiton should match requested orientation", requestedOrientation, getExifOrientationInDegree(exifOrientation, collector));
}
}
}
/**
* Ideally, need check exifSize == jpegSize == actual buffer size. But
* jpegSize == jpeg decode bounds size(from jpeg jpeg frame
* header, not exif) was validated in ImageReaderTest, no need to
* validate again here.
*/
collector.expectEquals("Exif size should match jpeg capture size", jpegSize, exifSize);
// TAG_DATETIME, it should be local time
long currentTimeInMs = System.currentTimeMillis();
long currentTimeInSecond = currentTimeInMs / 1000;
Date date = new Date(currentTimeInMs);
String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
if (collector.expectTrue("Exif TAG_DATETIME shouldn't be null", dateTime != null)) {
collector.expectTrue("Exif TAG_DATETIME is wrong", dateTime.length() == EXIF_DATETIME_LENGTH);
long exifTimeInSecond = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse(dateTime).getTime() / 1000;
long delta = currentTimeInSecond - exifTimeInSecond;
collector.expectTrue("Capture time deviates too much from the current time", Math.abs(delta) < EXIF_DATETIME_ERROR_MARGIN_SEC);
// It should be local time.
collector.expectTrue("Exif date time should be local time", dateTime.startsWith(localDatetime));
}
// TAG_FOCAL_LENGTH.
float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
float exifFocalLength = (float) exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
collector.expectEquals("Focal length should match", getClosestValueInArray(focalLengths, exifFocalLength), exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
// More checks for focal length.
collector.expectEquals("Exif focal length should match capture result", validateFocalLength(result, staticInfo, collector), exifFocalLength);
// TAG_EXPOSURE_TIME
// ExifInterface API gives exposure time value in the form of float instead of rational
String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
collector.expectNotNull("Exif TAG_EXPOSURE_TIME shouldn't be null", exposureTime);
if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_EXPOSURE_TIME)) {
if (exposureTime != null) {
double exposureTimeValue = Double.parseDouble(exposureTime);
long expTimeResult = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
double expected = expTimeResult / 1e9;
double tolerance = expected * EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO;
tolerance = Math.max(tolerance, EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC);
collector.expectEquals("Exif exposure time doesn't match", expected, exposureTimeValue, tolerance);
}
}
// TAG_APERTURE
// ExifInterface API gives aperture value in the form of float instead of rational
String exifAperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
collector.expectNotNull("Exif TAG_APERTURE shouldn't be null", exifAperture);
if (staticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
float[] apertures = staticInfo.getAvailableAperturesChecked();
if (exifAperture != null) {
float apertureValue = Float.parseFloat(exifAperture);
collector.expectEquals("Aperture value should match", getClosestValueInArray(apertures, apertureValue), apertureValue, EXIF_APERTURE_ERROR_MARGIN);
// More checks for aperture.
collector.expectEquals("Exif aperture length should match capture result", validateAperture(result, staticInfo, collector), apertureValue);
}
}
/**
* TAG_FLASH. TODO: For full devices, can check a lot more info
* (http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html#Flash)
*/
String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
collector.expectNotNull("Exif TAG_FLASH shouldn't be null", flash);
/**
* TAG_WHITE_BALANCE. TODO: For full devices, with the DNG tags, we
* should be able to cross-check android.sensor.referenceIlluminant.
*/
String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
collector.expectNotNull("Exif TAG_WHITE_BALANCE shouldn't be null", whiteBalance);
// TAG_MAKE
String make = exif.getAttribute(ExifInterface.TAG_MAKE);
collector.expectEquals("Exif TAG_MAKE is incorrect", Build.MANUFACTURER, make);
// TAG_MODEL
String model = exif.getAttribute(ExifInterface.TAG_MODEL);
collector.expectEquals("Exif TAG_MODEL is incorrect", Build.MODEL, model);
// TAG_ISO
int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, /*defaultValue*/
-1);
if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_SENSITIVITY)) {
int expectedIso = result.get(CaptureResult.SENSOR_SENSITIVITY);
collector.expectEquals("Exif TAG_ISO is incorrect", expectedIso, iso);
}
// TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
String digitizedTime = exif.getAttribute(ExifInterface.TAG_DATETIME_DIGITIZED);
collector.expectNotNull("Exif TAG_DATETIME_DIGITIZED shouldn't be null", digitizedTime);
if (digitizedTime != null) {
String expectedDateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
collector.expectNotNull("Exif TAG_DATETIME shouldn't be null", expectedDateTime);
if (expectedDateTime != null) {
collector.expectEquals("dataTime should match digitizedTime", expectedDateTime, digitizedTime);
}
}
/**
* TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
* most 9 digits in ExifInterface implementation, use getAttributeInt to
* sanitize it. When the default value -1 is returned, it means that
* this exif tag either doesn't exist or is a non-numerical invalid
* string. Same rule applies to the rest of sub second tags.
*/
int subSecTime = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME, /*defaultValue*/
-1);
collector.expectTrue("Exif TAG_SUBSEC_TIME value is null or invalid!", subSecTime > 0);
// TAG_SUBSEC_TIME_ORIG
int subSecTimeOrig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_ORIG, /*defaultValue*/
-1);
collector.expectTrue("Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!", subSecTimeOrig > 0);
// TAG_SUBSEC_TIME_DIG
int subSecTimeDig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_DIG, /*defaultValue*/
-1);
collector.expectTrue("Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", subSecTimeDig > 0);
}
use of android.util.Size in project android_frameworks_base by DirtyUnicorns.
the class CameraTestUtils method getSupportedPreviewSizes.
/**
* Get sorted size list in descending order. Remove the sizes larger than
* the bound. If the bound is null, don't do the size bound filtering.
*/
public static List<Size> getSupportedPreviewSizes(String cameraId, CameraManager cameraManager, Size bound) throws CameraAccessException {
Size[] rawSizes = getSupportedSizeForClass(android.view.SurfaceHolder.class, cameraId, cameraManager);
assertArrayNotEmpty(rawSizes, "Available sizes for SurfaceHolder class should not be empty");
if (VERBOSE) {
Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
}
if (bound == null) {
return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/
false);
}
List<Size> sizes = new ArrayList<Size>();
for (Size sz : rawSizes) {
if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
sizes.add(sz);
}
}
return getAscendingOrderSizes(sizes, /*ascending*/
false);
}
use of android.util.Size in project android_frameworks_base by DirtyUnicorns.
the class CameraTestUtils method getSupportedSizeForClass.
/**
* Get the available output sizes for the given class.
*
*/
public static Size[] getSupportedSizeForClass(Class klass, String cameraId, CameraManager cameraManager) throws CameraAccessException {
CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
assertNotNull("Can't get camera characteristics!", properties);
if (VERBOSE) {
Log.v(TAG, "get camera characteristics for camera: " + cameraId);
}
StreamConfigurationMap configMap = properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] availableSizes = configMap.getOutputSizes(klass);
assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for class: " + klass);
Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(ImageFormat.PRIVATE);
if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
System.arraycopy(availableSizes, 0, allSizes, 0, availableSizes.length);
System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length, highResAvailableSizes.length);
availableSizes = allSizes;
}
if (VERBOSE)
Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
return availableSizes;
}
use of android.util.Size in project android_frameworks_base by DirtyUnicorns.
the class Camera2StillCaptureTest method verifyRawCaptureResult.
/**
* Validate that raw {@link CaptureResult}.
*
* @param rawRequest a {@link CaptureRequest} use to capture a RAW16 image.
* @param rawResult the {@link CaptureResult} corresponding to the given request.
*/
private void verifyRawCaptureResult(CaptureRequest rawRequest, CaptureResult rawResult) {
assertNotNull(rawRequest);
assertNotNull(rawResult);
Rational[] empty = new Rational[] { Rational.ZERO, Rational.ZERO, Rational.ZERO };
Rational[] neutralColorPoint = mCollector.expectKeyValueNotNull("NeutralColorPoint", rawResult, CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
if (neutralColorPoint != null) {
mCollector.expectEquals("NeutralColorPoint length", empty.length, neutralColorPoint.length);
mCollector.expectNotEquals("NeutralColorPoint cannot be all zeroes, ", empty, neutralColorPoint);
mCollector.expectValuesGreaterOrEqual("NeutralColorPoint", neutralColorPoint, Rational.ZERO);
}
mCollector.expectKeyValueGreaterOrEqual(rawResult, CaptureResult.SENSOR_GREEN_SPLIT, 0.0f);
Pair<Double, Double>[] noiseProfile = mCollector.expectKeyValueNotNull("NoiseProfile", rawResult, CaptureResult.SENSOR_NOISE_PROFILE);
if (noiseProfile != null) {
mCollector.expectEquals("NoiseProfile length", noiseProfile.length, /*Num CFA channels*/
4);
for (Pair<Double, Double> p : noiseProfile) {
mCollector.expectTrue("NoiseProfile coefficients " + p + " must have: S > 0, O >= 0", p.first > 0 && p.second >= 0);
}
}
Integer hotPixelMode = mCollector.expectKeyValueNotNull("HotPixelMode", rawResult, CaptureResult.HOT_PIXEL_MODE);
Boolean hotPixelMapMode = mCollector.expectKeyValueNotNull("HotPixelMapMode", rawResult, CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
Point[] hotPixelMap = rawResult.get(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
Size pixelArraySize = mStaticInfo.getPixelArraySizeChecked();
boolean[] availableHotPixelMapModes = mStaticInfo.getValueFromKeyNonNull(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
if (hotPixelMode != null) {
Integer requestMode = mCollector.expectKeyValueNotNull(rawRequest, CaptureRequest.HOT_PIXEL_MODE);
if (requestMode != null) {
mCollector.expectKeyValueEquals(rawResult, CaptureResult.HOT_PIXEL_MODE, requestMode);
}
}
if (hotPixelMapMode != null) {
Boolean requestMapMode = mCollector.expectKeyValueNotNull(rawRequest, CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
if (requestMapMode != null) {
mCollector.expectKeyValueEquals(rawResult, CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE, requestMapMode);
}
if (!hotPixelMapMode) {
mCollector.expectTrue("HotPixelMap must be empty", hotPixelMap == null || hotPixelMap.length == 0);
} else {
mCollector.expectTrue("HotPixelMap must not be empty", hotPixelMap != null);
mCollector.expectNotNull("AvailableHotPixelMapModes must not be null", availableHotPixelMapModes);
if (availableHotPixelMapModes != null) {
mCollector.expectContains("HotPixelMapMode", availableHotPixelMapModes, true);
}
int height = pixelArraySize.getHeight();
int width = pixelArraySize.getWidth();
for (Point p : hotPixelMap) {
mCollector.expectTrue("Hotpixel " + p + " must be in pixelArray " + pixelArraySize, p.x >= 0 && p.x < width && p.y >= 0 && p.y < height);
}
}
}
// TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
}
Aggregations