163 lines
6.0 KiB
Java
163 lines
6.0 KiB
Java
/*
|
|
* 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.params;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* Immutable class to store a 4-element vector of integers corresponding to a 2x2 pattern
|
|
* of color channel offsets used for the black level offsets of each color channel.
|
|
*
|
|
* For a camera device with
|
|
* {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
|
|
* MONOCHROME} capability, all 4 elements of the pattern will have the same value.
|
|
*/
|
|
public final class BlackLevelPattern {
|
|
|
|
/**
|
|
* The number of offsets in this vector.
|
|
*/
|
|
public static final int COUNT = 4;
|
|
|
|
/**
|
|
* Create a new {@link BlackLevelPattern} from a given offset array.
|
|
*
|
|
* <p>The given offset array must contain offsets for each color channel in
|
|
* a 2x2 pattern corresponding to the color filter arrangement. Offsets are
|
|
* given in row-column scan order.</p>
|
|
*
|
|
* <p>This constructor is public to allow for easier application testing by
|
|
* creating custom object instances. It's not necessary to construct these
|
|
* objects during normal use of the camera API.</p>
|
|
*
|
|
* @param offsets an array containing a 2x2 pattern of offsets.
|
|
*
|
|
* @throws IllegalArgumentException if the given array has an incorrect length.
|
|
* @throws NullPointerException if the given array is null.
|
|
*/
|
|
public BlackLevelPattern(@NonNull int[] offsets) {
|
|
if (offsets == null) {
|
|
throw new NullPointerException("Null offsets array passed to constructor");
|
|
}
|
|
if (offsets.length < COUNT) {
|
|
throw new IllegalArgumentException("Invalid offsets array length");
|
|
}
|
|
mCfaOffsets = Arrays.copyOf(offsets, COUNT);
|
|
}
|
|
|
|
/**
|
|
* Return the color channel offset for a given index into the array of raw pixel values.
|
|
*
|
|
* @param column the column index in the the raw pixel array.
|
|
* @param row the row index in the raw pixel array.
|
|
* @return a color channel offset.
|
|
*
|
|
* @throws IllegalArgumentException if a column or row given is negative.
|
|
*/
|
|
public int getOffsetForIndex(int column, int row) {
|
|
if (row < 0 || column < 0) {
|
|
throw new IllegalArgumentException("column, row arguments must be positive");
|
|
}
|
|
return mCfaOffsets[((row & 1) << 1) | (column & 1)];
|
|
}
|
|
|
|
/**
|
|
* Copy the ColorChannel offsets into the destination vector.
|
|
*
|
|
* <p>Offsets are given in row-column scan order for a given 2x2 color pattern.</p>
|
|
*
|
|
* @param destination an array big enough to hold at least {@value #COUNT} elements after the
|
|
* {@code offset}
|
|
* @param offset a non-negative offset into the array
|
|
*
|
|
* @throws IllegalArgumentException if the offset is invalid.
|
|
* @throws ArrayIndexOutOfBoundsException if the destination vector is too small.
|
|
* @throws NullPointerException if the destination is null.
|
|
*/
|
|
public void copyTo(int[] destination, int offset) {
|
|
Objects.requireNonNull(destination, "destination must not be null");
|
|
if (offset < 0) {
|
|
throw new IllegalArgumentException("Null offset passed to copyTo");
|
|
}
|
|
if (destination.length - offset < COUNT) {
|
|
throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
|
|
}
|
|
for (int i = 0; i < COUNT; ++i) {
|
|
destination[offset + i] = mCfaOffsets[i];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if this {@link BlackLevelPattern} is equal to another {@link BlackLevelPattern}.
|
|
*
|
|
* <p>Two vectors are only equal if and only if each of the respective elements is equal.</p>
|
|
*
|
|
* @return {@code true} if the objects were equal, {@code false} otherwise
|
|
*/
|
|
@Override
|
|
public boolean equals(@Nullable Object obj) {
|
|
if (obj == null) {
|
|
return false;
|
|
} else if (this == obj) {
|
|
return true;
|
|
} else if (obj instanceof BlackLevelPattern) {
|
|
final BlackLevelPattern other = (BlackLevelPattern) obj;
|
|
return Arrays.equals(other.mCfaOffsets, mCfaOffsets);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public int hashCode() {
|
|
return Arrays.hashCode(mCfaOffsets);
|
|
}
|
|
|
|
/**
|
|
* Return this {@link BlackLevelPattern} as a string representation.
|
|
*
|
|
* <p> {@code "BlackLevelPattern([%d, %d], [%d, %d])"}, where each {@code %d} represents one
|
|
* black level offset of a color channel. The values are in the same order as channels listed
|
|
* for the CFA layout key (see
|
|
* {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}).
|
|
* </p>
|
|
*
|
|
* <p>A {@link
|
|
* android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
|
|
* MONOCHROME} camera only has one channel. As a result, the returned string will contain 4
|
|
* identical values.
|
|
* </p>
|
|
*
|
|
* @return string representation of {@link BlackLevelPattern}
|
|
*
|
|
* @see android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
return String.format("BlackLevelPattern([%d, %d], [%d, %d])", mCfaOffsets[0],
|
|
mCfaOffsets[1], mCfaOffsets[2], mCfaOffsets[3]);
|
|
}
|
|
|
|
private final int[] mCfaOffsets;
|
|
}
|