1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.tiff.photometricinterpreters.floatingpoint;
18
19 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22
23 import java.awt.Color;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import org.apache.commons.imaging.ImagingException;
29 import org.apache.commons.imaging.common.ImageBuilder;
30 import org.junit.jupiter.api.BeforeAll;
31 import org.junit.jupiter.api.Test;
32
33
34
35
36 public class PhotometricInterpreterFloatTest {
37
38 private static PhotometricInterpreterFloat pInterp;
39 private static PhotometricInterpreterFloat bandedInterp;
40 private static ImageBuilder imageBuilder;
41 private static ImageBuilder bandedImageBuilder;
42
43 private static final Color orange = new Color(255, 136, 62);
44 private static final Color green = new Color(22, 155, 98);
45
46 @BeforeAll
47 public static void setUpClass() throws ImagingException, IOException {
48
49
50
51
52
53
54 final List<PaletteEntry> paletteList = new ArrayList<>();
55 final List<PaletteEntry> reverseList = new ArrayList<>();
56 for (int i = 0; i < 256; i += 32) {
57 final int i1 = i + 31;
58 final float f0 = i / 256f;
59 final float f1 = (i + 32) / 256f;
60 final int argb0 = 0xff000000 | i << 8 | i;
61 final int argb1 = 0xff000000 | i1 << 8 | i;
62 final Color c0 = new Color(argb0);
63 final Color c1 = new Color(argb1);
64 final PaletteEntryForRange entry = new PaletteEntryForRange(f0, f1, c0, c1);
65 paletteList.add(entry);
66 }
67
68
69 for (int i = paletteList.size() - 1; i >= 0; i--) {
70 final PaletteEntry entry = paletteList.get(i);
71 reverseList.add(entry);
72 }
73
74 pInterp = new PhotometricInterpreterFloat(reverseList);
75
76
77
78 imageBuilder = new ImageBuilder(257, 257, false);
79 final int[] samples = new int[1];
80 for (int i = 0; i <= 256; i++) {
81 final float f = i / 256f;
82 samples[0] = Float.floatToRawIntBits(f);
83 pInterp.interpretPixel(imageBuilder, samples, i, i);
84 }
85
86
87 final List<PaletteEntry> bandedPaletteList = new ArrayList<>();
88 bandedPaletteList.add(new PaletteEntryForRange(0f, 0.33f, green));
89 bandedPaletteList.add(new PaletteEntryForRange(0.33f, 0.66f, Color.white));
90 bandedPaletteList.add(new PaletteEntryForRange(0.66f, 1.0f, orange));
91 bandedPaletteList.add(new PaletteEntryForValue(Float.NaN, Color.gray));
92 bandedPaletteList.add(new PaletteEntryForValue(-1, Color.gray));
93 bandedInterp = new PhotometricInterpreterFloat(bandedPaletteList);
94 bandedImageBuilder = new ImageBuilder(300, 200, false);
95 for (int j = 0; j < 300; j++) {
96 final float f = j / 299.0f;
97 samples[0] = Float.floatToRawIntBits(f);
98 for (int i = 0; i < 200; i++) {
99 bandedInterp.interpretPixel(bandedImageBuilder, samples, j, i);
100 }
101 }
102 samples[0] = Float.floatToRawIntBits(Float.NaN);
103 for (int i = 0; i < 200; i++) {
104 bandedInterp.interpretPixel(bandedImageBuilder, samples, 0, i);
105 bandedInterp.interpretPixel(bandedImageBuilder, samples, 299, i);
106 }
107 samples[0] = Float.floatToRawIntBits(-1);
108 for (int i = 0; i < 300; i++) {
109 bandedInterp.interpretPixel(bandedImageBuilder, samples, i, 0);
110 bandedInterp.interpretPixel(bandedImageBuilder, samples, i, 199);
111 }
112 }
113
114 public PhotometricInterpreterFloatTest() {
115 }
116
117 @Test
118 public void testConstructors() {
119 new PhotometricInterpreterFloat(0, 1);
120 new PhotometricInterpreterFloat(1, 0);
121
122 assertThrows(IllegalArgumentException.class, () -> new PhotometricInterpreterFloat(null), "Constructor failed to detect null arguments");
123
124 assertThrows(IllegalArgumentException.class, () -> new PhotometricInterpreterFloat(0.1f, 0.1f),
125 "Constructor failed to detect bad-range argument values");
126
127 }
128
129
130
131
132 @Test
133 public void testGetMaxFound() {
134 final float expResult = 1.0F;
135 final float result = pInterp.getMinFound();
136 assertEquals(expResult, result, 1.0, "Invalid maximum value");
137 }
138
139
140
141
142 @Test
143 public void testGetMaxXY() {
144 final int[] expResult = { 256, 256 };
145 final int[] result = pInterp.getMaxXY();
146 assertArrayEquals(expResult, result);
147 }
148
149
150
151
152 @Test
153 public void testGetMeanFound() {
154 final float expResult = 0.5F;
155 final float result = pInterp.getMinFound();
156 assertEquals(expResult, result, 1.0, "Invalid mean value");
157 }
158
159
160
161
162 @Test
163 public void testGetMinFound() {
164 final float expResult = 0.0F;
165 final float result = pInterp.getMinFound();
166 assertEquals(expResult, result, 0.0, "Invalid minimum value");
167 }
168
169
170
171
172 @Test
173 public void testGetMinXY() {
174 final int[] expResult = { 0, 0 };
175 final int[] result = pInterp.getMinXY();
176 assertArrayEquals(expResult, result);
177 }
178
179
180
181
182 @Test
183 public void testInterpretPixel() {
184 for (int i = 0; i < 256; i++) {
185 final int lowTest = i / 32 * 32;
186 final int argb = imageBuilder.getRgb(i, i);
187 final int b = argb & 0xff;
188 assertEquals(b, lowTest, "Invalid conversion for level " + i);
189 }
190
191
192
193
194
195
196 int argb = imageBuilder.getRgb(256, 256);
197 assertEquals(argb, 0, "Invalid upper-bound test");
198
199
200 argb = bandedImageBuilder.getRgb(0, 0);
201 assertEquals(Color.gray.getRGB(), argb, "Invalid mapping of NaN");
202 argb = bandedImageBuilder.getRgb(50, 10);
203 assertEquals(green.getRGB(), argb, "Invalid mapping of green range");
204 argb = bandedImageBuilder.getRgb(150, 10);
205 assertEquals(Color.white.getRGB(), argb, "Invalid mapping of white range");
206 argb = bandedImageBuilder.getRgb(250, 10);
207 assertEquals(orange.getRGB(), argb, "Invalid mapping of orange range");
208 }
209
210
211
212
213 @Test
214 public void testMapValueToARGB() {
215
216 int argb = pInterp.mapValueToArgb(0.5f);
217 int test = imageBuilder.getRgb(128, 128);
218 assertEquals(test, argb, "Conflicting results from value-to-ARGB map");
219
220
221
222 argb = pInterp.mapValueToArgb(Float.NaN);
223 assertEquals(0, argb, "Non-defined NaN did not return ARGB of zero");
224
225
226 argb = bandedInterp.mapValueToArgb(Float.NaN);
227 test = Color.gray.getRGB();
228 assertEquals(test, argb, "Float.NaN mapped to incorrect ARGB");
229 argb = bandedInterp.mapValueToArgb(-1f);
230 test = Color.gray.getRGB();
231 assertEquals(test, argb, "Excluded value mapped to incorrect ARGB");
232 }
233
234
235
236
237 @Test
238 public void testOverlappingEntriesEntry() throws ImagingException, IOException {
239 final Color c0 = new Color(0xff0000ff);
240 final Color c1 = new Color(0xff00ff00);
241 final List<PaletteEntry> overlapList = new ArrayList<>();
242 overlapList.add(new PaletteEntryForRange(0.0f, 1.0f, c0));
243 overlapList.add(new PaletteEntryForRange(0.0f, 1.5f, c1));
244
245 final PhotometricInterpreterFloat interpreter = new PhotometricInterpreterFloat(overlapList);
246
247 imageBuilder = new ImageBuilder(257, 257, false);
248 final int[] samples = new int[1];
249 samples[0] = Float.floatToRawIntBits(0.5f);
250 interpreter.interpretPixel(imageBuilder, samples, 0, 0);
251 samples[0] = Float.floatToRawIntBits(1.2f);
252 interpreter.interpretPixel(imageBuilder, samples, 1, 1);
253 int argb0 = imageBuilder.getRgb(0, 0) | 0xff000000;
254 int argb1 = imageBuilder.getRgb(1, 1) | 0xff000000;
255 assertEquals(argb0, c0.getRGB(), "Invalid result for overlapping palette entry 0");
256 assertEquals(argb1, c1.getRGB(), "Invalid result for overlapping palette entry 1");
257 argb0 = interpreter.mapValueToArgb(0.5f);
258 argb1 = interpreter.mapValueToArgb(1.2f);
259 assertEquals(argb0, c0.getRGB(), "Invalid mapping for overlapping palette entry 0");
260 assertEquals(argb1, c1.getRGB(), "Invalid mapping for overlapping palette entry 1");
261 }
262
263 }