nkkav / libpnmio

C library for reading and writing PNM (PBM/PGM/PPM) and PFM images.
Other
17 stars 9 forks source link

read_pfm_header #3

Open adammaj1 opened 4 years ago

adammaj1 commented 4 years ago

Hi , can you check read_pfm_header.

    // magic number
    switch (pnm_type ){
        case PBM_ASCII      : printf("P1 = PBM_ASCII\n"); break;
        case PGM_ASCII      : printf("P2 = PGM_ASCII\n"); break;
        case PPM_ASCII      : printf("P3 = PPM_ASCII\n"); break;
        case PBM_BINARY     : printf("P4 = PBM_BINARY\n"); break;
        case PGM_BINARY     : printf("P5 = PGM_BINARY\n"); break;
        case PPM_BINARY     : printf("P6 = PPM_BINARY\n"); break;
        case PAM        : printf("P7 = PAM\n"); break;
        case PFM_RGB        : printf("PF = PFM_RGB_BINARY\n"); break;
        case PFM_GREYSCALE  : printf("Pf = PFM_GREYSCALE_BINARY\n"); break;

        default: printf("Error: Unknown PNM/PFM file; wrong magic number!\n");
        }
    return 0;
}

//===========================================================

int main(){

    FILE * pFile;
    char * fName  = "memorial.pfm"; //"cornellbox_uniform_direct.pfm";
    int pnm_type;
    int img_xdim;
    int img_ydim;
    int img_type;
    int endianess;

    //  
    pFile = fopen (fName, "rb");
    pnm_type = get_pnm_type(pFile);
    info(pnm_type);

    if ( pnm_type ==PFM_RGB || pnm_type == PFM_GREYSCALE)
        {read_pfm_header(pFile, &img_xdim, &img_ydim, &img_type, &endianess);}

    fclose(pFile);
    return 0; 
}

it gives :

gcc p.c -lm -Wall
./a.out
PF = PFM_RGB_BINARY
 magic = 512 x_val=  768 y_val = -1 aspect_ratio = 0.000000
Error: Input file not in PFM format!

TIA

nkkav commented 4 years ago

The parsing is not robust. I want to improve it. The quick fix for your case would be to add this to your program, right after calling get_pnm_type(...):

    rewind(pFile);

as you need to rewind the file to reparse the header again and you would get:

user@userbox:~/projects/libpnmio/src$ ./issue3
Info: magic=PF, x_val=512, y_val=768, aspect_ratio=-1.000000
adammaj1 commented 4 years ago

I have changed :

void read_pfm_header(FILE *f, int *img_xdim, int *img_ydim, int *img_type, int *endianess)
{
  int flag=0; // read the line or not 
  int x_val, y_val;
  unsigned int i;
  int is_rgb=0, is_greyscale=0;
  float aspect_ratio=0;
  char magic[2];
  char line[MAXLINE];
  int count=0;
  int ch;

  /* Read the PFM file header. */

  //fgets(line, MAXLINE, f); 
  //if (fscanf(fp, "P%c\n", &ch) != 1 || ch != '6') 

  //sscanf(line, "%s", magic);
  /* read the width, height, and maximum value for a pixel */
  fscanf(f, "%d %d %f\n", &x_val, &y_val, &aspect_ratio);

  printf("\nx_val=  %d\n y_val = %d\n aspect_ratio = %f\n",  x_val, y_val, aspect_ratio);

 // fprintf(stderr, "Header:  x_val=%d\n, y_val=%d\n, aspect_ratio=%f\n",
  //   x_val, y_val, aspect_ratio);

  /* FIXME: Aspect ratio different to 1.0 is not yet supported. */
  if (!floatEqualComparison(aspect_ratio, -1.0, 1E-06) &&
      !floatEqualComparison(aspect_ratio, 1.0, 1E-06)) {
    fprintf(stderr, "Error: Aspect ratio different to -1.0 or +1.0 is unsupported!\n");
    exit(1);
  }

  *img_xdim   = x_val;
  *img_ydim   = y_val;
  *img_type   = is_rgb & ~is_greyscale;
  if (aspect_ratio > 0.0) {
    *endianess = 1;
  } else {
    *endianess = -1;
  }
}

Now it not works with comments but for simple files is enough. So without rewind:


    FILE * pFile;
    char * fName  = "memorial.pfm"; // "cornellbox_uniform_direct.pfm"; //
    int pnm_type;
    int img_xdim;
    int img_ydim;
    int img_type;
    int endianess;

    //  
    pFile = fopen (fName, "rb");
    pnm_type = get_pnm_type(pFile);

    if ( pnm_type ==PFM_RGB || pnm_type == PFM_GREYSCALE)
        {
            info(pnm_type);
            read_pfm_header(pFile, &img_xdim, &img_ydim, &img_type, &endianess);

        }

    fclose(pFile);
    return 0; 
}

it works good :

PF = PFM_RGB_BINARY

x_val=  512
 y_val = 768
 aspect_ratio = -1.000000