From 959c44658e8f92183d7e5877e13a612564630320 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sun, 5 Mar 2023 07:57:54 +0100 Subject: [PATCH] image: Use stb_image for image loading --- CONFIG.md | 2 +- README.md | 3 +- common/lib/bmp.c | 63 ------------------------------------------ common/lib/bmp.h | 10 ------- common/lib/gterm.c | 6 ++-- common/lib/image.c | 36 ++++++++++++++++++++---- common/lib/libc.h | 2 ++ common/lib/libc.s2.c | 4 +++ common/stb_image.patch | 15 ++++++---- 9 files changed, 52 insertions(+), 89 deletions(-) delete mode 100644 common/lib/bmp.c delete mode 100644 common/lib/bmp.h diff --git a/CONFIG.md b/CONFIG.md index e3fd2a4f..caf49277 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -84,7 +84,7 @@ Limine graphical terminal control options. They are ignored if using text mode. * `TERM_FOREGROUND_BRIGHT` - Terminal text foreground bright colour (RRGGBB). * `TERM_MARGIN` - Set the amount of margin around the terminal. * `TERM_MARGIN_GRADIENT` - Set the thickness in pixel for the gradient around the terminal. -* `TERM_WALLPAPER` - URI where to find the .BMP file to use as wallpaper. +* `TERM_WALLPAPER` - URI where to find the file to use as wallpaper. BMP, PNG, and JPEG formats are supported. * `TERM_WALLPAPER_STYLE` - The style which will be used to display the wallpaper image: `tiled`, `centered`, or `stretched`. Default is `stretched`. * `TERM_BACKDROP` - When the background style is `centered`, this specifies the colour of the backdrop for parts of the screen not covered by the background image, in RRGGBB format. diff --git a/README.md b/README.md index fbc27c37..9bd75d20 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,8 @@ An example `limine.cfg` file can be found in [`test/limine.cfg`](https://github. More info on the format of `limine.cfg` can be found in [`CONFIG.md`](https://github.com/limine-bootloader/limine/blob/trunk/CONFIG.md). ## Acknowledgments -Limine uses a stripped-down version of [tinf](https://github.com/jibsen/tinf). +Limine uses a stripped-down version of [tinf](https://github.com/jibsen/tinf) for early GZIP decompression. +Limine relies on [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h) for runtime GZIP decompression and image loading. ## Discord server We have a [Discord server](https://discord.gg/QEeZMz4) if you need support, diff --git a/common/lib/bmp.c b/common/lib/bmp.c deleted file mode 100644 index 0a8cb37f..00000000 --- a/common/lib/bmp.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -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)); - -bool 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 false; - - // We don't support bpp lower than 8 - if (header.bi_bpp % 8 != 0) - return false; - - image->img = ext_mem_alloc(header.bf_size); - - uint32_t bf_size; - if (header.bf_offset + header.bf_size > file->size) { - bf_size = file->size - header.bf_offset; - } else { - bf_size = header.bf_size; - } - - fread(file, image->img, header.bf_offset, bf_size); - - image->allocated_size = header.bf_size; - - image->x_size = header.bi_width; - image->y_size = header.bi_height; - image->pitch = ALIGN_UP(header.bi_width * header.bi_bpp, 32) / 8; - image->bpp = header.bi_bpp; - image->img_width = header.bi_width; - image->img_height = header.bi_height; - - return true; -} diff --git a/common/lib/bmp.h b/common/lib/bmp.h deleted file mode 100644 index 8763d6b4..00000000 --- a/common/lib/bmp.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIB__BMP_H__ -#define __LIB__BMP_H__ - -#include -#include -#include - -bool bmp_open_image(struct image *image, struct file_handle *file); - -#endif diff --git a/common/lib/gterm.c b/common/lib/gterm.c index ec3b7e7f..b01dcd20 100644 --- a/common/lib/gterm.c +++ b/common/lib/gterm.c @@ -434,7 +434,7 @@ __attribute__((always_inline)) static inline void genloop(struct fb_info *fb, si case IMAGE_TILED: for (size_t y = ystart; y < yend; y++) { size_t image_y = y % img_height, image_x = xstart % img_width; - const size_t off = img_pitch * (img_height - 1 - image_y); + const size_t off = img_pitch * image_y; size_t canvas_off = fb->framebuffer_width * y; for (size_t x = xstart; x < xend; x++) { uint32_t img_pixel = *(uint32_t*)(img + image_x * colsize + off); @@ -448,7 +448,7 @@ __attribute__((always_inline)) static inline void genloop(struct fb_info *fb, si case IMAGE_CENTERED: for (size_t y = ystart; y < yend; y++) { size_t image_y = y - background->y_displacement; - const size_t off = img_pitch * (img_height - 1 - image_y); + const size_t off = img_pitch * image_y; size_t canvas_off = fb->framebuffer_width * y; if (image_y >= background->y_size) { /* external part */ for (size_t x = xstart; x < xend; x++) { @@ -473,7 +473,7 @@ __attribute__((always_inline)) static inline void genloop(struct fb_info *fb, si case IMAGE_STRETCHED: for (size_t y = ystart; y < yend; y++) { size_t img_y = (y * img_height) / fb->framebuffer_height; // calculate Y with full precision - size_t off = img_pitch * (img_height - 1 - img_y); + size_t off = img_pitch * img_y; size_t canvas_off = fb->framebuffer_width * y; size_t ratio = int_to_fixedp6(img_width) / fb->framebuffer_width; diff --git a/common/lib/image.c b/common/lib/image.c index bc2d0319..758ee312 100644 --- a/common/lib/image.c +++ b/common/lib/image.c @@ -1,9 +1,10 @@ #include #include +#include #include #include #include -#include +#include void image_make_centered(struct image *image, int frame_x_size, int frame_y_size, uint32_t back_colour) { image->type = IMAGE_CENTERED; @@ -26,11 +27,36 @@ struct image *image_open(struct file_handle *file) { image->type = IMAGE_TILED; - if (bmp_open_image(image, file)) - return image; + void *src = ext_mem_alloc(file->size); - pmm_free(image, sizeof(struct image)); - return NULL; + fread(file, src, 0, file->size); + + int x, y, bpp; + + image->img = stbi_load_from_memory(src, file->size, &x, &y, &bpp, 4); + + pmm_free(src, file->size); + + if (image->img == NULL) { + pmm_free(image, sizeof(struct image)); + return NULL; + } + + // Convert ABGR to XRGB + uint32_t *pptr = (void *)image->img; + for (int i = 0; i < x * y; i++) { + pptr[i] = (pptr[i] & 0x0000ff00) | ((pptr[i] & 0x00ff0000) >> 16) | ((pptr[i] & 0x000000ff) << 16); + } + + image->allocated_size = x * y * 4; + image->x_size = x; + image->y_size = y; + image->pitch = x * 4; + image->bpp = 32; + image->img_width = x; + image->img_height = y; + + return image; } void image_close(struct image *image) { diff --git a/common/lib/libc.h b/common/lib/libc.h index 7e8add9d..19b50fc9 100644 --- a/common/lib/libc.h +++ b/common/lib/libc.h @@ -10,6 +10,8 @@ bool isspace(int c); int toupper(int c); int tolower(int c); +int abs(int i); + void *memset(void *, int, size_t); void *memcpy(void *, const void *, size_t); int memcmp(const void *, const void *, size_t); diff --git a/common/lib/libc.s2.c b/common/lib/libc.s2.c index 34f93a1f..c3eda16d 100644 --- a/common/lib/libc.s2.c +++ b/common/lib/libc.s2.c @@ -26,6 +26,10 @@ int tolower(int c) { return c; } +int abs(int i) { + return i < 0 ? -i : i; +} + char *strcpy(char *dest, const char *src) { size_t i; diff --git a/common/stb_image.patch b/common/stb_image.patch index ebeb5312..56d4c47c 100644 --- a/common/stb_image.patch +++ b/common/stb_image.patch @@ -1,6 +1,6 @@ ---- common/stb/stb_image.h 2023-02-18 09:34:39.771655260 +0100 -+++ common/stb/stb_image.h 2023-02-18 09:35:26.014990183 +0100 -@@ -127,6 +127,28 @@ +--- common/stb/stb_image.h 2023-03-05 06:32:45.628671768 +0100 ++++ common/stb/stb_image.h 2023-03-05 07:47:29.931051098 +0100 +@@ -127,6 +127,31 @@ #ifndef STBI_INCLUDE_STB_IMAGE_H #define STBI_INCLUDE_STB_IMAGE_H @@ -25,11 +25,14 @@ + +#define STBI_ONLY_ZLIB +#define STBI_SUPPORT_ZLIB ++#define STBI_ONLY_JPEG ++#define STBI_ONLY_PNG ++#define STBI_ONLY_BMP + // DOCUMENTATION // // Limitations: -@@ -381,7 +403,7 @@ +@@ -381,7 +406,7 @@ STBI_rgb_alpha = 4 }; @@ -38,7 +41,7 @@ typedef unsigned char stbi_uc; typedef unsigned short stbi_us; -@@ -584,8 +606,8 @@ +@@ -584,8 +609,8 @@ #include #include // ptrdiff_t on osx @@ -49,7 +52,7 @@ #include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -@@ -1574,10 +1596,12 @@ +@@ -1574,10 +1599,12 @@ STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } #endif