Skip to content

Instantly share code, notes, and snippets.

@tesuji
Last active February 5, 2018 03:56
Show Gist options
  • Save tesuji/355f673740a29587953340a266ae34b6 to your computer and use it in GitHub Desktop.
Save tesuji/355f673740a29587953340a266ae34b6 to your computer and use it in GitHub Desktop.
Read headers of BMP image file type.
CC=gcc
CFLAGS=-Wfatal-errors -std=gnu11 -Wall
readbmp.elf: readbmp.c
$(CC) $(CFLAGS) -o $@ $^
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
typedef struct __attribute__((__packed__)) FileHeader
{
unsigned short bfType; // 2 bytes -- The characters "BM"
unsigned int bfSize; // 4 bytes -- The size of the file in bytes
unsigned short bfReserved1; // 2 bytes -- Unused - must be zero
unsigned short bfReserved2; // 2 bytes -- Unused - must be zero
unsigned int bfOffBits; // 4 bytes -- Offset to start of Pixel Data
} FileHeader;
typedef struct __attribute__((__packed__)) ImageHeader
{
unsigned int biSize; // 4 -- Header Size - Must be at least 40
unsigned int biWidth; // 4 -- Image width in pixels
unsigned int biHeight; // 4 -- Image height in pixels
unsigned short biPlanes; // 2 -- Must be 1
unsigned short biBitCount; // 2 -- Bits per pixel - 1, 4, 8, 16, 24, or 32
unsigned int biCompression; // 4 -- Compression type (0 = uncompressed)
unsigned int biSizeImage; // 4 -- Image Size - may be zero for uncompressed images
unsigned int biXPelsPerMeter; // 4 -- Preferred resolution in pixels per meter
unsigned int biYPelsPerMeter; // 4 -- Preferred resolution in pixels per meter
unsigned int biClrUsed; // 4 -- Number Color Map entries that are actually used
unsigned int biClrImportant; // 4 -- Number of significant colors
} ImageHeader;
void usage(char const *programe_name)
{
printf("%s -- Print all image headers\n", programe_name);
printf("Usage: %s <image_file>\n", programe_name);
exit(1);
}
int main(int argc, char const *argv[])
{
if (argc < 2)
{
usage(argv[0]);
}
FILE *imgfile = fopen(argv[1], "rb");
if (imgfile == NULL)
{
perror("Cannot open image file.");
exit(2);
}
FileHeader fileHeader;
ImageHeader imgHeader;
size_t nItem = 0;
nItem = fread(&fileHeader, sizeof(FileHeader), 1, imgfile);
if (nItem != 1)
{
puts("Corrupted file.");
printf("Number:%lu\n", nItem);
fclose(imgfile);
exit(3);
}
nItem = fread(&imgHeader, sizeof(ImageHeader), 1, imgfile);
if (nItem != 1)
{
puts("Corrupted file.");
fclose(imgfile);
exit(3);
}
if ((fileHeader.bfType != 0x4d42) || (fileHeader.bfReserved1 != 0)
|| (fileHeader.bfReserved2 != 0))
{
puts("Not BMP file type.");
printf("bfType:%d, bfReserved1:%d, bfReserved2:%d\n",
fileHeader.bfType, fileHeader.bfReserved1, fileHeader.bfReserved2);
fclose(imgfile);
exit(4);
}
puts("================================================");
printf("File Name : %s\n", argv[1]);
printf("Offset to start of Pixel Data : %d\n", fileHeader.bfOffBits);
printf("Header Size - Must be at least 40 : %d\n", imgHeader.biSize);
printf("Image size (width x height in pixels) : %dx%d\n", imgHeader.biWidth, imgHeader.biHeight);
printf("Must be 1 : %d\n", imgHeader.biPlanes);
printf("Bits per pixel - 1, 4, 8, 16, 24, or 32 : %d\n", imgHeader.biBitCount);
printf("Compression type (0 = uncompressed) : %d\n", imgHeader.biCompression);
printf("Image Size - may be zero for uncompressed images: %d\n", imgHeader.biSizeImage);
printf("Preferred resolution in pixels per meter : %d\n", imgHeader.biXPelsPerMeter);
printf("Preferred resolution in pixels per meter : %d\n", imgHeader.biYPelsPerMeter);
printf("Number Color Map entries that are actually used : %d\n", imgHeader.biClrUsed);
printf("Number of significant colors : %d\n", imgHeader.biClrImportant);
fclose(imgfile);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment