#include #include #include #include #define STB_IMAGE_IMPLEMENTATION #include #define STB_IMAGE_WRITE_IMPLEMENTATION #include 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); } }