:: commit 296e0a2684479552d0cd2bca3d5aff25e08e6e4d

mintsuki <mintsuki@protonmail.com> — 2023-03-05 06:57

parents: af495884ba

image: Use stb_image for image loading

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 <stdint.h>
-#include <fs/file.h>
-#include <lib/image.h>
-#include <lib/bmp.h>
-#include <lib/libc.h>
-#include <lib/misc.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));
-
-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 <stdint.h>
-#include <fs/file.h>
-#include <lib/image.h>
-
-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 <stdint.h>
 #include <stddef.h>
+#include <lib/image.h>
 #include <lib/config.h>
 #include <lib/misc.h>
 #include <mm/pmm.h>
-#include <lib/bmp.h>
+#include <stb/stb_image.h>
 
 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 <stdarg.h>
  #include <stddef.h> // ptrdiff_t on osx
@@ -49,7 +52,7 @@
  #include <limits.h>
  
  #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
  
tab: 248 wrap: offon