C-Playground/lib/bmp.c

60 lines
2.1 KiB
C

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "bmp.h"
uint32_t calc_bitmap_pixel_array_size_bytes(bitmap *bitmap_in) {
/* We will assume that the bitmap bits per pixel is always a multiple of 8 and sizeof byte is always 8 */
uint32_t bytes_unpadded = (bitmap_in->image_width * bitmap_in->image_height * bitmap_in->bits_per_pixel) / 8;
return bytes_unpadded + (bytes_unpadded % 8); /* Add padding to ensure 4 byte allignment */
};
uint32_t calc_bitmap_file_size_bytes(bitmap *bitmap_in) {
/* We will assume that the bitmap bits per pixel is always a multiple of 8 and sizeof byte is always 8 */
return sizeof(bitmap) + calc_bitmap_pixel_array_size_bytes(bitmap_in) - 2 ; /* Take away two to account for compiler padding struct */
};
bitmap init_bitmap(int32_t image_width_in, int32_t image_height_in) {
bitmap new_bitmap;
/* Bitmap Info Header */
new_bitmap.info_header_size_bytes = 40;
new_bitmap.image_width = image_width_in;
new_bitmap.image_height = image_height_in;
new_bitmap.color_planes_used = 1;
new_bitmap.bits_per_pixel = 24;
new_bitmap.compression_method = 0;
new_bitmap.image_size = calc_bitmap_pixel_array_size_bytes(&new_bitmap);
new_bitmap.horizontal_resolution_pixels_per_metre = 2835; /* Approx 72DPI */
new_bitmap.vertical_resolution_pixels_per_metre = 2835;
new_bitmap.colors_in_palette = 0;
new_bitmap.important_colors = 0;
/* File Header */
new_bitmap.header_field[0] = 'B';
new_bitmap.header_field[1] = 'M';
new_bitmap.file_size_bytes = calc_bitmap_file_size_bytes(&new_bitmap);
new_bitmap.reserved1 = 0;
new_bitmap.reserved2 = 0;
new_bitmap.image_data_start_offset = 54;
return new_bitmap;
};
int write_to_bitmap(bitmap *bitmap_in, char *filename) {
int8_t write_status;
uint8_t *bitmap_in_byte_ptr = (uint8_t *)bitmap_in + 2; /* Offset by two to account for padding */
int8_t fd = open(filename, O_WRONLY | O_CREAT);
if (fd == -1)
return -1;
/* This is writing out of bounds (bitmap < bitmap_file_size), please fix */
write_status = write(fd, bitmap_in_byte_ptr, calc_bitmap_file_size_bytes(bitmap_in));
if (fd == -1) {
close(fd);
return -1;
}
close(fd);
return 0;
};