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 java.util.Arrays;
     20 
     21 import static com.android.internal.util.Preconditions.checkNotNull;
     22 
     23 /**
     24  * Immutable class to store a 4-element vector of integers corresponding to a 2x2 pattern
     25  * of color channel offsets used for the black level offsets of each color channel.
     26  */
     27 public final class BlackLevelPattern {
     28 
     29     /**
     30      * The number of offsets in this vector.
     31      */
     32     public static final int COUNT = 4;
     33 
     34     /**
     35      * Create a new {@link BlackLevelPattern} from a given offset array.
     36      *
     37      * <p>The given offset array must contain offsets for each color channel in
     38      * a 2x2 pattern corresponding to the color filter arrangement.  Offsets are
     39      * given in row-column scan order.</p>
     40      *
     41      * @param offsets an array containing a 2x2 pattern of offsets.
     42      *
     43      * @throws IllegalArgumentException if the given array has an incorrect length.
     44      * @throws NullPointerException if the given array is null.
     45      * @hide
     46      */
     47     public BlackLevelPattern(int[] offsets) {
     48         if (offsets == null) {
     49             throw new NullPointerException("Null offsets array passed to constructor");
     50         }
     51         if (offsets.length < COUNT) {
     52             throw new IllegalArgumentException("Invalid offsets array length");
     53         }
     54         mCfaOffsets = Arrays.copyOf(offsets, COUNT);
     55     }
     56 
     57     /**
     58      * Return the color channel offset for a given index into the array of raw pixel values.
     59      *
     60      * @param column the column index in the the raw pixel array.
     61      * @param row the row index in the raw pixel array.
     62      * @return a color channel offset.
     63      *
     64      * @throws IllegalArgumentException if a column or row given is negative.
     65      */
     66     public int getOffsetForIndex(int column, int row) {
     67         if (row < 0 || column < 0) {
     68             throw new IllegalArgumentException("column, row arguments must be positive");
     69         }
     70         return mCfaOffsets[((row & 1) << 1) | (column & 1)];
     71     }
     72 
     73     /**
     74      * Copy the ColorChannel offsets into the destination vector.
     75      *
     76      * <p>Offsets are given in row-column scan order for a given 2x2 color pattern.</p>
     77      *
     78      * @param destination an array big enough to hold at least {@value #COUNT} elements after the
     79      *          {@code offset}
     80      * @param offset a non-negative offset into the array
     81      *
     82      * @throws IllegalArgumentException if the offset is invalid.
     83      * @throws ArrayIndexOutOfBoundsException if the destination vector is too small.
     84      * @throws NullPointerException if the destination is null.
     85      */
     86     public void copyTo(int[] destination, int offset) {
     87         checkNotNull(destination, "destination must not be null");
     88         if (offset < 0) {
     89             throw new IllegalArgumentException("Null offset passed to copyTo");
     90         }
     91         if (destination.length - offset < COUNT) {
     92             throw new ArrayIndexOutOfBoundsException("destination too small to fit elements");
     93         }
     94         for (int i = 0; i < COUNT; ++i) {
     95             destination[offset + i] = mCfaOffsets[i];
     96         }
     97     }
     98 
     99     /**
    100      * Check if this {@link BlackLevelPattern} is equal to another {@link BlackLevelPattern}.
    101      *
    102      * <p>Two vectors are only equal if and only if each of the respective elements is equal.</p>
    103      *
    104      * @return {@code true} if the objects were equal, {@code false} otherwise
    105      */
    106     @Override
    107     public boolean equals(Object obj) {
    108         if (obj == null) {
    109             return false;
    110         } else if (this == obj) {
    111             return true;
    112         } else if (obj instanceof BlackLevelPattern) {
    113             final BlackLevelPattern other = (BlackLevelPattern) obj;
    114             return Arrays.equals(other.mCfaOffsets, mCfaOffsets);
    115         }
    116         return false;
    117     }
    118 
    119     /**
    120      * {@inheritDoc}
    121      */
    122     @Override
    123     public int hashCode() {
    124         return Arrays.hashCode(mCfaOffsets);
    125     }
    126 
    127     /**
    128      * Return this {@link BlackLevelPattern} as a string representation.
    129      *
    130      * <p> {@code "BlackLevelPattern([%d, %d], [%d, %d])"}, where each {@code %d} represents one
    131      * black level offset of a color channel. The values are in the same order as channels listed
    132      * for the CFA layout key (see
    133      * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}).
    134      * </p>
    135      *
    136      * @return string representation of {@link BlackLevelPattern}
    137      *
    138      * @see android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
    139      */
    140     @Override
    141     public String toString() {
    142         return String.format("BlackLevelPattern([%d, %d], [%d, %d])", mCfaOffsets[0],
    143                 mCfaOffsets[1], mCfaOffsets[2], mCfaOffsets[3]);
    144     }
    145 
    146     private final int[] mCfaOffsets;
    147 }
    148