This commit is contained in:
Curt Spark 2024-07-26 08:40:39 +01:00
parent 1e893bbc8e
commit a8ffd073c2
6 changed files with 73 additions and 17 deletions

Binary file not shown.

View File

@ -1,4 +1,8 @@
#!/bin/sh
rm test.bmp
gcc -g main.c lib/*.c
./a.out
chmod 777 test.bmp
printf "\n"
xxd test.bmp

View File

@ -4,13 +4,13 @@
#include "bmp.h"
uint32_t calc_bitmap_pixel_array_size_bytes(bitmap *bitmap_in) {
uint32_t calc_bitmap_pixel_array_size_bytes(const bitmap *bitmap_in) {
/* We will assume that the bitmap bits per pixel is always a multiple of 8 and sizeof byte is always 8 bits */
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 bytes_unpadded = (((bitmap_in->image_width * bitmap_in->image_height) * bitmap_in->bits_per_pixel) / 8);
return bytes_unpadded + ((bytes_unpadded / 6) * 2); /* Add padding to ensure 4 byte allignment */
};
uint32_t calc_bitmap_file_size_bytes(bitmap *bitmap_in) {
uint32_t calc_bitmap_file_size_bytes(const bitmap *bitmap_in) {
/* We will assume that the bitmap bits per pixel is always a multiple of 8 and sizeof byte is always 8 bits */
return sizeof(bitmap) + calc_bitmap_pixel_array_size_bytes(bitmap_in) - 2 ; /* Take away two to account for compiler padding struct */
};
@ -19,7 +19,8 @@ uint32_t calc_bitmap_header_size_bytes() {
return sizeof(bitmap) - 2 ; /* Take away two to account for compiler padding struct */
};
bitmap init_bitmap(int32_t image_width_in, int32_t image_height_in) {
/* Change name to init_bitmap_header */
bitmap init_bitmap(const int32_t image_width_in, const int32_t image_height_in) {
bitmap new_bitmap;
/* Bitmap Info Header */
new_bitmap.info_header_size_bytes = 40;
@ -46,23 +47,47 @@ bitmap init_bitmap(int32_t image_width_in, int32_t image_height_in) {
return new_bitmap;
};
int write_to_bitmap(bitmap *bitmap_in, char *filename) {
/* Change the name to init_bitmap_file */
bitmap_file write_to_bitmap(const bitmap *bitmap_in, const char *filename) {
bitmap_file new_bitmap_file;
int8_t write_status;
uint32_t current_byte;
uint8_t blank_byte_buffer[1] = { 0 };
uint8_t blank_byte_buffer[1] = { 255 };
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;
/* TODO Need an error return type */
return new_bitmap_file;
/* Write Header */
write_status = write(fd, bitmap_in_byte_ptr, calc_bitmap_header_size_bytes());
/* Write blank pixel array */
for (current_byte = bitmap_in->image_data_start_offset; current_byte < calc_bitmap_file_size_bytes(bitmap_in); ++current_byte)
for (current_byte = bitmap_in->image_data_start_offset; current_byte <= calc_bitmap_file_size_bytes(bitmap_in); ++current_byte)
write_status = pwrite(fd, blank_byte_buffer, 1, current_byte);
if (fd == -1) {
close(fd);
return -1;
/* TODO Need an error return type */
return new_bitmap_file;
}
close(fd);
new_bitmap_file.filename = filename;
new_bitmap_file.bitmap_metadata = bitmap_in;
return new_bitmap_file;
};
int write_bitmap_pixel(const bitmap_file *bitmap_file_in, const bitmap_pixel_color *bitmap_pixel_in, const int32_t x_in, const int32_t y_in) {
int8_t write_status;
int32_t byte_position_end = ((bitmap_file_in->bitmap_metadata->image_width * (y_in - 1)) + x_in) * 3; /* Three bytes */
int32_t byte_position_end_padded = byte_position_end + ((byte_position_end / 8) * 2); /* Account for padding of all pixels before this one */
int32_t byte_position_start = byte_position_end_padded - 3;
uint8_t *bitmap_pixel_in_byte_ptr = (uint8_t *)bitmap_pixel_in;
int8_t fd = open(bitmap_file_in->filename, O_WRONLY | O_CREAT);
if (fd == -1)
return -1;
if (byte_position_start % 4)
write_status = pwrite(fd, bitmap_pixel_in_byte_ptr, 5, bitmap_file_in->bitmap_metadata->image_data_start_offset + byte_position_start);
else
write_status = pwrite(fd, bitmap_pixel_in_byte_ptr, 3, bitmap_file_in->bitmap_metadata->image_data_start_offset + byte_position_start);
return 0;
};

View File

@ -3,6 +3,7 @@
#include <stdint.h>
/* Change struct name to bitmap header */
typedef struct bitmap {
/* File Header */
/* The header field used to identify the BMP and DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII. The following entries are possible:
@ -19,7 +20,7 @@ typedef struct bitmap {
OS/2 struct icon
PT
OS/2 pointer */
uint16_t padding_allignment; /* The compiler will pad structs automatically to ensure the struct is byte aligned. (i.e 54 bytes to 56). We declare padding allignment ourselves and we will make sure to account for this. */
uint16_t padding_alignment; /* The compiler will pad structs automatically to ensure the struct is byte aligned. (i.e 54 bytes to 56). We declare padding allignment ourselves and we will make sure to account for this. */
uint8_t header_field[2];
uint32_t file_size_bytes;
uint16_t reserved1;
@ -40,12 +41,27 @@ typedef struct bitmap {
uint32_t important_colors;
} bitmap;
bitmap init_bitmap(int32_t image_width_in, int32_t image_height_in);
typedef struct bitmap_file {
char *filename;
bitmap *bitmap_metadata;
} bitmap_file;
uint32_t calc_bitmap_file_size_bytes(bitmap *bitmap_in);
uint32_t calc_bitmap_pixel_array_size_bytes(bitmap *bitmap_in);
typedef struct bitmap_pixel_color {
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t padding_bytes_buffer[2];
} bitmap_pixel_color;
/* Change struct name to bitmap header */
bitmap init_bitmap(const int32_t image_width_in, const int32_t image_height_in);
/* Change the name to init_bitmap_file */
bitmap_file write_to_bitmap(const bitmap *bitmap_in, const char *filename);
uint32_t calc_bitmap_file_size_bytes(const bitmap *bitmap_in);
uint32_t calc_bitmap_pixel_array_size_bytes(const bitmap *bitmap_in);
uint32_t calc_bitmap_header_size_bytes();
int write_to_bitmap(bitmap *bitmap_in, char *filename);
int write_bitmap_pixel(const bitmap_file *bitmap_file_in, const bitmap_pixel_color *bitmap_pixel_in, const int32_t x_in, const int32_t y_in);
#endif

15
main.c
View File

@ -35,8 +35,19 @@ int main() {
//
// printf("40C == %dF\n", (int) celsius_to_farenheit(40.0));
bitmap test = init_bitmap(2, 2);
write_to_bitmap(&test, "test.bmp");
const bitmap test = init_bitmap(2, 2);
bitmap_file test_file = write_to_bitmap(&test, "test.bmp");
bitmap_pixel_color test_pixel;
test_pixel.red = 0;
test_pixel.green = 0;
test_pixel.blue = 0;
bitmap_pixel_color test_pixel2;
test_pixel2.red = 0;
test_pixel2.green = 0;
test_pixel2.blue = 255;
write_bitmap_pixel(&test_file, &test_pixel, 1, 2);
write_bitmap_pixel(&test_file, &test_pixel2, 2, 2);
char *reserved_memory = ss_alloc(100);
ss_alloc_free(reserved_memory);