/*
 * Raw_Processor_OpenCL.h
 *
 *  Created on: 19.10.2010
 *      Author: uwe
 */
#ifdef __OPENCL__

#ifndef RAW_PROCESSOR_OPENCL_H_
#define RAW_PROCESSOR_OPENCL_H_

#include <CL/cl.h>
#include <string.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include "Raw_Processor.h"

namespace MobilePhotoTool{

class Raw_Processor_OpenCL : public Raw_Processor{

private:
	/* The memory buffer that is used as input/output for OpenCL kernel */
	cl_mem	inputBuffer;
	cl_mem	outputBuffer;

	unsigned int num_of_ushort16;

	cl_mem	comp0, comp1, comp2;
	cl_mem  gamma_curve_cl;
	cl_mem	image_buffer;
	cl_mem	matrix_buffer_01;


	cl_context          context;
	cl_device_id        *devices;
	cl_command_queue    commandQueue;

	cl_program	program;

	cl_kernel	load_raw;
	cl_kernel	demosaik_bilienar_comp1;
	cl_kernel	demosaik_bilienar_comp2a;
	cl_kernel	demosaik_bilienar_comp2b;
	cl_kernel	demosaik_bilienar_comp0a;
	cl_kernel	demosaik_bilienar_comp0b;
	cl_kernel	gamma_correction;
	cl_kernel	write_to_imagebuffer;
	cl_kernel	matrix3x3_mul;

	cl_uint maxDims;
	cl_event events[2];
	size_t globalThreads[1];
	size_t localThreads[1];
	size_t maxWorkGroupSize;
	size_t maxWorkItemSizes[3];

	cl_uint raw_linestride;

	/**
	 * The buffersize for the uncompressed raw packed data
	 */
	unsigned int raw_buffersize;

	/**
	 * The raw and uncompressed raw packed data;
	 */
	unsigned char *data;

	unsigned int *temp_image;

private:

	/*
	 * Converts the contents of a file into a string
	 */
	std::string
	convertToString(const char *filename);

	/*
	 * \brief OpenCL related initialization
	 *        Create Context, Device list, Command Queue
	 *        Create OpenCL memory buffer objects
	 *        Load CL file, compile, link CL source
	 *		  Build program and kernel objects
	 */
	void initializeCL(MPT_Exception *exception);

	int cleanupCL(void);


protected:
	void createBuffer(MPT_Exception *exception);

public:

	/*
	 * Starts the OpenCL stuff platform, device ...
	 */
	Raw_Processor_OpenCL(MPT_Exception *exception, IFD *raw_ifd, IFD *ifd0);

	/**
	 * init special CPU GPU stuff.
	 */
	void init(MPT_Exception *exception);

	/**
	 *	Decode the raw Data and stores the components in the raw array.
	 */
	void loadRaw(MPT_Exception *exception, cl_command_queue *queue,cl_event *wait_ev, cl_event *fire_ev);

	/**
	 *
	 */
	void demosaik(MPT_Exception *exception, cl_command_queue *queue,cl_event *wait_ev, cl_event *fire_ev);

	/**
	 *
	 */
	void gamma(MPT_Exception *exception, cl_command_queue *queue,cl_event *wait_ev, cl_event *fire_ev);

	/**
	 *
	 */
	void get_image(	MPT_Exception *exception,
						cl_command_queue *queue,
						cl_event *wait_ev,
						cl_event *fire_ev);

	/*
	void get_image(	unsigned int *image,
						unsigned int linestride_image);
*/
	/**
	 *
	 */
	void basic_pipline(MPT_Exception *exception);

	void setup_temp_image(MPT_Exception *exception);

	void set_zoom(MPT_Exception *, float zoom, unsigned int size[2]);

	void get_zoom_image(	MPT_Exception *exception,
							unsigned int *data_out,
							unsigned int linestride,
							unsigned int width,
							unsigned int length,
							unsigned int out_x0,
							unsigned int out_y0,
							unsigned int in_x0,
							unsigned int in_y0);

	void matrix3x3_mul_01(	MPT_Exception *exception,
								cl_command_queue *queue,
								cl_event *wait_ev,
								cl_event *fire_ev,
								float *in_matrix);

};

}

#endif /* RAW_PROCESSOR_OPENCL_H_ */
#endif
