1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| /**
* Load an image from file using the FreeImage Library
* @param context : OpenCL context
* @param filename: Absolute or relative path to the file containing the image
* @param width : Width of the image
* @param height : Height of the image
* @return : the loaded image object if success and 0 otherwise
*/
cl_mem LoadImage (const cl_context context, const char* filename, int& width, int& height)
{
FREE_IMAGE_FORMAT format = FreeImage_GetFileType (filename, 0);
FIBITMAP* image = FreeImage_Load (format, filename);
// Convert to 32-bit image
FIBITMAP* temp = image;
image = FreeImage_ConvertTo32Bits (image);
FreeImage_Unload (temp);
width = FreeImage_GetWidth (image);
height = FreeImage_GetHeight (image);
// Allocate a buffer containing 4 * width * height characters (one pixel will be coded with a 32-bit value <=> 8-bit for each of the four components R, G, B and A)
char* buffer = new char[width * height * 4];
memcpy (buffer, FreeImage_GetBits (image), width * height * 4);
FreeImage_Unload (image);
// Create OpenCL image
// Create a format that precise how the individual pixels of the image are laid out in memory
// and how the results will be interpreted when read inside of a kernel
cl_image_format clImageFormat;
clImageFormat.image_channel_order = CL_RGBA; // Four channels of image data that will be read into the R, G, B and A components in the kernel
clImageFormat.image_channel_data_type = CL_UNORM_INT8; // Each 8-bit integer value will be mapped to the range [0.0, 1.0]
cl_int err;
cl_mem clImage;
// Flag CL_MEM_COPY_HOST_PTR to specify that OpenCL must allocate memory for the memory object and copy the data from memory referenced by host_ptr argument
// (host_ptr is the last-but-one argument in the clCreateImage2D function)
// If the flag CL_MEM_COPY_HOST_PTR is set, there will be no need to use clEnqueueWriteImage (cl->get_commandQueueGPU (), cl_image_input, CL_TRUE, origin, region, 0, 0, buffer_, 0, NULL, NULL);
// at line 208
clImage = clCreateImage2D (context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &clImageFormat, width, height, 0, buffer, &err);
if (err != CL_SUCCESS)
{
if (err == CL_INVALID_CONTEXT)
cout << "Invalid context" << endl;
if (err == CL_INVALID_VALUE)
cout << "Invalid value" << endl;
if (err == CL_INVALID_IMAGE_FORMAT_DESCRIPTOR)
cout << "Invalid image format descriptor" << endl;
if (err == CL_INVALID_IMAGE_SIZE)
cout << "Invalid image size" << endl;
if (err == CL_INVALID_HOST_PTR)
cout << "Invalid host ptr" << endl;
if (err == CL_IMAGE_FORMAT_NOT_SUPPORTED)
cout << "Invalid image format not supported" << endl;
if (err == CL_MEM_OBJECT_ALLOCATION_FAILURE)
cout << "Invalid allocation failure" << endl;
if (err == CL_INVALID_OPERATION)
cout << "Invalid operation" << endl;
if (err == CL_OUT_OF_HOST_MEMORY)
cout << "OUT of host memeoru" << endl;
return NULL;
}
err_check (err, "Unable to create the input 2D image with clCreateImage2D from file " + (string)filename);
return clImage;
} |
Partager