diff options
author | Anton Kling <anton@kling.gg> | 2023-10-30 22:44:02 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-31 00:18:38 +0100 |
commit | 34342b53c39aa3f22326b6e4eda960cc20cfa0f0 (patch) | |
tree | 01bc4fcbc78623e406bcfa45dd9bd04ebd915663 /userland | |
parent | 8a9208612eec8ddae4c418485d848ecfa0613699 (diff) |
Meta: Create simple build scripts for kernel, userland and general enviroment
Diffstat (limited to 'userland')
-rw-r--r-- | userland/libppm/.gitignore | 1 | ||||
-rw-r--r-- | userland/libppm/Makefile | 15 | ||||
-rw-r--r-- | userland/libppm/file.ppm | 7 | ||||
-rw-r--r-- | userland/libppm/ppm.c | 199 |
4 files changed, 222 insertions, 0 deletions
diff --git a/userland/libppm/.gitignore b/userland/libppm/.gitignore new file mode 100644 index 0000000..2f046a8 --- /dev/null +++ b/userland/libppm/.gitignore @@ -0,0 +1 @@ +ppm diff --git a/userland/libppm/Makefile b/userland/libppm/Makefile new file mode 100644 index 0000000..405e1dd --- /dev/null +++ b/userland/libppm/Makefile @@ -0,0 +1,15 @@ +CC="i686-sb-gcc" +CFLAGS = -ggdb -O3 -Wall -Wextra -pedantic +LIB=-L../libgui -lgui +INC=-I../libgui/ +BINS=ppm +all: $(BINS) + +ppm.o: ppm.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +ppm: ppm.o + $(CC) $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/libppm/file.ppm b/userland/libppm/file.ppm new file mode 100644 index 0000000..2925e2e --- /dev/null +++ b/userland/libppm/file.ppm @@ -0,0 +1,7 @@ +P3 +4 4 +15 + 0 0 0 0 0 0 0 0 0 15 0 15 + 0 0 0 0 15 7 0 0 0 0 0 0 + 0 0 0 0 0 0 0 15 7 0 0 0 +15 0 15 0 0 0 0 0 0 0 0 0 diff --git a/userland/libppm/ppm.c b/userland/libppm/ppm.c new file mode 100644 index 0000000..030c68d --- /dev/null +++ b/userland/libppm/ppm.c @@ -0,0 +1,199 @@ +// Very unfinished application that can view images and set the +// wallpaper. It only supports ppm3 and ppm6 files. +#include <assert.h> +#include <fcntl.h> +#include <libgui.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +GUI_Window *global_w; + +struct PPM_IMAGE { + uint8_t version; + uint32_t width; + uint32_t height; + uint32_t maxval; + long file_location; +}; + +int parse_ppm_header(FILE *fp, struct PPM_IMAGE *img) { + char magic[3]; + int width; + int height; + int maxval; + // TODO: Use %2s when scanf supports that + char c1; + char c2; + fscanf(fp, "%c%c\n%d %d\n%d", &c1, &c2, &width, &height, &maxval); + if ('P' != c1) + return 0; + if (!isdigit(c2)) + return 0; + img->version = c2 - '0'; + if (3 != img->version && 6 != img->version) + return 0; + if (maxval > 255) { + printf("maxval is: %d\n", maxval); + return 0; + } + img->width = width; + img->height = height; + img->maxval = maxval; + img->file_location = ftell(fp); + printf("width: %d\n", img->width); + printf("height: %d\n", img->height); + return 1; +} + +inline uint32_t low_32_reverse(uint32_t _value) { + return (((_value & 0x000000FF) << 24) | ((_value & 0x0000FF00) << 8) | + ((_value & 0x00FF0000) >> 8)); +} + +int load_ppm6_file(FILE *fp, const struct PPM_IMAGE *img, uint32_t buf_width, + uint32_t buf_height, uint32_t *buffer) { + fseek(fp, img->file_location, SEEK_SET); + const uint8_t modifier = 255 / img->maxval; + int cx = 0; + int cy = 0; + const int n_pixels = img->width * img->height; + printf("malloc\n"); + uint8_t *rgb = malloc(3 * n_pixels); + printf("end malloc\n"); + + printf("fread"); + int rc = fread(rgb, 3, n_pixels, fp); + if (0 == rc) + return 0; + printf("end fread"); + + uint32_t *p = rgb; + if (1 == modifier) { + for (; rc--; p = ((uint8_t *)p) + 3) { + uint32_t v = *p; + buffer[cy * buf_width + cx] = + ((v & 0xFF) << 16) | ((v & 0xFF00)) | ((v & 0xFF0000) >> 16); + cx++; + if (cx == img->width) { + cx = 0; + cy++; + continue; + } + } + } else { + for (; rc--; p = ((uint8_t *)p) + 3) { + ((uint8_t *)p)[0] *= modifier; + ((uint8_t *)p)[1] *= modifier; + ((uint8_t *)p)[2] *= modifier; + uint32_t v = *p; + buffer[cy * buf_width + cx] = + ((v & 0xFF) << 16) | ((v & 0xFF00)) | ((v & 0xFF0000) >> 16); + cx++; + if (cx == img->width) { + cx = 0; + cy++; + continue; + } + } + } + return 1; +} + +int load_ppm3_file(FILE *fp, const struct PPM_IMAGE *img, uint32_t buf_width, + uint32_t buf_height, uint32_t *buffer) { + fseek(fp, img->file_location, SEEK_SET); + uint8_t modifier = 255 / img->maxval; + int cx = 0; + int cy = 0; + for (int i = 0; i < img->width * img->height; i++) { + int red; + int green; + int blue; + int rc = fscanf(fp, "%d %d %d", &red, &green, &blue); + if (0 == rc) + break; + red &= 0xFF; + green &= 0xFF; + blue &= 0xFF; + red *= modifier; + green *= modifier; + blue *= modifier; + if (3 != rc) { + printf("not 3: %d\n", rc); + return 0; + } + buffer[cy * buf_width + cx] = + (red << 8 * 2) | (green << 8 * 1) | (blue << 8 * 0); + cx++; + if (cx == img->width) { + cx = 0; + cy++; + continue; + } + } + return 1; +} + +int load_ppm_file(FILE *fp, const struct PPM_IMAGE *img, uint32_t buf_width, + uint32_t buf_height, uint32_t *buffer) { + if (3 == img->version) + return load_ppm3_file(fp, img, buf_width, buf_height, buffer); + else if (6 == img->version) + return load_ppm6_file(fp, img, buf_width, buf_height, buffer); + return 0; +} + +struct DISPLAY_INFO { + uint32_t width; + uint32_t height; + uint8_t bpp; +}; + +int main(int argc, char **argv) { + if (argc < 2) { + printf("provide command line arguments dumbass\n"); + return 1; + } + argv++; + + int set_wallpaper = 0; + // Parse commandline arguments(shitty) + if (0 == strcmp(*argv, "-w")) { + set_wallpaper = 1; + argv++; + } + + const char *file = *argv; + + struct PPM_IMAGE img; + FILE *fp = fopen(file, "rb"); + assert(fp); + assert(parse_ppm_header(fp, &img)); + + if (!set_wallpaper) { + global_w = GUI_CreateWindow(80, 80, img.width, img.height); + assert(global_w); + assert( + load_ppm_file(fp, &img, img.width, img.height, global_w->bitmap_ptr)); + GUI_UpdateWindow(global_w); + fclose(fp); + GUI_EventLoop(global_w, NULL); + } else { + int wallpaper_fd = shm_open("wallpaper", O_RDWR, 0); + assert(wallpaper_fd >= 0); + + struct DISPLAY_INFO inf; + int fd = open("/dev/display_info", O_READ, 0); + assert(fd >= 0); + assert(sizeof(inf) == read(fd, &inf, sizeof(inf))); + + void *rc = mmap(NULL, inf.width * inf.height * sizeof(uint32_t), 0, 0, + wallpaper_fd, 0); + assert(rc); + assert(load_ppm_file(fp, &img, inf.width, inf.height, rc)); + close(fd); + } + return 0; +} |