Binary Files

  1. Overview
    1. Composed of bytes that do not equate to textual data
    2. Images, audio, and video are almost always stored in binary files
    3. Opening a binary file into a text editor usually displays only gibberish
    4. Bytes can be seen in Visual Studio by changing file extension to .bin before opening in VS
  2. Reading from a binary file
    1. Use ios::binary argument when opening
      // Open a binary file for input
      ifstream fin;
      fin.open("image.bmp", ios::binary);
      
    2. read(char* var, int num_bytes)
      1. Read num_bytes worth of data from the file into the var
      2. If the variable is not a char*, typecast into a char pointer
      3. Example reading 4 bytes into an integer
        // Read 4 bytes into the integer
        int num;
        fin.read((char*) &num, 4);
        
    3. Read pointer
      1. A read pointer keeps track of the byte offset where the file is being read from
      2. When the file is first opened, the read pointer is pointing to the beginning of the file
      3. The read pointer moves along with read calls
        // Read pointer advances 4 bytes after the read
        fin.read((char*) &num, 4);
        
      4. The read pointer can be moved using seekg(int byte_offset) before reading from the file
        // Move to the beginning of the file
        fin.seekg(0);
        
        // Read the first 4 bytes into an integer
        fin.read((char*) &num, 4);
        
        // Move the pointer to the 100 byte offset
        fin.seekg(100);
        
        // Read the next 4 bytes into an integer
        fin.read((char*) &num, 4);
        
  3. Writing to a binary file
    1. Use ios::binary argument when opening
      // Open a binary file for output
      ofstream fout;
      fout.open("image.bmp", ios::binary);
      
    2. write(char* variable, int num_bytes)
      1. Write num_bytes from the variable to the file
      2. If the variable is not a char*, type caste into a char pointer
      3. Example writing 4 bytes from an integer to the file
        // Write the integer to file
        int num = 15;
        fout.write((char*) &num, 4);
        
    3. Write pointer
      1. A write pointer keeps track of the byte offset where the file is being written to
      2. When the file is first opened, the write pointer is pointing to the beginning of the file
      3. The write pointer moves along with write calls
        // Write pointer advances 4 bytes after the write
        fout.write((char*) &num, 4);
        
      4. The write pointer can be moved using seekp(int byte_offset) before writing to the file
        // Move to the beginning of the file
        fout.seekp(0);
        
        // Write the integer to the first 4 bytes
        fout.write((char*) &num, 4);
        
        // Move the pointer to the 100 byte offset
        fout.seekp(100);
        
        // Write the integer to the next 4 bytes
        fout.write((char*) &num, 4);
        
  4. Bitmap image
    1. Images are stored in a binary BMP file using the color of each individual pixel
    2. Each pixel is composed of 3 colors: red, green, blue
      1. Red is 1 byte, green is 1 byte, blue is 1 byte
      2. The three byte combination (24 bits) can represent 16.8 million color variations (the human eye can only see 10 million)
      3. Common colors:
        1. RGB(255, 0, 0) = red
        2. RGB(0, 255, 0) = green
        3. RGB(0, 0, 255) = blue
        4. RGB(255, 255, 0) = yellow
        5. RGB(255, 0, 255) = purple
        6. RGB(0, 0, 0) = black
        7. RGB(255, 255, 255) = white
    3. BMP files are divided into several parts, only three listed here
      1. File header - General information about the file (14 bytes)
      2. DIB header - Info about the image and pixel format (40 bytes)
      3. Pixel Array - Pixel array (variable size)
    4. See the given code will read and write BMP files and provides functions for manipulating pixels