00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef RASTER_PNMWRITER_C_DEFINED
00039 #define RASTER_PNMWRITER_C_DEFINED
00040
00041 #include "Raster/PnmWriter.H"
00042
00043 #include "Image/Image.H"
00044 #include "Image/Normalize.H"
00045 #include "Image/Pixels.H"
00046 #include "Raster/GenericFrame.H"
00047 #include "Raster/PfmWriter.H"
00048
00049 #include <fstream>
00050
00051
00052 PnmWriter::PnmWriter(const bool forcepbm, const byte pbmthresh)
00053 :
00054 itsForcePBM(forcepbm),
00055 itsPBMThresh(pbmthresh)
00056 {}
00057
00058
00059 PnmWriter::~PnmWriter() {}
00060
00061
00062 std::string PnmWriter::writeFrame(const GenericFrame& image,
00063 const std::string& fnameorig)
00064 {
00065 if (itsForcePBM)
00066 {
00067 PnmWriter::writeRawBW(image.asGray(), itsPBMThresh, fnameorig);
00068 return fnameorig;
00069 }
00070
00071 std::string fname = fnameorig;
00072
00073 switch (image.nativeType())
00074 {
00075 case GenericFrame::NONE:
00076 LFATAL("can't write an empty image to '%s'", fname.c_str());
00077 break;
00078
00079 case GenericFrame::RGB_U8:
00080 case GenericFrame::RGBD:
00081 PnmWriter::writeRGB(image.asRgbU8(), fname);
00082 break;
00083
00084 case GenericFrame::RGB_U16:
00085 PnmWriter::writeRGB(image.asRgbU16(), fname);
00086 break;
00087
00088 case GenericFrame::RGB_F32:
00089 PnmWriter::writeRGB(image.asRgbU8(), fname);
00090 break;
00091
00092 case GenericFrame::GRAY_U8:
00093 PnmWriter::writeGray(image.asGrayU8(), fname);
00094 break;
00095
00096 case GenericFrame::GRAY_U16:
00097 PnmWriter::writeGray(image.asGrayU16(), fname);
00098 break;
00099
00100 case GenericFrame::GRAY_F32:
00101 {
00102 if (image.floatFlags() & FLOAT_NORM_PRESERVE)
00103 {
00104
00105
00106
00107 std::string::size_type len = fname.length();
00108 if ((len > 4)
00109 && (fname.compare(len-4, 4, ".pgm") == 0 ||
00110 fname.compare(len-4, 4, ".ppm") == 0 ||
00111 fname.compare(len-4, 4, ".pnm") == 0))
00112 {
00113 fname[len-2] = 'f';
00114 }
00115 else
00116 {
00117 fname += ".pfm";
00118 }
00119 PfmWriter::writeFloat(image.asGrayF32(), fname);
00120 }
00121 else
00122 {
00123 PnmWriter::writeGray(image.asGrayU8(), fname);
00124 }
00125 }
00126 break;
00127
00128 case GenericFrame::VIDEO:
00129 PnmWriter::writeRGB(image.asRgb(), fname);
00130 break;
00131 }
00132
00133 return fname;
00134 }
00135
00136
00137 void PnmWriter::writeRGB(const Image<PixRGB<byte> >& image,
00138 std::ostream& strm)
00139 {
00140 strm << "P6\n" << image.getWidth() << ' ' << image.getHeight()
00141 << "\n255\n";
00142 strm.write(reinterpret_cast<const char*>(image.getArrayPtr()),
00143 3 * image.getSize());
00144 }
00145
00146
00147 void PnmWriter::writeGray(const Image<byte>& image,
00148 std::ostream& strm)
00149 {
00150 strm << "P5\n" << image.getWidth() << ' ' << image.getHeight()
00151 << "\n255\n";
00152 strm.write(reinterpret_cast<const char*>(image.getArrayPtr()),
00153 image.getSize());
00154 }
00155
00156
00157 void PnmWriter::writeRawBW(const Image<byte>& image, const byte thresh,
00158 std::ostream& strm)
00159 {
00160 strm << "P4\n" << image.getWidth() << ' ' << image.getHeight() << '\n';
00161
00162 Image<byte>::const_iterator itr = image.begin(), stop = image.end();
00163
00164 int c = 0;
00165 int pos = 7;
00166
00167 while (itr != stop)
00168 {
00169 if (*itr++ >= thresh)
00170 { }
00171 else
00172 c |= (1 << pos);
00173
00174 if (pos == 0 || (itr == stop))
00175 {
00176 strm.put(byte(c));
00177 c = 0;
00178 pos = 7;
00179 }
00180 else
00181 --pos;
00182 }
00183 }
00184
00185
00186 void PnmWriter::writeAsciiBW(const Image<byte>& image, const byte thresh,
00187 std::ostream& strm)
00188 {
00189 strm << "P1\n" << image.getWidth() << ' ' << image.getHeight() << '\n';
00190
00191 Image<byte>::const_iterator itr = image.begin();
00192
00193 for (int j = 0; j < image.getHeight(); ++j)
00194 {
00195 for (int i = 0; i < image.getWidth(); ++i)
00196 {
00197 if (*itr++ >= thresh)
00198 strm << "0 ";
00199 else
00200 strm << "1 ";
00201 }
00202 strm << '\n';
00203 }
00204 }
00205
00206
00207 void PnmWriter::writeRGB(const Image<PixRGB<byte> >& image,
00208 const std::string& fname)
00209 {
00210 std::ofstream ofs(fname.c_str(), std::ios::binary);
00211 if (!ofs.is_open())
00212 LFATAL("Couldn't open PNM file '%s' for writing.", fname.c_str());
00213
00214 PnmWriter::writeRGB(image, ofs);
00215
00216 ofs.close();
00217 if (ofs.fail())
00218 LFATAL("Output stream failure while writing '%s'.", fname.c_str());
00219 }
00220
00221
00222 void PnmWriter::writeGray(const Image<byte>& image,
00223 const std::string& fname)
00224 {
00225 std::ofstream ofs(fname.c_str(), std::ios::binary);
00226 if (!ofs.is_open())
00227 LFATAL("Couldn't open PNM file '%s' for writing.", fname.c_str());
00228
00229 PnmWriter::writeGray(image, ofs);
00230
00231 if (ofs.fail())
00232 LFATAL("Output stream failure while writing '%s'.", fname.c_str());
00233 }
00234
00235
00236 void PnmWriter::writeRawBW(const Image<byte>& image, const byte thresh,
00237 const std::string& fname)
00238 {
00239 std::ofstream ofs(fname.c_str(), std::ios::binary);
00240 if (!ofs.is_open())
00241 LFATAL("Couldn't open PNM file '%s' for writing.", fname.c_str());
00242
00243 PnmWriter::writeRawBW(image, thresh, ofs);
00244
00245 if (ofs.fail())
00246 LFATAL("Output stream failure while writing '%s'.", fname.c_str());
00247 }
00248
00249
00250 void PnmWriter::writeAsciiBW(const Image<byte>& image, const byte thresh,
00251 const std::string& fname)
00252 {
00253 std::ofstream ofs(fname.c_str(), std::ios::binary);
00254 if (!ofs.is_open())
00255 LFATAL("Couldn't open PNM file '%s' for writing.", fname.c_str());
00256
00257 PnmWriter::writeAsciiBW(image, thresh, ofs);
00258
00259 if (ofs.fail())
00260 LFATAL("Output stream failure while writing '%s'.", fname.c_str());
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270 #endif // RASTER_PNMWRITER_C_DEFINED