Skip to content

Instantly share code, notes, and snippets.

@connors511
Created October 14, 2011 15:27
Show Gist options
  • Save connors511/1287429 to your computer and use it in GitHub Desktop.
Save connors511/1287429 to your computer and use it in GitHub Desktop.
BOOL bmp_open(char* file, IMAGE* image) {
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
unsigned int rowSize, i, totalPixels = 0;
BYTE blue, green, red;
/* note: "rb" means open for binary read */
FILE* fp = fopen(file, "rb");
if (fp == NULL) {
/* failed to open file, return failure */
perror("Could not open file");
return FALSE;
}
/* todo: process file */
fread(&bmfh, sizeof (bmfh), 1, fp);
fread(&bmih, sizeof (bmih), 1, fp);
image->Height = bmih.BiHeight;
image->Width = bmih.BiWidth;
// Starting address of the image data can be found in the file header
fseek(fp, bmfh.BfOffBits, SEEK_SET);
if (bmih.BiCompression == BI_RGB)
{
rowSize = ceil(bmih.BiBitCount * bmih.BiWidth / 32.0) * 4;
#ifdef DEBUG
printf("Image compression: RGB%d\n", bmih.BiBitCount);
printf("Bit offset: %d\n", bmfh.BfOffBits);
printf("Row size: %d\n", rowSize);
#endif
if (bmih.BiBitCount > 8) {
for (i = 0; i < (bmih.BiWidth * bmih.BiHeight); i++) {
fread(&blue, sizeof (BYTE), 1, fp);
fread(&green, sizeof (BYTE), 1, fp);
fread(&red, sizeof (BYTE), 1, fp);
image->Pixels[i] = 0.11 * blue + 0.59 * green + 0.3 * red;
if ((i + 1) % image->Width == 0) {
fseek(fp, sizeof (BYTE) * ((image->Width) % 4), SEEK_CUR); // padding
}
}
} else {
// Assuming 8 bit
for (i = 0; i < (bmih.BiWidth * bmih.BiHeight); i++) {
fread(&blue, sizeof (BYTE), 1, fp);
image->Pixels[i] = blue;
}
}
}
else if ( bmih.BiCompression == BI_RLE8)
{
#ifdef DEBUG
printf("Image compression: RLE8\n");
printf("Bit offset: %d\n", bmfh.BfOffBits);
#endif
/*if (!bmp_decompress(fp, image)) {
printf("Failed to decompress RLE8 image");
return EXIT_FAILURE;
}*/
}
#ifdef DEBUG
printf("Image width:\t%d\nImage height:\t%d\n", image->Width, image->Height);
printf("Pixels:\t%ld\n", sizeof(image->Pixels)/sizeof(BYTE));
printf("\nImage upper left 3x3:\n\t%d\t%d\t%d\n\t%d\t%d\t%d\n\t%d\t%d\t%d\n\n",
image->Pixels[0], image->Pixels[1], image->Pixels[2],
image->Pixels[3], image->Pixels[4], image->Pixels[5],
image->Pixels[6], image->Pixels[7], image->Pixels[8]);
#endif
/* success */
fclose(fp);
return TRUE;
}
BOOL bmp_save(char* file, IMAGE* image, BOOL compress) {
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
unsigned int rowSize, i;
COLORENTRY colorpalette[256];
int compressOffset = 0;
BYTE reserved = 0;
/* note: "wb" means open for binary write */
FILE* fp = fopen(file, "wb");
if (fp == NULL) {
/* failed to open file, return failure */
perror("Could not open file");
return FALSE;
}
/* todo: store image to fp */
bmih.BiSize = sizeof (BITMAPINFOHEADER);
bmih.BiWidth = image->Width;
bmih.BiHeight = image->Height;
bmih.BiPlanes = 1;
bmih.BiBitCount = 8;
bmih.BiCompression = BI_RGB;
bmih.BiSizeImage = sizeof (BYTE) * image->Width * image->Height;
bmih.BiXPelsPerMeter = 0;//2834;
bmih.BiYPelsPerMeter = 0;//2834;
bmih.BiClrUsed = 0;
bmih.BiClrImportant = 0;
#ifdef DEBUG
printf("Generating color palette..\n");
#endif
bmfh.BfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER);
/*if (compress) {
if (!(compressOffset = bmp_compress(image))) {
printf("Failed to compress image with RLE8");
return EXIT_FAILURE;
}
bmih.BiCompression = BI_RLE8;
bmfh.BfOffBits += compressOffset;
}
else
{*/
bmfh.BfOffBits += sizeof(image->Pixels);
//}
bmfh.BfType = 0x4D42;
bmfh.BfSize = bmfh.BfOffBits + bmih.BiSizeImage;
bmfh.BfReserved1 = 0;
bmfh.BfReserved2 = 0;
#ifdef DEBUG
printf("Bit offset: %d\n", bmfh.BfOffBits);
#endif
fwrite(&bmfh, sizeof (bmfh), 1, fp);
/*fwrite(&bmfh.BfType, sizeof(bmfh.BfType), 1, fp);
fwrite(&bmfh.BfSize, sizeof(bmfh.BfType), 1, fp);
fwrite(&bmfh.BfReserved1, sizeof(bmfh.BfType), 1, fp);
fwrite(&bmfh.BfReserved2, sizeof(bmfh.BfType), 1, fp);
fwrite(&bmfh.BfOffBits, sizeof(bmfh.BfType), 1, fp);*/
fwrite(&bmih, sizeof (bmih), 1, fp);
/*fwrite(&bmih.BiSize, sizeof(bmih.BiSize), 1, fp);
fwrite(&bmih.BiWidth, sizeof(bmih.BiWidth), 1, fp);
fwrite(&bmih.BiHeight, sizeof(bmih.BiHeight), 1, fp);
fwrite(&bmih.BiPlanes, sizeof(bmih.BiPlanes), 1, fp);
fwrite(&bmih.BiBitCount, sizeof(bmih.BiBitCount), 1, fp);
fwrite(&bmih.BiCompression, sizeof(bmih.BiCompression), 1, fp);
fwrite(&bmih.BiSizeImage, sizeof(bmih.BiSizeImage), 1, fp);
fwrite(&bmih.BiXPelsPerMeter, sizeof(bmih.BiXPelsPerMeter), 1, fp);
fwrite(&bmih.BiYPelsPerMeter, sizeof(bmih.BiYPelsPerMeter), 1, fp);
fwrite(&bmih.BiClrUsed, sizeof(bmih.BiClrUsed), 1, fp);
fwrite(&bmih.BiClrImportant, sizeof(bmih.BiClrImportant), 1, fp);*/
//fwrite(&colorpalette, sizeof (colorpalette), 1, fp);
for(i = 0; i < 256; i++)
{
fwrite(&i, sizeof(BYTE), 3, fp);
fwrite(&reserved, sizeof(BYTE), 1, fp);
}
rowSize = ceil(bmih.BiBitCount * bmih.BiWidth / 32.0) * 4;
#ifdef DEBUG
printf("Row size: %d\n", rowSize);
printf("\nImage upper left 3x3:\n\t%d\t%d\t%d\n\t%d\t%d\t%d\n\t%d\t%d\t%d\n\n",
image->Pixels[0], image->Pixels[1], image->Pixels[2],
image->Pixels[3], image->Pixels[4], image->Pixels[5],
image->Pixels[6], image->Pixels[7], image->Pixels[8]);
#endif
for (i = 0; i < (bmih.BiWidth * bmih.BiHeight); i++) {
fwrite(&image->Pixels[i], sizeof (BYTE), 1, fp);
if (( (i + 1) % image->Width == 0) ) {
fwrite(" ", sizeof (BYTE), rowSize - image->Width, fp); // padding
}
}
fclose(fp);
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment