diff --git a/src/java/com/threerings/cast/bundle/BundledComponentRepository.java b/src/java/com/threerings/cast/bundle/BundledComponentRepository.java
index 623a099f8..8addb6455 100644
--- a/src/java/com/threerings/cast/bundle/BundledComponentRepository.java
+++ b/src/java/com/threerings/cast/bundle/BundledComponentRepository.java
@@ -1,10 +1,9 @@
//
-// $Id: BundledComponentRepository.java,v 1.3 2001/11/30 02:34:57 mdb Exp $
+// $Id: BundledComponentRepository.java,v 1.4 2001/12/07 01:33:29 mdb Exp $
package com.threerings.cast.bundle;
import java.awt.Image;
-import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
@@ -196,7 +195,7 @@ public class BundledComponentRepository
}
// documentation inherited
- public BufferedImage loadImage (String path)
+ public Image loadImage (String path)
throws IOException
{
// obtain the image data from our resource bundle
diff --git a/src/java/com/threerings/media/image/ImageIOLoader.java b/src/java/com/threerings/media/image/ImageIOLoader.java
new file mode 100644
index 000000000..99290d9e2
--- /dev/null
+++ b/src/java/com/threerings/media/image/ImageIOLoader.java
@@ -0,0 +1,31 @@
+//
+// $Id: ImageIOLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
+
+package com.threerings.media;
+
+import java.awt.Image;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Loads images using the ImageIO services provided by J2SE
+ * 1.4 (and, presumably, above).
+ */
+public class ImageIOLoader
+{
+ // documentation inherited
+ public Image loadImage (InputStream source)
+ throws IOException
+ {
+ // this seems to choke when decoding the compressed image data
+ // which may mean it's a JDK bug or something, but I'd like to see
+ // it resolved so that the image manager will work on applets
+ //
+ // ImageInputStream iis = new MemoryCacheImageInputStream(source);
+ // return ImageIO.read(iis);
+
+ return ImageIO.read(source);
+ }
+}
diff --git a/src/java/com/threerings/media/image/ImageLoader.java b/src/java/com/threerings/media/image/ImageLoader.java
new file mode 100644
index 000000000..146a597b3
--- /dev/null
+++ b/src/java/com/threerings/media/image/ImageLoader.java
@@ -0,0 +1,24 @@
+//
+// $Id: ImageLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
+
+package com.threerings.media;
+
+import java.awt.Image;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * In order to take advantage of the new J2SE 1.4 image loading facilites
+ * (in the form of ImageIO and friends), while preserving the
+ * ability to operate on J2SE 1.3 and previous, we have the image loader
+ * interface. It allows us to attempt to load the ImageIO based loader and
+ * fall back if the class is not available.
+ */
+public interface ImageLoader
+{
+ /**
+ * Load up the image from the supplied input stream.
+ */
+ public Image loadImage (InputStream source)
+ throws IOException;
+}
diff --git a/src/java/com/threerings/media/image/ImageManager.java b/src/java/com/threerings/media/image/ImageManager.java
index ea098f27f..8271a8768 100644
--- a/src/java/com/threerings/media/image/ImageManager.java
+++ b/src/java/com/threerings/media/image/ImageManager.java
@@ -1,12 +1,14 @@
//
-// $Id: ImageManager.java,v 1.8 2001/11/30 02:33:34 mdb Exp $
+// $Id: ImageManager.java,v 1.9 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media;
+import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
+import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
@@ -17,7 +19,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
@@ -33,9 +34,13 @@ public class ImageManager
{
/**
* Construct an image manager with the specified {@link
- * ResourceManager} from which it will obtain its data.
+ * ResourceManager} from which it will obtain its data. A non-null
+ * context must be provided if there is any expectation
+ * that the image manager will not be able to load images via the
+ * ImageIO services and will have to fallback to Toolkit-style
+ * loading.
*/
- public ImageManager (ResourceManager rmgr)
+ public ImageManager (ResourceManager rmgr, Component context)
{
_rmgr = rmgr;
@@ -44,16 +49,25 @@ public class ImageManager
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gdev = genv.getDefaultScreenDevice();
_gconf = gdev.getDefaultConfiguration();
+
+ // try to figure out which image loader we'll be using
+ try {
+ _loader = (ImageLoader)Class.forName(IMAGEIO_LOADER).newInstance();
+ } catch (Exception e) {
+ Log.info("Unable to use ImageIO to load images. " +
+ "Falling back to Toolkit.");
+ _loader = new ToolkitLoader(context);
+ }
}
/**
* Loads the image via the resource manager using the specified path
* and caches it for faster retrieval henceforth.
*/
- public BufferedImage getImage (String path)
+ public Image getImage (String path)
throws IOException
{
- BufferedImage img = (BufferedImage)_imgs.get(path);
+ Image img = (Image)_imgs.get(path);
if (img != null) {
// Log.info("Retrieved image from cache [path=" + path + "].");
return img;
@@ -70,19 +84,12 @@ public class ImageManager
* environment and decodes the image data from the specified source
* image into that target image. The resulting image is not cached.
*/
- public BufferedImage createImage (InputStream source)
+ public Image createImage (InputStream source)
throws IOException
{
- // this seems to choke when decoding the compressed image data
- // which may mean it's a JDK bug or something, but I'd like to see
- // it resolved so that the image manager will work on applets
- //
- // ImageInputStream iis = new MemoryCacheImageInputStream(source);
- // BufferedImage src = ImageIO.read(iis);
-
- BufferedImage src = ImageIO.read(source);
- int swidth = src.getWidth();
- int sheight = src.getHeight();
+ Image src = _loader.loadImage(source);
+ int swidth = src.getWidth(null);
+ int sheight = src.getHeight(null);
// now convert the image to a format optimized for display
BufferedImage dest = _gconf.createCompatibleImage(
@@ -98,9 +105,19 @@ public class ImageManager
* by default. */
protected ResourceManager _rmgr;
+ /** The image loader via which we convert an input stream into an
+ * image. */
+ protected ImageLoader _loader;
+
/** A cache of loaded images. */
protected HashMap _imgs = new HashMap();
/** The graphics configuration of our default display device. */
protected GraphicsConfiguration _gconf;
+
+ /** The classname of the ImageIO-based image loader which we attempt
+ * to use but fallback from if we're not running a JVM that has
+ * ImageIO support. */
+ protected static final String IMAGEIO_LOADER =
+ "com.threerings.media.ImageIOLoader";
}
diff --git a/src/java/com/threerings/media/image/ImageUtil.java b/src/java/com/threerings/media/image/ImageUtil.java
new file mode 100644
index 000000000..5a8d98930
--- /dev/null
+++ b/src/java/com/threerings/media/image/ImageUtil.java
@@ -0,0 +1,40 @@
+//
+// $Id: ImageUtil.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
+
+package com.threerings.media;
+
+import java.awt.Image;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+
+/**
+ * Image related utility functions.
+ */
+public class ImageUtil
+{
+ /**
+ * Extracts a subimage from the supplied image with the specified
+ * dimensions. If the supplied image is an instance of {@link
+ * BufferedImage}, then the subimage will simply reference the main
+ * image. If it is not, the subimage will be created and the data will
+ * be rendered into the newly created image.
+ *
+ * @return the desired subimage.
+ */
+ public static Image getSubimage (
+ Image source, int x, int y, int width, int height)
+ {
+ if (source instanceof BufferedImage) {
+ return ((BufferedImage)source).getSubimage(x, y, width, height);
+
+ } else {
+ BufferedImage target =
+ new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics g = target.getGraphics();
+ g.drawImage(source, 0, 0, width, height,
+ x, y, x+width, y+height, null);
+ g.dispose();
+ return target;
+ }
+ }
+}
diff --git a/src/java/com/threerings/media/image/ToolkitLoader.java b/src/java/com/threerings/media/image/ToolkitLoader.java
new file mode 100644
index 000000000..850a9fb04
--- /dev/null
+++ b/src/java/com/threerings/media/image/ToolkitLoader.java
@@ -0,0 +1,74 @@
+//
+// $Id: ToolkitLoader.java,v 1.1 2001/12/07 01:33:29 mdb Exp $
+
+package com.threerings.media;
+
+import java.awt.Component;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Toolkit;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.util.StreamUtils;
+
+/**
+ * Loads images using the default AWT toolkit (for compatibility with
+ * pre-1.4 JVMs).
+ */
+public class ToolkitLoader implements ImageLoader
+{
+ public ToolkitLoader (Component context)
+ {
+ // do something more informative than NPE if we're misconfigured
+ if (context == null) {
+ String errmsg = "Toolkit image loader constructed without a " +
+ "context via which we can create a MediaTracker. If the " +
+ "image manager may fall back to using the Toolkit image " +
+ "loader (like it just did), then you have to provide a " +
+ "component instance for it at construct time. Thanks and " +
+ "have a nice day.";
+ throw new RuntimeException(errmsg);
+ }
+
+ _toolkit = context.getToolkit();
+ _tracker = new MediaTracker(context);
+ }
+
+ // documentation inherited
+ public Image loadImage (InputStream source)
+ throws IOException
+ {
+ byte[] data = StreamUtils.streamAsBytes(source, READ_BUFFER_SIZE);
+ Image image = _toolkit.createImage(data);
+
+ // we now have to wait for the image to finish decoding (this all
+ // apparently happens on another thread. yay!)
+ _tracker.addImage(image, 0);
+
+ // if something goes horribly awry, we don't want to go into an
+ // infinite loop, so we bound the number of times we'll allow
+ // ourselves to be interrupted and loop
+ boolean done = false;
+ for (int i = 0; (i < 1000) && !done; i++) {
+ try {
+ _tracker.waitForAll();
+ done = true;
+ } catch (InterruptedException e) {
+ // loop back around
+ }
+ }
+
+ return image;
+ }
+
+ /** Our AWT toolkit which we use to create images. */
+ protected Toolkit _toolkit;
+
+ /** Used to wait for images to load. */
+ protected MediaTracker _tracker;
+
+ /** The size of the read buffer used to load the image data. */
+ protected static final int READ_BUFFER_SIZE = 4096;
+}
diff --git a/src/java/com/threerings/media/tile/ImageProvider.java b/src/java/com/threerings/media/tile/ImageProvider.java
index cf68d1377..c772ef5ef 100644
--- a/src/java/com/threerings/media/tile/ImageProvider.java
+++ b/src/java/com/threerings/media/tile/ImageProvider.java
@@ -1,9 +1,9 @@
//
-// $Id: ImageProvider.java,v 1.1 2001/11/18 04:09:21 mdb Exp $
+// $Id: ImageProvider.java,v 1.2 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile;
-import java.awt.image.BufferedImage;
+import java.awt.Image;
import java.io.IOException;
/**
@@ -21,6 +21,6 @@ public interface ImageProvider
* @exception IOException thrown if an error occurs loading the image
* data.
*/
- public BufferedImage loadImage (String path)
+ public Image loadImage (String path)
throws IOException;
}
diff --git a/src/java/com/threerings/media/tile/SwissArmyTileSet.java b/src/java/com/threerings/media/tile/SwissArmyTileSet.java
index 1485f906b..1f5455c7e 100644
--- a/src/java/com/threerings/media/tile/SwissArmyTileSet.java
+++ b/src/java/com/threerings/media/tile/SwissArmyTileSet.java
@@ -1,12 +1,11 @@
//
-// $Id: SwissArmyTileSet.java,v 1.4 2001/11/29 21:57:31 mdb Exp $
+// $Id: SwissArmyTileSet.java,v 1.5 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile;
import java.awt.Image;
import java.awt.Point;
import java.awt.Dimension;
-import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -14,7 +13,7 @@ import java.io.ObjectInputStream;
import com.samskivert.util.StringUtil;
import com.threerings.media.Log;
-import com.threerings.media.ImageManager;
+import com.threerings.media.ImageUtil;
/**
* The swiss army tileset supports a diverse variety of tiles in the
@@ -131,7 +130,7 @@ public class SwissArmyTileSet extends TileSet
// documentation inherited
protected Image extractTileImage (int tileIndex)
{
- BufferedImage tsimg = getTilesetImage();
+ Image tsimg = getTilesetImage();
if (tsimg == null) {
return null;
}
@@ -160,7 +159,8 @@ public class SwissArmyTileSet extends TileSet
// ", tx=" + tx + ", ty=" + ty + "].");
// crop the tile-sized image chunk from the full image
- return tsimg.getSubimage(tx, ty, _widths[ridx], _heights[ridx]);
+ return ImageUtil.getSubimage(
+ tsimg, tx, ty, _widths[ridx], _heights[ridx]);
}
private void readObject (ObjectInputStream in)
diff --git a/src/java/com/threerings/media/tile/TileManager.java b/src/java/com/threerings/media/tile/TileManager.java
index 4225c5d16..01bc96e7d 100644
--- a/src/java/com/threerings/media/tile/TileManager.java
+++ b/src/java/com/threerings/media/tile/TileManager.java
@@ -1,9 +1,9 @@
//
-// $Id: TileManager.java,v 1.22 2001/11/30 02:34:57 mdb Exp $
+// $Id: TileManager.java,v 1.23 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile;
-import java.awt.image.BufferedImage;
+import java.awt.Image;
import java.io.IOException;
import com.samskivert.io.PersistenceException;
@@ -136,7 +136,7 @@ public class TileManager implements ImageProvider
}
// documentation inherited
- public BufferedImage loadImage (String path)
+ public Image loadImage (String path)
throws IOException
{
// load up the image data from the resource manager
diff --git a/src/java/com/threerings/media/tile/TileSet.java b/src/java/com/threerings/media/tile/TileSet.java
index fb817927c..05225c9f4 100644
--- a/src/java/com/threerings/media/tile/TileSet.java
+++ b/src/java/com/threerings/media/tile/TileSet.java
@@ -1,5 +1,5 @@
//
-// $Id: TileSet.java,v 1.22 2001/11/27 08:40:34 mdb Exp $
+// $Id: TileSet.java,v 1.23 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile;
@@ -227,7 +227,7 @@ public abstract class TileSet
* @return the tileset image or null if an error occurred loading the
* image.
*/
- protected BufferedImage getTilesetImage ()
+ protected Image getTilesetImage ()
{
// return it straight away if it's already loaded
if (_tilesetImg != null) {
@@ -281,5 +281,5 @@ public abstract class TileSet
/** The image containing all tile images for this set. This is private
* because it should be accessed via {@link #getTilesetImage} even by
* derived classes. */
- private transient BufferedImage _tilesetImg;
+ private transient Image _tilesetImg;
}
diff --git a/src/java/com/threerings/media/tile/UniformTileSet.java b/src/java/com/threerings/media/tile/UniformTileSet.java
index 53b6115fd..32b3c7926 100644
--- a/src/java/com/threerings/media/tile/UniformTileSet.java
+++ b/src/java/com/threerings/media/tile/UniformTileSet.java
@@ -1,13 +1,12 @@
//
-// $Id: UniformTileSet.java,v 1.4 2001/11/29 21:57:31 mdb Exp $
+// $Id: UniformTileSet.java,v 1.5 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile;
import java.awt.Image;
-import java.awt.image.BufferedImage;
import com.threerings.media.Log;
-import com.threerings.media.ImageManager;
+import com.threerings.media.ImageUtil;
/**
* A uniform tileset is one that is composed of tiles that are all the
@@ -68,7 +67,7 @@ public class UniformTileSet extends TileSet
// documentation inherited
protected Image extractTileImage (int tileId)
{
- BufferedImage tsimg = getTilesetImage();
+ Image tsimg = getTilesetImage();
if (tsimg == null) {
return null;
}
@@ -79,7 +78,8 @@ public class UniformTileSet extends TileSet
int col = tileId % tilesPerRow;
// crop the tile-sized image chunk from the full image
- return tsimg.getSubimage(_width*col, _height*row, _width, _height);
+ return ImageUtil.getSubimage(
+ tsimg, _width*col, _height*row, _width, _height);
}
// documentation inherited
diff --git a/src/java/com/threerings/media/tile/bundle/TileSetBundle.java b/src/java/com/threerings/media/tile/bundle/TileSetBundle.java
index 2e1c9423e..3546b053c 100644
--- a/src/java/com/threerings/media/tile/bundle/TileSetBundle.java
+++ b/src/java/com/threerings/media/tile/bundle/TileSetBundle.java
@@ -1,9 +1,9 @@
//
-// $Id: TileSetBundle.java,v 1.4 2001/11/30 02:34:57 mdb Exp $
+// $Id: TileSetBundle.java,v 1.5 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile.bundle;
-import java.awt.image.BufferedImage;
+import java.awt.Image;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -73,7 +73,7 @@ public class TileSetBundle
}
// documentation inherited
- public BufferedImage loadImage (String path)
+ public Image loadImage (String path)
throws IOException
{
// obtain the image data from our jarfile
diff --git a/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java b/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java
index d965cfec5..f0f207507 100644
--- a/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java
+++ b/src/java/com/threerings/media/tile/bundle/tools/DumpBundle.java
@@ -1,5 +1,5 @@
//
-// $Id: DumpBundle.java,v 1.3 2001/11/30 02:34:58 mdb Exp $
+// $Id: DumpBundle.java,v 1.4 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tools.tile.bundle;
@@ -34,7 +34,7 @@ public class DumpBundle
// create a resource and image manager in case they want to dump
// the tiles
ResourceManager rmgr = new ResourceManager(null, "rsrc");
- ImageManager imgr = new ImageManager(rmgr);
+ ImageManager imgr = new ImageManager(rmgr, null);
for (int i = 0; i < args.length; i++) {
// oh the hackery
diff --git a/tests/src/java/com/threerings/cast/builder/TestApp.java b/tests/src/java/com/threerings/cast/builder/TestApp.java
index 76165e4af..938ec72f3 100644
--- a/tests/src/java/com/threerings/cast/builder/TestApp.java
+++ b/tests/src/java/com/threerings/cast/builder/TestApp.java
@@ -1,5 +1,5 @@
//
-// $Id: TestApp.java,v 1.9 2001/11/30 02:35:37 mdb Exp $
+// $Id: TestApp.java,v 1.10 2001/12/07 01:33:29 mdb Exp $
package com.threerings.cast.builder;
@@ -34,7 +34,7 @@ public class TestApp
MisoUtil.bindProperties(_config);
ResourceManager rmgr = new ResourceManager(null, "rsrc");
- ImageManager imgr = new ImageManager(rmgr);
+ ImageManager imgr = new ImageManager(rmgr, _frame);
ComponentRepository crepo =
new BundledComponentRepository(rmgr, imgr, "components");
diff --git a/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java b/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java
index d390475d5..52a8a6ead 100644
--- a/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java
+++ b/tests/src/java/com/threerings/cast/bundle/BundledComponentRepositoryTest.java
@@ -1,5 +1,5 @@
//
-// $Id: BundledComponentRepositoryTest.java,v 1.3 2001/11/30 02:35:37 mdb Exp $
+// $Id: BundledComponentRepositoryTest.java,v 1.4 2001/12/07 01:33:29 mdb Exp $
package com.threerings.cast.bundle;
@@ -23,7 +23,7 @@ public class BundledComponentRepositoryTest extends TestCase
{
try {
ResourceManager rmgr = new ResourceManager(null, "rsrc");
- ImageManager imgr = new ImageManager(rmgr);
+ ImageManager imgr = new ImageManager(rmgr, null);
BundledComponentRepository repo =
new BundledComponentRepository(rmgr, imgr, "components");
diff --git a/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java b/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java
index 8ac23a2f0..3ba7fca41 100644
--- a/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java
+++ b/tests/src/java/com/threerings/media/tile/bundle/BundledTileSetRepositoryTest.java
@@ -1,5 +1,5 @@
//
-// $Id: BundledTileSetRepositoryTest.java,v 1.3 2001/11/30 02:35:37 mdb Exp $
+// $Id: BundledTileSetRepositoryTest.java,v 1.4 2001/12/07 01:33:29 mdb Exp $
package com.threerings.media.tile.bundle;
@@ -21,7 +21,7 @@ public class BundledTileSetRepositoryTest extends TestCase
{
try {
ResourceManager rmgr = new ResourceManager(null, "rsrc");
- ImageManager imgr = new ImageManager(rmgr);
+ ImageManager imgr = new ImageManager(rmgr, null);
BundledTileSetRepository repo =
new BundledTileSetRepository(rmgr, imgr, "tilesets");
Iterator sets = repo.enumerateTileSets();
diff --git a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java
index 93208b57e..81f279c2f 100644
--- a/tests/src/java/com/threerings/miso/viewer/ViewerApp.java
+++ b/tests/src/java/com/threerings/miso/viewer/ViewerApp.java
@@ -1,5 +1,5 @@
//
-// $Id: ViewerApp.java,v 1.19 2001/11/30 02:35:37 mdb Exp $
+// $Id: ViewerApp.java,v 1.20 2001/12/07 01:33:29 mdb Exp $
package com.threerings.miso.viewer;
@@ -42,10 +42,14 @@ public class ViewerApp
System.exit(-1);
}
+ // create and size the main application frame
+ _frame = new ViewerFrame();
+ _frame.setSize(WIDTH, HEIGHT);
+
// we don't need to configure anything
_config = new Config();
ResourceManager rmgr = new ResourceManager(null, "rsrc");
- ImageManager imgr = new ImageManager(rmgr);
+ ImageManager imgr = new ImageManager(rmgr, _frame);
_tilemgr = new TileManager(imgr);
_tilemgr.setTileSetRepository(
new BundledTileSetRepository(rmgr, imgr, "tilesets"));
@@ -62,10 +66,6 @@ public class ViewerApp
new BundledComponentRepository(rmgr, imgr, "components");
CharacterManager charmgr = new CharacterManager(crepo);
- // create and size the main application frame
- _frame = new ViewerFrame();
- _frame.setSize(WIDTH, HEIGHT);
-
// create our scene view panel
_panel = new ViewerSceneViewPanel(ctx, spritemgr, charmgr, crepo);
_frame.setPanel(_panel);