Skip to content

Instantly share code, notes, and snippets.

@opsJson
Last active March 19, 2022 05:29
Show Gist options
  • Select an option

  • Save opsJson/9dfc28e618d0229f4347ad57330f5eb7 to your computer and use it in GitHub Desktop.

Select an option

Save opsJson/9dfc28e618d0229f4347ad57330f5eb7 to your computer and use it in GitHub Desktop.
Easily read and write bitmaps image files.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct header {
unsigned char signature[2];
unsigned int fileSize;
unsigned int reserved;
unsigned int dataOffset;
} Header;
typedef struct infoHeader {
unsigned int size;
unsigned int width;
unsigned int height;
unsigned short planes;
unsigned short bitsPerPixel;
unsigned int compression;
unsigned int imageSize;
unsigned int xPixelsPerM;
unsigned int yPixelsPerM;
unsigned int colorUsed;
unsigned int importantColors;
} InfoHeader;
typedef struct colorTable {
char r;
char g;
char b;
char reserved;
} ColorTable;
typedef struct image {
Header header;
InfoHeader infoHeader;
ColorTable colorTable;
void *pixels;
} Image;
Image *LoadBMP(const char *file) {
FILE *fp;
Image *image;
size_t size;
if ((fp = fopen(file, "rb")) == NULL) return NULL;
if ((image = malloc(sizeof(Image))) == NULL)
{
fclose(fp);
return NULL;
}
fread(image->header.signature, sizeof(image->header.signature), 1, fp);
fread(&image->header.fileSize, sizeof(image->header.fileSize), 1, fp);
fread(&image->header.reserved, sizeof(image->header.reserved), 1, fp);
fread(&image->header.dataOffset, sizeof(image->header.dataOffset), 1, fp);
fread(&image->infoHeader.size, sizeof(image->infoHeader.size), 1, fp);
fread(&image->infoHeader.width, sizeof(image->infoHeader.width), 1, fp);
fread(&image->infoHeader.height, sizeof(image->infoHeader.height), 1, fp);
fread(&image->infoHeader.planes, sizeof(image->infoHeader.planes), 1, fp);
fread(&image->infoHeader.bitsPerPixel, sizeof(image->infoHeader.bitsPerPixel), 1, fp);
fread(&image->infoHeader.compression, sizeof(image->infoHeader.compression), 1, fp);
fread(&image->infoHeader.imageSize, sizeof(image->infoHeader.imageSize), 1, fp);
fread(&image->infoHeader.xPixelsPerM, sizeof(image->infoHeader.xPixelsPerM), 1, fp);
fread(&image->infoHeader.yPixelsPerM, sizeof(image->infoHeader.yPixelsPerM), 1, fp);
fread(&image->infoHeader.colorUsed, sizeof(image->infoHeader.colorUsed), 1, fp);
fread(&image->infoHeader.importantColors, sizeof(image->infoHeader.importantColors), 1, fp);
fread(&image->colorTable.r, sizeof(image->colorTable.r), 1, fp);
fread(&image->colorTable.g, sizeof(image->colorTable.g), 1, fp);
fread(&image->colorTable.b, sizeof(image->colorTable.b), 1, fp);
fread(&image->colorTable.reserved, sizeof(image->colorTable.reserved), 1, fp);
size = image->infoHeader.width * image->infoHeader.height * image->infoHeader.planes * image->infoHeader.bitsPerPixel;
image->pixels = malloc(size);
fread(image->pixels, size, 1, fp);
fclose(fp);
return image;
}
bool WriteBMP(const char *file, Image image) {
FILE *fp;
size_t size;
if ((fp = fopen(file, "wb")) == NULL) return false;
fwrite(image.header.signature, sizeof(image.header.signature), 1, fp);
fwrite(&image.header.fileSize, sizeof(image.header.fileSize), 1, fp);
fwrite(&image.header.reserved, sizeof(image.header.reserved), 1, fp);
fwrite(&image.header.dataOffset, sizeof(image.header.dataOffset), 1, fp);
fwrite(&image.infoHeader.size, sizeof(image.infoHeader.size), 1, fp);
fwrite(&image.infoHeader.width, sizeof(image.infoHeader.width), 1, fp);
fwrite(&image.infoHeader.height, sizeof(image.infoHeader.height), 1, fp);
fwrite(&image.infoHeader.planes, sizeof(image.infoHeader.planes), 1, fp);
fwrite(&image.infoHeader.bitsPerPixel, sizeof(image.infoHeader.bitsPerPixel), 1, fp);
fwrite(&image.infoHeader.compression, sizeof(image.infoHeader.compression), 1, fp);
fwrite(&image.infoHeader.imageSize, sizeof(image.infoHeader.imageSize), 1, fp);
fwrite(&image.infoHeader.xPixelsPerM, sizeof(image.infoHeader.xPixelsPerM), 1, fp);
fwrite(&image.infoHeader.yPixelsPerM, sizeof(image.infoHeader.yPixelsPerM), 1, fp);
fwrite(&image.infoHeader.colorUsed, sizeof(image.infoHeader.colorUsed), 1, fp);
fwrite(&image.infoHeader.importantColors, sizeof(image.infoHeader.importantColors), 1, fp);
fwrite(&image.colorTable.r, sizeof(image.colorTable.r), 1, fp);
fwrite(&image.colorTable.g, sizeof(image.colorTable.g), 1, fp);
fwrite(&image.colorTable.b, sizeof(image.colorTable.b), 1, fp);
fwrite(&image.colorTable.reserved, sizeof(image.colorTable.reserved), 1, fp);
size = image.infoHeader.width * image.infoHeader.height * image.infoHeader.planes * image.infoHeader.bitsPerPixel;
fwrite(image.pixels, size, 1, fp);
fclose(fp);
return true;
}
void FreeBMP(Image *image) {
free(image->pixels);
free(image);
}
/*///////////////////////////////////
Testing:
///////////////////////////////////*/
int main(void) {
Image *image = LoadBMP("bitmap.bmp");
printf("%i\n", image->infoHeader.compression);
printf("%i\n", image->infoHeader.width);
printf("%i\n", image->infoHeader.height);
printf("%i\n", image->infoHeader.planes);
printf("%i\n", image->infoHeader.bitsPerPixel);
if (WriteBMP("bitmap_copy.bmp", *image))
{
printf("done!\n");
}
FreeBMP(image);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment