Allowing raw images to be read from a stream.

git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@758 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Matt Jensen
2009-01-20 01:21:50 +00:00
parent f381f4fe01
commit 00d60b7397
@@ -24,9 +24,11 @@ package com.threerings.resource;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
@@ -39,6 +41,8 @@ import java.awt.image.IndexColorModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.WritableRaster;
import org.apache.commons.io.IOUtils;
/**
* Provides routines for writing and reading uncompressed 8-bit color
* mapped images in a manner that is extremely fast and generates a
@@ -46,7 +50,9 @@ import java.awt.image.WritableRaster;
*/
public class FastImageIO
{
/** A suffix for use when storing raw images in bundles or on the file system. */
/**
* A suffix for use when storing raw images in bundles or on the file system.
*/
public static final String FILE_SUFFIX = ".raw";
/**
@@ -112,51 +118,74 @@ public class FastImageIO
try {
MappedByteBuffer mbuf = fchan.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
// read in our integer fields
IntBuffer ibuf = mbuf.asIntBuffer();
int width = ibuf.get();
int height = ibuf.get();
/* int tpixel = */ ibuf.get();
int msize = ibuf.get();
if (width > Short.MAX_VALUE || width < 0 || height > Short.MAX_VALUE || height < 0) {
throw new IOException("Bogus image size " + width + "x" + height);
}
IndexColorModel cmodel;
synchronized (_origin) { // any old object will do
// make sure our colormap array is big enough
if (_cmap == null || _cmap.length < msize) {
_cmap = new int[msize];
}
// read in the data and create our colormap
ibuf.get(_cmap, 0, msize);
cmodel = new IndexColorModel(8, msize, _cmap, 0, DataBuffer.TYPE_BYTE, null);
}
// advance the byte buffer accordingly
mbuf.position(ibuf.position() * 4);
// read in the image data itself
byte[] data = new byte[width*height];
mbuf.get(data);
// create the image from our component parts
DataBuffer dbuf = new DataBufferByte(data, data.length, 0);
int[] offsets = new int[] { 0 };
PixelInterleavedSampleModel smodel =
new PixelInterleavedSampleModel(
DataBuffer.TYPE_BYTE, width, height, 1, width, offsets);
WritableRaster raster = WritableRaster.createWritableRaster(smodel, dbuf, _origin);
return new BufferedImage(cmodel, raster, false, null);
return read(mbuf);
} finally {
fchan.close();
raf.close();
}
}
/**
* Reads an image from the supplied input stream (which must return the image format previously
* written via a call to {@link #write}).
*
* @exception IOException thrown if an error occurs reading from the file.
*/
public static BufferedImage read (InputStream in)
throws IOException
{
return read(ByteBuffer.wrap(IOUtils.toByteArray(in)));
}
/**
* Reads an image from the supplied byte buffer (which must return the image format previously
* written via a call to {@link #write}).
*
* @exception IOException thrown if an error occurs reading from the file.
*/
public static BufferedImage read (ByteBuffer byteBuffer)
throws IOException
{
// read in our integer fields
IntBuffer ibuf = byteBuffer.asIntBuffer();
int width = ibuf.get();
int height = ibuf.get();
/* int tpixel = */ ibuf.get();
int msize = ibuf.get();
if (width > Short.MAX_VALUE || width < 0 || height > Short.MAX_VALUE || height < 0) {
throw new IOException("Bogus image size " + width + "x" + height);
}
IndexColorModel cmodel;
synchronized (_origin) { // any old object will do
// make sure our colormap array is big enough
if (_cmap == null || _cmap.length < msize) {
_cmap = new int[msize];
}
// read in the data and create our colormap
ibuf.get(_cmap, 0, msize);
cmodel = new IndexColorModel(
8, msize, _cmap, 0, DataBuffer.TYPE_BYTE, null);
}
// advance the byte buffer accordingly
byteBuffer.position(ibuf.position() * 4);
// read in the image data itself
byte[] data = new byte[width*height];
byteBuffer.get(data);
// create the image from our component parts
DataBuffer dbuf = new DataBufferByte(data, data.length, 0);
int[] offsets = new int[] { 0 };
PixelInterleavedSampleModel smodel =
new PixelInterleavedSampleModel(
DataBuffer.TYPE_BYTE, width, height, 1, width, offsets);
WritableRaster raster = WritableRaster.createWritableRaster(smodel, dbuf, _origin);
return new BufferedImage(cmodel, raster, false, null);
}
/** Used when loading our color map. */
protected static int[] _cmap;