io.h
Go to the documentation of this file.
00001 /*
00002  * pfmReader.h
00003  *
00004  *  Created on: Dec 4, 2015
00005  *      Author: mathieu
00006  */
00007 
00008 #ifndef PFMREADER_H_
00009 #define PFMREADER_H_
00010 
00011 #include <iostream>
00012 #include <stdio.h>
00013 #include <opencv2/opencv.hpp>
00014 
00015 // taken from http://vision.middlebury.edu/stereo/ evaluation tool
00016 
00017 void skipComment(FILE *fp)
00018 {
00019     // skip comment lines in the headers of pnm files
00020 
00021     char c;
00022     while ((c=getc(fp)) == '#')
00023         while (getc(fp) != '\n') ;
00024     ungetc(c, fp);
00025 }
00026 
00027 void skipSpace(FILE *fp)
00028 {
00029     // skip white space in the headers or pnm files
00030 
00031     char c;
00032     do {
00033         c = getc(fp);
00034     } while (c == '\n' || c == ' ' || c == '\t' || c == '\r');
00035     ungetc(c, fp);
00036 }
00037 
00038 bool readHeader(FILE *fp, const char *imtype, char c1, char c2,
00039                  int *width, int *height, int *nbands, int thirdArg)
00040 {
00041     // read the header of a pnmfile and initialize width and height
00042 
00043     char c;
00044 
00045         if (getc(fp) != c1 || getc(fp) != c2)
00046         {
00047                 printf("ReadFilePGM: wrong magic code for %s file\n", imtype);
00048                 return false;
00049         }
00050         skipSpace(fp);
00051         skipComment(fp);
00052         skipSpace(fp);
00053         int r = fscanf(fp, "%d", width);
00054         if(r==0)
00055         {
00056                 return false;
00057         }
00058         skipSpace(fp);
00059         r = fscanf(fp, "%d", height);
00060         if(r==0)
00061         {
00062                 return false;
00063         }
00064         if (thirdArg) {
00065                 skipSpace(fp);
00066                 r = fscanf(fp, "%d", nbands);
00067                 if(r==0)
00068                 {
00069                         return false;
00070                 }
00071         }
00072     // skip SINGLE newline character after reading image height (or third arg)
00073         c = getc(fp);
00074     if (c == '\r')      // <cr> in some files before newline
00075         c = getc(fp);
00076     if (c != '\n') {
00077         if (c == ' ' || c == '\t' || c == '\r')
00078         {
00079             printf("newline expected in file after image height\n");
00080             return false;
00081         }
00082         else
00083         {
00084                 printf("whitespace expected in file after image height\n");
00085                 return false;
00086         }
00087   }
00088 
00089     return true;
00090 }
00091 
00092 int littleendian()
00093 {
00094     int intval = 1;
00095     uchar *uval = (uchar *)&intval;
00096     return uval[0] == 1;
00097 }
00098 
00099 cv::Mat readPFM(const char* filename)
00100 {
00101         cv::Mat disp;
00102 
00103     // Open the file and read the header
00104     FILE *fp = fopen(filename, "rb");
00105     if (fp == 0)
00106     {
00107         printf("ReadFilePFM: could not open %s\n", filename);
00108         return cv::Mat();
00109     }
00110 
00111     int width, height, nBands;
00112     readHeader(fp, "PFM", 'P', 'f', &width, &height, &nBands, 0);
00113 
00114     skipSpace(fp);
00115 
00116     float scalef;
00117     int r = fscanf(fp, "%f", &scalef);  // scale factor (if negative, little endian)
00118     if(r==0)
00119         {
00120         return cv::Mat();
00121         }
00122 
00123     // skip SINGLE newline character after reading third arg
00124     char c = getc(fp);
00125     if (c == '\r')      // <cr> in some files before newline
00126         c = getc(fp);
00127     if (c != '\n') {
00128         if (c == ' ' || c == '\t' || c == '\r')
00129         {
00130             printf("newline expected in file after scale factor\n");
00131             return cv::Mat();
00132         }
00133         else
00134         {
00135             printf("whitespace expected in file after scale factor\n");
00136             return cv::Mat();
00137         }
00138     }
00139 
00140     // Set the image shape
00141     disp = cv::Mat(height, width, CV_32FC1);
00142 
00143     int littleEndianFile = (scalef < 0);
00144     int littleEndianMachine = littleendian();
00145     int needSwap = (littleEndianFile != littleEndianMachine);
00146     //printf("endian file = %d, endian machine = %d, need swap = %d\n",
00147     //       littleEndianFile, littleEndianMachine, needSwap);
00148 
00149     for (int y = height-1; y >= 0; y--) { // PFM stores rows top-to-bottom!!!!
00150         int n = width;
00151         float* ptr = (float *) disp.row(y).data;
00152         if ((int)fread(ptr, sizeof(float), n, fp) != n)
00153         {
00154             printf("ReadFilePFM(%s): file is too short\n", filename);
00155             return cv::Mat();
00156         }
00157 
00158         if (needSwap) { // if endianness doesn't agree, swap bytes
00159             uchar* ptr = (uchar *) disp.row(y).data;
00160             int x = 0;
00161             uchar tmp = 0;
00162             while (x < n) {
00163                 tmp = ptr[0]; ptr[0] = ptr[3]; ptr[3] = tmp;
00164                 tmp = ptr[1]; ptr[1] = ptr[2]; ptr[2] = tmp;
00165                 ptr += 4;
00166                 x++;
00167             }
00168         }
00169     }
00170     if (fclose(fp))
00171     {
00172         printf("ReadFilePGM(%s): error closing file\n", filename);
00173         return cv::Mat();
00174     }
00175 
00176     return disp;
00177 }
00178 
00179 
00180 #endif /* PFMREADER_H_ */


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:16