use of com.jme3.util.LittleEndien in project jmonkeyengine by jMonkeyEngine.
the class DDSLoader method load.
public Object load(AssetInfo info) throws IOException {
if (!(info.getKey() instanceof TextureKey)) {
throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey");
}
InputStream stream = null;
try {
stream = info.openStream();
in = new LittleEndien(stream);
loadHeader();
if (texture3D) {
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.ThreeDimensional);
} else if (depth > 1) {
((TextureKey) info.getKey()).setTextureTypeHint(Texture.Type.CubeMap);
}
ArrayList<ByteBuffer> data = readData(((TextureKey) info.getKey()).isFlipY());
return new Image(pixelFormat, width, height, depth, data, sizes, ColorSpace.sRGB);
} finally {
if (stream != null) {
stream.close();
}
}
}
use of com.jme3.util.LittleEndien in project jmonkeyengine by jMonkeyEngine.
the class KTXLoader method load.
private Image load(InputStream stream) {
byte[] fileId = new byte[12];
DataInput in = new DataInputStream(stream);
try {
stream.read(fileId, 0, 12);
if (!checkFileIdentifier(fileId)) {
throw new IllegalArgumentException("Unrecognized ktx file identifier : " + new String(fileId) + " should be " + new String(fileIdentifier));
}
int endianness = in.readInt();
//opposite endianness
if (endianness == 0x01020304) {
in = new LittleEndien(stream);
}
int glType = in.readInt();
int glTypeSize = in.readInt();
int glFormat = in.readInt();
int glInternalFormat = in.readInt();
int glBaseInternalFormat = in.readInt();
int pixelWidth = in.readInt();
int pixelHeight = in.readInt();
int pixelDepth = in.readInt();
int numberOfArrayElements = in.readInt();
int numberOfFaces = in.readInt();
int numberOfMipmapLevels = in.readInt();
int bytesOfKeyValueData = in.readInt();
log.log(Level.FINE, "glType = {0}", glType);
log.log(Level.FINE, "glTypeSize = {0}", glTypeSize);
log.log(Level.FINE, "glFormat = {0}", glFormat);
log.log(Level.FINE, "glInternalFormat = {0}", glInternalFormat);
log.log(Level.FINE, "glBaseInternalFormat = {0}", glBaseInternalFormat);
log.log(Level.FINE, "pixelWidth = {0}", pixelWidth);
log.log(Level.FINE, "pixelHeight = {0}", pixelHeight);
log.log(Level.FINE, "pixelDepth = {0}", pixelDepth);
log.log(Level.FINE, "numberOfArrayElements = {0}", numberOfArrayElements);
log.log(Level.FINE, "numberOfFaces = {0}", numberOfFaces);
log.log(Level.FINE, "numberOfMipmapLevels = {0}", numberOfMipmapLevels);
log.log(Level.FINE, "bytesOfKeyValueData = {0}", bytesOfKeyValueData);
if ((numberOfFaces > 1 && pixelDepth > 1) || (numberOfFaces > 1 && numberOfArrayElements > 1) || (pixelDepth > 1 && numberOfArrayElements > 1)) {
throw new UnsupportedOperationException("jME doesn't support cube maps of 3D textures or arrays of 3D texture or arrays of cube map of 3d textures");
}
PixelReader pixelReader = parseMetaData(bytesOfKeyValueData, in);
if (pixelReader == null) {
pixelReader = new SrTuRoPixelReader();
}
//some of the values may be 0 we need them at least to be 1
pixelDepth = Math.max(1, pixelDepth);
numberOfArrayElements = Math.max(1, numberOfArrayElements);
numberOfFaces = Math.max(1, numberOfFaces);
numberOfMipmapLevels = Math.max(1, numberOfMipmapLevels);
int nbSlices = Math.max(numberOfFaces, numberOfArrayElements);
Image.Format imgFormat = getImageFormat(glFormat, glInternalFormat, glType);
log.log(Level.FINE, "img format {0}", imgFormat.toString());
int bytePerPixel = imgFormat.getBitsPerPixel() / 8;
int byteBuffersSize = computeBuffersSize(numberOfMipmapLevels, pixelWidth, pixelHeight, bytePerPixel, pixelDepth);
log.log(Level.FINE, "data size {0}", byteBuffersSize);
int[] mipMapSizes = new int[numberOfMipmapLevels];
Image image = createImage(nbSlices, byteBuffersSize, imgFormat, pixelWidth, pixelHeight, pixelDepth);
byte[] pixelData = new byte[bytePerPixel];
int offset = 0;
//iterate over data
for (int mipLevel = 0; mipLevel < numberOfMipmapLevels; mipLevel++) {
//size of the image in byte.
//this value is bogus in many example, when using mipmaps.
//instead we compute the theorical size and display a warning when it does not match.
int fileImageSize = in.readInt();
int width = Math.max(1, pixelWidth >> mipLevel);
int height = Math.max(1, pixelHeight >> mipLevel);
int imageSize = width * height * bytePerPixel;
mipMapSizes[mipLevel] = imageSize;
log.log(Level.FINE, "current mip size {0}", imageSize);
if (fileImageSize != imageSize) {
log.log(Level.WARNING, "Mip map size is wrong in the file for mip level {0} size is {1} should be {2}", new Object[] { mipLevel, fileImageSize, imageSize });
}
for (int arrayElem = 0; arrayElem < numberOfArrayElements; arrayElem++) {
for (int face = 0; face < numberOfFaces; face++) {
int nbPixelRead = 0;
for (int depth = 0; depth < pixelDepth; depth++) {
ByteBuffer byteBuffer = image.getData(getSlice(face, arrayElem));
log.log(Level.FINE, "position {0}", byteBuffer.position());
byteBuffer.position(offset);
nbPixelRead = pixelReader.readPixels(width, height, pixelData, byteBuffer, in);
}
//cube padding
if (numberOfFaces == 6 && numberOfArrayElements == 0) {
in.skipBytes(3 - ((nbPixelRead + 3) % 4));
}
}
}
//mip padding
log.log(Level.FINE, "skipping {0}", (3 - ((imageSize + 3) % 4)));
in.skipBytes(3 - ((imageSize + 3) % 4));
offset += imageSize;
}
//there are loaded mip maps we set the sizes
if (numberOfMipmapLevels > 1) {
image.setMipMapSizes(mipMapSizes);
}
//if 3D texture and slices' orientation is inside, we reverse the data array.
if (pixelDepth > 1 && slicesInside) {
Collections.reverse(image.getData());
}
return image;
} catch (IOException ex) {
Logger.getLogger(KTXLoader.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
use of com.jme3.util.LittleEndien in project jmonkeyengine by jMonkeyEngine.
the class DDSLoader method load.
public Image load(InputStream stream) throws IOException {
in = new LittleEndien(stream);
loadHeader();
ArrayList<ByteBuffer> data = readData(false);
return new Image(pixelFormat, width, height, depth, data, sizes, ColorSpace.sRGB);
}
use of com.jme3.util.LittleEndien in project jmonkeyengine by jMonkeyEngine.
the class CursorLoader method loadCursor.
private JmeCursor loadCursor(InputStream inStream) throws IOException {
// new byte [0] facilitates read()
byte[] icoimages = new byte[0];
if (isAni) {
CursorLoader.CursorImageData ciDat = new CursorLoader.CursorImageData();
int numIcons = 0;
int jiffy = 0;
// not using those but keeping references for now.
int steps = 0;
int width = 0;
int height = 0;
// we don't use that.
int flag = 0;
int[] rate = null;
int[] animSeq = null;
ArrayList<byte[]> icons;
DataInput leIn = new LittleEndien(inStream);
int riff = leIn.readInt();
if (riff == 0x46464952) {
// RIFF
// read next int (file length), discarding it, we don't need that.
leIn.readInt();
int nextInt = 0;
nextInt = getNext(leIn);
if (nextInt == 0x4e4f4341) {
// We have ACON, we do nothing
// System.out.println("We have ACON. Next!");
nextInt = getNext(leIn);
while (nextInt >= 0) {
if (nextInt == 0x68696e61) {
// System.out.println("we have 'anih' header");
// internal struct length (always 36)
leIn.skipBytes(8);
numIcons = leIn.readInt();
// number of blits for ani cycles
steps = leIn.readInt();
width = leIn.readInt();
height = leIn.readInt();
leIn.skipBytes(8);
jiffy = leIn.readInt();
flag = leIn.readInt();
nextInt = leIn.readInt();
} else if (nextInt == 0x65746172) {
// found a 'rate' of animation
// System.out.println("we have 'rate'.");
// Fill rate here.
// Rate is synchronous with frames.
int length = leIn.readInt();
rate = new int[length / 4];
for (int i = 0; i < length / 4; i++) {
rate[i] = leIn.readInt();
}
nextInt = leIn.readInt();
} else if (nextInt == 0x20716573) {
// found a 'seq ' of animation
// System.out.println("we have 'seq '.");
// Fill animation sequence here
int length = leIn.readInt();
animSeq = new int[length / 4];
for (int i = 0; i < length / 4; i++) {
animSeq[i] = leIn.readInt();
}
nextInt = leIn.readInt();
} else if (nextInt == 0x5453494c) {
// Found a LIST
// System.out.println("we have 'LIST'.");
int length = leIn.readInt();
nextInt = leIn.readInt();
if (nextInt == 0x4f464e49) {
// Got an INFO, skip its length
// this part consist of Author, title, etc
leIn.skipBytes(length - 4);
// System.out.println(" Discarding INFO (skipped = " + skipped + ")");
nextInt = leIn.readInt();
} else if (nextInt == 0x6d617266) {
// System.out.println("we have 'fram'.");
if (leIn.readInt() == 0x6e6f6369) {
// we have 'icon'
// We have an icon and from this point on
// the rest is only icons.
int icoLength = leIn.readInt();
ciDat.numImages = numIcons;
icons = new ArrayList<byte[]>(numIcons);
for (int i = 0; i < numIcons; i++) {
if (i > 0) {
// skip 'icon' header and length as they are
// known already and won't change.
leIn.skipBytes(8);
}
byte[] data = new byte[icoLength];
((InputStream) leIn).read(data, 0, icoLength);
// get it from first image.
if (width == 0 || height == 0 && i == 1) {
width = data[6];
height = data[7];
}
icons.add(data);
}
// at this point we have the icons, rates (either
// through jiffy or rate array, the sequence (if
// applicable) and the ani header info.
// Put things together.
ciDat.assembleCursor(icons, rate, animSeq, jiffy, steps, width, height);
ciDat.completeCursor();
nextInt = leIn.readInt();
// if for some reason there's JUNK (nextInt > -1)
// bail out.
nextInt = nextInt > -1 ? -1 : nextInt;
}
}
}
}
}
return setJmeCursor(ciDat);
} else if (riff == 0x58464952) {
throw new IllegalArgumentException("Big-Endian RIFX is not supported. Sorry.");
} else {
throw new IllegalArgumentException("Unknown format.");
}
} else if (isCur || isIco) {
DataInputStream in = new DataInputStream(inStream);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[16384];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
icoimages = out.toByteArray();
}
BufferedImage[] bi = parseICOImage(icoimages);
int hotSpotX = 0;
int hotSpotY = 0;
CursorLoader.CursorImageData cid = new CursorLoader.CursorImageData(bi, 0, hotSpotX, hotSpotY, 0);
if (isCur) {
/*
* Per http://msdn.microsoft.com/en-us/library/ms997538.aspx
* every .cur file should provide hotspot coordinates.
*/
hotSpotX = icoimages[FDE_OFFSET + 4] + icoimages[FDE_OFFSET + 5] * 255;
hotSpotY = icoimages[FDE_OFFSET + 6] + icoimages[FDE_OFFSET + 7] * 255;
cid.xHotSpot = hotSpotX;
/*
* Flip the Y-coordinate.
*/
cid.yHotSpot = cid.height - 1 - hotSpotY;
}
cid.completeCursor();
return setJmeCursor(cid);
}
use of com.jme3.util.LittleEndien in project jmonkeyengine by jMonkeyEngine.
the class RawHeightMap method load.
/**
* <code>load</code> fills the height data array with the appropriate data
* from the set RAW image. If the RAW image has not been set a JmeException
* will be thrown.
*
* @return true if the load is successfull, false otherwise.
*/
@Override
public boolean load() {
// confirm data has been set. Redundant check...
if (null == stream || size <= 0) {
throw new RuntimeException("Must supply valid stream and " + "size (> 0)");
}
// clean up
if (null != heightData) {
unloadHeightMap();
}
// initialize the height data attributes
heightData = new float[size * size];
// attempt to connect to the supplied file.
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(stream);
if (format == RawHeightMap.FORMAT_16BITLE) {
LittleEndien dis = new LittleEndien(bis);
int index;
// read the raw file
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (swapxy) {
index = i + j * size;
} else {
index = (i * size) + j;
}
heightData[index] = dis.readUnsignedShort();
}
}
dis.close();
} else {
DataInputStream dis = new DataInputStream(bis);
// read the raw file
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
int index;
if (swapxy) {
index = i + j * size;
} else {
index = (i * size) + j;
}
if (format == RawHeightMap.FORMAT_16BITBE) {
heightData[index] = dis.readUnsignedShort();
} else {
heightData[index] = dis.readUnsignedByte();
}
}
}
dis.close();
}
bis.close();
} catch (IOException e1) {
logger.warning("Error reading height data from stream.");
return false;
}
return true;
}
Aggregations