From a54bd3e963a7be320dee0c9692d237607fcd0f96 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 1 Apr 2013 05:16:35 +0200 Subject: Fix Bug 671: Add JPEG Decoder w/o AWT Dependencies Original JavaScript code from , author 'notmasteryet' . Ported to Java. Enhancements: * InputStream instead of memory buffer * User provided memory handler * Fixed JPEG Component ID/Index mapping * Color space conversion (YCCK, CMYK -> RGB) * More error tolerant +++ Features: JOGL AWT RGB ok ok YCCK ok Exception CMYK ok Exception YUV Store ok n/a Need Y-Flip no yes +++ Benchmark: TestJPEGJoglAWTBenchmarkNewtAWT JOGL.RGB Loops 100, dt 1199 ms, 11.99 ms/l JOGL.YUV Loops 100, dt 351 ms, 3.51 ms/l AWT..... Loops 100, dt 2144 ms, 21.44 ms/l File: jogl/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/j1-baseline.jpg Machine: GNU/Linux PC (AMD 8 core), JavaSE 6 (1.6.0_38) .++++ UITestCase.setUp: com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTBenchmarkNewtAWT - benchmark libEGL warning: DRI2: failed to authenticate 0: JPEGImage[261x202, bytesPerPixel 3, reversedChannels false, JPEGPixels[261x202, sourceComp 3, sourceCS YCbCr, storageCS RGB, storageComp 3], java.nio.DirectByteBuffer[pos=0 lim=158166 cap=158166]] 0: TextureData[261x202, y-flip false, internFormat 0x1907, pixelFormat 0x1907, pixelType 0x1401, border 0, estSize 158166, alignment 1, rowlen 0, buffer java.nio.DirectByteBuffer[pos=0 lim=158166 cap=158166] JOGL.RGB Loops 100, dt 1199 ms, 11.99 ms/l 0: JPEGImage[261x202, bytesPerPixel 3, reversedChannels false, JPEGPixels[261x202, sourceComp 3, sourceCS YCbCr, storageCS YCbCr, storageComp 3], java.nio.DirectByteBuffer[pos=0 lim=158166 cap=158166]] 0: TextureData[261x202, y-flip false, internFormat 0x1907, pixelFormat 0x1907, pixelType 0x1401, border 0, estSize 158166, alignment 1, rowlen 0, buffer java.nio.DirectByteBuffer[pos=0 lim=158166 cap=158166] JOGL.YUV Loops 100, dt 351 ms, 3.51 ms/l 0: TextureData[261x202, y-flip true, internFormat 0x1907, pixelFormat 0x80e0, pixelType 0x1401, border 0, estSize 158166, alignment 1, rowlen 261, buffer java.nio.HeapByteBuffer[pos=0 lim=158166 cap=158166] AWT..... Loops 100, dt 2144 ms, 21.44 ms/l ++++ UITestCase.tearDown: com.jogamp.opengl.test.junit.jogl.util.texture.TestJPEGJoglAWTBenchmarkNewtAWT - benchmark --- .../jogl/util/texture/TestJPEGImage01NEWT.java | 124 ++++++++++ .../texture/TestJPEGJoglAWTBenchmarkNewtAWT.java | 152 ++++++++++++ .../texture/TestJPEGJoglAWTCompareNewtAWT.java | 267 +++++++++++++++++++++ .../util/texture/TestJPEGTextureFromFileNEWT.java | 264 ++++++++++++++++++++ .../test/junit/jogl/util/texture/j1-baseline.jpg | Bin 0 -> 21257 bytes .../junit/jogl/util/texture/j2-progressive.jpg | Bin 0 -> 22306 bytes .../junit/jogl/util/texture/j3-baseline_gray.jpg | Bin 0 -> 17776 bytes .../test/junit/jogl/util/texture/test-cmyk-01.jpg | Bin 0 -> 10445 bytes .../test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg | Bin 0 -> 2628 bytes .../test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg | Bin 0 -> 2376 bytes .../test-ntscN_3-01-160x90-90pct-yuv444-base.jpg | Bin 0 -> 4122 bytes .../test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg | Bin 0 -> 4411 bytes .../test/junit/jogl/util/texture/test-ycck-01.jpg | Bin 0 -> 62492 bytes 13 files changed, 807 insertions(+) create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTBenchmarkNewtAWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGJoglAWTCompareNewtAWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGTextureFromFileNEWT.java create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/j1-baseline.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/j2-progressive.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/j3-baseline_gray.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-cmyk-01.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscN_3-01-160x90-60pct-yuv422h-base.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscN_3-01-160x90-60pct-yuv422h-prog.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscN_3-01-160x90-90pct-yuv444-base.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ntscN_3-01-160x90-90pct-yuv444-prog.jpg create mode 100644 src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-ycck-01.jpg (limited to 'src/test/com') diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java new file mode 100644 index 000000000..37054afe6 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestJPEGImage01NEWT.java @@ -0,0 +1,124 @@ +package com.jogamp.opengl.test.junit.jogl.util.texture; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URLConnection; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLProfile; + +import org.junit.Assert; +import org.junit.Test; + +import com.jogamp.common.util.IOUtil; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.jogl.demos.TextureDraw01Accessor; +import com.jogamp.opengl.test.junit.jogl.demos.es2.TextureDraw01ES2Listener; +import com.jogamp.opengl.test.junit.util.MiscUtils; +import com.jogamp.opengl.test.junit.util.QuitAdapter; +import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.GLReadBufferUtil; +import com.jogamp.opengl.util.texture.TextureData; +import com.jogamp.opengl.util.texture.TextureIO; +import com.jogamp.opengl.util.texture.spi.JPEGImage; +import javax.media.opengl.GL; + +public class TestJPEGImage01NEWT extends UITestCase { + + static boolean showFPS = false; + static long duration = 100; // ms + + public void testImpl(final boolean withAlpha, final InputStream istream) throws InterruptedException, IOException { + final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); + final GLProfile glp = GLProfile.getGL2ES2(); + final GLCapabilities caps = new GLCapabilities(glp); + if( withAlpha ) { + caps.setAlphaBits(1); + } + + final JPEGImage image = JPEGImage.read(istream); + Assert.assertNotNull(image); + System.err.println("JPEGImage: "+image); + + final int internalFormat = (image.getBytesPerPixel()==4)?GL.GL_RGBA:GL.GL_RGB; + final TextureData texData = new TextureData(glp, internalFormat, + image.getWidth(), + image.getHeight(), + 0, + image.getGLFormat(), + image.getGLType(), + false /* mipmap */, + false /* compressed */, + false /* must flip-vert */, + image.getData(), + null); + // final TextureData texData = TextureIO.newTextureData(glp, istream, false /* mipmap */, TextureIO.JPG); + System.err.println("TextureData: "+texData); + + final GLWindow glad = GLWindow.create(caps); + glad.setTitle("TestJPEGImage01NEWT"); + // Size OpenGL to Video Surface + glad.setSize(texData.getWidth(), texData.getHeight()); + + // load texture from file inside current GL context to match the way + // the bug submitter was doing it + final GLEventListener gle = new TextureDraw01ES2Listener( texData ) ; + glad.addGLEventListener(gle); + glad.addGLEventListener(new GLEventListener() { + boolean shot = false; + + @Override public void init(GLAutoDrawable drawable) {} + + public void display(GLAutoDrawable drawable) { + // 1 snapshot + if(null!=((TextureDraw01Accessor)gle).getTexture() && !shot) { + shot = true; + snapshot(0, null, drawable.getGL(), screenshot, TextureIO.PNG, null); + } + } + + @Override public void dispose(GLAutoDrawable drawable) { } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } + }); + + Animator animator = new Animator(glad); + animator.setUpdateFPSFrames(60, showFPS ? System.err : null); + QuitAdapter quitAdapter = new QuitAdapter(); + glad.addKeyListener(quitAdapter); + glad.addWindowListener(quitAdapter); + glad.setVisible(true); + animator.start(); + + while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration() com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source) + } + + final GLReadBufferUtil screenshot = new GLReadBufferUtil(true, false); + final GLCapabilities caps = new GLCapabilities(glp); + caps.setAlphaBits(1); + + final GLWindow glad1 = GLWindow.create(caps); + glad1.setTitle("JPEG AWT"); + // Size OpenGL to Video Surface + glad1.setSize(w, h); + glad1.setPosition(xpos, 0); + + // load texture from file inside current GL context to match the way + // the bug submitter was doing it + final GLEventListener gle; + if( texData != null ) { + gle = new TextureDraw01ES2Listener( texData ) ; + glad1.addGLEventListener(gle); + } else { + gle = null; + } + glad1.addGLEventListener(new GLEventListener() { + boolean shot = false; + + @Override public void init(GLAutoDrawable drawable) {} + + public void display(GLAutoDrawable drawable) { + // 1 snapshot + if( null!=gle && null!=((TextureDraw01Accessor)gle).getTexture() && !shot) { + shot = true; + snapshot(0, "AWTJPEG", drawable.getGL(), screenshot, TextureIO.PNG, null); + } + } + + @Override public void dispose(GLAutoDrawable drawable) { } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } + }); + + return glad1; + } + + @Test + public void test01YUV444Base__ES2() throws InterruptedException, IOException { + testImpl(files[0]); + } + @Test + public void test01YUV444Prog__ES2() throws InterruptedException, IOException { + testImpl(files[1]); + } + + @Test + public void test01YUV422hBase__ES2() throws InterruptedException, IOException { + testImpl(files[2]); + } + @Test + public void test01YUV422hProg_ES2() throws InterruptedException, IOException { + testImpl(files[3]); + } + + @Test + public void test02YUV420Base__ES2() throws InterruptedException, IOException { + testImpl(files[4]); + } + @Test + public void test02YUV420Prog_ES2() throws InterruptedException, IOException { + testImpl(files[5]); + } + @Test + public void test02YUV420BaseGray_ES2() throws InterruptedException, IOException { + testImpl(files[6]); + } + + @Test + public void test03CMYK_01_ES2() throws InterruptedException, IOException { + testImpl(files[7]); + } + @Test + public void test03YCCK_01_ES2() throws InterruptedException, IOException { + testImpl(files[8]); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i