See the wiki to briefly understand a BMP file format:

https://en.wikipedia.org/wiki/BMP_file_format#Example_1

The following shows how a very simple bitmap file’s content (2x2, 4 pixels) looks like.

Untitled

Following is an example of a 2×2 pixel, 24-bit bitmap (Windows DIB header BITMAPINFOHEADER) with pixel format RGB24.

Offset Size Hex value Value Description
BMP Header
0h 2 42 4D "BM" ID field (42h, 4Dh)
2h 4 46 00 00 00 70 bytes (54+16) Size of the BMP file (54 bytes header + 16 bytes data)
6h 2 00 00 Unused Application specific
8h 2 00 00 Unused Application specific
Ah 4 36 00 00 00 54 bytes (14+40) Offset where the pixel array (bitmap data) can be found
DIB Header
Eh 4 28 00 00 00 40 bytes Number of bytes in the DIB header (from this point)
12h 4 02 00 00 00 2 pixels (left to right order) Width of the bitmap in pixels
16h 4 02 00 00 00 2 pixels (bottom to top order) Height of the bitmap in pixels. Positive for bottom to top pixel order.
1Ah 2 01 00 1 plane Number of color planes being used
1Ch 2 18 00 24 bits Number of bits per pixel
1Eh 4 00 00 00 00 0 BI_RGB, no pixel array compression used
22h 4 10 00 00 00 16 bytes Size of the raw bitmap data (including padding)
26h 4 13 0B 00 00 2835 pixels/metre horizontal Print resolution of the image,72 DPI × 39.3701 inches per metre yields 2834.6472
2Ah 4 13 0B 00 00 2835 pixels/metre vertical
2Eh 4 00 00 00 00 0 colors Number of colors in the palette
32h 4 00 00 00 00 0 important colors 0 means all colors are important
Start of pixel array (bitmap data)
36h 3 00 00 FF 0 0 255 Red, Pixel (x=0, y=1)
39h 3 FF FF FF 255 255 255 White, Pixel (x=1, y=1)
3Ch 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)
3Eh 3 FF 00 00 255 0 0 Blue, Pixel (x=0, y=0)
41h 3 00 FF 00 0 255 0 Green, Pixel (x=1, y=0)
44h 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)

Examples

1. Structure and Code

With the above information, you can define structures as follows:

(If your descriptions include similar level of information of the following structures and pseudo code, it should be sufficient. If you are in doubt, ask or try the same style pseudo code).

struct BMP_HEADER {
  char magic[2]; // “BM”  
  int  size; // size of the entire file
  int  unused;
  **int  bitmapDataOffset; // bitmap data offset**
};
struct DIB_HEADER {
  int size_DIBHeader; // size of DIB_HEADER (including the unused part).
  **int width;  // width and height of the image define the size of BITMAPDATA
  int height; // width and height of the image define the size of BITMAPDATA**
  short colorPlane;
  short bitsPerPixel;
  int unused;
  **int sizeRawBitmapData; // raw size of the bitmap data (= width * height * 4)**
  int resolutionHorizontal;
  int resolutionVertical;
  int numOfColorsPallete;
  int numOfImportantColors;
  char unused[...]; // DIB_HEADER's size is defeined by size_DIBHeader
};
typedef unsigned char byte;
struct BITMAPDATA {
  byte R;
  byte G;
  byte B;
};

Then, with the above structures, you can explain as follows:

// A pseudo program can parse as follows
// fread(BUFFER, bytes_to_read, FILE);
// fseek(FILE, offset);
procedure parse(FILE* fp) {
  // BMP HEADER
  fread(&bmp_header, sizeof(BMP_HEADER), fp);
  // DIB HEADER
  fread(&dib_header, sizeof(int), fp); // just read 4 bytes (for the size)
  fseek(fp, sizeof(BMP_HEADER)); // set the file pointer 4 bytes back
  fread(&dib_header, dib_header.**size_DIBHeader**, fp); // read the entire header

  // BITMAP DATA
  fseek(fp, bmp_header.**bitmapDataOffset**);
  fread(bmpData, dib_header.**sizeRawBitmapData**, fp);
  
  // It is important to show how each of the elements can be accessed.
  // Use access() function to demonstrate those.
  for( i = 0; i < dib_header.height; i++ ) {
    BITMAPDATA* pixels = bmpData;
    pixels = bmpData;

    for( j = 0; j < dib_header.width; j++ ) {
      // pixel's RGB can be accessed
      // with pixels[j].R/G/B
      access(pixels[j].R); 
      access(pixels[j].G); 
      access(pixels[j].B);
    }

    // next line
    bmpData += (sizeof(BITMAPDATA) + 1/*1 byte is for padding*/) * 
                dib_header.width;
  }
}

2. Graphical Representation

With the structure defined as follows,

struct BMP_HEADER {
  char magic[2]; // “BM”  
  int  size; // size of the entire file
  int  unused;
  **int  bitmapDataOffset; // bitmap data offset**
};
struct DIB_HEADER {
  int size_DIBHeader; // size of DIB_HEADER (including the unused part).
  **int width;  // width and height of the image define the size of BITMAPDATA
  int height; // width and height of the image define the size of BITMAPDATA**
  short colorPlane;
  short bitsPerPixel;
  int unused;
  **int sizeRawBitmapData; // raw size of the bitmap data (= width * height * 4)**
  int resolutionHorizontal;
  int resolutionVertical;
  int numOfColorsPallete;
  int numOfImportantColors;
  char unused[...]; // DIB_HEADER's size is defeined by size_DIBHeader
};
typedef unsigned char byte;
struct BITMAPDATA {
  byte R;
  byte G;
  byte B;
};