Source Code Cross Referenced for ColorModelFactory.java in  » GIS » GeoTools-2.4.1 » org » geotools » coverage » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.coverage 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Management Committee (PMC)
005:         *    (C) 2001, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.coverage;
018:
019:        // J2SE dependencies
020:        import java.awt.Transparency;
021:        import java.awt.color.ColorSpace;
022:        import java.awt.image.ColorModel;
023:        import java.awt.image.ComponentColorModel;
024:        import java.awt.image.DataBuffer;
025:        import java.awt.image.RenderedImage;
026:        import java.util.Arrays;
027:        import java.util.Map;
028:
029:        // JAI dependencies
030:        import javax.media.jai.FloatDoubleColorModel;
031:        import javax.media.jai.RasterFactory;
032:
033:        // Geotools dependencies
034:        import org.geotools.resources.i18n.Errors;
035:        import org.geotools.resources.i18n.ErrorKeys;
036:        import org.geotools.resources.image.ColorUtilities;
037:        import org.geotools.resources.image.ComponentColorModelJAI;
038:        import org.geotools.util.WeakValueHashMap;
039:
040:        /**
041:         * A factory for {@link ColorModel} objects built from a list of {@link Category} objects.
042:         * This factory provides only one public static method: {@link #getColorModel}.  Instances
043:         * of {@link ColorModel} are shared among all callers in the running virtual machine.
044:         *
045:         * @since 2.1
046:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/coverage/ColorModelFactory.java $
047:         * @version $Id: ColorModelFactory.java 25421 2007-05-05 16:55:18Z desruisseaux $
048:         * @author Martin Desruisseaux
049:         */
050:        final class ColorModelFactory {
051:            /**
052:             * A pool of color models previously created by {@link #getColorModel}.
053:             *
054:             * <b>Note:</b> we use {@linkplain java.lang.ref.WeakReference weak references} instead of
055:             * {@linkplain java.lang.ref.SoftReference soft references} because the intend is not to
056:             * cache the values. The intend is to share existing instances in order to reduce memory
057:             * usage. Rational:
058:             *
059:             * <ul>
060:             *   <li>{@link ColorModel} may consume a lot of memory. A 16 bits indexed color model
061:             *       can consume up to 256 kb. We don't want to retain such large objects longer
062:             *       than necessary. We want to share existing instances without preventing the
063:             *       garbage collector to collect them.</li>
064:             *   <li>{@link #getColorModel()} is reasonably fast if invoked only occasionally, so it
065:             *       is not worth consuming 256 kb for saving the few milliseconds requirying for
066:             *       building a new color model. Client code should retains their own reference to a
067:             *       {@link ColorModel} if they plan to reuse it often in a short period of time.</li>
068:             * </ul>
069:             */
070:            private static final Map/*<ColorModelFactory,ColorModel>*/colors = new WeakValueHashMap();
071:
072:            /**
073:             * The list of categories for the construction of a single instance of a {@link ColorModel}.
074:             */
075:            private final Category[] categories;
076:
077:            /**
078:             * The visible band (usually 0) used for the construction
079:             * of a single instance of a {@link ColorModel}.
080:             */
081:            private final int visibleBand;
082:
083:            /**
084:             * The number of bands (usually 1) used for the construction
085:             * of a single instance of a {@link ColorModel}.
086:             */
087:            private final int numBands;
088:
089:            /**
090:             * The color model type. One of {@link DataBuffer#TYPE_BYTE}, {@link DataBuffer#TYPE_USHORT},
091:             * {@link DataBuffer#TYPE_FLOAT} or {@link DataBuffer#TYPE_DOUBLE}.
092:             *
093:             * @task TODO: The user may want to set explicitly the number of bits each pixel occupied.
094:             *             We need to think about an API to allows that.
095:             */
096:            private final int type;
097:
098:            /**
099:             * Construct a new {@code ColorModelFactory}. This object will actually be used
100:             * as a key in a {@link Map}, so this is not really a {@code ColorModelFactory}
101:             * but a kind of "{@code ColorModelKey}" instead. However, since this constructor
102:             * is private, user doesn't need to know that.
103:             */
104:            private ColorModelFactory(final Category[] categories,
105:                    final int type, final int visibleBand, final int numBands) {
106:                this .categories = categories;
107:                this .visibleBand = visibleBand;
108:                this .numBands = numBands;
109:                this .type = type;
110:                if (visibleBand < 0 || visibleBand >= numBands) {
111:                    throw new IllegalArgumentException(Errors.format(
112:                            ErrorKeys.BAD_BAND_NUMBER_$1, new Integer(
113:                                    visibleBand)));
114:                }
115:            }
116:
117:            /**
118:             * Returns a color model for a category set. This method builds up the color model
119:             * from each category's colors (as returned by {@link Category#getColors}).
120:             *
121:             * @param  categories The set of categories.
122:             * @param  type The color model type. One of {@link DataBuffer#TYPE_BYTE},
123:             *         {@link DataBuffer#TYPE_USHORT}, {@link DataBuffer#TYPE_FLOAT} or
124:             *         {@link DataBuffer#TYPE_DOUBLE}.
125:             * @param  visibleBand The band to be made visible (usually 0). All other bands, if any
126:             *         will be ignored.
127:             * @param  numBands The number of bands for the color model (usually 1). The returned color
128:             *         model will renderer only the {@code visibleBand} and ignore the others, but
129:             *         the existence of all {@code numBands} will be at least tolerated. Supplemental
130:             *         bands, even invisible, are useful for processing with Java Advanced Imaging.
131:             * @return The requested color model, suitable for {@link RenderedImage} objects with values
132:             *         in the <code>{@link CategoryList#getRange}</code> range.
133:             */
134:            public static ColorModel getColorModel(final Category[] categories,
135:                    final int type, final int visibleBand, final int numBands) {
136:                synchronized (colors) {
137:                    ColorModelFactory key = new ColorModelFactory(categories,
138:                            type, visibleBand, numBands);
139:                    ColorModel model = (ColorModel) colors.get(key);
140:                    if (model == null) {
141:                        model = key.getColorModel();
142:                        colors.put(key, model);
143:                    }
144:                    return model;
145:                }
146:            }
147:
148:            /**
149:             * Constructs the color model.
150:             */
151:            private ColorModel getColorModel() {
152:                final int categoryCount = categories.length;
153:                if (type != DataBuffer.TYPE_BYTE
154:                        && type != DataBuffer.TYPE_USHORT) {
155:                    // If the requested type is any type not supported by IndexColorModel,
156:                    // fallback on a generic (but very slow!) color model.
157:                    double min = 0;
158:                    double max = 1;
159:                    if (categoryCount != 0) {
160:                        min = categories[0].minimum;
161:                        for (int i = categoryCount; --i >= 0;) {
162:                            final double val = categories[i].maximum;
163:                            if (!Double.isNaN(val)) {
164:                                max = val;
165:                                break;
166:                            }
167:                        }
168:                    }
169:                    final int transparency = Transparency.OPAQUE;
170:                    final ColorSpace colors = new ScaledColorSpace(visibleBand,
171:                            numBands, min, max);
172:                    if (false) {
173:                        // This is the J2SE implementation of color model. It should be our preferred one.
174:                        // Unfortunatly, as of JAI 1.1 we have to use JAI implementation instead of J2SE's
175:                        // one because javax.media.jai.iterator.RectIter do not work with J2SE's DataBuffer
176:                        // when the data type is float or double.
177:                        return new ComponentColorModel(colors, false, false,
178:                                transparency, type);
179:                    }
180:                    if (false) {
181:                        // This is the JAI implementation of color model. This implementation work with
182:                        // JAI's RectIter and should in theory support float and double data buffer.
183:                        // Unfortunatly, it seems to completly ignore our custom ColorSpace. We end
184:                        // up basically with all-black or all-white images.
185:                        return new FloatDoubleColorModel(colors, false, false,
186:                                transparency, type);
187:                    }
188:                    if (true) {
189:                        // Our patched color model extends J2SE's ComponentColorModel (which work correctly
190:                        // with our custom ColorSpace), but create JAI's SampleModel instead of J2SE's one.
191:                        // It make RectIter happy and display colors correctly.
192:                        return new ComponentColorModelJAI(colors, false, false,
193:                                transparency, type);
194:                    }
195:                    // This factory is not really different from a direct construction of
196:                    // FloatDoubleColorModel. We provide it here just because we must end
197:                    // with something.
198:                    return RasterFactory.createComponentColorModel(type,
199:                            colors, false, false, transparency);
200:                }
201:                if (numBands == 1 && categoryCount == 0) {
202:                    // Construct a gray scale palette.
203:                    final ColorSpace cs = ColorSpace
204:                            .getInstance(ColorSpace.CS_GRAY);
205:                    final int[] nBits = { DataBuffer.getDataTypeSize(type) };
206:                    return new ComponentColorModel(cs, nBits, false, true,
207:                            Transparency.OPAQUE, type);
208:                }
209:                /*
210:                 * Computes the number of entries required for the color palette.
211:                 * We take the upper range value of the last category.
212:                 */
213:                final int mapSize = (int) Math
214:                        .round(categories[categoryCount - 1].maximum) + 1;
215:                final int[] ARGB = new int[mapSize];
216:                /*
217:                 * Interpolate the colors in the color palette. Colors that do not fall
218:                 * in the range of a category will be set to a transparent color.
219:                 */
220:                for (int i = 0; i < categoryCount; i++) {
221:                    final Category category = categories[i];
222:                    ColorUtilities.expand(category.getColors(), ARGB,
223:                            (int) Math.round(category.minimum), (int) Math
224:                                    .round(category.maximum) + 1);
225:                }
226:                return ColorUtilities.getIndexColorModel(ARGB, numBands,
227:                        visibleBand);
228:            }
229:
230:            /**
231:             * Returns a hash code.
232:             */
233:            public int hashCode() {
234:                final int categoryCount = categories.length;
235:                int code = 962745549 + (numBands * 37 + visibleBand) * 37
236:                        + categoryCount;
237:                for (int i = 0; i < categoryCount; i++) {
238:                    code += categories[i].hashCode();
239:                    // Better be independant of categories order.
240:                }
241:                return code;
242:            }
243:
244:            /**
245:             * Check this object with an other one for equality.
246:             */
247:            public boolean equals(final Object other) {
248:                if (other == this ) {
249:                    return true;
250:                }
251:                if (other instanceof  ColorModelFactory) {
252:                    final ColorModelFactory that = (ColorModelFactory) other;
253:                    return this .numBands == that.numBands
254:                            && this .visibleBand == that.visibleBand
255:                            && Arrays.equals(this .categories, that.categories);
256:                }
257:                return false;
258:            }
259:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.