diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/AWTPixelInputOutput.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/AWTPixelInputOutput.java index d075f9c05..679be91dc 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/AWTPixelInputOutput.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/AWTPixelInputOutput.java @@ -2,6 +2,9 @@ package com.jme3.scene.plugins.blender.textures.io; import java.nio.ByteBuffer; +import jme3tools.converters.RGB565; + +import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.textures.TexturePixel; import com.jme3.texture.Image; @@ -11,31 +14,63 @@ import com.jme3.texture.Image; */ /*package*/ class AWTPixelInputOutput implements PixelInputOutput { public void read(Image image, int layer, TexturePixel pixel, int index) { - byte r,g,b,a; ByteBuffer data = image.getData(layer); - switch(image.getFormat()) {//TODO: add other formats + switch(image.getFormat()) { case RGBA8: - r = data.get(index); - g = data.get(index + 1); - b = data.get(index + 2); - a = data.get(index + 3); + pixel.fromARGB8(data.get(index + 3), data.get(index), data.get(index + 1), data.get(index + 2)); break; case ABGR8: - a = data.get(index); - b = data.get(index + 1); - g = data.get(index + 2); - r = data.get(index + 3); + pixel.fromARGB8(data.get(index), data.get(index + 3), data.get(index + 2), data.get(index + 1)); break; case BGR8: - b = data.get(index); - g = data.get(index + 1); - r = data.get(index + 2); - a = (byte)0xFF; + pixel.fromARGB8((byte)0xFF, data.get(index + 2), data.get(index + 1), data.get(index)); + break; + case RGB8: + pixel.fromARGB8((byte)0xFF, data.get(index), data.get(index + 1), data.get(index + 2)); + break; + case RGB565: + pixel.fromARGB8(RGB565.RGB565_to_ARGB8(data.getShort(index))); + break; + case RGB5A1: + short rgb5a1 = data.getShort(index); + byte a = (byte) (rgb5a1 & 0x01); + int r = (rgb5a1 & 0xf800) >> 11 << 3; + int g = (rgb5a1 & 0x07c0) >> 6 << 3; + int b = (rgb5a1 & 0x001f) >> 1 << 3; + pixel.fromARGB8(a == 1 ? (byte)255 : 0, (byte)r, (byte)g, (byte)b); + break; + case RGB16: + pixel.fromARGB16((short)0xFFFF, data.getShort(index), data.getShort(index + 2), data.getShort(index + 4)); break; + case RGBA16: + pixel.fromARGB16(data.getShort(index + 6), data.getShort(index), data.getShort(index + 2), data.getShort(index + 4)); + break; + case RGB16F: + case RGB16F_to_RGB111110F: + case RGB16F_to_RGB9E5: + pixel.fromARGB(1, FastMath.convertHalfToFloat(data.getShort(index)), + FastMath.convertHalfToFloat(data.getShort(index + 2)), + FastMath.convertHalfToFloat(data.getShort(index + 4))); + break; + case RGBA16F: + pixel.fromARGB(FastMath.convertHalfToFloat(data.getShort(index + 6)), FastMath.convertHalfToFloat(data.getShort(index)), + FastMath.convertHalfToFloat(data.getShort(index + 2)), FastMath.convertHalfToFloat(data.getShort(index + 4))); + break; + case RGBA32F: + pixel.fromARGB(Float.intBitsToFloat(data.getInt(index + 12)), Float.intBitsToFloat(data.getInt(index)), + Float.intBitsToFloat(data.getInt(index + 4)), Float.intBitsToFloat(data.getInt(index + 8))); + break; + case RGB111110F://the data is stored as 32-bit unsigned int, that is why we cast the read data to long and remove MSB-bytes to get the positive value + pixel.fromARGB(1, (float)Double.longBitsToDouble((long)data.getInt(index) & 0x00000000FFFFFFFF), + (float)Double.longBitsToDouble((long)data.getInt(index + 4) & 0x00000000FFFFFFFF), + (float)Double.longBitsToDouble((long)data.getInt(index + 8) & 0x00000000FFFFFFFF)); + break; + case RGB10: + case RGB9E5://TODO: support these + throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat()); default: throw new IllegalStateException("Unknown image format: " + image.getFormat()); } - pixel.fromARGB8(a, r, g, b); } public void read(Image image, int layer, TexturePixel pixel, int x, int y) { @@ -63,6 +98,61 @@ import com.jme3.texture.Image; data.put(index + 1, pixel.getG8()); data.put(index + 2, pixel.getR8()); break; + case RGB8: + data.put(index, pixel.getR8()); + data.put(index + 1, pixel.getG8()); + data.put(index + 2, pixel.getB8()); + break; + case RGB565: + data.putShort(RGB565.ARGB8_to_RGB565(pixel.toARGB8())); + break; + case RGB5A1: + int argb8 = pixel.toARGB8(); + short r = (short) ((argb8 & 0x00F80000) >> 8); + short g = (short) ((argb8 & 0x0000F800) >> 5); + short b = (short) ((argb8 & 0x000000F8) >> 2); + short a = (short) ((short) ((argb8 & 0xFF000000) >> 24) > 0 ? 1 : 0); + data.putShort(index, (short) (r | g | b | a)); + break; + case RGB16: + data.putShort(index, pixel.getR16()); + data.putShort(index + 2, pixel.getG16()); + data.putShort(index + 4, pixel.getB16()); + break; + case RGBA16: + data.putShort(index, pixel.getR16()); + data.putShort(index + 2, pixel.getG16()); + data.putShort(index + 4, pixel.getB16()); + data.putShort(index + 6, pixel.getA16()); + break; + case RGB16F: + case RGB16F_to_RGB111110F: + case RGB16F_to_RGB9E5: + data.putShort(index, FastMath.convertFloatToHalf(pixel.red)); + data.putShort(index + 2, FastMath.convertFloatToHalf(pixel.green)); + data.putShort(index + 4, FastMath.convertFloatToHalf(pixel.blue)); + break; + case RGBA16F: + data.putShort(index, FastMath.convertFloatToHalf(pixel.red)); + data.putShort(index + 2, FastMath.convertFloatToHalf(pixel.green)); + data.putShort(index + 4, FastMath.convertFloatToHalf(pixel.blue)); + data.putShort(index + 6, FastMath.convertFloatToHalf(pixel.blue)); + break; + case RGB32F: + case RGB111110F://this data is stored as 32-bit unsigned int + data.putInt(index, Float.floatToIntBits(pixel.red)); + data.putInt(index + 2, Float.floatToIntBits(pixel.green)); + data.putInt(index + 4, Float.floatToIntBits(pixel.blue)); + break; + case RGBA32F: + data.putInt(index, Float.floatToIntBits(pixel.red)); + data.putInt(index + 2, Float.floatToIntBits(pixel.green)); + data.putInt(index + 4, Float.floatToIntBits(pixel.blue)); + data.putInt(index + 6, Float.floatToIntBits(pixel.alpha)); + break; + case RGB10: + case RGB9E5://TODO: support these + throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat()); default: throw new IllegalStateException("Unknown image format: " + image.getFormat()); } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/LuminancePixelInputOutput.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/LuminancePixelInputOutput.java index 7529e9164..5afe4adaf 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/LuminancePixelInputOutput.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/io/LuminancePixelInputOutput.java @@ -2,6 +2,7 @@ package com.jme3.scene.plugins.blender.textures.io; import java.nio.ByteBuffer; +import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.textures.TexturePixel; import com.jme3.texture.Image; @@ -29,11 +30,11 @@ import com.jme3.texture.Image; pixel.setAlpha(data.getShort(index + 2)); break; case Luminance16F: - pixel.intensity = Float.intBitsToFloat(data.getShort(index)); + pixel.intensity = FastMath.convertHalfToFloat(data.getShort(index)); break; case Luminance16FAlpha16F: - pixel.intensity = Float.intBitsToFloat(data.getShort(index)); - pixel.alpha = Float.intBitsToFloat(data.getShort(index + 2)); + pixel.intensity = FastMath.convertHalfToFloat(data.getShort(index)); + pixel.alpha = FastMath.convertHalfToFloat(data.getShort(index + 2)); break; case Luminance32F: pixel.intensity = Float.intBitsToFloat(data.getInt(index)); @@ -67,11 +68,11 @@ import com.jme3.texture.Image; data.putShort(index + 2, (short) (pixel.alpha * 65535.0f)); break; case Luminance16F: - pixel.intensity = Float.intBitsToFloat(data.getShort(index)); + data.putShort(index, FastMath.convertFloatToHalf(pixel.intensity)); break; case Luminance16FAlpha16F: - pixel.intensity = Float.intBitsToFloat(data.getShort(index)); - pixel.alpha = Float.intBitsToFloat(data.getShort(index + 2)); + data.putShort(index, FastMath.convertFloatToHalf(pixel.intensity)); + data.putShort(index + 2, FastMath.convertFloatToHalf(pixel.alpha)); break; case Luminance32F: data.putInt(index, Float.floatToIntBits(pixel.intensity));