Home | History | Annotate | Download | only in params
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware.camera2.params;
     18 
     19 import static com.android.internal.util.Preconditions.*;
     20 
     21 /**
     22  * Immutable class to store a 4-element vector of floats indexable by a bayer RAW 2x2 pixel block.
     23  */
     24 public final class RggbChannelVector {
     25     /**
     26      * The number of color channels in this vector.
     27      */
     28     public static final int COUNT = 4;
     29 
     30     /** Red color channel in a bayer Raw pattern. */
     31     public static final int RED = 0;
     32 
     33     /** Green color channel in a bayer Raw pattern used by the even rows. */
     34     public static final int GREEN_EVEN = 1;
     35 
     36     /** Green color channel in a bayer Raw pattern used by the odd rows. */
     37     public static final int GREEN_ODD = 2;
     38 
     39     /** Blue color channel in a bayer Raw pattern. */
     40     public static final int BLUE = 3;
     41 
     42     /**
     43      * Create a new {@link RggbChannelVector} from an RGGB 2x2 pixel.
     44      *
     45      * <p>All pixel values are considered normalized within {@code [0.0f, 1.0f]}
     46      * (i.e. {@code 1.0f} could be linearized to {@code 255} if converting to a
     47      * non-floating point pixel representation).</p>
     48      *
     49      * <p>All arguments must be finite; NaN and infinity is not allowed.</p>
     50      *
     51      * @param red red pixel
     52      * @param greenEven green pixel (even row)
     53      * @param greenOdd green pixel (odd row)
     54      * @param blue blue pixel
     55      *
     56      * @throws IllegalArgumentException if any of the arguments were not finite
     57      */
     58     public RggbChannelVector(final float red, final float greenEven, final float greenOdd,
     59             final float blue) {
     60         mRed = checkArgumentFinite(red, "red");
     61         mGreenEven = checkArgumentFinite(greenEven, "greenEven");
     62         mGreenOdd = checkArgumentFinite(greenOdd, "greenOdd");
     63         mBlue = checkArgumentFinite(blue, "blue");
     64     }
     65 
     66     /**
     67      * Get the red component.
     68      *
     69      * @return a floating point value (guaranteed to be finite)
     70      */
     71     public final float getRed() {
     72         return mRed;
     73     }
     74 
     75     /**
     76      * Get the green (even rows) component.
     77      *
     78      * @return a floating point value (guaranteed to be finite)
     79      */
     80     public float getGreenEven() {
     81         return mGreenEven;
     82     }
     83 
     84     /**
     85      * Get the green (odd rows) component.
     86      *
     87      * @return a floating point value (guaranteed to be finite)
     88      */
     89     public float getGreenOdd() {
     90         return mGreenOdd;
     91     }
     92 
     93     /**
     94      * Get the blue component.
     95      *
     96      * @return a floating point value (guaranteed to be finite)
     97      */
     98     public float getBlue() {
     99         return mBlue;
    100     }
    101 
    102     /**
    103      * Get the component by the color channel index.
    104      *
    105      * <p>{@code colorChannel} must be one of {@link #RED}, {@link #GREEN_EVEN}, {@link #GREEN_ODD},
    106      * {@link #BLUE}.</p>
    107      *
    108      * @param colorChannel greater or equal to {@code 0} and less than {@link #COUNT}
    109      * @return a floating point value (guaranteed to be finite)
    110      *
    111      * @throws IllegalArgumentException if {@code colorChannel} was out of range
    112      */
    113     public float getComponent(final int colorChannel) {
    114         if (colorChannel < 0 || colorChannel >= COUNT) {
    115             throw new IllegalArgumentException("Color channel out of range");
    116         }
    117 
    118         switch (colorChannel) {
    119             case RED:
    120                 return mRed;
    121             case GREEN_EVEN:
    122                 return mGreenEven;
    123             case GREEN_ODD:
    124                 return mGreenOdd;
    125             case BLUE:
    126                 return mBlue;
    127             default:
    128                 throw new AssertionError("Unhandled case " + colorChannel);
    129         }
    130     }
    131 
    132     /**
    133      * Copy the vector into the destination in the order {@code [R, Geven, Godd, B]}.
    134      *
    135      * @param destination
    136      *          an array big enough to hold at least {@value #COUNT} elements after the
    137      *          {@code offset}
    138      * @param offset
    139      *          a non-negative offset into the array
    140      *
    141      * @throws NullPointerException
    142      *          If {@code destination} was {@code null}
    143      * @throws ArrayIndexOutOfBoundsException
    144      *          If there's not enough room to write the elements at the specified destination and
    145      *          offset.
    146      */
    147     public void copyTo(final float[] destination, final int offset) {
    148         checkNotNull(destination, "destination must not be null");
    149         if (destination.length - offset < COUNT) {
    150             throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
    151         }
    152 
    153         destination[offset + RED] = mRed;
    154         destination[offset + GREEN_EVEN] = mGreenEven;
    155         destination[offset + GREEN_ODD] = mGreenOdd;
    156         destination[offset + BLUE] = mBlue;
    157     }
    158 
    159     /**
    160      * Check if this {@link RggbChannelVector} is equal to another {@link RggbChannelVector}.
    161      *
    162      * <p>Two vectors are only equal if and only if each of the respective elements is equal.</p>
    163      *
    164      * @return {@code true} if the objects were equal, {@code false} otherwise
    165      */
    166     @Override
    167     public boolean equals(final Object obj) {
    168         if (obj == null) {
    169             return false;
    170         } else if (this == obj) {
    171             return true;
    172         } else if (obj instanceof RggbChannelVector) {
    173             final RggbChannelVector other = (RggbChannelVector) obj;
    174             return mRed == other.mRed &&
    175                     mGreenEven == other.mGreenEven &&
    176                     mGreenOdd == other.mGreenOdd &&
    177                     mBlue == other.mBlue;
    178         }
    179         return false;
    180     }
    181 
    182     /**
    183      * {@inheritDoc}
    184      */
    185     @Override
    186     public int hashCode() {
    187         return Float.floatToIntBits(mRed) ^
    188                 Float.floatToIntBits(mGreenEven) ^
    189                 Float.floatToIntBits(mGreenOdd) ^
    190                 Float.floatToIntBits(mBlue);
    191     }
    192 
    193     /**
    194      * Return the RggbChannelVector as a string representation.
    195      *
    196      * <p> {@code "RggbChannelVector{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each
    197      * {@code %f} respectively represents one of the the four color channels. </p>
    198      *
    199      * @return string representation of {@link RggbChannelVector}
    200      */
    201     @Override
    202     public String toString() {
    203         return String.format("RggbChannelVector%s", toShortString());
    204     }
    205 
    206     /**
    207      * Return the RggbChannelVector as a string in compact form.
    208      *
    209      * <p> {@code "{R:%f, G_even:%f, G_odd:%f, B:%f}"}, where each {@code %f}
    210      * respectively represents one of the the four color channels. </p>
    211      *
    212      * @return compact string representation of {@link RggbChannelVector}
    213      */
    214     private String toShortString() {
    215         return String.format("{R:%f, G_even:%f, G_odd:%f, B:%f}",
    216                 mRed, mGreenEven, mGreenOdd, mBlue);
    217     }
    218 
    219     private final float mRed;
    220     private final float mGreenEven;
    221     private final float mGreenOdd;
    222     private final float mBlue;
    223 }
    224