|
发表于 2021-6-2 15:59:34
|
显示全部楼层
参考
https://www.cnblogs.com/wainiwann/p/7086844.html
bmp.h
- #ifndef _READ_BMP_H_
- #define _READ_BMP_H_
- #include <stddef.h>
- #include <stdint.h>
- typedef struct {
- size_t width, height;
- uint8_t *data;
- } *bmp_t;
- bmp_t bmp_init(const char *filename);
- void bmp_deinit(bmp_t bmp);
- uint32_t bmp_get_pixel(const bmp_t bmp, size_t x, size_t y);
- #endif
复制代码
bmp.c
- #include "bmp.h"
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #define BI_RGB 0
- typedef struct tagBITMAPFILEHEADER {
- uint16_t bfType;
- uint32_t bfSize;
- uint16_t bfReserved1;
- uint16_t bfReserved2;
- uint32_t bfOffBits;
- } __attribute__((packed)) BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
- typedef struct tagBITMAPINFOHEADER {
- uint32_t biSize;
- uint32_t biWidth;
- uint32_t biHeight;
- uint16_t biPlanes;
- uint16_t biBitCount;
- uint32_t biCompression;
- uint32_t biSizeImage;
- uint32_t biXPelsPerMeter;
- uint32_t biYPelsPerMeter;
- uint32_t biClrUsed;
- uint32_t biClrImportant;
- } __attribute__((packed)) BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
- static bmp_t parse_bmp(uint8_t *base) {
- PBITMAPFILEHEADER bfh = (PBITMAPFILEHEADER)base;
- PBITMAPINFOHEADER bih = (PBITMAPINFOHEADER)(bfh + 1);
- uint8_t *bmp_data = base + bfh->bfOffBits;
- if(!(bih->biBitCount == 24 && bih->biCompression == BI_RGB)) return NULL;
- bmp_t bmp = malloc(sizeof(*bmp));
- if(!bmp) return NULL;
- bmp->width = bih->biWidth;
- bmp->height = bih->biHeight;
- bmp->data = malloc(bmp->width * bmp->height * 4);
- if(!bmp->data) {
- free(bmp); return NULL;
- }
- size_t row_size = bmp->width * 3;
- row_size = row_size & 0x03 ? (row_size & ~0x03) + 4 : row_size;
- uint32_t *dest_pixel = (uint32_t *)bmp->data;
- for(size_t h = 0; h < bmp->height; ++h) {
- uint8_t *row_base = bmp_data + (bmp->height - h - 1) * row_size;
- for(size_t w = 0; w < bmp->width; ++w) {
- uint8_t *rgb = row_base + w * 3;
- uint32_t src_pixel = rgb[0] | rgb[1] << 8 | rgb[2] << 16;
- dest_pixel[h * bmp->width + w] = src_pixel;
- }
- }
- return bmp;
- }
- bmp_t bmp_init(const char *filename) {
- if(!filename) return NULL;
- int fd = open(filename, O_RDONLY);
- if(fd < 0) return NULL;
- struct stat stat_buf;
- fstat(fd, &stat_buf);
- uint8_t *bmp_file = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if(bmp_file == MAP_FAILED) {
- close(fd); return NULL;
- }
- bmp_t bmp = parse_bmp(bmp_file);
- munmap(bmp_file, stat_buf.st_size);
- close(fd);
- return bmp;
- }
- void bmp_deinit(bmp_t bmp) {
- if(bmp) free(bmp->data);
- free(bmp);
- }
- uint32_t bmp_get_pixel(const bmp_t bmp, size_t x, size_t y) {
- if(!(x < bmp->width && y < bmp->height)) return 0;
- return ((uint32_t *)bmp->data)[y * bmp->width + x];
- }
复制代码
main.c
- #include "bmp.h"
- #include <SDL.h>
- int main(void) {
- bmp_t bmp = bmp_init("pic.bmp");
- SDL_Init(SDL_INIT_EVERYTHING);
- SDL_Window *win = SDL_CreateWindow("hello world", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, \
- bmp->width, bmp->height, SDL_WINDOW_SHOWN);
- SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
- for(size_t h = 0; h < bmp->height; ++h) {
- for(size_t w = 0; w < bmp->width; ++w) {
- uint32_t pixel = bmp_get_pixel(bmp, w, h);
- uint8_t a = (pixel >> 24) & 0xff;
- uint8_t r = (pixel >> 16) & 0xff;
- uint8_t g = (pixel >> 8) & 0xff;
- uint8_t b = (pixel >> 0) & 0xff;
- SDL_SetRenderDrawColor(ren, r, g, b, a);
- SDL_RenderDrawPoint(ren, w, h);
- }
- }
- SDL_RenderPresent(ren);
- SDL_Delay(3000);
- SDL_DestroyRenderer(ren);
- SDL_DestroyWindow(win);
- SDL_Quit();
- bmp_deinit(bmp);
- return 0;
- }
复制代码 |
|