Search code examples
c++bmp

Putting parts of array into struct


I am parsing a bitmap header (just for fun) and I'm having trouble putting the data into a struct. This is my code:

#include <iostream>
#include <fstream>

using namespace std;

struct bmp_header {
    char16_t id;
    int size;
    char16_t reserved1;
    char16_t reserved2;
    int offset_to_pxl_array;    
} bmp_header;

int main(int argc, char *argv[]) {
    if (argc < 2) {
        cout << "No image file specified." << endl;
        return -1;
    }
    ifstream file(argv[1], ios::in|ios::binary|ios::ate);
    streampos f_size = file.tellg();    
    char *memblock;

    if (!file.is_open()) {
        cout << "Error reading file." << endl;
        return -1;
    }

    memblock = new char[f_size];

    //Read whole file
    file.seekg(0, ios::beg);
    file.read(memblock, f_size);
    file.close();

    //Parse header
    //HOW TO PUT FIRST 14 BYTES OF memblock INTO bmp_header?

    //Output file   
    for(int x = 0; x < f_size; x++) {
        cout << memblock[x];
        if (x % 20 == 0)
            cout << endl;
    }
    cout << "End of file." << endl;

    delete[] memblock;

    return 0;
}

How do I put the first 14 elements of memblock into bmp_header? I've been trying to search a bit around the web, but most of the solutions seem to be a bit complex for such a simple problem.


Solution

  • The easiest way to do this would be to use std::ifstream and its read member function:

    std::ifstream in("input.bmp");
    bmp_header hdr;
    in.read(reinterpret_cast<char *>(&hdr), sizeof(bmp_header));
    

    There is one caveat though: Compiler will align member variables of the bmp_header. Therefore you have to prevent this. E.g. in gcc you do this by saying __attribute__((packed)):

    struct bmp_header {
        char16_t id;
        int size;
        char16_t reserved1;
        char16_t reserved2;
        int offset_to_pxl_array;    
    } __attribute__((packed));
    

    Also, as pointed by @ian-cook in the comments below, endianness needs to be taken care of as well.