defocus-modules/lib/image.c

110 lines
2.5 KiB
C

#include <defocus/image.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h>
struct df_image
{
int width;
int height;
uint8_t *pixels;
};
DF_API df_result df_create_image(int w, int h, df_image **out_image)
{
df_image *img = malloc(sizeof(df_image));
if (!img)
return df_result_out_of_memory;
DF_ZERO_STRUCT(img);
img->width = w;
img->height = h;
img->pixels = malloc(4 * sizeof(uint8_t) * w * h);
if (!img->pixels) {
free(img);
return df_result_out_of_memory;
}
memset(img->pixels, 0, 4 * w * h);
*out_image = img;
return df_result_success;
}
DF_API df_result df_load_image(const char *path, int *out_w, int *out_h, df_image **out_image)
{
int w, h, c;
stbi_uc *pixels = stbi_load(path, &w, &h, &c, 4);
if (!pixels) {
fprintf(stderr, "ERROR: failed to load %s: %s\n", path, stbi_failure_reason());
return df_result_io_error;
}
df_result res = df_result_success;
df_image *img = malloc(sizeof(df_image));
if (!img) {
res = df_result_out_of_memory;
goto err;
}
DF_ZERO_STRUCT(img);
img->width = w;
img->height = h;
img->pixels = (uint8_t *)pixels;
*out_image = img;
*out_w = w;
*out_h = h;
goto out;
err:
free(img);
out:
return res;
}
DF_API void df_release_image(df_image *img)
{
if (img) {
free(img->pixels);
free(img);
}
}
DF_API df_result df_write_image(df_image *image, const char *path)
{
df_result res = stbi_write_png(path, image->width, image->height, 4, image->pixels, image->width * 4)
? df_result_success
: df_result_io_error;
return res;
}
DF_API void df_get_image_size(const df_image *image, int *w, int *h)
{
if (w)
*w = image->width;
if (h)
*h = image->height;
}
DF_API df_color df_get_image_pixel(const df_image *image, int x, int y)
{
df_color c = {0, 0, 0, 255};
if (x >= 0 && x < image->width && y >= 0 && y < image->height) {
memcpy(&c.e[0], &image->pixels[4 * (y * image->width + x)], 4);
}
return c;
}
DF_API void df_set_image_pixel(df_image *image, int x, int y, df_color c)
{
if (x >= 0 && x < image->width && y >= 0 && y < image->height) {
memcpy(&image->pixels[4 * (y * image->width + x)], &c.e[0], 4);
}
}