001: /*
002: * Copyright (c) 2000 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, modify and redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silv?re Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silv?re Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: * @Author: Silvere Martin-Michiellot
032: *
033: */
034:
035: package com.db.utils;
036:
037: import java.net.URL;
038: import java.awt.*;
039: import java.awt.image.*;
040: import com.sun.j3d.utils.image.TextureLoader;
041: import javax.media.j3d.*;
042:
043: /**
044: * This class serves as a factory for Texture and ImageComponent2D objects.
045: * It creates these objects from image files (GIF or JPEG).
046: * The files must be stored at the same location the as classfile for this class.
047: *<p>
048: * Examples:
049: * If the TextureBuilder.class is in /home/j3d/TextureBuilder.class
050: * and one calls buildTexture("test.gif"), the there must be a file
051: * /home/j3d/test.gif.<br>
052: *
053: *<p>
054: * To create a Texture, do something like:
055: * TextureBuilder tb = new TextureBuilder(); Texture t = tb.buildTexture("a.gif");<br>
056: *
057: * Note: This class loads images using a polling mechanism. Bad style! I should
058: * use MT and synchronization.<br>
059: *
060: */
061: public class TextureBuilder {
062:
063: public TextureBuilder() {
064: }
065:
066: /**
067: * Loads the image file and creates an ImageComponent2D.
068: *
069: * @throws RuntimeException if the image does not exist or is corrupted
070: * Note: It would be better to throw an IOException, so users would be
071: * forced to catch it. But I want to make this class as similiar to
072: * the com.sun.j3d.utils.image.TextureLoader (which does not throw
073: * checked Exceptions either) as possible.
074: */
075: public ImageComponent2D buildImage(String imageName) {
076:
077: BufferedImage bufferedImage = createBufferedImage(imageName);
078: TextureLoader textureLoader = new TextureLoader(bufferedImage);
079: ImageComponent2D imageComponent2D = textureLoader.getImage();
080:
081: return imageComponent2D;
082: }
083:
084: /**
085: * Loads the image file and creates an Texture.
086: *
087: * @throws RuntimeException if the image does not exist or is corrupted
088: * Note: It would be better to throw an IOException, so users would be
089: * forced to catch it. But I want to make this class as similiar to
090: * the com.sun.j3d.utils.image.TextureLoader (which does not throw
091: * checked Exceptions either) as possible.
092: */
093: public Texture buildTexture(String imageName) {
094:
095: BufferedImage bufferedImage = createBufferedImage(imageName);
096: TextureLoader textureLoader = new TextureLoader(bufferedImage);
097: Texture texture = textureLoader.getTexture();
098:
099: return texture;
100: }
101:
102: /**
103: * Creates a BufferedImage from an image file.
104: *
105: * @throws RuntimeException if the image does not exist or is corrupted
106: * Note: It would be better to throw an IOException, so users would be
107: * forced to catch it. But I want to make this class as similiar to
108: * the com.sun.j3d.utils.image.TextureLoader (which does not throw
109: * checked Exceptions either) as possible.
110: */
111: private BufferedImage createBufferedImage(String imageName) {
112:
113: URL imageURL = getClass().getResource(imageName);
114: if (imageURL == null) {
115: throw new RuntimeException("Image resource '" + imageName
116: + "' not found.");
117: }
118:
119: Toolkit toolkit = Toolkit.getDefaultToolkit();
120: Image image = toolkit.createImage(imageURL);
121: int status;
122:
123: // start loading image
124: toolkit.prepareImage(image, -1, -1, null);
125:
126: // wait and poll periodically until complete
127: while (true) {
128: status = toolkit.checkImage(image, -1, -1, null);
129: if ((status & ImageObserver.ERROR) != 0) {
130: throw new RuntimeException("Error loading image '"
131: + imageURL + "'");
132: } else if ((status & ImageObserver.ALLBITS) != 0) {
133: break;
134: }
135: try {
136: Thread.sleep(250);
137: } catch (InterruptedException e) {
138: throw new Error("Internal Error. Should never happen.");
139: }
140: }
141:
142: int width = image.getWidth(null);
143: int height = image.getHeight(null);
144:
145: BufferedImage bufferedImage = new BufferedImage(width, height,
146: BufferedImage.TYPE_INT_ARGB);
147: int[] intPixels = ((DataBufferInt) bufferedImage.getRaster()
148: .getDataBuffer()).getData();
149:
150: // retrieve image data using PixelGrabber
151: PixelGrabber pg = new PixelGrabber(image, 0, 0, width, height,
152: intPixels, 0, width);
153: try {
154: pg.grabPixels();
155: } catch (InterruptedException e) {
156: throw new Error("Internal Error. Should never happen.");
157: }
158:
159: return bufferedImage;
160: }
161:
162: }
|