Added comments to save_bmp
This commit is contained in:
+36
-21
@@ -202,69 +202,84 @@ int main(int argc, char** argv)
|
||||
|
||||
|
||||
void save_bmp(const char *filename, unsigned char *img, size_t width, ssize_t height) {
|
||||
// Open a file at the filepath given as a stream in the program
|
||||
FILE *fptr = fopen(filename,"wb");
|
||||
if(fptr == NULL) {
|
||||
|
||||
if(fptr == NULL) { // Chech for errors with opening the file stream
|
||||
fprintf(stderr,"ERROR: Could not open output file at %s\n.",filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int actual_height = (height < 0) ? -height : height;
|
||||
size_t row_padding = (4 - (width) * 3 % 4) % 4;
|
||||
size_t row_width = width * 3 + row_padding;
|
||||
|
||||
|
||||
int actual_height = (height < 0) ? -height : height; // Calculate absolute height for iteration and calculation purposes
|
||||
size_t row_padding = (4 - (width) * 3 % 4) % 4; // Calculate padding for each row as .bmp is 4 bytes aligned
|
||||
size_t row_width = width * 3 + row_padding; // Calculate row width with padding
|
||||
|
||||
size_t image_size = actual_height * row_width;
|
||||
size_t file_size = image_size + 54;
|
||||
size_t file_size = image_size + 54; // File size = Image Size + Headers
|
||||
|
||||
// File header - contains information about the file
|
||||
unsigned char file_header[14] = {
|
||||
'B', 'M',
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
54, 0, 0, 0
|
||||
'B', 'M', // BM - identifies file as a .bmp file
|
||||
0, 0, 0, 0, // 4 bytes for file size - will be set later
|
||||
0, 0, 0, 0, // Reserved
|
||||
54, 0, 0, 0 // 4 bytes that specify the offset where the image array begins
|
||||
};
|
||||
|
||||
// Serialize the size into 4 bytes - (unsigned char) takes only bottom 4 bytes
|
||||
file_header[2] = (unsigned char)(file_size);
|
||||
file_header[3] = (unsigned char)(file_size >> 8);
|
||||
file_header[4] = (unsigned char)(file_size >> 16);
|
||||
file_header[5] = (unsigned char)(file_size >> 24);
|
||||
|
||||
// Info header - contains information about the image itself
|
||||
unsigned char info_header[40] = {
|
||||
40, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
1, 0,
|
||||
24, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0x13, 0x0B, 0, 0,
|
||||
0x13, 0x0B, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
40, 0, 0, 0, // Size of this header
|
||||
0, 0, 0, 0, // Width in pixels - set later
|
||||
0, 0, 0, 0, // Height in pixels - set later
|
||||
1, 0, // Number of color planes - always 1
|
||||
24, 0, // Number of bits per pixel or color depth
|
||||
0, 0, 0, 0, // Compression method - 0 for no compression
|
||||
0, 0, 0, 0, // Image size - set later
|
||||
0x13, 0x0B, 0, 0, // Horizontal resolution in pixels per metre - Set to standart 72 pixels per inch
|
||||
0x13, 0x0B, 0, 0, // Vertical resolution in pixels per metre - Set to standart 72 pixels per inch
|
||||
0, 0, 0, 0, // Number of colors in the color pallete - 0 for default of 2^n where n is bits per pixel
|
||||
0, 0, 0, 0 // Number of important colors - 0 for all colors important
|
||||
};
|
||||
|
||||
// Setting width
|
||||
info_header[4] = (unsigned char)(width);
|
||||
info_header[5] = (unsigned char)(width >> 8);
|
||||
info_header[6] = (unsigned char)(width >> 16);
|
||||
info_header[7] = (unsigned char)(width >> 24);
|
||||
|
||||
// Setting height
|
||||
uint32_t h = (uint32_t)height;
|
||||
info_header[8] = (unsigned char)(h);
|
||||
info_header[9] = (unsigned char)(h >> 8);
|
||||
info_header[10] = (unsigned char)(h >> 16);
|
||||
info_header[11] = (unsigned char)(h >> 24);
|
||||
|
||||
// Setting image size
|
||||
info_header[20] = (unsigned char)(image_size);
|
||||
info_header[21] = (unsigned char)(image_size >> 8);
|
||||
info_header[22] = (unsigned char)(image_size >> 16);
|
||||
info_header[23] = (unsigned char)(image_size >> 24);
|
||||
|
||||
// Write headers into file
|
||||
//size_t fwrite(const void ptr[restrict .size * .n], size_t size, size_t n, FILE *restrict stream);
|
||||
fwrite(file_header,1,14,fptr);
|
||||
fwrite(info_header,1,40,fptr);
|
||||
|
||||
// Save padding bytes as array so we can write from it easily to the file later
|
||||
unsigned char padding_bytes[3] = {0, 0, 0};
|
||||
|
||||
for(int i = 0; i < actual_height; i++) {
|
||||
// Write whole row of pixels - img + (i * width * 3) is the position of the row in the image array
|
||||
// size = 3 as we are interpreting every pixel as an object
|
||||
fwrite(img + (i * width * 3), 3, width, fptr);
|
||||
if(row_padding > 0) {
|
||||
fwrite(padding_bytes,1,row_padding,fptr);
|
||||
fwrite(padding_bytes,1,row_padding,fptr); // Write row_padding number of padding bytes to the file stream
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user