/* * 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: * *

*

* */ public class ImageComponent3D extends ImageComponent { // non-public, no parameter constructor ImageComponent3D() {} /** * Constructs a 3D image component object using the specified * format, width, height, and depth. Default values are used for * all other parameters. The default values are as follows: * * * @param format the image component format, one of: FORMAT_RGB, * FORMAT_RGBA, etc. * @param width the number of columns of pixels in this image component * object * @param height the number of rows of pixels in this image component * object * @param depth the number of 2D slices in this image component object * @exception IllegalArgumentException if format is invalid, or if * any of width, height, or depth are not positive. */ public ImageComponent3D(int format, int width, int height, int depth) { ((ImageComponent3DRetained)this.retained).processParams(format, width, height, depth); } /** * Constructs a 3D image component object using the specified format, * and the BufferedImage array. * The image class is set to ImageClass.BUFFERED_IMAGE. * Default values are used for all other parameters. * * @param format the image component format, one of: FORMAT_RGB, * FORMAT_RGBA etc. * @param images an array of BufferedImage objects. The * first image in the array determines the width and height of this * ImageComponent3D. * * @exception IllegalArgumentException if format is invalid, or if * the width or height of the first image are not positive. */ public ImageComponent3D(int format, BufferedImage[] images) { ((ImageComponent3DRetained)this.retained).processParams(format, images[0].getWidth(null), images[0].getHeight(null), images.length); for (int i=0; inot an * instance of BufferedImage. In all other cases, the image class is set to * ImageClass.BUFFERED_IMAGE. * * @param format the image component format, one of: FORMAT_RGB, * FORMAT_RGBA etc. * @param images an array of RenderedImage objects. The * first image in the array determines the width and height of this * ImageComponent3D. * @param byReference a flag that indicates whether the data is copied * into this image component object or is accessed by reference. * @param yUp a flag that indicates the y-orientation of this image * component. If yUp is set to true, the origin of the image is * the lower left; otherwise, the origin of the image is the upper * left. * @exception IllegalArgumentException if format is invalid, or if * the width or height of the first image are not positive. * * @since Java 3D 1.2 */ public ImageComponent3D(int format, RenderedImage[] images, boolean byReference, boolean yUp) { ((ImageComponentRetained)this.retained).setByReference(byReference); ((ImageComponentRetained)this.retained).setYUp(yUp); ((ImageComponent3DRetained)this.retained).processParams(format, images[0].getWidth(), images[0].getHeight(), images.length); for (int i=0; i * The image class is set to ImageClass.BUFFERED_IMAGE. * * @param images array of BufferedImage objects containing the image. * The size (width and height) of each image must be the same as the * size of the image component, and the length of the images array * must equal the depth of the image component. * * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * * @exception IllegalArgumentException if the length of the images array is * not equal to the depth of this ImageComponent object. * * @exception IllegalArgumentException if the width and height of each * image in the images array is not equal to the width and height of this * ImageComponent object. */ public void set(BufferedImage[] images) { checkForLiveOrCompiled(); int depth = ((ImageComponent3DRetained)this.retained).getDepth(); if (depth != images.length) throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D1")); for (int i=0; i * The image class is set to ImageClass.RENDERED_IMAGE if the data access * mode is by-reference and any of the specified RenderedImages * is not an instance of BufferedImage. In all other cases, * the image class is set to ImageClass.BUFFERED_IMAGE. * * @param images array of RenderedImage objects containing the image. * The size (width and height) of each image must be the same as the * size of the image component, and the length of the images array * must equal the depth of the image component. * * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * * @exception IllegalArgumentException if the length of the images array is * not equal to the depth of this ImageComponent object. * * @exception IllegalArgumentException if the width and height of each * image in the images array is not equal to the width and height of this * ImageComponent object. * * @since Java 3D 1.2 */ public void set(RenderedImage[] images) { checkForLiveOrCompiled(); int depth = ((ImageComponent3DRetained)this.retained).getDepth(); if (depth != images.length) throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D1")); for (int i=0; i * The image class is set to ImageClass.NIO_IMAGE_BUFFER. * * @param images array of NioImageBuffer objects containing the image. * The size (width and height) of each image must be the same as the * size of the image component, and the length of the images array * must equal the depth of the image component. * * @exception CapabilityNotSetException if appropriate capability is * not set and this object is part of live or compiled scene graph * * @exception IllegalStateException if this ImageComponent object * is not yUp. * * @exception IllegalArgumentException if the length of the images array is * not equal to the depth of this ImageComponent object. * * @exception IllegalArgumentException if the width and height of each * image in the images array is not equal to the width and height of this * ImageComponent object. * * @exception UnsupportedOperationException this method is not supported * for Java 3D 1.5. * * @since Java 3D 1.5 */ public void set(NioImageBuffer[] images) { throw new UnsupportedOperationException(); /* checkForLiveOrCompiled(); int depth = ((ImageComponent3DRetained)this.retained).getDepth(); if (depth != images.length) throw new IllegalArgumentException(J3dI18N.getString("ImageComponent3D1")); for (int i=0; iBY_REFERENCE. * * @exception IllegalArgumentException if 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); } }