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
179c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinpackage android.hardware.camera2.params;
1894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
1994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkinimport static com.android.internal.util.Preconditions.*;
2094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
219c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkinimport android.hardware.camera2.CameraCharacteristics;
223c40a046cf0ea7b6af01ec93e5276eccb3234bfeIgor Murashkinimport android.hardware.camera2.utils.HashCodeHelpers;
2394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
2494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkinimport java.util.Arrays;
2594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
2694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin/**
2794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Immutable class to store the input to output formats
2894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * {@link CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP map} to be used for with
2994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * camera image reprocessing.
3094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
3194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * <p>
3294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * The mapping of image formats that are supported by this camera device for input streams,
3394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * to their corresponding output formats.</p>
3494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
3594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * <p>
3694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * Attempting to configure an input stream with output streams not listed as available in this map
3794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * is not valid.
3894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * </p>
3994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
4094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * @see CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP
4194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
4294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin *
4394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * <!-- hide this until we expose input streams through public API -->
4494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin * @hide
4594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin */
4694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkinpublic final class ReprocessFormatsMap {
4794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
4894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Create a new {@link ReprocessFormatsMap}
4994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
5094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>This value is encoded as a variable-size array-of-arrays.
5194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * The inner array always contains {@code [format, length, ...]} where ... has length elements.
5294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * An inner array is followed by another inner array if the total metadata entry size hasn't
5394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * yet been exceeded.</p>
5494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
5594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>Entry must not be {@code null}. Empty array is acceptable.</p>
5694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
5794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>The entry array ownership is passed to this instance after construction; do not
5894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * write to it afterwards.</p>
5994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
6094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param entry Array of ints, not yet deserialized (not-null)
6194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
6294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws IllegalArgumentException
6394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *              if the data was poorly formatted
6494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *              (missing output format length or too few output formats)
659c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin     *              or if any of the input/formats were not valid
6694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @throws NullPointerException
6794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *              if entry was null
6894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
699c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin     * @see StreamConfigurationMap#checkArgumentFormatInternal
709c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin     *
7194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @hide
7294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
7394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public ReprocessFormatsMap(final int[] entry) {
7494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        checkNotNull(entry, "entry must not be null");
7594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
7694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        int numInputs = 0;
7794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        int left = entry.length;
7894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        for (int i = 0; i < entry.length; ) {
799c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin            int inputFormat = StreamConfigurationMap.checkArgumentFormatInternal(entry[i]);
8094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
8194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
8294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
8394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
8494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (left < 1) {
8594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                throw new IllegalArgumentException(
869c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                        String.format("Input %x had no output format length listed", inputFormat));
8794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
8894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
8994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final int length = entry[i];
9094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
9194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
9294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
939c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin            for (int j = 0; j < length; ++j) {
949c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                int outputFormat = entry[i + j];
959c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                StreamConfigurationMap.checkArgumentFormatInternal(outputFormat);
969c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin            }
979c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin
9894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (length > 0) {
9994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                if (left < length) {
10094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    throw new IllegalArgumentException(
10194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                            String.format(
10294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                                    "Input %x had too few output formats listed (actual: %d, " +
1039c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                                    "expected: %d)", inputFormat, left, length));
10494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                }
10594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
10694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                i += length;
10794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                left -= length;
10894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
10994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
11094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            numInputs++;
11194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
11294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
11394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mEntry = entry;
11494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        mInputCount = numInputs;
11594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
11694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
11794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
11894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get a list of all input image formats that can be used to reprocess an input
11994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * stream into an output stream.
12094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
12194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>Use this input format to look up the available output formats with {@link #getOutputs}.
12294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * </p>
12394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
12494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return an array of inputs (possibly empty, but never {@code null})
12594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
12694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @see ImageFormat
12794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @see #getOutputs
12894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
12994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public int[] getInputs() {
13094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        final int[] inputs = new int[mInputCount];
13194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
13294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        int left = mEntry.length;
13394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        for (int i = 0, j = 0; i < mEntry.length; j++) {
13494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final int format = mEntry[i];
13594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
13694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
13794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
13894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
13994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (left < 1) {
14094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                throw new AssertionError(
14194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                        String.format("Input %x had no output format length listed", format));
14294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
14394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
14494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final int length = mEntry[i];
14594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
14694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
14794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
14894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (length > 0) {
14994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                if (left < length) {
15094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    throw new AssertionError(
15194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                            String.format(
15294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                                    "Input %x had too few output formats listed (actual: %d, " +
15394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                                    "expected: %d)", format, left, length));
15494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                }
15594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
15694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                i += length;
15794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                left -= length;
15894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
15994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
16094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            inputs[j] = format;
16194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
16294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
1639c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin        return StreamConfigurationMap.imageFormatToPublic(inputs);
16494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
16594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
16694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
16794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Get the list of output formats that can be reprocessed into from the input {@code format}.
16894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
16994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>The input {@code format} must be one of the formats returned by {@link #getInputs}.</p>
17094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
17194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @param format an input format
17294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
17394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return list of output image formats
17494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
17594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @see ImageFormat
17694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @see #getInputs
17794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
17894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public int[] getOutputs(final int format) {
17994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
18094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        int left = mEntry.length;
18194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        for (int i = 0; i < mEntry.length; ) {
18294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final int inputFormat = mEntry[i];
18394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
18494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
18594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
18694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
18794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (left < 1) {
18894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                throw new AssertionError(
18994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                        String.format("Input %x had no output format length listed", format));
19094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
19194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
19294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final int length = mEntry[i];
19394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left--;
19494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i++;
19594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
19694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (length > 0) {
19794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                if (left < length) {
19894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    throw new AssertionError(
19994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                            String.format(
20094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                                    "Input %x had too few output formats listed (actual: %d, " +
20194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                                    "expected: %d)", format, left, length));
20294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                }
20394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
20494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
20594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            if (inputFormat == format) {
20694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                int[] outputs = new int[length];
20794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
20894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                // Copying manually faster than System.arraycopy for small arrays
20994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                for (int k = 0; k < length; ++k) {
21094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                    outputs[k] = mEntry[i + k];
21194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                }
21294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
2139c595174ccaaf3d36315c4a100e47ee4369073f6Igor Murashkin                return StreamConfigurationMap.imageFormatToPublic(outputs);
21494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            }
21594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
21694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            i += length;
21794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            left -= length;
21894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
21994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
22094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
22194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        throw new IllegalArgumentException(
22294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin                String.format("Input format %x was not one in #getInputs", format));
22394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
22494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
22594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
22694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Check if this {@link ReprocessFormatsMap} is equal to another
22794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * {@link ReprocessFormatsMap}.
22894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
22994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * <p>These two objects are only equal if and only if each of the respective elements is equal.
23094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * </p>
23194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     *
23294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * @return {@code true} if the objects were equal, {@code false} otherwise
23394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
23494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    @Override
23594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public boolean equals(final Object obj) {
23694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        if (obj == null) {
23794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return false;
23894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
23994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        if (this == obj) {
24094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return true;
24194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
24294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        if (obj instanceof ReprocessFormatsMap) {
24394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            final ReprocessFormatsMap other = (ReprocessFormatsMap) obj;
24494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            // Do not compare anything besides mEntry, since the rest of the values are derived
24594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin            return Arrays.equals(mEntry, other.mEntry);
24694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        }
24794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return false;
24894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
24994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
25094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /**
25194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * {@inheritDoc}
25294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
25394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    @Override
25494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    public int hashCode() {
25594814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        // Do not hash anything besides mEntry since the rest of the values are derived
25694814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin        return HashCodeHelpers.hashCode(mEntry);
25794814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    }
25894814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin
25994814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final int[] mEntry;
26094814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    /*
26194814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     * Dependent fields: values are derived from mEntry
26294814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin     */
26394814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin    private final int mInputCount;
26494814218d2313a989a5a8969f633e3fc33e43071Igor Murashkin}
265