source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/Rectification/src/PNM.h @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 7.7 KB
Line 
1//-*-c++-*-
2
3#ifndef _PNM_H
4#define _PNM_H
5
6#include "Rectify/Ops.h"
7
8#include <iostream>
9#include <string>
10
11class PNMLoadSave {
12
13private:
14
15  // Skip over spaces and comments; temp is the current file character
16  static void SkipSpaces(std::ifstream& file, signed char& temp)
17  {
18    while (temp == ' ' || temp == '\t' || temp == '\n' || temp == '#')
19    {
20      if (file.eof())
21        return;
22      if (temp == '#') // skip this line:
23        while ((temp != '\n') && (temp != EOF))
24          temp=file.get();
25      // skip this `whitespace' byte:
26      temp=file.get();
27    }
28  }
29
30  // Get an integer from the file stream; temp is the current file character
31  static int ReadInteger(std::ifstream& file, signed char& temp)
32  {
33    int n = 0;
34    bool neg=false;
35    while (((temp >= '0') && (temp <= '9')) || (temp == '-'))
36    {
37      if (file.eof())
38        return 0;
39      if (temp=='-')
40        neg=true;
41      n *= 10; n += (temp - '0');
42      temp=file.get();
43    }
44    if (neg)
45      n=-n;
46    return n;
47  }
48
49  struct pgm_image_header
50  {
51    char magic_number[2]; // magic number
52    int height; // number of scan lines
53    int width; // scan line length
54    int maxval;
55  };
56
57public:
58
59  /// Load the image in the given filename. If succeeds, image is filled and returns true. Returns false otherwise
60  template <class DataT>
61    static bool LoadImage(const std::string &filename, Image::Image<DataT> &image) {
62      // assume filename already verified
63      std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary);
64      if (!file) {
65        std::cerr << "Couldn't open file '" << filename << "' for reading image" << std::endl;
66        exit(1);
67      }
68
69      unsigned int xsize, ysize, bitspp, magicnumber;
70      bool colour;
71
72      colour=false; // PGM is greyscale by default
73      signed char temp;
74
75      /** READ THE HEADER **/
76
77      //This method assumes the PGM header is in the following format
78      //P[25]
79      //#comments
80      //#up to any amount of comments (including no comments)
81      //width height
82      //maxval
83      file.seekg(0, std::ios::beg);
84      //Because PGM Image files can contain an unlimited number of
85      //comments, this method of reading in the header is infeasible
86      //It was left in to read in the magic number
87      pgm_image_header header;
88      file.read((char*)(&header), sizeof(header));
89
90      if ((header.magic_number[0]!='P') || (!file)) {
91        std::cerr << "Couldn't open image file! " << std::endl;
92        exit(1);
93      }
94      magicnumber=header.magic_number[1]-'0';
95      if (magicnumber!=2 && magicnumber!=3 && magicnumber!=5 && magicnumber!=6) {
96        std::cerr << "Couldn't open pnm image file because found bad magic number: only 2,3,5,6 recognised" << std::endl;
97        exit(1);
98      }
99
100      file.seekg(3, std::ios::beg);
101      temp=file.get();
102
103      //Skip over spaces and comments
104      SkipSpaces(file,temp);
105      //Read in Width
106      xsize=(unsigned int)ReadInteger(file,temp);
107      //Skip over spaces and comments
108      SkipSpaces(file,temp);
109      //Read in Height
110      ysize=ReadInteger(file,temp);
111      //Skip over spaces and comments
112      SkipSpaces(file,temp);
113      //Read in Maxval
114      unsigned int maxval=ReadInteger(file,temp);
115
116      if (temp == ' ' || temp == '\t' || temp == '\n')
117        temp=file.get();
118
119      // Step the file back one.
120      file.seekg(-1,std::ios::cur);
121
122      if (maxval==0)
123        bitspp=8;
124      else
125      {
126        bitspp=0;
127        while (maxval>0)
128        {
129          bitspp++; maxval=maxval>>1;
130        }
131      }
132
133      /** DONE READING THE HEADER **/
134
135      if (magicnumber==3 || magicnumber==6) {
136        // Colour so must have 3 of those samples per pixel
137        bitspp=bitspp*3;
138        colour=true;
139      }
140
141      image.resize(xsize, ysize, colour);
142
143      // Every image should have 1D access unless the image class is written by a retard
144      // However, I'm going to assume retard level and simply assume a 1D block for the image at (0,0)
145      // so don't add unnecesary functions to Image.h and freak those retards out
146      if (magicnumber==2)
147      {
148        DataT TempStore;
149        DataT *oiter=&(image(0,0)), *containerend=oiter+(xsize*ysize);
150
151        while (!file.eof() && oiter!=containerend) {
152          // Problems with my gcc unless copy to a temp - probably optimisations or something
153          file >> TempStore;
154          *oiter++=TempStore;
155        }
156      }
157      if (magicnumber==3)
158      {
159        DataT R,G,B;
160
161        DataT *oiter=&(image(0,0)), *containerend=oiter+(xsize*ysize);
162        while (!file.eof() && oiter!=containerend) {
163          file >> R >> G >> B;
164          *oiter++=(R<<16)+(G<<8)+B;
165        }
166      }
167      if (magicnumber==5)
168      {
169        DataT *oiter=&(image(0,0)), *containerend=oiter+(xsize*ysize);
170        while (!file.eof() && oiter!=containerend)
171          *oiter++=file.get();
172      }
173      if (magicnumber==6)
174      {
175        DataT *oiter=&(image(0,0)), *containerend=oiter+(xsize*ysize);
176        while (!file.eof() && oiter!=containerend)
177          *oiter++=(file.get()<<16)+(file.get()<<8)+file.get();
178      }
179
180      if (!(file.good()) && !(file.eof()))
181        return false;
182
183      return true;
184    }
185
186    // Save an image to the given file.
187    template <class DataT>
188    static void SaveImage(const std::string &filename, const Image::Image<DataT> &image) {
189      std::ofstream file(filename.c_str(), std::ios::out | std::ios::binary);
190      if (!file) {
191        std::cerr << "Couldn't open file '" << filename << "' for writing image" << std::endl;
192        exit(1);
193      }
194
195      if (!image.isColour()) {
196        DataT maxval=0;
197        // Get bits per pixel for container based on max value if greyscale
198        for (size_t x=0;x<image.xsize();++x) {
199          for (size_t y=0;y<image.ysize();++y) {
200            if (image(x,y)>maxval)
201              maxval=image(x,y);
202          }
203        }
204        // Get bits per pixel based on maximum value in the image
205        unsigned int bpp=0;
206        while (maxval>0) {
207          ++bpp;
208          maxval=maxval>>1;
209        }
210
211        // Write magic number.
212        if (bpp==8)
213          file << "P5" << std::endl;
214        else
215          file << "P2" << std::endl;
216
217        // Write comments
218        file << "# Created by some nice code" << std::endl;
219
220        // Write Height and Width
221        file << (unsigned int)image.xsize() << " " << (unsigned int)image.ysize() << std::endl;
222
223        // Write max val
224        if (bpp<32)
225          file << (1<<bpp)-1 << std::endl;
226        else
227          file << UINT_MAX << std::endl;
228
229        if (bpp==8) {
230          char *buffer=new char[image.xsize()*image.ysize()];
231          char *iter=buffer;
232          for (size_t y=0;y<image.ysize();++y)
233            for (size_t x=0;x<image.xsize();++x)
234              *iter++=image(x,y);
235          file.write(buffer, ((std::streamsize)(image.xsize()*image.ysize())));
236          delete[] buffer;
237        }
238        else
239        {
240          for (size_t y=0;y<image.ysize();++y)
241            for (size_t x=0;x<image.xsize();++x)
242              file << image(x,y) << std::endl;
243        }
244      }
245      else
246      {
247
248        file << "P6" << std::endl;
249
250        // Write comments
251        file << "# Created by some nice code" << std::endl;
252
253        // Write Height and Width
254        file << (unsigned int)image.xsize() << " " << (unsigned int)image.ysize() << std::endl;
255
256        // Write max val
257        file << "255" << std::endl;
258
259        for (size_t y=0;y<image.ysize();++y)
260          for (size_t x=0;x<image.xsize();++x) {
261            DataT imval=image(x,y);
262            file.put((imval & (255<<16))>>16);
263            file.put((imval & (255<<8))>>8);
264            file.put(imval & 255);
265          }
266      }
267
268      if (!file) {
269        std::cerr << "Filesystem error whilst writing image: " << filename << std::endl;
270        exit(1);
271      }
272
273      return;
274
275    }
276
277};
278
279#endif
Note: See TracBrowser for help on using the repository browser.