简体   繁体   中英

Reading a P2 .pgm image into a 2D array in C

I have started learning about image processing and I am trying to read a .pgm file into a 2D array in C. I am testing the input and output, but the program did not work properly so, I tried to make some changes. How could I improve/modify the code to make it work?

#include<stdio.h>
#include<stdlib.h>

struct PGMstructure 
{
    int maxVal;
    int width;
    int height;
    int data[800][800];
};


int main()
{
    FILE *imagein,*imageout;

    int row, col;

    int i,j;
    int ch_int;
    struct PGMstructure *imginfo;   
    char infpath[500],outfpath[500];

    printf("Enter PGM file path:");
    scanf("%s",infpath);
    imagein = fopen(infpath,"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=0; row<imginfo->height; row++){

        for (col=0; col < imginfo->width; col++)
        {    
            fscanf(imagein,"%d", &ch_int);
            imginfo->data[row][col] = ch_int;
        }
    }

    printf("Enter path of output file:");

    scanf("%s",outfpath);
    imageout = fopen(outfpath,"w+");


    for ( i = 0 ; i < row ; i++ )
    {
        for ( j = 0 ; j < col ; j++ )
        {
            fprintf( imageout,"%d" , imginfo->data[row][col] );
        }
        printf( "\n" ) ;
    }

    return 0;
}

Your code seems alright, the only problem is that you are only creating the pointer, not referencing it to an actual structure in memory.

You can do this by adding the following line of code and everything should work as intended.

imginfo = malloc(sizeof(struct PGMstructure));

The main problem with your code is the one highlighted by MiteshNinja, that is you forgot to allocate space for your structure.
When you no longer need the struct, remember to release the memory you've allocated with malloc using the function free . This is extremely important in order to avoid memory leaks!

Another thing I think it is worth pointing out is that whenever you're done with a file, you should remember to close it with fclose .

Then there are a number of trivial problems that you can find below in the code.

At last, maybe this post could be of help, too.

#include<stdio.h>
#include<stdlib.h>

struct PGMstructure
{
    int maxVal;
    int width;
    int height;
    int data[800][800];
};


int main()
{
    FILE *imagein,*imageout;

    int row, col;

    int i,j;
    int ch_int;
//--- CHANGED ------ Start
    struct PGMstructure *imginfo = malloc(sizeof(struct PGMstructure));
//--- CHANGED ------ End
    char infpath[500],outfpath[500];

    printf("Enter PGM file path:");
    scanf("%s",infpath);
    imagein = fopen(infpath,"r+");

    if(imagein == NULL)
    {
        printf("Error opening first file");
        exit(8);
    }

//--- CHANGED ------ Start
    while(getc(imagein) != '\n');           // Ignore the first line in the input file

    if (getc(imagein) == '#' )              // If it is the case, ignore the second line in the input file
        {
        while(getc(imagein) != '\n');
        }
    else
        {
        fseek(imagein, -1, SEEK_CUR);
        }
//--- CHANGED ------ End

    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=0; row<imginfo->height; row++){

        for (col=0; col < imginfo->width; col++)
        {
            fscanf(imagein,"%d", &ch_int);
            imginfo->data[row][col] = ch_int;
        }
    }

//--- CHANGED ------ Start
    fclose(imagein);
//--- CHANGED ------ End

    printf("Enter path of output file:");

    scanf("%s",outfpath);
    imageout = fopen(outfpath,"w+");

//--- CHANGED ------ Start
    for ( i = 0 ; i < imginfo->height ; i++ )
    {
        for ( j = 0 ; j < imginfo->width ; j++ )
        {
            fprintf( imageout,"%d  " , imginfo->data[i][j] );
        }
            fprintf( imageout,"\n" );
    }

    fclose(imageout);
    free(imginfo);
//--- CHANGED ------ End

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM