2

So I have a .ppm file and the goal is to read each pixel to corresponding r[] g[] and b[] elements. The code reads the first line (idk correct or not), but it does not go any further. I'm unsure if I need these getc(fp); in order to skip spaces. Reading each line and parsing it to int is not an option. Thanks for any help.

int main(int argc, char** argv) 
    {
        int height;
        int width;
        int max;
        FILE *fp;
        fp = fopen("vit_small.ppm", "r");
        fscanf(fp, "%*[^\n]\n", NULL);
        fscanf(fp, "%d %d", &width, &height);
        printf("Width is %d height is %d \n", width, height);
        fscanf(fp, "%d", &max);
        printf("Maximum value %d \n", max);
        int r [height][width];
        int g [height][width];
        int b [height][width];
        int hist [5];
        int w = 0;
        int h = 0;
        char buffer [1000];
        for (;w<height;w++)
        {
            printf("Row number %d \n", w);
            for (;h<width;h++)
                {
                fread(&r[w][h], 1, 1, fp);
                printf("%d ", r[w][h]);
                getc(fp);
                fread(&g[w][h], 1, 1, fp);
                printf("%d ", g[w][h]);
                getc(fp);
                fread(&b[w][h], 1, 1, fp);
                printf("%d ", b[w][h]);
                getc(fp);
                }
            getc(fp);
            printf("\n");
        }

        int i = 0;
        int j = 0;
        for (;i<height; i++) 
        {
            for (;j<width; j++) 
            {
                printf("%d %d %d ", r[i][j], g[i][j], b[i][j]);
            }
        printf("\n");
        }

     fclose(fp);
     FILE * res;
     res = fopen ("Image_output.ppm", "w");
     fprintf (res, "P6\n");
     fprintf(res, "%d\n", width);
     fprintf(res, "%d\n", height);
     fprintf(res, "%d\n", max);
     i = 0;
     j = 0;
     for(; i < height; i++)
     {
         for(; j < width; j++)
         {
             fprintf(res, "%d %d %d", r[i][j], g[i][j], b[i][j]);
         }
         fprintf(res,"\n");
     }
        return (EXIT_SUCCESS);
    }
  • Totally unrelated, but if you use the `"%*..."` format with `scanf` and family, then you don't need an argument. – Some programmer dude Apr 25 '15 at 21:05
  • Also, `scanf` treats all whitespace in the format as any whitespace. So the format `"%[^\n]"` will match any non-whitespace character, not only non-newline. So if the line contains *any* spaces like the normal space or tab or anything else, then the scanning will stop at that. So you can't use that to read (or in your case discard) any line containing a space. Not really relevant to your question and your problem, but good to know for future reference. – Some programmer dude Apr 25 '15 at 21:07
  • Also, you should probably be using e.g. `fgets` to get each line, and then parse the line. – Some programmer dude Apr 25 '15 at 21:09
  • That line with "%[^\n]" is used just to skip the first line containing P6 as it's useless, but thanks – Iurii Coroli Apr 25 '15 at 21:12
  • every call to any of the scanf() family of functions (including fscanf()) needs to have the returned value (not the parameter) checked to assure the operation was successful. – user3629249 Apr 27 '15 at 00:08
  • the returned value from fopen() needs to be checked (!=NULL) to assure the operation was successful. – user3629249 Apr 27 '15 at 00:08
  • the function: 'getc()' should not be used. rather, use 'fgetc()' – user3629249 Apr 27 '15 at 00:14
  • this line: 'fscanf(fp, "%*[^\n]\n", NULL);' raises a compiler warning about too many arguments for format. Suggest: 'fscanf(fp, "%*[^\n]\n", NULL);' The variable 'hist' raises a compiler warning as that variable is not used. The variable 'buffer' raises a compiler warning as that variable is not used. the passed parameters 'argc' and 'argv' raise compiler warnings as those parameters are not used, suggest; 'int main( void )' – user3629249 Apr 27 '15 at 00:31

1 Answers1

1

The P6 format of PPM stores each primary as a byte and there are no rows and no spaces. So if an image is 10 by 6, it will have 180 bytes (10x6x3) following the 255 and newline character. See Wikipedia entry on PPM.

vacawama
  • 150,663
  • 30
  • 266
  • 294