Thread: Reading a .pgm file into 2D array using C language

  1. #1
    Registered User
    Join Date
    Jun 2016
    Posts
    3

    Reading a .pgm file into 2D array using C language

    What is the best way to read a .pgm file into a 2D array ?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What's your definition of 'best'?

    Fewest lines of code?
    Most usable for displaying as a picture on screen?

    How To Ask Questions The Smart Way
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2016
    Posts
    3
    I have just started learning about image processing in C language and I am struggling to write a program to read a .pgm file into a 2D array so that I may later on transpose the image.
    However I am getting some problems, the program stops running suddenly. I am not sure where the problem is :
    Code:
    struct PGMstructure 
     {
       int maxVal;
       int width;
       int height;
       unsigned char data[800][800];
      };
    
    
    int main()
    {
    
    
    
    
    FILE *imagein,*imageout;
    char ch;
    int row,col,type;
    int num_elements;
    int i,j;
    int ch_int;
    struct PGMstructure *imginfo;	
    char fpath[1000],tpath[1000];
    printf("Enter PGM file path:");
    
    
    scanf("%s",fpath);
    imagein = fopen(fpath,"r+");
    
    
     
    if(imagein==NULL)
    {
    printf("Error opening first file");
    exit(8);
    }
    
    
    
    
    
    
        while(getc(imagein) != '\n');             
      
        while (getc(imagein) == '#')              
        {
          while (getc(imagein) != '\n');          
        }
         fseek(imagein, -1, SEEK_CUR);
         fscanf(imagein,"%d", &imginfo->width);
         fscanf(imagein,"%d", &imginfo->height);
         fscanf(imagein,"%d", &imginfo->maxVal);
         printf("\n width  = %d\n",imginfo->width);
         printf("\n height = %d\n",imginfo->height);
    	 printf("\n maxVal = %d\n",imginfo->maxVal);
         
     
         for (row=imginfo->height-1;row>=0; row--){
         
             for (col=0; col< imginfo->data; col++)
            {    
    		    fscanf(imagein,"%d", &ch_int);
                imginfo->data[row][col] = ch_int;
                }
    		 }
        
       printf("Enter path of output file:");
    
    
        scanf("%s",tpath);
        imageout=fopen(tpath,"w+");
    
    
    	for ( i = 0 ; i < row ; i++ )
      {
        for ( j = 0 ; j < col ; j++ )
        {
          fprintf( imageout,"%d" , imginfo->data[row][col] );
          
        }
        printf( "\n" ) ;
      }
      
    return 0;
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The first step is to learn how to indent code consistently.
    Code:
    struct PGMstructure {
      int maxVal;
      int width;
      int height;
      unsigned char data[800][800];
    };
    
    int main()
    {
      FILE *imagein, *imageout;
      char ch;
      int row, col, type;
      int num_elements;
      int i, j;
      int ch_int;
      struct PGMstructure *imginfo;
      char fpath[1000], tpath[1000];
    
      printf("Enter PGM file path:");
      scanf("%s", fpath);
    
      imagein = fopen(fpath, "r+");
      if (imagein == NULL) {
        printf("Error opening first file");
        exit(8);
      }
    
      while (getc(imagein) != '\n');
    
      while (getc(imagein) == '#') {
        while (getc(imagein) != '\n');
      }
    
      fseek(imagein, -1, SEEK_CUR);
      fscanf(imagein, "%d", &imginfo->width);
      fscanf(imagein, "%d", &imginfo->height);
      fscanf(imagein, "%d", &imginfo->maxVal);
    
      printf("\n width  = %d\n", imginfo->width);
      printf("\n height = %d\n", imginfo->height);
      printf("\n maxVal = %d\n", imginfo->maxVal);
    
      for (row = imginfo->height - 1; row >= 0; row--) {
        for (col = 0; col < imginfo->data; col++) {
          fscanf(imagein, "%d", &ch_int);
          imginfo->data[row][col] = ch_int;
        }
      }
    
      printf("Enter path of output file:");
      scanf("%s", tpath);
      imageout = fopen(tpath, "w+");
    
      for (i = 0; i < row; i++) {
        for (j = 0; j < col; j++) {
          fprintf(imageout, "%d", imginfo->data[row][col]);
        }
        printf("\n");
      }
    
      return 0;
    }
    > However I am getting some problems, the program stops running suddenly. I am not sure where the problem is :
    How do you know it's stopped?
    - do you get a command prompt back?
    - does it pop up some error message like "this program has stopped working" ?

    Is the behaviour consistent?
    Say for example one .pgm file always works, and another always fails. If so, study the apparent differences and consider how that affects your code.

    Are all your input files less than 800x800 in size? If either is exceeded, your code will blow up.

    For example, your code to deal with comment lines (beginning with #) is extremely fragile. The spec says comments can appear anywhere, but you assume a specific place.

    > struct PGMstructure *imginfo;
    Probably the biggest mistake of all, where is the memory for this pointer allocated?
    You can't just declare a pointer, then go do things like imginfo->member without considering how imginfo has been initialised to point to some usable memory.


    Have you tried to use a debugger?

    What is the purpose of the final printf("\n") in the last loop? Did you mean to write this to the file?

    > scanf("%s", fpath);
    I hope you don't have filenames with spaces in, otherwise it just won't work.

    > imagein = fopen(fpath, "r+");
    Why the + in all the modes? You're not updating any files, it's straight forward read from one, write to another.

    > fprintf(imageout, "%d", imginfo->data[row][col]);
    If you're trying to create another .pgm file, then you need to space separate the pixel values.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jun 2016
    Posts
    3
    Quote Originally Posted by Salem View Post
    The first step is to learn how to indent code consistently.
    Code:
    struct PGMstructure {
      int maxVal;
      int width;
      int height;
      unsigned char data[800][800];
    };
    
    int main()
    {
      FILE *imagein, *imageout;
      char ch;
      int row, col, type;
      int num_elements;
      int i, j;
      int ch_int;
      struct PGMstructure *imginfo;
      char fpath[1000], tpath[1000];
    
      printf("Enter PGM file path:");
      scanf("%s", fpath);
    
      imagein = fopen(fpath, "r+");
      if (imagein == NULL) {
        printf("Error opening first file");
        exit(8);
      }
    
      while (getc(imagein) != '\n');
    
      while (getc(imagein) == '#') {
        while (getc(imagein) != '\n');
      }
    
      fseek(imagein, -1, SEEK_CUR);
      fscanf(imagein, "%d", &imginfo->width);
      fscanf(imagein, "%d", &imginfo->height);
      fscanf(imagein, "%d", &imginfo->maxVal);
    
      printf("\n width  = %d\n", imginfo->width);
      printf("\n height = %d\n", imginfo->height);
      printf("\n maxVal = %d\n", imginfo->maxVal);
    
      for (row = imginfo->height - 1; row >= 0; row--) {
        for (col = 0; col < imginfo->data; col++) {
          fscanf(imagein, "%d", &ch_int);
          imginfo->data[row][col] = ch_int;
        }
      }
    
      printf("Enter path of output file:");
      scanf("%s", tpath);
      imageout = fopen(tpath, "w+");
    
      for (i = 0; i < row; i++) {
        for (j = 0; j < col; j++) {
          fprintf(imageout, "%d", imginfo->data[row][col]);
        }
        printf("\n");
      }
    
      return 0;
    }
    > However I am getting some problems, the program stops running suddenly. I am not sure where the problem is :
    How do you know it's stopped?
    - do you get a command prompt back?
    - does it pop up some error message like "this program has stopped working" ?

    Is the behaviour consistent?
    Say for example one .pgm file always works, and another always fails. If so, study the apparent differences and consider how that affects your code.

    Are all your input files less than 800x800 in size? If either is exceeded, your code will blow up.

    For example, your code to deal with comment lines (beginning with #) is extremely fragile. The spec says comments can appear anywhere, but you assume a specific place.

    > struct PGMstructure *imginfo;
    Probably the biggest mistake of all, where is the memory for this pointer allocated?
    You can't just declare a pointer, then go do things like imginfo->member without considering how imginfo has been initialised to point to some usable memory.


    Have you tried to use a debugger?

    What is the purpose of the final printf("\n") in the last loop? Did you mean to write this to the file?

    > scanf("%s", fpath);
    I hope you don't have filenames with spaces in, otherwise it just won't work.

    > imagein = fopen(fpath, "r+");
    Why the + in all the modes? You're not updating any files, it's straight forward read from one, write to another.

    > fprintf(imageout, "%d", imginfo->data[row][col]);
    If you're trying to create another .pgm file, then you need to space separate the pixel values.
    There were some improvements. Yes, spacing is relevant.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. writing array into file and reading array from file
    By isolatedleo in forum C Programming
    Replies: 1
    Last Post: 04-20-2014, 02:59 AM
  2. Reading from file into Array
    By lvl99 in forum C Programming
    Replies: 8
    Last Post: 09-23-2009, 02:27 PM
  3. Reading a language file (UTF-8 to wstring)
    By EVOEx in forum C++ Programming
    Replies: 2
    Last Post: 10-27-2008, 09:45 AM
  4. Reading from a file into an array
    By fmsguy06 in forum C Programming
    Replies: 6
    Last Post: 10-18-2008, 09:25 PM
  5. Replies: 1
    Last Post: 04-25-2006, 12:14 AM

Tags for this Thread