title: Copy an 8 bit greyscale bmp file generated from a tif file using C
body: <p>The following code is part of my program that tries to extract image features from a bitmap file. I need to extract information (width and height only) about the image and also make copies of it. These images are of 2048X 2168 resolution, 8-bit greyscale. </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  #define NAMELENGTH 301
  
  long getImageInfo(FILE* Finput, long offset, int nchars){
     unsigned char *ptrChar;
     unsigned char dummy;
     long value=0L;
     int i;
  
     dummy='0';
     ptrChar=&amp;dummy;
  
     fseek(Finput,offset,SEEK_SET);
     for (i=1; i&lt;=nchars; i++){
       fread(ptrChar,sizeof(char),1,Finput);
       value += ((long) ((*ptrChar)*pow(256,(i-1))));
      }
     return(value);
  }
  
  void copyImageInfo(FILE* Finput, FILE* Foutput){
      unsigned char *ptrChar;
      unsigned char dummy;
      long offset;
      int i;
  
      dummy='0';
      ptrChar=&amp;dummy;
      int byte_size = ((int) getImageInfo(Finput,34,4));
  
      /* copying header: signature, image width &amp; height, number bit/pixel, image size, number of colors */
      offset=0L;
      fseek(Finput,offset,SEEK_SET);
      fseek(Foutput,offset,SEEK_SET);
      for (i=0; i&lt;=54; i++){
          fread(ptrChar,sizeof(char),1,Finput);
          fwrite(ptrChar,sizeof(char),1,Foutput);
      }
  
      /* copying pixel data */
      /* This part of the code may not be complete */
      offset=54L;
      fseek(Finput,offset,SEEK_SET);
      fseek(Foutput,offset,SEEK_SET);
      for (i=0; i&lt;=byte_size; i++){
          fread(ptrChar,sizeof(char),1,Finput);
          fwrite(ptrChar,sizeof(char),1,Foutput);
      }
  }
  
  int main(int argc, char *argv[]){
      FILE* Finput;
      FILE* Foutput;
  
      char input_name[NAMELENGTH];
      char output_name[NAMELENGTH];
      char job_name[NAMELENGTH];
      char history_name[NAMELENGTH];
  
      unsigned char *ptrChar;
      int pix_width,pix_height;
      int bit_pixel,byte_size,ncolors;
  
      strcpy(input_name,argv[1]); /* first argument contains path to the image file */
      strcpy(job_name, argv[1]);
      job_name[strlen(job_name)-4]='\0';
      sprintf(history_name,"%s%s",job_name,"_hist.txt"); /* history file stores image header information */
  
      if( (Finput=fopen(input_name,"r"))==NULL ){
          fprintf(stderr,"\n ERROR: file %s could not be opened for reading\n",input_name);
          exit(-1);
      }
      else{
          fseek(Finput,0L,SEEK_END);
          if (getImageInfo(Finput,0,2)!=19778) fprintf(stdout,"\n WARNING: wrong BMP signature!\n");
          pix_width    = ((int) getImageInfo(Finput,18,4));
          pix_height   = ((int) getImageInfo(Finput,22,4));
          bit_pixel    = ((int) getImageInfo(Finput,28,2));
          byte_size    = ((int) getImageInfo(Finput,34,4));
          ncolors      = ((int) getImageInfo(Finput,46,4));
  
          fprintf(stdout,"\n width pixels=%d",pix_width);
          fprintf(stdout,"\n height pixels=%d",pix_height);
          fprintf(stdout,"\n bits per pixel=%d",bit_pixel);
          fprintf(stdout,"\n image data size=%d",byte_size);
          fprintf(stdout,"\n number colors=%d\n",ncolors);
  
          /* history file */
          if ( (Foutput=fopen(history_name,"a"))==NULL ){
              fprintf(stderr,"\n ERROR: file %s could not be opened for appending\n",history_name);
              exit(-1);
          }
          else{
              fprintf(Foutput,"Path to Image: %s ",input_name);
              fprintf(Foutput,"\n\t 18 - biWidth - width pixels=%d",pix_width);
              fprintf(Foutput,"\n\t 22 - biHeight - height pixels=%d",pix_height);
              fprintf(Foutput,"\n\t 28 - biBitCount - bits per pixel=%d",bit_pixel);
              fprintf(Foutput,"\n\t 34 - biSizeImage - image data size=%d",byte_size);
              fprintf(Foutput,"\n\t 46 - biClrUsed - number colors=%d\n",ncolors);
              fclose(Foutput);
  
          }
  
          sprintf(output_name,"%s%s",job_name,"_copy.bmp");
          if ( (Foutput=fopen(output_name,"wb"))==NULL ){
              fprintf(stderr,"\n ERROR: file %s could not be opened for writing\n",output_name);
              exit(-1);
          }
          else{
              copyImageInfo(Finput,Foutput);
              fclose(Foutput);
          }
      }
      fclose(Finput);
  }
  </code></pre>
  
  <p>Unfortunately, my original image files are in tif format. So when I convert them, I am unable to preserve some of the header file information. One online tool lets me preserve the bits-per-pixel (8 bit) but then I lose the biSizeImage (which turns to 0).  Another conversion tool gets me the size correctly but image bitrate changes to 24. (<a href="https://www.zamzar.com/convert/tiff-to-bmp/" rel="nofollow noreferrer">link1</a>, <a href="https://online-converting.com/image/convert2bmp/" rel="nofollow noreferrer">link2</a>)</p>
  
  <p>An example of my original tif image (<a href="https://filebin.net/0e94js58djlvm6zm/example.tif?t=1egjg8bj" rel="nofollow noreferrer">temporary_link1</a>) and the corresponding BMP image (<a href="https://filebin.net/un8n0ybdu301apqt/image_check.bmp?t=w6mcj239" rel="nofollow noreferrer">temporary_link2</a>)</p>
  
  <p>When I run the above, I am able to copy the header information correctly but not the pixel data. If this can be copied using some other method (like for example by comparing the EOF), it may be a good alternative. I am unsure about calculating the padding and also the direction of writing.</p>
  
  <p>Any guidance would be appreciated starting with the correct conversion of tif format to my required bmp format. Evidently I am new to image formatting and compression.</p>
  
  <p>Output:</p>
  
  <pre><code> width pixels=2048
   height pixels=2168
   bits per pixel=8
   image data size=0
   number colors=0
  </code></pre>