fileiopp

File IO ++ or fileiopp serves as a utility that interprets files in ways that I deem useful
Log | Files | Refs | README | LICENSE

bmpfileiopp.c (4178B)


      1 /*
      2   Bitmap File IO ++ Implementation File
      3   "bmpfileiopp.c"
      4   M. Yamanaka
      5   email: myamanaka@live.com
      6   website: csmyamanaka.com
      7   license: MIT (See included "LICENSE" file for details)
      8 */
      9 
     10 /*
     11   According to the wikipedia page (full URL in the header file), the bitmap header requires:
     12   - 2 bytes for the BMP file signature
     13   - 4 bytes for the file size
     14   - 4 bytes for some reason
     15   - 4 bytes that points to the location of the actual data
     16   - 4 bytes just to say 40?
     17   - 4 bytes for the image width
     18   - 4 bytes for the image height
     19   - 2 bytes for the image plane (apparently we can just set this to 1)??
     20   - 2 bytes for bits per pixel 8 bits for 0-255 so for RGB, it should be 24 bits
     21   - 4 bytes for the compression, pretty sure we don't have to do any compression so probably just set this to 0
     22   - 4 bytes for idkwtf. apparently i can set this to 0 as well if we set the compression to 0
     23   - 4 bytes for pixels per meter for x. idk 1000 might be a good number. that's 1 pixel = 1 mm
     24   - 4 bytes for pixels per meter for y. same here, probably just 1000
     25   - 4 bytes for "Colors Used". It looks like I can set this to 0
     26   - 4 bytes for "Important Colors"  it says we can just set this to 0
     27 
     28   According to "Example 1" on the wikipedia page, it seems like I don't need the color table section
     29   or at least it is outisde the scope at least for now to have to handle any of that.
     30 
     31   Whew that was a lot so that's 14 bytes for the first section and 40 bytes for the second so the 54th bytes is where the image data begins.
     32   
     33   The total file size is therefore 54 bytes + number of elements in the data array
     34 */
     35 
     36 #include "bmpfileiopp.h"
     37 
     38 int readBMP(BMPIS* bfi, char** bd){
     39   /*
     40     fn ... bmp file name
     41     bfi ... bitmap file information
     42     bd ... bitmap image data
     43   */
     44   
     45   FILE* imf = fopen(bfi->fn, "r");
     46   char rb[64]; //read buffer
     47   
     48   //check if the file in question is indeed a bitmap file by checking the header
     49   fread(rb, sizeof(char), 2, imf);
     50   if(rb[0] != 'B' || rb[1] != 'M') return -1;
     51   
     52   int details[4]; //temporary storage for important variables: image date location, width, height, and number of cnannels
     53   int ds[4] = {4, 4, 4, 2}; //the byte sizes of each 
     54   int adv[7] = {8, 4, 4, 4, 4, 2, 2}; //read sizes. Some reads will contain the above variables. Others are ignored.
     55   for(int i = 0, di = 0; i < 7; i++){
     56     fread(rb, sizeof(char), adv[i], imf);
     57     if(i == 1|| i == 3 || i == 4 || i == 6){
     58       rDataFromChar(rb, details + di, ds[di], 0);
     59       di++;
     60     }
     61   }
     62   
     63   bfi->w = details[1];
     64   bfi->h = details[2];
     65   bfi->c = details[3]/8;
     66   
     67   //the file pointer is at byte 30 at this point so we need bring this to details[0]
     68   fread(rb, sizeof(char), details[0] - 30, imf);
     69 
     70   //the actual data size (assuming there's no compression) is width*height*channels
     71   int dsz = (bfi->w)*(bfi->h)*(bfi->c); //data size
     72   *bd = (char*)malloc(sizeof(char)*dsz);
     73   fread(*bd, sizeof(char), dsz, imf);
     74   fclose(imf);
     75   return 0;
     76 }
     77 
     78 int writeBMP(BMPIS bfi, char* bd){
     79   /*
     80     bfi: bitmap file information
     81     bd: bitmap data array
     82   */
     83   
     84   //the size of the data array whould be height x width x number of channels
     85   int datsz = bfi.h*bfi.w*bfi.c;
     86   
     87   //create an array of bytes that represents the file
     88   char* file_contents = (char*)malloc(sizeof(char)*(54 + datsz));
     89 
     90   //but starting with byte 54, the entirety of array a1 is copied onto the file contents
     91   for(int i = 0; i < datsz; i++) file_contents[i + 54] = bd[i];
     92 
     93   //for the BMP signature, set byte 0 to 'B' and byte 1 to 'M' as indicated by ece.ualberta.ca
     94   file_contents[0] = 'B';
     95   file_contents[1] = 'M';
     96   
     97   int cb = 2; //the current byte position is 2 after having read 'B' and 'M'
     98   int details[14] = {54 + datsz, 0, 54, 40, bfi.w, bfi.h, 1, bfi.c*8, 0, 0, 1000, 1000, 0, 0};
     99   int bsz[14] = {4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4};
    100   
    101   for(int i = 0; i < 14; cb += bsz[i++]) wDataToChar(details + i, file_contents + cb, bsz[i], 0);
    102 
    103   //Write the char array into the output file
    104   FILE* bmpfile = fopen(bfi.fn, "w");
    105   for(int i = 0; i < 54 + datsz; i++) fputc(file_contents[i], bmpfile);
    106   fclose(bmpfile);
    107   
    108   //deallocate memory
    109   free(file_contents);
    110   return 0;
    111 }
    112 
    113 

Generated using stagit (https://codemadness.org/stagit.html)