Skip to content
Related Articles

Related Articles

How to read a PGMB format image in C

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 29 Oct, 2021
Improve Article
Save Article

PGM or Portable Gray Map file is a grayscale image where each pixel is encoded with 1 or 2 bytes. It contains header information and pixel grayscale values in a matrix form.

Approach: The idea is followed to read PGMB format image is as follows:

  • Open a PGMB (binary format PGM image).
  • Extract the pixel information, which can be then used for further processing.
  • The header information is stored in ASCII format can be read using any text editor but the pixel information is stored in a binary formation and the text editor will show that as some gibberish text.

Below is the sample pgm image.

Header Information:

  • magic number for identifying the file type:
    • Binary PGM File (PGMB): “P5”
    • ASCII PGM File (PGMA): “P2”
  • Width in ASCII decimal format
  • Height in ASCII decimal format
  • Maximum Gray Value, ASCII decimal format, between 0-255
  • Can contain comments, denoted by beginning the line with a ‘#’
  • All separated with white spaces (blanks space, tabs, CRs, LFs)

Header information in gfg_logo.pgm:

# sample PGMB image
# gfg_logo.pgm
200 200

After the header information, there is a grid of dimensions height * weight containing the grayscale pixel values of the image in binary format.

Reading PGMB Image:

  • Open the image in the read binary, rb mode.
  • Check if any comments are present and ignore them.
  • Read the Magic Number.
  • Read any comments/blank line/white space.
  • Read width and height separated by white space.
  • Read the max gray value, before and after any white space/comment.
  • Read the grid (width * height) of pixel values, separated by white spaces.

Below is the program for the above approach:


// C Program to read a PGMB image
// and print its parameters
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Structure for storing the
// image data
typedef struct PGMImage {
    char pgmType[3];
    unsigned char** data;
    unsigned int width;
    unsigned int height;
    unsigned int maxValue;
} PGMImage;
// Function to ignore any comments
// in file
void ignoreComments(FILE* fp)
    int ch;
    char line[100];
    // Ignore any blank lines
    while ((ch = fgetc(fp)) != EOF
           && isspace(ch))
    // Recursively ignore comments
    // in a PGM image commented lines
    // start with a '#'
    if (ch == '#') {
        fgets(line, sizeof(line), fp);
        fseek(fp, -1, SEEK_CUR);
// Function to open the input a PGM
// file and process it
bool openPGM(PGMImage* pgm,
             const char* filename)
    // Open the image file in the
    // 'read binary' mode
    FILE* pgmfile
        = fopen(filename, "rb");
    // If file does not exist,
    // then return
    if (pgmfile == NULL) {
        printf("File does not exist\n");
        return false;
    fscanf(pgmfile, "%s",
    // Check for correct PGM Binary
    // file type
    if (strcmp(pgm->pgmType, "P5")) {
                "Wrong file type!\n");
    // Read the image dimensions
    fscanf(pgmfile, "%d %d",
    // Read maximum gray value
    fscanf(pgmfile, "%d", &(pgm->maxValue));
    // Allocating memory to store
    // img info in defined struct
        = malloc(pgm->height
                 * sizeof(unsigned char*));
    // Storing the pixel info in
    // the struct
    if (pgm->pgmType[1] == '5') {
        for (int i = 0;
             i < pgm->height; i++) {
                = malloc(pgm->width
                         * sizeof(unsigned char));
            // If memory allocation
            // is failed
            if (pgm->data[i] == NULL) {
                        "malloc failed\n");
            // Read the gray values and
            // write on allocated memory
                  sizeof(unsigned char),
                  pgm->width, pgmfile);
    // Close the file
    return true;
// Function to print the file details
void printImageDetails(PGMImage* pgm,
                       const char* filename)
    FILE* pgmfile = fopen(filename, "rb");
    // Retrieving the file extension
    char* ext = strrchr(filename, '.');
    if (!ext)
        printf("No extension found"
               "in file %s",
        printf("File format"
               "    : %s\n",
               ext + 1);
    printf("PGM File type  : %s\n",
    // Print type of PGM file, in ascii
    // and binary format
    if (!strcmp(pgm->pgmType, "P2"))
        printf("PGM File Format:"
    else if (!strcmp(pgm->pgmType,
        printf("PGM File Format:"
               " Binary\n");
    printf("Width of img   : %d px\n",
    printf("Height of img  : %d px\n",
    printf("Max Gray value : %d\n",
    // close file
// Driver Code
int main(int argc, char const* argv[])
    PGMImage* pgm = malloc(sizeof(PGMImage));
    const char* ipfile;
    if (argc == 2)
        ipfile = argv[1];
        ipfile = "gfg_logo.pgm";
    printf("\tip file : %s\n", ipfile);
    // Process the image and print
    // its details
    if (openPGM(pgm, ipfile))
        printImageDetails(pgm, ipfile);
    return 0;




  • Create a structure for storing the PGMB image details and allocate memory for the same.
  • Take the file name input either as a command-line argument or by hard coding it in the program.
  • The openPGM() function processes the input image files and takes the memory pointer and filename are input.
  • The ignoreComments() function is used to skip any comments in the file. Comments are usually present in the header portion and thus, we check for them after reading every property.
  • In openPGM() function, read the file header information, ie. file type, height, weight, etc as given above.
  • Then allocate memory as per the height of the image and for each row, allocate memory for the width of the image.
  • The fread() method reads the gray values and stores them in the allocated memory for the 2d character matrix of the pgm structure.
  • printImageDetails() is used to print the values retrieved from the PGMB image file. 

My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!