001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/* 020* 021 022Licensed under the Apache License, Version 2.0 (the "License"); 023you may not use this file except in compliance with the License. 024You may obtain a copy of the License at 025 026 http://www.apache.org/licenses/LICENSE-2.0 027 028Unless required by applicable law or agreed to in writing, software 029distributed under the License is distributed on an "AS IS" BASIS, 030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 031See the License for the specific language governing permissions and 032limitations under the License. 033*/ 034 035package lucee.runtime.img.filter; 036 037/** 038 * An image histogram. 039 */ 040public class Histogram { 041 042 public static final int RED = 0; 043 public static final int GREEN = 1; 044 public static final int BLUE = 2; 045 public static final int GRAY = 3; 046 047 protected int[][] histogram; 048 protected int numSamples; 049 protected int[] minValue; 050 protected int[] maxValue; 051 protected int[] minFrequency; 052 protected int[] maxFrequency; 053 protected float[] mean; 054 protected boolean isGray; 055 056 public Histogram() { 057 histogram = null; 058 numSamples = 0; 059 isGray = true; 060 minValue = null; 061 maxValue = null; 062 minFrequency = null; 063 maxFrequency = null; 064 mean = null; 065 } 066 067 public Histogram(int[] pixels, int w, int h, int offset, int stride) { 068 histogram = new int[3][256]; 069 minValue = new int[4]; 070 maxValue = new int[4]; 071 minFrequency = new int[3]; 072 maxFrequency = new int[3]; 073 mean = new float[3]; 074 075 numSamples = w*h; 076 isGray = true; 077 078 int index = 0; 079 for (int y = 0; y < h; y++) { 080 index = offset+y*stride; 081 for (int x = 0; x < w; x++) { 082 int rgb = pixels[index++]; 083 int r = (rgb >> 16) & 0xff; 084 int g = (rgb >> 8) & 0xff; 085 int b = rgb & 0xff; 086 histogram[RED][r]++; 087 histogram[GREEN][g]++; 088 histogram[BLUE][b]++; 089 } 090 } 091 092 for (int i = 0; i < 256; i++) { 093 if (histogram[RED][i] != histogram[GREEN][i] || histogram[GREEN][i] != histogram[BLUE][i]) { 094 isGray = false; 095 break; 096 } 097 } 098 099 for (int i = 0; i < 3; i++) { 100 for (int j = 0; j < 256; j++) { 101 if (histogram[i][j] > 0) { 102 minValue[i] = j; 103 break; 104 } 105 } 106 107 for (int j = 255; j >= 0; j--) { 108 if (histogram[i][j] > 0) { 109 maxValue[i] = j; 110 break; 111 } 112 } 113 114 minFrequency[i] = Integer.MAX_VALUE; 115 maxFrequency[i] = 0; 116 for (int j = 0; j < 256; j++) { 117 minFrequency[i] = Math.min(minFrequency[i], histogram[i][j]); 118 maxFrequency[i] = Math.max(maxFrequency[i], histogram[i][j]); 119 mean[i] += (j*histogram[i][j]); 120 } 121 mean[i] /= numSamples; 122 } 123 minValue[GRAY] = Math.min(Math.min(minValue[RED], minValue[GREEN]), minValue[BLUE]); 124 maxValue[GRAY] = Math.max(Math.max(maxValue[RED], maxValue[GREEN]), maxValue[BLUE]); 125 } 126 127 public boolean isGray() { 128 return isGray; 129 } 130 131 public int getNumSamples() { 132 return numSamples; 133 } 134 135 public int getFrequency(int value) { 136 if (numSamples > 0 && isGray && value >= 0 && value <= 255) 137 return histogram[0][value]; 138 return -1; 139 } 140 141 public int getFrequency(int channel, int value) { 142 if (numSamples < 1 || channel < 0 || channel > 2 || 143 value < 0 || value > 255) 144 return -1; 145 return histogram[channel][value]; 146 } 147 148 public int getMinFrequency() { 149 if (numSamples > 0 && isGray) 150 return minFrequency[0]; 151 return -1; 152 } 153 154 public int getMinFrequency(int channel) { 155 if (numSamples < 1 || channel < 0 || channel > 2) 156 return -1; 157 return minFrequency[channel]; 158 } 159 160 161 public int getMaxFrequency() { 162 if (numSamples > 0 && isGray) 163 return maxFrequency[0]; 164 return -1; 165 } 166 167 public int getMaxFrequency(int channel) { 168 if (numSamples < 1 || channel < 0 || channel > 2) 169 return -1; 170 return maxFrequency[channel]; 171 } 172 173 174 public int getMinValue() { 175 if (numSamples > 0 && isGray) 176 return minValue[0]; 177 return -1; 178 } 179 180 public int getMinValue(int channel) { 181 return minValue[channel]; 182 } 183 184 public int getMaxValue() { 185 if (numSamples > 0 && isGray) 186 return maxValue[0]; 187 return -1; 188 } 189 190 public int getMaxValue(int channel) { 191 return maxValue[channel]; 192 } 193 194 public float getMeanValue() { 195 if (numSamples > 0 && isGray) 196 return mean[0]; 197 return -1.0F; 198 } 199 200 public float getMeanValue(int channel) { 201 if (numSamples > 0 && RED <= channel && channel <= BLUE) 202 return mean[channel]; 203 return -1.0F; 204 } 205 206 207}