diff options
-rwxr-xr-x | src/classes/com/sun/opengl/util/StreamUtil.java | 74 | ||||
-rwxr-xr-x | src/classes/com/sun/opengl/util/texture/TextureIO.java | 192 | ||||
-rwxr-xr-x | src/classes/com/sun/opengl/util/texture/spi/DDSImage.java | 42 |
3 files changed, 229 insertions, 79 deletions
diff --git a/src/classes/com/sun/opengl/util/StreamUtil.java b/src/classes/com/sun/opengl/util/StreamUtil.java new file mode 100755 index 000000000..c7a32d737 --- /dev/null +++ b/src/classes/com/sun/opengl/util/StreamUtil.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.sun.opengl.util; + +import java.io.*; + +/** Utilities for dealing with streams. */ + +public class StreamUtil { + private StreamUtil() {} + + public static byte[] readAll(InputStream in) throws IOException { + in = new BufferedInputStream(in); + int avail = in.available(); + byte[] data = new byte[avail]; + int numRead = 0; + int pos = 0; + do { + if (pos + avail > data.length) { + byte[] newData = new byte[pos + avail]; + System.arraycopy(data, 0, newData, 0, pos); + data = newData; + } + numRead = in.read(data, pos, avail); + if (numRead >= 0) { + pos += numRead; + } + avail = in.available(); + } while (avail > 0 && numRead >= 0); + if (pos != data.length) { + byte[] newData = new byte[pos]; + System.arraycopy(data, 0, newData, 0, pos); + data = newData; + } + return data; + } +} diff --git a/src/classes/com/sun/opengl/util/texture/TextureIO.java b/src/classes/com/sun/opengl/util/texture/TextureIO.java index c1e5bcf8b..ca57e9886 100755 --- a/src/classes/com/sun/opengl/util/texture/TextureIO.java +++ b/src/classes/com/sun/opengl/util/texture/TextureIO.java @@ -168,6 +168,9 @@ public class TextureIO { public static TextureData newTextureData(File file, boolean mipmap, String fileSuffix) throws IOException { + if (fileSuffix == null) { + fileSuffix = FileUtil.getFileSuffix(file); + } return newTextureDataImpl(file, 0, 0, mipmap, fileSuffix); } @@ -218,6 +221,9 @@ public class TextureIO { public static TextureData newTextureData(URL url, boolean mipmap, String fileSuffix) throws IOException { + if (fileSuffix == null) { + fileSuffix = FileUtil.getFileSuffix(url.getPath()); + } return newTextureDataImpl(url, 0, 0, mipmap, fileSuffix); } @@ -281,6 +287,10 @@ public class TextureIO { throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero"); } + if (fileSuffix == null) { + fileSuffix = FileUtil.getFileSuffix(file); + } + return newTextureDataImpl(file, internalFormat, pixelFormat, mipmap, fileSuffix); } @@ -365,6 +375,10 @@ public class TextureIO { throw new IllegalArgumentException("internalFormat and pixelFormat must be non-zero"); } + if (fileSuffix == null) { + fileSuffix = FileUtil.getFileSuffix(url.getPath()); + } + return newTextureDataImpl(url, internalFormat, pixelFormat, mipmap, fileSuffix); } @@ -496,6 +510,9 @@ public class TextureIO { * OpenGL error occurred */ public static Texture newTexture(URL url, boolean mipmap, String fileSuffix) throws IOException, GLException { + if (fileSuffix == null) { + fileSuffix = FileUtil.getFileSuffix(url.getPath()); + } TextureData data = newTextureData(url, mipmap, fileSuffix); Texture texture = newTexture(data); data.flush(); @@ -835,82 +852,8 @@ public class TextureIO { String fileSuffix) throws IOException { if (DDS.equals(fileSuffix) || DDS.equals(FileUtil.getFileSuffix(file))) { - final DDSImage image = DDSImage.read(file); - DDSImage.ImageInfo info = image.getMipMap(0); - if (pixelFormat == 0) { - switch (image.getPixelFormat()) { - case DDSImage.D3DFMT_R8G8B8: - pixelFormat = GL.GL_RGB; - break; - default: - pixelFormat = GL.GL_RGBA; - break; - } - } - if (info.isCompressed()) { - switch (info.getCompressionFormat()) { - case DDSImage.D3DFMT_DXT1: - internalFormat = GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - break; - case DDSImage.D3DFMT_DXT3: - internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case DDSImage.D3DFMT_DXT5: - internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - default: - throw new RuntimeException("Unsupported DDS compression format \"" + - DDSImage.getCompressionFormatName(info.getCompressionFormat()) + "\""); - } - } - if (internalFormat == 0) { - switch (image.getPixelFormat()) { - case DDSImage.D3DFMT_R8G8B8: - pixelFormat = GL.GL_RGB; - break; - default: - pixelFormat = GL.GL_RGBA; - break; - } - } - TextureData.Flusher flusher = new TextureData.Flusher() { - public void flush() { - image.close(); - } - }; - TextureData data; - if (mipmap && image.getNumMipMaps() > 0) { - Buffer[] mipmapData = new Buffer[image.getNumMipMaps()]; - for (int i = 0; i < image.getNumMipMaps(); i++) { - mipmapData[i] = image.getMipMap(i).getData(); - } - data = new TextureData(internalFormat, - info.getWidth(), - info.getHeight(), - 0, - pixelFormat, - GL.GL_UNSIGNED_BYTE, - info.isCompressed(), - true, - mipmapData, - flusher); - } else { - // Fix this up for the end user because we can't generate - // mipmaps for compressed textures - mipmap = false; - data = new TextureData(internalFormat, - info.getWidth(), - info.getHeight(), - 0, - pixelFormat, - GL.GL_UNSIGNED_BYTE, - mipmap, - info.isCompressed(), - true, - info.getData(), - flusher); - } - return data; + DDSImage image = DDSImage.read(file); + return newTextureData(image, internalFormat, pixelFormat, mipmap); } return null; @@ -921,6 +864,14 @@ public class TextureIO { int pixelFormat, boolean mipmap, String fileSuffix) throws IOException { + if (DDS.equals(fileSuffix) || + DDSImage.isDDSImage(stream)) { + byte[] data = StreamUtil.readAll(stream); + ByteBuffer buf = ByteBuffer.wrap(data); + DDSImage image = DDSImage.read(buf); + return newTextureData(image, internalFormat, pixelFormat, mipmap); + } + return null; } @@ -929,7 +880,94 @@ public class TextureIO { int pixelFormat, boolean mipmap, String fileSuffix) throws IOException { - return null; + InputStream stream = new BufferedInputStream(url.openStream()); + try { + return newTextureData(stream, internalFormat, pixelFormat, mipmap, fileSuffix); + } finally { + stream.close(); + } + } + + private TextureData newTextureData(final DDSImage image, + int internalFormat, + int pixelFormat, + boolean mipmap) { + DDSImage.ImageInfo info = image.getMipMap(0); + if (pixelFormat == 0) { + switch (image.getPixelFormat()) { + case DDSImage.D3DFMT_R8G8B8: + pixelFormat = GL.GL_RGB; + break; + default: + pixelFormat = GL.GL_RGBA; + break; + } + } + if (info.isCompressed()) { + switch (info.getCompressionFormat()) { + case DDSImage.D3DFMT_DXT1: + internalFormat = GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + break; + case DDSImage.D3DFMT_DXT3: + internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case DDSImage.D3DFMT_DXT5: + internalFormat = GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + default: + throw new RuntimeException("Unsupported DDS compression format \"" + + DDSImage.getCompressionFormatName(info.getCompressionFormat()) + "\""); + } + } + if (internalFormat == 0) { + switch (image.getPixelFormat()) { + case DDSImage.D3DFMT_R8G8B8: + pixelFormat = GL.GL_RGB; + break; + default: + pixelFormat = GL.GL_RGBA; + break; + } + } + TextureData.Flusher flusher = new TextureData.Flusher() { + public void flush() { + image.close(); + } + }; + TextureData data; + if (mipmap && image.getNumMipMaps() > 0) { + Buffer[] mipmapData = new Buffer[image.getNumMipMaps()]; + for (int i = 0; i < image.getNumMipMaps(); i++) { + mipmapData[i] = image.getMipMap(i).getData(); + } + System.err.println("Creating from mipmapped data"); + data = new TextureData(internalFormat, + info.getWidth(), + info.getHeight(), + 0, + pixelFormat, + GL.GL_UNSIGNED_BYTE, + info.isCompressed(), + true, + mipmapData, + flusher); + } else { + // Fix this up for the end user because we can't generate + // mipmaps for compressed textures + mipmap = false; + data = new TextureData(internalFormat, + info.getWidth(), + info.getHeight(), + 0, + pixelFormat, + GL.GL_UNSIGNED_BYTE, + mipmap, + info.isCompressed(), + true, + info.getData(), + flusher); + } + return data; } } diff --git a/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java b/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java index 486515628..068e3baa6 100755 --- a/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java +++ b/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java @@ -148,6 +148,14 @@ public class DDSImage { return image; } + /** Reads a DirectDraw surface from the specified ByteBuffer, returning + the resulting DDSImage. */ + public static DDSImage read(ByteBuffer buf) throws IOException { + DDSImage image = new DDSImage(); + image.readFromBuffer(buf); + return image; + } + /** Closes open files and resources associated with the open DDSImage. No other methods may be called on this object once this is called. */ @@ -191,6 +199,31 @@ public class DDSImage { return image; } + /** Determines from the magic number whether the given InputStream + points to a DDS image. The given InputStream must return true + from markSupported() and support a minimum of four bytes of + read-ahead. */ + public static boolean isDDSImage(InputStream in) throws IOException { + if (!(in instanceof BufferedInputStream)) { + in = new BufferedInputStream(in); + } + if (!in.markSupported()) { + throw new IOException("Can not test non-destructively whether given InputStream is a DDS image"); + } + in.mark(4); + int magic = 0; + for (int i = 0; i < 4; i++) { + int tmp = in.read(); + if (tmp < 0) { + in.reset(); + return false; + } + magic = ((magic >>> 8) | (tmp << 24)); + } + in.reset(); + return (magic == MAGIC); + } + /** * Writes this DDSImage to the specified file name. */ @@ -555,8 +588,13 @@ public class DDSImage { private void readFromFile(File file) throws IOException { fis = new FileInputStream(file); chan = fis.getChannel(); - buf = chan.map(FileChannel.MapMode.READ_ONLY, - 0, (int) file.length()); + ByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, + 0, (int) file.length()); + readFromBuffer(buf); + } + + private void readFromBuffer(ByteBuffer buf) throws IOException { + this.buf = buf; buf.order(ByteOrder.LITTLE_ENDIAN); header = new Header(); header.read(buf); |