|
|
|
@ -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()); |
|
|
|
|
} |
|
|
|
|