image: Use stb_image for image loading
This commit is contained in:
parent
11ef3bced2
commit
959c44658e
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue