src/shell/imgview.c (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
#include "cedos.h"
#include "stdio.h"
#include <stdint.h>
#define GMODE_TEXT 0x02
#define GMODE_VIDEO 0x13
#define MAX(x, y) (x > y ? x : y)
#define MIN(x, y) (x < y ? x : y)
typedef struct __attribute__((packed)) {
uint16_t signature;
uint32_t file_size;
uint16_t reserved_1;
uint16_t reserved_2;
uint32_t offset_pixelarray;
} BMP_FILE_HEADER;
typedef struct {
uint32_t DIB_header_size;
uint32_t image_width;
uint32_t image_height;
/* ... */
} DIB_HEADER;
uint32_t convert_endian(uint32_t value) {
uint32_t res = 0;
return value;
for (int i = 0; i < 2; i++) {
uint8_t c = value & 0x0000FFFF;
value = value >> 16;
res = res << 16;
res |= c;
}
return res;
}
void main(char *args) {
// open image file
int fd = fopen(args, "r");
if (fd < 0) {
printf("Could not find file: %s\n", args);
return;
}
int limit = 320 * 240;
BMP_FILE_HEADER bmp_header;
DIB_HEADER dib_header;
int size = 0;
size = fread(&bmp_header, sizeof(bmp_header), 1, fd);
if (size != sizeof(bmp_header)) { printf("Error while reading BMP header\n"); return; }
size = fread(&dib_header, sizeof(dib_header), 1, fd);
if (size != sizeof(dib_header)) { printf("Error while reading DIB header\n"); return; }
int offset = bmp_header.offset_pixelarray;
int width = dib_header.image_width;
int height = dib_header.image_height;
uint8_t rowbuf[512];
int off_x = 0;
int off_y = 0;
fseek(fd, offset, SEEK_SET);
// switch video mode and display image
graphics_set_mode(GMODE_VIDEO);
uint8_t *gbuff = (uint8_t*)(0xA0000);
for (int y = 0; y < MIN(height, 240); y++) {
size = fread(rowbuf, sizeof(uint8_t), width, fd);
if (size != width) {
graphics_set_mode(GMODE_TEXT);
printf("Error while reading row %i.", y);
}
for (int x = 0; x < MIN(width, 320); x++) {
int g_i = (239 - y) * 320 + x;
gbuff[g_i] = rowbuf[x];
}
}
while (1) {
char c = getchar();
if (c == 0x1B) { break; }
}
graphics_set_mode(GMODE_TEXT);
}