BMP Header Info
Following the tradition of analysing image headers, I have made another small program in C to read header information from BMP (BitMaP) images. There does not seem to be a complete specification of BMP images, so the program is based on various information found on the Internet.
This program works the same way as the other one; by reading the image as standard input, and presenting information in human readable form on standard out.
#include <stdio.h>
typedef struct bmp_infoheader_s {
unsigned long int header_size;
signed long int width, height;
unsigned short int planes;
unsigned short int bits;
unsigned long int compression;
unsigned long int image_size;
signed long int xres, yres;
unsigned long int colors;
unsigned long int imp_colors;
} bmp_infoheader_t;
int main(void)
{
bmp_infoheader_t infoheader;
char *p;
/* First header cannot be defined as a structure, because of aligment
problems with the compiler. */
unsigned short int bmp_header_type;
unsigned long int bmp_header_size;
unsigned short int bmp_header_reserved_1, bmp_header_reserved_2;
unsigned long int bmp_header_offset;
/* Read first header (in many steps). */
fread(&bmp_header_type, sizeof(unsigned short int), 1, stdin);
fread(&bmp_header_size, sizeof(unsigned long int), 1, stdin);
fread(&bmp_header_reserved_1, sizeof(unsigned short int), 1, stdin);
fread(&bmp_header_reserved_2, sizeof(unsigned short int), 1, stdin);
fread(&bmp_header_offset, sizeof(unsigned long int), 1, stdin);
if (feof(stdin)) {
fprintf(stderr, "Error: Could not read first BMP header.\n");
return 1;
}
if (bmp_header_type != 19778) { /* (77[M] * 256) + 66[B] = 19778 */
fprintf(stderr, "Error: Not a BMP image. (%d)\n", bmp_header_type);
return 1;
}
printf("--- First Header ---\n");
printf("File size : %lu bytes\n", bmp_header_size);
printf("Reserved 1 : %hd\n", bmp_header_reserved_1);
printf("Reserved 2 : %hd\n", bmp_header_reserved_2);
printf("Image data offset: 0x%lx\n", bmp_header_offset);
/* Read second header (infoheader). */
fread(&infoheader, sizeof(bmp_infoheader_t), 1, stdin);
if (feof(stdin)) {
fprintf(stderr, "Error: Could not read second BMP header.\n");
return 1;
}
printf("--- Second Header ---\n");
printf("Header size (2nd): %lu bytes\n", infoheader.header_size);
printf("Image height : %ld pixels\n", infoheader.height);
printf("Image width : %ld pixels\n", infoheader.width);
printf("Bits per pixel : %hu\n", infoheader.bits);
switch (infoheader.compression) {
case 0:
p = "None/RGB";
break;
case 1:
p = "8-bit Run-length encoding";
break;
case 2:
p = "4-bit Run-length encoding";
break;
case 3:
p = "Bit fields";
break;
case 4:
p = "Embedded JPEG";
break;
case 5:
p = "Embedded PNG";
break;
default:
p = "Unknown";
break;
}
printf("Compression type : %lu (%s)\n", infoheader.compression, p);
printf("Image size : %lu bytes\n", infoheader.image_size);
printf("Pixels/Meter (X) : %ld\n", infoheader.xres);
printf("Pixels/Meter (Y) : %ld\n", infoheader.yres);
printf("Color planes : %hu\n", infoheader.planes);
printf("Colors in palette: %lu\n", infoheader.colors);
printf("Important colors : %lu\n", infoheader.imp_colors);
return 0;
}