211 lines
6.1 KiB
C
211 lines
6.1 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include "stb/stb_image.h"
|
|
#include "stb/stb_image_write.h"
|
|
#include "utils.h"
|
|
|
|
Matrixd matrixd_create(uint32_t w, uint32_t h)
|
|
{
|
|
Matrixd ret;
|
|
ret.w = w;
|
|
ret.h = h;
|
|
ret.buf = calloc(w * h, sizeof(double));
|
|
|
|
return ret;
|
|
}
|
|
|
|
size_t matrixd_size(Matrixd *m)
|
|
{
|
|
return m->w * m->h;
|
|
}
|
|
|
|
void matrixd_print(Matrixd *m)
|
|
{
|
|
assert(m);
|
|
|
|
for (size_t i = 0; i < m->w; i++) {
|
|
for (size_t j = 0; j < m->h; j++) {
|
|
printf("%f ", m->buf[i * m->h + j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
Matrixp matrixp_create(uint32_t w, uint32_t h)
|
|
{
|
|
Matrixp ret;
|
|
ret.w = w;
|
|
ret.h = h;
|
|
ret.buf = calloc(w * h, sizeof(Pixel));
|
|
|
|
return ret;
|
|
}
|
|
|
|
Matrixp matrixp_create_from_file(const char *filename)
|
|
{
|
|
Matrixp matrix = (Matrixp) { 0 };
|
|
|
|
if (!filename)
|
|
return matrix;
|
|
|
|
int x, y, channels;
|
|
uint8_t *ret_ptr = stbi_load(filename, &x, &y, &channels, 3);
|
|
matrix.w = x;
|
|
matrix.h = y;
|
|
matrix.buf = calloc(matrix.w * matrix.h, sizeof(Pixel));
|
|
memcpy(matrix.buf, ret_ptr, x * y * sizeof(Pixel));
|
|
stbi_image_free(ret_ptr);
|
|
|
|
return matrix;
|
|
}
|
|
|
|
Matrixu8 matrixu8_create_from_file(const char *filename)
|
|
{
|
|
Matrixu8 matrix = (Matrixu8) { 0 };
|
|
|
|
if (!filename)
|
|
return matrix;
|
|
|
|
int x, y, channels;
|
|
uint8_t *ret_ptr = stbi_load(filename, &x, &y, &channels, 4);
|
|
printf("%s return channels: %d\n", __func__, channels);
|
|
matrix.w = x;
|
|
matrix.h = y;
|
|
matrix.buf = calloc(matrix.w * matrix.h * 4, 1);
|
|
memcpy(matrix.buf, ret_ptr, x * y * 4);
|
|
stbi_image_free(ret_ptr);
|
|
|
|
return matrix;
|
|
}
|
|
|
|
void matrixu8_write_to_bmp(Matrixu8 *matrix, const char *filename)
|
|
{
|
|
assert(matrix);
|
|
assert(filename);
|
|
|
|
stbi_write_bmp(filename, matrix->w, matrix->h, 4, matrix->buf);
|
|
}
|
|
|
|
size_t matrixu8_size(Matrixu8* m)
|
|
{
|
|
return m->w * m->h;
|
|
}
|
|
|
|
size_t matrixp_size(Matrixp* m)
|
|
{
|
|
return m->w * m->h;
|
|
}
|
|
|
|
Matrixd gauss_filter_create(uint32_t size, double sigma)
|
|
{
|
|
Matrixd ret = matrixd_create(size, size);
|
|
|
|
size_t _i, _j, index;
|
|
|
|
double k = (size - 1.0) / 2.0;
|
|
double sigma2 = sigma * sigma;
|
|
double pi_part = 1 / (2.0 * M_PI * sigma2);
|
|
double sum = 0;
|
|
|
|
for (_i = 0; _i < size; _i++)
|
|
for (_j = 0; _j < size; _j++) {
|
|
index = _i * size + _j;
|
|
|
|
double i = _i + 1;
|
|
double j = _j + 1;
|
|
|
|
double exp_numerator_1 = pow(i - (k + 1), 2);
|
|
double exp_numerator_2 = pow(j - (k + 1), 2);
|
|
double exp_denominator = 2 * sigma2;
|
|
double _exp = exp(-(exp_numerator_1 + exp_numerator_2) / exp_denominator);
|
|
|
|
ret.buf[index] = pi_part * _exp;
|
|
sum += ret.buf[index];
|
|
}
|
|
|
|
for (_i = 0; _i < size; _i++)
|
|
for (_j = 0; _j < size; _j++) {
|
|
index = _i * size + _j;
|
|
ret.buf[index] /= sum;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const char *cl_get_error_string(int error)
|
|
{
|
|
switch(error){
|
|
case 0: return "CL_SUCCESS";
|
|
case -1: return "CL_DEVICE_NOT_FOUND";
|
|
case -2: return "CL_DEVICE_NOT_AVAILABLE";
|
|
case -3: return "CL_COMPILER_NOT_AVAILABLE";
|
|
case -4: return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
|
|
case -5: return "CL_OUT_OF_RESOURCES";
|
|
case -6: return "CL_OUT_OF_HOST_MEMORY";
|
|
case -7: return "CL_PROFILING_INFO_NOT_AVAILABLE";
|
|
case -8: return "CL_MEM_COPY_OVERLAP";
|
|
case -9: return "CL_IMAGE_FORMAT_MISMATCH";
|
|
case -10: return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
|
|
case -11: return "CL_BUILD_PROGRAM_FAILURE";
|
|
case -12: return "CL_MAP_FAILURE";
|
|
case -13: return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
|
|
case -14: return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
|
|
case -15: return "CL_COMPILE_PROGRAM_FAILURE";
|
|
case -16: return "CL_LINKER_NOT_AVAILABLE";
|
|
case -17: return "CL_LINK_PROGRAM_FAILURE";
|
|
case -18: return "CL_DEVICE_PARTITION_FAILED";
|
|
case -19: return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE";
|
|
|
|
// compile-time errors
|
|
case -30: return "CL_INVALID_VALUE";
|
|
case -31: return "CL_INVALID_DEVICE_TYPE";
|
|
case -32: return "CL_INVALID_PLATFORM";
|
|
case -33: return "CL_INVALID_DEVICE";
|
|
case -34: return "CL_INVALID_CONTEXT";
|
|
case -35: return "CL_INVALID_QUEUE_PROPERTIES";
|
|
case -36: return "CL_INVALID_COMMAND_QUEUE";
|
|
case -37: return "CL_INVALID_HOST_PTR";
|
|
case -38: return "CL_INVALID_MEM_OBJECT";
|
|
case -39: return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
|
|
case -40: return "CL_INVALID_IMAGE_SIZE";
|
|
case -41: return "CL_INVALID_SAMPLER";
|
|
case -42: return "CL_INVALID_BINARY";
|
|
case -43: return "CL_INVALID_BUILD_OPTIONS";
|
|
case -44: return "CL_INVALID_PROGRAM";
|
|
case -45: return "CL_INVALID_PROGRAM_EXECUTABLE";
|
|
case -46: return "CL_INVALID_KERNEL_NAME";
|
|
case -47: return "CL_INVALID_KERNEL_DEFINITION";
|
|
case -48: return "CL_INVALID_KERNEL";
|
|
case -49: return "CL_INVALID_ARG_INDEX";
|
|
case -50: return "CL_INVALID_ARG_VALUE";
|
|
case -51: return "CL_INVALID_ARG_SIZE";
|
|
case -52: return "CL_INVALID_KERNEL_ARGS";
|
|
case -53: return "CL_INVALID_WORK_DIMENSION";
|
|
case -54: return "CL_INVALID_WORK_GROUP_SIZE";
|
|
case -55: return "CL_INVALID_WORK_ITEM_SIZE";
|
|
case -56: return "CL_INVALID_GLOBAL_OFFSET";
|
|
case -57: return "CL_INVALID_EVENT_WAIT_LIST";
|
|
case -58: return "CL_INVALID_EVENT";
|
|
case -59: return "CL_INVALID_OPERATION";
|
|
case -60: return "CL_INVALID_GL_OBJECT";
|
|
case -61: return "CL_INVALID_BUFFER_SIZE";
|
|
case -62: return "CL_INVALID_MIP_LEVEL";
|
|
case -63: return "CL_INVALID_GLOBAL_WORK_SIZE";
|
|
case -64: return "CL_INVALID_PROPERTY";
|
|
case -65: return "CL_INVALID_IMAGE_DESCRIPTOR";
|
|
case -66: return "CL_INVALID_COMPILER_OPTIONS";
|
|
case -67: return "CL_INVALID_LINKER_OPTIONS";
|
|
case -68: return "CL_INVALID_DEVICE_PARTITION_COUNT";
|
|
|
|
case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
|
|
case -1001: return "CL_PLATFORM_NOT_FOUND_KHR";
|
|
case -1002: return "CL_INVALID_D3D10_DEVICE_KHR";
|
|
case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR";
|
|
case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR";
|
|
case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR";
|
|
default: return "Unknown OpenCL error";
|
|
}
|
|
}
|