From 76d8bd47c6f6a47742c986ad9146e6ae59fca053 Mon Sep 17 00:00:00 2001 From: jonas Date: Tue, 19 Feb 2019 01:46:05 +0100 Subject: Moved all bitmap stuff to bitmap.h / .c --- Makefile | 4 +- bitmap.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bitmap.h | 68 ++++++++++++++++++++++++++++ main.c | 2 +- 4 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 bitmap.c create mode 100644 bitmap.h diff --git a/Makefile b/Makefile index dee2c36..952a4fe 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ LDFLAGS = -lm OUTPUT = bitmap BUILDDIR = build -FILE = a +FILE = 022 -OBJ = main.o +OBJ = main.o bitmap.o build: $(OBJ) mkdir -p $(BUILDDIR) diff --git a/bitmap.c b/bitmap.c new file mode 100644 index 0000000..3ca2236 --- /dev/null +++ b/bitmap.c @@ -0,0 +1,156 @@ +#include "bitmap.h" + +uint32_t bitmap_flip_byte(unsigned char* _v, int _c) +{ + uint32_t ret = 0; + uint32_t counter = (_c-1) * 8; + + for(int i = 0; i < _c; i++) + { + ret |= (uint32_t)(_v[i] << (counter)); + counter -= 8; + } + + return ret; +}//flip + +struct bitmap_pixel_data bitmap_read(char *_file) +{ + struct bitmap_pixel_data ret; + struct bitmap_file_header header; + + ret.R = ret.G = ret.B = NULL; + + FILE *bitmap = fopen(_file,"r"); + + if(!bitmap) + return ret; + + header = bitmap_read_file_header(bitmap); + + if(header.error) + return ret; + + if(header.biBitCount != 24) + return ret; + + if(header.biCompression != 0) + return ret; + + ret = bitmap_read_pixel_data(bitmap, header); + + fclose(bitmap); + + return ret; +} + +struct bitmap_file_header bitmap_read_file_header(FILE *_file) +{ + struct bitmap_file_header ret; + unsigned char fileheader[_HEADER_SIZE]; + uint32_t read_counter = 0; + + ret.error = 1; + + size_t tt = fread((void*)&fileheader, sizeof(char), _HEADER_SIZE, _file); + read_counter += _HEADER_SIZE; + + if(!tt) + return ret; + + //Copy file header + ret.bfType = (uint16_t) bitmap_flip_byte(&fileheader[BF_TYPE], sizeof(ret.bfType)); + + if(ret.bfType != (uint16_t)IDENTIFIER) + return ret; + + ret.bfSize = (uint32_t) bitmap_flip_byte(&fileheader[BF_SIZE], sizeof(ret.bfSize)); + ret.bfOffBits = *(uint32_t*) &fileheader[BF_OFF_BITS]; + ret.biSize = *(uint32_t*) &fileheader[BI_SIZE]; + ret.biWidth = *(int32_t*) &fileheader[BI_WIDTH]; + ret.biHeight = *(int32_t*) &fileheader[BI_HEIGHT]; + ret.biBitCount = *(uint16_t*) &fileheader[BI_BIT_COUNT]; + ret.biCompression = (uint32_t) bitmap_flip_byte(&fileheader[BI_COMPRESSION], sizeof(ret.biCompression)); + ret.biSizeImage = *(uint32_t*) &fileheader[BI_SIZE_IMAGE]; + ret.biClrUsed = (uint32_t) bitmap_flip_byte(&fileheader[BI_CLR_USED], sizeof(ret.biClrUsed)); + ret.biClrImportant = (uint32_t) bitmap_flip_byte(&fileheader[BI_CLR_IMPORTANT], sizeof(ret.biClrImportant)); + + + //Read to start of Pixel block + //This block contains Colormasks and Colortables. + ret.tablesc = ret.bfOffBits - read_counter; + ret.tables = malloc(sizeof(char)* ret.tablesc); + fread(ret.tables, sizeof(char), ret.tablesc, _file); + ////////// + + ret.error = 0; + return ret; +} + +struct bitmap_pixel_data bitmap_read_pixel_data(FILE *_file, struct bitmap_file_header _header) +{ + uint32_t **bitmap_buff; + + struct bitmap_pixel_data ret; + + uint32_t row_size = _header.biWidth * 3; + while(row_size%4) + row_size++; + + ret.x = _header.biWidth; + ret.y = _header.biHeight < 0 ? -_header.biHeight: _header.biHeight; + + //If biHeight > 0 Data starts with last row!! + + //Allocate 2D array + //!! + //bitmap_buff indeces are flipped!! [y][x]!!!!! + bitmap_buff = malloc(sizeof(*bitmap_buff) * _header.biHeight); + for(int i = 0; i < ret.y; i++) + { + bitmap_buff[i] = malloc(sizeof(*bitmap_buff[i]) * _header.biWidth); + } + + //Copy Bitmap into bitmap_buff + for(int row = 0; row < _header.biHeight; row++) + { + //printf("Row %i\n", row); + //fread(bitmap_buff[row], sizeof(char), row_size, bitmap); + for(int col = 0; col < _header.biWidth; col++) + fread(&bitmap_buff[row][col], 1, 3, _file); + + for(int i = 0; i < row_size - (_header.biWidth * 3); i++) //read excess NULL-Bytes + fgetc(_file); + } + + ret.x = _header.biWidth; + ret.y = _header.biHeight < 0 ? -_header.biHeight: _header.biHeight; + + ret.R = malloc(sizeof(*ret.R) * ret.x); + ret.G = malloc(sizeof(*ret.G) * ret.x); + ret.B = malloc(sizeof(*ret.B) * ret.x); + for(int i = 0; i < ret.y; i++) + { + ret.R[i] = malloc(sizeof(*ret.R[i]) * ret.y); + ret.G[i] = malloc(sizeof(*ret.G[i]) * ret.y); + ret.B[i] = malloc(sizeof(*ret.B[i]) * ret.y); + } + + for(int y = 0; y < ret.y; y++) + { + for(int x = 0; x < ret.x; x++) + { + int row = _header.biHeight > 0 ? (ret.y - 1) - y : y; + + ret.R[x][y] = (bitmap_buff[row][x] & 0xff0000)>>16; + ret.G[x][y] = (bitmap_buff[row][x] & 0x00ff00)>>8; + ret.B[x][y] = (bitmap_buff[row][x] & 0x0000ff); + } + } + + for(int i = 0; i < ret.y; i++) + free(bitmap_buff[i]); + free(bitmap_buff); + + return ret; +} diff --git a/bitmap.h b/bitmap.h new file mode 100644 index 0000000..5c16401 --- /dev/null +++ b/bitmap.h @@ -0,0 +1,68 @@ +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +#include +#include +#include + +#define _HEADER_SIZE 54 //Fileheader + infoheader +#define IDENTIFIER 0x424d //BM BitMap identifier + +//Address Definitions +#define BF_TYPE 0x00 +#define BF_SIZE 0x02 +#define BF_OFF_BITS 0x0a + +#define BI_SIZE 0x0e +#define BI_WIDTH 0x12 +#define BI_HEIGHT 0x16 +#define BI_BIT_COUNT 0x1c +#define BI_COMPRESSION 0x1e +#define BI_SIZE_IMAGE 0x22 +#define BI_CLR_USED 0x2e +#define BI_CLR_IMPORTANT 0x32 + +#define R(x) (0xff0000 & x) >> 16 +#define G(x) (0x00ff00 & x) >> 8 +#define B(x) (0x0000ff & x) + +struct bitmap_file_header +{ + uint8_t error; + + uint16_t bfType; + uint32_t bfSize; + uint32_t bfOffBits; + + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + uint32_t biClrUsed; + uint32_t biClrImportant; + + unsigned char *tables; + uint32_t tablesc; +}; + +struct bitmap_pixel_data +{ + unsigned int x,y; + uint8_t **R; + uint8_t **G; + uint8_t **B; +}; + + +uint32_t bitmap_flip_byte(unsigned char* _v, int _c); + +struct bitmap_pixel_data bitmap_read(char *_file); + +struct bitmap_file_header bitmap_read_file_header(FILE *_file); + +struct bitmap_pixel_data bitmap_read_pixel_data(FILE *_file, struct bitmap_file_header _header); + + +#endif /* end of include guard: _BITMAP_H_ */ diff --git a/main.c b/main.c index 8d4bae2..ca2cf9b 100644 --- a/main.c +++ b/main.c @@ -25,7 +25,7 @@ #define CHAR_SIZE_Y (2 * CHAR_SIZE_X) const char map[] = {' ', ' ', '.', ',', '`', '-', '~', '"', '*', ':', ';', '<', '!', '/', '?', '%', '&', '=', '$', '#'}; -//const char map[] = {' ', '`', '.', ',', ':', ';', '\'', '+', '#', '@'}; +//const char map[] = {' ', '`', '.', ',', ':', ';', '\"', '+', '#', '@'}; //Routine for flipping bytes uint32_t flip(unsigned char* _v, int _c); -- cgit v1.2.3