reformat and better bmp all in one function

This commit is contained in:
2025-06-03 19:41:53 +02:00
parent 43927dadf4
commit 9a819f3a81
5 changed files with 92 additions and 122 deletions
+1 -3
View File
@@ -1,5 +1,3 @@
rootdir = $(realpath .)
.PHONY: build .PHONY: build
clean: clean:
rm -rf build rm -rf build
@@ -7,5 +5,5 @@ clean:
build: build:
mkdir -p build && \ mkdir -p build && \
cd build && \ cd build && \
gcc -Wall -c $(rootdir)/src/*.c && \ gcc -Wall -c ../src/*.c && \
gcc -Wall -o mg *.o gcc -Wall -o mg *.o
+40 -47
View File
@@ -1,38 +1,36 @@
#include "bmp.h" #include <stdio.h>
#include <stdlib.h>
void write_str(char *buffer, int offset, int size, char *value, int value_offset) #define HEADER_SIZE 54
{
void write_str(char *buffer, int offset, int size, char *value) {
int i; int i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++) {
{
buffer[offset + i] = value[i]; buffer[offset + i] = value[i];
} }
} }
void write_num(char *buffer, int offset, int size, unsigned long value) void write_num(char *buffer, int offset, int size, unsigned long value) {
{
int i; int i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++) {
{
buffer[offset + i] = (char)((value >> (8 * i)) & 0xFFu); buffer[offset + i] = (char)((value >> (8 * i)) & 0xFFu);
} }
} }
void write_nul(char *buffer, int offset, int size) void write_nul(char *buffer, int offset, int size) {
{
int i; int i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++) {
{
buffer[offset + i] = 0; buffer[offset + i] = 0;
} }
} }
char *bmp_header(unsigned long width, unsigned long height, unsigned long color_depth) char *bmp_header(unsigned long width, unsigned long height,
{ unsigned int color_depth) {
char *output = (char *)malloc(HEADER_SIZE); char *output = (char *)malloc(HEADER_SIZE);
write_str(output, 0x00, 0x02, "BM", 0); // 0x00(2) BM 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_num(output, 0x02, 0x04,
HEADER_SIZE + width * height * color_depth); // 0x02(4) file size
write_nul(output, 0x06, 0x04); // 0x06(4) application reserved write_nul(output, 0x06, 0x04); // 0x06(4) application reserved
write_num(output, 0x0A, 0x04, HEADER_SIZE); // 0x0A(4) data offset 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, 0x0E, 0x04, 40); // 0x0E(4) DIB header size
@@ -41,7 +39,8 @@ char *bmp_header(unsigned long width, unsigned long height, unsigned long color_
write_num(output, 0x1A, 0x04, 1); // 0x1A(2) color panes write_num(output, 0x1A, 0x04, 1); // 0x1A(2) color panes
write_num(output, 0x1C, 0x02, color_depth * 8); // 0x1C(2) bits per pixel 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_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, 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, 0x26, 0x04, 2835); // 0x26(4) horizontal print resolution
write_num(output, 0x2A, 0x04, 2835); // 0x2A(4) vertical 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, 0x2E, 0x04); // 0x2E(4) color in palette
@@ -50,48 +49,42 @@ char *bmp_header(unsigned long width, unsigned long height, unsigned long color_
return output; return output;
} }
unsigned long bmp_data_line_length(unsigned long width, unsigned long color_depth) unsigned long bmp_data_line_length(unsigned long width,
{ unsigned int color_depth) {
unsigned long line_offset = (width * color_depth) % 4; unsigned long line_offset = (width * color_depth) % 4;
unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0;
return width * color_depth + line_padding; return width * color_depth + line_padding;
} }
char *bmp_data_line(unsigned long width, unsigned long color_depth, char *data, unsigned long data_offset) char *bmp_data_line(unsigned long width, unsigned int color_depth, char *data) {
{
unsigned long line_offset = (width * color_depth) % 4; unsigned long line_offset = (width * color_depth) % 4;
unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0;
unsigned long line_length = width * color_depth + line_padding; unsigned long line_length = width * color_depth + line_padding;
char *output = (char *)malloc(line_length); char *output = (char *)malloc(line_length);
write_str(output, 0, width * color_depth, data, data_offset); write_str(output, 0, width * color_depth, data);
if (line_padding > 0) if (line_padding > 0) {
{
write_nul(output, width * color_depth, line_padding); write_nul(output, width * color_depth, line_padding);
} }
return output; return output;
} }
unsigned long bmp_data_length(unsigned long width, unsigned long height, unsigned long color_depth) void bmp_generate(unsigned long width, unsigned long height,
{ unsigned int color_depth, char *file_path,
return bmp_data_line_length(width, color_depth) * height; void generate_line(unsigned long y, char *data_buffer)) {
} FILE *fptr;
fptr = fopen(file_path, "w");
char *bmp_data(unsigned long width, unsigned long height, unsigned long color_depth, char *data) char *header = bmp_header(width, height, color_depth);
{ fwrite(header, HEADER_SIZE, 1, fptr);
unsigned long line_offset = (width * color_depth) % 4; free(header);
unsigned long line_padding = line_offset > 0 ? 4 - line_offset : 0; int y;
unsigned long line_length = width * color_depth + line_padding; char *data_buffer = malloc(width * color_depth);
char *output = (char *)malloc(height * line_length); char *line_buffer = NULL;
int y, offset, offset_data; for (y = 0; y < height; y++) {
for (y = 0; y < height; y++) generate_line(height - y - 1, data_buffer);
{ line_buffer = bmp_data_line(width, color_depth, data_buffer);
offset = y * line_length; fwrite(line_buffer, bmp_data_line_length(width, color_depth), 1, fptr);
offset_data = (height - y - 1) * color_depth * width; free(line_buffer);
write_str(output, offset, width * color_depth, data, offset_data);
if (line_padding > 0)
{
write_nul(output, offset + width * color_depth, line_padding);
} }
} free(data_buffer);
return output; fclose(fptr);
} }
+3 -9
View File
@@ -1,9 +1,3 @@
#include <stdlib.h> void bmp_generate(unsigned long width, unsigned long height,
unsigned int color_depth, char *file_path,
#define HEADER_SIZE 54 void generate_line(unsigned long y, char *data_buffer));
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);
+13 -20
View File
@@ -1,23 +1,16 @@
#include "main.h" #include <string.h>
int main() #include "bmp.h"
{
FILE *fptr; #define WIDTH 256
fptr = fopen("test.bmp", "w"); #define HEIGHT 256
char *header = bmp_header(WIDTH, HEIGHT, COLOR_DEPTH); #define COLOR_DEPTH 3
fwrite(header, HEADER_SIZE, 1, fptr);
free(header); void generate_line(unsigned long y, char *data_buffer) {
int y; memset(data_buffer, y, WIDTH * COLOR_DEPTH);
char *data = malloc(WIDTH * COLOR_DEPTH); }
char *data_line = NULL;
for (y = 0; y < HEIGHT; y++) int main() {
{ bmp_generate(WIDTH, HEIGHT, COLOR_DEPTH, "test.bmp", generate_line);
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; return 0;
} }
-8
View File
@@ -1,8 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmp.h"
#define WIDTH 256
#define HEIGHT 256
#define COLOR_DEPTH 3