This commit is contained in:
J. Duke 2017-07-05 16:37:14 +02:00
commit 7c5220bfee
144 changed files with 17955 additions and 528 deletions

View File

@ -1,3 +1,4 @@
cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24
cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
9410f77cc30c604d1caf7c9fe3a57fa19e1acbe8 jdk7-b26
11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27

View File

@ -1,3 +1,4 @@
55540e827aef970ecc010b7e06b912d991c8e3ce jdk7-b24
5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25
0043eb3d4e628f049ff80a8c223b5657136085e7 jdk7-b26
e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27

View File

@ -1,3 +1,4 @@
a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24
7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25
ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26
e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27

View File

@ -1,3 +1,4 @@
37a05a11f281b4d238e2f9e7ebb67c63f64d0e77 jdk7-b24
75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
fb57027902e04ecafceae31a605e69b436c23d57 jdk7-b26
3e599d98875ddf919c8ea11cff9b3a99ba631a9b jdk7-b27

View File

@ -126,44 +126,10 @@ com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
com/sun/media/sound/SimpleInputDeviceProvider.class
PLUG_AWT_CLASS_NAMES = \
java/awt/color/CMMException.class \
java/awt/color/ColorSpace.class \
java/awt/color/ICC_ColorSpace.class \
java/awt/color/ICC_Profile\$$1.class \
java/awt/color/ICC_Profile\$$2.class \
java/awt/color/ICC_Profile\$$3.class \
java/awt/color/ICC_Profile.class \
java/awt/color/ICC_ProfileGray.class \
java/awt/color/ICC_ProfileRGB.class \
java/awt/image/BandedSampleModel.class \
java/awt/image/ColorConvertOp.class \
java/awt/image/ComponentSampleModel.class \
java/awt/image/DataBuffer\$$1.class \
java/awt/image/DataBuffer.class \
java/awt/image/DataBufferByte.class \
java/awt/image/DataBufferInt.class \
java/awt/image/DataBufferShort.class \
java/awt/image/DataBufferUShort.class \
java/awt/image/MultiPixelPackedSampleModel.class \
java/awt/image/Raster.class \
java/awt/image/RenderedImage.class \
java/awt/image/SampleModel.class \
java/awt/image/SinglePixelPackedSampleModel.class \
java/awt/image/WritableRaster.class \
java/awt/image/WritableRenderedImage.class \
java/awt/image/renderable/ContextualRenderedImageFactory.class \
java/awt/image/renderable/ParameterBlock.class \
java/awt/image/renderable/RenderContext.class \
java/awt/image/renderable/RenderableImage.class \
java/awt/image/renderable/RenderableImageOp.class \
java/awt/image/renderable/RenderableImageProducer.class \
java/awt/image/renderable/RenderedImageFactory.class
# Class list temp files (used by both import and export of plugs)
PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
PLUG_CLASS_AREAS = jmf sound awt
PLUG_CLASS_AREAS = jmf sound
PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
# Create jargs file command
@ -186,11 +152,6 @@ $(PLUG_TEMPDIR)/sound.clist:
@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
$(ECHO) "$$i" >> $@ ; \
done
$(PLUG_TEMPDIR)/awt.clist:
@$(prep-target)
@for i in $(PLUG_AWT_CLASS_NAMES) ; do \
$(ECHO) "$$i" >> $@ ; \
done
$(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
@$(prep-target)
$(CAT) $(PLUG_CLISTS) > $@
@ -198,8 +159,6 @@ $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
$(plug-create-jargs)
$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
$(plug-create-jargs)
$(PLUG_TEMPDIR)/awt.jargs: $(PLUG_TEMPDIR)/awt.clist
$(plug-create-jargs)
$(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
$(plug-create-jargs)
@ -235,15 +194,12 @@ import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
import-binary-plug-awt-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/awt.clist
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/awt.clist)
# Import all classes from the jar file
import-binary-plug-jar: \
import-binary-plug-jmf-classes \
import-binary-plug-sound-classes \
import-binary-plug-awt-classes
import-binary-plug-sound-classes
# Import native libraries
@ -286,7 +242,6 @@ import-binary-plugs: \
import-binary-plug-jar \
import-binary-plug-jmf-classes \
import-binary-plug-sound-classes \
import-binary-plug-awt-classes \
import-binary-plug-jsound-library
else # !OPENJDK

View File

@ -148,13 +148,15 @@ ifeq ($(PLATFORM),windows)
ECHO = $(UNIXCOMMAND_PATH)echo -e
ZIPEXE = $(UNIXCOMMAND_PATH)zip
UNZIP = $(UNIXCOMMAND_PATH)unzip
# Some CYGWIN nawk versions require BINMODE=w for proper '\r' interpretation
NAWK = $(UNIXCOMMAND_PATH)awk -v BINMODE=w
else
ZIPEXE = $(UTILS_DEVTOOL_PATH)zip
UNZIP = $(UTILS_DEVTOOL_PATH)unzip
NAWK = $(UNIXCOMMAND_PATH)awk
endif
# Re-define some utilities
LEX =# override GNU Make intrinsic: no lex on windows
NAWK = $(UNIXCOMMAND_PATH)awk
endif
# Linux specific

View File

@ -28,24 +28,12 @@ PACKAGE = java.awt
PRODUCT = sun
include $(BUILDDIR)/common/Defs.gmk
# WARNING: Make sure the OPENJDK plugs are up-to-date, see make/common/internal/BinaryPlugs.gmk
#
# Files
#
AUTO_FILES_JAVA_DIRS = java/awt sun/awt/geom
#
# Specific to OPENJDK
#
ifdef OPENJDK
build: import-binary-plug-awt-classes
include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
endif
build: properties cursors
#

View File

@ -394,7 +394,7 @@ LOCALES_GEN_SH = localelist.sh
$(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \
$(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java $(LOCALES_GEN_SH)
@$(prep-target)
NAWK=$(NAWK) SED=$(SED) $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
$< $@
clean::
$(RM) $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java

View File

@ -191,7 +191,7 @@ sources: $(SPP) $(FILES_genout)
GEN_BUFFER_SH = genBuffer.sh
GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) SH=$(SH) \
GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK="$(NAWK)" SED="$(SED)" SH="$(SH)" \
$(SH) $(GEN_BUFFER_SH)
# Public abstract buffer classes
@ -582,7 +582,7 @@ $(BUF_GEN)/ByteBufferAsDoubleBuffer%L.java: $(BUF_SRC)/ByteBufferAs-X-Buffer.jav
GEN_CODER_SH = genCoder.sh
GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_CODER_SH)
GEN_CODER_CMD = SPP="$(SPP_CMD)" SED="$(SED)" NAWK="$(NAWK)" SH="$(SH)" $(SH) $(GEN_CODER_SH)
$(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
$(prep-target)
@ -602,7 +602,7 @@ $(CS_GEN)/CharsetEncoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
GEN_EX_SH = genExceptions.sh
GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH)
GEN_EX_CMD = NAWK="$(NAWK)" SH="$(SH)" $(SH) $(GEN_EX_SH)
$(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions
$(prep-target)
@ -635,7 +635,7 @@ $(SCS_GEN)/StandardCharsets.java: genCharsetProvider.sh \
$(HASHER_JARFILE) $(SCS_SRC)/standard-charsets
$(prep-target)
@$(RM) $@.temp
NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) SH=$(SH) \
NAWK="$(NAWK)" TEMPDIR="$(TEMPDIR)" SH="$(SH)" \
HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \
$(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)

View File

@ -41,12 +41,8 @@ endif # OPENJDK
ICCPROFILE_DEST_DIR = $(LIBDIR)/cmm
iccprofiles: $(ICCPROFILE_DEST_DIR)/sRGB.pf $(ICCPROFILE_DEST_DIR)/GRAY.pf \
$(ICCPROFILE_DEST_DIR)/CIEXYZ.pf
ifndef OPENJDK
iccprofiles: $(ICCPROFILE_DEST_DIR)/PYCC.pf \
$(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
endif
$(ICCPROFILE_DEST_DIR)/CIEXYZ.pf $(ICCPROFILE_DEST_DIR)/PYCC.pf \
$(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
$(ICCPROFILE_DEST_DIR)/sRGB.pf: $(ICCPROFILE_SRC_DIR)/sRGB.pf
$(RM) $(ICCPROFILE_DEST_DIR)/sRGB.pf

View File

@ -113,7 +113,9 @@ FILES_cpp_shared = \
ifeq ($(PLATFORM),windows)
FILES_c_platform = fontpath.c
FILES_c_platform = fontpath.c \
lcdglyph.c
FILES_cpp_platform = D3DTextRenderer.cpp
else
FILES_c_platform = X11FontScaler.c \

View File

@ -63,6 +63,7 @@ FILES_export = \
java/awt/Font.java \
java/text/Bidi.java \
sun/font/FileFont.java \
sun/font/FileFontStrike.java \
sun/font/FontManager.java \
sun/font/GlyphList.java \
sun/font/NativeFont.java \

View File

@ -233,7 +233,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException {
ObjectName logicalName = name;
Class theClass;
if (className == null) {
@ -519,8 +518,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
QueryExp query) {
// Query the MBeans on the repository
//
Set<NamedObject> list = null;
list = repository.query(name, query);
Set<NamedObject> list = repository.query(name, query);
if (queryByRepo) {
// The repository performs the filtering
@ -576,8 +574,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
private Set<ObjectName> queryNamesImpl(ObjectName name, QueryExp query) {
// Query the MBeans on the repository
//
Set<NamedObject> list = null;
list = repository.query(name, query);
Set<NamedObject> list = repository.query(name, query);
if (queryByRepo) {
// The repository performs the filtering
@ -1042,7 +1039,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if (registerFailed && moi instanceof DynamicMBean2)
((DynamicMBean2) moi).registerFailed();
try {
moi.postRegister(new Boolean(registrationDone));
moi.postRegister(registrationDone);
} catch (RuntimeException e) {
throw new RuntimeMBeanException(e,
"RuntimeException thrown in postRegister method");
@ -1094,8 +1091,7 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
IllegalArgumentException("Object name cannot be null"),
"Exception occurred trying to get an MBean");
}
DynamicMBean obj = null;
obj = repository.retrieve(name);
DynamicMBean obj = repository.retrieve(name);
if (obj == null) {
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER,
@ -1568,7 +1564,6 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
query.setMBeanServer(server);
try {
for (NamedObject no : list) {
final DynamicMBean obj = no.getObject();
boolean res;
try {
res = query.apply(no.getName());

View File

@ -205,7 +205,7 @@ public class MBeanInstantiator {
*/
public Object instantiate(Class theClass)
throws ReflectionException, MBeanException {
Object moi = null;
Object moi;
// ------------------------------
@ -265,7 +265,7 @@ public class MBeanInstantiator {
// ------------------------------
// ------------------------------
final Class[] tab;
Object moi= null;
Object moi;
try {
// Build the signature of the method
//
@ -283,8 +283,7 @@ public class MBeanInstantiator {
}
// Query the metadata service to get the right constructor
Constructor cons = null;
cons = findConstructor(theClass, tab);
Constructor cons = findConstructor(theClass, tab);
if (cons == null) {
throw new ReflectionException(new
@ -408,7 +407,7 @@ public class MBeanInstantiator {
throw new RuntimeOperationsException(new
IllegalArgumentException(), "Null className passed in parameter");
}
Class theClass = null;
Class theClass;
if (loaderName == null) {
// Load the class using the agent class loader
theClass = findClass(className, loader);
@ -621,7 +620,7 @@ public class MBeanInstantiator {
static Class loadClass(String className, ClassLoader loader)
throws ReflectionException {
Class theClass = null;
Class theClass;
if (className == null) {
throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"),

View File

@ -89,7 +89,6 @@ public class Repository {
/* This class is used to match an ObjectName against a pattern. */
private final static class ObjectNamePattern {
private final char[] domain;
private final String[] keys;
private final String[] values;
private final String properties;
@ -106,8 +105,7 @@ public class Repository {
* @param pattern The ObjectName pattern under examination.
**/
public ObjectNamePattern(ObjectName pattern) {
this(pattern.getDomain(),
pattern.isPropertyListPattern(),
this(pattern.isPropertyListPattern(),
pattern.isPropertyValuePattern(),
pattern.getCanonicalKeyPropertyListString(),
pattern.getKeyPropertyList(),
@ -124,13 +122,11 @@ public class Repository {
* @param keyPropertyList pattern.getKeyPropertyList().
* @param pattern The ObjectName pattern under examination.
**/
ObjectNamePattern(String domain,
boolean propertyListPattern,
ObjectNamePattern(boolean propertyListPattern,
boolean propertyValuePattern,
String canonicalProps,
Map<String,String> keyPropertyList,
ObjectName pattern) {
this.domain = domain.toCharArray();
this.isPropertyListPattern = propertyListPattern;
this.isPropertyValuePattern = propertyValuePattern;
this.properties = canonicalProps;
@ -538,7 +534,7 @@ public class Repository {
// "domain:*", "domain:[key=value],*" : names in the specified domain
// Surely one of the most frequent case ... query on the whole world
ObjectName name = null;
ObjectName name;
if (pattern == null ||
pattern.getCanonicalName().length() == 0 ||
pattern.equals(ObjectName.WILDCARD))
@ -660,7 +656,7 @@ public class Repository {
* @return Number of MBeans.
*/
public Integer getCount() {
return new Integer(nbElements);
return nbElements;
}
/**
@ -669,7 +665,7 @@ public class Repository {
*
* @return A string giving the name of the default domain name.
*/
public String getDefaultDomain() {
public String getDefaultDomain() {
return domain;
}

View File

@ -435,7 +435,6 @@ public abstract class ClientNotifForwarder {
clientSequenceNumber = nr.getNextSequenceNumber();
final int size = infoList.size();
listeners = new HashMap<Integer, ClientListenerInfo>();
for (int i = 0 ; i < len ; i++) {
@ -792,9 +791,6 @@ public abstract class ClientNotifForwarder {
private Thread currentFetchThread;
// admin stuff
private boolean inited = false;
// state
/**
* This state means that a thread is being created for fetching and forwarding notifications.

View File

@ -269,7 +269,7 @@ public class ServerNotifForwarder {
", the maxNotifications is " + maxNotifications);
}
NotificationResult nr = null;
NotificationResult nr;
final long t = Math.min(connectionTimeout, timeout);
try {
nr = notifBuffer.fetchNotifications(bufferFilter,
@ -322,7 +322,7 @@ public class ServerNotifForwarder {
private Integer getListenerID() {
synchronized(listenerCounterLock) {
return new Integer(listenerCounter++);
return listenerCounter++;
}
}
@ -336,7 +336,7 @@ public class ServerNotifForwarder {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
AccessControlContext acc = AccessController.getContext();
ObjectInstance oi = null;
ObjectInstance oi;
try {
oi = AccessController.doPrivileged(
new PrivilegedExceptionAction<ObjectInstance>() {

View File

@ -437,7 +437,7 @@ public class FileLoginModule implements LoginModule {
// get the username and password
getUsernamePassword(usePasswdFromSharedState);
String localPassword = null;
String localPassword;
// userCredentials is initialized in login()
if (((localPassword = userCredentials.getProperty(username)) == null) ||
@ -487,10 +487,14 @@ public class FileLoginModule implements LoginModule {
throw ace;
}
}
BufferedInputStream bis = new BufferedInputStream(fis);
userCredentials = new Properties();
userCredentials.load(bis);
bis.close();
try {
BufferedInputStream bis = new BufferedInputStream(fis);
userCredentials = new Properties();
userCredentials.load(bis);
bis.close();
} finally {
fis.close();
}
}
/**

View File

@ -295,7 +295,7 @@ private final class JMXCallbackHandler implements CallbackHandler {
private static class FileLoginConfig extends Configuration {
// The JAAS configuration for file-based authentication
private static AppConfigurationEntry[] entries;
private AppConfigurationEntry[] entries;
// The classname of the login module for file-based authentication
private static final String FILE_LOGIN_MODULE =

View File

@ -231,10 +231,13 @@ public class MBeanServerFileAccessController
private static Properties propertiesFromFile(String fname)
throws IOException {
FileInputStream fin = new FileInputStream(fname);
Properties p = new Properties();
p.load(fin);
fin.close();
return p;
try {
Properties p = new Properties();
p.load(fin);
return p;
} finally {
fin.close();
}
}
private void checkAccessLevel(String accessLevel) {

View File

@ -711,7 +711,7 @@ public class Font implements java.io.Serializable
EBIDI_EMBEDDING, EJUSTIFICATION,
EINPUT_METHOD_HIGHLIGHT, EINPUT_METHOD_UNDERLINE,
ESWAP_COLORS, ENUMERIC_SHAPING, EKERNING,
ELIGATURES, ETRACKING);
ELIGATURES, ETRACKING, ESUPERSCRIPT);
private static final int EXTRA_MASK =
AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH);
@ -1970,7 +1970,6 @@ public class Font implements java.io.Serializable
* in the JDK - and the only likely caller - is in this same class.
*/
private float getItalicAngle(FontRenderContext frc) {
AffineTransform at = (isTransformed()) ? getTransform() : identityTx;
Object aa, fm;
if (frc == null) {
aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
@ -1979,7 +1978,7 @@ public class Font implements java.io.Serializable
aa = frc.getAntiAliasingHint();
fm = frc.getFractionalMetricsHint();
}
return getFont2D().getItalicAngle(this, at, aa, fm);
return getFont2D().getItalicAngle(this, identityTx, aa, fm);
}
/**

View File

@ -0,0 +1,57 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
Created by gbp, October 25, 1997
*
*/
/**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
/**
* This exception is thrown if the native CMM returns an error.
*/
public class CMMException extends java.lang.RuntimeException {
/**
* Constructs a CMMException with the specified detail message.
* @param s the specified detail message
*/
public CMMException (String s) {
super (s);
}
}

View File

@ -0,0 +1,611 @@
/*
* Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager;
/**
* This abstract class is used to serve as a color space tag to identify the
* specific color space of a Color object or, via a ColorModel object,
* of an Image, a BufferedImage, or a GraphicsDevice. It contains
* methods that transform colors in a specific color space to/from sRGB
* and to/from a well-defined CIEXYZ color space.
* <p>
* For purposes of the methods in this class, colors are represented as
* arrays of color components represented as floats in a normalized range
* defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
* range is 0.0 to 1.0. However, some ColorSpaces have components whose
* values have a different range. Methods are provided to inquire per
* component minimum and maximum normalized values.
* <p>
* Several variables are defined for purposes of referring to color
* space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
* color spaces (e.g. CS_sRGB and CS_CIEXYZ).
* sRGB is a proposed standard RGB color space. For more information,
* see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
* </A>.
* <p>
* The purpose of the methods to transform to/from the well-defined
* CIEXYZ color space is to support conversions between any two color
* spaces at a reasonably high degree of accuracy. It is expected that
* particular implementations of subclasses of ColorSpace (e.g.
* ICC_ColorSpace) will support high performance conversion based on
* underlying platform color management systems.
* <p>
* The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
* described as follows:
<pre>
&nbsp; CIEXYZ
&nbsp; viewing illuminance: 200 lux
&nbsp; viewing white point: CIE D50
&nbsp; media white point: "that of a perfectly reflecting diffuser" -- D50
&nbsp; media black point: 0 lux or 0 Reflectance
&nbsp; flare: 1 percent
&nbsp; surround: 20percent of the media white point
&nbsp; media description: reflection print (i.e., RLAB, Hunt viewing media)
&nbsp; note: For developers creating an ICC profile for this conversion
&nbsp; space, the following is applicable. Use a simple Von Kries
&nbsp; white point adaptation folded into the 3X3 matrix parameters
&nbsp; and fold the flare and surround effects into the three
&nbsp; one-dimensional lookup tables (assuming one uses the minimal
&nbsp; model for monitors).
</pre>
*
* <p>
* @see ICC_ColorSpace
*/
public abstract class ColorSpace implements java.io.Serializable {
static final long serialVersionUID = -409452704308689724L;
private int type;
private int numComponents;
private transient String [] compName = null;
// Cache of singletons for the predefined color spaces.
private static ColorSpace sRGBspace;
private static ColorSpace XYZspace;
private static ColorSpace PYCCspace;
private static ColorSpace GRAYspace;
private static ColorSpace LINEAR_RGBspace;
/**
* Any of the family of XYZ color spaces.
*/
public static final int TYPE_XYZ = 0;
/**
* Any of the family of Lab color spaces.
*/
public static final int TYPE_Lab = 1;
/**
* Any of the family of Luv color spaces.
*/
public static final int TYPE_Luv = 2;
/**
* Any of the family of YCbCr color spaces.
*/
public static final int TYPE_YCbCr = 3;
/**
* Any of the family of Yxy color spaces.
*/
public static final int TYPE_Yxy = 4;
/**
* Any of the family of RGB color spaces.
*/
public static final int TYPE_RGB = 5;
/**
* Any of the family of GRAY color spaces.
*/
public static final int TYPE_GRAY = 6;
/**
* Any of the family of HSV color spaces.
*/
public static final int TYPE_HSV = 7;
/**
* Any of the family of HLS color spaces.
*/
public static final int TYPE_HLS = 8;
/**
* Any of the family of CMYK color spaces.
*/
public static final int TYPE_CMYK = 9;
/**
* Any of the family of CMY color spaces.
*/
public static final int TYPE_CMY = 11;
/**
* Generic 2 component color spaces.
*/
public static final int TYPE_2CLR = 12;
/**
* Generic 3 component color spaces.
*/
public static final int TYPE_3CLR = 13;
/**
* Generic 4 component color spaces.
*/
public static final int TYPE_4CLR = 14;
/**
* Generic 5 component color spaces.
*/
public static final int TYPE_5CLR = 15;
/**
* Generic 6 component color spaces.
*/
public static final int TYPE_6CLR = 16;
/**
* Generic 7 component color spaces.
*/
public static final int TYPE_7CLR = 17;
/**
* Generic 8 component color spaces.
*/
public static final int TYPE_8CLR = 18;
/**
* Generic 9 component color spaces.
*/
public static final int TYPE_9CLR = 19;
/**
* Generic 10 component color spaces.
*/
public static final int TYPE_ACLR = 20;
/**
* Generic 11 component color spaces.
*/
public static final int TYPE_BCLR = 21;
/**
* Generic 12 component color spaces.
*/
public static final int TYPE_CCLR = 22;
/**
* Generic 13 component color spaces.
*/
public static final int TYPE_DCLR = 23;
/**
* Generic 14 component color spaces.
*/
public static final int TYPE_ECLR = 24;
/**
* Generic 15 component color spaces.
*/
public static final int TYPE_FCLR = 25;
/**
* The sRGB color space defined at
* <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
* </A>.
*/
public static final int CS_sRGB = 1000;
/**
* A built-in linear RGB color space. This space is based on the
* same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
*/
public static final int CS_LINEAR_RGB = 1004;
/**
* The CIEXYZ conversion color space defined above.
*/
public static final int CS_CIEXYZ = 1001;
/**
* The Photo YCC conversion color space.
*/
public static final int CS_PYCC = 1002;
/**
* The built-in linear gray scale color space.
*/
public static final int CS_GRAY = 1003;
/**
* Constructs a ColorSpace object given a color space type
* and the number of components.
* @param type one of the <CODE>ColorSpace</CODE> type constants
* @param numcomponents the number of components in the color space
*/
protected ColorSpace (int type, int numcomponents) {
this.type = type;
this.numComponents = numcomponents;
}
/**
* Returns a ColorSpace representing one of the specific
* predefined color spaces.
* @param colorspace a specific color space identified by one of
* the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
* CS_CIEXYZ, CS_GRAY, or CS_PYCC)
* @return the requested <CODE>ColorSpace</CODE> object
*/
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public static ColorSpace getInstance (int colorspace)
{
ColorSpace theColorSpace;
switch (colorspace) {
case CS_sRGB:
synchronized(ColorSpace.class) {
if (sRGBspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
sRGBspace = new ICC_ColorSpace (theProfile);
}
theColorSpace = sRGBspace;
}
break;
case CS_CIEXYZ:
synchronized(ColorSpace.class) {
if (XYZspace == null) {
ICC_Profile theProfile =
ICC_Profile.getInstance (CS_CIEXYZ);
XYZspace = new ICC_ColorSpace (theProfile);
}
theColorSpace = XYZspace;
}
break;
case CS_PYCC:
synchronized(ColorSpace.class) {
if (PYCCspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
PYCCspace = new ICC_ColorSpace (theProfile);
}
theColorSpace = PYCCspace;
}
break;
case CS_GRAY:
synchronized(ColorSpace.class) {
if (GRAYspace == null) {
ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
GRAYspace = new ICC_ColorSpace (theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.GRAYspace = GRAYspace;
}
theColorSpace = GRAYspace;
}
break;
case CS_LINEAR_RGB:
synchronized(ColorSpace.class) {
if (LINEAR_RGBspace == null) {
ICC_Profile theProfile =
ICC_Profile.getInstance(CS_LINEAR_RGB);
LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
/* to allow access from java.awt.ColorModel */
CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
}
theColorSpace = LINEAR_RGBspace;
}
break;
default:
throw new IllegalArgumentException ("Unknown color space");
}
return theColorSpace;
}
/**
* Returns true if the ColorSpace is CS_sRGB.
* @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
* space, <code>false</code> if it is not
*/
public boolean isCS_sRGB () {
/* REMIND - make sure we know sRGBspace exists already */
return (this == sRGBspace);
}
/**
* Transforms a color value assumed to be in this ColorSpace
* into a value in the default CS_sRGB color space.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of this color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace
*/
public abstract float[] toRGB(float[] colorvalue);
/**
* Transforms a color value assumed to be in the default CS_sRGB
* color space into this ColorSpace.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of the CS_sRGB color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of this color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param rgbvalue a float array with length of at least 3
* @return a float array with length equal to the number of
* components in this ColorSpace
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3
*/
public abstract float[] fromRGB(float[] rgbvalue);
/**
* Transforms a color value assumed to be in this ColorSpace
* into the CS_CIEXYZ conversion color space.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the International Color Consortium standard. This
* means that the XYZ values returned by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. This
* representation is not the same as the XYZ values that would
* be measured from the given color value by a colorimeter.
* A further transformation is necessary to compute the XYZ values
* that would be measured using current CIE recommended practices.
* See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
* <code>ICC_ColorSpace</code> for further information.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace
* @return a float array of length 3
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace.
*/
public abstract float[] toCIEXYZ(float[] colorvalue);
/**
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
* color space into this ColorSpace.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the International Color Consortium standard. This
* means that the XYZ argument values taken by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. The color
* values returned by this method are not those that would produce
* the XYZ value passed to the method when measured by a colorimeter.
* If you have XYZ values corresponding to measurements made using
* current CIE recommended practices, they must be converted to D50
* relative values before being passed to this method.
* See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
* <code>ICC_ColorSpace</code> for further information.
* <p>
* @param colorvalue a float array with length of at least 3
* @return a float array with length equal to the number of
* components in this ColorSpace
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3
*/
public abstract float[] fromCIEXYZ(float[] colorvalue);
/**
* Returns the color space type of this ColorSpace (for example
* TYPE_RGB, TYPE_XYZ, ...). The type defines the
* number of components of the color space and the interpretation,
* e.g. TYPE_RGB identifies a color space with three components - red,
* green, and blue. It does not define the particular color
* characteristics of the space, e.g. the chromaticities of the
* primaries.
*
* @return the type constant that represents the type of this
* <CODE>ColorSpace</CODE>
*/
public int getType() {
return type;
}
/**
* Returns the number of components of this ColorSpace.
* @return The number of components in this <CODE>ColorSpace</CODE>.
*/
public int getNumComponents() {
return numComponents;
}
/**
* Returns the name of the component given the component index.
*
* @param idx the component index
* @return the name of the component at the specified index
* @throws IllegalArgumentException if <code>idx</code> is
* less than 0 or greater than numComponents - 1
*/
public String getName (int idx) {
/* REMIND - handle common cases here */
if ((idx < 0) || (idx > numComponents - 1)) {
throw new IllegalArgumentException(
"Component index out of range: " + idx);
}
if (compName == null) {
switch (type) {
case ColorSpace.TYPE_XYZ:
compName = new String[] {"X", "Y", "Z"};
break;
case ColorSpace.TYPE_Lab:
compName = new String[] {"L", "a", "b"};
break;
case ColorSpace.TYPE_Luv:
compName = new String[] {"L", "u", "v"};
break;
case ColorSpace.TYPE_YCbCr:
compName = new String[] {"Y", "Cb", "Cr"};
break;
case ColorSpace.TYPE_Yxy:
compName = new String[] {"Y", "x", "y"};
break;
case ColorSpace.TYPE_RGB:
compName = new String[] {"Red", "Green", "Blue"};
break;
case ColorSpace.TYPE_GRAY:
compName = new String[] {"Gray"};
break;
case ColorSpace.TYPE_HSV:
compName = new String[] {"Hue", "Saturation", "Value"};
break;
case ColorSpace.TYPE_HLS:
compName = new String[] {"Hue", "Lightness",
"Saturation"};
break;
case ColorSpace.TYPE_CMYK:
compName = new String[] {"Cyan", "Magenta", "Yellow",
"Black"};
break;
case ColorSpace.TYPE_CMY:
compName = new String[] {"Cyan", "Magenta", "Yellow"};
break;
default:
String [] tmp = new String[numComponents];
for (int i = 0; i < tmp.length; i++) {
tmp[i] = "Unnamed color component(" + i + ")";
}
compName = tmp;
}
}
return compName[idx];
}
/**
* Returns the minimum normalized color component value for the
* specified component. The default implementation in this abstract
* class returns 0.0 for all components. Subclasses should override
* this method if necessary.
*
* @param component the component index
* @return the minimum normalized component value
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1
* @since 1.4
*/
public float getMinValue(int component) {
if ((component < 0) || (component > numComponents - 1)) {
throw new IllegalArgumentException(
"Component index out of range: " + component);
}
return 0.0f;
}
/**
* Returns the maximum normalized color component value for the
* specified component. The default implementation in this abstract
* class returns 1.0 for all components. Subclasses should override
* this method if necessary.
*
* @param component the component index
* @return the maximum normalized component value
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1
* @since 1.4
*/
public float getMaxValue(int component) {
if ((component < 0) || (component > numComponents - 1)) {
throw new IllegalArgumentException(
"Component index out of range: " + component);
}
return 1.0f;
}
/* Returns true if cspace is the XYZspace.
*/
static boolean isCS_CIEXYZ(ColorSpace cspace) {
return (cspace == XYZspace);
}
}

View File

@ -0,0 +1,616 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.CMSManager;
import sun.java2d.cmm.PCMM;
/**
*
* The ICC_ColorSpace class is an implementation of the abstract
* ColorSpace class. This representation of
* device independent and device dependent color spaces is based on the
* International Color Consortium Specification ICC.1:2001-12, File Format for
* Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
* <p>
* Typically, a Color or ColorModel would be associated with an ICC
* Profile which is either an input, display, or output profile (see
* the ICC specification). There are other types of ICC Profiles, e.g.
* abstract profiles, device link profiles, and named color profiles,
* which do not contain information appropriate for representing the color
* space of a color, image, or device (see ICC_Profile).
* Attempting to create an ICC_ColorSpace object from an inappropriate ICC
* Profile is an error.
* <p>
* ICC Profiles represent transformations from the color space of
* the profile (e.g. a monitor) to a Profile Connection Space (PCS).
* Profiles of interest for tagging images or colors have a
* PCS which is one of the device independent
* spaces (one CIEXYZ space and two CIELab spaces) defined in the
* ICC Profile Format Specification. Most profiles of interest
* either have invertible transformations or explicitly specify
* transformations going both directions. Should an ICC_ColorSpace
* object be used in a way requiring a conversion from PCS to
* the profile's native space and there is inadequate data to
* correctly perform the conversion, the ICC_ColorSpace object will
* produce output in the specified type of color space (e.g. TYPE_RGB,
* TYPE_CMYK, etc.), but the specific color values of the output data
* will be undefined.
* <p>
* The details of this class are not important for simple applets,
* which draw in a default color space or manipulate and display
* imported images with a known color space. At most, such applets
* would need to get one of the default color spaces via
* ColorSpace.getInstance().
* <p>
* @see ColorSpace
* @see ICC_Profile
*/
public class ICC_ColorSpace extends ColorSpace {
static final long serialVersionUID = 3455889114070431483L;
private ICC_Profile thisProfile;
private float[] minVal;
private float[] maxVal;
private float[] diffMinMax;
private float[] invDiffMinMax;
private boolean needScaleInit = true;
// {to,from}{RGB,CIEXYZ} methods create and cache these when needed
private transient ColorTransform this2srgb;
private transient ColorTransform srgb2this;
private transient ColorTransform this2xyz;
private transient ColorTransform xyz2this;
/**
* Constructs a new ICC_ColorSpace from an ICC_Profile object.
* @param profile the specified ICC_Profile object
* @exception IllegalArgumentException if profile is inappropriate for
* representing a ColorSpace.
*/
public ICC_ColorSpace (ICC_Profile profile) {
super (profile.getColorSpaceType(), profile.getNumComponents());
int profileClass = profile.getProfileClass();
/* REMIND - is NAMEDCOLOR OK? */
if ((profileClass != ICC_Profile.CLASS_INPUT) &&
(profileClass != ICC_Profile.CLASS_DISPLAY) &&
(profileClass != ICC_Profile.CLASS_OUTPUT) &&
(profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
(profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
(profileClass != ICC_Profile.CLASS_ABSTRACT)) {
throw new IllegalArgumentException("Invalid profile type");
}
thisProfile = profile;
setMinMax();
}
/**
* Returns the ICC_Profile for this ICC_ColorSpace.
* @return the ICC_Profile for this ICC_ColorSpace.
*/
public ICC_Profile getProfile() {
return thisProfile;
}
/**
* Transforms a color value assumed to be in this ColorSpace
* into a value in the default CS_sRGB color space.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of this color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace.
* @return a float array of length 3.
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace.
*/
public float[] toRGB (float[] colorvalue) {
if (this2srgb == null) {
ColorTransform[] transformList = new ColorTransform [2];
ICC_ColorSpace srgbCS =
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
PCMM mdl = CMSManager.getModule();
transformList[0] = mdl.createTransform(
thisProfile, ColorTransform.Any, ColorTransform.In);
transformList[1] = mdl.createTransform(
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
this2srgb = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
int nc = this.getNumComponents();
short tmp[] = new short[nc];
for (int i = 0; i < nc; i++) {
tmp[i] = (short)
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
}
tmp = this2srgb.colorConvert(tmp, null);
float[] result = new float [3];
for (int i = 0; i < 3; i++) {
result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
}
return result;
}
/**
* Transforms a color value assumed to be in the default CS_sRGB
* color space into this ColorSpace.
* <p>
* This method transforms color values using algorithms designed
* to produce the best perceptual match between input and output
* colors. In order to do colorimetric conversion of color values,
* you should use the <code>toCIEXYZ</code>
* method of the CS_sRGB color space to first convert from the input
* color space to the CS_CIEXYZ color space, and then use the
* <code>fromCIEXYZ</code> method of this color space to
* convert from CS_CIEXYZ to the output color space.
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
* <p>
* @param rgbvalue a float array with length of at least 3.
* @return a float array with length equal to the number of
* components in this ColorSpace.
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3.
*/
public float[] fromRGB(float[] rgbvalue) {
if (srgb2this == null) {
ColorTransform[] transformList = new ColorTransform [2];
ICC_ColorSpace srgbCS =
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
PCMM mdl = CMSManager.getModule();
transformList[0] = mdl.createTransform(
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
transformList[1] = mdl.createTransform(
thisProfile, ColorTransform.Any, ColorTransform.Out);
srgb2this = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
short tmp[] = new short[3];
for (int i = 0; i < 3; i++) {
tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
}
tmp = srgb2this.colorConvert(tmp, null);
int nc = this.getNumComponents();
float[] result = new float [nc];
for (int i = 0; i < nc; i++) {
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
diffMinMax[i] + minVal[i];
}
return result;
}
/**
* Transforms a color value assumed to be in this ColorSpace
* into the CS_CIEXYZ conversion color space.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the ICC Specification. This
* means that the XYZ values returned by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. This
* representation is not the same as the XYZ values that would
* be measured from the given color value by a colorimeter.
* A further transformation is necessary to compute the XYZ values
* that would be measured using current CIE recommended practices.
* The paragraphs below explain this in more detail.
* <p>
* The ICC standard uses a device independent color space (DICS) as the
* mechanism for converting color from one device to another device. In
* this architecture, colors are converted from the source device's color
* space to the ICC DICS and then from the ICC DICS to the destination
* device's color space. The ICC standard defines device profiles which
* contain transforms which will convert between a device's color space
* and the ICC DICS. The overall conversion of colors from a source
* device to colors of a destination device is done by connecting the
* device-to-DICS transform of the profile for the source device to the
* DICS-to-device transform of the profile for the destination device.
* For this reason, the ICC DICS is commonly referred to as the profile
* connection space (PCS). The color space used in the methods
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
* Specification. This is also the color space represented by
* ColorSpace.CS_CIEXYZ.
* <p>
* The XYZ values of a color are often represented as relative to some
* white point, so the actual meaning of the XYZ values cannot be known
* without knowing the white point of those values. This is known as
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
* values of the PCS are relative to D50. For example, white in the PCS
* will have the XYZ values of D50, which is defined to be X=.9642,
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
* arts applications, but others are often used in other applications.
* <p>
* To quantify the color characteristics of a device such as a printer
* or monitor, measurements of XYZ values for particular device colors
* are typically made. For purposes of this discussion, the term
* device XYZ values is used to mean the XYZ values that would be
* measured from device colors using current CIE recommended practices.
* <p>
* Converting between device XYZ values and the PCS XYZ values returned
* by this method corresponds to converting between the device's color
* space, as represented by CIE colorimetric values, and the PCS. There
* are many factors involved in this process, some of which are quite
* subtle. The most important, however, is the adjustment made to account
* for differences between the device's white point and the white point of
* the PCS. There are many techniques for doing this and it is the
* subject of much current research and controversy. Some commonly used
* methods are XYZ scaling, the von Kries transform, and the Bradford
* transform. The proper method to use depends upon each particular
* application.
* <p>
* The simplest method is XYZ scaling. In this method each device XYZ
* value is converted to a PCS XYZ value by multiplying it by the ratio
* of the PCS white point (D50) to the device white point.
* <pre>
*
* Xd, Yd, Zd are the device XYZ values
* Xdw, Ydw, Zdw are the device XYZ white point values
* Xp, Yp, Zp are the PCS XYZ values
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
*
* Xp = Xd * (Xd50 / Xdw)
* Yp = Yd * (Yd50 / Ydw)
* Zp = Zd * (Zd50 / Zdw)
*
* </pre>
* <p>
* Conversion from the PCS to the device would be done by inverting these
* equations:
* <pre>
*
* Xd = Xp * (Xdw / Xd50)
* Yd = Yp * (Ydw / Yd50)
* Zd = Zp * (Zdw / Zd50)
*
* </pre>
* <p>
* Note that the media white point tag in an ICC profile is not the same
* as the device white point. The media white point tag is expressed in
* PCS values and is used to represent the difference between the XYZ of
* device illuminant and the XYZ of the device media when measured under
* that illuminant. The device white point is expressed as the device
* XYZ values corresponding to white displayed on the device. For
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
* will result in a measured device XYZ value of D65. This will not
* be the same as the media white point tag XYZ value in the ICC
* profile for an sRGB device.
* <p>
* @param colorvalue a float array with length of at least the number
* of components in this ColorSpace.
* @return a float array of length 3.
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least the number of components in this ColorSpace.
*/
public float[] toCIEXYZ(float[] colorvalue) {
if (this2xyz == null) {
ColorTransform[] transformList = new ColorTransform [2];
ICC_ColorSpace xyzCS =
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
PCMM mdl = CMSManager.getModule();
try {
transformList[0] = mdl.createTransform(
thisProfile, ICC_Profile.icRelativeColorimetric,
ColorTransform.In);
} catch (CMMException e) {
transformList[0] = mdl.createTransform(
thisProfile, ColorTransform.Any, ColorTransform.In);
}
transformList[1] = mdl.createTransform(
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
this2xyz = mdl.createTransform (transformList);
if (needScaleInit) {
setComponentScaling();
}
}
int nc = this.getNumComponents();
short tmp[] = new short[nc];
for (int i = 0; i < nc; i++) {
tmp[i] = (short)
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
}
tmp = this2xyz.colorConvert(tmp, null);
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
float[] result = new float [3];
for (int i = 0; i < 3; i++) {
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
}
return result;
}
/**
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
* color space into this ColorSpace.
* <p>
* This method transforms color values using relative colorimetry,
* as defined by the ICC Specification. This
* means that the XYZ argument values taken by this method are represented
* relative to the D50 white point of the CS_CIEXYZ color space.
* This representation is useful in a two-step color conversion
* process in which colors are transformed from an input color
* space to CS_CIEXYZ and then to an output color space. The color
* values returned by this method are not those that would produce
* the XYZ value passed to the method when measured by a colorimeter.
* If you have XYZ values corresponding to measurements made using
* current CIE recommended practices, they must be converted to D50
* relative values before being passed to this method.
* The paragraphs below explain this in more detail.
* <p>
* The ICC standard uses a device independent color space (DICS) as the
* mechanism for converting color from one device to another device. In
* this architecture, colors are converted from the source device's color
* space to the ICC DICS and then from the ICC DICS to the destination
* device's color space. The ICC standard defines device profiles which
* contain transforms which will convert between a device's color space
* and the ICC DICS. The overall conversion of colors from a source
* device to colors of a destination device is done by connecting the
* device-to-DICS transform of the profile for the source device to the
* DICS-to-device transform of the profile for the destination device.
* For this reason, the ICC DICS is commonly referred to as the profile
* connection space (PCS). The color space used in the methods
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
* Specification. This is also the color space represented by
* ColorSpace.CS_CIEXYZ.
* <p>
* The XYZ values of a color are often represented as relative to some
* white point, so the actual meaning of the XYZ values cannot be known
* without knowing the white point of those values. This is known as
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
* values of the PCS are relative to D50. For example, white in the PCS
* will have the XYZ values of D50, which is defined to be X=.9642,
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
* arts applications, but others are often used in other applications.
* <p>
* To quantify the color characteristics of a device such as a printer
* or monitor, measurements of XYZ values for particular device colors
* are typically made. For purposes of this discussion, the term
* device XYZ values is used to mean the XYZ values that would be
* measured from device colors using current CIE recommended practices.
* <p>
* Converting between device XYZ values and the PCS XYZ values taken as
* arguments by this method corresponds to converting between the device's
* color space, as represented by CIE colorimetric values, and the PCS.
* There are many factors involved in this process, some of which are quite
* subtle. The most important, however, is the adjustment made to account
* for differences between the device's white point and the white point of
* the PCS. There are many techniques for doing this and it is the
* subject of much current research and controversy. Some commonly used
* methods are XYZ scaling, the von Kries transform, and the Bradford
* transform. The proper method to use depends upon each particular
* application.
* <p>
* The simplest method is XYZ scaling. In this method each device XYZ
* value is converted to a PCS XYZ value by multiplying it by the ratio
* of the PCS white point (D50) to the device white point.
* <pre>
*
* Xd, Yd, Zd are the device XYZ values
* Xdw, Ydw, Zdw are the device XYZ white point values
* Xp, Yp, Zp are the PCS XYZ values
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
*
* Xp = Xd * (Xd50 / Xdw)
* Yp = Yd * (Yd50 / Ydw)
* Zp = Zd * (Zd50 / Zdw)
*
* </pre>
* <p>
* Conversion from the PCS to the device would be done by inverting these
* equations:
* <pre>
*
* Xd = Xp * (Xdw / Xd50)
* Yd = Yp * (Ydw / Yd50)
* Zd = Zp * (Zdw / Zd50)
*
* </pre>
* <p>
* Note that the media white point tag in an ICC profile is not the same
* as the device white point. The media white point tag is expressed in
* PCS values and is used to represent the difference between the XYZ of
* device illuminant and the XYZ of the device media when measured under
* that illuminant. The device white point is expressed as the device
* XYZ values corresponding to white displayed on the device. For
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
* will result in a measured device XYZ value of D65. This will not
* be the same as the media white point tag XYZ value in the ICC
* profile for an sRGB device.
* <p>
* <p>
* @param colorvalue a float array with length of at least 3.
* @return a float array with length equal to the number of
* components in this ColorSpace.
* @throws ArrayIndexOutOfBoundsException if array length is not
* at least 3.
*/
public float[] fromCIEXYZ(float[] colorvalue) {
if (xyz2this == null) {
ColorTransform[] transformList = new ColorTransform [2];
ICC_ColorSpace xyzCS =
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
PCMM mdl = CMSManager.getModule();
transformList[0] = mdl.createTransform (
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
try {
transformList[1] = mdl.createTransform(
thisProfile, ICC_Profile.icRelativeColorimetric,
ColorTransform.Out);
} catch (CMMException e) {
transformList[1] = CMSManager.getModule().createTransform(
thisProfile, ColorTransform.Any, ColorTransform.Out);
}
xyz2this = mdl.createTransform(transformList);
if (needScaleInit) {
setComponentScaling();
}
}
short tmp[] = new short[3];
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
float factor = 65535.0f / ALMOST_TWO;
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
for (int i = 0; i < 3; i++) {
tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
}
tmp = xyz2this.colorConvert(tmp, null);
int nc = this.getNumComponents();
float[] result = new float [nc];
for (int i = 0; i < nc; i++) {
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
diffMinMax[i] + minVal[i];
}
return result;
}
/**
* Returns the minimum normalized color component value for the
* specified component. For TYPE_XYZ spaces, this method returns
* minimum values of 0.0 for all components. For TYPE_Lab spaces,
* this method returns 0.0 for L and -128.0 for a and b components.
* This is consistent with the encoding of the XYZ and Lab Profile
* Connection Spaces in the ICC specification. For all other types, this
* method returns 0.0 for all components. When using an ICC_ColorSpace
* with a profile that requires different minimum component values,
* it is necessary to subclass this class and override this method.
* @param component The component index.
* @return The minimum normalized component value.
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1.
* @since 1.4
*/
public float getMinValue(int component) {
if ((component < 0) || (component > this.getNumComponents() - 1)) {
throw new IllegalArgumentException(
"Component index out of range: + component");
}
return minVal[component];
}
/**
* Returns the maximum normalized color component value for the
* specified component. For TYPE_XYZ spaces, this method returns
* maximum values of 1.0 + (32767.0 / 32768.0) for all components.
* For TYPE_Lab spaces,
* this method returns 100.0 for L and 127.0 for a and b components.
* This is consistent with the encoding of the XYZ and Lab Profile
* Connection Spaces in the ICC specification. For all other types, this
* method returns 1.0 for all components. When using an ICC_ColorSpace
* with a profile that requires different maximum component values,
* it is necessary to subclass this class and override this method.
* @param component The component index.
* @return The maximum normalized component value.
* @throws IllegalArgumentException if component is less than 0 or
* greater than numComponents - 1.
* @since 1.4
*/
public float getMaxValue(int component) {
if ((component < 0) || (component > this.getNumComponents() - 1)) {
throw new IllegalArgumentException(
"Component index out of range: + component");
}
return maxVal[component];
}
private void setMinMax() {
int nc = this.getNumComponents();
int type = this.getType();
minVal = new float[nc];
maxVal = new float[nc];
if (type == ColorSpace.TYPE_Lab) {
minVal[0] = 0.0f; // L
maxVal[0] = 100.0f;
minVal[1] = -128.0f; // a
maxVal[1] = 127.0f;
minVal[2] = -128.0f; // b
maxVal[2] = 127.0f;
} else if (type == ColorSpace.TYPE_XYZ) {
minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
} else {
for (int i = 0; i < nc; i++) {
minVal[i] = 0.0f;
maxVal[i] = 1.0f;
}
}
}
private void setComponentScaling() {
int nc = this.getNumComponents();
diffMinMax = new float[nc];
invDiffMinMax = new float[nc];
for (int i = 0; i < nc; i++) {
minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
diffMinMax[i] = maxVal[i] - minVal[i];
invDiffMinMax[i] = 65535.0f / diffMinMax[i];
}
needScaleInit = false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
*
* A subclass of the ICC_Profile class which represents profiles
* which meet the following criteria: the color space type of the
* profile is TYPE_GRAY and the profile includes the grayTRCTag and
* mediaWhitePointTag tags. Examples of this kind of profile are
* monochrome input profiles, monochrome display profiles, and
* monochrome output profiles. The getInstance methods in the
* ICC_Profile class will
* return an ICC_ProfileGray object when the above conditions are
* met. The advantage of this class is that it provides a lookup
* table that Java or native methods may be able to use directly to
* optimize color conversion in some cases.
* <p>
* To transform from a GRAY device profile color space to the CIEXYZ Profile
* Connection Space, the device gray component is transformed by
* a lookup through the tone reproduction curve (TRC). The result is
* treated as the achromatic component of the PCS.
<pre>
&nbsp; PCSY = grayTRC[deviceGray]
</pre>
* The inverse transform is done by converting the PCS Y components to
* device Gray via the inverse of the grayTRC.
* <p>
*/
public class ICC_ProfileGray
extends ICC_Profile {
static final long serialVersionUID = -1124721290732002649L;
/**
* Constructs a new ICC_ProfileGray from a CMM ID.
*/
ICC_ProfileGray(long ID) {
super(ID);
}
/**
* Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object.
*/
ICC_ProfileGray(ProfileDeferralInfo pdi) {
super(pdi);
}
/**
* Returns a float array of length 3 containing the X, Y, and Z
* components of the mediaWhitePointTag in the ICC profile.
* @return an array containing the components of the
* mediaWhitePointTag in the ICC profile.
*/
public float[] getMediaWhitePoint() {
return super.getMediaWhitePoint();
}
/**
* Returns a gamma value representing the tone reproduction
* curve (TRC). If the profile represents the TRC as a table rather
* than a single gamma value, then an exception is thrown. In this
* case the actual table can be obtained via getTRC(). When
* using a gamma value, the PCS Y component is computed as follows:
<pre>
&nbsp; gamma
&nbsp; PCSY = deviceGray
</pre>
* @return the gamma value as a float.
* @exception ProfileDataException if the profile does not specify
* the TRC as a single gamma value.
*/
public float getGamma() {
float theGamma;
theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag);
return theGamma;
}
/**
* Returns the TRC as an array of shorts. If the profile has
* specified the TRC as linear (gamma = 1.0) or as a simple gamma
* value, this method throws an exception, and the getGamma() method
* should be used to get the gamma value. Otherwise the short array
* returned here represents a lookup table where the input Gray value
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
* to array index 0 and value 1.0 maps to array index length-1.
* Interpolation may be used to generate output values for
* input values which do not map exactly to an index in the
* array. Output values also map linearly to the range [0.0, 1.0].
* Value 0.0 is represented by an array value of 0x0000 and
* value 1.0 by 0xFFFF, i.e. the values are really unsigned
* short values, although they are returned in a short array.
* @return a short array representing the TRC.
* @exception ProfileDataException if the profile does not specify
* the TRC as a table.
*/
public short[] getTRC() {
short[] theTRC;
theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag);
return theTRC;
}
}

View File

@ -0,0 +1,282 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.color;
import java.awt.image.LookupTable;
import sun.java2d.cmm.ProfileDeferralInfo;
/**
*
* The ICC_ProfileRGB class is a subclass of the ICC_Profile class
* that represents profiles which meet the following criteria:
* <ul>
* <li>The profile's color space type is RGB.</li>
* <li>The profile includes the <code>redColorantTag</code>,
* <code>greenColorantTag</code>, <code>blueColorantTag</code>,
* <code>redTRCTag</code>, <code>greenTRCTag</code>,
* <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
* </ul>
* The <code>ICC_Profile</code> <code>getInstance</code> method will
* return an <code>ICC_ProfileRGB</code> object when these conditions are met.
* Three-component, matrix-based input profiles and RGB display profiles are
* examples of this type of profile.
* <p>
* This profile class provides color transform matrices and lookup tables
* that Java or native methods can use directly to
* optimize color conversion in some cases.
* <p>
* To transform from a device profile color space to the CIEXYZ Profile
* Connection Space, each device color component is first linearized by
* a lookup through the corresponding tone reproduction curve (TRC).
* The resulting linear RGB components are converted to the CIEXYZ PCS
* using a a 3x3 matrix constructed from the RGB colorants.
* <pre>
*
* &nbsp; linearR = redTRC[deviceR]
*
* &nbsp; linearG = greenTRC[deviceG]
*
* &nbsp; linearB = blueTRC[deviceB]
*
* &nbsp; _ _ _ _ _ _
* &nbsp;[ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
* &nbsp;[ ] [ ] [ ]
* &nbsp;[ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
* &nbsp;[ ] [ ] [ ]
* &nbsp;[_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
*
* </pre>
* The inverse transform is performed by converting PCS XYZ components to linear
* RGB components through the inverse of the above 3x3 matrix, and then converting
* linear RGB to device RGB through inverses of the TRCs.
* <p>
*/
public class ICC_ProfileRGB
extends ICC_Profile {
static final long serialVersionUID = 8505067385152579334L;
/**
* Used to get a gamma value or TRC for the red component.
*/
public static final int REDCOMPONENT = 0;
/**
* Used to get a gamma value or TRC for the green component.
*/
public static final int GREENCOMPONENT = 1;
/**
* Used to get a gamma value or TRC for the blue component.
*/
public static final int BLUECOMPONENT = 2;
/**
* Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
*
* @param ID The CMM ID for the profile.
*
*/
ICC_ProfileRGB(long ID) {
super(ID);
}
/**
* Constructs a new <code>ICC_ProfileRGB</code> from a
* ProfileDeferralInfo object.
*
* @param pdi
*/
ICC_ProfileRGB(ProfileDeferralInfo pdi) {
super(pdi);
}
/**
* Returns an array that contains the components of the profile's
* <CODE>mediaWhitePointTag</CODE>.
*
* @return A 3-element <CODE>float</CODE> array containing the x, y,
* and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
*/
public float[] getMediaWhitePoint() {
return super.getMediaWhitePoint();
}
/**
* Returns a 3x3 <CODE>float</CODE> matrix constructed from the
* X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
* <p>
* This matrix can be used for color transforms in the forward
* direction of the profile--from the profile color space
* to the CIEXYZ PCS.
*
* @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
* components of the profile's <CODE>redColorantTag</CODE>,
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
*/
public float[][] getMatrix() {
float[][] theMatrix = new float[3][3];
float[] tmpMatrix;
tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
theMatrix[0][0] = tmpMatrix[0];
theMatrix[1][0] = tmpMatrix[1];
theMatrix[2][0] = tmpMatrix[2];
tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
theMatrix[0][1] = tmpMatrix[0];
theMatrix[1][1] = tmpMatrix[1];
theMatrix[2][1] = tmpMatrix[2];
tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
theMatrix[0][2] = tmpMatrix[0];
theMatrix[1][2] = tmpMatrix[1];
theMatrix[2][2] = tmpMatrix[2];
return theMatrix;
}
/**
* Returns a gamma value representing the tone reproduction curve
* (TRC) for a particular component. The component parameter
* must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
* <p>
* If the profile
* represents the TRC for the corresponding component
* as a table rather than a single gamma value, an
* exception is thrown. In this case the actual table
* can be obtained through the {@link #getTRC(int)} method.
* When using a gamma value,
* the linear component (R, G, or B) is computed as follows:
* <pre>
*
* &nbsp; gamma
* &nbsp; linearComponent = deviceComponent
*
*</pre>
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
* represents the component whose TRC you want to retrieve
* @return the gamma value as a float.
* @exception ProfileDataException if the profile does not specify
* the corresponding TRC as a single gamma value.
*/
public float getGamma(int component) {
float theGamma;
int theSignature;
switch (component) {
case REDCOMPONENT:
theSignature = ICC_Profile.icSigRedTRCTag;
break;
case GREENCOMPONENT:
theSignature = ICC_Profile.icSigGreenTRCTag;
break;
case BLUECOMPONENT:
theSignature = ICC_Profile.icSigBlueTRCTag;
break;
default:
throw new IllegalArgumentException("Must be Red, Green, or Blue");
}
theGamma = super.getGamma(theSignature);
return theGamma;
}
/**
* Returns the TRC for a particular component as an array.
* Component must be <code>REDCOMPONENT</code>,
* <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
* Otherwise the returned array
* represents a lookup table where the input component value
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
* to array index 0 and value 1.0 maps to array index length-1.
* Interpolation might be used to generate output values for
* input values that do not map exactly to an index in the
* array. Output values also map linearly to the range [0.0, 1.0].
* Value 0.0 is represented by an array value of 0x0000 and
* value 1.0 by 0xFFFF. In other words, the values are really unsigned
* <code>short</code> values even though they are returned in a
* <code>short</code> array.
*
* If the profile has specified the corresponding TRC
* as linear (gamma = 1.0) or as a simple gamma value, this method
* throws an exception. In this case, the {@link #getGamma(int)}
* method should be used to get the gamma value.
*
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
* represents the component whose TRC you want to retrieve:
* <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
* <CODE>BLUECOMPONENT</CODE>.
*
* @return a short array representing the TRC.
* @exception ProfileDataException if the profile does not specify
* the corresponding TRC as a table.
*/
public short[] getTRC(int component) {
short[] theTRC;
int theSignature;
switch (component) {
case REDCOMPONENT:
theSignature = ICC_Profile.icSigRedTRCTag;
break;
case GREENCOMPONENT:
theSignature = ICC_Profile.icSigGreenTRCTag;
break;
case BLUECOMPONENT:
theSignature = ICC_Profile.icSigBlueTRCTag;
break;
default:
throw new IllegalArgumentException("Must be Red, Green, or Blue");
}
theTRC = super.getTRC(theSignature);
return theTRC;
}
}

View File

@ -31,9 +31,9 @@ package java.awt.font;
* <i>sfnt</i> tables from the font. A particular
* <code>Font</code> object can implement this interface.
* <p>
* For more information on TrueType fonts, see the
* Apple TrueType Reference Manual
* ( <a href="http://fonts.apple.com/TTRefMan/index.html">http://fonts.apple.com/TTRefMan/index.html</a> ).
* For more information on TrueType and OpenType fonts, see the
* OpenType specification.
* ( <a href=http://www.microsoft.com/typography/otspec/">http://www.microsoft.com/typography/otspec/l</a> ).
*/
public interface OpenType {

View File

@ -0,0 +1,839 @@
/*
* Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
/**
* This class represents image data which is stored in a band interleaved
* fashion and for
* which each sample of a pixel occupies one data element of the DataBuffer.
* It subclasses ComponentSampleModel but provides a more efficent
* implementation for accessing band interleaved image data than is provided
* by ComponentSampleModel. This class should typically be used when working
* with images which store sample data for each band in a different bank of the
* DataBuffer. Accessor methods are provided so that image data can be
* manipulated directly. Pixel stride is the number of
* data array elements between two samples for the same band on the same
* scanline. The pixel stride for a BandedSampleModel is one.
* Scanline stride is the number of data array elements between
* a given sample and the corresponding sample in the same column of the next
* scanline. Band offsets denote the number
* of data array elements from the first data array element of the bank
* of the DataBuffer holding each band to the first sample of the band.
* The bands are numbered from 0 to N-1.
* Bank indices denote the correspondence between a bank of the data buffer
* and a band of image data. This class supports
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
* {@link DataBuffer#TYPE_INT TYPE_INT},
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
*/
public final class BandedSampleModel extends ComponentSampleModel
{
/**
* Constructs a BandedSampleModel with the specified parameters.
* The pixel stride will be one data element. The scanline stride
* will be the same as the width. Each band will be stored in
* a separate bank and all band offsets will be zero.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of
* image data described.
* @param h The height (in pixels) of the region of image
* data described.
* @param numBands The number of bands for the image data.
* @throws IllegalArgumentException if <code>dataType</code> is not
* one of the supported data types
*/
public BandedSampleModel(int dataType, int w, int h, int numBands) {
super(dataType, w, h, 1, w,
BandedSampleModel.createIndicesArray(numBands),
BandedSampleModel.createOffsetArray(numBands));
}
/**
* Constructs a BandedSampleModel with the specified parameters.
* The number of bands will be inferred from the lengths of the
* bandOffsets bankIndices arrays, which must be equal. The pixel
* stride will be one data element.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of
* image data described.
* @param h The height (in pixels) of the region of
* image data described.
* @param scanlineStride The line stride of the of the image data.
* @param bankIndices The bank index for each band.
* @param bandOffsets The band offset for each band.
* @throws IllegalArgumentException if <code>dataType</code> is not
* one of the supported data types
*/
public BandedSampleModel(int dataType,
int w, int h,
int scanlineStride,
int bankIndices[],
int bandOffsets[]) {
super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
}
/**
* Creates a new BandedSampleModel with the specified
* width and height. The new BandedSampleModel will have the same
* number of bands, storage data type, and bank indices
* as this BandedSampleModel. The band offsets will be compressed
* such that the offset between bands will be w*pixelStride and
* the minimum of all of the band offsets is zero.
* @param w the width of the resulting <code>BandedSampleModel</code>
* @param h the height of the resulting <code>BandedSampleModel</code>
* @return a new <code>BandedSampleModel</code> with the specified
* width and height.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> equals either
* <code>Integer.MAX_VALUE</code> or
* <code>Integer.MIN_VALUE</code>
* @throws IllegalArgumentException if <code>dataType</code> is not
* one of the supported data types
*/
public SampleModel createCompatibleSampleModel(int w, int h) {
int[] bandOffs;
if (numBanks == 1) {
bandOffs = orderBands(bandOffsets, w*h);
}
else {
bandOffs = new int[bandOffsets.length];
}
SampleModel sampleModel =
new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
return sampleModel;
}
/**
* Creates a new BandedSampleModel with a subset of the bands of this
* BandedSampleModel. The new BandedSampleModel can be
* used with any DataBuffer that the existing BandedSampleModel
* can be used with. The new BandedSampleModel/DataBuffer
* combination will represent an image with a subset of the bands
* of the original BandedSampleModel/DataBuffer combination.
* @throws RasterFormatException if the number of bands is greater than
* the number of banks in this sample model.
* @throws IllegalArgumentException if <code>dataType</code> is not
* one of the supported data types
*/
public SampleModel createSubsetSampleModel(int bands[]) {
if (bands.length > bankIndices.length)
throw new RasterFormatException("There are only " +
bankIndices.length +
" bands");
int newBankIndices[] = new int[bands.length];
int newBandOffsets[] = new int[bands.length];
for (int i=0; i<bands.length; i++) {
newBankIndices[i] = bankIndices[bands[i]];
newBandOffsets[i] = bandOffsets[bands[i]];
}
return new BandedSampleModel(this.dataType, width, height,
this.scanlineStride,
newBankIndices, newBandOffsets);
}
/**
* Creates a DataBuffer that corresponds to this BandedSampleModel,
* The DataBuffer's data type, number of banks, and size
* will be consistent with this BandedSampleModel.
* @throws IllegalArgumentException if <code>dataType</code> is not
* one of the supported types.
*/
public DataBuffer createDataBuffer() {
DataBuffer dataBuffer = null;
int size = scanlineStride * height;
switch (dataType) {
case DataBuffer.TYPE_BYTE:
dataBuffer = new DataBufferByte(size, numBanks);
break;
case DataBuffer.TYPE_USHORT:
dataBuffer = new DataBufferUShort(size, numBanks);
break;
case DataBuffer.TYPE_SHORT:
dataBuffer = new DataBufferShort(size, numBanks);
break;
case DataBuffer.TYPE_INT:
dataBuffer = new DataBufferInt(size, numBanks);
break;
case DataBuffer.TYPE_FLOAT:
dataBuffer = new DataBufferFloat(size, numBanks);
break;
case DataBuffer.TYPE_DOUBLE:
dataBuffer = new DataBufferDouble(size, numBanks);
break;
default:
throw new IllegalArgumentException("dataType is not one " +
"of the supported types.");
}
return dataBuffer;
}
/**
* Returns data for a single pixel in a primitive array of type
* TransferType. For a BandedSampleModel, this will be the same
* as the data type, and samples will be returned one per array
* element. Generally, obj
* should be passed in as null, so that the Object will be created
* automatically and will be of the right primitive data type.
* <p>
* The following code illustrates transferring data for one pixel from
* DataBuffer <code>db1</code>, whose storage layout is described by
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
* whose storage layout is described by
* BandedSampleModel <code>bsm2</code>.
* The transfer will generally be more efficient than using
* getPixel/setPixel.
* <pre>
* BandedSampleModel bsm1, bsm2;
* DataBufferInt db1, db2;
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
* db2);
* </pre>
* Using getDataElements/setDataElements to transfer between two
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
* the same number of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* If obj is non-null, it should be a primitive array of type TransferType.
* Otherwise, a ClassCastException is thrown. An
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if obj is non-null and is not large enough to hold
* the pixel data.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param obj If non-null, a primitive array in which to return
* the pixel data.
* @param data The DataBuffer containing the image data.
* @return the data for the specified pixel.
* @see #setDataElements(int, int, Object, DataBuffer)
*/
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
int numDataElems = getNumDataElements();
int pixelOffset = y*scanlineStride + x;
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] bdata;
if (obj == null) {
bdata = new byte[numDataElems];
} else {
bdata = (byte[])obj;
}
for (int i=0; i<numDataElems; i++) {
bdata[i] = (byte)data.getElem(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
obj = (Object)bdata;
break;
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_SHORT:
short[] sdata;
if (obj == null) {
sdata = new short[numDataElems];
} else {
sdata = (short[])obj;
}
for (int i=0; i<numDataElems; i++) {
sdata[i] = (short)data.getElem(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
obj = (Object)sdata;
break;
case DataBuffer.TYPE_INT:
int[] idata;
if (obj == null) {
idata = new int[numDataElems];
} else {
idata = (int[])obj;
}
for (int i=0; i<numDataElems; i++) {
idata[i] = data.getElem(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
obj = (Object)idata;
break;
case DataBuffer.TYPE_FLOAT:
float[] fdata;
if (obj == null) {
fdata = new float[numDataElems];
} else {
fdata = (float[])obj;
}
for (int i=0; i<numDataElems; i++) {
fdata[i] = data.getElemFloat(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
obj = (Object)fdata;
break;
case DataBuffer.TYPE_DOUBLE:
double[] ddata;
if (obj == null) {
ddata = new double[numDataElems];
} else {
ddata = (double[])obj;
}
for (int i=0; i<numDataElems; i++) {
ddata[i] = data.getElemDouble(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
obj = (Object)ddata;
break;
}
return obj;
}
/**
* Returns all samples for the specified pixel in an int array.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param iArray If non-null, returns the samples in this array
* @param data The DataBuffer containing the image data
* @return the samples for the specified pixel.
* @see #setPixel(int, int, int[], DataBuffer)
*/
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int[] pixels;
if (iArray != null) {
pixels = iArray;
} else {
pixels = new int [numBands];
}
int pixelOffset = y*scanlineStride + x;
for (int i=0; i<numBands; i++) {
pixels[i] = data.getElem(bankIndices[i],
pixelOffset + bandOffsets[i]);
}
return pixels;
}
/**
* Returns all samples for the specified rectangle of pixels in
* an int array, one sample per data array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location
* @param y The Y coordinate of the upper left pixel location
* @param w The width of the pixel rectangle
* @param h The height of the pixel rectangle
* @param iArray If non-null, returns the samples in this array
* @param data The DataBuffer containing the image data
* @return the samples for the pixels within the specified region.
* @see #setPixels(int, int, int, int, int[], DataBuffer)
*/
public int[] getPixels(int x, int y, int w, int h,
int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int[] pixels;
if (iArray != null) {
pixels = iArray;
} else {
pixels = new int[w*h*numBands];
}
for (int k = 0; k < numBands; k++) {
int lineOffset = y*scanlineStride + x + bandOffsets[k];
int srcOffset = k;
int bank = bankIndices[k];
for (int i = 0; i < h; i++) {
int pixelOffset = lineOffset;
for (int j = 0; j < w; j++) {
pixels[srcOffset] = data.getElem(bank, pixelOffset++);
srcOffset += numBands;
}
lineOffset += scanlineStride;
}
}
return pixels;
}
/**
* Returns as int the sample in a specified band for the pixel
* located at (x,y).
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to return
* @param data The DataBuffer containing the image data
* @return the sample in the specified band for the specified pixel.
* @see #setSample(int, int, int, int, DataBuffer)
*/
public int getSample(int x, int y, int b, DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int sample =
data.getElem(bankIndices[b],
y*scanlineStride + x + bandOffsets[b]);
return sample;
}
/**
* Returns the sample in a specified band
* for the pixel located at (x,y) as a float.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to return
* @param data The DataBuffer containing the image data
* @return a float value that represents the sample in the specified
* band for the specified pixel.
*/
public float getSampleFloat(int x, int y, int b, DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
float sample = data.getElemFloat(bankIndices[b],
y*scanlineStride + x + bandOffsets[b]);
return sample;
}
/**
* Returns the sample in a specified band
* for a pixel located at (x,y) as a double.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to return
* @param data The DataBuffer containing the image data
* @return a double value that represents the sample in the specified
* band for the specified pixel.
*/
public double getSampleDouble(int x, int y, int b, DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
double sample = data.getElemDouble(bankIndices[b],
y*scanlineStride + x + bandOffsets[b]);
return sample;
}
/**
* Returns the samples in a specified band for the specified rectangle
* of pixels in an int array, one sample per data array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location
* @param y The Y coordinate of the upper left pixel location
* @param w The width of the pixel rectangle
* @param h The height of the pixel rectangle
* @param b The band to return
* @param iArray If non-null, returns the samples in this array
* @param data The DataBuffer containing the image data
* @return the samples in the specified band for the pixels within
* the specified region.
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
*/
public int[] getSamples(int x, int y, int w, int h, int b,
int iArray[], DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int samples[];
if (iArray != null) {
samples = iArray;
} else {
samples = new int [w*h];
}
int lineOffset = y*scanlineStride + x + bandOffsets[b];
int srcOffset = 0;
int bank = bankIndices[b];
for (int i = 0; i < h; i++) {
int sampleOffset = lineOffset;
for (int j = 0; j < w; j++) {
samples[srcOffset++] = data.getElem(bank, sampleOffset++);
}
lineOffset += scanlineStride;
}
return samples;
}
/**
* Sets the data for a single pixel in the specified DataBuffer from a
* primitive array of type TransferType. For a BandedSampleModel,
* this will be the same as the data type, and samples are transferred
* one per array element.
* <p>
* The following code illustrates transferring data for one pixel from
* DataBuffer <code>db1</code>, whose storage layout is described by
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
* whose storage layout is described by
* BandedSampleModel <code>bsm2</code>.
* The transfer will generally be more efficient than using
* getPixel/setPixel.
* <pre>
* BandedSampleModel bsm1, bsm2;
* DataBufferInt db1, db2;
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
* db2);
* </pre>
* Using getDataElements/setDataElements to transfer between two
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
* the same number of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* obj must be a primitive array of type TransferType. Otherwise,
* a ClassCastException is thrown. An
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if obj is not large enough to hold the pixel data.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param obj If non-null, returns the primitive array in this
* object
* @param data The DataBuffer containing the image data
* @see #getDataElements(int, int, Object, DataBuffer)
*/
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
int numDataElems = getNumDataElements();
int pixelOffset = y*scanlineStride + x;
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] barray = (byte[])obj;
for (int i=0; i<numDataElems; i++) {
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
barray[i] & 0xff);
}
break;
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_SHORT:
short[] sarray = (short[])obj;
for (int i=0; i<numDataElems; i++) {
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
sarray[i] & 0xffff);
}
break;
case DataBuffer.TYPE_INT:
int[] iarray = (int[])obj;
for (int i=0; i<numDataElems; i++) {
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
iarray[i]);
}
break;
case DataBuffer.TYPE_FLOAT:
float[] farray = (float[])obj;
for (int i=0; i<numDataElems; i++) {
data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
farray[i]);
}
break;
case DataBuffer.TYPE_DOUBLE:
double[] darray = (double[])obj;
for (int i=0; i<numDataElems; i++) {
data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
darray[i]);
}
break;
}
}
/**
* Sets a pixel in the DataBuffer using an int array of samples for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param iArray The input samples in an int array
* @param data The DataBuffer containing the image data
* @see #getPixel(int, int, int[], DataBuffer)
*/
public void setPixel(int x, int y, int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int pixelOffset = y*scanlineStride + x;
for (int i=0; i<numBands; i++) {
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
iArray[i]);
}
}
/**
* Sets all samples for a rectangle of pixels from an int array containing
* one sample per array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location
* @param y The Y coordinate of the upper left pixel location
* @param w The width of the pixel rectangle
* @param h The height of the pixel rectangle
* @param iArray The input samples in an int array
* @param data The DataBuffer containing the image data
* @see #getPixels(int, int, int, int, int[], DataBuffer)
*/
public void setPixels(int x, int y, int w, int h,
int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
for (int k = 0; k < numBands; k++) {
int lineOffset = y*scanlineStride + x + bandOffsets[k];
int srcOffset = k;
int bank = bankIndices[k];
for (int i = 0; i < h; i++) {
int pixelOffset = lineOffset;
for (int j = 0; j < w; j++) {
data.setElem(bank, pixelOffset++, iArray[srcOffset]);
srcOffset += numBands;
}
lineOffset += scanlineStride;
}
}
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using an int for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to set
* @param s The input sample as an int
* @param data The DataBuffer containing the image data
* @see #getSample(int, int, int, DataBuffer)
*/
public void setSample(int x, int y, int b, int s,
DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
data.setElem(bankIndices[b],
y*scanlineStride + x + bandOffsets[b], s);
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using a float for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to set
* @param s The input sample as a float
* @param data The DataBuffer containing the image data
* @see #getSample(int, int, int, DataBuffer)
*/
public void setSample(int x, int y, int b,
float s ,
DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
data.setElemFloat(bankIndices[b],
y*scanlineStride + x + bandOffsets[b], s);
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using a double for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location
* @param y The Y coordinate of the pixel location
* @param b The band to set
* @param s The input sample as a double
* @param data The DataBuffer containing the image data
* @see #getSample(int, int, int, DataBuffer)
*/
public void setSample(int x, int y, int b,
double s,
DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
data.setElemDouble(bankIndices[b],
y*scanlineStride + x + bandOffsets[b], s);
}
/**
* Sets the samples in the specified band for the specified rectangle
* of pixels from an int array containing one sample per data array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location
* @param y The Y coordinate of the upper left pixel location
* @param w The width of the pixel rectangle
* @param h The height of the pixel rectangle
* @param b The band to set
* @param iArray The input sample array
* @param data The DataBuffer containing the image data
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
*/
public void setSamples(int x, int y, int w, int h, int b,
int iArray[], DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int lineOffset = y*scanlineStride + x + bandOffsets[b];
int srcOffset = 0;
int bank = bankIndices[b];
for (int i = 0; i < h; i++) {
int sampleOffset = lineOffset;
for (int j = 0; j < w; j++) {
data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
}
lineOffset += scanlineStride;
}
}
private static int[] createOffsetArray(int numBands) {
int[] bandOffsets = new int[numBands];
for (int i=0; i < numBands; i++) {
bandOffsets[i] = 0;
}
return bandOffsets;
}
private static int[] createIndicesArray(int numBands) {
int[] bankIndices = new int[numBands];
for (int i=0; i < numBands; i++) {
bankIndices[i] = i;
}
return bankIndices;
}
// Differentiate hash code from other ComponentSampleModel subclasses
public int hashCode() {
return super.hashCode() ^ 0x2;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,535 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import sun.java2d.StateTrackable.State;
import static sun.java2d.StateTrackable.State.*;
import sun.java2d.StateTrackableDelegate;
import sun.awt.image.SunWritableRaster;
/**
* This class exists to wrap one or more data arrays. Each data array in
* the DataBuffer is referred to as a bank. Accessor methods for getting
* and setting elements of the DataBuffer's banks exist with and without
* a bank specifier. The methods without a bank specifier use the default 0th
* bank. The DataBuffer can optionally take an offset per bank, so that
* data in an existing array can be used even if the interesting data
* doesn't start at array location zero. Getting or setting the 0th
* element of a bank, uses the (0+offset)th element of the array. The
* size field specifies how much of the data array is available for
* use. Size + offset for a given bank should never be greater
* than the length of the associated data array. The data type of
* a data buffer indicates the type of the data array(s) and may also
* indicate additional semantics, e.g. storing unsigned 8-bit data
* in elements of a byte array. The data type may be TYPE_UNDEFINED
* or one of the types defined below. Other types may be added in
* the future. Generally, an object of class DataBuffer will be cast down
* to one of its data type specific subclasses to access data type specific
* methods for improved performance. Currently, the Java 2D(tm) API
* image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
* TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
* @see java.awt.image.Raster
* @see java.awt.image.SampleModel
*/
public abstract class DataBuffer {
/** Tag for unsigned byte data. */
public static final int TYPE_BYTE = 0;
/** Tag for unsigned short data. */
public static final int TYPE_USHORT = 1;
/** Tag for signed short data. Placeholder for future use. */
public static final int TYPE_SHORT = 2;
/** Tag for int data. */
public static final int TYPE_INT = 3;
/** Tag for float data. Placeholder for future use. */
public static final int TYPE_FLOAT = 4;
/** Tag for double data. Placeholder for future use. */
public static final int TYPE_DOUBLE = 5;
/** Tag for undefined data. */
public static final int TYPE_UNDEFINED = 32;
/** The data type of this DataBuffer. */
protected int dataType;
/** The number of banks in this DataBuffer. */
protected int banks;
/** Offset into default (first) bank from which to get the first element. */
protected int offset;
/** Usable size of all banks. */
protected int size;
/** Offsets into all banks. */
protected int offsets[];
/* The current StateTrackable state. */
StateTrackableDelegate theTrackable;
/** Size of the data types indexed by DataType tags defined above. */
private static final int dataTypeSize[] = {8,16,16,32,32,64};
/** Returns the size (in bits) of the data type, given a datatype tag.
* @param type the value of one of the defined datatype tags
* @return the size of the data type
* @throws IllegalArgumentException if <code>type</code> is less than
* zero or greater than {@link #TYPE_DOUBLE}
*/
public static int getDataTypeSize(int type) {
if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
throw new IllegalArgumentException("Unknown data type "+type);
}
return dataTypeSize[type];
}
/**
* Constructs a DataBuffer containing one bank of the specified
* data type and size.
*
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
*/
protected DataBuffer(int dataType, int size) {
this(UNTRACKABLE, dataType, size);
}
/**
* Constructs a DataBuffer containing one bank of the specified
* data type and size with the indicated initial {@link State State}.
*
* @param initialState the initial {@link State State} state of the data
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @since 1.7
*/
DataBuffer(State initialState,
int dataType, int size)
{
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
this.dataType = dataType;
this.banks = 1;
this.size = size;
this.offset = 0;
this.offsets = new int[1]; // init to 0 by new
}
/**
* Constructs a DataBuffer containing the specified number of
* banks. Each bank has the specified size and an offset of 0.
*
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
*/
protected DataBuffer(int dataType, int size, int numBanks) {
this(UNTRACKABLE, dataType, size, numBanks);
}
/**
* Constructs a DataBuffer containing the specified number of
* banks with the indicated initial {@link State State}.
* Each bank has the specified size and an offset of 0.
*
* @param initialState the initial {@link State State} state of the data
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
* @since 1.7
*/
DataBuffer(State initialState,
int dataType, int size, int numBanks)
{
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
this.dataType = dataType;
this.banks = numBanks;
this.size = size;
this.offset = 0;
this.offsets = new int[banks]; // init to 0 by new
}
/**
* Constructs a DataBuffer that contains the specified number
* of banks. Each bank has the specified datatype, size and offset.
*
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
* @param offset the offset for each bank
*/
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
this(UNTRACKABLE, dataType, size, numBanks, offset);
}
/**
* Constructs a DataBuffer that contains the specified number
* of banks with the indicated initial {@link State State}.
* Each bank has the specified datatype, size and offset.
*
* @param initialState the initial {@link State State} state of the data
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
* @param offset the offset for each bank
* @since 1.7
*/
DataBuffer(State initialState,
int dataType, int size, int numBanks, int offset)
{
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
this.dataType = dataType;
this.banks = numBanks;
this.size = size;
this.offset = offset;
this.offsets = new int[numBanks];
for (int i = 0; i < numBanks; i++) {
this.offsets[i] = offset;
}
}
/**
* Constructs a DataBuffer which contains the specified number
* of banks. Each bank has the specified datatype and size. The
* offset for each bank is specified by its respective entry in
* the offsets array.
*
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
* @param offsets an array containing an offset for each bank.
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
* does not equal the length of <code>offsets</code>
*/
protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
this(UNTRACKABLE, dataType, size, numBanks, offsets);
}
/**
* Constructs a DataBuffer which contains the specified number
* of banks with the indicated initial {@link State State}.
* Each bank has the specified datatype and size. The
* offset for each bank is specified by its respective entry in
* the offsets array.
*
* @param initialState the initial {@link State State} state of the data
* @param dataType the data type of this <code>DataBuffer</code>
* @param size the size of the banks
* @param numBanks the number of banks in this
* <code>DataBuffer</code>
* @param offsets an array containing an offset for each bank.
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
* does not equal the length of <code>offsets</code>
* @since 1.7
*/
DataBuffer(State initialState,
int dataType, int size, int numBanks, int offsets[])
{
if (numBanks != offsets.length) {
throw new ArrayIndexOutOfBoundsException("Number of banks" +
" does not match number of bank offsets");
}
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
this.dataType = dataType;
this.banks = numBanks;
this.size = size;
this.offset = offsets[0];
this.offsets = (int[])offsets.clone();
}
/** Returns the data type of this DataBuffer.
* @return the data type of this <code>DataBuffer</code>.
*/
public int getDataType() {
return dataType;
}
/** Returns the size (in array elements) of all banks.
* @return the size of all banks.
*/
public int getSize() {
return size;
}
/** Returns the offset of the default bank in array elements.
* @return the offset of the default bank.
*/
public int getOffset() {
return offset;
}
/** Returns the offsets (in array elements) of all the banks.
* @return the offsets of all banks.
*/
public int[] getOffsets() {
return (int[])offsets.clone();
}
/** Returns the number of banks in this DataBuffer.
* @return the number of banks.
*/
public int getNumBanks() {
return banks;
}
/**
* Returns the requested data array element from the first (default) bank
* as an integer.
* @param i the index of the requested data array element
* @return the data array element at the specified index.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int i) {
return getElem(0,i);
}
/**
* Returns the requested data array element from the specified bank
* as an integer.
* @param bank the specified bank
* @param i the index of the requested data array element
* @return the data array element at the specified index from the
* specified bank at the specified index.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public abstract int getElem(int bank, int i);
/**
* Sets the requested data array element in the first (default) bank
* from the given integer.
* @param i the specified index into the data array
* @param val the data to set the element at the specified index in
* the data array
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int i, int val) {
setElem(0,i,val);
}
/**
* Sets the requested data array element in the specified bank
* from the given integer.
* @param bank the specified bank
* @param i the specified index into the data array
* @param val the data to set the element in the specified bank
* at the specified index in the data array
* @see #getElem(int)
* @see #getElem(int, int)
*/
public abstract void setElem(int bank, int i, int val);
/**
* Returns the requested data array element from the first (default) bank
* as a float. The implementation in this class is to cast getElem(i)
* to a float. Subclasses may override this method if another
* implementation is needed.
* @param i the index of the requested data array element
* @return a float value representing the data array element at the
* specified index.
* @see #setElemFloat(int, float)
* @see #setElemFloat(int, int, float)
*/
public float getElemFloat(int i) {
return (float)getElem(i);
}
/**
* Returns the requested data array element from the specified bank
* as a float. The implementation in this class is to cast
* {@link #getElem(int, int)}
* to a float. Subclasses can override this method if another
* implementation is needed.
* @param bank the specified bank
* @param i the index of the requested data array element
* @return a float value representing the data array element from the
* specified bank at the specified index.
* @see #setElemFloat(int, float)
* @see #setElemFloat(int, int, float)
*/
public float getElemFloat(int bank, int i) {
return (float)getElem(bank,i);
}
/**
* Sets the requested data array element in the first (default) bank
* from the given float. The implementation in this class is to cast
* val to an int and call {@link #setElem(int, int)}. Subclasses
* can override this method if another implementation is needed.
* @param i the specified index
* @param val the value to set the element at the specified index in
* the data array
* @see #getElemFloat(int)
* @see #getElemFloat(int, int)
*/
public void setElemFloat(int i, float val) {
setElem(i,(int)val);
}
/**
* Sets the requested data array element in the specified bank
* from the given float. The implementation in this class is to cast
* val to an int and call {@link #setElem(int, int)}. Subclasses can
* override this method if another implementation is needed.
* @param bank the specified bank
* @param i the specified index
* @param val the value to set the element in the specified bank at
* the specified index in the data array
* @see #getElemFloat(int)
* @see #getElemFloat(int, int)
*/
public void setElemFloat(int bank, int i, float val) {
setElem(bank,i,(int)val);
}
/**
* Returns the requested data array element from the first (default) bank
* as a double. The implementation in this class is to cast
* {@link #getElem(int)}
* to a double. Subclasses can override this method if another
* implementation is needed.
* @param i the specified index
* @return a double value representing the element at the specified
* index in the data array.
* @see #setElemDouble(int, double)
* @see #setElemDouble(int, int, double)
*/
public double getElemDouble(int i) {
return (double)getElem(i);
}
/**
* Returns the requested data array element from the specified bank as
* a double. The implementation in this class is to cast getElem(bank, i)
* to a double. Subclasses may override this method if another
* implementation is needed.
* @param bank the specified bank
* @param i the specified index
* @return a double value representing the element from the specified
* bank at the specified index in the data array.
* @see #setElemDouble(int, double)
* @see #setElemDouble(int, int, double)
*/
public double getElemDouble(int bank, int i) {
return (double)getElem(bank,i);
}
/**
* Sets the requested data array element in the first (default) bank
* from the given double. The implementation in this class is to cast
* val to an int and call {@link #setElem(int, int)}. Subclasses can
* override this method if another implementation is needed.
* @param i the specified index
* @param val the value to set the element at the specified index
* in the data array
* @see #getElemDouble(int)
* @see #getElemDouble(int, int)
*/
public void setElemDouble(int i, double val) {
setElem(i,(int)val);
}
/**
* Sets the requested data array element in the specified bank
* from the given double. The implementation in this class is to cast
* val to an int and call {@link #setElem(int, int)}. Subclasses can
* override this method if another implementation is needed.
* @param bank the specified bank
* @param i the specified index
* @param val the value to set the element in the specified bank
* at the specified index of the data array
* @see #getElemDouble(int)
* @see #getElemDouble(int, int)
*/
public void setElemDouble(int bank, int i, double val) {
setElem(bank,i,(int)val);
}
static int[] toIntArray(Object obj) {
if (obj instanceof int[]) {
return (int[])obj;
} else if (obj == null) {
return null;
} else if (obj instanceof short[]) {
short sdata[] = (short[])obj;
int idata[] = new int[sdata.length];
for (int i = 0; i < sdata.length; i++) {
idata[i] = (int)sdata[i] & 0xffff;
}
return idata;
} else if (obj instanceof byte[]) {
byte bdata[] = (byte[])obj;
int idata[] = new int[bdata.length];
for (int i = 0; i < bdata.length; i++) {
idata[i] = 0xff & (int)bdata[i];
}
return idata;
}
return null;
}
static {
SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
public byte[] getData(DataBufferByte dbb, int bank) {
return dbb.bankdata[bank];
}
public short[] getData(DataBufferUShort dbus, int bank) {
return dbus.bankdata[bank];
}
public int[] getData(DataBufferInt dbi, int bank) {
return dbi.bankdata[bank];
}
public StateTrackableDelegate getTrackable(DataBuffer db) {
return db.theTrackable;
}
});
}
}

View File

@ -0,0 +1,286 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import static sun.java2d.StateTrackable.State.*;
/**
* This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
* Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
* unsigned values.
* <p>
* <a name="optimizations">
* Note that some implementations may function more efficiently
* if they can maintain control over how the data for an image is
* stored.
* For example, optimizations such as caching an image in video
* memory require that the implementation track all modifications
* to that data.
* Other implementations may operate better if they can store the
* data in locations other than a Java array.
* To maintain optimum compatibility with various optimizations
* it is best to avoid constructors and methods which expose the
* underlying storage as a Java array, as noted below in the
* documentation for those methods.
* </a>
*/
public final class DataBufferByte extends DataBuffer
{
/** The default data bank. */
byte data[];
/** All data banks */
byte bankdata[][];
/**
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
* specified size.
*
* @param size The size of the <CODE>DataBuffer</CODE>.
*/
public DataBufferByte(int size) {
super(STABLE, TYPE_BYTE, size);
data = new byte[size];
bankdata = new byte[1][];
bankdata[0] = data;
}
/**
* Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
* banks all of which are the specified size.
*
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
*/
public DataBufferByte(int size, int numBanks) {
super(STABLE, TYPE_BYTE, size, numBanks);
bankdata = new byte[numBanks][];
for (int i= 0; i < numBanks; i++) {
bankdata[i] = new byte[size];
}
data = bankdata[0];
}
/**
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array.
* Only the first <CODE>size</CODE> elements should be used by accessors of
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
* hold <CODE>size</CODE> elements.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
*/
public DataBufferByte(byte dataArray[], int size) {
super(UNTRACKABLE, TYPE_BYTE, size);
data = dataArray;
bankdata = new byte[1][];
bankdata[0] = data;
}
/**
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
* should be used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
* @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
* must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
*/
public DataBufferByte(byte dataArray[], int size, int offset){
super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
data = dataArray;
bankdata = new byte[1][];
bankdata[0] = data;
}
/**
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
* The number of banks is equal to <CODE>dataArray.length</CODE>.
* Only the first <CODE>size</CODE> elements of each array should be used by
* accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
*/
public DataBufferByte(byte dataArray[][], int size) {
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
bankdata = (byte[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
* and offsets.
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
* be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
* There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
* entry. For each bank, only elements <CODE>offset</CODE> through
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
* <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param offsets The offsets into each array.
*/
public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
bankdata = (byte[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Returns the default (first) byte data array.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return The first byte data array.
*/
public byte[] getData() {
theTrackable.setUntrackable();
return data;
}
/**
* Returns the data array for the specified bank.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param bank The bank whose data array you want to get.
* @return The data array for the specified bank.
*/
public byte[] getData(int bank) {
theTrackable.setUntrackable();
return bankdata[bank];
}
/**
* Returns the data arrays for all banks.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return All of the data arrays.
*/
public byte[][] getBankData() {
theTrackable.setUntrackable();
return (byte[][]) bankdata.clone();
}
/**
* Returns the requested data array element from the first (default) bank.
*
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int i) {
return (int)(data[i+offset]) & 0xff;
}
/**
* Returns the requested data array element from the specified bank.
*
* @param bank The bank from which you want to get a data array element.
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int bank, int i) {
return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
}
/**
* Sets the requested data array element in the first (default) bank
* to the specified value.
*
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int i, int val) {
data[i+offset] = (byte)val;
theTrackable.markDirty();
}
/**
* Sets the requested data array element in the specified bank
* from the given integer.
* @param bank The bank in which you want to set the data array element.
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the specified data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int bank, int i, int val) {
bankdata[bank][i+offsets[bank]] = (byte)val;
theTrackable.markDirty();
}
}

View File

@ -0,0 +1,284 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import static sun.java2d.StateTrackable.State.*;
/**
* This class extends <CODE>DataBuffer</CODE> and stores data internally
* as integers.
* <p>
* <a name="optimizations">
* Note that some implementations may function more efficiently
* if they can maintain control over how the data for an image is
* stored.
* For example, optimizations such as caching an image in video
* memory require that the implementation track all modifications
* to that data.
* Other implementations may operate better if they can store the
* data in locations other than a Java array.
* To maintain optimum compatibility with various optimizations
* it is best to avoid constructors and methods which expose the
* underlying storage as a Java array as noted below in the
* documentation for those methods.
* </a>
*/
public final class DataBufferInt extends DataBuffer
{
/** The default data bank. */
int data[];
/** All data banks */
int bankdata[][];
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
* and the specified size.
*
* @param size The size of the <CODE>DataBuffer</CODE>.
*/
public DataBufferInt(int size) {
super(STABLE, TYPE_INT, size);
data = new int[size];
bankdata = new int[1][];
bankdata[0] = data;
}
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
* banks, all of which are the specified size.
*
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
*/
public DataBufferInt(int size, int numBanks) {
super(STABLE, TYPE_INT, size, numBanks);
bankdata = new int[numBanks][];
for (int i= 0; i < numBanks; i++) {
bankdata[i] = new int[size];
}
data = bankdata[0];
}
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array.
* Only the first <CODE>size</CODE> elements should be used by accessors of
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
* hold <CODE>size</CODE> elements.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
*/
public DataBufferInt(int dataArray[], int size) {
super(UNTRACKABLE, TYPE_INT, size);
data = dataArray;
bankdata = new int[1][];
bankdata[0] = data;
}
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
* should be used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
* @param offset The offset into the <CODE>dataArray</CODE>.
*/
public DataBufferInt(int dataArray[], int size, int offset) {
super(UNTRACKABLE, TYPE_INT, size, 1, offset);
data = dataArray;
bankdata = new int[1][];
bankdata[0] = data;
}
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
* Only the first <CODE>size</CODE> elements of each array should be used by
* accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
*/
public DataBufferInt(int dataArray[][], int size) {
super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
bankdata = (int [][]) dataArray.clone();
data = bankdata[0];
}
/**
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
* and offsets.
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
* bank, only elements <CODE>offset</CODE> through
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
* used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param offsets The offsets into each array.
*/
public DataBufferInt(int dataArray[][], int size, int offsets[]) {
super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
bankdata = (int [][]) dataArray.clone();
data = bankdata[0];
}
/**
* Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return The first integer data array.
*/
public int[] getData() {
theTrackable.setUntrackable();
return data;
}
/**
* Returns the data array for the specified bank.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param bank The bank whose data array you want to get.
* @return The data array for the specified bank.
*/
public int[] getData(int bank) {
theTrackable.setUntrackable();
return bankdata[bank];
}
/**
* Returns the data arrays for all banks.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return All of the data arrays.
*/
public int[][] getBankData() {
theTrackable.setUntrackable();
return (int [][]) bankdata.clone();
}
/**
* Returns the requested data array element from the first (default) bank.
*
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int i) {
return data[i+offset];
}
/**
* Returns the requested data array element from the specified bank.
*
* @param bank The bank from which you want to get a data array element.
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int bank, int i) {
return bankdata[bank][i+offsets[bank]];
}
/**
* Sets the requested data array element in the first (default) bank
* to the specified value.
*
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int i, int val) {
data[i+offset] = val;
theTrackable.markDirty();
}
/**
* Sets the requested data array element in the specified bank
* to the integer value <CODE>i</CODE>.
* @param bank The bank in which you want to set the data array element.
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the specified data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int bank, int i, int val) {
bankdata[bank][i+offsets[bank]] = (int)val;
theTrackable.markDirty();
}
}

View File

@ -0,0 +1,283 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import static sun.java2d.StateTrackable.State.*;
/**
* This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
* <p>
* <a name="optimizations">
* Note that some implementations may function more efficiently
* if they can maintain control over how the data for an image is
* stored.
* For example, optimizations such as caching an image in video
* memory require that the implementation track all modifications
* to that data.
* Other implementations may operate better if they can store the
* data in locations other than a Java array.
* To maintain optimum compatibility with various optimizations
* it is best to avoid constructors and methods which expose the
* underlying storage as a Java array as noted below in the
* documentation for those methods.
* </a>
*/
public final class DataBufferShort extends DataBuffer
{
/** The default data bank. */
short data[];
/** All data banks */
short bankdata[][];
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
* specified size.
*
* @param size The size of the <CODE>DataBuffer</CODE>.
*/
public DataBufferShort(int size) {
super(STABLE, TYPE_SHORT,size);
data = new short[size];
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
* banks all of which are the specified size.
*
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
*/
public DataBufferShort(int size, int numBanks) {
super(STABLE, TYPE_SHORT,size,numBanks);
bankdata = new short[numBanks][];
for (int i= 0; i < numBanks; i++) {
bankdata[i] = new short[size];
}
data = bankdata[0];
}
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array.
* Only the first <CODE>size</CODE> elements should be used by accessors of
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
* hold <CODE>size</CODE> elements.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
*/
public DataBufferShort(short dataArray[], int size) {
super(UNTRACKABLE, TYPE_SHORT, size);
data = dataArray;
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
* should be used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
* @param offset The offset into the <CODE>dataArray</CODE>.
*/
public DataBufferShort(short dataArray[], int size, int offset) {
super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
data = dataArray;
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
* Only the first <CODE>size</CODE> elements of each array should be used by
* accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
*/
public DataBufferShort(short dataArray[][], int size) {
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
bankdata = (short[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
* and offsets.
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
* bank, only elements <CODE>offset</CODE> through
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
* used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param offsets The offsets into each array.
*/
public DataBufferShort(short dataArray[][], int size, int offsets[]) {
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
bankdata = (short[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Returns the default (first) byte data array.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return The first short data array.
*/
public short[] getData() {
theTrackable.setUntrackable();
return data;
}
/**
* Returns the data array for the specified bank.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param bank The bank whose data array you want to get.
* @return The data array for the specified bank.
*/
public short[] getData(int bank) {
theTrackable.setUntrackable();
return bankdata[bank];
}
/**
* Returns the data arrays for all banks.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return All of the data arrays.
*/
public short[][] getBankData() {
theTrackable.setUntrackable();
return (short[][]) bankdata.clone();
}
/**
* Returns the requested data array element from the first (default) bank.
*
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int i) {
return (int)(data[i+offset]);
}
/**
* Returns the requested data array element from the specified bank.
*
* @param bank The bank from which you want to get a data array element.
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int bank, int i) {
return (int)(bankdata[bank][i+offsets[bank]]);
}
/**
* Sets the requested data array element in the first (default) bank
* to the specified value.
*
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int i, int val) {
data[i+offset] = (short)val;
theTrackable.markDirty();
}
/**
* Sets the requested data array element in the specified bank
* from the given integer.
* @param bank The bank in which you want to set the data array element.
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the specified data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int bank, int i, int val) {
bankdata[bank][i+offsets[bank]] = (short)val;
theTrackable.markDirty();
}
}

View File

@ -0,0 +1,318 @@
/*
* Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import static sun.java2d.StateTrackable.State.*;
/**
* This class extends <CODE>DataBuffer</CODE> and stores data internally as
* shorts. Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
* are treated as unsigned values.
* <p>
* <a name="optimizations">
* Note that some implementations may function more efficiently
* if they can maintain control over how the data for an image is
* stored.
* For example, optimizations such as caching an image in video
* memory require that the implementation track all modifications
* to that data.
* Other implementations may operate better if they can store the
* data in locations other than a Java array.
* To maintain optimum compatibility with various optimizations
* it is best to avoid constructors and methods which expose the
* underlying storage as a Java array as noted below in the
* documentation for those methods.
* </a>
*/
public final class DataBufferUShort extends DataBuffer
{
/** The default data bank. */
short data[];
/** All data banks */
short bankdata[][];
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
* specified size.
*
* @param size The size of the <CODE>DataBuffer</CODE>.
*/
public DataBufferUShort(int size) {
super(STABLE, TYPE_USHORT, size);
data = new short[size];
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
* banks, all of which are the specified size.
*
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
*/
public DataBufferUShort(int size, int numBanks) {
super(STABLE, TYPE_USHORT, size, numBanks);
bankdata = new short[numBanks][];
for (int i= 0; i < numBanks; i++) {
bankdata[i] = new short[size];
}
data = bankdata[0];
}
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
* using the specified array.
* Only the first <CODE>size</CODE> elements should be used by accessors of
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
* hold <CODE>size</CODE> elements.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
*/
public DataBufferUShort(short dataArray[], int size) {
super(UNTRACKABLE, TYPE_USHORT, size);
if (dataArray == null) {
throw new NullPointerException("dataArray is null");
}
data = dataArray;
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
* using the specified array, size, and offset. <CODE>dataArray</CODE> must have at
* least <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements
* <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
* be used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
* @param size The size of the <CODE>DataBuffer</CODE> bank.
* @param offset The offset into the <CODE>dataArray</CODE>.
*/
public DataBufferUShort(short dataArray[], int size, int offset) {
super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
if (dataArray == null) {
throw new NullPointerException("dataArray is null");
}
if ((size+offset) > dataArray.length) {
throw new IllegalArgumentException("Length of dataArray is less "+
" than size+offset.");
}
data = dataArray;
bankdata = new short[1][];
bankdata[0] = data;
}
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
* Only the first <CODE>size</CODE> elements of each array should be used by
* accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
*/
public DataBufferUShort(short dataArray[][], int size) {
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
if (dataArray == null) {
throw new NullPointerException("dataArray is null");
}
for (int i=0; i < dataArray.length; i++) {
if (dataArray[i] == null) {
throw new NullPointerException("dataArray["+i+"] is null");
}
}
bankdata = (short[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
* size, and offsets.
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
* bank, only elements <CODE>offset</CODE> through
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
* used by accessors of this <CODE>DataBuffer</CODE>.
* <p>
* Note that {@code DataBuffer} objects created by this constructor
* may be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
* @param offsets The offsets into each array.
*/
public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
if (dataArray == null) {
throw new NullPointerException("dataArray is null");
}
for (int i=0; i < dataArray.length; i++) {
if (dataArray[i] == null) {
throw new NullPointerException("dataArray["+i+"] is null");
}
if ((size+offsets[i]) > dataArray[i].length) {
throw new IllegalArgumentException("Length of dataArray["+i+
"] is less than size+"+
"offsets["+i+"].");
}
}
bankdata = (short[][]) dataArray.clone();
data = bankdata[0];
}
/**
* Returns the default (first) unsigned-short data array.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return The first unsigned-short data array.
*/
public short[] getData() {
theTrackable.setUntrackable();
return data;
}
/**
* Returns the data array for the specified bank.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @param bank The bank whose data array you want to get.
* @return The data array for the specified bank.
*/
public short[] getData(int bank) {
theTrackable.setUntrackable();
return bankdata[bank];
}
/**
* Returns the data arrays for all banks.
* <p>
* Note that calling this method may cause this {@code DataBuffer}
* object to be incompatible with <a href="#optimizations">performance
* optimizations</a> used by some implementations (such as caching
* an associated image in video memory).
*
* @return All of the data arrays.
*/
public short[][] getBankData() {
theTrackable.setUntrackable();
return (short[][]) bankdata.clone();
}
/**
* Returns the requested data array element from the first (default) bank.
*
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int i) {
return (int)(data[i+offset]&0xffff);
}
/**
* Returns the requested data array element from the specified bank.
*
* @param bank The bank from which you want to get a data array element.
* @param i The data array element you want to get.
* @return The requested data array element as an integer.
* @see #setElem(int, int)
* @see #setElem(int, int, int)
*/
public int getElem(int bank, int i) {
return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
}
/**
* Sets the requested data array element in the first (default) bank
* to the specified value.
*
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int i, int val) {
data[i+offset] = (short)(val&0xffff);
theTrackable.markDirty();
}
/**
* Sets the requested data array element in the specified bank
* from the given integer.
* @param bank The bank in which you want to set the data array element.
* @param i The data array element you want to set.
* @param val The integer value to which you want to set the specified data array element.
* @see #getElem(int)
* @see #getElem(int, int)
*/
public void setElem(int bank, int i, int val) {
bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
theTrackable.markDirty();
}
}

View File

@ -0,0 +1,699 @@
/*
* Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
/**
* The <code>MultiPixelPackedSampleModel</code> class represents
* one-banded images and can pack multiple one-sample
* pixels into one data element. Pixels are not allowed to span data elements.
* The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
* or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
* and a power of 2 number of pixels must fit exactly in one data element.
* Pixel bit stride is equal to the number of bits per pixel. Scanline
* stride is in data elements and the last several data elements might be
* padded with unused pixels. Data bit offset is the offset in bits from
* the beginning of the {@link DataBuffer} to the first pixel and must be
* a multiple of pixel bit stride.
* <p>
* The following code illustrates extracting the bits for pixel
* <code>x,&nbsp;y</code> from <code>DataBuffer</code> <code>data</code>
* and storing the pixel data in data elements of type
* <code>dataType</code>:
* <pre>
* int dataElementSize = DataBuffer.getDataTypeSize(dataType);
* int bitnum = dataBitOffset + x*pixelBitStride;
* int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
* int shift = dataElementSize - (bitnum & (dataElementSize-1))
* - pixelBitStride;
* int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
* </pre>
*/
public class MultiPixelPackedSampleModel extends SampleModel
{
/** The number of bits from one pixel to the next. */
int pixelBitStride;
/** Bitmask that extracts the rightmost pixel of a data element. */
int bitMask;
/**
* The number of pixels that fit in a data element. Also used
* as the number of bits per pixel.
*/
int pixelsPerDataElement;
/** The size of a data element in bits. */
int dataElementSize;
/** The bit offset into the data array where the first pixel begins.
*/
int dataBitOffset;
/** ScanlineStride of the data buffer described in data array elements. */
int scanlineStride;
/**
* Constructs a <code>MultiPixelPackedSampleModel</code> with the
* specified data type, width, height and number of bits per pixel.
* @param dataType the data type for storing samples
* @param w the width, in pixels, of the region of
* image data described
* @param h the height, in pixels, of the region of
* image data described
* @param numberOfBits the number of bits per pixel
* @throws IllegalArgumentException if <code>dataType</code> is not
* either <code>DataBuffer.TYPE_BYTE</code>,
* <code>DataBuffer.TYPE_USHORT</code>, or
* <code>DataBuffer.TYPE_INT</code>
*/
public MultiPixelPackedSampleModel(int dataType,
int w,
int h,
int numberOfBits) {
this(dataType,w,h,
numberOfBits,
(w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
DataBuffer.getDataTypeSize(dataType),
0);
if (dataType != DataBuffer.TYPE_BYTE &&
dataType != DataBuffer.TYPE_USHORT &&
dataType != DataBuffer.TYPE_INT) {
throw new IllegalArgumentException("Unsupported data type "+
dataType);
}
}
/**
* Constructs a <code>MultiPixelPackedSampleModel</code> with
* specified data type, width, height, number of bits per pixel,
* scanline stride and data bit offset.
* @param dataType the data type for storing samples
* @param w the width, in pixels, of the region of
* image data described
* @param h the height, in pixels, of the region of
* image data described
* @param numberOfBits the number of bits per pixel
* @param scanlineStride the line stride of the image data
* @param dataBitOffset the data bit offset for the region of image
* data described
* @exception RasterFormatException if the number of bits per pixel
* is not a power of 2 or if a power of 2 number of
* pixels do not fit in one data element.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> is not greater than 0
* @throws IllegalArgumentException if <code>dataType</code> is not
* either <code>DataBuffer.TYPE_BYTE</code>,
* <code>DataBuffer.TYPE_USHORT</code>, or
* <code>DataBuffer.TYPE_INT</code>
*/
public MultiPixelPackedSampleModel(int dataType, int w, int h,
int numberOfBits,
int scanlineStride,
int dataBitOffset) {
super(dataType, w, h, 1);
if (dataType != DataBuffer.TYPE_BYTE &&
dataType != DataBuffer.TYPE_USHORT &&
dataType != DataBuffer.TYPE_INT) {
throw new IllegalArgumentException("Unsupported data type "+
dataType);
}
this.dataType = dataType;
this.pixelBitStride = numberOfBits;
this.scanlineStride = scanlineStride;
this.dataBitOffset = dataBitOffset;
this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
this.pixelsPerDataElement = dataElementSize/numberOfBits;
if (pixelsPerDataElement*numberOfBits != dataElementSize) {
throw new RasterFormatException("MultiPixelPackedSampleModel " +
"does not allow pixels to " +
"span data element boundaries");
}
this.bitMask = (1 << numberOfBits) - 1;
}
/**
* Creates a new <code>MultiPixelPackedSampleModel</code> with the
* specified width and height. The new
* <code>MultiPixelPackedSampleModel</code> has the
* same storage data type and number of bits per pixel as this
* <code>MultiPixelPackedSampleModel</code>.
* @param w the specified width
* @param h the specified height
* @return a {@link SampleModel} with the specified width and height
* and with the same storage data type and number of bits per pixel
* as this <code>MultiPixelPackedSampleModel</code>.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> is not greater than 0
*/
public SampleModel createCompatibleSampleModel(int w, int h) {
SampleModel sampleModel =
new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
return sampleModel;
}
/**
* Creates a <code>DataBuffer</code> that corresponds to this
* <code>MultiPixelPackedSampleModel</code>. The
* <code>DataBuffer</code> object's data type and size
* is consistent with this <code>MultiPixelPackedSampleModel</code>.
* The <code>DataBuffer</code> has a single bank.
* @return a <code>DataBuffer</code> with the same data type and
* size as this <code>MultiPixelPackedSampleModel</code>.
*/
public DataBuffer createDataBuffer() {
DataBuffer dataBuffer = null;
int size = (int)scanlineStride*height;
switch (dataType) {
case DataBuffer.TYPE_BYTE:
dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
break;
case DataBuffer.TYPE_USHORT:
dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
break;
case DataBuffer.TYPE_INT:
dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
break;
}
return dataBuffer;
}
/**
* Returns the number of data elements needed to transfer one pixel
* via the {@link #getDataElements} and {@link #setDataElements}
* methods. For a <code>MultiPixelPackedSampleModel</code>, this is
* one.
* @return the number of data elements.
*/
public int getNumDataElements() {
return 1;
}
/**
* Returns the number of bits per sample for all bands.
* @return the number of bits per sample.
*/
public int[] getSampleSize() {
int sampleSize[] = {pixelBitStride};
return sampleSize;
}
/**
* Returns the number of bits per sample for the specified band.
* @param band the specified band
* @return the number of bits per sample for the specified band.
*/
public int getSampleSize(int band) {
return pixelBitStride;
}
/**
* Returns the offset of pixel (x,&nbsp;y) in data array elements.
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @return the offset of the specified pixel.
*/
public int getOffset(int x, int y) {
int offset = y * scanlineStride;
offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
return offset;
}
/**
* Returns the offset, in bits, into the data element in which it is
* stored for the <code>x</code>th pixel of a scanline.
* This offset is the same for all scanlines.
* @param x the specified pixel
* @return the bit offset of the specified pixel.
*/
public int getBitOffset(int x){
return (x*pixelBitStride+dataBitOffset)%dataElementSize;
}
/**
* Returns the scanline stride.
* @return the scanline stride of this
* <code>MultiPixelPackedSampleModel</code>.
*/
public int getScanlineStride() {
return scanlineStride;
}
/**
* Returns the pixel bit stride in bits. This value is the same as
* the number of bits per pixel.
* @return the <code>pixelBitStride</code> of this
* <code>MultiPixelPackedSampleModel</code>.
*/
public int getPixelBitStride() {
return pixelBitStride;
}
/**
* Returns the data bit offset in bits.
* @return the <code>dataBitOffset</code> of this
* <code>MultiPixelPackedSampleModel</code>.
*/
public int getDataBitOffset() {
return dataBitOffset;
}
/**
* Returns the TransferType used to transfer pixels by way of the
* <code>getDataElements</code> and <code>setDataElements</code>
* methods. The TransferType might or might not be the same as the
* storage DataType. The TransferType is one of
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
* or DataBuffer.TYPE_INT.
* @return the transfertype.
*/
public int getTransferType() {
if (pixelBitStride > 16)
return DataBuffer.TYPE_INT;
else if (pixelBitStride > 8)
return DataBuffer.TYPE_USHORT;
else
return DataBuffer.TYPE_BYTE;
}
/**
* Creates a new <code>MultiPixelPackedSampleModel</code> with a
* subset of the bands of this
* <code>MultiPixelPackedSampleModel</code>. Since a
* <code>MultiPixelPackedSampleModel</code> only has one band, the
* bands argument must have a length of one and indicate the zeroth
* band.
* @param bands the specified bands
* @return a new <code>SampleModel</code> with a subset of bands of
* this <code>MultiPixelPackedSampleModel</code>.
* @exception RasterFormatException if the number of bands requested
* is not one.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> is not greater than 0
*/
public SampleModel createSubsetSampleModel(int bands[]) {
if (bands != null) {
if (bands.length != 1)
throw new RasterFormatException("MultiPixelPackedSampleModel has "
+ "only one band.");
}
SampleModel sm = createCompatibleSampleModel(width, height);
return sm;
}
/**
* Returns as <code>int</code> the sample in a specified band for the
* pixel located at (x,&nbsp;y). An
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
* coordinates are not in bounds.
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @param b the band to return, which is assumed to be 0
* @param data the <code>DataBuffer</code> containing the image
* data
* @return the specified band containing the sample of the specified
* pixel.
* @exception ArrayIndexOutOfBoundException if the specified
* coordinates are not in bounds.
* @see #setSample(int, int, int, int, DataBuffer)
*/
public int getSample(int x, int y, int b, DataBuffer data) {
// 'b' must be 0
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
(b != 0)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int bitnum = dataBitOffset + x*pixelBitStride;
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
return (element >> shift) & bitMask;
}
/**
* Sets a sample in the specified band for the pixel located at
* (x,&nbsp;y) in the <code>DataBuffer</code> using an
* <code>int</code> for input.
* An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
* coordinates are not in bounds.
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @param b the band to return, which is assumed to be 0
* @param s the input sample as an <code>int</code>
* @param data the <code>DataBuffer</code> where image data is stored
* @exception ArrayIndexOutOfBoundsException if the coordinates are
* not in bounds.
* @see #getSample(int, int, int, DataBuffer)
*/
public void setSample(int x, int y, int b, int s,
DataBuffer data) {
// 'b' must be 0
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
(b != 0)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int bitnum = dataBitOffset + x * pixelBitStride;
int index = y * scanlineStride + (bitnum / dataElementSize);
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
int element = data.getElem(index);
element &= ~(bitMask << shift);
element |= (s & bitMask) << shift;
data.setElem(index,element);
}
/**
* Returns data for a single pixel in a primitive array of type
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
* the array has one element, and the type is the smallest of
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
* that can hold a single pixel. Generally, <code>obj</code>
* should be passed in as <code>null</code>, so that the
* <code>Object</code> is created automatically and is the
* correct primitive data type.
* <p>
* The following code illustrates transferring data for one pixel from
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
* described by <code>MultiPixelPackedSampleModel</code>
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
* whose storage layout is described by
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
* The transfer is generally more efficient than using
* <code>getPixel</code> or <code>setPixel</code>.
* <pre>
* MultiPixelPackedSampleModel mppsm1, mppsm2;
* DataBufferInt db1, db2;
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
* db1), db2);
* </pre>
* Using <code>getDataElements</code> or <code>setDataElements</code>
* to transfer between two <code>DataBuffer/SampleModel</code> pairs
* is legitimate if the <code>SampleModels</code> have the same number
* of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* If <code>obj</code> is not <code>null</code>, it should be a
* primitive array of type TransferType. Otherwise, a
* <code>ClassCastException</code> is thrown. An
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
* coordinates are not in bounds, or if <code>obj</code> is not
* <code>null</code> and is not large enough to hold the pixel data.
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @param obj a primitive array in which to return the pixel data or
* <code>null</code>.
* @param data the <code>DataBuffer</code> containing the image data.
* @return an <code>Object</code> containing data for the specified
* pixel.
* @exception ClassCastException if <code>obj</code> is not a
* primitive array of type TransferType or is not <code>null</code>
* @exception ArrayIndexOutOfBoundsException if the coordinates are
* not in bounds, or if <code>obj</code> is not <code>null</code> or
* not large enough to hold the pixel data
* @see #setDataElements(int, int, Object, DataBuffer)
*/
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
int bitnum = dataBitOffset + x*pixelBitStride;
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
int element = 0;
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] bdata;
if (obj == null)
bdata = new byte[1];
else
bdata = (byte[])obj;
element = data.getElem(y*scanlineStride +
bitnum/dataElementSize);
bdata[0] = (byte)((element >> shift) & bitMask);
obj = (Object)bdata;
break;
case DataBuffer.TYPE_USHORT:
short[] sdata;
if (obj == null)
sdata = new short[1];
else
sdata = (short[])obj;
element = data.getElem(y*scanlineStride +
bitnum/dataElementSize);
sdata[0] = (short)((element >> shift) & bitMask);
obj = (Object)sdata;
break;
case DataBuffer.TYPE_INT:
int[] idata;
if (obj == null)
idata = new int[1];
else
idata = (int[])obj;
element = data.getElem(y*scanlineStride +
bitnum/dataElementSize);
idata[0] = (element >> shift) & bitMask;
obj = (Object)idata;
break;
}
return obj;
}
/**
* Returns the specified single band pixel in the first element
* of an <code>int</code> array.
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
* coordinates are not in bounds.
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @param iArray the array containing the pixel to be returned or
* <code>null</code>
* @param data the <code>DataBuffer</code> where image data is stored
* @return an array containing the specified pixel.
* @exception ArrayIndexOutOfBoundsException if the coordinates
* are not in bounds
* @see #setPixel(int, int, int[], DataBuffer)
*/
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int pixels[];
if (iArray != null) {
pixels = iArray;
} else {
pixels = new int [numBands];
}
int bitnum = dataBitOffset + x*pixelBitStride;
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
pixels[0] = (element >> shift) & bitMask;
return pixels;
}
/**
* Sets the data for a single pixel in the specified
* <code>DataBuffer</code> from a primitive array of type
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
* only the first element of the array holds valid data,
* and the type must be the smallest of
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
* that can hold a single pixel.
* <p>
* The following code illustrates transferring data for one pixel from
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
* described by <code>MultiPixelPackedSampleModel</code>
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
* whose storage layout is described by
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
* The transfer is generally more efficient than using
* <code>getPixel</code> or <code>setPixel</code>.
* <pre>
* MultiPixelPackedSampleModel mppsm1, mppsm2;
* DataBufferInt db1, db2;
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
* db1), db2);
* </pre>
* Using <code>getDataElements</code> or <code>setDataElements</code> to
* transfer between two <code>DataBuffer/SampleModel</code> pairs is
* legitimate if the <code>SampleModel</code> objects have
* the same number of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* <code>obj</code> must be a primitive array of type TransferType.
* Otherwise, a <code>ClassCastException</code> is thrown. An
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
* coordinates are not in bounds, or if <code>obj</code> is not large
* enough to hold the pixel data.
* @param x the X coordinate of the pixel location
* @param y the Y coordinate of the pixel location
* @param obj a primitive array containing pixel data
* @param data the <code>DataBuffer</code> containing the image data
* @see #getDataElements(int, int, Object, DataBuffer)
*/
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
int bitnum = dataBitOffset + x * pixelBitStride;
int index = y * scanlineStride + (bitnum / dataElementSize);
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
int element = data.getElem(index);
element &= ~(bitMask << shift);
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] barray = (byte[])obj;
element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
data.setElem(index, element);
break;
case DataBuffer.TYPE_USHORT:
short[] sarray = (short[])obj;
element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
data.setElem(index, element);
break;
case DataBuffer.TYPE_INT:
int[] iarray = (int[])obj;
element |= (iarray[0] & bitMask) << shift;
data.setElem(index, element);
break;
}
}
/**
* Sets a pixel in the <code>DataBuffer</code> using an
* <code>int</code> array for input.
* <code>ArrayIndexOutOfBoundsException</code> is thrown if
* the coordinates are not in bounds.
* @param x the X coordinate of the pixel location
* @param y the Y coordinate of the pixel location
* @param iArray the input pixel in an <code>int</code> array
* @param data the <code>DataBuffer</code> containing the image data
* @see #getPixel(int, int, int[], DataBuffer)
*/
public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int bitnum = dataBitOffset + x * pixelBitStride;
int index = y * scanlineStride + (bitnum / dataElementSize);
int shift = dataElementSize - (bitnum & (dataElementSize-1))
- pixelBitStride;
int element = data.getElem(index);
element &= ~(bitMask << shift);
element |= (iArray[0] & bitMask) << shift;
data.setElem(index,element);
}
public boolean equals(Object o) {
if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
return false;
}
MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
return this.width == that.width &&
this.height == that.height &&
this.numBands == that.numBands &&
this.dataType == that.dataType &&
this.pixelBitStride == that.pixelBitStride &&
this.bitMask == that.bitMask &&
this.pixelsPerDataElement == that.pixelsPerDataElement &&
this.dataElementSize == that.dataElementSize &&
this.dataBitOffset == that.dataBitOffset &&
this.scanlineStride == that.scanlineStride;
}
// If we implement equals() we must also implement hashCode
public int hashCode() {
int hash = 0;
hash = width;
hash <<= 8;
hash ^= height;
hash <<= 8;
hash ^= numBands;
hash <<= 8;
hash ^= dataType;
hash <<= 8;
hash ^= pixelBitStride;
hash <<= 8;
hash ^= bitMask;
hash <<= 8;
hash ^= pixelsPerDataElement;
hash <<= 8;
hash ^= dataElementSize;
hash <<= 8;
hash ^= dataBitOffset;
hash <<= 8;
hash ^= scanlineStride;
return hash;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,217 @@
/*
* Portions Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import java.awt.Rectangle;
import java.util.Dictionary;
import java.util.Vector;
/**
* RenderedImage is a common interface for objects which contain
* or can produce image data in the form of Rasters. The image
* data may be stored/produced as a single tile or a regular array
* of tiles.
*/
public interface RenderedImage {
/**
* Returns a vector of RenderedImages that are the immediate sources of
* image data for this RenderedImage. This method returns null if
* the RenderedImage object has no information about its immediate
* sources. It returns an empty Vector if the RenderedImage object has
* no immediate sources.
* @return a Vector of <code>RenderedImage</code> objects.
*/
Vector<RenderedImage> getSources();
/**
* Gets a property from the property set of this image. The set of
* properties and whether it is immutable is determined by the
* implementing class. This method returns
* java.awt.Image.UndefinedProperty if the specified property is
* not defined for this RenderedImage.
* @param name the name of the property
* @return the property indicated by the specified name.
* @see java.awt.Image#UndefinedProperty
*/
Object getProperty(String name);
/**
* Returns an array of names recognized by
* {@link #getProperty(String) getProperty(String)}
* or <code>null</code>, if no property names are recognized.
* @return a <code>String</code> array containing all of the
* property names that <code>getProperty(String)</code> recognizes;
* or <code>null</code> if no property names are recognized.
*/
String[] getPropertyNames();
/**
* Returns the ColorModel associated with this image. All Rasters
* returned from this image will have this as their ColorModel. This
* can return null.
* @return the <code>ColorModel</code> of this image.
*/
ColorModel getColorModel();
/**
* Returns the SampleModel associated with this image. All Rasters
* returned from this image will have this as their SampleModel.
* @return the <code>SampleModel</code> of this image.
*/
SampleModel getSampleModel();
/**
* Returns the width of the RenderedImage.
* @return the width of this <code>RenderedImage</code>.
*/
int getWidth();
/**
* Returns the height of the RenderedImage.
* @return the height of this <code>RenderedImage</code>.
*/
int getHeight();
/**
* Returns the minimum X coordinate (inclusive) of the RenderedImage.
* @return the X coordinate of this <code>RenderedImage</code>.
*/
int getMinX();
/**
* Returns the minimum Y coordinate (inclusive) of the RenderedImage.
* @return the Y coordinate of this <code>RenderedImage</code>.
*/
int getMinY();
/**
* Returns the number of tiles in the X direction.
* @return the number of tiles in the X direction.
*/
int getNumXTiles();
/**
* Returns the number of tiles in the Y direction.
* @return the number of tiles in the Y direction.
*/
int getNumYTiles();
/**
* Returns the minimum tile index in the X direction.
* @return the minimum tile index in the X direction.
*/
int getMinTileX();
/**
* Returns the minimum tile index in the Y direction.
* @return the minimum tile index in the X direction.
*/
int getMinTileY();
/**
* Returns the tile width in pixels. All tiles must have the same
* width.
* @return the tile width in pixels.
*/
int getTileWidth();
/**
* Returns the tile height in pixels. All tiles must have the same
* height.
* @return the tile height in pixels.
*/
int getTileHeight();
/**
* Returns the X offset of the tile grid relative to the origin,
* i.e., the X coordinate of the upper-left pixel of tile (0, 0).
* (Note that tile (0, 0) may not actually exist.)
* @return the X offset of the tile grid relative to the origin.
*/
int getTileGridXOffset();
/**
* Returns the Y offset of the tile grid relative to the origin,
* i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
* (Note that tile (0, 0) may not actually exist.)
* @return the Y offset of the tile grid relative to the origin.
*/
int getTileGridYOffset();
/**
* Returns tile (tileX, tileY). Note that tileX and tileY are indices
* into the tile array, not pixel locations. The Raster that is returned
* is live and will be updated if the image is changed.
* @param tileX the X index of the requested tile in the tile array
* @param tileY the Y index of the requested tile in the tile array
* @return the tile given the specified indices.
*/
Raster getTile(int tileX, int tileY);
/**
* Returns the image as one large tile (for tile based
* images this will require fetching the whole image
* and copying the image data over). The Raster returned is
* a copy of the image data and will not be updated if the image
* is changed.
* @return the image as one large tile.
*/
Raster getData();
/**
* Computes and returns an arbitrary region of the RenderedImage.
* The Raster returned is a copy of the image data and will not
* be updated if the image is changed.
* @param rect the region of the RenderedImage to be returned.
* @return the region of the <code>RenderedImage</code>
* indicated by the specified <code>Rectangle</code>.
*/
Raster getData(Rectangle rect);
/**
* Computes an arbitrary rectangular region of the RenderedImage
* and copies it into a caller-supplied WritableRaster. The region
* to be computed is determined from the bounds of the supplied
* WritableRaster. The supplied WritableRaster must have a
* SampleModel that is compatible with this image. If raster is null,
* an appropriate WritableRaster is created.
* @param raster a WritableRaster to hold the returned portion of the
* image, or null.
* @return a reference to the supplied or created WritableRaster.
*/
WritableRaster copyData(WritableRaster raster);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,805 @@
/*
* Portions Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import java.util.Arrays;
/**
* This class represents pixel data packed such that the N samples which make
* up a single pixel are stored in a single data array element, and each data
* data array element holds samples for only one pixel.
* This class supports
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
* {@link DataBuffer#TYPE_INT TYPE_INT} data types.
* All data array elements reside
* in the first bank of a DataBuffer. Accessor methods are provided so
* that the image data can be manipulated directly. Scanline stride is the
* number of data array elements between a given sample and the corresponding
* sample in the same column of the next scanline. Bit masks are the masks
* required to extract the samples representing the bands of the pixel.
* Bit offsets are the offsets in bits into the data array
* element of the samples representing the bands of the pixel.
* <p>
* The following code illustrates extracting the bits of the sample
* representing band <code>b</code> for pixel <code>x,y</code>
* from DataBuffer <code>data</code>:
* <pre>
* int sample = data.getElem(y * scanlineStride + x);
* sample = (sample & bitMasks[b]) >>> bitOffsets[b];
* </pre>
*/
public class SinglePixelPackedSampleModel extends SampleModel
{
/** Bit masks for all bands of the image data. */
private int bitMasks[];
/** Bit Offsets for all bands of the image data. */
private int bitOffsets[];
/** Bit sizes for all the bands of the image data. */
private int bitSizes[];
/** Maximum bit size. */
private int maxBitSize;
/** Line stride of the region of image data described by this
* SinglePixelPackedSampleModel.
*/
private int scanlineStride;
private static native void initIDs();
static {
ColorModel.loadLibraries();
initIDs();
}
/**
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
* Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and
* masks must not overlap.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of the
* image data described.
* @param h The height (in pixels) of the region of the
* image data described.
* @param bitMasks The bit masks for all bands.
* @throws IllegalArgumentException if <code>dataType</code> is not
* either <code>DataBuffer.TYPE_BYTE</code>,
* <code>DataBuffer.TYPE_USHORT</code>, or
* <code>DataBuffer.TYPE_INT</code>
*/
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int bitMasks[]) {
this(dataType, w, h, w, bitMasks);
if (dataType != DataBuffer.TYPE_BYTE &&
dataType != DataBuffer.TYPE_USHORT &&
dataType != DataBuffer.TYPE_INT) {
throw new IllegalArgumentException("Unsupported data type "+
dataType);
}
}
/**
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
* and a scanline stride equal to scanlineStride data array elements.
* Each sample is stored in a data array element in the position of
* its corresponding bit mask. Each bit mask must be contiguous and
* masks must not overlap.
* @param dataType The data type for storing samples.
* @param w The width (in pixels) of the region of
* image data described.
* @param h The height (in pixels) of the region of
* image data described.
* @param scanlineStride The line stride of the image data.
* @param bitMasks The bit masks for all bands.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> is not greater than 0
* @throws IllegalArgumentException if any mask in
* <code>bitMask</code> is not contiguous
* @throws IllegalArgumentException if <code>dataType</code> is not
* either <code>DataBuffer.TYPE_BYTE</code>,
* <code>DataBuffer.TYPE_USHORT</code>, or
* <code>DataBuffer.TYPE_INT</code>
*/
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int scanlineStride, int bitMasks[]) {
super(dataType, w, h, bitMasks.length);
if (dataType != DataBuffer.TYPE_BYTE &&
dataType != DataBuffer.TYPE_USHORT &&
dataType != DataBuffer.TYPE_INT) {
throw new IllegalArgumentException("Unsupported data type "+
dataType);
}
this.dataType = dataType;
this.bitMasks = (int[]) bitMasks.clone();
this.scanlineStride = scanlineStride;
this.bitOffsets = new int[numBands];
this.bitSizes = new int[numBands];
this.maxBitSize = 0;
for (int i=0; i<numBands; i++) {
int bitOffset = 0, bitSize = 0, mask;
mask = bitMasks[i];
if (mask != 0) {
while ((mask & 1) == 0) {
mask = mask >>> 1;
bitOffset++;
}
while ((mask & 1) == 1) {
mask = mask >>> 1;
bitSize++;
}
if (mask != 0) {
throw new IllegalArgumentException("Mask "+bitMasks[i]+
" must be contiguous");
}
}
bitOffsets[i] = bitOffset;
bitSizes[i] = bitSize;
if (bitSize > maxBitSize) {
maxBitSize = bitSize;
}
}
}
/**
* Returns the number of data elements needed to transfer one pixel
* via the getDataElements and setDataElements methods.
* For a SinglePixelPackedSampleModel, this is one.
*/
public int getNumDataElements() {
return 1;
}
/**
* Returns the size of the buffer (in data array elements)
* needed for a data buffer that matches this
* SinglePixelPackedSampleModel.
*/
private long getBufferSize() {
long size = scanlineStride * (height-1) + width;
return size;
}
/**
* Creates a new SinglePixelPackedSampleModel with the specified
* width and height. The new SinglePixelPackedSampleModel will have the
* same storage data type and bit masks as this
* SinglePixelPackedSampleModel.
* @param w the width of the resulting <code>SampleModel</code>
* @param h the height of the resulting <code>SampleModel</code>
* @return a <code>SinglePixelPackedSampleModel</code> with the
* specified width and height.
* @throws IllegalArgumentException if <code>w</code> or
* <code>h</code> is not greater than 0
*/
public SampleModel createCompatibleSampleModel(int w, int h) {
SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
bitMasks);
return sampleModel;
}
/**
* Creates a DataBuffer that corresponds to this
* SinglePixelPackedSampleModel. The DataBuffer's data type and size
* will be consistent with this SinglePixelPackedSampleModel. The
* DataBuffer will have a single bank.
*/
public DataBuffer createDataBuffer() {
DataBuffer dataBuffer = null;
int size = (int)getBufferSize();
switch (dataType) {
case DataBuffer.TYPE_BYTE:
dataBuffer = new DataBufferByte(size);
break;
case DataBuffer.TYPE_USHORT:
dataBuffer = new DataBufferUShort(size);
break;
case DataBuffer.TYPE_INT:
dataBuffer = new DataBufferInt(size);
break;
}
return dataBuffer;
}
/** Returns the number of bits per sample for all bands. */
public int[] getSampleSize() {
int mask;
int sampleSize[] = new int [numBands];
for (int i=0; i<numBands; i++) {
sampleSize[i] = 0;
mask = bitMasks[i] >>> bitOffsets[i];
while ((mask & 1) != 0) {
sampleSize[i] ++;
mask = mask >>> 1;
}
}
return sampleSize;
}
/** Returns the number of bits per sample for the specified band. */
public int getSampleSize(int band) {
int sampleSize = 0;
int mask = bitMasks[band] >>> bitOffsets[band];
while ((mask & 1) != 0) {
sampleSize ++;
mask = mask >>> 1;
}
return sampleSize;
}
/** Returns the offset (in data array elements) of pixel (x,y).
* The data element containing pixel <code>x,y</code>
* can be retrieved from a DataBuffer <code>data</code> with a
* SinglePixelPackedSampleModel <code>sppsm</code> as:
* <pre>
* data.getElem(sppsm.getOffset(x, y));
* </pre>
* @param x the X coordinate of the specified pixel
* @param y the Y coordinate of the specified pixel
* @return the offset of the specified pixel.
*/
public int getOffset(int x, int y) {
int offset = y * scanlineStride + x;
return offset;
}
/** Returns the bit offsets into the data array element representing
* a pixel for all bands.
* @return the bit offsets representing a pixel for all bands.
*/
public int [] getBitOffsets() {
return (int[])bitOffsets.clone();
}
/** Returns the bit masks for all bands.
* @return the bit masks for all bands.
*/
public int [] getBitMasks() {
return (int[])bitMasks.clone();
}
/** Returns the scanline stride of this SinglePixelPackedSampleModel.
* @return the scanline stride of this
* <code>SinglePixelPackedSampleModel</code>.
*/
public int getScanlineStride() {
return scanlineStride;
}
/**
* This creates a new SinglePixelPackedSampleModel with a subset of the
* bands of this SinglePixelPackedSampleModel. The new
* SinglePixelPackedSampleModel can be used with any DataBuffer that the
* existing SinglePixelPackedSampleModel can be used with. The new
* SinglePixelPackedSampleModel/DataBuffer combination will represent
* an image with a subset of the bands of the original
* SinglePixelPackedSampleModel/DataBuffer combination.
* @exception RasterFormatException if the length of the bands argument is
* greater than the number of bands in
* the sample model.
*/
public SampleModel createSubsetSampleModel(int bands[]) {
if (bands.length > numBands)
throw new RasterFormatException("There are only " +
numBands +
" bands");
int newBitMasks[] = new int[bands.length];
for (int i=0; i<bands.length; i++)
newBitMasks[i] = bitMasks[bands[i]];
return new SinglePixelPackedSampleModel(this.dataType, width, height,
this.scanlineStride, newBitMasks);
}
/**
* Returns data for a single pixel in a primitive array of type
* TransferType. For a SinglePixelPackedSampleModel, the array will
* have one element, and the type will be the same as the storage
* data type. Generally, obj
* should be passed in as null, so that the Object will be created
* automatically and will be of the right primitive data type.
* <p>
* The following code illustrates transferring data for one pixel from
* DataBuffer <code>db1</code>, whose storage layout is described by
* SinglePixelPackedSampleModel <code>sppsm1</code>, to
* DataBuffer <code>db2</code>, whose storage layout is described by
* SinglePixelPackedSampleModel <code>sppsm2</code>.
* The transfer will generally be more efficient than using
* getPixel/setPixel.
* <pre>
* SinglePixelPackedSampleModel sppsm1, sppsm2;
* DataBufferInt db1, db2;
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
* db1), db2);
* </pre>
* Using getDataElements/setDataElements to transfer between two
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
* the same number of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* If obj is non-null, it should be a primitive array of type TransferType.
* Otherwise, a ClassCastException is thrown. An
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if obj is non-null and is not large enough to hold
* the pixel data.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param obj If non-null, a primitive array in which to return
* the pixel data.
* @param data The DataBuffer containing the image data.
* @return the data for the specified pixel.
* @see #setDataElements(int, int, Object, DataBuffer)
*/
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] bdata;
if (obj == null)
bdata = new byte[1];
else
bdata = (byte[])obj;
bdata[0] = (byte)data.getElem(y * scanlineStride + x);
obj = (Object)bdata;
break;
case DataBuffer.TYPE_USHORT:
short[] sdata;
if (obj == null)
sdata = new short[1];
else
sdata = (short[])obj;
sdata[0] = (short)data.getElem(y * scanlineStride + x);
obj = (Object)sdata;
break;
case DataBuffer.TYPE_INT:
int[] idata;
if (obj == null)
idata = new int[1];
else
idata = (int[])obj;
idata[0] = data.getElem(y * scanlineStride + x);
obj = (Object)idata;
break;
}
return obj;
}
/**
* Returns all samples in for the specified pixel in an int array.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param iArray If non-null, returns the samples in this array
* @param data The DataBuffer containing the image data.
* @return all samples for the specified pixel.
* @see #setPixel(int, int, int[], DataBuffer)
*/
public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int pixels[];
if (iArray == null) {
pixels = new int [numBands];
} else {
pixels = iArray;
}
int value = data.getElem(y * scanlineStride + x);
for (int i=0; i<numBands; i++) {
pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
}
return pixels;
}
/**
* Returns all samples for the specified rectangle of pixels in
* an int array, one sample per array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w The width of the pixel rectangle.
* @param h The height of the pixel rectangle.
* @param iArray If non-null, returns the samples in this array.
* @param data The DataBuffer containing the image data.
* @return all samples for the specified region of pixels.
* @see #setPixels(int, int, int, int, int[], DataBuffer)
*/
public int[] getPixels(int x, int y, int w, int h,
int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int pixels[];
if (iArray != null) {
pixels = iArray;
} else {
pixels = new int [w*h*numBands];
}
int lineOffset = y*scanlineStride + x;
int dstOffset = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int value = data.getElem(lineOffset+j);
for (int k=0; k < numBands; k++) {
pixels[dstOffset++] =
((value & bitMasks[k]) >>> bitOffsets[k]);
}
}
lineOffset += scanlineStride;
}
return pixels;
}
/**
* Returns as int the sample in a specified band for the pixel
* located at (x,y).
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param b The band to return.
* @param data The DataBuffer containing the image data.
* @return the sample in a specified band for the specified
* pixel.
* @see #setSample(int, int, int, int, DataBuffer)
*/
public int getSample(int x, int y, int b, DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int sample = data.getElem(y * scanlineStride + x);
return ((sample & bitMasks[b]) >>> bitOffsets[b]);
}
/**
* Returns the samples for a specified band for the specified rectangle
* of pixels in an int array, one sample per array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w The width of the pixel rectangle.
* @param h The height of the pixel rectangle.
* @param b The band to return.
* @param iArray If non-null, returns the samples in this array.
* @param data The DataBuffer containing the image data.
* @return the samples for the specified band for the specified
* region of pixels.
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
*/
public int[] getSamples(int x, int y, int w, int h, int b,
int iArray[], DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int samples[];
if (iArray != null) {
samples = iArray;
} else {
samples = new int [w*h];
}
int lineOffset = y*scanlineStride + x;
int dstOffset = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int value = data.getElem(lineOffset+j);
samples[dstOffset++] =
((value & bitMasks[b]) >>> bitOffsets[b]);
}
lineOffset += scanlineStride;
}
return samples;
}
/**
* Sets the data for a single pixel in the specified DataBuffer from a
* primitive array of type TransferType. For a
* SinglePixelPackedSampleModel, only the first element of the array
* will hold valid data, and the type of the array must be the same as
* the storage data type of the SinglePixelPackedSampleModel.
* <p>
* The following code illustrates transferring data for one pixel from
* DataBuffer <code>db1</code>, whose storage layout is described by
* SinglePixelPackedSampleModel <code>sppsm1</code>,
* to DataBuffer <code>db2</code>, whose storage layout is described by
* SinglePixelPackedSampleModel <code>sppsm2</code>.
* The transfer will generally be more efficient than using
* getPixel/setPixel.
* <pre>
* SinglePixelPackedSampleModel sppsm1, sppsm2;
* DataBufferInt db1, db2;
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
* db1), db2);
* </pre>
* Using getDataElements/setDataElements to transfer between two
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
* the same number of bands, corresponding bands have the same number of
* bits per sample, and the TransferTypes are the same.
* <p>
* obj must be a primitive array of type TransferType. Otherwise,
* a ClassCastException is thrown. An
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if obj is not large enough to hold the pixel data.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param obj A primitive array containing pixel data.
* @param data The DataBuffer containing the image data.
* @see #getDataElements(int, int, Object, DataBuffer)
*/
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int type = getTransferType();
switch(type) {
case DataBuffer.TYPE_BYTE:
byte[] barray = (byte[])obj;
data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
break;
case DataBuffer.TYPE_USHORT:
short[] sarray = (short[])obj;
data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
break;
case DataBuffer.TYPE_INT:
int[] iarray = (int[])obj;
data.setElem(y*scanlineStride+x, iarray[0]);
break;
}
}
/**
* Sets a pixel in the DataBuffer using an int array of samples for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param iArray The input samples in an int array.
* @param data The DataBuffer containing the image data.
* @see #getPixel(int, int, int[], DataBuffer)
*/
public void setPixel(int x, int y,
int iArray[],
DataBuffer data) {
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int lineOffset = y * scanlineStride + x;
int value = data.getElem(lineOffset);
for (int i=0; i < numBands; i++) {
value &= ~bitMasks[i];
value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
}
data.setElem(lineOffset, value);
}
/**
* Sets all samples for a rectangle of pixels from an int array containing
* one sample per array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w The width of the pixel rectangle.
* @param h The height of the pixel rectangle.
* @param iArray The input samples in an int array.
* @param data The DataBuffer containing the image data.
* @see #getPixels(int, int, int, int, int[], DataBuffer)
*/
public void setPixels(int x, int y, int w, int h,
int iArray[], DataBuffer data) {
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int lineOffset = y*scanlineStride + x;
int srcOffset = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int value = data.getElem(lineOffset+j);
for (int k=0; k < numBands; k++) {
value &= ~bitMasks[k];
int srcValue = iArray[srcOffset++];
value |= ((srcValue << bitOffsets[k])
& bitMasks[k]);
}
data.setElem(lineOffset+j, value);
}
lineOffset += scanlineStride;
}
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using an int for input.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param b The band to set.
* @param s The input sample as an int.
* @param data The DataBuffer containing the image data.
* @see #getSample(int, int, int, DataBuffer)
*/
public void setSample(int x, int y, int b, int s,
DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int value = data.getElem(y*scanlineStride + x);
value &= ~bitMasks[b];
value |= (s << bitOffsets[b]) & bitMasks[b];
data.setElem(y*scanlineStride + x,value);
}
/**
* Sets the samples in the specified band for the specified rectangle
* of pixels from an int array containing one sample per array element.
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w The width of the pixel rectangle.
* @param h The height of the pixel rectangle.
* @param b The band to set.
* @param iArray The input samples in an int array.
* @param data The DataBuffer containing the image data.
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
*/
public void setSamples(int x, int y, int w, int h, int b,
int iArray[], DataBuffer data) {
// Bounds check for 'b' will be performed automatically
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int lineOffset = y*scanlineStride + x;
int srcOffset = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int value = data.getElem(lineOffset+j);
value &= ~bitMasks[b];
int sample = iArray[srcOffset++];
value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
data.setElem(lineOffset+j,value);
}
lineOffset += scanlineStride;
}
}
public boolean equals(Object o) {
if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
return false;
}
SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
return this.width == that.width &&
this.height == that.height &&
this.numBands == that.numBands &&
this.dataType == that.dataType &&
Arrays.equals(this.bitMasks, that.bitMasks) &&
Arrays.equals(this.bitOffsets, that.bitOffsets) &&
Arrays.equals(this.bitSizes, that.bitSizes) &&
this.maxBitSize == that.maxBitSize &&
this.scanlineStride == that.scanlineStride;
}
// If we implement equals() we must also implement hashCode
public int hashCode() {
int hash = 0;
hash = width;
hash <<= 8;
hash ^= height;
hash <<= 8;
hash ^= numBands;
hash <<= 8;
hash ^= dataType;
hash <<= 8;
for (int i = 0; i < bitMasks.length; i++) {
hash ^= bitMasks[i];
hash <<= 8;
}
for (int i = 0; i < bitOffsets.length; i++) {
hash ^= bitOffsets[i];
hash <<= 8;
}
for (int i = 0; i < bitSizes.length; i++) {
hash ^= bitSizes[i];
hash <<= 8;
}
hash ^= maxBitSize;
hash <<= 8;
hash ^= scanlineStride;
return hash;
}
}

View File

@ -0,0 +1,741 @@
/*
* Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import java.awt.Rectangle;
import java.awt.Point;
/**
* This class extends Raster to provide pixel writing capabilities.
* Refer to the class comment for Raster for descriptions of how
* a Raster stores pixels.
*
* <p> The constructors of this class are protected. To instantiate
* a WritableRaster, use one of the createWritableRaster factory methods
* in the Raster class.
*/
public class WritableRaster extends Raster {
/**
* Constructs a WritableRaster with the given SampleModel. The
* WritableRaster's upper left corner is origin and it is the
* same size as the SampleModel. A DataBuffer large enough to
* describe the WritableRaster is automatically created.
* @param sampleModel The SampleModel that specifies the layout.
* @param origin The Point that specifies the origin.
* @throws RasterFormatException if computing either
* <code>origin.x + sampleModel.getWidth()</code> or
* <code>origin.y + sampleModel.getHeight()</code> results
* in integer overflow
*/
protected WritableRaster(SampleModel sampleModel,
Point origin) {
this(sampleModel,
sampleModel.createDataBuffer(),
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a WritableRaster with the given SampleModel and DataBuffer.
* The WritableRaster's upper left corner is origin and it is the same
* size as the SampleModel. The DataBuffer is not initialized and must
* be compatible with SampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBuffer that contains the image data.
* @param origin The Point that specifies the origin.
* @throws RasterFormatException if computing either
* <code>origin.x + sampleModel.getWidth()</code> or
* <code>origin.y + sampleModel.getHeight()</code> results
* in integer overflow
*/
protected WritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin) {
this(sampleModel,
dataBuffer,
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a WritableRaster with the given SampleModel, DataBuffer,
* and parent. aRegion specifies the bounding rectangle of the new
* Raster. When translated into the base Raster's coordinate
* system, aRegion must be contained by the base Raster.
* (The base Raster is the Raster's ancestor which has no parent.)
* sampleModelTranslate specifies the sampleModelTranslateX and
* sampleModelTranslateY values of the new Raster.
*
* Note that this constructor should generally be called by other
* constructors or create methods, it should not be used directly.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBuffer that contains the image data.
* @param aRegion The Rectangle that specifies the image area.
* @param sampleModelTranslate The Point that specifies the translation
* from SampleModel to Raster coordinates.
* @param parent The parent (if any) of this raster.
* @throws RasterFormatException if <code>aRegion</code> has width
* or height less than or equal to zero, or computing either
* <code>aRegion.x + aRegion.width</code> or
* <code>aRegion.y + aRegion.height</code> results in integer
* overflow
*/
protected WritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point sampleModelTranslate,
WritableRaster parent){
super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
}
/** Returns the parent WritableRaster (if any) of this WritableRaster,
* or else null.
* @return the parent of this <code>WritableRaster</code>, or
* <code>null</code>.
*/
public WritableRaster getWritableParent() {
return (WritableRaster)parent;
}
/**
* Create a WritableRaster with the same size, SampleModel and DataBuffer
* as this one, but with a different location. The new WritableRaster
* will possess a reference to the current WritableRaster, accessible
* through its getParent() and getWritableParent() methods.
*
* @param childMinX X coord of the upper left corner of the new Raster.
* @param childMinY Y coord of the upper left corner of the new Raster.
* @return a <code>WritableRaster</code> the same as this one except
* for the specified location.
* @throws RasterFormatException if computing either
* <code>childMinX + this.getWidth()</code> or
* <code>childMinY + this.getHeight()</code> results in integer
* overflow
*/
public WritableRaster createWritableTranslatedChild(int childMinX,
int childMinY) {
return createWritableChild(minX,minY,width,height,
childMinX,childMinY,null);
}
/**
* Returns a new WritableRaster which shares all or part of this
* WritableRaster's DataBuffer. The new WritableRaster will
* possess a reference to the current WritableRaster, accessible
* through its getParent() and getWritableParent() methods.
*
* <p> The parentX, parentY, width and height parameters form a
* Rectangle in this WritableRaster's coordinate space, indicating
* the area of pixels to be shared. An error will be thrown if
* this Rectangle is not contained with the bounds of the current
* WritableRaster.
*
* <p> The new WritableRaster may additionally be translated to a
* different coordinate system for the plane than that used by the current
* WritableRaster. The childMinX and childMinY parameters give
* the new (x, y) coordinate of the upper-left pixel of the
* returned WritableRaster; the coordinate (childMinX, childMinY)
* in the new WritableRaster will map to the same pixel as the
* coordinate (parentX, parentY) in the current WritableRaster.
*
* <p> The new WritableRaster may be defined to contain only a
* subset of the bands of the current WritableRaster, possibly
* reordered, by means of the bandList parameter. If bandList is
* null, it is taken to include all of the bands of the current
* WritableRaster in their current order.
*
* <p> To create a new WritableRaster that contains a subregion of
* the current WritableRaster, but shares its coordinate system
* and bands, this method should be called with childMinX equal to
* parentX, childMinY equal to parentY, and bandList equal to
* null.
*
* @param parentX X coordinate of the upper left corner in this
* WritableRaster's coordinates.
* @param parentY Y coordinate of the upper left corner in this
* WritableRaster's coordinates.
* @param w Width of the region starting at (parentX, parentY).
* @param h Height of the region starting at (parentX, parentY).
* @param childMinX X coordinate of the upper left corner of
* the returned WritableRaster.
* @param childMinY Y coordinate of the upper left corner of
* the returned WritableRaster.
* @param bandList Array of band indices, or null to use all bands.
* @return a <code>WritableRaster</code> sharing all or part of the
* <code>DataBuffer</code> of this <code>WritableRaster</code>.
* @exception RasterFormatException if the subregion is outside of the
* raster bounds.
* @throws RasterFormatException if <code>w</code> or
* <code>h</code>
* is less than or equal to zero, or computing any of
* <code>parentX + w</code>, <code>parentY + h</code>,
* <code>childMinX + w</code>, or
* <code>childMinY + h</code> results in integer
* overflow
*/
public WritableRaster createWritableChild(int parentX, int parentY,
int w, int h,
int childMinX, int childMinY,
int bandList[]) {
if (parentX < this.minX) {
throw new RasterFormatException("parentX lies outside raster");
}
if (parentY < this.minY) {
throw new RasterFormatException("parentY lies outside raster");
}
if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
throw new RasterFormatException("(parentX + width) is outside raster");
}
if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
throw new RasterFormatException("(parentY + height) is outside raster");
}
SampleModel sm;
// Note: the SampleModel for the child Raster should have the same
// width and height as that for the parent, since it represents
// the physical layout of the pixel data. The child Raster's width
// and height represent a "virtual" view of the pixel data, so
// they may be different than those of the SampleModel.
if (bandList != null) {
sm = sampleModel.createSubsetSampleModel(bandList);
}
else {
sm = sampleModel;
}
int deltaX = childMinX - parentX;
int deltaY = childMinY - parentY;
return new WritableRaster(sm,
getDataBuffer(),
new Rectangle(childMinX,childMinY,
w, h),
new Point(sampleModelTranslateX+deltaX,
sampleModelTranslateY+deltaY),
this);
}
/**
* Sets the data for a single pixel from a
* primitive array of type TransferType. For image data supported by
* the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
* may be in a packed format, thus increasing efficiency for data
* transfers.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if inData is not large enough to hold the pixel data.
* However, explicit bounds checking is not guaranteed.
* A ClassCastException will be thrown if the input object is not null
* and references anything other than an array of TransferType.
* @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements()
* containing the pixel data to place at x,y.
*
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if inData is too small to hold the input.
*/
public void setDataElements(int x, int y, Object inData) {
sampleModel.setDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
inData, dataBuffer);
}
/**
* Sets the data for a rectangle of pixels from an input Raster.
* The input Raster must be compatible with this WritableRaster
* in that they must have the same number of bands, corresponding bands
* must have the same number of bits per sample, the TransferTypes
* and NumDataElements must be the same, and the packing used by
* the getDataElements/setDataElements must be identical.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inRaster Raster containing data to place at x,y.
*
* @throws NullPointerException if inRaster is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds.
*/
public void setDataElements(int x, int y, Raster inRaster) {
int dstOffX = x+inRaster.getMinX();
int dstOffY = y+inRaster.getMinY();
int width = inRaster.getWidth();
int height = inRaster.getHeight();
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
(dstOffX + width > this.minX + this.width) ||
(dstOffY + height > this.minY + this.height)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int srcOffX = inRaster.getMinX();
int srcOffY = inRaster.getMinY();
Object tdata = null;
for (int startY=0; startY < height; startY++) {
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
width, 1, tdata);
setDataElements(dstOffX, dstOffY+startY,
width, 1, tdata);
}
}
/**
* Sets the data for a rectangle of pixels from a
* primitive array of type TransferType. For image data supported by
* the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
* may be in a packed format, thus increasing efficiency for data
* transfers.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds, or if inData is not large enough to hold the pixel data.
* However, explicit bounds checking is not guaranteed.
* A ClassCastException will be thrown if the input object is not null
* and references anything other than an array of TransferType.
* @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements()
* containing the pixel data to place between x,y and
* x+w-1, y+h-1.
*
* @throws NullPointerException if inData is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if inData is too small to hold the input.
*/
public void setDataElements(int x, int y, int w, int h, Object inData) {
sampleModel.setDataElements(x-sampleModelTranslateX,
y-sampleModelTranslateY,
w,h,inData,dataBuffer);
}
/**
* Copies pixels from Raster srcRaster to this WritableRaster. Each pixel
* in srcRaster is copied to the same x,y address in this raster, unless
* the address falls outside the bounds of this raster. srcRaster
* must have the same number of bands as this WritableRaster. The
* copy is a simple copy of source samples to the corresponding destination
* samples.
* <p>
* If all samples of both source and destination Rasters are of
* integral type and less than or equal to 32 bits in size, then calling
* this method is equivalent to executing the following code for all
* <code>x,y</code> addresses valid in both Rasters.
* <pre>
* Raster srcRaster;
* WritableRaster dstRaster;
* for (int b = 0; b < srcRaster.getNumBands(); b++) {
* dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
* }
* </pre>
* Thus, when copying an integral type source to an integral type
* destination, if the source sample size is greater than the destination
* sample size for a particular band, the high order bits of the source
* sample are truncated. If the source sample size is less than the
* destination size for a particular band, the high order bits of the
* destination are zero-extended or sign-extended depending on whether
* srcRaster's SampleModel treats the sample as a signed or unsigned
* quantity.
* <p>
* When copying a float or double source to an integral type destination,
* each source sample is cast to the destination type. When copying an
* integral type source to a float or double destination, the source
* is first converted to a 32-bit int (if necessary), using the above
* rules for integral types, and then the int is cast to float or
* double.
* <p>
* @param srcRaster The Raster from which to copy pixels.
*
* @throws NullPointerException if srcRaster is null.
*/
public void setRect(Raster srcRaster) {
setRect(0,0,srcRaster);
}
/**
* Copies pixels from Raster srcRaster to this WritableRaster.
* For each (x, y) address in srcRaster, the corresponding pixel
* is copied to address (x+dx, y+dy) in this WritableRaster,
* unless (x+dx, y+dy) falls outside the bounds of this raster.
* srcRaster must have the same number of bands as this WritableRaster.
* The copy is a simple copy of source samples to the corresponding
* destination samples. For details, see
* {@link WritableRaster#setRect(Raster)}.
*
* @param dx The X translation factor from src space to dst space
* of the copy.
* @param dy The Y translation factor from src space to dst space
* of the copy.
* @param srcRaster The Raster from which to copy pixels.
*
* @throws NullPointerException if srcRaster is null.
*/
public void setRect(int dx, int dy, Raster srcRaster) {
int width = srcRaster.getWidth();
int height = srcRaster.getHeight();
int srcOffX = srcRaster.getMinX();
int srcOffY = srcRaster.getMinY();
int dstOffX = dx+srcOffX;
int dstOffY = dy+srcOffY;
// Clip to this raster
if (dstOffX < this.minX) {
int skipX = this.minX - dstOffX;
width -= skipX;
srcOffX += skipX;
dstOffX = this.minX;
}
if (dstOffY < this.minY) {
int skipY = this.minY - dstOffY;
height -= skipY;
srcOffY += skipY;
dstOffY = this.minY;
}
if (dstOffX+width > this.minX+this.width) {
width = this.minX + this.width - dstOffX;
}
if (dstOffY+height > this.minY+this.height) {
height = this.minY + this.height - dstOffY;
}
if (width <= 0 || height <= 0) {
return;
}
switch (srcRaster.getSampleModel().getDataType()) {
case DataBuffer.TYPE_BYTE:
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_INT:
int[] iData = null;
for (int startY=0; startY < height; startY++) {
// Grab one scanline at a time
iData =
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
iData);
setPixels(dstOffX, dstOffY+startY, width, 1, iData);
}
break;
case DataBuffer.TYPE_FLOAT:
float[] fData = null;
for (int startY=0; startY < height; startY++) {
fData =
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
fData);
setPixels(dstOffX, dstOffY+startY, width, 1, fData);
}
break;
case DataBuffer.TYPE_DOUBLE:
double[] dData = null;
for (int startY=0; startY < height; startY++) {
// Grab one scanline at a time
dData =
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
dData);
setPixels(dstOffX, dstOffY+startY, width, 1, dData);
}
break;
}
}
/**
* Sets a pixel in the DataBuffer using an int array of samples for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param iArray The input samples in a int array.
*
* @throws NullPointerException if iArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if iArray is too small to hold the input.
*/
public void setPixel(int x, int y, int iArray[]) {
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
iArray,dataBuffer);
}
/**
* Sets a pixel in the DataBuffer using a float array of samples for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param fArray The input samples in a float array.
*
* @throws NullPointerException if fArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if fArray is too small to hold the input.
*/
public void setPixel(int x, int y, float fArray[]) {
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
fArray,dataBuffer);
}
/**
* Sets a pixel in the DataBuffer using a double array of samples for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param dArray The input samples in a double array.
*
* @throws NullPointerException if dArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if dArray is too small to hold the input.
*/
public void setPixel(int x, int y, double dArray[]) {
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
dArray,dataBuffer);
}
/**
* Sets all samples for a rectangle of pixels from an int array containing
* one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param iArray The input int pixel array.
*
* @throws NullPointerException if iArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if iArray is too small to hold the input.
*/
public void setPixels(int x, int y, int w, int h, int iArray[]) {
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,iArray,dataBuffer);
}
/**
* Sets all samples for a rectangle of pixels from a float array containing
* one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param fArray The input float pixel array.
*
* @throws NullPointerException if fArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if fArray is too small to hold the input.
*/
public void setPixels(int x, int y, int w, int h, float fArray[]) {
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,fArray,dataBuffer);
}
/**
* Sets all samples for a rectangle of pixels from a double array containing
* one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param dArray The input double pixel array.
*
* @throws NullPointerException if dArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
* in bounds, or if dArray is too small to hold the input.
*/
public void setPixels(int x, int y, int w, int h, double dArray[]) {
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,dArray,dataBuffer);
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using an int for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param b The band to set.
* @param s The input sample.
*
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds.
*/
public void setSample(int x, int y, int b, int s) {
sampleModel.setSample(x-sampleModelTranslateX,
y-sampleModelTranslateY, b, s,
dataBuffer);
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using a float for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param b The band to set.
* @param s The input sample as a float.
*
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds.
*/
public void setSample(int x, int y, int b, float s){
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
b,s,dataBuffer);
}
/**
* Sets a sample in the specified band for the pixel located at (x,y)
* in the DataBuffer using a double for input.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param b The band to set.
* @param s The input sample as a double.
*
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds.
*/
public void setSample(int x, int y, int b, double s){
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
b,s,dataBuffer);
}
/**
* Sets the samples in the specified band for the specified rectangle
* of pixels from an int array containing one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param b The band to set.
* @param iArray The input int sample array.
*
* @throws NullPointerException if iArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds, or if iArray is too small to
* hold the input.
*/
public void setSamples(int x, int y, int w, int h, int b,
int iArray[]) {
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,b,iArray,dataBuffer);
}
/**
* Sets the samples in the specified band for the specified rectangle
* of pixels from a float array containing one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param b The band to set.
* @param fArray The input float sample array.
*
* @throws NullPointerException if fArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds, or if fArray is too small to
* hold the input.
*/
public void setSamples(int x, int y, int w, int h, int b,
float fArray[]) {
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,b,fArray,dataBuffer);
}
/**
* Sets the samples in the specified band for the specified rectangle
* of pixels from a double array containing one sample per array element.
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
* not in bounds.
* However, explicit bounds checking is not guaranteed.
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param b The band to set.
* @param dArray The input double sample array.
*
* @throws NullPointerException if dArray is null.
* @throws ArrayIndexOutOfBoundsException if the coordinates or
* the band index are not in bounds, or if dArray is too small to
* hold the input.
*/
public void setSamples(int x, int y, int w, int h, int b,
double dArray[]) {
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
w,h,b,dArray,dataBuffer);
}
}

View File

@ -0,0 +1,151 @@
/*
* Portions Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ****************************************************************
******************************************************************
******************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997
*** As an unpublished work pursuant to Title 17 of the United
*** States Code. All rights reserved.
******************************************************************
******************************************************************
******************************************************************/
package java.awt.image;
import java.awt.Point;
/**
* WriteableRenderedImage is a common interface for objects which
* contain or can produce image data in the form of Rasters and
* which can be modified and/or written over. The image
* data may be stored/produced as a single tile or a regular array
* of tiles.
* <p>
* WritableRenderedImage provides notification to other interested
* objects when a tile is checked out for writing (via the
* getWritableTile method) and when the last writer of a particular
* tile relinquishes its access (via a call to releaseWritableTile).
* Additionally, it allows any caller to determine whether any tiles
* are currently checked out (via hasTileWriters), and to obtain a
* list of such tiles (via getWritableTileIndices, in the form of a Vector
* of Point objects).
* <p>
* Objects wishing to be notified of changes in tile writability must
* implement the TileObserver interface, and are added by a
* call to addTileObserver. Multiple calls to
* addTileObserver for the same object will result in multiple
* notifications. An existing observer may reduce its notifications
* by calling removeTileObserver; if the observer had no
* notifications the operation is a no-op.
* <p>
* It is necessary for a WritableRenderedImage to ensure that
* notifications occur only when the first writer acquires a tile and
* the last writer releases it.
*
*/
public interface WritableRenderedImage extends RenderedImage
{
/**
* Adds an observer. If the observer is already present,
* it will receive multiple notifications.
* @param to the specified <code>TileObserver</code>
*/
public void addTileObserver(TileObserver to);
/**
* Removes an observer. If the observer was not registered,
* nothing happens. If the observer was registered for multiple
* notifications, it will now be registered for one fewer.
* @param to the specified <code>TileObserver</code>
*/
public void removeTileObserver(TileObserver to);
/**
* Checks out a tile for writing.
*
* The WritableRenderedImage is responsible for notifying all
* of its TileObservers when a tile goes from having
* no writers to having one writer.
*
* @param tileX the X index of the tile.
* @param tileY the Y index of the tile.
* @return a writable tile.
*/
public WritableRaster getWritableTile(int tileX, int tileY);
/**
* Relinquishes the right to write to a tile. If the caller
* continues to write to the tile, the results are undefined.
* Calls to this method should only appear in matching pairs
* with calls to getWritableTile; any other use will lead
* to undefined results.
*
* The WritableRenderedImage is responsible for notifying all of
* its TileObservers when a tile goes from having one writer
* to having no writers.
*
* @param tileX the X index of the tile.
* @param tileY the Y index of the tile.
*/
public void releaseWritableTile(int tileX, int tileY);
/**
* Returns whether a tile is currently checked out for writing.
*
* @param tileX the X index of the tile.
* @param tileY the Y index of the tile.
* @return <code>true</code> if specified tile is checked out
* for writing; <code>false</code> otherwise.
*/
public boolean isTileWritable(int tileX, int tileY);
/**
* Returns an array of Point objects indicating which tiles
* are checked out for writing. Returns null if none are
* checked out.
* @return an array containing the locations of tiles that are
* checked out for writing.
*/
public Point[] getWritableTileIndices();
/**
* Returns whether any tile is checked out for writing.
* Semantically equivalent to (getWritableTileIndices() != null).
* @return <code>true</code> if any tiles are checked out for
* writing; <code>false</code> otherwise.
*/
public boolean hasTileWriters();
/**
* Sets a rect of the image to the contents of the Raster r, which is
* assumed to be in the same coordinate space as the WritableRenderedImage.
* The operation is clipped to the bounds of the WritableRenderedImage.
* @param r the specified <code>Raster</code>
*/
public void setData(Raster r);
}

View File

@ -0,0 +1,143 @@
/*
* Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
/**
* ContextualRenderedImageFactory provides an interface for the
* functionality that may differ between instances of
* RenderableImageOp. Thus different operations on RenderableImages
* may be performed by a single class such as RenderedImageOp through
* the use of multiple instances of ContextualRenderedImageFactory.
* The name ContextualRenderedImageFactory is commonly shortened to
* "CRIF."
*
* <p> All operations that are to be used in a rendering-independent
* chain must implement ContextualRenderedImageFactory.
*
* <p> Classes that implement this interface must provide a
* constructor with no arguments.
*/
public interface ContextualRenderedImageFactory extends RenderedImageFactory {
/**
* Maps the operation's output RenderContext into a RenderContext
* for each of the operation's sources. This is useful for
* operations that can be expressed in whole or in part simply as
* alterations in the RenderContext, such as an affine mapping, or
* operations that wish to obtain lower quality renderings of
* their sources in order to save processing effort or
* transmission bandwith. Some operations, such as blur, can also
* use this mechanism to avoid obtaining sources of higher quality
* than necessary.
*
* @param i the index of the source image.
* @param renderContext the RenderContext being applied to the operation.
* @param paramBlock a ParameterBlock containing the operation's
* sources and parameters.
* @param image the RenderableImage being rendered.
* @return a <code>RenderContext</code> for
* the source at the specified index of the parameters
* Vector contained in the specified ParameterBlock.
*/
RenderContext mapRenderContext(int i,
RenderContext renderContext,
ParameterBlock paramBlock,
RenderableImage image);
/**
* Creates a rendering, given a RenderContext and a ParameterBlock
* containing the operation's sources and parameters. The output
* is a RenderedImage that takes the RenderContext into account to
* determine its dimensions and placement on the image plane.
* This method houses the "intelligence" that allows a
* rendering-independent operation to adapt to a specific
* RenderContext.
*
* @param renderContext The RenderContext specifying the rendering
* @param paramBlock a ParameterBlock containing the operation's
* sources and parameters
* @return a <code>RenderedImage</code> from the sources and parameters
* in the specified ParameterBlock and according to the
* rendering instructions in the specified RenderContext.
*/
RenderedImage create(RenderContext renderContext,
ParameterBlock paramBlock);
/**
* Returns the bounding box for the output of the operation,
* performed on a given set of sources, in rendering-independent
* space. The bounds are returned as a Rectangle2D, that is, an
* axis-aligned rectangle with floating-point corner coordinates.
*
* @param paramBlock a ParameterBlock containing the operation's
* sources and parameters.
* @return a Rectangle2D specifying the rendering-independent
* bounding box of the output.
*/
Rectangle2D getBounds2D(ParameterBlock paramBlock);
/**
* Gets the appropriate instance of the property specified by the name
* parameter. This method must determine which instance of a property to
* return when there are multiple sources that each specify the property.
*
* @param paramBlock a ParameterBlock containing the operation's
* sources and parameters.
* @param name a String naming the desired property.
* @return an object reference to the value of the property requested.
*/
Object getProperty(ParameterBlock paramBlock, String name);
/**
* Returns a list of names recognized by getProperty.
* @return the list of property names.
*/
String[] getPropertyNames();
/**
* Returns true if successive renderings (that is, calls to
* create(RenderContext, ParameterBlock)) with the same arguments
* may produce different results. This method may be used to
* determine whether an existing rendering may be cached and
* reused. It is always safe to return true.
* @return <code>true</code> if successive renderings with the
* same arguments might produce different results;
* <code>false</code> otherwise.
*/
boolean isDynamic();
}

View File

@ -0,0 +1,272 @@
/*
* Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.util.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.image.*;
/**
* A RenderContext encapsulates the information needed to produce a
* specific rendering from a RenderableImage. It contains the area to
* be rendered specified in rendering-independent terms, the
* resolution at which the rendering is to be performed, and hints
* used to control the rendering process.
*
* <p> Users create RenderContexts and pass them to the
* RenderableImage via the createRendering method. Most of the methods of
* RenderContexts are not meant to be used directly by applications,
* but by the RenderableImage and operator classes to which it is
* passed.
*
* <p> The AffineTransform parameter passed into and out of this class
* are cloned. The RenderingHints and Shape parameters are not
* necessarily cloneable and are therefore only reference copied.
* Altering RenderingHints or Shape instances that are in use by
* instances of RenderContext may have undesired side effects.
*/
public class RenderContext implements Cloneable {
/** Table of hints. May be null. */
RenderingHints hints;
/** Transform to convert user coordinates to device coordinates. */
AffineTransform usr2dev;
/** The area of interest. May be null. */
Shape aoi;
// Various constructors that allow different levels of
// specificity. If the Shape is missing the whole renderable area
// is assumed. If hints is missing no hints are assumed.
/**
* Constructs a RenderContext with a given transform.
* The area of interest is supplied as a Shape,
* and the rendering hints are supplied as a RenderingHints object.
*
* @param usr2dev an AffineTransform.
* @param aoi a Shape representing the area of interest.
* @param hints a RenderingHints object containing rendering hints.
*/
public RenderContext(AffineTransform usr2dev,
Shape aoi,
RenderingHints hints) {
this.hints = hints;
this.aoi = aoi;
this.usr2dev = (AffineTransform)usr2dev.clone();
}
/**
* Constructs a RenderContext with a given transform.
* The area of interest is taken to be the entire renderable area.
* No rendering hints are used.
*
* @param usr2dev an AffineTransform.
*/
public RenderContext(AffineTransform usr2dev) {
this(usr2dev, null, null);
}
/**
* Constructs a RenderContext with a given transform and rendering hints.
* The area of interest is taken to be the entire renderable area.
*
* @param usr2dev an AffineTransform.
* @param hints a RenderingHints object containing rendering hints.
*/
public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
this(usr2dev, null, hints);
}
/**
* Constructs a RenderContext with a given transform and area of interest.
* The area of interest is supplied as a Shape.
* No rendering hints are used.
*
* @param usr2dev an AffineTransform.
* @param aoi a Shape representing the area of interest.
*/
public RenderContext(AffineTransform usr2dev, Shape aoi) {
this(usr2dev, aoi, null);
}
/**
* Gets the rendering hints of this <code>RenderContext</code>.
* @return a <code>RenderingHints</code> object that represents
* the rendering hints of this <code>RenderContext</code>.
* @see #setRenderingHints(RenderingHints)
*/
public RenderingHints getRenderingHints() {
return hints;
}
/**
* Sets the rendering hints of this <code>RenderContext</code>.
* @param hints a <code>RenderingHints</code> object that represents
* the rendering hints to assign to this <code>RenderContext</code>.
* @see #getRenderingHints
*/
public void setRenderingHints(RenderingHints hints) {
this.hints = hints;
}
/**
* Sets the current user-to-device AffineTransform contained
* in the RenderContext to a given transform.
*
* @param newTransform the new AffineTransform.
* @see #getTransform
*/
public void setTransform(AffineTransform newTransform) {
usr2dev = (AffineTransform)newTransform.clone();
}
/**
* Modifies the current user-to-device transform by prepending another
* transform. In matrix notation the operation is:
* <pre>
* [this] = [modTransform] x [this]
* </pre>
*
* @param modTransform the AffineTransform to prepend to the
* current usr2dev transform.
* @since 1.3
*/
public void preConcatenateTransform(AffineTransform modTransform) {
this.preConcetenateTransform(modTransform);
}
/**
* Modifies the current user-to-device transform by prepending another
* transform. In matrix notation the operation is:
* <pre>
* [this] = [modTransform] x [this]
* </pre>
* This method does the same thing as the preConcatenateTransform
* method. It is here for backward compatibility with previous releases
* which misspelled the method name.
*
* @param modTransform the AffineTransform to prepend to the
* current usr2dev transform.
* @deprecated replaced by
* <code>preConcatenateTransform(AffineTransform)</code>.
*/
@Deprecated
public void preConcetenateTransform(AffineTransform modTransform) {
usr2dev.preConcatenate(modTransform);
}
/**
* Modifies the current user-to-device transform by appending another
* transform. In matrix notation the operation is:
* <pre>
* [this] = [this] x [modTransform]
* </pre>
*
* @param modTransform the AffineTransform to append to the
* current usr2dev transform.
* @since 1.3
*/
public void concatenateTransform(AffineTransform modTransform) {
this.concetenateTransform(modTransform);
}
/**
* Modifies the current user-to-device transform by appending another
* transform. In matrix notation the operation is:
* <pre>
* [this] = [this] x [modTransform]
* </pre>
* This method does the same thing as the concatenateTransform
* method. It is here for backward compatibility with previous releases
* which misspelled the method name.
*
* @param modTransform the AffineTransform to append to the
* current usr2dev transform.
* @deprecated replaced by
* <code>concatenateTransform(AffineTransform)</code>.
*/
@Deprecated
public void concetenateTransform(AffineTransform modTransform) {
usr2dev.concatenate(modTransform);
}
/**
* Gets the current user-to-device AffineTransform.
*
* @return a reference to the current AffineTransform.
* @see #setTransform(AffineTransform)
*/
public AffineTransform getTransform() {
return (AffineTransform)usr2dev.clone();
}
/**
* Sets the current area of interest. The old area is discarded.
*
* @param newAoi The new area of interest.
* @see #getAreaOfInterest
*/
public void setAreaOfInterest(Shape newAoi) {
aoi = newAoi;
}
/**
* Gets the ares of interest currently contained in the
* RenderContext.
*
* @return a reference to the area of interest of the RenderContext,
* or null if none is specified.
* @see #setAreaOfInterest(Shape)
*/
public Shape getAreaOfInterest() {
return aoi;
}
/**
* Makes a copy of a RenderContext. The area of interest is copied
* by reference. The usr2dev AffineTransform and hints are cloned,
* while the area of interest is copied by reference.
*
* @return the new cloned RenderContext.
*/
public Object clone() {
RenderContext newRenderContext = new RenderContext(usr2dev,
aoi, hints);
return newRenderContext;
}
}

View File

@ -0,0 +1,198 @@
/*
* Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.util.Vector;
import java.awt.RenderingHints;
import java.awt.image.*;
/**
* A RenderableImage is a common interface for rendering-independent
* images (a notion which subsumes resolution independence). That is,
* images which are described and have operations applied to them
* independent of any specific rendering of the image. For example, a
* RenderableImage can be rotated and cropped in
* resolution-independent terms. Then, it can be rendered for various
* specific contexts, such as a draft preview, a high-quality screen
* display, or a printer, each in an optimal fashion.
*
* <p> A RenderedImage is returned from a RenderableImage via the
* createRendering() method, which takes a RenderContext. The
* RenderContext specifies how the RenderedImage should be
* constructed. Note that it is not possible to extract pixels
* directly from a RenderableImage.
*
* <p> The createDefaultRendering() and createScaledRendering() methods are
* convenience methods that construct an appropriate RenderContext
* internally. All of the rendering methods may return a reference to a
* previously produced rendering.
*/
public interface RenderableImage {
/**
* String constant that can be used to identify a property on
* a RenderedImage obtained via the createRendering or
* createScaledRendering methods. If such a property exists,
* the value of the propoery will be a RenderingHints object
* specifying which hints were observed in creating the rendering.
*/
static final String HINTS_OBSERVED = "HINTS_OBSERVED";
/**
* Returns a vector of RenderableImages that are the sources of
* image data for this RenderableImage. Note that this method may
* return an empty vector, to indicate that the image has no sources,
* or null, to indicate that no information is available.
*
* @return a (possibly empty) Vector of RenderableImages, or null.
*/
Vector<RenderableImage> getSources();
/**
* Gets a property from the property set of this image.
* If the property name is not recognized, java.awt.Image.UndefinedProperty
* will be returned.
*
* @param name the name of the property to get, as a String.
* @return a reference to the property Object, or the value
* java.awt.Image.UndefinedProperty.
*/
Object getProperty(String name);
/**
* Returns a list of names recognized by getProperty.
* @return a list of property names.
*/
String[] getPropertyNames();
/**
* Returns true if successive renderings (that is, calls to
* createRendering() or createScaledRendering()) with the same arguments
* may produce different results. This method may be used to
* determine whether an existing rendering may be cached and
* reused. It is always safe to return true.
* @return <code>true</code> if successive renderings with the
* same arguments might produce different results;
* <code>false</code> otherwise.
*/
boolean isDynamic();
/**
* Gets the width in user coordinate space. By convention, the
* usual width of a RenderableImage is equal to the image's aspect
* ratio (width divided by height).
*
* @return the width of the image in user coordinates.
*/
float getWidth();
/**
* Gets the height in user coordinate space. By convention, the
* usual height of a RenderedImage is equal to 1.0F.
*
* @return the height of the image in user coordinates.
*/
float getHeight();
/**
* Gets the minimum X coordinate of the rendering-independent image data.
* @return the minimum X coordinate of the rendering-independent image
* data.
*/
float getMinX();
/**
* Gets the minimum Y coordinate of the rendering-independent image data.
* @return the minimum Y coordinate of the rendering-independent image
* data.
*/
float getMinY();
/**
* Creates a RenderedImage instance of this image with width w, and
* height h in pixels. The RenderContext is built automatically
* with an appropriate usr2dev transform and an area of interest
* of the full image. All the rendering hints come from hints
* passed in.
*
* <p> If w == 0, it will be taken to equal
* Math.round(h*(getWidth()/getHeight())).
* Similarly, if h == 0, it will be taken to equal
* Math.round(w*(getHeight()/getWidth())). One of
* w or h must be non-zero or else an IllegalArgumentException
* will be thrown.
*
* <p> The created RenderedImage may have a property identified
* by the String HINTS_OBSERVED to indicate which RenderingHints
* were used to create the image. In addition any RenderedImages
* that are obtained via the getSources() method on the created
* RenderedImage may have such a property.
*
* @param w the width of rendered image in pixels, or 0.
* @param h the height of rendered image in pixels, or 0.
* @param hints a RenderingHints object containg hints.
* @return a RenderedImage containing the rendered data.
*/
RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
/**
* Returnd a RenderedImage instance of this image with a default
* width and height in pixels. The RenderContext is built
* automatically with an appropriate usr2dev transform and an area
* of interest of the full image. The rendering hints are
* empty. createDefaultRendering may make use of a stored
* rendering for speed.
*
* @return a RenderedImage containing the rendered data.
*/
RenderedImage createDefaultRendering();
/**
* Creates a RenderedImage that represented a rendering of this image
* using a given RenderContext. This is the most general way to obtain a
* rendering of a RenderableImage.
*
* <p> The created RenderedImage may have a property identified
* by the String HINTS_OBSERVED to indicate which RenderingHints
* (from the RenderContext) were used to create the image.
* In addition any RenderedImages
* that are obtained via the getSources() method on the created
* RenderedImage may have such a property.
*
* @param renderContext the RenderContext to use to produce the rendering.
* @return a RenderedImage containing the rendered data.
*/
RenderedImage createRendering(RenderContext renderContext);
}

View File

@ -0,0 +1,350 @@
/*
* Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.awt.RenderingHints;
import java.util.Hashtable;
import java.util.Vector;
/**
* This class handles the renderable aspects of an operation with help
* from its associated instance of a ContextualRenderedImageFactory.
*/
public class RenderableImageOp implements RenderableImage {
/** A ParameterBlock containing source and parameters. */
ParameterBlock paramBlock;
/** The associated ContextualRenderedImageFactory. */
ContextualRenderedImageFactory myCRIF;
/** The bounding box of the results of this RenderableImageOp. */
Rectangle2D boundingBox;
/**
* Constructs a RenderedImageOp given a
* ContextualRenderedImageFactory object, and
* a ParameterBlock containing RenderableImage sources and other
* parameters. Any RenderedImage sources referenced by the
* ParameterBlock will be ignored.
*
* @param CRIF a ContextualRenderedImageFactory object
* @param paramBlock a ParameterBlock containing this operation's source
* images and other parameters necessary for the operation
* to run.
*/
public RenderableImageOp(ContextualRenderedImageFactory CRIF,
ParameterBlock paramBlock) {
this.myCRIF = CRIF;
this.paramBlock = (ParameterBlock) paramBlock.clone();
}
/**
* Returns a vector of RenderableImages that are the sources of
* image data for this RenderableImage. Note that this method may
* return an empty vector, to indicate that the image has no sources,
* or null, to indicate that no information is available.
*
* @return a (possibly empty) Vector of RenderableImages, or null.
*/
public Vector<RenderableImage> getSources() {
return getRenderableSources();
}
private Vector getRenderableSources() {
Vector sources = null;
if (paramBlock.getNumSources() > 0) {
sources = new Vector();
int i = 0;
while (i < paramBlock.getNumSources()) {
Object o = paramBlock.getSource(i);
if (o instanceof RenderableImage) {
sources.add((RenderableImage)o);
i++;
} else {
break;
}
}
}
return sources;
}
/**
* Gets a property from the property set of this image.
* If the property name is not recognized, java.awt.Image.UndefinedProperty
* will be returned.
*
* @param name the name of the property to get, as a String.
* @return a reference to the property Object, or the value
* java.awt.Image.UndefinedProperty.
*/
public Object getProperty(String name) {
return myCRIF.getProperty(paramBlock, name);
}
/**
* Return a list of names recognized by getProperty.
* @return a list of property names.
*/
public String[] getPropertyNames() {
return myCRIF.getPropertyNames();
}
/**
* Returns true if successive renderings (that is, calls to
* createRendering() or createScaledRendering()) with the same arguments
* may produce different results. This method may be used to
* determine whether an existing rendering may be cached and
* reused. The CRIF's isDynamic method will be called.
* @return <code>true</code> if successive renderings with the
* same arguments might produce different results;
* <code>false</code> otherwise.
*/
public boolean isDynamic() {
return myCRIF.isDynamic();
}
/**
* Gets the width in user coordinate space. By convention, the
* usual width of a RenderableImage is equal to the image's aspect
* ratio (width divided by height).
*
* @return the width of the image in user coordinates.
*/
public float getWidth() {
if (boundingBox == null) {
boundingBox = myCRIF.getBounds2D(paramBlock);
}
return (float)boundingBox.getWidth();
}
/**
* Gets the height in user coordinate space. By convention, the
* usual height of a RenderedImage is equal to 1.0F.
*
* @return the height of the image in user coordinates.
*/
public float getHeight() {
if (boundingBox == null) {
boundingBox = myCRIF.getBounds2D(paramBlock);
}
return (float)boundingBox.getHeight();
}
/**
* Gets the minimum X coordinate of the rendering-independent image data.
*/
public float getMinX() {
if (boundingBox == null) {
boundingBox = myCRIF.getBounds2D(paramBlock);
}
return (float)boundingBox.getMinX();
}
/**
* Gets the minimum Y coordinate of the rendering-independent image data.
*/
public float getMinY() {
if (boundingBox == null) {
boundingBox = myCRIF.getBounds2D(paramBlock);
}
return (float)boundingBox.getMinY();
}
/**
* Change the current ParameterBlock of the operation, allowing
* editing of image rendering chains. The effects of such a
* change will be visible when a new rendering is created from
* this RenderableImageOp or any dependent RenderableImageOp.
*
* @param paramBlock the new ParameterBlock.
* @return the old ParameterBlock.
* @see #getParameterBlock
*/
public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
ParameterBlock oldParamBlock = this.paramBlock;
this.paramBlock = (ParameterBlock)paramBlock.clone();
return oldParamBlock;
}
/**
* Returns a reference to the current parameter block.
* @return the <code>ParameterBlock</code> of this
* <code>RenderableImageOp</code>.
* @see #setParameterBlock(ParameterBlock)
*/
public ParameterBlock getParameterBlock() {
return paramBlock;
}
/**
* Creates a RenderedImage instance of this image with width w, and
* height h in pixels. The RenderContext is built automatically
* with an appropriate usr2dev transform and an area of interest
* of the full image. All the rendering hints come from hints
* passed in.
*
* <p> If w == 0, it will be taken to equal
* Math.round(h*(getWidth()/getHeight())).
* Similarly, if h == 0, it will be taken to equal
* Math.round(w*(getHeight()/getWidth())). One of
* w or h must be non-zero or else an IllegalArgumentException
* will be thrown.
*
* <p> The created RenderedImage may have a property identified
* by the String HINTS_OBSERVED to indicate which RenderingHints
* were used to create the image. In addition any RenderedImages
* that are obtained via the getSources() method on the created
* RenderedImage may have such a property.
*
* @param w the width of rendered image in pixels, or 0.
* @param h the height of rendered image in pixels, or 0.
* @param hints a RenderingHints object containg hints.
* @return a RenderedImage containing the rendered data.
*/
public RenderedImage createScaledRendering(int w, int h,
RenderingHints hints) {
// DSR -- code to try to get a unit scale
double sx = (double)w/getWidth();
double sy = (double)h/getHeight();
if (Math.abs(sx/sy - 1.0) < 0.01) {
sx = sy;
}
AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
RenderContext newRC = new RenderContext(usr2dev, hints);
return createRendering(newRC);
}
/**
* Gets a RenderedImage instance of this image with a default
* width and height in pixels. The RenderContext is built
* automatically with an appropriate usr2dev transform and an area
* of interest of the full image. All the rendering hints come
* from hints passed in. Implementors of this interface must be
* sure that there is a defined default width and height.
*
* @return a RenderedImage containing the rendered data.
*/
public RenderedImage createDefaultRendering() {
AffineTransform usr2dev = new AffineTransform(); // Identity
RenderContext newRC = new RenderContext(usr2dev);
return createRendering(newRC);
}
/**
* Creates a RenderedImage which represents this
* RenderableImageOp (including its Renderable sources) rendered
* according to the given RenderContext.
*
* <p> This method supports chaining of either Renderable or
* RenderedImage operations. If sources in
* the ParameterBlock used to construct the RenderableImageOp are
* RenderableImages, then a three step process is followed:
*
* <ol>
* <li> mapRenderContext() is called on the associated CRIF for
* each RenderableImage source;
* <li> createRendering() is called on each of the RenderableImage sources
* using the backwards-mapped RenderContexts obtained in step 1,
* resulting in a rendering of each source;
* <li> ContextualRenderedImageFactory.create() is called
* with a new ParameterBlock containing the parameters of
* the RenderableImageOp and the RenderedImages that were created by the
* createRendering() calls.
* </ol>
*
* <p> If the elements of the source Vector of
* the ParameterBlock used to construct the RenderableImageOp are
* instances of RenderedImage, then the CRIF.create() method is
* called immediately using the original ParameterBlock.
* This provides a basis case for the recursion.
*
* <p> The created RenderedImage may have a property identified
* by the String HINTS_OBSERVED to indicate which RenderingHints
* (from the RenderContext) were used to create the image.
* In addition any RenderedImages
* that are obtained via the getSources() method on the created
* RenderedImage may have such a property.
*
* @param renderContext The RenderContext to use to perform the rendering.
* @return a RenderedImage containing the desired output image.
*/
public RenderedImage createRendering(RenderContext renderContext) {
RenderedImage image = null;
RenderContext rcOut = null;
// Clone the original ParameterBlock; if the ParameterBlock
// contains RenderableImage sources, they will be replaced by
// RenderedImages.
ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
Vector sources = getRenderableSources();
try {
// This assumes that if there is no renderable source, that there
// is a rendered source in paramBlock
if (sources != null) {
Vector renderedSources = new Vector();
for (int i = 0; i < sources.size(); i++) {
rcOut = myCRIF.mapRenderContext(i, renderContext,
paramBlock, this);
RenderedImage rdrdImage =
((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
if (rdrdImage == null) {
return null;
}
// Add this rendered image to the ParameterBlock's
// list of RenderedImages.
renderedSources.addElement(rdrdImage);
}
if (renderedSources.size() > 0) {
renderedParamBlock.setSources(renderedSources);
}
}
return myCRIF.create(renderContext, renderedParamBlock);
} catch (ArrayIndexOutOfBoundsException e) {
// This should never happen
return null;
}
}
}

View File

@ -0,0 +1,219 @@
/*
* Portions Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageProducer;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.util.Enumeration;
import java.util.Vector;
/**
* An adapter class that implements ImageProducer to allow the
* asynchronous production of a RenderableImage. The size of the
* ImageConsumer is determined by the scale factor of the usr2dev
* transform in the RenderContext. If the RenderContext is null, the
* default rendering of the RenderableImage is used. This class
* implements an asynchronous production that produces the image in
* one thread at one resolution. This class may be subclassed to
* implement versions that will render the image using several
* threads. These threads could render either the same image at
* progressively better quality, or different sections of the image at
* a single resolution.
*/
public class RenderableImageProducer implements ImageProducer, Runnable {
/** The RenderableImage source for the producer. */
RenderableImage rdblImage;
/** The RenderContext to use for producing the image. */
RenderContext rc;
/** A Vector of image consumers. */
Vector ics = new Vector();
/**
* Constructs a new RenderableImageProducer from a RenderableImage
* and a RenderContext.
*
* @param rdblImage the RenderableImage to be rendered.
* @param rc the RenderContext to use for producing the pixels.
*/
public RenderableImageProducer(RenderableImage rdblImage,
RenderContext rc) {
this.rdblImage = rdblImage;
this.rc = rc;
}
/**
* Sets a new RenderContext to use for the next startProduction() call.
*
* @param rc the new RenderContext.
*/
public synchronized void setRenderContext(RenderContext rc) {
this.rc = rc;
}
/**
* Adds an ImageConsumer to the list of consumers interested in
* data for this image.
*
* @param ic an ImageConsumer to be added to the interest list.
*/
public synchronized void addConsumer(ImageConsumer ic) {
if (!ics.contains(ic)) {
ics.addElement(ic);
}
}
/**
* Determine if an ImageConsumer is on the list of consumers
* currently interested in data for this image.
*
* @param ic the ImageConsumer to be checked.
* @return true if the ImageConsumer is on the list; false otherwise.
*/
public synchronized boolean isConsumer(ImageConsumer ic) {
return ics.contains(ic);
}
/**
* Remove an ImageConsumer from the list of consumers interested in
* data for this image.
*
* @param ic the ImageConsumer to be removed.
*/
public synchronized void removeConsumer(ImageConsumer ic) {
ics.removeElement(ic);
}
/**
* Adds an ImageConsumer to the list of consumers interested in
* data for this image, and immediately starts delivery of the
* image data through the ImageConsumer interface.
*
* @param ic the ImageConsumer to be added to the list of consumers.
*/
public synchronized void startProduction(ImageConsumer ic) {
addConsumer(ic);
// Need to build a runnable object for the Thread.
Thread thread = new Thread(this, "RenderableImageProducer Thread");
thread.start();
}
/**
* Requests that a given ImageConsumer have the image data delivered
* one more time in top-down, left-right order.
*
* @param ic the ImageConsumer requesting the resend.
*/
public void requestTopDownLeftRightResend(ImageConsumer ic) {
// So far, all pixels are already sent in TDLR order
}
/**
* The runnable method for this class. This will produce an image using
* the current RenderableImage and RenderContext and send it to all the
* ImageConsumer currently registered with this class.
*/
public void run() {
// First get the rendered image
RenderedImage rdrdImage;
if (rc != null) {
rdrdImage = rdblImage.createRendering(rc);
} else {
rdrdImage = rdblImage.createDefaultRendering();
}
// And its ColorModel
ColorModel colorModel = rdrdImage.getColorModel();
Raster raster = rdrdImage.getData();
SampleModel sampleModel = raster.getSampleModel();
DataBuffer dataBuffer = raster.getDataBuffer();
if (colorModel == null) {
colorModel = ColorModel.getRGBdefault();
}
int minX = raster.getMinX();
int minY = raster.getMinY();
int width = raster.getWidth();
int height = raster.getHeight();
Enumeration icList;
ImageConsumer ic;
// Set up the ImageConsumers
icList = ics.elements();
while (icList.hasMoreElements()) {
ic = (ImageConsumer)icList.nextElement();
ic.setDimensions(width,height);
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
ImageConsumer.COMPLETESCANLINES |
ImageConsumer.SINGLEPASS |
ImageConsumer.SINGLEFRAME);
}
// Get RGB pixels from the raster scanline by scanline and
// send to consumers.
int pix[] = new int[width];
int i,j;
int numBands = sampleModel.getNumBands();
int tmpPixel[] = new int[numBands];
for (j = 0; j < height; j++) {
for(i = 0; i < width; i++) {
sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
pix[i] = colorModel.getDataElement(tmpPixel, 0);
}
// Now send the scanline to the Consumers
icList = ics.elements();
while (icList.hasMoreElements()) {
ic = (ImageConsumer)icList.nextElement();
ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
}
}
// Now tell the consumers we're done.
icList = ics.elements();
while (icList.hasMoreElements()) {
ic = (ImageConsumer)icList.nextElement();
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
}
}
}

View File

@ -0,0 +1,78 @@
/*
* Portions Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* ********************************************************************
**********************************************************************
**********************************************************************
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
*** As an unpublished work pursuant to Title 17 of the United ***
*** States Code. All rights reserved. ***
**********************************************************************
**********************************************************************
**********************************************************************/
package java.awt.image.renderable;
import java.awt.image.RenderedImage;
import java.awt.RenderingHints;
/**
* The RenderedImageFactory interface (often abbreviated RIF) is
* intended to be implemented by classes that wish to act as factories
* to produce different renderings, for example by executing a series
* of BufferedImageOps on a set of sources, depending on a specific
* set of parameters, properties, and rendering hints.
*/
public interface RenderedImageFactory {
/**
* Creates a RenderedImage representing the results of an imaging
* operation (or chain of operations) for a given ParameterBlock and
* RenderingHints. The RIF may also query any source images
* referenced by the ParameterBlock for their dimensions,
* SampleModels, properties, etc., as necessary.
*
* <p> The create() method can return null if the
* RenderedImageFactory is not capable of producing output for the
* given set of source images and parameters. For example, if a
* RenderedImageFactory is only capable of performing a 3x3
* convolution on single-banded image data, and the source image has
* multiple bands or the convolution Kernel is 5x5, null should be
* returned.
*
* <p> Hints should be taken into account, but can be ignored.
* The created RenderedImage may have a property identified
* by the String HINTS_OBSERVED to indicate which RenderingHints
* were used to create the image. In addition any RenderedImages
* that are obtained via the getSources() method on the created
* RenderedImage may have such a property.
*
* @param paramBlock a ParameterBlock containing sources and parameters
* for the RenderedImage to be created.
* @param hints a RenderingHints object containing hints.
* @return A RenderedImage containing the desired output.
*/
RenderedImage create(ParameterBlock paramBlock,
RenderingHints hints);
}

View File

@ -83,7 +83,7 @@ class NumericValueExp extends QueryEval implements ValueExp {
* <p>The <b>serialVersionUID</b> of this class is <code>-4679739485102359104L</code>.
*/
private static final ObjectStreamField[] serialPersistentFields;
private Number val = new Double(0);
private Number val = 0.0;
private static boolean compat = false;
static {
@ -213,11 +213,11 @@ class NumericValueExp extends QueryEval implements ValueExp {
}
if (isLong)
{
this.val = new Long(longVal);
this.val = longVal;
}
else
{
this.val = new Double(doubleVal);
this.val = doubleVal;
}
}
else

View File

@ -449,7 +449,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
// parses domain part
domain_parsing:
while (index < len) {
switch (c = name_chars[index]) {
switch (name_chars[index]) {
case ':' :
_domain_length = index++;
break domain_parsing;
@ -619,7 +619,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
case '\n' :
final String ichar = ((c1=='\n')?"\\n":""+c1);
throw new MalformedObjectNameException(
"Invalid character '" + c1 +
"Invalid character '" + ichar +
"' in value part of property");
default :
in_index++;

View File

@ -750,7 +750,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* @return the Descriptor for the new MBeanInfo.
*/
Descriptor getDescriptor(MBeanInfo info, boolean immutableInfo) {
ImmutableDescriptor desc = null;
ImmutableDescriptor desc;
if (info == null ||
info.getDescriptor() == null ||
info.getDescriptor().getFieldNames().length == 0) {

View File

@ -591,8 +591,8 @@ public class MLet extends java.net.URLClassLoader
// Instantiate the class specified in the
// CODE or OBJECT section of the MLet tag
//
Object o = null;
ObjectInstance objInst = null;
Object o;
ObjectInstance objInst;
if (code != null && serName != null) {
final String msg =
@ -1131,11 +1131,17 @@ public class MLet extends java.net.URLClassLoader
return null;
} finally {
// Cleanup ...
if (tmpFile!=null) try {
tmpFile.delete();
} catch (Exception x) {
MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
"getTmpDir", "Failed to delete temporary file", x);
if (tmpFile!=null) {
try {
boolean deleted = tmpFile.delete();
if (!deleted) {
MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
"getTmpDir", "Failed to delete temp file");
}
} catch (Exception x) {
MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
"getTmpDir", "Failed to delete temporary file", x);
}
}
}
}
@ -1178,25 +1184,8 @@ public class MLet extends java.net.URLClassLoader
* Removes any white space from a string. This is used to
* convert strings such as "Windows NT" to "WindowsNT".
*/
private String removeSpace(String s) {
s = s.trim();
int j = s.indexOf(' ');
if (j == -1) {
return s;
}
String temp = "";
int k = 0;
while (j != -1) {
s = s.substring(k);
j = s.indexOf(' ');
if (j != -1) {
temp = temp + s.substring(0, j);
} else {
temp = temp + s.substring(0);
}
k = j + 1;
}
return temp;
private static String removeSpace(String s) {
return s.trim().replace(" ", "");
}
/**

View File

@ -240,14 +240,12 @@ class MLetParser {
MLET_LOGGER.logp(Level.FINER,
MLetParser.class.getName(),
mth, requiresCodeWarning);
atts = null;
throw new IOException(requiresCodeWarning);
}
if (atts.get("archive") == null) {
MLET_LOGGER.logp(Level.FINER,
MLetParser.class.getName(),
mth, requiresJarsWarning);
atts = null;
throw new IOException(requiresJarsWarning);
}
}
@ -265,7 +263,7 @@ class MLetParser {
public List<MLetContent> parseURL(String urlname) throws IOException {
// Parse the document
//
URL url = null;
URL url;
if (urlname.indexOf(':') <= 1) {
String userDir = System.getProperty("user.dir");
String prot;

View File

@ -591,8 +591,6 @@ public class DescriptorSupport
Set returnedSet = descriptorMap.entrySet();
int i = 0;
Object currValue = null;
Map.Entry currElement = null;
if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
MODELMBEAN_LOGGER.logp(Level.FINEST,
@ -600,7 +598,7 @@ public class DescriptorSupport
"getFields()", "Returning " + numberOfEntries + " fields");
}
for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) {
currElement = (Map.Entry) iter.next();
Map.Entry currElement = (Map.Entry) iter.next();
if (currElement == null) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINEST)) {
@ -609,7 +607,7 @@ public class DescriptorSupport
"getFields()", "Element is null");
}
} else {
currValue = currElement.getValue();
Object currValue = currElement.getValue();
if (currValue == null) {
responseFields[i] = currElement.getKey() + "=";
} else {
@ -1127,7 +1125,7 @@ public class DescriptorSupport
final char c = entities[i].charAt(0);
final String entity = entities[i].substring(1);
charToEntityMap[c] = entity;
entityToCharMap.put(entity, new Character(c));
entityToCharMap.put(entity, c);
}
}
@ -1325,13 +1323,11 @@ public class DescriptorSupport
// utility to convert to int, returns -2 if bogus.
private long toNumeric(String inStr) {
long result = -2;
try {
result = java.lang.Long.parseLong(inStr);
return java.lang.Long.parseLong(inStr);
} catch (Exception e) {
return -2;
}
return result;
}

View File

@ -432,7 +432,7 @@ public class ModelMBeanAttributeInfo
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone = null;
Descriptor clone;
if (in == null) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");

View File

@ -393,7 +393,7 @@ public class ModelMBeanConstructorInfo
* @exception RuntimeOperationsException if Descriptor is invalid
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone = null;
Descriptor clone;
if (in == null) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");

View File

@ -944,7 +944,7 @@ public class ModelMBeanInfoSupport extends MBeanInfo implements ModelMBeanInfo {
* @exception RuntimeOperationsException if Descriptor is invalid
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone = null;
Descriptor clone;
if (in == null) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");

View File

@ -328,7 +328,7 @@ public class ModelMBeanNotificationInfo
* @exception RuntimeOperationsException if Descriptor is invalid
*/
private Descriptor validDescriptor(final Descriptor in) throws RuntimeOperationsException {
Descriptor clone = null;
Descriptor clone;
if (in == null) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");

View File

@ -424,7 +424,7 @@ public class ModelMBeanOperationInfo extends MBeanOperationInfo
*/
private Descriptor validDescriptor(final Descriptor in)
throws RuntimeOperationsException {
Descriptor clone = null;
Descriptor clone;
if (in == null) {
clone = new DescriptorSupport();
MODELMBEAN_LOGGER.finer("Null Descriptor, creating new.");

View File

@ -1425,9 +1425,7 @@ public class RequiredModelMBean
}
/* Check attributeDescriptor for getMethod */
ModelMBeanAttributeInfo attrInfo=null;
Descriptor attrDescr=null;
Object response = null;
Object response;
try {
if (modelMBeanInfo == null)
@ -1435,14 +1433,14 @@ public class RequiredModelMBean
"getAttribute failed: ModelMBeanInfo not found for "+
attrName);
attrInfo = modelMBeanInfo.getAttribute(attrName);
ModelMBeanAttributeInfo attrInfo = modelMBeanInfo.getAttribute(attrName);
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
if (attrInfo == null)
throw new AttributeNotFoundException("getAttribute failed:"+
" ModelMBeanAttributeInfo not found for " + attrName);
attrDescr = attrInfo.getDescriptor();
Descriptor attrDescr = attrInfo.getDescriptor();
if (attrDescr != null) {
if (!attrInfo.isReadable())
throw new AttributeNotFoundException(
@ -1684,14 +1682,13 @@ public class RequiredModelMBean
"getAttributes(String[])","Entry");
}
AttributeList responseList = null;
if (attrNames == null)
throw new RuntimeOperationsException(new
IllegalArgumentException("attributeNames must not be null"),
"Exception occurred trying to get attributes of a "+
"RequiredModelMBean");
responseList = new AttributeList();
AttributeList responseList = new AttributeList();
for (int i = 0; i < attrNames.length; i++) {
try {
responseList.add(new Attribute(attrNames[i],
@ -1833,8 +1830,6 @@ public class RequiredModelMBean
throw new AttributeNotFoundException("setAttribute failed: "
+ attrName + " is not writable ");
Object setResponse = null;
String attrSetMethod = (String)
(attrDescr.getFieldValue("setMethod"));
String attrGetMethod = (String)
@ -1873,9 +1868,9 @@ public class RequiredModelMBean
}
updateDescriptor = true;
} else {
setResponse = invoke(attrSetMethod,
(new Object[] {attrValue}),
(new String[] {attrType}) );
invoke(attrSetMethod,
(new Object[] {attrValue}),
(new String[] {attrType}) );
}
/* change cached value */
@ -2023,8 +2018,6 @@ public class RequiredModelMBean
private synchronized void writeToLog(String logFileName,
String logEntry) throws Exception {
PrintStream logOut = null;
FileOutputStream fos = null;
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
@ -2041,9 +2034,9 @@ public class RequiredModelMBean
return;
}
FileOutputStream fos = new FileOutputStream(logFileName, true);
try {
fos = new FileOutputStream(logFileName, true);
logOut = new PrintStream(fos);
PrintStream logOut = new PrintStream(fos);
logOut.println(logEntry);
logOut.close();
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
@ -2062,6 +2055,8 @@ public class RequiredModelMBean
logFileName);
}
throw e;
} finally {
fos.close();
}
}

View File

@ -740,16 +740,16 @@ public class CounterMonitor extends Monitor implements CounterMonitorMBean {
//
switch (o.getType()) {
case INTEGER:
o.setThreshold(new Integer((int)threshold_value));
o.setThreshold(Integer.valueOf((int)threshold_value));
break;
case BYTE:
o.setThreshold(new Byte((byte)threshold_value));
o.setThreshold(Byte.valueOf((byte)threshold_value));
break;
case SHORT:
o.setThreshold(new Short((short)threshold_value));
o.setThreshold(Short.valueOf((short)threshold_value));
break;
case LONG:
o.setThreshold(new Long(threshold_value));
o.setThreshold(Long.valueOf(threshold_value));
break;
default:
// Should never occur...
@ -810,10 +810,10 @@ public class CounterMonitor extends Monitor implements CounterMonitorMBean {
derived += modulus.longValue();
switch (o.getType()) {
case INTEGER: o.setDerivedGauge(new Integer((int) derived)); break;
case BYTE: o.setDerivedGauge(new Byte((byte) derived)); break;
case SHORT: o.setDerivedGauge(new Short((short) derived)); break;
case LONG: o.setDerivedGauge(new Long(derived)); break;
case INTEGER: o.setDerivedGauge(Integer.valueOf((int) derived)); break;
case BYTE: o.setDerivedGauge(Byte.valueOf((byte) derived)); break;
case SHORT: o.setDerivedGauge(Short.valueOf((short) derived)); break;
case LONG: o.setDerivedGauge(Long.valueOf(derived)); break;
default:
// Should never occur...
MONITOR_LOGGER.logp(Level.FINEST, CounterMonitor.class.getName(),

View File

@ -636,28 +636,28 @@ public class GaugeMonitor extends Monitor implements GaugeMonitorMBean {
Number der;
switch (o.getType()) {
case INTEGER:
der = new Integer(((Integer)scanGauge).intValue() -
((Integer)prev).intValue());
der = Integer.valueOf(((Integer)scanGauge).intValue() -
((Integer)prev).intValue());
break;
case BYTE:
der = new Byte((byte)(((Byte)scanGauge).byteValue() -
((Byte)prev).byteValue()));
der = Byte.valueOf((byte)(((Byte)scanGauge).byteValue() -
((Byte)prev).byteValue()));
break;
case SHORT:
der = new Short((short)(((Short)scanGauge).shortValue() -
((Short)prev).shortValue()));
der = Short.valueOf((short)(((Short)scanGauge).shortValue() -
((Short)prev).shortValue()));
break;
case LONG:
der = new Long(((Long)scanGauge).longValue() -
((Long)prev).longValue());
der = Long.valueOf(((Long)scanGauge).longValue() -
((Long)prev).longValue());
break;
case FLOAT:
der = new Float(((Float)scanGauge).floatValue() -
((Float)prev).floatValue());
der = Float.valueOf(((Float)scanGauge).floatValue() -
((Float)prev).floatValue());
break;
case DOUBLE:
der = new Double(((Double)scanGauge).doubleValue() -
((Double)prev).doubleValue());
der = Double.valueOf(((Double)scanGauge).doubleValue() -
((Double)prev).doubleValue());
break;
default:
// Should never occur...

View File

@ -367,7 +367,7 @@ public abstract class Monitor
/**
* Constant used to initialize all the numeric values.
*/
static final Integer INTEGER_ZERO = new Integer(0);
static final Integer INTEGER_ZERO = 0;
/*
@ -1122,12 +1122,12 @@ public abstract class Monitor
*/
private void monitor(ObservedObject o, int index, int an[]) {
String attribute = null;
String attribute;
String notifType = null;
String msg = null;
Object derGauge = null;
Object trigger = null;
ObjectName object = null;
ObjectName object;
Comparable<?> value = null;
MonitorNotification alarm = null;
@ -1565,7 +1565,7 @@ public abstract class Monitor
final ThreadGroup group;
final AtomicInteger threadNumber = new AtomicInteger(1);
final String namePrefix;
final String nameSuffix = "]";
static final String nameSuffix = "]";
public DaemonThreadFactory(String poolName) {
SecurityManager s = System.getSecurityManager();

View File

@ -726,7 +726,7 @@ public class ArrayType<T> extends OpenType<T> {
value += dimension;
value += elementType.hashCode();
value += Boolean.valueOf(primitiveArray).hashCode();
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -426,7 +426,7 @@ public class CompositeType extends OpenType<CompositeData> {
value += key.hashCode();
value += this.nameToType.get(key).hashCode();
}
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -769,7 +769,6 @@ public class OpenMBeanAttributeInfoSupport
"array with same dimensions";
throw new IllegalArgumentException(msg);
}
Class<?> targetComponentClass = targetArrayClass.getComponentType();
OpenType<?> componentOpenType;
if (dim == 1)
componentOpenType = baseType;

View File

@ -252,7 +252,7 @@ public class OpenMBeanConstructorInfoSupport
int value = 0;
value += this.getName().hashCode();
value += Arrays.asList(this.getSignature()).hashCode();
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -347,7 +347,7 @@ public class OpenMBeanInfoSupport
value += arraySetHash(this.getConstructors());
value += arraySetHash(this.getOperations());
value += arraySetHash(this.getNotifications());
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -352,7 +352,7 @@ public class OpenMBeanOperationInfoSupport
value += Arrays.asList(this.getSignature()).hashCode();
value += this.getReturnOpenType().hashCode();
value += this.getImpact();
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -257,7 +257,7 @@ public final class SimpleType<T> extends OpenType<T> {
// Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
//
if (myHashCode == null) {
myHashCode = new Integer(this.getClassName().hashCode());
myHashCode = Integer.valueOf(this.getClassName().hashCode());
}
// return always the same hash code for this instance (immutable)

View File

@ -332,7 +332,7 @@ public class TabularType extends OpenType<TabularData> {
for (Iterator k = indexNames.iterator(); k.hasNext(); ) {
value += k.next().hashCode();
}
myHashCode = new Integer(value);
myHashCode = Integer.valueOf(value);
}
// return always the same hash code for this instance (immutable)

View File

@ -369,7 +369,7 @@ public class RelationNotification extends Notification {
* @return a {@link List} of {@link ObjectName}.
*/
public List<ObjectName> getMBeansToUnregister() {
List<ObjectName> result = null;
List<ObjectName> result;
if (unregisterMBeanList != null) {
result = new ArrayList<ObjectName>(unregisterMBeanList);
} else {
@ -397,7 +397,7 @@ public class RelationNotification extends Notification {
* @return the old value of the updated role.
*/
public List<ObjectName> getOldRoleValue() {
List<ObjectName> result = null;
List<ObjectName> result;
if (oldRoleValue != null) {
result = new ArrayList<ObjectName>(oldRoleValue);
} else {
@ -412,7 +412,7 @@ public class RelationNotification extends Notification {
* @return the new value of the updated role.
*/
public List<ObjectName> getNewRoleValue() {
List<ObjectName> result = null;
List<ObjectName> result;
if (newRoleValue != null) {
result = new ArrayList<ObjectName>(newRoleValue);
} else {

View File

@ -35,6 +35,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import javax.management.Attribute;
@ -122,7 +123,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Internal counter to provide sequence numbers for notifications sent by:
// - the Relation Service
// - a relation handled by the Relation Service
private Long myNtfSeqNbrCounter = new Long(0);
private final AtomicLong atomicSeqNo = new AtomicLong();
// ObjectName used to register the Relation Service in the MBean Server
private ObjectName myObjName = null;
@ -256,19 +257,6 @@ public class RelationService extends NotificationBroadcasterSupport
return;
}
// Returns internal counter to be used for Sequence Numbers of
// notifications to be raised by:
// - a relation handled by this Relation Service (when updated)
// - the Relation Service
private Long getNotificationSequenceNumber() {
Long result = null;
synchronized(myNtfSeqNbrCounter) {
result = new Long(myNtfSeqNbrCounter.longValue() + 1);
myNtfSeqNbrCounter = new Long(result.longValue());
}
return result;
}
//
// Relation type handling
//
@ -369,7 +357,7 @@ public class RelationService extends NotificationBroadcasterSupport
* @return ArrayList of relation type names (Strings)
*/
public List<String> getAllRelationTypeNames() {
ArrayList<String> result = null;
ArrayList<String> result;
synchronized(myRelType2ObjMap) {
result = new ArrayList<String>(myRelType2ObjMap.keySet());
}
@ -684,7 +672,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, and no
// ReflectionException
String relId = null;
String relId;
try {
relId = (String)(myMBeanServer.getAttribute(relationObjectName,
"RelationId"));
@ -707,7 +695,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
ObjectName relServObjName = null;
ObjectName relServObjName;
try {
relServObjName = (ObjectName)
(myMBeanServer.getAttribute(relationObjectName,
@ -737,7 +725,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
String relTypeName = null;
String relTypeName;
try {
relTypeName = (String)(myMBeanServer.getAttribute(relationObjectName,
"RelationTypeName"));
@ -758,7 +746,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
RoleList roleList = null;
RoleList roleList;
try {
roleList = (RoleList)(myMBeanServer.invoke(relationObjectName,
"retrieveAllRoles",
@ -912,7 +900,7 @@ public class RelationService extends NotificationBroadcasterSupport
* @return ArrayList of String
*/
public List<String> getAllRelationIds() {
List<String> result = null;
List<String> result;
synchronized(myRelId2ObjMap) {
result = new ArrayList<String>(myRelId2ObjMap.keySet());
}
@ -948,7 +936,7 @@ public class RelationService extends NotificationBroadcasterSupport
RELATION_LOGGER.entering(RelationService.class.getName(),
"checkRoleReading", new Object[] {roleName, relationTypeName});
Integer result = null;
Integer result;
// Can throw a RelationTypeNotFoundException
RelationType relType = getRelationType(relationTypeName);
@ -965,7 +953,7 @@ public class RelationService extends NotificationBroadcasterSupport
false);
} catch (RoleInfoNotFoundException exc) {
result = new Integer(RoleStatus.NO_ROLE_WITH_NAME);
result = Integer.valueOf(RoleStatus.NO_ROLE_WITH_NAME);
}
RELATION_LOGGER.exiting(RelationService.class.getName(),
@ -1021,13 +1009,13 @@ public class RelationService extends NotificationBroadcasterSupport
writeChkFlag = false;
}
RoleInfo roleInfo = null;
RoleInfo roleInfo;
try {
roleInfo = relType.getRoleInfo(roleName);
} catch (RoleInfoNotFoundException exc) {
RELATION_LOGGER.exiting(RelationService.class.getName(),
"checkRoleWriting");
return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
return Integer.valueOf(RoleStatus.NO_ROLE_WITH_NAME);
}
Integer result = checkRoleInt(2,
@ -1436,7 +1424,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Relation id to relation type name map
// First retrieves the relation type name
String relTypeName = null;
String relTypeName;
synchronized(myRelId2RelTypeMap) {
relTypeName = myRelId2RelTypeMap.get(relationId);
myRelId2RelTypeMap.remove(relationId);
@ -1641,7 +1629,7 @@ public class RelationService extends NotificationBroadcasterSupport
// List of relation ids of interest regarding the selected
// relation type
List<String> relIdList = null;
List<String> relIdList;
if (relationTypeName == null) {
// Considers all relations
relIdList = new ArrayList<String>(allRelIdSet);
@ -1655,7 +1643,7 @@ public class RelationService extends NotificationBroadcasterSupport
for (String currRelId : allRelIdSet) {
// Retrieves its relation type
String currRelTypeName = null;
String currRelTypeName;
synchronized(myRelId2RelTypeMap) {
currRelTypeName =
myRelId2RelTypeMap.get(currRelId);
@ -1952,7 +1940,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw a RelationNotFoundException
Object relObj = getRelation(relationId);
RoleResult result = null;
RoleResult result;
if (relObj instanceof RelationSupport) {
// Internal relation
@ -2022,7 +2010,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw a RelationNotFoundException
Object relObj = getRelation(relationId);
RoleResult result = null;
RoleResult result;
if (relObj instanceof RelationSupport) {
// Internal relation
@ -2073,7 +2061,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw a RelationNotFoundException
Object relObj = getRelation(relationId);
Integer result = null;
Integer result;
if (relObj instanceof RelationSupport) {
// Internal relation
@ -2268,7 +2256,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw a RelationNotFoundException
Object relObj = getRelation(relationId);
RoleResult result = null;
RoleResult result;
if (relObj instanceof RelationSupport) {
// Internal relation
@ -2390,7 +2378,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Can throw a RelationNotFoundException
Object relObj = getRelation(relationId);
String result = null;
String result;
if (relObj instanceof RelationSupport) {
// Internal relation
@ -2473,7 +2461,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Note: do both tests as a relation can be an MBean and be
// itself referenced in another relation :)
String relId = null;
String relId;
synchronized(myRelMBeanObjName2RelIdMap){
relId = myRelMBeanObjName2RelIdMap.get(mbeanName);
}
@ -2511,9 +2499,6 @@ public class RelationService extends NotificationBroadcasterSupport
RELATION_LOGGER.entering(RelationService.class.getName(),
"getNotificationInfo");
MBeanNotificationInfo[] ntfInfoArray =
new MBeanNotificationInfo[1];
String ntfClass = "javax.management.relation.RelationNotification";
String[] ntfTypes = new String[] {
@ -2615,7 +2600,7 @@ public class RelationService extends NotificationBroadcasterSupport
"getRelationType", relationTypeName);
// No null relation type accepted, so can use get()
RelationType relType = null;
RelationType relType;
synchronized(myRelType2ObjMap) {
relType = (myRelType2ObjMap.get(relationTypeName));
}
@ -2659,7 +2644,7 @@ public class RelationService extends NotificationBroadcasterSupport
"getRelation", relationId);
// No null relation accepted, so can use get()
Object rel = null;
Object rel;
synchronized(myRelId2ObjMap) {
rel = myRelId2ObjMap.get(relationId);
}
@ -3077,7 +3062,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Retrieves corresponding role info
// Can throw a RoleInfoNotFoundException to be converted into a
// RoleNotFoundException
RoleInfo roleInfo = null;
RoleInfo roleInfo;
try {
roleInfo = relType.getRoleInfo(currRoleName);
} catch (RoleInfoNotFoundException exc) {
@ -3227,7 +3212,7 @@ public class RelationService extends NotificationBroadcasterSupport
if (!(roleName.equals(expName))) {
RELATION_LOGGER.exiting(RelationService.class.getName(),
"checkRoleInt");
return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
return Integer.valueOf(RoleStatus.NO_ROLE_WITH_NAME);
}
// Checks read access if required
@ -3236,7 +3221,7 @@ public class RelationService extends NotificationBroadcasterSupport
if (!isReadable) {
RELATION_LOGGER.exiting(RelationService.class.getName(),
"checkRoleInt");
return new Integer(RoleStatus.ROLE_NOT_READABLE);
return Integer.valueOf(RoleStatus.ROLE_NOT_READABLE);
} else {
// End of check :)
RELATION_LOGGER.exiting(RelationService.class.getName(),
@ -3572,7 +3557,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Relation type name
// Note: do not use getRelationTypeName() as if it is a relation MBean
// it is already unregistered.
String relTypeName = null;
String relTypeName;
synchronized(myRelId2RelTypeMap) {
relTypeName = (myRelId2RelTypeMap.get(relationId));
}
@ -3609,7 +3594,7 @@ public class RelationService extends NotificationBroadcasterSupport
}
// Sequence number
Long seqNbr = getNotificationSequenceNumber();
Long seqNo = atomicSeqNo.incrementAndGet();
// Timestamp
Date currDate = new Date();
@ -3625,7 +3610,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Creation or removal
ntf = new RelationNotification(ntfType,
this,
seqNbr.longValue(),
seqNo.longValue(),
timeStamp,
message,
relationId,
@ -3640,7 +3625,7 @@ public class RelationService extends NotificationBroadcasterSupport
// Update
ntf = new RelationNotification(ntfType,
this,
seqNbr.longValue(),
seqNo.longValue(),
timeStamp,
message,
relationId,
@ -3732,7 +3717,7 @@ public class RelationService extends NotificationBroadcasterSupport
//
// Shall not throw RelationTypeNotFoundException or
// RoleInfoNotFoundException
RoleInfo currRoleInfo = null;
RoleInfo currRoleInfo;
try {
currRoleInfo = getRoleInfo(currRelTypeName,
currRoleName);

View File

@ -34,6 +34,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.sun.jmx.defaults.JmxProperties.RELATION_LOGGER;
import static com.sun.jmx.mbeanserver.Util.cast;
import javax.management.InstanceNotFoundException;
@ -110,7 +111,7 @@ public class RelationSupport
private Map<String,Role> myRoleName2ValueMap = new HashMap<String,Role>();
// Flag to indicate if the object has been added in the Relation Service
private Boolean myInRelServFlg = null;
private final AtomicBoolean myInRelServFlg = new AtomicBoolean();
//
// Constructors
@ -403,7 +404,7 @@ public class RelationSupport
"getRoleCardinality", roleName);
// Try to retrieve the role
Role role = null;
Role role;
synchronized(myRoleName2ValueMap) {
// No null Role is allowed, so direct use of get()
role = (myRoleName2ValueMap.get(roleName));
@ -427,7 +428,7 @@ public class RelationSupport
RELATION_LOGGER.exiting(RelationSupport.class.getName(),
"getRoleCardinality");
return new Integer(roleValue.size());
return roleValue.size();
}
/**
@ -701,11 +702,7 @@ public class RelationSupport
* the Relation Service.
*/
public Boolean isInRelationService() {
Boolean result = null;
synchronized(myInRelServFlg) {
result = Boolean.valueOf(myInRelServFlg.booleanValue());
}
return result;
return myInRelServFlg.get();
}
public void setRelationServiceManagementFlag(Boolean flag)
@ -715,10 +712,7 @@ public class RelationSupport
String excMsg = "Invalid parameter.";
throw new IllegalArgumentException(excMsg);
}
synchronized(myInRelServFlg) {
myInRelServFlg = Boolean.valueOf(flag.booleanValue());
}
return;
myInRelServFlg.set(flag);
}
//
@ -790,7 +784,7 @@ public class RelationSupport
int pbType = 0;
Role role = null;
Role role;
synchronized(myRoleName2ValueMap) {
// No null Role is allowed, so direct use of get()
role = (myRoleName2ValueMap.get(roleName));
@ -801,7 +795,7 @@ public class RelationSupport
} else {
// Checks if the role is readable
Integer status = null;
Integer status;
if (relationServCallFlg) {
@ -851,7 +845,7 @@ public class RelationSupport
pbType = status.intValue();
}
Object result = null;
Object result;
if (pbType == 0) {
// Role can be retrieved
@ -937,7 +931,7 @@ public class RelationSupport
for (int i = 0; i < roleNameArray.length; i++) {
String currRoleName = roleNameArray[i];
Object currResult = null;
Object currResult;
// Can throw RelationServiceNotRegisteredException
//
@ -1102,13 +1096,13 @@ public class RelationSupport
// handle initialization of role when creating the relation
// (roles provided in the RoleList parameter are directly set but
// roles automatically initialized are set using setRole())
Role role = null;
Role role;
synchronized(myRoleName2ValueMap) {
role = (myRoleName2ValueMap.get(roleName));
}
List<ObjectName> oldRoleValue;
Boolean initFlg = null;
Boolean initFlg;
if (role == null) {
initFlg = true;
@ -1122,7 +1116,7 @@ public class RelationSupport
// Checks if the role can be set: is writable (except if
// initialization) and correct value
try {
Integer status = null;
Integer status;
if (relationServCallFlg) {
@ -1314,7 +1308,7 @@ public class RelationSupport
Object[] params = new Object[3];
params[0] = myRelId;
params[1] = newRole;
params[2] = ((ArrayList)oldRoleValue);
params[2] = oldRoleValue;
String[] signature = new String[3];
signature[0] = "java.lang.String";
signature[1] = "javax.management.relation.Role";
@ -1598,7 +1592,6 @@ public class RelationSupport
myRelTypeName = relationTypeName;
// Can throw InvalidRoleValueException
initRoleMap(list);
myInRelServFlg = Boolean.FALSE;
RELATION_LOGGER.exiting(RelationSupport.class.getName(), "initMembers");
return;
@ -1710,7 +1703,7 @@ public class RelationSupport
roleName, relationServCallFlg, relationServ});
// Retrieves current role value
Role role = null;
Role role;
synchronized(myRoleName2ValueMap) {
role = (myRoleName2ValueMap.get(roleName));
}

View File

@ -435,7 +435,7 @@ public class JMXConnectorFactory {
Iterator<JMXConnectorProvider> providers =
getProviderIterator(JMXConnectorProvider.class, loader);
JMXConnector connection = null;
JMXConnector connection;
IOException exception = null;
while(providers.hasNext()) {
try {
@ -450,7 +450,7 @@ public class JMXConnectorFactory {
"] Service provider exception: " + e);
if (!(e instanceof MalformedURLException)) {
if (exception == null) {
if (exception instanceof IOException) {
if (e instanceof IOException) {
exception = (IOException) e;
} else {
exception = EnvHelp.initCause(

View File

@ -215,12 +215,10 @@ public class JMXConnectorServerFactory {
JMXConnectorFactory.
getProviderIterator(JMXConnectorServerProvider.class, loader);
JMXConnectorServer connection = null;
IOException exception = null;
while (providers.hasNext()) {
try {
connection = providers.next().newJMXConnectorServer(url, map, mbs);
return connection;
return providers.next().newJMXConnectorServer(url, map, mbs);
} catch (JMXProviderException e) {
throw e;
} catch (Exception e) {
@ -230,7 +228,7 @@ public class JMXConnectorServerFactory {
"] Service provider exception: " + e);
if (!(e instanceof MalformedURLException)) {
if (exception == null) {
if (exception instanceof IOException) {
if (e instanceof IOException) {
exception = (IOException) e;
} else {
exception = EnvHelp.initCause(

View File

@ -162,8 +162,6 @@ public class JMXServiceURL implements Serializable {
requiredPrefix);
}
int[] ptr = new int[1];
// Parse the protocol name
final int protoStart = requiredPrefixLength;
final int protoEnd = indexOf(serviceURL, ':', protoStart);
@ -664,11 +662,6 @@ public class JMXServiceURL implements Serializable {
hostNameBitSet.set('.');
}
private static void addCharsToBitSet(BitSet set, String chars) {
for (int i = 0; i < chars.length(); i++)
set.set(chars.charAt(i));
}
/**
* The value returned by {@link #getProtocol()}.
*/

View File

@ -1376,12 +1376,12 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
protected Integer addListenerForMBeanRemovedNotif()
throws IOException, InstanceNotFoundException {
MarshalledObject<NotificationFilter> sFilter = null;
NotificationFilterSupport clientFilter =
new NotificationFilterSupport();
clientFilter.enableType(
MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
sFilter = new MarshalledObject<NotificationFilter>(clientFilter);
MarshalledObject<NotificationFilter> sFilter =
new MarshalledObject<NotificationFilter>(clientFilter);
Integer[] listenerIDs;
final ObjectName[] names =
@ -1434,7 +1434,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
connectionId,
clientNotifCounter++,
message,
new Long(number));
Long.valueOf(number));
sendNotification(n);
}
}
@ -1593,7 +1593,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
protected void doStart() throws IOException {
// Get RMIServer stub from directory or URL encoding if needed.
RMIServer stub = null;
RMIServer stub;
try {
stub = (rmiServer!=null)?rmiServer:
findRMIServer(jmxServiceURL, env);
@ -2532,7 +2532,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
* A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to
* connect unconnected stubs.
**/
private static WeakReference<ORB> orb = null;
private static volatile WeakReference<ORB> orb = null;
// TRACES & DEBUG
//---------------

View File

@ -365,7 +365,7 @@ public class RMIConnectorServer extends JMXConnectorServer {
// Access file property specified, create an instance
// of the MBeanServerFileAccessController class
//
MBeanServerForwarder mbsf = null;
MBeanServerForwarder mbsf;
try {
mbsf = new MBeanServerFileAccessController(accessFile);
} catch (IOException e) {

View File

@ -344,13 +344,11 @@ public class Timer extends NotificationBroadcasterSupport
//
if (isActive == true) {
TimerAlarmClock alarmClock;
for (Object[] obj : timerTable.values()) {
// Stop all the TimerAlarmClock.
//
alarmClock = (TimerAlarmClock)obj[ALARM_CLOCK_INDEX];
TimerAlarmClock alarmClock = (TimerAlarmClock)obj[ALARM_CLOCK_INDEX];
if (alarmClock != null) {
// alarmClock.interrupt();
// try {
@ -364,7 +362,6 @@ public class Timer extends NotificationBroadcasterSupport
// //
alarmClock.cancel();
alarmClock = null;
}
}
@ -458,8 +455,7 @@ public class Timer extends NotificationBroadcasterSupport
// Create and add the timer notification into the timer table.
//
Integer notifID = null;
notifID = new Integer(++counterID);
Integer notifID = Integer.valueOf(++counterID);
// The sequenceNumber and the timeStamp attributes are updated
// when the notification is emitted by the timer.
@ -486,8 +482,8 @@ public class Timer extends NotificationBroadcasterSupport
obj[TIMER_NOTIF_INDEX] = (Object)notif;
obj[TIMER_DATE_INDEX] = (Object)d;
obj[TIMER_PERIOD_INDEX] = (Object) new Long(period);
obj[TIMER_NB_OCCUR_INDEX] = (Object) new Long(nbOccurences);
obj[TIMER_PERIOD_INDEX] = (Object) period;
obj[TIMER_NB_OCCUR_INDEX] = (Object) nbOccurences;
obj[ALARM_CLOCK_INDEX] = (Object)alarmClock;
obj[FIXED_RATE_INDEX] = Boolean.valueOf(fixedRate);
@ -678,7 +674,6 @@ public class Timer extends NotificationBroadcasterSupport
// // Remove the reference on the TimerAlarmClock.
// //
alarmClock.cancel();
alarmClock = null;
}
// Remove the timer notification from the timer table.
@ -755,7 +750,6 @@ public class Timer extends NotificationBroadcasterSupport
//
// }
alarmClock.cancel();
alarmClock = null;
}
// Remove all the timer notifications from the timer table.
@ -906,8 +900,7 @@ public class Timer extends NotificationBroadcasterSupport
Object[] obj = timerTable.get(id);
if (obj != null) {
Long period = (Long)obj[TIMER_PERIOD_INDEX];
return (new Long(period.longValue()));
return (Long)obj[TIMER_PERIOD_INDEX];
}
return null;
}
@ -924,8 +917,7 @@ public class Timer extends NotificationBroadcasterSupport
Object[] obj = timerTable.get(id);
if (obj != null) {
Long nbOccurences = (Long)obj[TIMER_NB_OCCUR_INDEX];
return (new Long(nbOccurences.longValue()));
return (Long)obj[TIMER_NB_OCCUR_INDEX];
}
return null;
}
@ -1096,7 +1088,7 @@ public class Timer extends NotificationBroadcasterSupport
if ((nbOccurences.longValue() == 0) || (nbOccurences.longValue() > 1)) {
date.setTime(date.getTime() + period.longValue());
obj[TIMER_NB_OCCUR_INDEX] = new Long(java.lang.Math.max(0L, (nbOccurences.longValue() - 1)));
obj[TIMER_NB_OCCUR_INDEX] = Long.valueOf(java.lang.Math.max(0L, (nbOccurences.longValue() - 1)));
nbOccurences = (Long)obj[TIMER_NB_OCCUR_INDEX];
if (isActive == true) {
@ -1146,9 +1138,6 @@ public class Timer extends NotificationBroadcasterSupport
// // Ignore...
// }
alarmClock.cancel();
// Remove the reference on the TimerAlarmClock.
//
alarmClock = null;
}
timerTable.remove(notifID);
}
@ -1165,10 +1154,6 @@ public class Timer extends NotificationBroadcasterSupport
// }
alarmClock.cancel();
// Remove the reference on the TimerAlarmClock.
//
alarmClock = null;
}
timerTable.remove(notifID);
}

View File

@ -44,7 +44,7 @@ import javax.print.attribute.Attribute;
* print request's, print job's, or print service's attribute set.
* <P>
* The Internet Assigned Numbers Authority maintains the
* <A HREF="http://www.isi.edu/in-notes/iana/assignments/url-schemes">official
* <A HREF="http://www.iana.org/assignments/uri-schemes.html">official
* list of URI schemes</A>.
* <p>
* Class ReferenceUriSchemesSupported defines enumeration values for widely

View File

@ -165,7 +165,8 @@ public class SunVolatileImage extends VolatileImage {
{
return new BufImgVolatileSurfaceManager(this, context);
}
return SurfaceManagerFactory.createVolatileManager(this, context);
SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
return smf.createVolatileManager(this, context);
}
private Color getForeground() {

View File

@ -887,10 +887,10 @@ public final class AttributeValues implements Cloneable {
try {
AffineTransform rtxi = rtx.createInverse();
double dx = tx.getTranslateX();
double dy = tx.getTranslateY();
tx.preConcatenate(rtxi);
if (andTranslation) {
double dx = tx.getTranslateX();
double dy = tx.getTranslateY();
if (dx != 0 || dy != 0) {
tx.setTransform(tx.getScaleX(), tx.getShearY(),
tx.getShearX(), tx.getScaleY(), 0, 0);

View File

@ -27,6 +27,7 @@ package sun.font;
import java.lang.ref.SoftReference;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
@ -105,6 +106,19 @@ public class FileFontStrike extends PhysicalStrike {
boolean useNatives;
NativeStrike[] nativeStrikes;
/* Used only for communication to native layer */
private int intPtSize;
/* Perform global initialisation needed for Windows native rasterizer */
private static native boolean initNative();
private static boolean isXPorLater = false;
static {
if (FontManager.isWindows && !FontManager.useT2K &&
!GraphicsEnvironment.isHeadless()) {
isXPorLater = initNative();
}
}
FileFontStrike(FileFont fileFont, FontStrikeDesc desc) {
super(fileFont, desc);
this.fileFont = fileFont;
@ -165,7 +179,7 @@ public class FileFontStrike extends PhysicalStrike {
* should not segment unless there's another reason to do so.
*/
float ptSize = (float)matrix[3]; // interpreted only when meaningful.
int iSize = (int)ptSize;
int iSize = intPtSize = (int)ptSize;
boolean isSimpleTx = (at.getType() & complexTX) == 0;
segmentedCache =
(numGlyphs > SEGSIZE << 3) ||
@ -189,8 +203,26 @@ public class FileFontStrike extends PhysicalStrike {
FontManager.deRegisterBadFont(fileFont);
return;
}
if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
/* First, see if native code should be used to create the glyph.
* GDI will return the integer metrics, not fractional metrics, which
* may be requested for this strike, so we would require here that :
* desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
* except that the advance returned by GDI is always overwritten by
* the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
*/
if (FontManager.isWindows && isXPorLater &&
!FontManager.useT2K &&
!GraphicsEnvironment.isHeadless() &&
!fileFont.useJavaRasterizer &&
(desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
(matrix[1] == 0.0 && matrix[2] == 0.0 &&
matrix[0] == matrix[3] &&
matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
!((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
useNatives = true;
}
else if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
/* Check its a simple scale of a pt size in the range
* where native bitmaps typically exist (6-36 pts) */
if (matrix[1] == 0.0 && matrix[2] == 0.0 &&
@ -208,7 +240,16 @@ public class FileFontStrike extends PhysicalStrike {
}
}
}
if (FontManager.logging && FontManager.isWindows) {
FontManager.logger.info
("Strike for " + fileFont + " at size = " + intPtSize +
" use natives = " + useNatives +
" useJavaRasteriser = " + fileFont.useJavaRasterizer +
" AAHint = " + desc.aaHint +
" Has Embedded bitmaps = " +
((TrueTypeFont)fileFont).
useEmbeddedBitmapsForSize(intPtSize));
}
this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
/* Always get the image and the advance together for smaller sizes
@ -217,7 +258,12 @@ public class FileFontStrike extends PhysicalStrike {
* "maximumSizeForGetImageWithAdvance".
* This should be no greater than OutlineTextRender.THRESHOLD.
*/
getImageWithAdvance = at.getScaleY() <= 48.0;
double maxSz = 48.0;
getImageWithAdvance =
Math.abs(at.getScaleX()) <= maxSz &&
Math.abs(at.getScaleY()) <= maxSz &&
Math.abs(at.getShearX()) <= maxSz &&
Math.abs(at.getShearY()) <= maxSz;
/* Some applications request advance frequently during layout.
* If we are not getting and caching the image with the advance,
@ -250,8 +296,50 @@ public class FileFontStrike extends PhysicalStrike {
return fileFont.getNumGlyphs();
}
/* Try the native strikes first, then try the fileFont strike */
long getGlyphImageFromNative(int glyphCode) {
if (FontManager.isWindows) {
return getGlyphImageFromWindows(glyphCode);
} else {
return getGlyphImageFromX11(glyphCode);
}
}
/* There's no global state conflicts, so this method is not
* presently synchronized.
*/
private native long _getGlyphImageFromWindows(String family,
int style,
int size,
int glyphCode,
boolean fracMetrics);
long getGlyphImageFromWindows(int glyphCode) {
String family = fileFont.getFamilyName(null);
int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
| fileFont.getStyle();
int size = intPtSize;
long ptr = _getGlyphImageFromWindows
(family, style, size, glyphCode,
desc.fmHint == INTVAL_FRACTIONALMETRICS_ON);
if (ptr != 0) {
/* Get the advance from the JDK rasterizer. This is mostly
* necessary for the fractional metrics case, but there are
* also some very small number (<0.25%) of marginal cases where
* there is some rounding difference between windows and JDK.
* After these are resolved, we can restrict this extra
* work to the FM case.
*/
float advance = getGlyphAdvance(glyphCode, false);
StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
advance);
return ptr;
} else {
return fileFont.getGlyphImage(pScalerContext, glyphCode);
}
}
/* Try the native strikes first, then try the fileFont strike */
long getGlyphImageFromX11(int glyphCode) {
long glyphPtr;
char charCode = fileFont.glyphToCharMap[glyphCode];
for (int i=0;i<nativeStrikes.length;i++) {
@ -271,13 +359,19 @@ public class FileFontStrike extends PhysicalStrike {
if (glyphCode >= INVISIBLE_GLYPHS) {
return StrikeCache.invisibleGlyphPtr;
}
long glyphPtr;
long glyphPtr = 0L;
if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
return glyphPtr;
} else {
if (useNatives) {
glyphPtr = getGlyphImageFromNative(glyphCode);
} else {
if (glyphPtr == 0L && FontManager.logging) {
FontManager.logger.info
("Strike for " + fileFont +
" at size = " + intPtSize +
" couldn't get native glyph for code = " + glyphCode);
}
} if (glyphPtr == 0L) {
glyphPtr = fileFont.getGlyphImage(pScalerContext,
glyphCode);
}
@ -295,10 +389,10 @@ public class FileFontStrike extends PhysicalStrike {
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
continue;
} else {
long glyphPtr;
long glyphPtr = 0L;
if (useNatives) {
glyphPtr = getGlyphImageFromNative(glyphCode);
} else {
} if (glyphPtr == 0L) {
glyphPtr = fileFont.getGlyphImage(pScalerContext,
glyphCode);
}
@ -327,10 +421,11 @@ public class FileFontStrike extends PhysicalStrike {
} else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
continue;
} else {
long glyphPtr;
long glyphPtr = 0L;
if (useNatives) {
glyphPtr = getGlyphImageFromNative(glyphCode);
} else {
}
if (glyphPtr == 0L) {
glyphPtr = fileFont.getGlyphImage(pScalerContext,
glyphCode);
}
@ -454,11 +549,16 @@ public class FileFontStrike extends PhysicalStrike {
}
}
float getGlyphAdvance(int glyphCode) {
return getGlyphAdvance(glyphCode, true);
}
/* Metrics info is always retrieved. If the GlyphInfo address is non-zero
* then metrics info there is valid and can just be copied.
* This is in user space coordinates.
* This is in user space coordinates unless getUserAdv == false.
* Device space advance should not be propagated out of this class.
*/
float getGlyphAdvance(int glyphCode) {
private float getGlyphAdvance(int glyphCode, boolean getUserAdv) {
float advance;
if (glyphCode >= INVISIBLE_GLYPHS) {
@ -480,11 +580,11 @@ public class FileFontStrike extends PhysicalStrike {
}
}
if (invertDevTx != null) {
if (invertDevTx != null || !getUserAdv) {
/* If there is a device transform need x & y advance to
* transform back into user space.
*/
advance = getGlyphMetrics(glyphCode).x;
advance = getGlyphMetrics(glyphCode, getUserAdv).x;
} else {
long glyphPtr;
if (getImageWithAdvance) {
@ -620,6 +720,10 @@ public class FileFontStrike extends PhysicalStrike {
}
Point2D.Float getGlyphMetrics(int glyphCode) {
return getGlyphMetrics(glyphCode, true);
}
private Point2D.Float getGlyphMetrics(int glyphCode, boolean getUserAdv) {
Point2D.Float metrics = new Point2D.Float();
// !!! or do we force sgv user glyphs?
@ -627,7 +731,7 @@ public class FileFontStrike extends PhysicalStrike {
return metrics;
}
long glyphPtr;
if (getImageWithAdvance) {
if (getImageWithAdvance && getUserAdv) {
/* A heuristic optimisation says that for most cases its
* worthwhile retrieving the image at the same time as the
* metrics. So here we get the image data even if its not
@ -644,9 +748,9 @@ public class FileFontStrike extends PhysicalStrike {
metrics.y = StrikeCache.unsafe.getFloat
(glyphPtr + StrikeCache.yAdvanceOffset);
/* advance is currently in device space, need to convert back
* into user space.
* into user space, unless getUserAdv == false.
* This must not include the translation component. */
if (invertDevTx != null) {
if (invertDevTx != null && getUserAdv) {
invertDevTx.deltaTransform(metrics, metrics);
}
} else {
@ -675,9 +779,9 @@ public class FileFontStrike extends PhysicalStrike {
if (value == null) {
fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics);
/* advance is currently in device space, need to convert back
* into user space.
* into user space, unless getUserAdv == false.
*/
if (invertDevTx != null) {
if (invertDevTx != null && getUserAdv) {
invertDevTx.deltaTransform(metrics, metrics);
}
value = new Point2D.Float(metrics.x, metrics.y);

View File

@ -241,6 +241,13 @@ public abstract class Font2D {
if (font.isTransformed()) {
glyphTx.concatenate(font.getTransform());
}
if (glyphTx.getTranslateX() != 0 || glyphTx.getTranslateY() != 0) {
glyphTx.setTransform(glyphTx.getScaleX(),
glyphTx.getShearY(),
glyphTx.getShearX(),
glyphTx.getScaleY(),
0.0, 0.0);
}
FontStrikeDesc desc = new FontStrikeDesc(devTx, glyphTx,
font.getStyle(), aa, fm);
return getStrike(desc, false);
@ -266,6 +273,13 @@ public abstract class Font2D {
at.scale(ptSize, ptSize);
if (font.isTransformed()) {
at.concatenate(font.getTransform());
if (at.getTranslateX() != 0 || at.getTranslateY() != 0) {
at.setTransform(at.getScaleX(),
at.getShearY(),
at.getShearX(),
at.getScaleY(),
0.0, 0.0);
}
}
int aa = FontStrikeDesc.getAAHintIntVal(this, font, frc);
int fm = FontStrikeDesc.getFMHintIntVal(frc.getFractionalMetricsHint());

View File

@ -93,7 +93,6 @@ public final class FontManager {
*/
private static final int CHANNELPOOLSIZE = 20;
private static int lastPoolIndex = 0;
private static int poolSize = 0;
private static FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE];
/* Need to implement a simple linked list scheme for fast
@ -245,9 +244,11 @@ public final class FontManager {
osName = System.getProperty("os.name", "unknownOS");
isSolaris = osName.startsWith("SunOS");
if (isSolaris) {
String t2kStr= System.getProperty("sun.java2d.font.scaler");
String t2kStr = System.getProperty("sun.java2d.font.scaler");
if (t2kStr != null) {
useT2K = "t2k".equals(t2kStr);
}
if (isSolaris) {
String version = System.getProperty("os.version", "unk");
isSolaris8 = version.equals("5.8");
isSolaris9 = version.equals("5.9");
@ -283,29 +284,32 @@ public final class FontManager {
private static native void initIDs();
public static void addToPool(FileFont font) {
boolean added = false;
FileFont fontFileToClose = null;
int freeSlot = -1;
synchronized (fontFileCache) {
/* use poolSize to quickly detect if there's any free slots.
* This is a performance tweak based on the assumption that
* if this is executed at all often, its because there are many
* fonts being used and the pool will be full, and we will save
* a fruitless iteration
/* Avoid duplicate entries in the pool, and don't close() it,
* since this method is called only from within open().
* Seeing a duplicate is most likely to happen if the thread
* was interrupted during a read, forcing perhaps repeated
* close and open calls and it eventually it ends up pointing
* at the same slot.
*/
if (poolSize < CHANNELPOOLSIZE) {
for (int i=0; i<CHANNELPOOLSIZE; i++) {
if (fontFileCache[i] == null) {
fontFileCache[i] = font;
poolSize++;
added = true;
break;
}
for (int i=0;i<CHANNELPOOLSIZE;i++) {
if (fontFileCache[i] == font) {
return;
}
assert added;
if (fontFileCache[i] == null && freeSlot < 0) {
freeSlot = i;
}
}
if (freeSlot >= 0) {
fontFileCache[freeSlot] = font;
return;
} else {
// is it possible for this to be the same font?
assert fontFileCache[lastPoolIndex] != font;
/* replace with new font, poolSize is unchanged. */
fontFileCache[lastPoolIndex].close();
/* replace with new font. */
fontFileToClose = fontFileCache[lastPoolIndex];
fontFileCache[lastPoolIndex] = font;
/* lastPoolIndex is updated so that the least recently opened
* file will be closed next.
@ -313,6 +317,19 @@ public final class FontManager {
lastPoolIndex = (lastPoolIndex+1) % CHANNELPOOLSIZE;
}
}
/* Need to close the font file outside of the synchronized block,
* since its possible some other thread is in an open() call on
* this font file, and could be holding its lock and the pool lock.
* Releasing the pool lock allows that thread to continue, so it can
* then release the lock on this font, allowing the close() call
* below to proceed.
* Also, calling close() is safe because any other thread using
* the font we are closing() synchronizes all reading, so we
* will not close the file while its in use.
*/
if (fontFileToClose != null) {
fontFileToClose.close();
}
}
/*
@ -334,7 +351,6 @@ public final class FontManager {
for (int i=0; i<CHANNELPOOLSIZE; i++) {
if (fontFileCache[i] == font) {
fontFileCache[i] = null;
poolSize--;
}
}
}

View File

@ -85,7 +85,7 @@ public final class GlyphLayout {
private GVData _gvdata;
// cached glyph layout data for reuse
private static GlyphLayout cache; // reusable
private static volatile GlyphLayout cache; // reusable
private LayoutEngineFactory _lef; // set when get is called, unset when done is called
private TextRecord _textRecord; // the text we're working on, used by iterators

View File

@ -893,6 +893,31 @@ public class TrueTypeFont extends FileFont {
return null;
}
/* Used to determine if this size has embedded bitmaps, which
* for CJK fonts should be used in preference to LCD glyphs.
*/
boolean useEmbeddedBitmapsForSize(int ptSize) {
if (!supportsCJK) {
return false;
}
if (getDirectoryEntry(EBLCTag) == null) {
return false;
}
ByteBuffer eblcTable = getTableBuffer(EBLCTag);
int numSizes = eblcTable.getInt(4);
/* The bitmapSizeTable's start at offset of 8.
* Each bitmapSizeTable entry is 48 bytes.
* The offset of ppemY in the entry is 45.
*/
for (int i=0;i<numSizes;i++) {
int ppemY = eblcTable.get(8+(i*48)+45) &0xff;
if (ppemY == ptSize) {
return true;
}
}
return false;
}
public String getFullName() {
return fullName;
}

View File

@ -589,7 +589,7 @@ public class Type1Font extends FileFont {
protected synchronized FontScaler getScaler() {
if (scaler == null) {
return FontManager.getScaler(this, 0, false, fileSize);
scaler = FontManager.getScaler(this, 0, false, fileSize);
}
return scaler;

View File

@ -2805,6 +2805,9 @@ public final class SunGraphics2D
}
if (font.hasLayoutAttributes()) {
if (str.length() == 0) {
return;
}
new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
return;
}
@ -2831,6 +2834,9 @@ public final class SunGraphics2D
}
if (font.hasLayoutAttributes()) {
if (str.length() == 0) {
return;
}
new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
return;
}
@ -2856,6 +2862,9 @@ public final class SunGraphics2D
if (iterator == null) {
throw new NullPointerException("AttributedCharacterIterator is null");
}
if (iterator.getBeginIndex() == iterator.getEndIndex()) {
return; /* nothing to draw */
}
TextLayout tl = new TextLayout(iterator, getFontRenderContext());
tl.draw(this, (float) x, (float) y);
}
@ -2865,6 +2874,9 @@ public final class SunGraphics2D
if (iterator == null) {
throw new NullPointerException("AttributedCharacterIterator is null");
}
if (iterator.getBeginIndex() == iterator.getEndIndex()) {
return; /* nothing to draw */
}
TextLayout tl = new TextLayout(iterator, getFontRenderContext());
tl.draw(this, x, y);
}
@ -2900,6 +2912,9 @@ public final class SunGraphics2D
throw new ArrayIndexOutOfBoundsException("bad offset/length");
}
if (font.hasLayoutAttributes()) {
if (data.length == 0) {
return;
}
new TextLayout(new String(data, offset, length),
font, getFontRenderContext()).draw(this, x, y);
return;
@ -2934,6 +2949,9 @@ public final class SunGraphics2D
chData[i] = (char)(data[i+offset] & 0xff);
}
if (font.hasLayoutAttributes()) {
if (data.length == 0) {
return;
}
new TextLayout(new String(chData),
font, getFontRenderContext()).draw(this, x, y);
return;

View File

@ -0,0 +1,91 @@
/*
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.java2d;
import sun.awt.image.SunVolatileImage;
import sun.awt.image.VolatileSurfaceManager;
/**
* This factory creates platform specific VolatileSurfaceManager
* implementations.
*
* There are two platform specific SurfaceManagerFactories in OpenJDK,
* UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
* The actually used SurfaceManagerFactory is set by the respective platform
* GraphicsEnvironment implementations in the static initializer.
*/
public abstract class SurfaceManagerFactory {
/**
* The single shared instance.
*/
private static SurfaceManagerFactory instance;
/**
* Returns the surface manager factory instance. This returns a factory
* that has been set by {@link #setInstance(SurfaceManagerFactory)}.
*
* @return the surface manager factory
*/
public synchronized static SurfaceManagerFactory getInstance() {
if (instance == null) {
throw new IllegalStateException("No SurfaceManagerFactory set.");
}
return instance;
}
/**
* Sets the surface manager factory. This may only be called once, and it
* may not be set back to {@code null} when the factory is already
* instantiated.
*
* @param factory the factory to set
*/
public synchronized static void setInstance(SurfaceManagerFactory factory) {
if (factory == null) {
// We don't want to allow setting this to null at any time.
throw new IllegalArgumentException("factory must be non-null");
}
if (instance != null) {
// We don't want to re-set the instance at any time.
throw new IllegalStateException("The surface manager factory is already initialized");
}
instance = factory;
}
/**
* Creates a new instance of a VolatileSurfaceManager given any
* arbitrary SunVolatileImage. An optional context Object can be supplied
* as a way for the caller to pass pipeline-specific context data to
* the VolatileSurfaceManager (such as a backbuffer handle, for example).
*/
public abstract VolatileSurfaceManager
createVolatileManager(SunVolatileImage image, Object context);
}

View File

@ -344,8 +344,15 @@ class PSPathGraphics extends PathGraphics {
double devScaleX = devResX / DEFAULT_USER_RES;
double devScaleY = devResY / DEFAULT_USER_RES;
if (scaleX > devScaleX) scaleX = devScaleX;
if (scaleY > devScaleY) scaleY = devScaleY;
/* check if rotated or sheared */
int transformType = fullTransform.getType();
boolean clampScale = ((transformType &
(AffineTransform.TYPE_GENERAL_ROTATION |
AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
if (clampScale) {
if (scaleX > devScaleX) scaleX = devScaleX;
if (scaleY > devScaleY) scaleY = devScaleY;
}
/* We do not need to draw anything if either scaling
* factor is zero.

View File

@ -2149,48 +2149,55 @@ public class ServiceDialog extends JDialog implements ActionListener {
}
}
}
}
rbPortrait.setEnabled(pSupported);
rbLandscape.setEnabled(lSupported);
rbRevPortrait.setEnabled(rpSupported);
rbRevLandscape.setEnabled(rlSupported);
OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
if (or == null ||
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
rbPortrait.setEnabled(pSupported);
rbLandscape.setEnabled(lSupported);
rbRevPortrait.setEnabled(rpSupported);
rbRevLandscape.setEnabled(rlSupported);
or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
// need to validate if default is not supported
if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
or = null;
Object values =
psCurrent.getSupportedAttributeValues(orCategory,
docFlavor,
asCurrent);
if (values instanceof OrientationRequested[]) {
OrientationRequested[] orValues =
OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
if (or == null ||
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
// need to validate if default is not supported
if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
or = null;
values =
psCurrent.getSupportedAttributeValues(orCategory,
docFlavor,
asCurrent);
if (values instanceof OrientationRequested[]) {
OrientationRequested[] orValues =
(OrientationRequested[])values;
if (orValues.length > 1) {
// get the first in the list
or = orValues[0];
if (orValues.length > 1) {
// get the first in the list
or = orValues[0];
}
}
}
if (or == null) {
or = OrientationRequested.PORTRAIT;
}
asCurrent.add(or);
}
if (or == null) {
or = OrientationRequested.PORTRAIT;
if (or == OrientationRequested.PORTRAIT) {
rbPortrait.setSelected(true);
} else if (or == OrientationRequested.LANDSCAPE) {
rbLandscape.setSelected(true);
} else if (or == OrientationRequested.REVERSE_PORTRAIT) {
rbRevPortrait.setSelected(true);
} else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
rbRevLandscape.setSelected(true);
}
asCurrent.add(or);
}
} else {
rbPortrait.setEnabled(pSupported);
rbLandscape.setEnabled(lSupported);
rbRevPortrait.setEnabled(rpSupported);
rbRevLandscape.setEnabled(rlSupported);
if (or == OrientationRequested.PORTRAIT) {
rbPortrait.setSelected(true);
} else if (or == OrientationRequested.LANDSCAPE) {
rbLandscape.setSelected(true);
} else if (or == OrientationRequested.REVERSE_PORTRAIT) {
rbRevPortrait.setSelected(true);
} else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
rbRevLandscape.setSelected(true);
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -368,7 +368,7 @@ Java_sun_font_FreetypeFontScaler_createScalerContextNative(
//text can not be smaller than 1 point
ptsz = 1.0;
}
context->ptsz = (((int) ptsz) << 6);
context->ptsz = (int)(ptsz * 64);
context->transform.xx = FloatToFTFixed((float)dmat[0]/ptsz);
context->transform.yx = -FloatToFTFixed((float)dmat[1]/ptsz);
context->transform.xy = -FloatToFTFixed((float)dmat[2]/ptsz);
@ -779,13 +779,24 @@ Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
}
if (context->fmType == TEXT_FM_ON) {
glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
} else {
double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
glyphInfo->advanceX =
(float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
(float) (advh * FTFixedToFloat(context->transform.xx));
glyphInfo->advanceY =
(float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
(float) (advh * FTFixedToFloat(context->transform.xy));
} else {
if (!ftglyph->advance.y) {
glyphInfo->advanceX =
(float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
glyphInfo->advanceY = 0;
} else if (!ftglyph->advance.x) {
glyphInfo->advanceX = 0;
glyphInfo->advanceY =
(float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
} else {
glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
}
}
if (imageSize == 0) {
@ -974,7 +985,7 @@ static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
FT_Outline_Translate(&ftglyph->outline,
FloatToF26Dot6(xpos),
FloatToF26Dot6(ypos));
-FloatToF26Dot6(ypos));
return &ftglyph->outline;
}

View File

@ -416,7 +416,8 @@ void NAME_SRCOVER_MASKBLIT(SRC, DST) \
MultiplyAndStore ## STRATEGY ## Comps(res, \
srcF, res);\
} \
if (!(DST ## IsPremultiplied) && resA && \
if (!(DST ## IsOpaque) && \
!(DST ## IsPremultiplied) && resA && \
resA < MaxValFor ## STRATEGY) \
{ \
DivideAndStore ## STRATEGY ## Comps(res, \
@ -475,7 +476,8 @@ void NAME_SRCOVER_MASKBLIT(SRC, DST) \
MultiplyAndStore ## STRATEGY ## Comps(res, \
srcF, res); \
} \
if (!(DST ## IsPremultiplied) && resA && \
if (!(DST ## IsOpaque) && \
!(DST ## IsPremultiplied) && resA && \
resA < MaxValFor ## STRATEGY) \
{ \
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
@ -797,7 +799,8 @@ void NAME_SRCOVER_MASKFILL(TYPE) \
Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
} \
} \
if (!(TYPE ## IsPremultiplied) && resA && \
if (!(TYPE ## IsOpaque) && \
!(TYPE ## IsPremultiplied) && resA && \
resA < MaxValFor ## STRATEGY) \
{ \
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
@ -831,7 +834,8 @@ void NAME_SRCOVER_MASKFILL(TYPE) \
Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \
MultiplyAddAndStore ## STRATEGY ## Comps(res, \
dstF, res, src); \
if (!(TYPE ## IsPremultiplied) && resA && \
if (!(TYPE ## IsOpaque) && \
!(TYPE ## IsPremultiplied) && resA && \
resA < MaxValFor ## STRATEGY) \
{ \
DivideAndStore ## STRATEGY ## Comps(res, res, resA); \

View File

@ -36,6 +36,8 @@
typedef jubyte ByteGrayPixelType;
typedef jubyte ByteGrayDataType;
#define ByteGrayIsOpaque 1
#define ByteGrayPixelStride 1
#define ByteGrayBitsPerPixel 8

Some files were not shown because too many files have changed in this diff Show More