001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2005, 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.image.jai;
018:
019: // J2SE dependencies
020: import java.util.List;
021: import java.util.Iterator;
022: import java.util.logging.Level;
023: import java.util.logging.LogRecord;
024: import java.awt.image.renderable.RenderedImageFactory;
025:
026: // JAI dependencies
027: import javax.media.jai.JAI;
028: import javax.media.jai.OperationRegistry;
029: import javax.media.jai.registry.RIFRegistry;
030: import javax.media.jai.registry.RenderedRegistryMode;
031:
032: // Geotools dependencies
033: import org.geotools.resources.Utilities;
034: import org.geotools.resources.i18n.Logging;
035: import org.geotools.resources.i18n.LoggingKeys;
036:
037: /**
038: * A set of static methods for managing JAI's {@linkplain OperationRegistry operation registry}.
039: *
040: * @since 2.2
041: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/coverage/src/main/java/org/geotools/image/jai/Registry.java $
042: * @version $Id: Registry.java 27862 2007-11-12 19:51:19Z desruisseaux $
043: * @author Martin Desruisseaux
044: */
045: public final class Registry {
046: /**
047: * Do not allows instantiation of this class.
048: */
049: private Registry() {
050: }
051:
052: /**
053: * Unconditionnaly registers all JAI operations provided in the {@link org.geotools.image.jai}
054: * package. This method usually don't need to be invoked, since JAI should parse automatically
055: * the {@code META-INF/registryFile.jai} file at startup time. However, this default mechanism
056: * may fail when the geotools JAR file is unreachable from the JAI class loader, in which case
057: * the {@link org.geotools.coverage.processing} package will invoke this method as a fallback.
058: * <p>
059: * Note to module maintainer: if this method is updated, remember to update the
060: * {@code META-INF/registryFile.jai} file accordingly.
061: *
062: * @param registry The operation registry to register with.
063: * @return {@code true} if all registrations have been successful.
064: */
065: public static boolean registerGeotoolsServices(
066: final OperationRegistry registry) {
067: LogRecord record;
068: String op = "org.geotools";
069: try {
070: op = CombineDescriptor.OPERATION_NAME;
071: registry.registerDescriptor(new CombineDescriptor());
072: RIFRegistry.register(registry, op, "org.geotools",
073: new CombineCRIF());
074:
075: op = HysteresisDescriptor.OPERATION_NAME;
076: registry.registerDescriptor(new HysteresisDescriptor());
077: RIFRegistry.register(registry, op, "org.geotools",
078: new HysteresisCRIF());
079:
080: op = NodataFilterDescriptor.OPERATION_NAME;
081: registry.registerDescriptor(new NodataFilterDescriptor());
082: RIFRegistry.register(registry, op, "org.geotools",
083: new NodataFilterCRIF());
084:
085: record = Logging.format(Level.CONFIG,
086: LoggingKeys.REGISTERED_JAI_OPERATIONS);
087: op = null;
088: } catch (IllegalArgumentException exception) {
089: /*
090: * Logs a message with the WARNING level, because DefaultProcessing class initialization
091: * is likely to fails (since it tries to load operations declared in META-INF/services,
092: * and some of them depend on JAI operations).
093: */
094: record = Logging.getResources(null).getLogRecord(
095: Level.WARNING,
096: LoggingKeys.CANT_REGISTER_JAI_OPERATION_$1, op);
097: record.setThrown(exception);
098: }
099: log("registerGeotoolsServices", record);
100: return op == null;
101: }
102:
103: /**
104: * Allows or disallow native acceleration for the specified JAI operation. By default, JAI uses
105: * hardware accelerated methods when available. For example, it make use of MMX instructions on
106: * Intel processors. Unfortunatly, some native method crash the Java Virtual Machine under some
107: * circonstances. For example on JAI 1.1.2, the "Affine" operation on an image with float data
108: * type, bilinear interpolation and an {@link javax.media.jai.ImageLayout} rendering hint cause
109: * an exception in medialib native code. Disabling the native acceleration (i.e using the pure
110: * Java version) is a convenient workaround until Sun fix the bug.
111: * <p>
112: * <strong>Implementation note:</strong> the current implementation assumes that factories for
113: * native implementations are declared in the {@code com.sun.media.jai.mlib} package, while
114: * factories for pure java implementations are declared in the {@code com.sun.media.jai.opimage}
115: * package. It work for Sun's 1.1.2 implementation, but may change in future versions. If this
116: * method doesn't recognize the package, it does nothing.
117: *
118: * @param operation The operation name (e.g. "Affine").
119: * @param allowed {@code false} to disallow native acceleration.
120: *
121: * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4906854">JAI bug report 4906854</a>
122: */
123: public synchronized static void setNativeAccelerationAllowed(
124: final String operation, final boolean allowed) {
125: final String product = "com.sun.media.jai";
126: final OperationRegistry registry = JAI.getDefaultInstance()
127: .getOperationRegistry();
128: final List factories = registry.getOrderedFactoryList(
129: RenderedRegistryMode.MODE_NAME, operation, product);
130: if (factories != null) {
131: RenderedImageFactory javaFactory = null;
132: RenderedImageFactory nativeFactory = null;
133: Boolean currentState = null;
134: for (final Iterator it = factories.iterator(); it.hasNext();) {
135: final RenderedImageFactory factory = (RenderedImageFactory) it
136: .next();
137: final String pack = factory.getClass().getPackage()
138: .getName();
139: if (pack.equals("com.sun.media.jai.mlib")) {
140: nativeFactory = factory;
141: if (javaFactory != null) {
142: currentState = Boolean.FALSE;
143: }
144: }
145: if (pack.equals("com.sun.media.jai.opimage")) {
146: javaFactory = factory;
147: if (nativeFactory != null) {
148: currentState = Boolean.TRUE;
149: }
150: }
151: }
152: if (currentState != null
153: && currentState.booleanValue() != allowed) {
154: RIFRegistry.unsetPreference(registry, operation,
155: product, allowed ? javaFactory : nativeFactory,
156: allowed ? nativeFactory : javaFactory);
157: RIFRegistry.setPreference(registry, operation, product,
158: allowed ? nativeFactory : javaFactory,
159: allowed ? javaFactory : nativeFactory);
160: final LogRecord record = Logging.format(Level.CONFIG,
161: LoggingKeys.NATIVE_ACCELERATION_STATE_$2,
162: operation, new Integer(allowed ? 1 : 0));
163: log("setNativeAccelerationAllowed", record);
164: }
165: }
166: }
167:
168: /**
169: * Log the specified record.
170: */
171: private static void log(final String method, final LogRecord record) {
172: record.setSourceClassName(Registry.class.getName());
173: record.setSourceMethodName(method);
174: org.geotools.util.logging.Logging.getLogger(
175: "org.geotools.image").log(record);
176: }
177: }
|