diff options
| 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) | |
| tree | 86a6cb2047a940699dd6e018556047569f7e0234 /d-bmp-header/main.d | |
| parent | 4236ea42a15aaebeb6d1a872f78fafb2b1804c5a (diff) | |
| download | probe-069304a75fa5d14b11d4fee999588530a0535cd3.tar.gz | |
Added BMP header reader in D language
Diffstat (limited to 'd-bmp-header/main.d')
| -rw-r--r-- | d-bmp-header/main.d | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/d-bmp-header/main.d b/d-bmp-header/main.d new file mode 100644 index 0000000..c8fcaf0 --- /dev/null +++ b/d-bmp-header/main.d | |||
| @@ -0,0 +1,111 @@ | |||
| 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 | } | ||
