bit munster
bit munster

Reputation: 11

C: not writing BMP file properly

new here, first post...been teaching myself C.

Having an issue with writing out to file, specifically, a BMP file. I've stripped out an RGB value and wrote the remaining data to a new file. When I try to open it, it's not recognised and then frustration ensues. The code writes out the appropriate size, I get no errors whatsoever, it runs...I just don't get the output file I need and stuck on how to work around it.

Obviously I'm messing up on my conversion back to file or missing something else completely. Help is appreciated.

FILE * fPointer;
fPointer = fopen("myBMP.bmp", "rb");

FILE * wfPointer;
wfPointer = fopen("myBMP2.bmp", "wb");

unsigned char fileChars;
unsigned char wfBMP;

unsigned int toBMPFile[1024];
unsigned int intcon;

int count = 0;
int countchars = 0;
int i = 0;

while(!feof(fPointer))
{
    fileChars = fgetc(fPointer);
    intcon = fileChars;

    // strip 255 out of file
    if(intcon == 255)
    {
        // printf("%i ", intcon);
        continue;
    }
    else if(intcon < 255)
    {
        // write values < 255 into file
        toBMPFile[i] = intcon;
        printf("%c ", toBMPFile[i]);
        wfBMP = toBMPFile[i];
        fwrite(&wfBMP, sizeof(wfBMP), 1, wfPointer);
        // fprintf(wfPointer, "%c", wfBMP);
        countchars++;
    }   
    else 
    {
        continue;
    }   

    count++;

}

printf("\nnumber of characters in new file: %i\n", countchars);
fclose(fPointer);

fclose(wfPointer);

return 0;

}

Upvotes: 1

Views: 210

Answers (2)

moonshadow
moonshadow

Reputation: 89185

A BMP file contains a header, which describes the format of the data and the dimensions of the image, followed by the image data. You are creating a copy of the entire file except for whichever bytes happen to have the value 255.

This leads to two problems:

  • if any bytes in the header happen to have the value 255, they will not be copied, and so the resulting header will not have the correct structure and likely not contain sane information either
  • since you are omitting some image data, the total amount of data present will no longer be what the header leads the reader to expect

What do you actually want to do?

If your intent is to make a smaller image, you need to change the header to reflect that.

If your intent is to replace some colour values with different ones without changing the size of the image, you need to write out the new values instead of just skipping those bytes.

In either case, you need to deal with the header separately to the operation that processes the image data. The BMP header format is documented in many places, but if all you're after is to process the image data, the simplest way is probably to just use a third-party library to read and write the image - that way you'll get all kinds of other functionality (coping with different colour depths, maybe other image formats) for free.

Upvotes: 3

Andrew Henle
Andrew Henle

Reputation: 1

fgetc() returns int, not char.

Per the man page:

int fgetc(FILE *stream);

Because you're truncating the int value of EOF down to a character, you're not properly identifying the end of the file.

Turn on all your compiler warnings.

Randomly removing values from a BMP file likely also causes problems as it seems to me you're not properly recreating the header part after you strip out the 255 pixels.

Upvotes: 1

Related Questions