Initial work on bitmap and background support. Add a public domain picture.
Co-authored-by: ethan <55000224+ethan4984@users.noreply.github.com>
diff --git a/Makefile b/Makefile
index f6a1301b..f3a90715 100644
--- a/Makefile
+++ b/Makefile
@@ -41,6 +41,7 @@ echfs-test: limine-install test.img
echfs-utils -m -p0 test.img quick-format 512
echfs-utils -m -p0 test.img import test/test.elf boot/test.elf
echfs-utils -m -p0 test.img import test/limine.cfg limine.cfg
+ echfs-utils -m -p0 test.img import test/bg.bmp bg.bmp
./limine-install limine.bin test.img
qemu-system-x86_64 -net none -smp 4 -hda test.img -debugcon stdio -enable-kvm
diff --git a/stage2/lib/bmp.c b/stage2/lib/bmp.c
new file mode 100644
index 00000000..ae6907b4
--- /dev/null
+++ b/stage2/lib/bmp.c
@@ -0,0 +1,62 @@
+#include <stdint.h>
+#include <fs/file.h>
+#include <lib/image.h>
+#include <lib/bmp.h>
+#include <lib/libc.h>
+#include <mm/pmm.h>
+
+struct bmp_header {
+ uint16_t bf_signature;
+ uint32_t bf_size;
+ uint32_t reserved;
+ uint32_t bf_offset;
+
+ uint32_t bi_size;
+ uint32_t bi_width;
+ uint32_t bi_height;
+ uint16_t bi_planes;
+ uint16_t bi_bpp;
+ uint32_t bi_compression;
+ uint32_t bi_image_size;
+ uint32_t bi_xcount;
+ uint32_t bi_ycount;
+ uint32_t bi_clr_used;
+ uint32_t bi_clr_important;
+ uint32_t red_mask;
+ uint32_t green_mask;
+ uint32_t blue_mask;
+} __attribute__((packed));
+
+struct bmp_local {
+ uint32_t *image;
+ uint32_t pitch;
+ struct bmp_header header;
+};
+
+static uint32_t get_pixel(struct image *this, int x, int y) {
+ struct bmp_local *local = this->local;
+ return local->image[x + (local->pitch / local->header.bi_bpp) * y];
+}
+
+int bmp_open_image(struct image *image, struct file_handle *file) {
+ struct bmp_header header;
+ fread(file, &header, 0, sizeof(struct bmp_header));
+
+ if (memcmp(&header.bf_signature, "BM", 2) != 0)
+ return -1;
+
+ struct bmp_local *local = ext_mem_alloc(sizeof(struct bmp_local));
+
+ local->image = ext_mem_alloc(header.bf_size);
+ fread(file, local->image, header.bf_offset, header.bf_size);
+
+ local->pitch = header.bi_width * (header.bi_bpp / 8);
+ local->header = header;
+
+ image->x_size = header.bi_width;
+ image->y_size = header.bi_height;
+ image->get_pixel = get_pixel;
+ image->local = local;
+
+ return 0;
+}
diff --git a/stage2/lib/bmp.h b/stage2/lib/bmp.h
new file mode 100644
index 00000000..5292bdc4
--- /dev/null
+++ b/stage2/lib/bmp.h
@@ -0,0 +1,10 @@
+#ifndef __LIB__BMP_H__
+#define __LIB__BMP_H__
+
+#include <stdint.h>
+#include <fs/file.h>
+#include <lib/image.h>
+
+int bmp_open_image(struct image *image, struct file_handle *file);
+
+#endif
diff --git a/stage2/lib/image.c b/stage2/lib/image.c
new file mode 100644
index 00000000..37cb8b8f
--- /dev/null
+++ b/stage2/lib/image.c
@@ -0,0 +1,13 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <lib/image.h>
+#include <lib/bmp.h>
+
+int open_image(struct image *image, struct file_handle *file) {
+ image->file = file;
+
+ if (!bmp_open_image(image, file))
+ return 0;
+
+ return -1;
+}
diff --git a/stage2/lib/image.h b/stage2/lib/image.h
new file mode 100644
index 00000000..09af1228
--- /dev/null
+++ b/stage2/lib/image.h
@@ -0,0 +1,17 @@
+#ifndef __LIB__IMAGE_H__
+#define __LIB__IMAGE_H__
+
+#include <stdint.h>
+#include <fs/file.h>
+
+struct image {
+ struct file_handle *file;
+ int x_size;
+ int y_size;
+ uint32_t (*get_pixel)(struct image *this, int x, int y);
+ void *local;
+};
+
+int open_image(struct image *image, struct file_handle *file);
+
+#endif
diff --git a/test/bg.bmp b/test/bg.bmp
new file mode 100644
index 00000000..87155831
Binary files /dev/null and b/test/bg.bmp differ
diff --git a/test/limine.cfg b/test/limine.cfg
index 8f70a2f0..690e7bdb 100644
--- a/test/limine.cfg
+++ b/test/limine.cfg
@@ -1,5 +1,8 @@
TIMEOUT=3
-GRAPHICS=on
+
+BACKGROUND_DRIVE=0
+BACKGROUND_PARTITION=0
+BACKGROUND_PATH=bg.bmp
:MyOS
