summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml7
-rw-r--r--nbproject/configs/Gamma.properties1
-rw-r--r--src/com/jogamp/opencl/demos/gamma/CLSimpleGammaCorrection.java178
-rw-r--r--src/com/jogamp/opencl/demos/gamma/Gamma.cl10
-rw-r--r--src/com/jogamp/opencl/demos/gamma/lena.pngbin0 -> 476248 bytes
5 files changed, 196 insertions, 0 deletions
diff --git a/build.xml b/build.xml
index 4c43ad7..0fb30d0 100644
--- a/build.xml
+++ b/build.xml
@@ -74,6 +74,13 @@
<param name="jnlp.jogl" value="false"/>
<param name="jnlp.mainclass" value="com.jogamp.opencl.demos.info.CLInfo"/>
</antcall>
+
+ <antcall target="create-jnlp" inheritrefs="true">
+ <param name="jnlp.name" value="gamma"/>
+ <param name="jnlp.title" value="Simple gamma correction."/>
+ <param name="jnlp.jogl" value="false"/>
+ <param name="jnlp.mainclass" value="com.jogamp.opencl.demos.gamma.CLSimpleGammaCorrection"/>
+ </antcall>
</target>
diff --git a/nbproject/configs/Gamma.properties b/nbproject/configs/Gamma.properties
new file mode 100644
index 0000000..fd191d4
--- /dev/null
+++ b/nbproject/configs/Gamma.properties
@@ -0,0 +1 @@
+main.class=com.jogamp.opencl.demos.gamma.CLSimpleGammaCorrection
diff --git a/src/com/jogamp/opencl/demos/gamma/CLSimpleGammaCorrection.java b/src/com/jogamp/opencl/demos/gamma/CLSimpleGammaCorrection.java
new file mode 100644
index 0000000..1845cbc
--- /dev/null
+++ b/src/com/jogamp/opencl/demos/gamma/CLSimpleGammaCorrection.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2009 - 2011 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+/*
+ * Created on Monday, December 13 2010 17:43
+ */
+
+package com.jogamp.opencl.demos.gamma;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.opencl.CLBuffer;
+import com.jogamp.opencl.CLCommandQueue;
+import com.jogamp.opencl.CLCommandQueue.Mode;
+import com.jogamp.opencl.CLContext;
+import com.jogamp.opencl.CLKernel;
+import com.jogamp.opencl.CLPlatform;
+import com.jogamp.opencl.CLProgram;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.FloatBuffer;
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+
+import static com.jogamp.opencl.CLProgram.*;
+
+/**
+ * Computes the classical gamma correction for a given image.
+ * http://en.wikipedia.org/wiki/Gamma_correction
+ * @author Michael Bien
+ */
+public class CLSimpleGammaCorrection {
+
+ private static InputStream getStreamFor(String filename) {
+ return CLSimpleGammaCorrection.class.getResourceAsStream(filename);
+ }
+
+ public static BufferedImage readImage(String filename) throws IOException {
+ return ImageIO.read(getStreamFor(filename));
+ }
+
+ private static BufferedImage createImage(int width, int height, CLBuffer<FloatBuffer> buffer) {
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ float[] pixels = new float[buffer.getBuffer().capacity()];
+ buffer.getBuffer().get(pixels).rewind();
+ image.getRaster().setPixels(0, 0, width, height, pixels);
+ return image;
+ }
+
+ public static void main(String[] args) throws IOException {
+
+ // find a CL implementation
+ CLPlatform platform = CLPlatform.getDefault(/*type(CPU)*/);
+
+ CLContext context = CLContext.create(platform.getMaxFlopsDevice());
+
+ try{
+ //load and compile program for the chosen device
+ CLProgram program = context.createProgram(getStreamFor("Gamma.cl"));
+ program.build(CompilerOptions.FAST_RELAXED_MATH);
+ assert program.isExecutable();
+
+ // load image
+ BufferedImage image = readImage("lena.png");
+ assert image.getColorModel().getNumComponents() == 3;
+
+ float[] pixels = image.getRaster().getPixels(0, 0, image.getWidth(), image.getHeight(), (float[])null);
+
+ // copy to direct float buffer
+ FloatBuffer fb = Buffers.newDirectFloatBuffer(pixels);
+
+ // allocate a OpenCL buffer using the direct fb as working copy
+ CLBuffer<FloatBuffer> buffer = context.createBuffer(fb, CLBuffer.Mem.READ_WRITE);
+
+ // creade a command queue with benchmarking flag set
+ CLCommandQueue queue = context.getDevices()[0].createCommandQueue(Mode.PROFILING_MODE);
+
+ int localWorkSize = queue.getDevice().getMaxWorkGroupSize(); // Local work size dimensions
+ int globalWorkSize = roundUp(localWorkSize, fb.capacity()); // rounded up to the nearest multiple of the localWorkSize
+
+ // create kernel and set function parameters
+ CLKernel kernel = program.createCLKernel("gamma");
+
+ // original lenna
+ show(image, 0, 50, "reference");
+
+ // a few gamma corrected versions
+ float gamma = 0.5f;
+ gammaCorrection(gamma, queue, kernel, buffer, localWorkSize, globalWorkSize);
+ show(createImage(image.getWidth(), image.getHeight(), buffer), image.getWidth()/2, 50, "corrected with gama="+gamma);
+
+ gamma = 1.5f;
+ gammaCorrection(gamma, queue, kernel, buffer, localWorkSize, globalWorkSize);
+ show(createImage(image.getWidth(), image.getHeight(), buffer), image.getWidth()/2*2, 50, "corrected with gama="+gamma);
+
+ gamma = 2.0f;
+ gammaCorrection(gamma, queue, kernel, buffer, localWorkSize, globalWorkSize);
+ show(createImage(image.getWidth(), image.getHeight(), buffer), image.getWidth()/2*3, 50, "corrected with gama="+gamma);
+
+ }finally{
+ context.release();
+ }
+
+ }
+
+ private static void gammaCorrection(float gamma, CLCommandQueue queue, CLKernel kernel, CLBuffer<FloatBuffer> buffer, int localWorkSize, int globalWorkSize) {
+
+ float scaleFactor = (float) Math.pow(255, 1.0f-gamma);
+
+ // setup kernel
+ kernel.putArg(buffer).putArg(gamma).putArg(scaleFactor).putArg(buffer.getNIOSize()).rewind();
+
+// CLEventList list = new CLEventList(1);
+
+ queue.putWriteBuffer(buffer, false); // upload image
+ queue.put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize/*, list*/); // execute program
+ queue.putReadBuffer(buffer, true); // read results back (blocking read)
+
+// CLEvent event = list.getEvent(0);
+// System.out.println((event.getProfilingInfo(END)
+// - event.getProfilingInfo(START))/1000000.0);
+//
+// long res = queue.getDevice().getProfilingTimerResolution();
+// System.out.println(res);
+
+ }
+
+ private static void show(final BufferedImage image, final int x, final int y, final String title) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ JFrame frame = new JFrame("gamma correction example ["+title+"]");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.add(new JLabel(new ImageIcon(image)));
+ frame.pack();
+ frame.setLocation(x, y);
+ frame.setVisible(true);
+ }
+ });
+ }
+
+ private static int roundUp(int groupSize, int globalSize) {
+ int r = globalSize % groupSize;
+ if (r == 0) {
+ return globalSize;
+ } else {
+ return globalSize + groupSize - r;
+ }
+ }
+
+}
diff --git a/src/com/jogamp/opencl/demos/gamma/Gamma.cl b/src/com/jogamp/opencl/demos/gamma/Gamma.cl
new file mode 100644
index 0000000..69b0618
--- /dev/null
+++ b/src/com/jogamp/opencl/demos/gamma/Gamma.cl
@@ -0,0 +1,10 @@
+ /**
+ * gamma correction kernel
+ */
+ kernel void gamma(global float* image, const float gamma, const float scale, const int max) {
+ int index = get_global_id(0);
+ if (index >= max) {
+ return;
+ }
+ image[index] = pow(image[index], gamma) * scale;
+ } \ No newline at end of file
diff --git a/src/com/jogamp/opencl/demos/gamma/lena.png b/src/com/jogamp/opencl/demos/gamma/lena.png
new file mode 100644
index 0000000..508a066
--- /dev/null
+++ b/src/com/jogamp/opencl/demos/gamma/lena.png
Binary files differ