title: Inverting colors of pixels in a BMP file in C
body: <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>