diff --git a/Makefile b/Makefile index 060724a..e9b423a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,3 @@ -rootdir = $(realpath .) - .PHONY: build clean: rm -rf build @@ -7,5 +5,5 @@ clean: build: mkdir -p build && \ cd build && \ - gcc -Wall -c $(rootdir)/src/*.c && \ + gcc -Wall -c ../src/*.c && \ gcc -Wall -o mg *.o \ No newline at end of file diff --git a/src/bmp.c b/src/bmp.c index dd5d639..40e49a9 100644 --- a/src/bmp.c +++ b/src/bmp.c @@ -1,97 +1,90 @@ -#include "bmp.h" +#include +#include -void write_str(char *buffer, int offset, int size, char *value, int value_offset) -{ - int i; - for (i = 0; i < size; i++) - { - buffer[offset + i] = value[i]; - } +#define HEADER_SIZE 54 + +void write_str(char *buffer, int offset, int size, char *value) { + int i; + for (i = 0; i < size; i++) { + buffer[offset + i] = value[i]; + } } -void write_num(char *buffer, int offset, int size, unsigned long value) -{ - int i; - for (i = 0; i < size; i++) - { - buffer[offset + i] = (char)((value >> (8 * i)) & 0xFFu); - } +void write_num(char *buffer, int offset, int size, unsigned long value) { + int i; + for (i = 0; i < size; i++) { + buffer[offset + i] = (char)((value >> (8 * i)) & 0xFFu); + } } -void write_nul(char *buffer, int offset, int size) -{ - int i; - for (i = 0; i < size; i++) - { - buffer[offset + i] = 0; - } +void write_nul(char *buffer, int offset, int size) { + int i; + for (i = 0; i < size; i++) { + buffer[offset + i] = 0; + } } -char *bmp_header(unsigned long width, unsigned long height, unsigned long color_depth) -{ - char *output = (char *)malloc(HEADER_SIZE); +char *bmp_header(unsigned long width, unsigned long height, + unsigned int color_depth) { + char *output = (char *)malloc(HEADER_SIZE); - write_str(output, 0x00, 0x02, "BM", 0); // 0x00(2) BM - write_num(output, 0x02, 0x04, HEADER_SIZE + width * height * color_depth); // 0x02(4) file size - write_nul(output, 0x06, 0x04); // 0x06(4) application reserved - write_num(output, 0x0A, 0x04, HEADER_SIZE); // 0x0A(4) data offset - write_num(output, 0x0E, 0x04, 40); // 0x0E(4) DIB header size - write_num(output, 0x12, 0x04, width); // 0x12(4) width - write_num(output, 0x16, 0x04, height); // 0x16(4) height - write_num(output, 0x1A, 0x04, 1); // 0x1A(2) color panes - write_num(output, 0x1C, 0x02, color_depth * 8); // 0x1C(2) bits per pixel - write_nul(output, 0x1E, 0x04); // 0x1E(4) BI_RGB, no compression - write_num(output, 0x22, 0x04, width * height * color_depth); // 0x22(4) size of raw bitmap data - write_num(output, 0x26, 0x04, 2835); // 0x26(4) horizontal print resolution - write_num(output, 0x2A, 0x04, 2835); // 0x2A(4) vertical print resolution - write_nul(output, 0x2E, 0x04); // 0x2E(4) color in palette - write_nul(output, 0x32, 0x04); // 0x32(4) 0 important colors + write_str(output, 0x00, 0x02, "BM"); // 0x00(2) BM + write_num(output, 0x02, 0x04, + HEADER_SIZE + width * height * color_depth); // 0x02(4) file size + write_nul(output, 0x06, 0x04); // 0x06(4) application reserved + write_num(output, 0x0A, 0x04, HEADER_SIZE); // 0x0A(4) data offset + write_num(output, 0x0E, 0x04, 40); // 0x0E(4) DIB header size + write_num(output, 0x12, 0x04, width); // 0x12(4) width + write_num(output, 0x16, 0x04, height); // 0x16(4) height + write_num(output, 0x1A, 0x04, 1); // 0x1A(2) color panes + write_num(output, 0x1C, 0x02, color_depth * 8); // 0x1C(2) bits per pixel + write_nul(output, 0x1E, 0x04); // 0x1E(4) BI_RGB, no compression + write_num(output, 0x22, 0x04, + width * height * color_depth); // 0x22(4) size of raw bitmap data + write_num(output, 0x26, 0x04, 2835); // 0x26(4) horizontal print resolution + write_num(output, 0x2A, 0x04, 2835); // 0x2A(4) vertical print resolution + write_nul(output, 0x2E, 0x04); // 0x2E(4) color in palette + write_nul(output, 0x32, 0x04); // 0x32(4) 0 important colors - return output; + return output; } -unsigned long bmp_data_line_length(unsigned long width, unsigned long color_depth) -{ - unsigned long line_offset = (width * color_depth) % 4; - unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; - return width * color_depth + line_padding; +unsigned long bmp_data_line_length(unsigned long width, + unsigned int color_depth) { + unsigned long line_offset = (width * color_depth) % 4; + unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; + return width * color_depth + line_padding; } -char *bmp_data_line(unsigned long width, unsigned long color_depth, char *data, unsigned long data_offset) -{ - unsigned long line_offset = (width * color_depth) % 4; - unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; - unsigned long line_length = width * color_depth + line_padding; - char *output = (char *)malloc(line_length); - write_str(output, 0, width * color_depth, data, data_offset); - if (line_padding > 0) - { - write_nul(output, width * color_depth, line_padding); - } - return output; +char *bmp_data_line(unsigned long width, unsigned int color_depth, char *data) { + unsigned long line_offset = (width * color_depth) % 4; + unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; + unsigned long line_length = width * color_depth + line_padding; + char *output = (char *)malloc(line_length); + write_str(output, 0, width * color_depth, data); + if (line_padding > 0) { + write_nul(output, width * color_depth, line_padding); + } + return output; } -unsigned long bmp_data_length(unsigned long width, unsigned long height, unsigned long color_depth) -{ - return bmp_data_line_length(width, color_depth) * height; -} - -char *bmp_data(unsigned long width, unsigned long height, unsigned long color_depth, char *data) -{ - unsigned long line_offset = (width * color_depth) % 4; - unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; - unsigned long line_length = width * color_depth + line_padding; - char *output = (char *)malloc(height * line_length); - int y, offset, offset_data; - for (y = 0; y < height; y++) - { - offset = y * line_length; - offset_data = (height - y - 1) * color_depth * width; - write_str(output, offset, width * color_depth, data, offset_data); - if (line_padding > 0) - { - write_nul(output, offset + width * color_depth, line_padding); - } - } - return output; +void bmp_generate(unsigned long width, unsigned long height, + unsigned int color_depth, char *file_path, + void generate_line(unsigned long y, char *data_buffer)) { + FILE *fptr; + fptr = fopen(file_path, "w"); + char *header = bmp_header(width, height, color_depth); + fwrite(header, HEADER_SIZE, 1, fptr); + free(header); + int y; + char *data_buffer = malloc(width * color_depth); + char *line_buffer = NULL; + for (y = 0; y < height; y++) { + generate_line(height - y - 1, data_buffer); + line_buffer = bmp_data_line(width, color_depth, data_buffer); + fwrite(line_buffer, bmp_data_line_length(width, color_depth), 1, fptr); + free(line_buffer); + } + free(data_buffer); + fclose(fptr); } \ No newline at end of file diff --git a/src/bmp.h b/src/bmp.h index b6e43a1..ab37a92 100644 --- a/src/bmp.h +++ b/src/bmp.h @@ -1,9 +1,3 @@ -#include - -#define HEADER_SIZE 54 - -char *bmp_header(unsigned long width, unsigned long height, unsigned long color_depth); -unsigned long bmp_data_line_length(unsigned long width, unsigned long color_depth); -char *bmp_data_line(unsigned long width, unsigned long color_depth, char *data, unsigned long data_offset); -unsigned long bmp_data_length(unsigned long width, unsigned long height, unsigned long color_depth); -char *bmp_data(unsigned long width, unsigned long height, unsigned long color_depth, char *data); \ No newline at end of file +void bmp_generate(unsigned long width, unsigned long height, + unsigned int color_depth, char *file_path, + void generate_line(unsigned long y, char *data_buffer)); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 118f246..c7fa90b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,23 +1,16 @@ -#include "main.h" +#include -int main() -{ - FILE *fptr; - fptr = fopen("test.bmp", "w"); - char *header = bmp_header(WIDTH, HEIGHT, COLOR_DEPTH); - fwrite(header, HEADER_SIZE, 1, fptr); - free(header); - int y; - char *data = malloc(WIDTH * COLOR_DEPTH); - char *data_line = NULL; - for (y = 0; y < HEIGHT; y++) - { - memset(data, HEIGHT - y - 1, WIDTH * COLOR_DEPTH); - data_line = bmp_data_line(WIDTH, COLOR_DEPTH, data, 0); - fwrite(data_line, bmp_data_line_length(WIDTH, COLOR_DEPTH), 1, fptr); - free(data_line); - } - free(data); - fclose(fptr); - return 0; +#include "bmp.h" + +#define WIDTH 256 +#define HEIGHT 256 +#define COLOR_DEPTH 3 + +void generate_line(unsigned long y, char *data_buffer) { + memset(data_buffer, y, WIDTH * COLOR_DEPTH); +} + +int main() { + bmp_generate(WIDTH, HEIGHT, COLOR_DEPTH, "test.bmp", generate_line); + return 0; } \ No newline at end of file diff --git a/src/main.h b/src/main.h index 9476f49..e69de29 100644 --- a/src/main.h +++ b/src/main.h @@ -1,8 +0,0 @@ -#include -#include -#include -#include "bmp.h" - -#define WIDTH 256 -#define HEIGHT 256 -#define COLOR_DEPTH 3 \ No newline at end of file