2023-05-17 17:45:47 +02:00

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";
}
}