001: /*
002: * $RCSfile: ImageComponent.java,v $
003: *
004: * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.8 $
028: * $Date: 2008/02/28 20:17:23 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: /**
035: * Abstract class that is used to define 2D or 3D ImageComponent
036: * classes used in a Java 3D scene graph. This is used for texture
037: * images, background images and raster components of Shape3D nodes.
038: *
039: * <p>
040: * Image data may be passed to this ImageComponent object in
041: * one of two ways: by copying the image data into this object or by
042: * accessing the image data by reference.
043: *
044: * <p>
045: * <ul>
046: * <li>
047: * <b>By Copying:</b>
048: * By default, the set and get image methods copy the image
049: * data into or out of this ImageComponent object. This is
050: * appropriate for many applications, since the application may reuse
051: * the RenderedImage object after copying it to the ImageComponent.
052: * </li>
053: * <li><b>By Reference:</b>
054: * A new feature in Java 3D version 1.2 allows image data to
055: * be accessed by reference, directly from the RenderedImage object.
056: * To use this feature, you need to construct an ImageComponent object
057: * with the <code>byReference</code> flag set to <code>true</code>.
058: * In this mode, a reference to the input data is saved, but the data
059: * itself is not necessarily copied (although it may be, depending on
060: * the value of the <code>yUp</code> flag, the format of the
061: * ImageComponent, and the format of the RenderedImage). Image data
062: * referenced by an ImageComponent object can only be modified via
063: * the updateData method.
064: * Applications must exercise care not to violate this rule. If any
065: * referenced RenderedImage is modified outside the updateData method
066: * after it has been passed
067: * to an ImageComponent object, the results are undefined.
068: * Another restriction in by-reference mode is that if the specified
069: * RenderedImage is not an instance of BufferedImage, then
070: * this ImageComponent cannot be used for readRaster or
071: * off-screen rendering operations, since these operations modify
072: * the ImageComponent data.
073: * </li>
074: * </ul>
075: *
076: * <p>
077: * An image component object also specifies whether the orientation of
078: * its image data is "y-up" or "y-down" (the default). Y-up mode
079: * causes images to be interpreted as having their origin at the lower
080: * left (rather than the default upper left) of a texture or raster
081: * image with successive scan lines moving up. This is more
082: * consistent with texture mapping data onto a surface, and maps
083: * directly into the the way textures are used in OpenGL and other 3D
084: * APIs. Setting the <code>yUp</code> flag to true in conjunction
085: * with setting the <code>byReference</code> flag to true makes it
086: * possible for Java 3D to avoid copying the texture map in some
087: * cases.
088: *
089: * <p>
090: * Note that all color fields are treated as unsigned values, even though
091: * Java does not directly support unsigned variables. This means, for
092: * example, that an ImageComponent using a format of FORMAT_RGB5 can
093: * represent red, green, and blue values between 0 and 31, while an
094: * ImageComponent using a format of FORMAT_RGB8 can represent color
095: * values between 0 and 255. Even when byte values are used to create a
096: * RenderedImage with 8-bit color components, the resulting colors
097: * (bytes) are interpreted as if they were unsigned.
098: * Values greater than 127 can be assigned to a byte variable using a
099: * type cast. For example:
100: * <ul>byteVariable = (byte) intValue; // intValue can be > 127</ul>
101: * If intValue is greater than 127, then byteVariable will be negative. The
102: * correct value will be extracted when it is used (by masking off the upper
103: * bits).
104: */
105:
106: public abstract class ImageComponent extends NodeComponent {
107: //
108: // Pixel format values
109: //
110:
111: /**
112: * Specifies that each pixel contains 3 8-bit channels: one each
113: * for red, green, blue. Same as FORMAT_RGB8.
114: */
115: public static final int FORMAT_RGB = 1;
116:
117: /**
118: * Specifies that each pixel contains 4 8-bit channels: one each
119: * for red, green, blue, alpha. Same as FORMAT_RGBA8.
120: */
121: public static final int FORMAT_RGBA = 2;
122:
123: /**
124: * Specifies that each pixel contains 3 8-bit channels: one each
125: * for red, green, blue. Same as FORMAT_RGB.
126: */
127: public static final int FORMAT_RGB8 = FORMAT_RGB;
128:
129: /**
130: * Specifies that each pixel contains 4 8-bit channels: one each
131: * for red, green, blue, alpha. Same as FORMAT_RGBA.
132: */
133: public static final int FORMAT_RGBA8 = FORMAT_RGBA;
134:
135: /**
136: * Specifies that each pixel contains 3 5-bit channels: one each
137: * for red, green, blue.
138: */
139: public static final int FORMAT_RGB5 = 3;
140:
141: /**
142: * Specifies that each pixel contains 3 5-bit channels: one each
143: * for red, green, blue and 1 1-bit channel for alpha.
144: */
145: public static final int FORMAT_RGB5_A1 = 4;
146:
147: /**
148: * Specifies that each pixel contains 3 4-bit channels: one each
149: * for red, green, blue.
150: */
151: public static final int FORMAT_RGB4 = 5;
152:
153: /**
154: * Specifies that each pixel contains 4 4-bit channels: one each
155: * for red, green, blue, alpha.
156: */
157: public static final int FORMAT_RGBA4 = 6;
158:
159: /**
160: * Specifies that each pixel contains 2 4-bit channels: one each
161: * for luminance and alpha.
162: */
163: public static final int FORMAT_LUM4_ALPHA4 = 7;
164:
165: /**
166: * Specifies that each pixel contains 2 8-bit channels: one each
167: * for luminance and alpha.
168: */
169: public static final int FORMAT_LUM8_ALPHA8 = 8;
170:
171: /**
172: * Specifies that each pixel contains 2 3-bit channels: one each
173: * for red, green, and 1 2-bit channel for blue.
174: */
175: public static final int FORMAT_R3_G3_B2 = 9;
176:
177: /**
178: * Specifies that each pixel contains 1 8-bit channel: it can be
179: * used for only luminance or only alpha or only intensity.
180: */
181: public static final int FORMAT_CHANNEL8 = 10;
182:
183: // Internal variable for checking validity of formats
184: // Change this if any more formats are added or removed
185: static final int FORMAT_TOTAL = 10;
186:
187: /**
188: * Used to specify the class of the image being wrapped.
189: *
190: * @since Java 3D 1.5
191: */
192: public enum ImageClass {
193: /**
194: * Indicates that this ImageComponent object wraps a BufferedImage
195: * object. This is the default state. Note that the image class will
196: * be BUFFERED_IMAGE following a call to set(RenderedImage image)
197: * if we are in by-copy mode, or if the image is an instance of
198: * BufferedImage.
199: */
200: BUFFERED_IMAGE,
201:
202: /**
203: * Indicates that this ImageComponent object wraps a RenderedImage
204: * object that is <i>not</i> a BufferedImage. Note that the image class
205: * of an ImageComponent following a call to set(RenderedImage image)
206: * will be RENDERED_IMAGE, if and only if the image is not an instance
207: * of BufferedImage and the ImageComponent is in by-reference mode.
208: */
209: RENDERED_IMAGE,
210:
211: /**
212: * Indicates that this ImageComponent object wraps an NioImageBuffer
213: * object. Note that an ImageComponent in this state must not be used
214: * as the off-screen buffer of a Canvas3D nor as the target of a
215: * readRaster operation.
216: */
217: NIO_IMAGE_BUFFER,
218: }
219:
220: /**
221: * Specifies that this ImageComponent object allows reading its
222: * size component information (width, height, and depth).
223: */
224: public static final int ALLOW_SIZE_READ = CapabilityBits.IMAGE_COMPONENT_ALLOW_SIZE_READ;
225:
226: /**
227: * Specifies that this ImageComponent object allows reading its
228: * format component information.
229: */
230: public static final int ALLOW_FORMAT_READ = CapabilityBits.IMAGE_COMPONENT_ALLOW_FORMAT_READ;
231:
232: /**
233: * Specifies that this ImageComponent object allows reading its
234: * image component information.
235: */
236: public static final int ALLOW_IMAGE_READ = CapabilityBits.IMAGE_COMPONENT_ALLOW_IMAGE_READ;
237:
238: /**
239: * Specifies that this ImageComponent object allows writing its
240: * image component information.
241: *
242: * @since Java 3D 1.3
243: */
244: public static final int ALLOW_IMAGE_WRITE = CapabilityBits.IMAGE_COMPONENT_ALLOW_IMAGE_WRITE;
245:
246: // Array for setting default read capabilities
247: private static final int[] readCapabilities = { ALLOW_SIZE_READ,
248: ALLOW_IMAGE_READ, ALLOW_FORMAT_READ };
249:
250: /**
251: * Not a public constructor, for internal use
252: */
253: ImageComponent() {
254: // set default read capabilities
255: setDefaultReadCapabilities(readCapabilities);
256: }
257:
258: /**
259: * Constructs an image component object using the specified format, width,
260: * and height. Default values are used for all other parameters. The
261: * default values are as follows:
262: * <ul>
263: * byReference : false<br>
264: * yUp : false<br>
265: * </ul>
266: *
267: * @param format the image component format, one of: FORMAT_RGB,
268: * FORMAT_RGBA etc.
269: * @param width the number of columns of pixels in this image component
270: * object
271: * @param height the number of rows of pixels in this image component
272: * object
273: * @exception IllegalArgumentException if format is invalid, or if
274: * width or height are not positive.
275: */
276: public ImageComponent(int format, int width, int height) {
277: // set default read capabilities
278: setDefaultReadCapabilities(readCapabilities);
279:
280: ((ImageComponentRetained) this .retained).processParams(format,
281: width, height, 1);
282: }
283:
284: /**
285: * Constructs an image component object using the specified format, width,
286: * height, byReference flag, and yUp flag.
287: *
288: * @param format the image component format, one of: FORMAT_RGB,
289: * FORMAT_RGBA etc.
290: * @param width the number of columns of pixels in this image component
291: * object
292: * @param height the number of rows of pixels in this image component
293: * object
294: * @param byReference a flag that indicates whether the data is copied
295: * into this image component object or is accessed by reference.
296: * @param yUp a flag that indicates the y-orientation of this image
297: * component. If yUp is set to true, the origin of the image is
298: * the lower left; otherwise, the origin of the image is the upper
299: * left.
300: * @exception IllegalArgumentException if format is invalid, or if
301: * width or height are not positive.
302: *
303: * @since Java 3D 1.2
304: */
305: public ImageComponent(int format, int width, int height,
306: boolean byReference, boolean yUp) {
307: // set default read capabilities
308: setDefaultReadCapabilities(readCapabilities);
309:
310: ((ImageComponentRetained) this .retained).setYUp(yUp);
311: ((ImageComponentRetained) this .retained)
312: .setByReference(byReference);
313: ((ImageComponentRetained) this .retained).processParams(format,
314: width, height, 1);
315: }
316:
317: /**
318: * Retrieves the width of this image component object.
319: * @return the width of this image component object
320: * @exception CapabilityNotSetException if appropriate capability is
321: * not set and this object is part of live or compiled scene graph
322: */
323: public int getWidth() {
324: if (isLiveOrCompiled())
325: if (!this .getCapability(ALLOW_SIZE_READ))
326: throw new CapabilityNotSetException(J3dI18N
327: .getString("ImageComponent0"));
328: return ((ImageComponentRetained) this .retained).getWidth();
329: }
330:
331: /**
332: * Retrieves the height of this image component object.
333: * @return the height of this image component object
334: * @exception CapabilityNotSetException if appropriate capability is
335: * not set and this object is part of live or compiled scene graph
336: */
337: public int getHeight() {
338: if (isLiveOrCompiled())
339: if (!this .getCapability(ALLOW_SIZE_READ))
340: throw new CapabilityNotSetException(J3dI18N
341: .getString("ImageComponent1"));
342: return ((ImageComponentRetained) this .retained).getHeight();
343: }
344:
345: /**
346: * Retrieves the format of this image component object.
347: * @return the format of this image component object
348: * @exception CapabilityNotSetException if appropriate capability is
349: * not set and this object is part of live or compiled scene graph
350: */
351: public int getFormat() {
352: if (isLiveOrCompiled())
353: if (!this .getCapability(ALLOW_FORMAT_READ))
354: throw new CapabilityNotSetException(J3dI18N
355: .getString("ImageComponent2"));
356: return ((ImageComponentRetained) this .retained).getFormat();
357: }
358:
359: /**
360: * Retrieves the data access mode for this ImageComponent object.
361: *
362: * @return <code>true</code> if the data access mode for this
363: * ImageComponent object is by-reference;
364: * <code>false</code> if the data access mode is by-copying.
365: *
366: * @since Java 3D 1.2
367: */
368: public boolean isByReference() {
369: return ((ImageComponentRetained) this .retained).isByReference();
370: }
371:
372: /**
373: * Sets the y-orientation of this ImageComponent object to
374: * y-up or y-down.
375: *
376: * @param yUp a flag that indicates the y-orientation of this image
377: * component. If yUp is set to true, the origin of the image is
378: * the lower left; otherwise, the origin of the image is the upper
379: * left.
380: *
381: * @exception RestrictedAccessException if the method is called
382: * when this object is part of live or compiled scene graph.
383: *
384: * @exception IllegalStateException if the image class of this object
385: * is ImageClass.NIO_IMAGE_BUFFER.
386: *
387: * @deprecated as of Java 3D 1.5, the yUp flag should only be set at object
388: * construction time.
389: *
390: * @since Java 3D 1.2
391: */
392: public void setYUp(boolean yUp) {
393: checkForLiveOrCompiled();
394:
395: // check for illegal image class
396: if (((ImageComponentRetained) this .retained).getImageClass() == ImageClass.NIO_IMAGE_BUFFER) {
397: throw new IllegalStateException("ImageComponent4");
398: }
399:
400: ((ImageComponentRetained) this .retained).setYUp(yUp);
401: }
402:
403: /**
404: * Retrieves the y-orientation for this ImageComponent object.
405: *
406: * @return <code>true</code> if the y-orientation of this
407: * ImageComponent object is y-up; <code>false</code> if the
408: * y-orientation of this ImageComponent object is y-down.
409: *
410: * @since Java 3D 1.2
411: */
412: public boolean isYUp() {
413: return ((ImageComponentRetained) this .retained).isYUp();
414: }
415:
416: /**
417: * Retrieves the image class of this ImageComponent object.
418: *
419: * @return the image class of this ImageComponent,
420: * one of: ImageClass.BUFFERED_IMAGE,
421: * ImageClass.RENDERED_IMAGE, or ImageClass.NIO_IMAGE_BUFFER.
422: *
423: * @since Java 3D 1.5
424: */
425: public ImageClass getImageClass() {
426: return ((ImageComponentRetained) this.retained).getImageClass();
427: }
428:
429: }
|