// Bitmap image renderer // Author: xamidev // Licensed under the Unlicense. See the repo below. // https://github.com/xamidev/blankos #include "../kernel/kmain.h" #include #include "../kernel/initrd.h" #include "../drivers/framebuffer.h" #include "../libc/stdio.h" #include "../drivers/serial.h" #pragma pack(push, 1) typedef struct { uint16_t bfType; uint32_t bfSize; uint16_t bfReserved1; uint16_t bfReserved2; uint32_t bfOffBits; } BMPHeader; typedef struct { uint32_t biSize; int32_t biWidth; int32_t biHeight; uint16_t biPlanes; uint16_t biBitCount; uint32_t biCompression; uint32_t biSizeImage; int32_t biXPelsPerMeter; int32_t biYPelsPerMeter; uint32_t biClrUsed; uint32_t biClrImportant; } BMPInfoHeader; #pragma pack(pop) void display_bmp(uint32_t* fb, int pitch, int bpp, uint8_t* initrd, const char* filename) { // Should use dynamic allocation when heap works // Cannot go more than ~500k size for buffer // Fail zone 450k->470k // So right now the max should be 400kb img size char buffer[400*1000]; int file_status = tar_file_to_buffer(initrd, filename, buffer); if (file_status != 0) { printf("Error loading file '%s'\n", filename); return; } BMPHeader* bmp_header = (BMPHeader*)buffer; BMPInfoHeader* bmp_info = (BMPInfoHeader*) (buffer+sizeof(BMPHeader)); if (bmp_header->bfType != 0x4D42) { printf("'%s' is not a valid BMP file\n", filename); return; } int width = bmp_info->biWidth; int height = bmp_info->biHeight; int pixel_offset = bmp_header->bfOffBits; printf("%d-bit BMP, width: %d, height: %d, pixel offset: %d\n", bmp_info->biBitCount, bmp_info->biWidth, bmp_info->biHeight, bmp_header->bfOffBits); erase_cursor(); uint8_t* pixel_data = (uint8_t*)(buffer + pixel_offset); int cursor_y = (get_cursor_y()+1)*16; serial_printf(3, "cursor_y=%d\n", cursor_y); for (int y=cursor_y; y\n"); return; } display_bmp(framebuffer, pitch, bpp, (uint8_t*)initrd_addr, argv[1]); }