1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#ifndef __BMP_H_V2__
#define __BMP_H_V2__
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

static const size_t BMP_HEADER_SIZE = 54;
static const size_t DIB_HEADER_SIZE = 40;

#pragma pack(push)  // save the original data alignment
#pragma pack(1)     // Set data alignment to 1 byte boundary

// uint16_t is a 16-bit unsigned integer
// uint32_t is a 32-bit unsigned integer

typedef struct {
    uint16_t type;              // Magic identifier: 0x4d42
    uint32_t size;              // File size in bytes
    uint16_t reserved1;         // Not used
    uint16_t reserved2;         // Not used
    uint32_t offset;            // Offset to image data in bytes from beginning of file
    uint32_t dib_header_size;   // DIB Header size in bytes
    int32_t  width_px;          // Width of the image
    int32_t  height_px;         // Height of image
    uint16_t num_planes;        // Number of color planes
    uint16_t bits_per_pixel;    // Bits per pixel
    uint32_t compression;       // Compression type
    uint32_t image_size_bytes;  // Image size in bytes
    int32_t  x_resolution_ppm;  // Pixels per meter
    int32_t  y_resolution_ppm;  // Pixels per meter
    uint32_t num_colors;        // Number of colors  
    uint32_t important_colors;  // Important colors
} BMPHeader;

#pragma pack(pop) // restore the previous pack setting

typedef struct {
    BMPHeader header;
    unsigned char* data; 
} BMPImage;

BMPImage* read_bmp(FILE* fp, const char** a_error);
bool      check_bmp_header(const BMPHeader* bmp_header, FILE* fp);
bool      write_bmp(FILE* fp, BMPImage* image, const char** a_error);
void      free_bmp(BMPImage* image);
BMPImage* crop_bmp(const BMPImage* image, int x, int y, int w, int h, const char** a_error);

#endif /* __BMP_H_V2__ */

© Copyright 2019 Alexander J. Quinn         This content is protected and may not be shared, uploaded, or distributed.