00001
00007 #ifndef __PNM_IO_H__
00008 #define __PNM_IO_H__
00009
00010 #include <string>
00011 using std::string;
00012 #include <fstream>
00013 #include <utility>
00014 #ifdef _CRAYMPP
00015 #include <pair.h>
00016 #endif
00017
00018
00019 #ifdef USE_ZLIB
00020 #include "gzstream.h"
00021 #define IFSTREAM igzstream
00022 #else
00023 #define IFSTREAM std::ifstream
00024 #endif
00025
00026
00032 inline std::istream& eatcomments(std::istream& is)
00033 {
00034 char c;
00035 is >> c;
00036 while (c=='#') {
00037 while (is.get()!='\n');
00038 is >> c;
00039 }
00040 is.putback(c);
00041
00042 return is;
00043 }
00044
00045
00053 template <class Array2D>
00054 bool pgm_read(const string& filename, Array2D& image)
00055 {
00056 IFSTREAM file(filename.c_str());
00057 if (!file) return false;
00058
00059 string filetype; file >> filetype >> eatcomments;
00060 const bool is_greyscale = (filetype=="P2" || filetype=="P5");
00061 const bool is_bitmap = (filetype=="P1" || filetype=="P4");
00062 if (!(is_greyscale || is_bitmap)) return false;
00063
00064 int width; file >> width >> eatcomments;
00065 int height; file >> height >> eatcomments;
00066 double maxval=1;
00067 if (!is_bitmap) file >> maxval;
00068
00069 if (!maxval) return false;
00070
00071 image=Array2D(height,width);
00072
00073
00074 if (filetype=="P1") {
00075 file >> eatcomments;
00076 for (int i=0; i<height; i++) {
00077 for (int j=0; j<width; j++) {
00078 int val;
00079 file >> val;
00080 image[i][j] = (val? 0.0 : 1.0);
00081 }
00082 file >> eatcomments;
00083 }
00084 }
00085
00086
00087 if (filetype=="P2") {
00088 file >> eatcomments;
00089 for (int i=0; i<height; i++) {
00090 for (int j=0; j<width; j++) {
00091 int val;
00092 file >> val;
00093 image[i][j] = val/maxval;
00094 }
00095 file >> eatcomments;
00096 }
00097 }
00098
00099
00100 else if (filetype=="P4") {
00101
00102 for (int i=0; i<height; i++) {
00103 int b=8;
00104 char bitbuffer=0;
00105 for (int j=0; j<width; j++, b++) {
00106 if (b>7) {
00107 b=0;
00108 file.get(bitbuffer);
00109 }
00110 const unsigned char mask = 128>>b;
00111 const bool bit = ((unsigned char)bitbuffer) & mask;
00112 image[i][j] = bit? 0.0 : 1.0;
00113 }
00114 }
00115 }
00116
00117
00118 else if (filetype=="P5") {
00119 file.get();
00120 for (int i=0; i<height; i++) {
00121 for (int j=0; j<width; j++) {
00122 char val;
00123 file.get(val);
00124 image[i][j] = ((unsigned char)val)/maxval;
00125 }
00126 }
00127 }
00128
00129 return true;
00130 }
00131
00132
00133
00138 inline std::pair<int,int> pnm_size(const string& filename)
00139 {
00140 IFSTREAM file(filename.c_str());
00141 if (!file) return std::make_pair(0,0);
00142
00143 string filetype; file >> filetype >> eatcomments;
00144 if (filetype[0]!='P') return std::make_pair(0,0);
00145
00146 int width; file >> width >> eatcomments;
00147 int height; file >> height >> eatcomments;
00148 return std::make_pair(width,height);
00149 }
00150
00151
00174 inline bool pgm_white_is_transparent(const string& filename)
00175 {
00176 IFSTREAM file(filename.c_str());
00177 if (!file) return false;
00178
00179 int non_comment_lines=0;
00180 while (!file.eof()) {
00181 char c;
00182 file >> c;
00183
00184
00185 if (c=='#') {
00186 string line;
00187 c=file.get();
00188 while (c!='\n') {
00189
00190 if (line.length()<=15) line+=c;
00191 c=file.get();
00192 }
00193 if (line=="Transparent: 255")
00194 return true;
00195 }
00196
00197
00198 else {
00199 non_comment_lines++;
00200 if (non_comment_lines>2) return false;
00201 while (file.get()!='\n' && !file.eof());
00202 }
00203 }
00204
00205 return false;
00206 }
00207
00208 #endif