-
Notifications
You must be signed in to change notification settings - Fork 1
/
bmp.c
110 lines (91 loc) · 3.33 KB
/
bmp.c
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
102
103
104
105
106
107
108
109
110
#include "bmp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char* loadBMP(char* filename, DIBHeader* DIBitmapHeader) {
FILE* filePtr;
BMPFileHeader bitmapFileHeader;
unsigned char* bitmapImage;
// Open the file in read bin mode
filePtr = fopen(filename, "rb");
if (filePtr == NULL) {
return NULL;
}
// Read the BMP header into the struct
fread(&bitmapFileHeader, sizeof(BMPFileHeader), 1, filePtr);
// Check if this is a BMP file with the signature
if (bitmapFileHeader.signature != 0x4D42) {
fclose(filePtr);
return NULL;
}
// Read the DIB header into the struct
fread(DIBitmapHeader, sizeof(DIBHeader), 1, filePtr);
if (DIBitmapHeader->imageSizeBytes == 0) {
DIBitmapHeader->imageSizeBytes =
((DIBitmapHeader->imgHeight * DIBitmapHeader->imgWidth) * DIBitmapHeader->bitsPerPixel) / 8;
}
// This shifts the the file position pointer (similar to say, a cursor
// pointer) to the beginning of the bitmap data. The bitmap data is located
// after the header (containing all the metadata), which is of 54 bytes.
// However, this offset is also in the bitmap header, in this case, the
// defined offset property.
fseek(filePtr, bitmapFileHeader.offset, SEEK_SET);
// Allocate memory to save pixel array
bitmapImage = (unsigned char*)malloc(DIBitmapHeader->imageSizeBytes);
// Check malloc
if (!bitmapImage) {
free(bitmapImage);
fclose(filePtr);
return NULL;
}
// read in the bitmap image data
fread(bitmapImage, DIBitmapHeader->imageSizeBytes, 1, filePtr);
// Check if it worked
if (bitmapImage == NULL) {
fclose(filePtr);
return NULL;
}
// BGR -> RGB
unsigned char tempRGB; // our swap variable
int increment = DIBitmapHeader->bitsPerPixel / 8;
for (int imageIdx = 0; imageIdx < DIBitmapHeader->imageSizeBytes;
imageIdx += increment) {
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
// Reverse the rows
const int32_t rows = DIBitmapHeader->imgHeight;
const int32_t cols = DIBitmapHeader->imgWidth;
for (int j = 0; j < rows / 2 ; j++) {
for (int i = 0; i < cols; i++) {
int idxFrom = (j * cols + i) * increment;
int idxTo = ((rows - j - 1) * cols + i) * increment;
int offset;
for (offset = 0; offset < increment; offset++) {
unsigned char temp = bitmapImage[idxFrom + offset];
bitmapImage[idxFrom + offset] = bitmapImage[idxTo + offset];
bitmapImage[idxTo + offset] = temp;
}
}
}
fclose(filePtr);
return bitmapImage;
}
void getBufferArray(unsigned char* imageData, uint32_t size,
const unsigned int bSize, color* buffer[bSize]) {
int counter = 0;
for (int i = 0; i < size; i += 4) {
int r = imageData[i];
int g = imageData[i + 1];
int b = imageData[i + 2];
int greyVal = ((float)r + (float)g + (float)b) / 3;
color* col = (color*)malloc(sizeof(color));
col->r = r;
col->g = g;
col->b = b;
col->grey = greyVal;
buffer[counter] = col;
counter++;
}
}