diff --git a/An-Introduction-to-Ray-Tracing-The-Morgan-Kaufmann-Series-in-Computer-Graphics-.pdf b/An-Introduction-to-Ray-Tracing-The-Morgan-Kaufmann-Series-in-Computer-Graphics-.pdf new file mode 100644 index 0000000..4055d8b Binary files /dev/null and b/An-Introduction-to-Ray-Tracing-The-Morgan-Kaufmann-Series-in-Computer-Graphics-.pdf differ diff --git a/Linear Algebra - Jim Hefferon - 4th Ed.pdf b/Linear Algebra - Jim Hefferon - 4th Ed.pdf new file mode 100644 index 0000000..413b618 Binary files /dev/null and b/Linear Algebra - Jim Hefferon - 4th Ed.pdf differ diff --git a/comprun.sh b/comprun.sh index 6f88c82..1426ffe 100755 --- a/comprun.sh +++ b/comprun.sh @@ -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 diff --git a/lib/bmp.c b/lib/bmp.c index da45a5f..72bf4ad 100644 --- a/lib/bmp.c +++ b/lib/bmp.c @@ -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; }; diff --git a/lib/bmp.h b/lib/bmp.h index 1f8570b..16e3972 100644 --- a/lib/bmp.h +++ b/lib/bmp.h @@ -3,6 +3,7 @@ #include +/* 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 diff --git a/main.c b/main.c index 0b454ba..4f89561 100755 --- a/main.c +++ b/main.c @@ -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);