#include "img.h" #include "aliases.h" #include "mem_arena.h" #include "pam.h" #include "utils.h" #include #include #include internal i64 calculate_pixel_index(Buffer *buffer, u64 x, u64 y, u64 base_size); bool _init_buffer(Arena *arena, Buffer *buffer, u64 base_size) { if (!arena || !buffer || buffer->width == 0 || buffer->height == 0) { return false; } u64 size = buffer->width * buffer->height * base_size; buffer->buf = wapp_mem_arena_alloc(arena, size); return buffer->buf != NULL; } u8 *_get_pixel(Buffer *buffer, u64 x, u64 y, u64 base_size) { i64 idx = calculate_pixel_index(buffer, x, y, base_size); if (idx == -1) { idx = 0; } return ((u8 *)(buffer->buf)) + idx; } void _set_pixel(Buffer *buffer, u64 x, u64 y, void *value, u64 base_size) { i64 idx = calculate_pixel_index(buffer, x, y, base_size); if (idx == -1) { return; } memcpy(((u8 *)(buffer->buf)) + idx, value, base_size); return; } void _clear_buffer(Buffer *buffer, void *value, u64 base_size) { for (u64 y = 0; y < buffer->height; ++y) { for (u64 x = 0; x < buffer->width; ++x) { _set_pixel(buffer, x, y, value, base_size); } } } void draw_line(Image *img, u64 x0, u64 y0, u64 x1, u64 y1, Colour colour) { u64 dx = absolute((i64)x1 - (i64)x0); u64 dy = absolute((i64)y1 - (i64)y0); f32 t = 0.0f; i64 x = 0; i64 y = 0; if (dx > dy) { if (x0 > x1) { swap(u64, x0, x1); swap(u64, y0, y1); } for (u64 x = x0; x < x1; ++x) { t = (f32)(x - x0) / (f32)(x1 - x0); y = (i64)y0 + ((i64)y1 - (i64)y0) * t; set_pixel(img, x, y, &colour); } } else { if (y0 > y1) { swap(u64, x0, x1); swap(u64, y0, y1); } for (u64 y = y0; y < y1; ++y) { t = (f32)(y - y0) / (f32)(y1 - y0); x = (i64)x0 + ((i64)x1 - (i64)x0) * t; set_pixel(img, x, y, &colour); } } } void save_image(const Image *img, const char *filename) { write_p7_image(img->width, img->height, (u8 *)(img->buf), filename); } internal i64 calculate_pixel_index(Buffer *buffer, u64 x, u64 y, u64 base_size) { if (x < 0 || y < 0 || x >= buffer->width || y >= buffer->height) { return -1; } return (y * buffer->width + x) * base_size; }