1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.palette;
18
19 import java.util.Arrays;
20 import java.util.Comparator;
21 import java.util.logging.Logger;
22
23 final class ColorSpaceSubset {
24
25 public static class RgbComparator implements Comparator<ColorSpaceSubset> {
26
27 @Override
28 public int compare(final ColorSpaceSubset c1, final ColorSpaceSubset c2) {
29 return c1.rgb - c2.rgb;
30 }
31 }
32
33 private static final Logger LOGGER = Logger.getLogger(ColorSpaceSubset.class.getName());
34 public static final RgbComparator RGB_COMPARATOR = new RgbComparator();
35 static final int SHALLOW_SIZE = 40;
36 final int[] mins;
37 final int[] maxs;
38 final int precision;
39 final int precisionMask;
40 final int total;
41
42 int rgb;
43
44 private int index;
45
46 ColorSpaceSubset(final int total, final int precision) {
47 this.total = total;
48 this.precision = precision;
49 precisionMask = (1 << precision) - 1;
50
51 mins = new int[PaletteFactory.COMPONENTS];
52 maxs = new int[PaletteFactory.COMPONENTS];
53 Arrays.fill(maxs, precisionMask);
54
55 rgb = -1;
56 }
57
58 ColorSpaceSubset(final int total, final int precision, final int[] mins, final int[] maxs) {
59 this.total = total;
60 this.precision = precision;
61 this.mins = mins;
62 this.maxs = maxs;
63 precisionMask = (1 << precision) - 1;
64
65 rgb = -1;
66 }
67
68 public boolean contains(int red, int green, int blue) {
69 red >>= 8 - precision;
70 if (mins[0] > red) {
71 return false;
72 }
73 if (maxs[0] < red) {
74 return false;
75 }
76
77 green >>= 8 - precision;
78 if (mins[1] > green) {
79 return false;
80 }
81 if (maxs[1] < green) {
82 return false;
83 }
84
85 blue >>= 8 - precision;
86 if (mins[2] > blue) {
87 return false;
88 }
89 if (maxs[2] < blue) {
90 return false;
91 }
92
93 return true;
94 }
95
96 public void dump(final String prefix) {
97 final int rdiff = maxs[0] - mins[0] + 1;
98 final int gdiff = maxs[1] - mins[1] + 1;
99 final int bdiff = maxs[2] - mins[2] + 1;
100 final int colorArea = rdiff * gdiff * bdiff;
101
102 LOGGER.fine(prefix + ": [" + Integer.toHexString(rgb) + "] total : " + total
103
104
105
106 );
107 LOGGER.fine("\t" + "rgb: " + Integer.toHexString(rgb) + ", " + "red: " + Integer.toHexString(mins[0] << 8 - precision) + ", "
108 + Integer.toHexString(maxs[0] << 8 - precision) + ", " + "green: " + Integer.toHexString(mins[1] << 8 - precision) + ", "
109 + Integer.toHexString(maxs[1] << 8 - precision) + ", " + "blue: " + Integer.toHexString(mins[2] << 8 - precision) + ", "
110 + Integer.toHexString(maxs[2] << 8 - precision));
111 LOGGER.fine("\t" + "red: " + mins[0] + ", " + maxs[0] + ", " + "green: " + mins[1] + ", " + maxs[1] + ", " + "blue: " + mins[2] + ", " + maxs[2]);
112 LOGGER.fine("\t" + "rdiff: " + rdiff + ", " + "gdiff: " + gdiff + ", " + "bdiff: " + bdiff + ", " + "colorArea: " + colorArea);
113 }
114
115 public void dumpJustRgb(final String prefix) {
116 LOGGER.fine("\t" + "rgb: " + Integer.toHexString(rgb) + ", " + "red: " + Integer.toHexString(mins[0] << 8 - precision) + ", "
117 + Integer.toHexString(maxs[0] << 8 - precision) + ", " + "green: " + Integer.toHexString(mins[1] << 8 - precision) + ", "
118 + Integer.toHexString(maxs[1] << 8 - precision) + ", " + "blue: " + Integer.toHexString(mins[2] << 8 - precision) + ", "
119 + Integer.toHexString(maxs[2] << 8 - precision));
120 }
121
122 public int getArea() {
123 final int rdiff = maxs[0] - mins[0] + 1;
124 final int gdiff = maxs[1] - mins[1] + 1;
125 final int bdiff = maxs[2] - mins[2] + 1;
126
127 return rdiff * gdiff * bdiff;
128
129 }
130
131 public int getIndex() {
132 return index;
133 }
134
135 public void setAverageRgb(final int[] table) {
136 long redsum = 0;
137 long greensum = 0;
138 long bluesum = 0;
139
140 for (int red = mins[0]; red <= maxs[0]; red++) {
141 for (int green = mins[1]; green <= maxs[1]; green++) {
142 for (int blue = mins[2]; blue <= maxs[2]; blue++) {
143
144 final int idx = blue << 2 * precision | green << 1 * precision | red << 0 * precision;
145 final int count = table[idx];
146 redsum += count * (red << 8 - precision);
147 greensum += count * (green << 8 - precision);
148 bluesum += count * (blue << 8 - precision);
149 }
150 }
151 }
152
153 redsum /= total;
154 greensum /= total;
155 bluesum /= total;
156 rgb = (int) ((redsum & 0xff) << 16 | (greensum & 0xff) << 8 | (bluesum & 0xff) << 0);
157 }
158
159 public void setIndex(final int i) {
160 index = i;
161 }
162 }