/* Jason Lawrence Princeton University pfm.cc File I/O for images stored in PFM format. */ #include #include #include #include "pfm.h" inline void check_string(char *buf, const char *tag) { if (strncmp(buf+2,tag,strlen(tag)==0)) { fprintf(stderr, "Invalid header or file not valid \"gantry\" PFM image.\n"); fprintf(stderr, "Failed at tag: [%s]\n", tag); exit(1); } } inline void get_string(FILE *in, const char *tag, char *value) { static char buf[1024]; fgets(buf,1024,in);buf[1023]=0; check_string(buf,tag); // Trim trailing newline buf[strlen(buf)-1]=0; char *needle = strstr(buf,":"); if (!needle) { fprintf(stderr, "Failed to parse [%s]\n", buf); exit(1); } // Copy past comment field strcpy(value,needle+1); } inline void get_double(FILE *in, const char *tag, double &value) { static char buf[1024]; fgets(buf,1024,in);buf[1023]=0; check_string(buf,tag); // Trim trailing newline buf[strlen(buf)-1]=0; char *needle = strstr(buf,":"); if (!needle) { fprintf(stderr, "Failed to parse [%s]\n", buf); exit(1); } // Copy past comment field value = atof(needle+1); } inline void get_int(FILE *in, const char *tag, int &value) { static char buf[1024]; fgets(buf,1024,in);buf[1023]=0; check_string(buf,tag); // Trim trailing newline buf[strlen(buf)-1]=0; char *needle = strstr(buf,":"); if (!needle) { fprintf(stderr, "Failed while parsing [%s]\n", buf); exit(1); } // Copy past comment field value = atoi(needle+1); } void read_header (FILE *in, gantry_img_header_t &header) { // Blank header bzero(&header,sizeof(header)); // Parse PFM header static char buf[1024]; fgets(buf, 1024, in); fgets(buf, 1024, in); sscanf(buf, "%d %d", &header.width, &header.height); if (header.width < 0 || header.height < 0) { fprintf(stderr, "Invalid header or file not valid \"Cornell gantry\" PFM image.\n"); exit(1); } get_string(in,"COLORBAL",header.colorbal); get_string(in,"READOUT",header.readout); get_string(in,"COMMENT",header.comment); get_string(in,"DATE",header.date); get_string(in,"GAIN",header.gain); get_string(in,"OFFSET",header.offset); get_string(in,"EXPOSURES",header.exps); get_string(in,"COLOR",header.color); get_int (in,"WIDTH",header.orig_width); get_int (in,"HEIGHT",header.orig_height); get_int (in,"BANDS",header.bands); get_double(in,"LIGHT",header.light); get_double(in,"BASE",header.base); get_double(in,"OBJECT",header.obj); get_double(in,"CAMERA",header.cam); get_double(in,"THETAV",header.thetav); get_double(in,"PHIV",header.phiv); get_double(in,"THETAL",header.thetal); get_double(in,"PHIL",header.phil); get_double(in,"THETAH",header.thetah); get_double(in,"OFFX",header.offx); get_double(in,"OFFY",header.offy); get_double(in,"VX",header.vx); get_double(in,"VY",header.vy); get_double(in,"VZ",header.vz); get_double(in,"LX",header.lx); get_double(in,"LY",header.ly); get_double(in,"LZ",header.lz); fgets(buf, 1024, in); if (buf[0] == '#') { fprintf(stderr, "Invalid header or file not valid \"Cornell gantry\" PFM image.\n"); fprintf(stderr, "Failed after last tag.\n"); exit(1); } } float * read_pfm (char *fname, gantry_img_header_t &header) { // Open image file FILE *in = fopen(fname, "rb"); if (!in) { fprintf(stderr, "Failed to open file [%s].\n",fname); return NULL; } read_header(in,header); float *img = new float[header.width*header.height*3]; // Read pixel data if (fread(img, sizeof(float), 3*header.width*header.height, in) != 3*header.width*header.height) { fprintf(stderr, "Unexpected EOF while reading image data.\n"); return NULL; } fclose(in); return img; } bool read_pfm (char *fname, gantry_img_header_t &header, float *img) { // Open image file FILE *in = fopen(fname, "rb"); if (!in) { fprintf(stderr, "Failed to open file [%s].\n",fname); return false; } read_header(in,header); // Read pixel data if (fread(img, sizeof(float), 3*header.width*header.height, in) != 3*header.width*header.height) { fprintf(stderr, "Unexpected EOF while reading image data.\n"); return false; } fclose(in); return true; }