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; }