1/** 2 * \file 3 * \brief BMP Loader 4 */ 5 6/* 7 * Copyright (c) 2007, 2008, 2009, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <stddef.h> 16#include <stdint.h> 17#include <string.h> 18#include <assert.h> 19 20#include "bmp.h" 21 22#define MUST(x) if(!(x)) return 1; 23 24struct bmp_header { 25 char header[2]; 26 uint32_t size; 27 uint32_t reserved; 28 uint32_t bitmap_start; 29} __attribute__ ((packed)); 30 31enum comp_alg { 32 COMP_BI_RGB = 0, 33 COMP_BI_RLE8 = 1, 34 COMP_BI_RLE4 = 2, 35 COMP_BI_BITFIELDS = 3, 36 COMP_BI_JPEG = 4, 37 COMP_BI_PNG = 5 38}; 39 40struct dib_header { 41 uint32_t size; 42 uint32_t width, height; 43 uint16_t planes; 44 uint16_t bpp; 45 enum comp_alg compression; 46 uint32_t image_size; 47 uint32_t hres, vres; 48 uint32_t colors, important; 49} __attribute__ ((packed)); 50 51int bmp_load(void *data, size_t size) 52{ 53 struct bmp_header *bh = data; 54 struct dib_header *dh = data + sizeof(struct bmp_header); 55 56 MUST(size > sizeof(struct bmp_header) + sizeof(struct dib_header)); 57 MUST(!strncmp(bh->header, "BM", 2)); 58 MUST(dh->size == 40); 59 MUST(dh->planes == 1); 60 MUST(dh->compression == COMP_BI_RGB); 61 62 char *bitmap = data + bh->bitmap_start; 63 64 assert(24 == dh->bpp); 65 assert(dh->height <= yres); 66 assert(dh->width <= xres); 67 68 size_t linesize = dh->image_size / dh->height; 69 int mbpp = dh->bpp / 8; 70 71 // BMPs are stored upside-down 72 for(size_t y = 0; y < dh->height; y++) { 73 for(size_t x = 0; x < dh->width; x++) { 74 SCREEN(x, y)[0] = bitmap[(linesize * (dh->height - y - 1)) + x * mbpp + 0]; 75 SCREEN(x, y)[1] = bitmap[(linesize * (dh->height - y - 1)) + x * mbpp + 1]; 76 SCREEN(x, y)[2] = bitmap[(linesize * (dh->height - y - 1)) + x * mbpp + 2]; 77 } 78 } 79 80 return 0; 81} 82