Added BMP header reader in D language

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2025-03-18 13:16:30 +0100
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2025-03-18 13:16:30 +0100
Commit 069304a75fa5d14b11d4fee999588530a0535cd3 (patch)
-rw-r--r-- README.md 1
-rw-r--r-- d-bmp-header/.gitignore 2
-rw-r--r-- d-bmp-header/Makefile 5
-rw-r--r-- d-bmp-header/image.bmp bin 0 B -> 1.3 KB
-rw-r--r-- d-bmp-header/main.d 111
5 files changed, 119 insertions, 0 deletions
diff --git a/README.md b/README.md
...
41
| [zig-elf](./zig-elf)                   | zig-0.14.0 | Read execution header of Elf64 format in Zig.                  |
41
| [zig-elf](./zig-elf)                   | zig-0.14.0 | Read execution header of Elf64 format in Zig.                  |
42
| [c-bluetooth](./c-bluetooth)           | clang-17   | Scans for all Bluetooth devices.                               |
42
| [c-bluetooth](./c-bluetooth)           | clang-17   | Scans for all Bluetooth devices.                               |
43
| [d-x11](./d-x11)                       | dmd-2.110  | Uses X11 to create a basic window without any bindings needed. |
43
| [d-x11](./d-x11)                       | dmd-2.110  | Uses X11 to create a basic window without any bindings needed. |
  
44
| [d-bmp-header](./d-bmp-header)         | dmd-2.110  | Reads BMP image header and prints the information out.         |
44
  
45
  
45
## License
46
## License
46
  
47
  
...
diff --git a/d-bmp-header/.gitignore b/d-bmp-header/.gitignore
  
1
main
  
2
*.o
diff --git a/d-bmp-header/Makefile b/d-bmp-header/Makefile
  
1
main: main.d
  
2
	dmd main.d
  
3
  
  
4
run:
  
5
	./main image.bmp
diff --git a/d-bmp-header/image.bmp b/d-bmp-header/image.bmp
diff --git a/d-bmp-header/main.d b/d-bmp-header/main.d
  
1
import std.stdio;
  
2
import std.file;
  
3
import std.format;
  
4
import std.string;
  
5
import std.range;
  
6
import std.algorithm;
  
7
import std.array;
  
8
import std.math;
  
9
  
  
10
// BMP file header (14 bytes).
  
11
struct BitmapFileHeader {
  
12
	char[2] signature;      // "BM" signature
  
13
	uint fileSize;          // Size of the file in bytes
  
14
	ushort reserved1;       // Reserved (0)
  
15
	ushort reserved2;       // Reserved (0)
  
16
	uint dataOffset;        // Offset to the start of image data
  
17
}
  
18
  
  
19
// BMP info header (40 bytes for BITMAPINFOHEADER).
  
20
struct BitmapInfoHeader {
  
21
	uint size;              // Size of this header (40 bytes)
  
22
	int width;              // Image width in pixels
  
23
	int height;             // Image height in pixels
  
24
	ushort planes;          // Number of color planes (must be 1)
  
25
	ushort bitsPerPixel;    // Bits per pixel (1, 4, 8, 16, 24, or 32)
  
26
	uint compression;       // Compression method (0 = none, 1 = RLE-8, 2 = RLE-4)
  
27
	uint imageSize;         // Size of the image data in bytes
  
28
	int xPixelsPerMeter;    // Horizontal resolution (pixels per meter)
  
29
	int yPixelsPerMeter;    // Vertical resolution (pixels per meter)
  
30
	uint colorsUsed;        // Number of colors in the palette
  
31
	uint importantColors;   // Number of important colors used (0 = all)
  
32
}
  
33
  
  
34
// RGB pixel structure.
  
35
struct RGB {
  
36
	ubyte blue;
  
37
	ubyte green;
  
38
	ubyte red;
  
39
  
  
40
	string toString() const {
  
41
		return format("RGB(%d, %d, %d)", red, green, blue);
  
42
	}
  
43
}
  
44
  
  
45
void main(string[] args) {
  
46
	if (args.length < 2) {
  
47
		writeln("Usage: main <filename.bmp>");
  
48
		return;
  
49
	}
  
50
  
  
51
	string fileName = args[1];
  
52
  
  
53
	try {
  
54
		// Read the file.
  
55
		auto file = File(fileName, "rb");
  
56
  
  
57
		// Read the BMP file header.
  
58
		BitmapFileHeader fileHeader;
  
59
		file.rawRead((&fileHeader)[0..1]);
  
60
  
  
61
		// Check if it's a valid BMP file
  
62
		if (fileHeader.signature != "BM") {
  
63
			writeln("Error: Not a valid BMP file");
  
64
			return;
  
65
		}
  
66
  
  
67
		// Read the BMP info header.
  
68
		BitmapInfoHeader infoHeader;
  
69
		file.rawRead((&infoHeader)[0..1]);
  
70
  
  
71
		// Display header information.
  
72
		writeln("BMP File Header Information:");
  
73
		writefln("  Signature: %s", fileHeader.signature);
  
74
		writefln("  File Size: %d bytes", fileHeader.fileSize);
  
75
		writefln("  Data Offset: %d bytes", fileHeader.dataOffset);
  
76
  
  
77
		writeln("\nBMP Info Header Information:");
  
78
		writefln("  Header Size: %d bytes", infoHeader.size);
  
79
		writefln("  Image Width: %d pixels", infoHeader.width);
  
80
		writefln("  Image Height: %d pixels", infoHeader.height);
  
81
		writefln("  Color Planes: %d", infoHeader.planes);
  
82
		writefln("  Bits Per Pixel: %d", infoHeader.bitsPerPixel);
  
83
  
  
84
		// Display compression method.
  
85
		string compressionMethod;
  
86
		switch (infoHeader.compression) {
  
87
			case 0: compressionMethod = "None (BI_RGB)"; break;
  
88
			case 1: compressionMethod = "RLE-8 (BI_RLE8)"; break;
  
89
			case 2: compressionMethod = "RLE-4 (BI_RLE4)"; break;
  
90
			case 3: compressionMethod = "Bitfields (BI_BITFIELDS)"; break;
  
91
			default: compressionMethod = format("Unknown (%d)", infoHeader.compression);
  
92
		}
  
93
		writefln("  Compression: %s", compressionMethod);
  
94
  
  
95
		writefln("  Image Size: %d bytes", infoHeader.imageSize);
  
96
		writefln("  Horizontal Resolution: %d pixels/meter", infoHeader.xPixelsPerMeter);
  
97
		writefln("  Vertical Resolution: %d pixels/meter", infoHeader.yPixelsPerMeter);
  
98
		writefln("  Colors Used: %d", infoHeader.colorsUsed);
  
99
		writefln("  Important Colors: %d", infoHeader.importantColors);
  
100
  
  
101
		// Calculate color depth information.
  
102
		int numColors = (infoHeader.bitsPerPixel <= 8) ? (1 << infoHeader.bitsPerPixel) : 0;
  
103
		if (numColors > 0) {
  
104
			writefln("  Color Palette: %d colors", numColors);
  
105
		} else {
  
106
			writefln("  Color Palette: None (direct color)");
  
107
		}
  
108
	} catch (Exception e) {
  
109
		writefln("Error reading BMP file: %s", e.msg);
  
110
	}
  
111
}