summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Gouesse <[email protected]>2013-03-20 02:50:28 +0100
committerSven Gothel <[email protected]>2013-03-20 02:50:28 +0100
commit6d85470b2cb58670fd326b66ccbb396e24139014 (patch)
treed88ced43eab04210b0370126a387154b80518a21
parent1a1557cd9e31bd7975d858b7b2d49e586805bba4 (diff)
Handles indexed PNGs
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/PNGImage.java70
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java68
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP301-160x90.pngbin0 -> 1898 bytes
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP401-160x90.pngbin0 -> 1911 bytes
4 files changed, 117 insertions, 21 deletions
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 d9be4ce31..464cc8ec3 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
@@ -12,8 +12,11 @@ import javax.media.opengl.GL;
import jogamp.opengl.util.pngj.ImageInfo;
import jogamp.opengl.util.pngj.ImageLine;
+import jogamp.opengl.util.pngj.ImageLineHelper;
import jogamp.opengl.util.pngj.PngReader;
import jogamp.opengl.util.pngj.PngWriter;
+import jogamp.opengl.util.pngj.chunks.PngChunkPLTE;
+import jogamp.opengl.util.pngj.chunks.PngChunkTRNS;
import jogamp.opengl.util.pngj.chunks.PngChunkTextVar;
import com.jogamp.common.nio.Buffers;
@@ -35,15 +38,24 @@ public class PNGImage {
}
/** Reverse read and store, implicitly flip image to GL coords. */
- private static final int getPixelRGBA8(ByteBuffer d, int dOff, ImageLine line, int lineOff, boolean hasAlpha) {
- if(hasAlpha) {
- d.put(dOff--, (byte)line.scanline[lineOff + 3]); // A
+ private static final int getPixelRGBA8Unindexed(ByteBuffer d, int dOff, ImageLine line, int lineOff, boolean hasAlpha) {
+ dOff = getPixelRG8Common(d, dOff, line.scanline, lineOff, hasAlpha);
+ return dOff;
+ }
+ private static final int getPixelRGBA8Indexed(ByteBuffer d, int dOff, ImageLine line, int lineOff, boolean hasAlpha, PngChunkPLTE plte, PngChunkTRNS trns) {
+ final int[] scanline = ImageLineHelper.palette2rgb(line, plte, trns, null);
+ dOff = getPixelRG8Common(d, dOff, scanline, lineOff, hasAlpha);
+ return dOff;
+ }
+ private static final int getPixelRG8Common(ByteBuffer d, int dOff, int[] scanline, int lineOff, boolean hasAlpha) {
+ if(hasAlpha) {
+ d.put(dOff--, (byte)scanline[lineOff + 3]); // A
}
- d.put(dOff--, (byte)line.scanline[lineOff + 2]); // B
- d.put(dOff--, (byte)line.scanline[lineOff + 1]); // G
- d.put(dOff--, (byte)line.scanline[lineOff ]); // R
+ d.put(dOff--, (byte)scanline[lineOff + 2]); // B
+ d.put(dOff--, (byte)scanline[lineOff + 1]); // G
+ d.put(dOff--, (byte)scanline[lineOff ]); // R
return dOff;
- }
+ }
/** 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) {
@@ -82,15 +94,19 @@ public class PNGImage {
private PNGImage(InputStream in) {
final PngReader pngr = new PngReader(new BufferedInputStream(in), null);
- final int channels = pngr.imgInfo.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);
+ final ImageInfo imgInfo = pngr.imgInfo;
+ final PngChunkPLTE plte = pngr.getMetadata().getPLTE();
+ final PngChunkTRNS trns = pngr.getMetadata().getTRNS();
+ final boolean hasAlpha = (imgInfo.indexed) ? (trns != null) : imgInfo.alpha;
+ final int channels = imgInfo.channels;
+ if ( ! ( imgInfo.indexed || 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 + " Paletted: " + imgInfo.indexed);
}
- bytesPerPixel=pngr.imgInfo.bytesPixel;
- if ( ! ( 1 == bytesPerPixel || 3 == bytesPerPixel || 4 == bytesPerPixel ) ) {
+ bytesPerPixel=imgInfo.indexed?(hasAlpha?4:3):pngr.imgInfo.bytesPixel;
+ if ( ! ( imgInfo.indexed || 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) {
+ if(channels != bytesPerPixel && !imgInfo.indexed) {
throw new RuntimeException("PNGImage currently only handles Channels [1/3/4] == BytePerPixel [1/3/4], channels: "+channels+", bytesPerPixel "+bytesPerPixel);
}
pixelWidth=pngr.imgInfo.cols;
@@ -101,26 +117,38 @@ public class PNGImage {
dpi[0]=dpi2[0];
dpi[1]=dpi2[1];
}
- 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);
+ if (imgInfo.indexed) {
+ if (hasAlpha) {
+ glFormat = GL.GL_RGBA;
+ } else {
+ glFormat = GL.GL_RGB;
+ }
+ } else {
+ 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 == 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
- if(1 == channels) {
+ if(1 == channels && !imgInfo.indexed) {
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);
+ if (imgInfo.indexed) {
+ dataOff = getPixelRGBA8Indexed(data, dataOff, l1, lineOff, hasAlpha, plte, trns);
+ } else {
+ dataOff = getPixelRGBA8Unindexed(data, dataOff, l1, lineOff, hasAlpha);
+ }
lineOff -= bytesPerPixel;
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
index fe21f86a9..15a0eec50 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestPNGTextureFromFileNEWT.java
@@ -64,6 +64,10 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
InputStream testTextureStreamN;
InputStream testTextureStreamI;
InputStream testTextureStreamIG;
+ InputStream testTextureStreamPRGB;
+ InputStream testTextureStreamPRGBA;/*
+ InputStream testTextureStreamNRGBA;
+ InputStream testTextureStreamIRGBA;*/
@Before
public void initTest() throws IOException {
@@ -87,6 +91,30 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
testTextureStreamIG = testTextureUrlConn.getInputStream();
Assert.assertNotNull(testTextureStreamIG);
}
+ {
+ URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscP301-160x90.png");
+ Assert.assertNotNull(testTextureUrlConn);
+ testTextureStreamPRGB = testTextureUrlConn.getInputStream();
+ Assert.assertNotNull(testTextureStreamPRGB);
+ }
+ {
+ URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscP401-160x90.png");
+ Assert.assertNotNull(testTextureUrlConn);
+ testTextureStreamPRGBA = testTextureUrlConn.getInputStream();
+ Assert.assertNotNull(testTextureStreamPRGBA);
+ }
+ /*{
+ URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscN401-160x90.png");
+ Assert.assertNotNull(testTextureUrlConn);
+ testTextureStreamNRGBA = testTextureUrlConn.getInputStream();
+ Assert.assertNotNull(testTextureStreamNRGBA);
+ }
+ {
+ URLConnection testTextureUrlConn = IOUtil.getResource(this.getClass(), "test-ntscI401-160x90.png");
+ Assert.assertNotNull(testTextureUrlConn);
+ testTextureStreamIRGBA = testTextureUrlConn.getInputStream();
+ Assert.assertNotNull(testTextureStreamIRGBA);
+ }*/
}
@After
@@ -95,6 +123,10 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
testTextureStreamN = null;
testTextureStreamI = null;
testTextureStreamIG = null;
+ testTextureStreamPRGB = null;
+ testTextureStreamPRGBA = null;/*
+ testTextureStreamNRGBA = null;
+ testTextureStreamIRGBA = null;*/
}
public void testImpl(boolean useFFP, final InputStream istream) throws InterruptedException, IOException {
@@ -190,6 +222,42 @@ public class TestPNGTextureFromFileNEWT extends UITestCase {
testImpl(false, testTextureStreamIG);
}
+ @Test
+ public void testTestPRGB_PNGJLoaderGL2() throws InterruptedException, IOException {
+ testImpl(true, testTextureStreamPRGB);
+ }
+ @Test
+ public void testTestPRGB_PNGJLoaderES2() throws InterruptedException, IOException {
+ testImpl(false, testTextureStreamPRGB);
+ }
+
+ @Test
+ public void testTestPRGBA_PNGJLoaderGL2() throws InterruptedException, IOException {
+ testImpl(true, testTextureStreamPRGBA);
+ }
+ @Test
+ public void testTestPRGBA_PNGJLoaderES2() throws InterruptedException, IOException {
+ testImpl(false, testTextureStreamPRGBA);
+ }
+
+ /*@Test
+ public void testTestNRGBA_PNGJLoaderGL2() throws InterruptedException, IOException {
+ testImpl(true, testTextureStreamNRGBA);
+ }
+ @Test
+ public void testTestNRGBA_PNGJLoaderES2() throws InterruptedException, IOException {
+ testImpl(false, testTextureStreamNRGBA);
+ }
+
+ @Test
+ public void testTestIRGBA_PNGJLoaderGL2() throws InterruptedException, IOException {
+ testImpl(true, testTextureStreamIRGBA);
+ }
+ @Test
+ public void testTestIRGBA_PNGJLoaderES2() throws InterruptedException, IOException {
+ testImpl(false, testTextureStreamIRGBA);
+ }*/
+
public static void main(String args[]) throws IOException {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP301-160x90.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP301-160x90.png
new file mode 100644
index 000000000..32e7f0042
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP301-160x90.png
Binary files differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP401-160x90.png b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP401-160x90.png
new file mode 100644
index 000000000..55405ee89
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscP401-160x90.png
Binary files differ