/* * Copyright 1996-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 javax.media.j3d; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; /** * This class defines a 3D image component. This is used for texture * images. * Prior to Java 3D 1.2, only BufferedImage objects could be used as * the input to an ImageComponent3D object. As of Java 3D 1.2, an * ImageComponent3D accepts an array of arbitrary RenderedImage * objects (BufferedImage is an implementation of the RenderedImage * interface). The methods that set/get a BufferedImage object are * left in for compatibility. The new methods that set/get a * RenderedImage are a superset of the old methods. In particular, * the two set methods in the following example are equivalent: * *
*
* BufferedImage bi;
* RenderedImage ri = bi;
* ImageComponent3D ic;
*
* // Set image 0 to the specified BufferedImage
* ic.set(0, bi);
*
* // Set image 0 to the specified RenderedImage
* ic.set(0, ri);
*
* width
or
* height
of
* the subregion exceeds the dimension of the image in this object.
*
* @exception IllegalArgumentException if dstX
< 0, or
* (dstX
+ width
) > width of this object, or
* dstY
< 0, or
* (dstY
+ height
) > height of this object.
*
* @exception IllegalArgumentException if srcX
< 0, or
* (srcX
+ width
) > width of the RenderedImage
* object containing the subimage, or
* srcY
< 0, or
* (srcY
+ height
) > height of the
* RenderedImage object containing the subimage.
*
* @exception IllegalArgumentException if the specified RenderedImage
* is not compatible with the existing RenderedImage.
*
* @exception IllegalStateException if the image class is not one of:
* ImageClass.BUFFERED_IMAGE or ImageClass.RENDERED_IMAGE.
*
* @since Java 3D 1.3
*/
public void setSubImage(int index, RenderedImage image,
int width, int height,
int srcX, int srcY, int dstX, int dstY) {
if (isLiveOrCompiled() &&
!this.getCapability(ALLOW_IMAGE_WRITE)) {
throw new CapabilityNotSetException(
J3dI18N.getString("ImageComponent3D5"));
}
if (((ImageComponent3DRetained)this.retained).isByReference()) {
throw new IllegalStateException(
J3dI18N.getString("ImageComponent3D8"));
}
int w = ((ImageComponent3DRetained)this.retained).getWidth();
int h = ((ImageComponent3DRetained)this.retained).getHeight();
if ((srcX < 0) || (srcY < 0) ||
((srcX + width) > w) || ((srcY + height) > h) ||
(dstX < 0) || (dstY < 0) ||
((dstX + width) > w) || ((dstY + height) > h)) {
throw new IllegalArgumentException(
J3dI18N.getString("ImageComponent3D7"));
}
((ImageComponent3DRetained)this.retained).setSubImage(
index, image, width, height, srcX, srcY, dstX, dstY);
}
/**
* Updates a particular slice of image data that is accessed by reference.
* This method calls the updateData method of the specified
* ImageComponent3D.Updater object to synchronize updates to the
* image data that is referenced by this ImageComponent3D object.
* Applications that wish to modify such data must perform all
* updates via this method.
* * The data to be modified has to be within the boundary of the * subregion * specified by the offset (x, y) and the dimension (width*height). * It is illegal to modify data outside this boundary. If any * referenced data is modified outside the updateData method, or * any data outside the specified boundary is modified, the * results are undefined. *
* @param updater object whose updateData callback method will be
* called to update the data referenced by this ImageComponent3D object.
* @param index index of the image to be modified.
* The index must be less than the depth of this ImageComponent3D object.
* @param x starting X offset of the subregion.
* @param y starting Y offset of the subregion.
* @param width width of the subregion.
* @param height height of the subregion.
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
* @exception IllegalStateException if the data access mode is
* BY_COPY
.
* @exception IllegalArgumentException if width
or
* height
of
* the subregion exceeds the dimension of the image in this object.
* @exception IllegalArgumentException if x
< 0, or
* (x
+ width
) > width of this object, or
* y
< 0, or
* (y
+ height
) > height of this object.
* @exception ArrayIndexOutOfBoundsException if index
> the
* depth of this object.
*
* @since Java 3D 1.3
*/
public void updateData(Updater updater, int index,
int x, int y,
int width, int height) {
if (isLiveOrCompiled() &&
!this.getCapability(ALLOW_IMAGE_WRITE)) {
throw new CapabilityNotSetException(
J3dI18N.getString("ImageComponent3D5"));
}
if (!((ImageComponent3DRetained)this.retained).isByReference()) {
throw new IllegalStateException(
J3dI18N.getString("ImageComponent3D6"));
}
int w = ((ImageComponent3DRetained)this.retained).getWidth();
int h = ((ImageComponent3DRetained)this.retained).getHeight();
if ((x < 0) || (y < 0) || ((x + width) > w) || ((y + height) > h)) {
throw new IllegalArgumentException(
J3dI18N.getString("ImageComponent3D7"));
}
((ImageComponent3DRetained)this.retained).updateData(
updater, index, x, y, width, height);
}
/**
* Creates a retained mode ImageComponent3DRetained object that this
* ImageComponent3D component object will point to.
*/
@Override
void createRetained() {
this.retained = new ImageComponent3DRetained();
this.retained.setSource(this);
}
/**
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
@Override
public NodeComponent cloneNodeComponent() {
ImageComponent3DRetained rt = (ImageComponent3DRetained) retained;
ImageComponent3D img = new ImageComponent3D(rt.getFormat(),
rt.width,
rt.height,
rt.depth);
// XXXX : replace by this to duplicate other attributes
/*
ImageComponent3D img = new ImageComponent3D(rt.format,
rt.width,
rt.height,
rt.depth,
rt.byReference,
rt.yUp);
*/
img.duplicateNodeComponent(this);
return img;
}
/**
* Copies all node information from originalNodeComponent
into
* the current node. This method is called from the
* duplicateNode
method. This routine does
* the actual duplication of all "local data" (any data defined in
* this object).
*
* @param originalNodeComponent the original node to duplicate.
* @param forceDuplicate when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @see Node#cloneTree
* @see NodeComponent#setDuplicateOnCloneTree
*/
@Override
void duplicateAttributes(NodeComponent originalNodeComponent,
boolean forceDuplicate) {
super.duplicateAttributes(originalNodeComponent, forceDuplicate);
// TODO : Handle NioImageBuffer if its supported.
RenderedImage imgs[] = ((ImageComponent3DRetained)
originalNodeComponent.retained).getImage();
if (imgs != null) {
ImageComponent3DRetained rt = (ImageComponent3DRetained) retained;
for (int i=rt.depth-1; i>=0; i--) {
if (imgs[i] != null) {
rt.set(i, imgs[i]);
}
}
}
}
/**
* The ImageComponent3D.Updater interface is used in updating image data
* that is accessed by reference from a live or compiled ImageComponent
* object. Applications that wish to modify such data must define a
* class that implements this interface. An instance of that class is
* then passed to the updateData
method of the
* ImageComponent object to be modified.
*
* @since Java 3D 1.3
*/
public static interface Updater {
/**
* Updates image data that is accessed by reference.
* This method is called by the updateData method of an
* ImageComponent object to effect
* safe updates to image data that
* is referenced by that object. Applications that wish to modify
* such data must implement this method and perform all updates
* within it.
*
* NOTE: Applications should not call this method directly.
*
* @param imageComponent the ImageComponent object being updated.
* @param index index of the image to be modified.
* @param x starting X offset of the subregion.
* @param y starting Y offset of the subregion.
* @param width width of the subregion.
* @param height height of the subregion.
*
* @see ImageComponent3D#updateData
*/
public void updateData(ImageComponent3D imageComponent,
int index,
int x, int y,
int width, int height);
}
}