001    package org.bukkit.map;
002    
003    import java.awt.Color;
004    import java.awt.Graphics2D;
005    import java.awt.Image;
006    import java.awt.image.BufferedImage;
007    
008    /**
009     * Represents the palette that map items use.
010     * <p>
011     * These fields are hee base color ranges. Each entry corresponds to four
012     * colors of varying shades with values entry to entry + 3.
013     */
014    public final class MapPalette {
015        // Internal mechanisms
016        private MapPalette() {}
017    
018        private static Color c(int r, int g, int b) {
019            return new Color(r, g, b);
020        }
021    
022        private static double getDistance(Color c1, Color c2) {
023            double rmean = (c1.getRed() + c2.getRed()) / 2.0;
024            double r = c1.getRed() - c2.getRed();
025            double g = c1.getGreen() - c2.getGreen();
026            int b = c1.getBlue() - c2.getBlue();
027            double weightR = 2 + rmean / 256.0;
028            double weightG = 4.0;
029            double weightB = 2 + (255 - rmean) / 256.0;
030            return weightR * r * r + weightG * g * g + weightB * b * b;
031        }
032    
033        private static final Color[] colors = {
034            new Color(0, 0, 0, 0), new Color(0, 0, 0, 0),
035            new Color(0, 0, 0, 0), new Color(0, 0, 0, 0),
036            c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29),
037            c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86),
038            c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88),
039            c(180, 0, 0), c(220, 0, 0), c(255, 0, 0), c(135, 0, 0),
040            c(112, 112, 180), c(138, 138, 220), c(160, 160, 255), c(84, 84, 135),
041            c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88),
042            c(0, 87, 0), c(0, 106, 0), c(0, 124, 0), c(0, 65, 0),
043            c(180, 180, 180), c(220, 220, 220), c(255, 255, 255), c(135, 135, 135),
044            c(115, 118, 129), c(141, 144, 158), c(164, 168, 184), c(86, 88, 97),
045            c(129, 74, 33), c(157, 91, 40), c(183, 106, 47), c(96, 56, 24),
046            c(79, 79, 79), c(96, 96, 96), c(112, 112, 112), c(59, 59, 59),
047            c(45, 45, 180), c(55, 55, 220), c(64, 64, 255), c(33, 33, 135),
048            c(73, 58, 35), c(89, 71, 43), c(104, 83, 50), c(55, 43, 26),
049            c(180, 177, 172), c(220, 217, 211), c(255, 252, 245), c(135, 133, 129),
050            c(152, 89, 36), c(186, 109, 44), c(216, 127, 51), c(114, 67, 27),
051            c(125, 53, 152), c(153, 65, 186), c(178, 76, 216), c(94, 40, 114),
052            c(72, 108, 152), c(88, 132, 186), c(102, 153, 216), c(54, 81, 114),
053            c(161, 161, 36), c(197, 197, 44), c(229, 229, 51), c(121, 121, 27),
054            c(89, 144, 17), c(109, 176, 21), c(127, 204, 25), c(67, 108, 13),
055            c(170, 89, 116), c(208, 109, 142), c(242, 127, 165), c(128, 67, 87),
056            c(53, 53, 53), c(65, 65, 65), c(76, 76, 76), c(40, 40, 40),
057            c(108, 108, 108), c(132, 132, 132), c(153, 153, 153), c(81, 81, 81),
058            c(53, 89, 108), c(65, 109, 132), c(76, 127, 153), c(40, 67, 81),
059            c(89, 44, 125), c(109, 54, 153), c(127, 63, 178), c(67, 33, 94),
060            c(36, 53, 125), c(44, 65, 153), c(51, 76, 178), c(27, 40, 94),
061            c(72, 53, 36), c(88, 65, 44), c(102, 76, 51), c(54, 40, 27),
062            c(72, 89, 36), c(88, 109, 44), c(102, 127, 51), c(54, 67, 27),
063            c(108, 36, 36), c(132, 44, 44), c(153, 51, 51), c(81, 27, 27),
064            c(17, 17, 17), c(21, 21, 21), c(25, 25, 25), c(13, 13, 13),
065            c(176, 168, 54), c(215, 205, 66), c(250, 238, 77), c(132, 126, 40),
066            c(64, 154, 150), c(79, 188, 183), c(92, 219, 213), c(48, 115, 112),
067            c(52, 90, 180), c(63, 110, 220), c(74, 128, 255), c(39, 67, 135),
068            c(0, 153, 40), c(0, 187, 50), c(0, 217, 58), c(0, 114, 30),
069            c(14, 14, 21), c(18, 17, 26), c(21, 20, 31), c(11, 10, 16),
070            c(79, 1, 0), c(96, 1, 0), c(112, 2, 0), c(59, 1, 0)
071        };
072    
073        // Interface
074        /**
075         * @deprecated Magic value
076         */
077        @Deprecated
078        public static final byte TRANSPARENT = 0;
079        /**
080         * @deprecated Magic value
081         */
082        @Deprecated
083        public static final byte LIGHT_GREEN = 4;
084        /**
085         * @deprecated Magic value
086         */
087        @Deprecated
088        public static final byte LIGHT_BROWN = 8;
089        /**
090         * @deprecated Magic value
091         */
092        @Deprecated
093        public static final byte GRAY_1 = 12;
094        /**
095         * @deprecated Magic value
096         */
097        @Deprecated
098        public static final byte RED = 16;
099        /**
100         * @deprecated Magic value
101         */
102        @Deprecated
103        public static final byte PALE_BLUE = 20;
104        /**
105         * @deprecated Magic value
106         */
107        @Deprecated
108        public static final byte GRAY_2 = 24;
109        /**
110         * @deprecated Magic value
111         */
112        @Deprecated
113        public static final byte DARK_GREEN = 28;
114        /**
115         * @deprecated Magic value
116         */
117        @Deprecated
118        public static final byte WHITE = 32;
119        /**
120         * @deprecated Magic value
121         */
122        @Deprecated
123        public static final byte LIGHT_GRAY = 36;
124        /**
125         * @deprecated Magic value
126         */
127        @Deprecated
128        public static final byte BROWN = 40;
129        /**
130         * @deprecated Magic value
131         */
132        @Deprecated
133        public static final byte DARK_GRAY = 44;
134        /**
135         * @deprecated Magic value
136         */
137        @Deprecated
138        public static final byte BLUE = 48;
139        /**
140         * @deprecated Magic value
141         */
142        @Deprecated
143        public static final byte DARK_BROWN = 52;
144    
145        /**
146         * Resize an image to 128x128.
147         *
148         * @param image The image to resize.
149         * @return The resized image.
150         */
151        public static BufferedImage resizeImage(Image image) {
152            BufferedImage result = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
153            Graphics2D graphics = result.createGraphics();
154            graphics.drawImage(image, 0, 0, 128, 128, null);
155            graphics.dispose();
156            return result;
157        }
158    
159        /**
160         * Convert an Image to a byte[] using the palette.
161         *
162         * @param image The image to convert.
163         * @return A byte[] containing the pixels of the image.
164         * @deprecated Magic value
165         */
166        @Deprecated
167        public static byte[] imageToBytes(Image image) {
168            BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
169            Graphics2D graphics = temp.createGraphics();
170            graphics.drawImage(image, 0, 0, null);
171            graphics.dispose();
172    
173            int[] pixels = new int[temp.getWidth() * temp.getHeight()];
174            temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth());
175    
176            byte[] result = new byte[temp.getWidth() * temp.getHeight()];
177            for (int i = 0; i < pixels.length; i++) {
178                result[i] = matchColor(new Color(pixels[i], true));
179            }
180            return result;
181        }
182    
183        /**
184         * Get the index of the closest matching color in the palette to the given
185         * color.
186         *
187         * @param r The red component of the color.
188         * @param b The blue component of the color.
189         * @param g The green component of the color.
190         * @return The index in the palette.
191         * @deprecated Magic value
192         */
193        @Deprecated
194        public static byte matchColor(int r, int g, int b) {
195            return matchColor(new Color(r, g, b));
196        }
197    
198        /**
199         * Get the index of the closest matching color in the palette to the given
200         * color.
201         *
202         * @param color The Color to match.
203         * @return The index in the palette.
204         * @deprecated Magic value
205         */
206        @Deprecated
207        public static byte matchColor(Color color) {
208            if (color.getAlpha() < 128) return 0;
209    
210            int index = 0;
211            double best = -1;
212    
213            for (int i = 4; i < colors.length; i++) {
214                double distance = getDistance(color, colors[i]);
215                if (distance < best || best == -1) {
216                    best = distance;
217                    index = i;
218                }
219            }
220    
221            // Minecraft has 143 colors, some of which have negative byte representations
222            return (byte) (index < 128 ? index : -129 + (index - 127));
223        }
224    
225        /**
226         * Get the value of the given color in the palette.
227         *
228         * @param index The index in the palette.
229         * @return The Color of the palette entry.
230         * @deprecated Magic value
231         */
232        @Deprecated
233        public static Color getColor(byte index) {
234            if ((index > -113 && index < 0) || index > 127) {
235                throw new IndexOutOfBoundsException();
236            } else {
237                // Minecraft has 143 colors, some of which have negative byte representations
238                return colors[index >= 0 ? index : index + 256];
239            }
240        }
241    }