aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-06-18 03:42:13 +0200
committerSven Gothel <[email protected]>2012-06-18 03:42:13 +0200
commit6f5f8a8eb046689e49668dd4d82e48bc7cb341d7 (patch)
treeb6e12865432d1e1cf10cb36359d99b356fcda43d
parente8078eb70f6f82613d730ae5b8f837ccb46b81fb (diff)
TextureIO TGA/PNG: Use RGB[9] for 1-3 channel data; PNGImage(PNGJ) add 1 channel (Luminance) read/write
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java30
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java53
4 files changed, 65 insertions, 35 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index a94b1f827..49d4add5f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -907,12 +907,17 @@ public class Texture {
}
} else {
if (mustFlipVertically) {
- coords = new TextureCoords(0, (float) imgHeight / (float) texHeight,
- (float) imgWidth / (float) texWidth, 0);
+ coords = new TextureCoords(0, // l
+ (float) imgHeight / (float) texHeight, // b
+ (float) imgWidth / (float) texWidth, // r
+ 0 // t
+ );
} else {
- coords = new TextureCoords(0, 0,
- (float) imgWidth / (float) texWidth,
- (float) imgHeight / (float) texHeight);
+ coords = new TextureCoords(0, // l
+ 0, // b
+ (float) imgWidth / (float) texWidth, // r
+ (float) imgHeight / (float) texHeight // t
+ );
}
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
index 928f91ce5..96ee233fd 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java
@@ -355,7 +355,7 @@ public class TextureData {
}
public String toString() {
- return "TextureData["+width+"x"+height+", internFormat 0x"+Integer.toHexString(internalFormat)+", pixelFormat 0x"+Integer.toHexString(pixelFormat)+", pixelType 0x"+Integer.toHexString(pixelType)+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength;
+ return "TextureData["+width+"x"+height+", y-flip "+mustFlipVertically+", internFormat 0x"+Integer.toHexString(internalFormat)+", pixelFormat 0x"+Integer.toHexString(pixelFormat)+", pixelType 0x"+Integer.toHexString(pixelType)+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength;
}
//----------------------------------------------------------------------
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
index d72210016..ca97cdc4b 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureIO.java
@@ -1106,7 +1106,7 @@ public class TextureIO {
}
if (internalFormat == 0) {
if(glp.isGL2GL3()) {
- internalFormat = GL.GL_RGBA8;
+ internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA8:GL.GL_RGB8;
} else {
internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
}
@@ -1143,7 +1143,7 @@ public class TextureIO {
}
if (internalFormat == 0) {
if(glp.isGL2GL3()) {
- internalFormat = GL.GL_RGBA8;
+ internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA8:GL.GL_RGB8;
} else {
internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB;
}
@@ -1153,7 +1153,7 @@ public class TextureIO {
image.getHeight(),
0,
pixelFormat,
- GL.GL_UNSIGNED_BYTE,
+ image.getGLType(),
mipmap,
false,
false,
@@ -1183,13 +1183,13 @@ public class TextureIO {
int d3dFormat = 0;
// FIXME: some of these are probably not completely correct and would require swizzling
switch (pixelFormat) {
- case GL.GL_RGB: d3dFormat = DDSImage.D3DFMT_R8G8B8; break;
- case GL.GL_RGBA: d3dFormat = DDSImage.D3DFMT_A8R8G8B8; break;
- case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: d3dFormat = DDSImage.D3DFMT_DXT1; break;
- case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: throw new IOException("RGBA DXT1 not yet supported");
- case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: d3dFormat = DDSImage.D3DFMT_DXT3; break;
- case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: d3dFormat = DDSImage.D3DFMT_DXT5; break;
- default: throw new IOException("Unsupported pixel format 0x" + Integer.toHexString(pixelFormat) + " by DDS writer");
+ case GL.GL_RGB: d3dFormat = DDSImage.D3DFMT_R8G8B8; break;
+ case GL.GL_RGBA: d3dFormat = DDSImage.D3DFMT_A8R8G8B8; break;
+ case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: d3dFormat = DDSImage.D3DFMT_DXT1; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: throw new IOException("RGBA DXT1 not yet supported");
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: d3dFormat = DDSImage.D3DFMT_DXT3; break;
+ case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: d3dFormat = DDSImage.D3DFMT_DXT5; break;
+ default: throw new IOException("Unsupported pixel format 0x" + Integer.toHexString(pixelFormat) + " by DDS writer");
}
ByteBuffer[] mipmaps = null;
@@ -1319,6 +1319,10 @@ public class TextureIO {
boolean reversedChannels;
int bytesPerPixel;
switch(pixelFormat) {
+ case GL.GL_LUMINANCE:
+ reversedChannels=false;
+ bytesPerPixel=1;
+ break;
case GL.GL_RGB:
reversedChannels=false;
bytesPerPixel=3;
@@ -1340,10 +1344,8 @@ public class TextureIO {
bytesPerPixel=-1;
break;
}
- if ( 1 < bytesPerPixel &&
- (pixelType == GL.GL_BYTE ||
- pixelType == GL.GL_UNSIGNED_BYTE)) {
-
+ if ( ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel) &&
+ ( pixelType == GL.GL_BYTE || pixelType == GL.GL_UNSIGNED_BYTE)) {
ByteBuffer buf = (ByteBuffer) data.getBuffer();
if (null == buf) {
buf = (ByteBuffer) data.getMipmapData()[0];
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
index a89418f84..d8d6f7daa 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java
@@ -23,7 +23,7 @@ import com.jogamp.common.util.IOUtil;
public class PNGImage {
/** Creates a PNGImage from data supplied by the end user. Shares
data with the passed ByteBuffer. Assumes the data is already in
- the correct byte order for writing to disk, i.e., RGB or RGBA bottom-to-top (OpenGL coord). */
+ the correct byte order for writing to disk, i.e., LUMINANCE, RGB or RGBA bottom-to-top (OpenGL coord). */
public static PNGImage createFromData(int width, int height, double dpiX, double dpiY,
int bytesPerPixel, boolean reversedChannels, ByteBuffer data) {
return new PNGImage(width, height, dpiX, dpiY, bytesPerPixel, reversedChannels, data);
@@ -44,7 +44,7 @@ public class PNGImage {
d.put(dOff--, (byte)line.scanline[lineOff ]); // R
return dOff;
}
- /** Reverse read and store, implicitly flip image from GL coords. */
+ /** Reverse read and store, implicitly flip image from GL coords. Handle reversed channels (BGR[A])*/
private static int setPixelRGBA8(ImageLine line, int lineOff, ByteBuffer d, int dOff, boolean hasAlpha, boolean reversedChannels) {
if(reversedChannels) {
line.scanline[lineOff ] = d.get(dOff--); // R, A
@@ -83,12 +83,15 @@ public class PNGImage {
private PNGImage(InputStream in) {
final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
final int channels = pngr.imgInfo.channels;
- if (3 > channels || channels > 4 ) {
- throw new RuntimeException("PNGImage can only handle RGB/RGBA images for now. Channels "+channels);
+ if ( ! ( 1 == channels || 3 == channels || 4 == channels ) ) {
+ throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 channels] images for now. Channels "+channels);
}
bytesPerPixel=pngr.imgInfo.bytesPixel;
- if (3 > bytesPerPixel || bytesPerPixel > 4 ) {
- throw new RuntimeException("PNGImage can only handle RGB/RGBA images for now. BytesPerPixel "+bytesPerPixel);
+ if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel ) ) {
+ throw new RuntimeException("PNGImage can only handle Lum/RGB/RGBA [1/3/4 bpp] images for now. BytesPerPixel "+bytesPerPixel);
+ }
+ if(channels != bytesPerPixel) {
+ throw new RuntimeException("PNGImage currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel);
}
pixelWidth=pngr.imgInfo.cols;
pixelHeight=pngr.imgInfo.rows;
@@ -97,18 +100,29 @@ public class PNGImage {
final double[] dpi2 = pngr.getMetadata().getDpi();
dpi[0]=dpi2[0];
dpi[1]=dpi2[1];
- }
- glFormat= ( 4 == bytesPerPixel ) ? GL.GL_RGBA : GL.GL_RGB;
+ }
+ switch(channels) {
+ case 1: glFormat = GL.GL_LUMINANCE; break;
+ case 3: glFormat = GL.GL_RGB; break;
+ case 4: glFormat = GL.GL_RGBA; break;
+ default: throw new InternalError("XXX: channels: "+channels+", bytesPerPixel "+bytesPerPixel);
+ }
data = Buffers.newDirectByteBuffer(bytesPerPixel * pixelWidth * pixelHeight);
reversedChannels = false; // RGB[A]
- final boolean hasAlpha = 4 == bytesPerPixel;
+ final boolean hasAlpha = 4 == channels;
int dataOff = bytesPerPixel * pixelWidth * pixelHeight - 1; // start at end-of-buffer, reverse store
for (int row = 0; row < pixelHeight; row++) {
final ImageLine l1 = pngr.readRow(row);
int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse read
- for (int j = pixelWidth - 1; j >= 0; j--) {
- dataOff = getPixelRGBA8(data, dataOff, l1, lineOff, hasAlpha);
- lineOff -= bytesPerPixel;
+ if(1 == channels) {
+ for (int j = pixelWidth - 1; j >= 0; j--) {
+ data.put(dataOff--, (byte)l1.scanline[lineOff--]); // Luminance, 1 bytesPerPixel
+ }
+ } else {
+ for (int j = pixelWidth - 1; j >= 0; j--) {
+ dataOff = getPixelRGBA8(data, dataOff, l1, lineOff, hasAlpha);
+ lineOff -= bytesPerPixel;
+ }
}
}
pngr.end();
@@ -132,6 +146,9 @@ public class PNGImage {
/** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */
public int getGLFormat() { return glFormat; }
+
+ /** Returns the OpenGL data type: GL.GL_UNSIGNED_BYTE. */
+ public int getGLType() { return GL.GL_UNSIGNED_BYTE; }
/** Returns the bytes per pixel */
public int getBytesPerPixel() { return bytesPerPixel; }
@@ -156,9 +173,15 @@ public class PNGImage {
int dataOff = bytesPerPixel * pixelWidth * pixelHeight - 1; // start at end-of-buffer, reverse read
for (int row = 0; row < pixelHeight; row++) {
int lineOff = ( pixelWidth - 1 ) * bytesPerPixel ; // start w/ last pixel in line, reverse store
- for (int j = pixelWidth - 1; j >= 0; j--) {
- dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha, reversedChannels);
- lineOff -= bytesPerPixel;
+ if(1 == bytesPerPixel) {
+ for (int j = pixelWidth - 1; j >= 0; j--) {
+ l1.scanline[lineOff--] = data.get(dataOff--); // // Luminance, 1 bytesPerPixel
+ }
+ } else {
+ for (int j = pixelWidth - 1; j >= 0; j--) {
+ dataOff = setPixelRGBA8(l1, lineOff, data, dataOff, hasAlpha, reversedChannels);
+ lineOff -= bytesPerPixel;
+ }
}
png.writeRow(l1, row);
}