Package: HistogramJava2D
HistogramJava2D
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
HistogramJava2D(RenderedImage) |
|
|
|
|
|
||||||||||||||||||||
compute() |
|
|
|
|
|
||||||||||||||||||||
genericCompute() |
|
|
|
|
|
||||||||||||||||||||
getFrequencies(int) |
|
|
|
|
|
||||||||||||||||||||
getMax(int) |
|
|
|
|
|
||||||||||||||||||||
getMin(int) |
|
|
|
|
|
||||||||||||||||||||
getPreview(PreviewSettings) |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
Coverage
1: /*
2: * *********************************************************************************************************************
3: *
4: * Mistral: open source imaging engine
5: * http://tidalwave.it/projects/mistral
6: *
7: * Copyright (C) 2003 - 2023 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *********************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
12: * the License. You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
17: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
18: * specific language governing permissions and limitations under the License.
19: *
20: * *********************************************************************************************************************
21: *
22: * git clone https://bitbucket.org/tidalwave/mistral-src
23: * git clone https://github.com/tidalwave-it/mistral-src
24: *
25: * *********************************************************************************************************************
26: */
27: package it.tidalwave.image.java2d;
28:
29: import java.awt.image.BufferedImage;
30: import java.awt.image.Raster;
31: import java.awt.image.RenderedImage;
32: import it.tidalwave.image.Histogram;
33: import it.tidalwave.image.render.PreviewSettings;
34: import lombok.extern.slf4j.Slf4j;
35:
36: /***********************************************************************************************************************
37: *
38: * @author Fabrizio Giudici
39: *
40: **********************************************************************************************************************/
41: @Slf4j
42: public class HistogramJava2D extends Histogram
43: {
44: private RenderedImage renderedImage;
45: private int[][] bandData;
46: private int[] max;
47: private int[] min;
48: private int shift;
49:
50: /*******************************************************************************************************************
51: *
52: * @param image
53: *
54: ******************************************************************************************************************/
55:
56: /* package */ HistogramJava2D (final RenderedImage renderedImage)
57: {
58: super(renderedImage);
59: this.renderedImage = renderedImage;
60: compute();
61: }
62:
63: /*******************************************************************************************************************
64: *
65: * {@inheritDoc}
66: *
67: ******************************************************************************************************************/
68: @Override
69: public int[] getFrequencies (final int band)
70: {
71: validateBand(band);
72:
73: synchronized (this)
74: {
75:• if (bandData == null)
76: {
77: compute();
78: }
79: }
80:
81: return bandData[band];
82: }
83:
84: /*******************************************************************************************************************
85: *
86: * {@inheritDoc}
87: *
88: ******************************************************************************************************************/
89: @Override
90: public int getMin (final int band)
91: {
92: validateBand(band);
93:
94: return min[band];
95: }
96:
97: /*******************************************************************************************************************
98: *
99: * {@inheritDoc}
100: *
101: ******************************************************************************************************************/
102: @Override
103: public int getMax (final int band)
104: {
105: validateBand(band);
106:
107: return max[band];
108: }
109:
110: /*******************************************************************************************************************
111: *
112: ******************************************************************************************************************/
113: private void compute()
114: {
115: log.info("compute()");
116: bandCount = renderedImage.getSampleModel().getNumBands();
117: bitsPerBand = renderedImage.getSampleModel().getSampleSize(0);
118: shift = 0;
119:
120:• if (bitsPerBand == 16)
121: {
122: shift = 16 - 8; // FIXME: should be only for 12bbp files such as NEF
123: }
124:
125: bandData = new int[bandCount][1 << (bitsPerBand - shift)];
126: min = new int[bandCount];
127: max = new int[bandCount];
128: log.info(">>>> Allocated bandData[" + bandData.length + "][" + bandData[0].length + "]");
129: genericCompute();
130:
131: //DataBuffer dataBuffer = raster.getDataBuffer();
132: //int dataBufferSize = DataBuffer.getDataTypeSize(dataBuffer.getDataType());
133: // if (dataBuffer instanceof DataBufferInt)
134: // DataBufferInt dbs = (DataBufferInt)dataBuffer;
135: // int[][] bankData = dbs.getBankData();
136: // log.info(">>>> bankData[" + bankData.length + "][" + bankData[0].length + "]");
137: // int[] offsets = dbs.getOffsets();
138: // int scanStride = w;
139: }
140:
141: /*******************************************************************************************************************
142: *
143: * {@inheritDoc}
144: *
145: ******************************************************************************************************************/
146: @Override
147: public it.tidalwave.image.Histogram getPreview (final PreviewSettings previewSetting)
148: {
149: final var previewHistogram = new HistogramJava2D(null);
150: previewHistogram.bandCount = bandCount;
151: previewHistogram.bandData = new int[bandCount][];
152:
153: final var lut8bit = previewSetting.getLookupTable8bit().getTable();
154: final var lut16bit = previewSetting.getLookupTable16bit().getTable();
155:
156:• for (var band = 0; band < bandCount; band++)
157: {
158: final var len = bandData[band].length;
159: previewHistogram.bandData[band] = new int[len];
160:
161:• for (var i = 0; i < len; i++)
162: {
163:• final var dst = (len <= 256) ? (lut8bit[band][i] & 0xff) : (lut16bit[band][i] & 0xffff);
164: previewHistogram.bandData[band][dst] += bandData[band][i];
165: }
166: }
167:
168: return previewHistogram;
169: }
170:
171: /*******************************************************************************************************************
172: *
173: * Works with every kind of data buffer, but it's not fast.
174: *
175: * @param raster
176: * @param shift
177: * @param w
178: * @param h
179: * @param first
180: *
181: ******************************************************************************************************************/
182: private void genericCompute()
183: {
184: final Raster raster = ((BufferedImage)image).getRaster();
185: final var w = renderedImage.getWidth();
186: final var h = renderedImage.getHeight();
187: var first = true;
188:
189:• for (var y = 0; y < h; y++)
190: {
191:• for (var x = 0; x < w; x++)
192: {
193:• for (var b = 0; b < bandCount; b++)
194: {
195: final var v = raster.getSample(x, y, b) >> shift;
196:
197: bandData[b][v]++;
198:
199:• if (first)
200: {
201: min[b] = max[b] = v;
202: }
203:
204: else
205: {
206:• if (v < min[b])
207: {
208: min[b] = v;
209: }
210:
211:• else if (v > max[b])
212: {
213: max[b] = v;
214: }
215: }
216: }
217:
218: first = false;
219: }
220: }
221: }
222: }