Package com.jogamp.opencl.demos.gamma

Source Code of com.jogamp.opencl.demos.gamma.CLSimpleGammaCorrection

/*
* 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, "gamma="+gamma);
           
            gamma = 1.5f;
            gammaCorrection(gamma, queue, kernel, buffer, localWorkSize, globalWorkSize);
            show(createImage(image.getWidth(), image.getHeight(), buffer), image.getWidth()/2*2, 50, "gamma="+gamma);
           
            gamma = 2.0f;
            gammaCorrection(gamma, queue, kernel, buffer, localWorkSize, globalWorkSize);
            show(createImage(image.getWidth(), image.getHeight(), buffer), image.getWidth()/2*3, 50, "gamma="+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;
        }
    }
   
}
TOP

Related Classes of com.jogamp.opencl.demos.gamma.CLSimpleGammaCorrection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.