image: Use stb_image for image loading

This commit is contained in:
mintsuki 2023-03-05 07:57:54 +01:00
parent 11ef3bced2
commit 959c44658e
9 changed files with 52 additions and 89 deletions

View File

@ -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_FOREGROUND_BRIGHT` - Terminal text foreground bright colour (RRGGBB).
* `TERM_MARGIN` - Set the amount of margin around the terminal. * `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_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_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. * `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.

View File

@ -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). 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 ## 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 ## Discord server
We have a [Discord server](https://discord.gg/QEeZMz4) if you need support, We have a [Discord server](https://discord.gg/QEeZMz4) if you need support,

View File

@ -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;
}

View File

@ -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

View File

@ -434,7 +434,7 @@ __attribute__((always_inline)) static inline void genloop(struct fb_info *fb, si
case IMAGE_TILED: case IMAGE_TILED:
for (size_t y = ystart; y < yend; y++) { for (size_t y = ystart; y < yend; y++) {
size_t image_y = y % img_height, image_x = xstart % img_width; 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; size_t canvas_off = fb->framebuffer_width * y;
for (size_t x = xstart; x < xend; x++) { for (size_t x = xstart; x < xend; x++) {
uint32_t img_pixel = *(uint32_t*)(img + image_x * colsize + off); 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: case IMAGE_CENTERED:
for (size_t y = ystart; y < yend; y++) { for (size_t y = ystart; y < yend; y++) {
size_t image_y = y - background->y_displacement; 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; size_t canvas_off = fb->framebuffer_width * y;
if (image_y >= background->y_size) { /* external part */ if (image_y >= background->y_size) { /* external part */
for (size_t x = xstart; x < xend; x++) { 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: case IMAGE_STRETCHED:
for (size_t y = ystart; y < yend; y++) { 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 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 canvas_off = fb->framebuffer_width * y;
size_t ratio = int_to_fixedp6(img_width) / fb->framebuffer_width; size_t ratio = int_to_fixedp6(img_width) / fb->framebuffer_width;

View File

@ -1,9 +1,10 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <lib/image.h>
#include <lib/config.h> #include <lib/config.h>
#include <lib/misc.h> #include <lib/misc.h>
#include <mm/pmm.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) { void image_make_centered(struct image *image, int frame_x_size, int frame_y_size, uint32_t back_colour) {
image->type = IMAGE_CENTERED; image->type = IMAGE_CENTERED;
@ -26,11 +27,36 @@ struct image *image_open(struct file_handle *file) {
image->type = IMAGE_TILED; image->type = IMAGE_TILED;
if (bmp_open_image(image, file)) void *src = ext_mem_alloc(file->size);
return image;
pmm_free(image, sizeof(struct image)); fread(file, src, 0, file->size);
return NULL;
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) { void image_close(struct image *image) {

View File

@ -10,6 +10,8 @@ bool isspace(int c);
int toupper(int c); int toupper(int c);
int tolower(int c); int tolower(int c);
int abs(int i);
void *memset(void *, int, size_t); void *memset(void *, int, size_t);
void *memcpy(void *, const void *, size_t); void *memcpy(void *, const void *, size_t);
int memcmp(const void *, const void *, size_t); int memcmp(const void *, const void *, size_t);

View File

@ -26,6 +26,10 @@ int tolower(int c) {
return c; return c;
} }
int abs(int i) {
return i < 0 ? -i : i;
}
char *strcpy(char *dest, const char *src) { char *strcpy(char *dest, const char *src) {
size_t i; size_t i;

View File

@ -1,6 +1,6 @@
--- common/stb/stb_image.h 2023-02-18 09:34:39.771655260 +0100 --- common/stb/stb_image.h 2023-03-05 06:32:45.628671768 +0100
+++ common/stb/stb_image.h 2023-02-18 09:35:26.014990183 +0100 +++ common/stb/stb_image.h 2023-03-05 07:47:29.931051098 +0100
@@ -127,6 +127,28 @@ @@ -127,6 +127,31 @@
#ifndef STBI_INCLUDE_STB_IMAGE_H #ifndef STBI_INCLUDE_STB_IMAGE_H
#define STBI_INCLUDE_STB_IMAGE_H #define STBI_INCLUDE_STB_IMAGE_H
@ -25,11 +25,14 @@
+ +
+#define STBI_ONLY_ZLIB +#define STBI_ONLY_ZLIB
+#define STBI_SUPPORT_ZLIB +#define STBI_SUPPORT_ZLIB
+#define STBI_ONLY_JPEG
+#define STBI_ONLY_PNG
+#define STBI_ONLY_BMP
+ +
// DOCUMENTATION // DOCUMENTATION
// //
// Limitations: // Limitations:
@@ -381,7 +403,7 @@ @@ -381,7 +406,7 @@
STBI_rgb_alpha = 4 STBI_rgb_alpha = 4
}; };
@ -38,7 +41,7 @@
typedef unsigned char stbi_uc; typedef unsigned char stbi_uc;
typedef unsigned short stbi_us; typedef unsigned short stbi_us;
@@ -584,8 +606,8 @@ @@ -584,8 +609,8 @@
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> // ptrdiff_t on osx #include <stddef.h> // ptrdiff_t on osx
@ -49,7 +52,7 @@
#include <limits.h> #include <limits.h>
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) #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; } STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
#endif #endif