Inverting colors of pixels in a BMP file in C
<p>My problem I am having is trying to invert the colors on a simple black and white image. </p>

<p><a href="https://i.stack.imgur.com/kToIO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/kToIO.png" alt="enter image description here"></a></p>

<p>When I run my C program and perform bitwise-NOT on each of the BGR values I instead end up with an image like so. It appears to repeat, Black, Blue, Green and Red pixels for the entire image. I have read there is an extra byte for padding at the end of each pixel, which I attempt to skip over each iteration.</p>

<p><a href="https://i.stack.imgur.com/jrB2r.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jrB2r.png" alt="enter image description here"></a></p>

<p>This is a close up of the bottom left corner.</p>

<p><a href="https://i.stack.imgur.com/RBMTp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RBMTp.png" alt="enter image description here"></a></p>

<p>Here is my code to read the BMP file and invert the colors of the image.</p>

<pre><code>void invertImage(char fileName[]) {

    struct BMP bmp;
    struct DIB dib;
    struct PIXEL pixel;

    FILE *fp = fopen(fileName, "rb+");

    //FileType
    fread(bmp.filetype, 1, 2, fp);
    printf("Value is %c\n", bmp.filetype[1]);

    //Check if file format is BM
    if (bmp.filetype[0] != 'B' &amp;&amp; bmp.filetype[1] != 'M') {
        printf("File format not supported");
        exit(-1);
    }
    //Size of the file in bytes
    fread(&amp;bmp.filesize, 4, 1, fp);
    printf("Value is %d\n", bmp.filesize);

    //Go to dataoffset
    fseek(fp, 4, SEEK_CUR);

    fread(&amp;bmp.dataoffset, 4, 1, fp);
    printf("Offset is %d\n", bmp.dataoffset);


    fread(&amp;dib.fileheader, 4, 1, fp);
    printf("File header is %d bytes\n", dib.fileheader);

    if (dib.fileheader != 40) {
        printf("File format not supported");
        exit(-1);
    }

    fread(&amp;dib.width, 4, 1, fp);
    printf("Width is %d\n", dib.width);

    fread(&amp;dib.height, 4, 1, fp);
    printf("Height is %d\n", dib.height);

    fread(&amp;dib.planes, 2, 1, fp);
    printf("Color planes is %d\n", dib.planes);

    //Number of bits per pixel
    fread(&amp;dib.bitsperpixel, 2, 1, fp);
    printf("Pixels per bit is %d\n", dib.bitsperpixel);


    fread(&amp;dib.compression, 4, 1, fp);
    printf("Compression scheme used is %d\n", dib.compression);

    fread(&amp;dib.bitmapsize, 4, 1, fp);
    printf("Image size is %d\n", dib.bitmapsize);

    fread(&amp;dib.horizontalres, 4, 1, fp);
    printf("Horizontal resolution is %d\n", dib.horizontalres);

    fread(&amp;dib.verticalres, 4, 1, fp);
    printf("Vertical resolution is %d\n", dib.verticalres);

    fread(&amp;dib.numcolors, 4, 1, fp);
    printf("Number of colors used %d\n", dib.numcolors);

    fread(&amp;dib.importantcolors, 4, 1, fp);
    printf("Important colors used %d\n", dib.importantcolors);

    //fseek(fp,3,SEEK_CUR);

    int x = 0;
    while (x &lt; dib.width) {
        int y = 0;
        while (y &lt; dib.height) {

            fread(&amp;pixel.b, 1, 1, fp);
            unsigned int blue = pixel.b;
            blue = ~blue;
            pixel.b = (char) blue;
            printf("Pixel 1 is %d\n", pixel.b);

            fread(&amp;pixel.g, 1, 1, fp);
            unsigned int green = pixel.g;
            green = ~green;
            pixel.g = (char) green;
            printf("Pixel 2 is %d\n", pixel.g);

            fread(&amp;pixel.r, 1, 1, fp);
            unsigned int red = pixel.r;
            red = ~red;
            pixel.r = (char) red;
            printf("Pixel 3 is %d\n", pixel.r);

            fseek(fp, -3, SEEK_CUR);
            fwrite(&amp;pixel.b, 1, 1, fp);
            fwrite(&amp;pixel.g, 1, 1, fp);
            fwrite(&amp;pixel.r, 1, 1, fp);
            fseek(fp, 1, SEEK_CUR);

            y++;
        }
        //  fseek(fp,1,SEEK_CUR);

        x++;
    }

    fclose(fp);
}

int main(int argc, char *argv[]) {

    printf("Program name %s\n", argv[0]);
   if( strcmp(argv[1],"-invert") == 0) {

    printf("Invert\n");
    printf("File name is %s\n", argv[2]);

    invertImage(argv[2]);
}
    return 0;
}
</code></pre>

<p>And also the structures that I use in my program.</p>

<pre><code>struct BMP {
    char filetype[2]; // must be BM, must check if BM
    unsigned int filesize;
    short reserved1;
    short reserved2;
    unsigned int dataoffset;

};

struct DIB {
    unsigned int fileheader;
    unsigned int headersize;
    int width;
    int height;
    short planes;
    short bitsperpixel; /* we only support the value 24 here */
    unsigned int compression; /* we do not support compression */
    unsigned int bitmapsize;
    int horizontalres;
    int verticalres;
    unsigned int numcolors;
    unsigned int importantcolors;
};

struct PIXEL {
    unsigned char b;
    unsigned char g;
    unsigned char r;

};
</code></pre>

<p>This is the output minus the output from the double while loops which is just "Pixel n is 0" or "Pixel n is 255"</p>

<p><a href="https://i.stack.imgur.com/8Mj8k.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8Mj8k.png" alt="enter image description here"></a></p>