194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin/*
294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Copyright (C) 2014 The Android Open Source Project
394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * you may not use this file except in compliance with the License.
694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * You may obtain a copy of the License at
794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
1094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Unless required by applicable law or agreed to in writing, software
1194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
1294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * See the License for the specific language governing permissions and
1494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * limitations under the License.
1594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin */
1694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
1772f9f0a96e4476ef231d5001cb30521ad4ce5b1eIgor Murashkinpackage android.hardware.camera2.params;
1894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
1994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkinimport static com.android.internal.util.Preconditions.*;
2094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
2194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin/**
2294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Immutable class to store a 4-element vector of floats indexable by a bayer RAW 2x2 pixel block.
2394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin */
2494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkinpublic final class RggbChannelVector {
2594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
2694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * The number of color channels in this vector.
2794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
2894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public static final int COUNT = 4;
2994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
3094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /** Red color channel in a bayer Raw pattern. */
3194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public static final int RED = 0;
3294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
3394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /** Green color channel in a bayer Raw pattern used by the even rows. */
3494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public static final int GREEN_EVEN = 1;
3594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
3694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /** Green color channel in a bayer Raw pattern used by the odd rows. */
3794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public static final int GREEN_ODD = 2;
3894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
3994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /** Blue color channel in a bayer Raw pattern. */
4094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public static final int BLUE = 3;
4194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
4294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
4394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Create a new {@link RggbChannelVector} from an RGGB 2x2 pixel.
4494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
4594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>All pixel values are considered normalized within {@code [0.0f, 1.0f]}
4694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * (i.e. {@code 1.0f} could be linearized to {@code 255} if converting to a
4794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * non-floating point pixel representation).</p>
4894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
4994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>All arguments must be finite; NaN and infinity is not allowed.</p>
5094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
5194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param red red pixel
5294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param greenEven green pixel (even row)
5394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param greenOdd green pixel (odd row)
5494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param blue blue pixel
5594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
5694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws IllegalArgumentException if any of the arguments were not finite
5794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
5894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public RggbChannelVector(final float red, final float greenEven, final float greenOdd,
5994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final float blue) {
6094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mRed = checkArgumentFinite(red, "red");
6194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mGreenEven = checkArgumentFinite(greenEven, "greenEven");
6294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mGreenOdd = checkArgumentFinite(greenOdd, "greenOdd");
6394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mBlue = checkArgumentFinite(blue, "blue");
6494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
6594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
6694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
6794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the red component.
6894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
6994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return a floating point value (guaranteed to be finite)
7094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
7194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public final float getRed() {
7294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return mRed;
7394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
7494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
7594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
7694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the green (even rows) component.
7794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
7894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return a floating point value (guaranteed to be finite)
7994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
8094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public float getGreenEven() {
8194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return mGreenEven;
8294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
8394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
8494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
8594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the green (odd rows) component.
8694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
8794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return a floating point value (guaranteed to be finite)
8894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
8994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public float getGreenOdd() {
9094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return mGreenOdd;
9194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
9294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
9394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
9494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the blue component.
9594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
9694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return a floating point value (guaranteed to be finite)
9794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
9894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public float getBlue() {
9994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return mBlue;
10094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
10194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
10294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
10394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the component by the color channel index.
10494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
10594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>{@code colorChannel} must be one of {@link #RED}, {@link #GREEN_EVEN}, {@link #GREEN_ODD},
10694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * {@link #BLUE}.</p>
10794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
10894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param colorChannel greater or equal to {@code 0} and less than {@link #COUNT}
10994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return a floating point value (guaranteed to be finite)
11094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
11194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws IllegalArgumentException if {@code colorChannel} was out of range
11294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
11394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public float getComponent(final int colorChannel) {
11494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        if (colorChannel < 0 || colorChannel >= COUNT) {
11594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            throw new IllegalArgumentException("Color channel out of range");
11694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
11794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
11894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        switch (colorChannel) {
11994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            case RED:
12094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                return mRed;
12194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            case GREEN_EVEN:
12294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                return mGreenEven;
12394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            case GREEN_ODD:
12494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                return mGreenOdd;
12594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            case BLUE:
12694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                return mBlue;
12794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            default:
12894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                throw new AssertionError("Unhandled case " + colorChannel);
12994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
13094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
13194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
13294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
13394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Copy the vector into the destination in the order {@code [R, Geven, Godd, B]}.
13494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
13594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param destination
13694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          an array big enough to hold at least {@value #COUNT} elements after the
13794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          {@code offset}
13894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param offset
13994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          a non-negative offset into the array
14094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
14194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws NullPointerException
14294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          If {@code destination} was {@code null}
14394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws ArrayIndexOutOfBoundsException
14494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          If there's not enough room to write the elements at the specified destination and
14594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *          offset.
14694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
14794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public void copyTo(final float[] destination, final int offset) {
14894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        checkNotNull(destination, "destination must not be null");
14952842e7a6f0e922185db04ae8b91c776a234acf1Ruben Brunk        if (destination.length - offset < COUNT) {
15094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
15194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
15294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
15394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        destination[offset + RED] = mRed;
15494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        destination[offset + GREEN_EVEN] = mGreenEven;
15594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        destination[offset + GREEN_ODD] = mGreenOdd;
15694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        destination[offset + BLUE] = mBlue;
15794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
15894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
15994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
16094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Check if this {@link RggbChannelVector} is equal to another {@link RggbChannelVector}.
16194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
16294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>Two vectors are only equal if and only if each of the respective elements is equal.</p>
16394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
16494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return {@code true} if the objects were equal, {@code false} otherwise
16594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
16694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    @Override
16794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public boolean equals(final Object obj) {
16894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        if (obj == null) {
16994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return false;
17052842e7a6f0e922185db04ae8b91c776a234acf1Ruben Brunk        } else if (this == obj) {
17194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return true;
17252842e7a6f0e922185db04ae8b91c776a234acf1Ruben Brunk        } else if (obj instanceof RggbChannelVector) {
17394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final RggbChannelVector other = (RggbChannelVector) obj;
17494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return mRed == other.mRed &&
17594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    mGreenEven == other.mGreenEven &&
17694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    mGreenOdd == other.mGreenOdd &&
17794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    mBlue == other.mBlue;
17894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
17994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return false;
18094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
18194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
18294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
18394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * {@inheritDoc}
18494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
18594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    @Override
18694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public int hashCode() {
18794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return Float.floatToIntBits(mRed) ^
18894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                Float.floatToIntBits(mGreenEven) ^
18994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                Float.floatToIntBits(mGreenOdd) ^
19094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                Float.floatToIntBits(mBlue);
19194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
19294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
19397376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    /**
19497376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * Return the RggbChannelVector as a string representation.
19597376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     *
19697376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * <p> {@code "RggbChannelVector{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each
19797376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * {@code %f} respectively represents one of the the four color channels. </p>
19897376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     *
19997376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * @return string representation of {@link RggbChannelVector}
20097376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     */
20197376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    @Override
20297376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    public String toString() {
20397376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh        return String.format("RggbChannelVector%s", toShortString());
20497376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    }
20597376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh
20697376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    /**
20797376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * Return the RggbChannelVector as a string in compact form.
20897376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     *
20997376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * <p> {@code "{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each {@code %f}
21097376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * respectively represents one of the the four color channels. </p>
21197376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     *
21297376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     * @return compact string representation of {@link RggbChannelVector}
21397376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh     */
21497376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    private String toShortString() {
21597376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh        return String.format("{R:%f, G_even:%f, G_odd:%f, B:%f}",
21697376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh                mRed, mGreenEven, mGreenOdd, mBlue);
21797376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh    }
21897376d90d660254a934fab7708198d53f03fe2e4Yin-Chia Yeh
21994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final float mRed;
22094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final float mGreenEven;
22194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final float mGreenOdd;
22294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final float mBlue;
22394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin}
224