001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.imaging.formats.tiff;
018
019/**
020 * Collects and stores a set of simple statistics from the input raster.
021 */
022public class TiffRasterStatistics {
023
024    private final int nSample;
025    private final int nNull;
026    private final float minValue;
027    private final float maxValue;
028    private final float meanValue;
029    private final float excludedValue;
030
031    /**
032     * Constructs an instance of this class, tabulating results from the input raster data.
033     *
034     * @param raster        the input data
035     * @param excludedValue an optional value to ignore; use Float.NaN if no value is to be ignored.
036     */
037    TiffRasterStatistics(final TiffRasterData raster, final float excludedValue) {
038        this.excludedValue = excludedValue;
039        float vMin = Float.POSITIVE_INFINITY;
040        float vMax = Float.NEGATIVE_INFINITY;
041        double vSum = 0;
042        int nS = 0;
043        int nN = 0;
044        final float[] data = raster.getData();
045        for (final float test : data) {
046            if (Float.isNaN(test)) {
047                nN++;
048                continue;
049            }
050            if (test == excludedValue) {
051                continue;
052            }
053
054            nS++;
055            vSum += test;
056            if (test < vMin) {
057                vMin = test;
058            }
059            if (test > vMax) {
060                vMax = test;
061            }
062        }
063
064        minValue = vMin;
065        maxValue = vMax;
066        nSample = nS;
067        nNull = nN;
068        if (nSample == 0) {
069            meanValue = 0;
070        } else {
071            meanValue = (float) (vSum / nSample);
072        }
073    }
074
075    /**
076     * Gets the count of the number of null samples in the collection.
077     *
078     * @return the a positive number, potentially zero
079     */
080    public int getCountOfNulls() {
081        return nNull;
082    }
083
084    /**
085     * Gets the count of the number of non-null and non-excluded samples in the collection.
086     *
087     * @return the a positive number, potentially zero
088     */
089    public int getCountOfSamples() {
090        return nSample;
091    }
092
093    /**
094     * Gets the value that was set for exclusion, or a Float&#46;NaN if not was set.
095     *
096     * @return the excluded value (if any).
097     */
098    public float getExcludedValue() {
099        return excludedValue;
100    }
101
102    /**
103     * Gets the maximum value found in the source data
104     *
105     * @return the maximum value found in the source data
106     */
107    public float getMaxValue() {
108        return maxValue;
109    }
110
111    /**
112     * Gets the mean value for all sample values in the raster. Null-data values and excluded values are not considered.
113     *
114     * @return the mean value of the samples
115     */
116    public float getMeanValue() {
117        return meanValue;
118    }
119
120    /**
121     * Gets the minimum value found in the source data
122     *
123     * @return the minimum value found in the source data
124     */
125    public float getMinValue() {
126        return minValue;
127    }
128
129    /**
130     * Indicates if a sample value was set to be deliberately excluded from the statistics.
131     *
132     * @return true if a value was set for exclusion; otherwise, false
133     */
134    public boolean isAnExcludedValueSet() {
135        return !Float.isNaN(excludedValue);
136    }
137}