-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBitmapReadWrite.cpp
184 lines (152 loc) · 5.98 KB
/
BitmapReadWrite.cpp
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
* BitmapReadWrite.cpp - function definitions for bitmap image IO
* -------------------
* Includes function definitions for reading and writing bitmap images from/to disk
* and utility functions for summarizing header info and more.
*/
#include <stdio.h>
#include <stdlib.h>
#include "BitmapReadWrite.h"
//Bypass MSVC warnings about safe file IO functions.
#pragma warning(disable : 4996)
//Hint compiler for struct packing of size of 1 bytes
#pragma pack(1)
/*
* bitCountToNColor - determine number of colors in a bitmap image
* -------------
* Map a bitmap images bitcount to number of colors in the image.
* Returns 0 if bitcount is greater than 24.
*/
unsigned int bitCountToNColor(unsigned int bitCount) {
unsigned int nColors;
switch (bitCount) {
case 1:
nColors = 2;
break;
case 4:
nColors = 16;
break;
case 8:
nColors = 256;
break;
case 16:
nColors = 65536;
break;
default:
nColors = 0; //If bitcount is 24 or higher there will be no color palette
break;
}
return nColors;
}
/*
* ReadImage - read bitmap image from disk
* -------------
* Read bitmap image from the given path and return pointer for it.
*/
BitmapImage* ReadImage(const char* fileName) {
//Get the file and info header data from the image
BitmapFileHeader bitmapFileHeader;
BitmapInfoHeader bitmapInfoHeader;
FILE* imageFilePointer;
imageFilePointer = fopen(fileName, "rb");
if (imageFilePointer == NULL) {
printf("File is not found or an error occured while reading the file in specified path.");
return NULL;
}
fread(
&bitmapFileHeader,
sizeof(BitmapFileHeader),
1,
imageFilePointer);
fread(
&bitmapInfoHeader,
sizeof(BitmapInfoHeader),
1,
imageFilePointer
);
//Copy all of image data to the memory
BitmapImage* bitmapImage = (BitmapImage*) malloc(bitmapFileHeader.bfSize);
if (bitmapImage == NULL) {
printf("Not enough memory available for reading the bitmap file.");
return NULL;
}
bitmapImage->bitmapFileHeader = bitmapFileHeader;
bitmapImage->bitmapInfoHeader = bitmapInfoHeader;
//Set up palette before reading imagedata
unsigned int nColors = bitCountToNColor(bitmapInfoHeader.biBitCount);
//If there is a color palette, read it from the bitmap file and allocate it
if (nColors != 0) {
//sizeof(BitmapRGBTriplet) = 4 bytes, thus 4 bytes per color. 1 triplet per color
bitmapImage->bitmapColorPalette = (BitmapRGBTriplet*) malloc(4 * nColors);
if (bitmapImage->bitmapColorPalette == NULL) {
printf("Memory could not be allocated for color palette. Please check available memory and try again.");
return NULL;
}
fread(bitmapImage->bitmapColorPalette, 4 * nColors, 1, imageFilePointer);
}
//calculate image size in bytes
unsigned int rowSize = (((bitmapInfoHeader.biWidth * bitmapInfoHeader.biBitCount) + 31) / 32) * 4;
unsigned int wholeSize = rowSize * bitmapInfoHeader.biHeight;
//Allocate space and read image pixeldata
bitmapImage->bitmapImageData = (BYTE*) malloc(wholeSize);
if (bitmapImage->bitmapImageData == NULL) {
printf("Memory could not be allocated for image data. Please check available memory and try again.");
return NULL;
}
fread(bitmapImage->bitmapImageData, wholeSize, 1, imageFilePointer);
//Close the filestream
fclose(imageFilePointer);
return bitmapImage;
}
/*
* WriteImage - write bitmap image to disk
* -------------
* Writes the given bitmap image to the given path.
*/
void WriteImage(BitmapImage* bitmapImage, const char* fileName) {
FILE* imageFilePointer = fopen(fileName, "wb");
if (imageFilePointer == NULL) {
printf("The specified file could not be found or could not be read.");
return;
}
//Write info and file headers
fwrite(&(bitmapImage->bitmapFileHeader), sizeof(BitmapFileHeader), 1, imageFilePointer);
fwrite(&(bitmapImage->bitmapInfoHeader), sizeof(BitmapInfoHeader), 1, imageFilePointer);
//Determine number of colors in the image
unsigned int nColors = bitCountToNColor(bitmapImage->bitmapInfoHeader.biBitCount);
//If 0, it means bitcount is > 24 bits and these kind of images don't have a palette
if (nColors != 0) {
//Write color palette, 4-byte triplet for each color in the image
fwrite(bitmapImage->bitmapColorPalette, 4 * nColors, 1, imageFilePointer);
}
//Determine rowsize and wholesize, then write pixeldata to the file
unsigned int rowSize = ((((bitmapImage->bitmapInfoHeader.biWidth) * (bitmapImage->bitmapInfoHeader.biBitCount)) + 31) / 32) * 4;
unsigned int wholeSize = rowSize * (bitmapImage->bitmapInfoHeader.biHeight);
fwrite(bitmapImage->bitmapImageData, wholeSize, 1, imageFilePointer);
fclose(imageFilePointer);
}
/*
* SummarizeInfo - summarize all bitmap image metadata
* -------------
* Prints all data stored in given image's info and file header.
*/
void SummarizeInfo(BitmapImage* bitmapImage, const char* fileName)
{
printf("--------Info about %s image file--------\n", fileName);
printf("bfType value :%c%c\n", bitmapImage->bitmapFileHeader.bfType1, bitmapImage->bitmapFileHeader.bfType2);
printf("bfsize :%d\n", bitmapImage->bitmapFileHeader.bfSize);
printf("bfreserved1 :%d\n", bitmapImage->bitmapFileHeader.bfReserved1);
printf("bfreserved2 :%d\n", bitmapImage->bitmapFileHeader.bfReserved2);
printf("bfOffbits :%d\n", bitmapImage->bitmapFileHeader.bfOffBits);
printf("bisize :%d\n", bitmapImage->bitmapInfoHeader.biSize);
printf("Width :%d\n", bitmapImage->bitmapInfoHeader.biWidth);
printf("Height :%d\n", bitmapImage->bitmapInfoHeader.biHeight);
printf("biplane :%d\n", bitmapImage->bitmapInfoHeader.biPlanes);
printf("bibitcount :%d\n", bitmapImage->bitmapInfoHeader.biBitCount);
printf("Compression :%d\n", bitmapImage->bitmapInfoHeader.biCompression);
printf("bisizeimage :%d\n", bitmapImage->bitmapInfoHeader.biSizeImage);
printf("bix :%d\n", bitmapImage->bitmapInfoHeader.biXPelsPerMeter);
printf("biy :%d\n", bitmapImage->bitmapInfoHeader.biYPelsPerMeter);
printf("bi color used :%d\n", bitmapImage->bitmapInfoHeader.biClrImportant);
printf("bi color imp. :%d\n", bitmapImage->bitmapInfoHeader.biClrUsed);
}