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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user