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