| /* |
| * 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 static com.android.internal.util.Preconditions.*; |
| |
| /** |
| * Immutable class to store a 4-element vector of floats indexable by a bayer RAW 2x2 pixel block. |
| */ |
| public final class RggbChannelVector { |
| /** |
| * The number of color channels in this vector. |
| */ |
| public static final int COUNT = 4; |
| |
| /** Red color channel in a bayer Raw pattern. */ |
| public static final int RED = 0; |
| |
| /** Green color channel in a bayer Raw pattern used by the even rows. */ |
| public static final int GREEN_EVEN = 1; |
| |
| /** Green color channel in a bayer Raw pattern used by the odd rows. */ |
| public static final int GREEN_ODD = 2; |
| |
| /** Blue color channel in a bayer Raw pattern. */ |
| public static final int BLUE = 3; |
| |
| /** |
| * Create a new {@link RggbChannelVector} from an RGGB 2x2 pixel. |
| * |
| * <p>All pixel values are considered normalized within {@code [0.0f, 1.0f]} |
| * (i.e. {@code 1.0f} could be linearized to {@code 255} if converting to a |
| * non-floating point pixel representation).</p> |
| * |
| * <p>All arguments must be finite; NaN and infinity is not allowed.</p> |
| * |
| * @param red red pixel |
| * @param greenEven green pixel (even row) |
| * @param greenOdd green pixel (odd row) |
| * @param blue blue pixel |
| * |
| * @throws IllegalArgumentException if any of the arguments were not finite |
| */ |
| public RggbChannelVector(final float red, final float greenEven, final float greenOdd, |
| final float blue) { |
| mRed = checkArgumentFinite(red, "red"); |
| mGreenEven = checkArgumentFinite(greenEven, "greenEven"); |
| mGreenOdd = checkArgumentFinite(greenOdd, "greenOdd"); |
| mBlue = checkArgumentFinite(blue, "blue"); |
| } |
| |
| /** |
| * Get the red component. |
| * |
| * @return a floating point value (guaranteed to be finite) |
| */ |
| public final float getRed() { |
| return mRed; |
| } |
| |
| /** |
| * Get the green (even rows) component. |
| * |
| * @return a floating point value (guaranteed to be finite) |
| */ |
| public float getGreenEven() { |
| return mGreenEven; |
| } |
| |
| /** |
| * Get the green (odd rows) component. |
| * |
| * @return a floating point value (guaranteed to be finite) |
| */ |
| public float getGreenOdd() { |
| return mGreenOdd; |
| } |
| |
| /** |
| * Get the blue component. |
| * |
| * @return a floating point value (guaranteed to be finite) |
| */ |
| public float getBlue() { |
| return mBlue; |
| } |
| |
| /** |
| * Get the component by the color channel index. |
| * |
| * <p>{@code colorChannel} must be one of {@link #RED}, {@link #GREEN_EVEN}, {@link #GREEN_ODD}, |
| * {@link #BLUE}.</p> |
| * |
| * @param colorChannel greater or equal to {@code 0} and less than {@link #COUNT} |
| * @return a floating point value (guaranteed to be finite) |
| * |
| * @throws IllegalArgumentException if {@code colorChannel} was out of range |
| */ |
| public float getComponent(final int colorChannel) { |
| if (colorChannel < 0 || colorChannel >= COUNT) { |
| throw new IllegalArgumentException("Color channel out of range"); |
| } |
| |
| switch (colorChannel) { |
| case RED: |
| return mRed; |
| case GREEN_EVEN: |
| return mGreenEven; |
| case GREEN_ODD: |
| return mGreenOdd; |
| case BLUE: |
| return mBlue; |
| default: |
| throw new AssertionError("Unhandled case " + colorChannel); |
| } |
| } |
| |
| /** |
| * Copy the vector into the destination in the order {@code [R, Geven, Godd, B]}. |
| * |
| * @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 NullPointerException |
| * If {@code destination} was {@code null} |
| * @throws ArrayIndexOutOfBoundsException |
| * If there's not enough room to write the elements at the specified destination and |
| * offset. |
| */ |
| public void copyTo(final float[] destination, final int offset) { |
| checkNotNull(destination, "destination must not be null"); |
| if (destination.length - offset < COUNT) { |
| throw new ArrayIndexOutOfBoundsException("destination too small to fit elements"); |
| } |
| |
| destination[offset + RED] = mRed; |
| destination[offset + GREEN_EVEN] = mGreenEven; |
| destination[offset + GREEN_ODD] = mGreenOdd; |
| destination[offset + BLUE] = mBlue; |
| } |
| |
| /** |
| * Check if this {@link RggbChannelVector} is equal to another {@link RggbChannelVector}. |
| * |
| * <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(final Object obj) { |
| if (obj == null) { |
| return false; |
| } else if (this == obj) { |
| return true; |
| } else if (obj instanceof RggbChannelVector) { |
| final RggbChannelVector other = (RggbChannelVector) obj; |
| return mRed == other.mRed && |
| mGreenEven == other.mGreenEven && |
| mGreenOdd == other.mGreenOdd && |
| mBlue == other.mBlue; |
| } |
| return false; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public int hashCode() { |
| return Float.floatToIntBits(mRed) ^ |
| Float.floatToIntBits(mGreenEven) ^ |
| Float.floatToIntBits(mGreenOdd) ^ |
| Float.floatToIntBits(mBlue); |
| } |
| |
| /** |
| * Return the RggbChannelVector as a string representation. |
| * |
| * <p> {@code "RggbChannelVector{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each |
| * {@code %f} respectively represents one of the the four color channels. </p> |
| * |
| * @return string representation of {@link RggbChannelVector} |
| */ |
| @Override |
| public String toString() { |
| return String.format("RggbChannelVector%s", toShortString()); |
| } |
| |
| /** |
| * Return the RggbChannelVector as a string in compact form. |
| * |
| * <p> {@code "{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each {@code %f} |
| * respectively represents one of the the four color channels. </p> |
| * |
| * @return compact string representation of {@link RggbChannelVector} |
| */ |
| private String toShortString() { |
| return String.format("{R:%f, G_even:%f, G_odd:%f, B:%f}", |
| mRed, mGreenEven, mGreenOdd, mBlue); |
| } |
| |
| private final float mRed; |
| private final float mGreenEven; |
| private final float mGreenOdd; |
| private final float mBlue; |
| } |