00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CVD_IMAGE_IO_H
00022 #define CVD_IMAGE_IO_H
00023
00024 #include <cvd/config.h>
00025
00026 #include <cvd/exceptions.h>
00027 #include <cvd/image_convert.h>
00028 #include <cvd/internal/load_and_save.h>
00029 #include <cvd/internal/name_builtin_types.h>
00030 #include <cvd/internal/name_CVD_rgb_types.h>
00031 #include <errno.h>
00032 #include <memory>
00033 #include <string>
00034 #include <fstream>
00035 #include <cctype>
00036
00037 #include <cvd/internal/io/pnm_grok.h>
00038 #include <cvd/internal/io/save_postscript.h>
00039 #include <cvd/internal/io/bmp.h>
00040 #include <cvd/internal/io/fits.h>
00041 #include <cvd/internal/io/text.h>
00042
00043
00044 #ifdef CVD_HAVE_JPEG
00045 #include <cvd/internal/io/jpeg.h>
00046 #endif
00047
00048 #ifdef CVD_HAVE_TIFF
00049 #include <cvd/internal/io/tiff.h>
00050 #endif
00051
00052
00053 #ifdef CVD_HAVE_PNG
00054 #include <cvd/internal/io/png.h>
00055 #endif
00056
00057 namespace CVD
00058 {
00059
00060
00061
00063
00064
00065
00066
00067 #ifndef DOXYGEN_IGNORE_INTERNAL
00068 namespace ImageType
00069 {
00070 enum ImageType
00071 {
00072 Automatic= -2,
00073 Unknown = -1,
00074 PNM=0,
00075 PS=1,
00076 EPS=2,
00077 BMP=3,
00078 #ifdef CVD_HAVE_JPEG
00079 JPEG=4,
00080 #endif
00081 #ifdef CVD_HAVE_PNG
00082 PNG=5,
00083 #endif
00084 #ifdef CVD_HAVE_TIFF
00085 TIFF=6,
00086 #endif
00087 TXT=7,
00088 TEXT=7,
00089 };
00090 }
00091
00092 namespace Internal
00093 {
00094 class ImageLoaderIstream{};
00095 template<> struct ImagePromise<ImageLoaderIstream>
00096 {
00097 ImagePromise(std::istream& is)
00098 :i(is){}
00099
00100 std::istream& i;
00101 template<class C> void execute(Image<C>& im)
00102 {
00103 img_load(im, i);
00104 }
00105 };
00106
00107 class ImageLoaderString{};
00108 template<> struct ImagePromise<ImageLoaderString>
00109 {
00110 ImagePromise(const std::string& ss)
00111 :s(ss){}
00112
00113 const std::string& s;
00114 template<class C> void execute(Image<C>& im)
00115 {
00116 img_load(im, s);
00117 }
00118 };
00119 };
00120 #endif
00121
00122 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00123
00124
00126 namespace ImageType
00127 {
00129 enum ImageType
00130 {
00132 Automatic,
00134 Unknown,
00137 PNM,
00140 JPEG,
00142 BMP,
00145 PNG,
00149 TIFF,
00157 PS,
00159 EPS,
00163 TXT,
00164 };
00165 }
00166 #endif
00167
00168 #ifndef DOXYGEN_IGNORE_INTERNAL
00169
00170 Internal::ImagePromise<Internal::ImageLoaderIstream> img_load(std::istream& i);
00171 Internal::ImagePromise<Internal::ImageLoaderString> img_load(const std::string &s);
00172 #endif
00173
00174 #if DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00175
00184 template<class C> Image<C> img_load(std::istream& i);
00185
00194 template<class C> Image<C> img_load(std::string& i);
00195
00196
00197
00198 #endif
00199
00200
00208 template<class I> void img_load(Image<I>& im, std::istream& i)
00209 {
00210 if(!i.good())
00211 {
00212
00213
00214 std::ifstream* fs;
00215 if((fs = dynamic_cast<std::ifstream*>(&i)) && !fs->is_open())
00216 throw Exceptions::Image_IO::IfstreamNotOpen();
00217 else
00218 throw Exceptions::Image_IO::EofBeforeImage();
00219 }
00220 unsigned char c = i.peek();
00221
00222 if(!i.good())
00223 throw Exceptions::Image_IO::EofBeforeImage();
00224
00225 if(c == 'P')
00226 PNM::readPNM(im, i);
00227 #ifdef CVD_HAVE_JPEG
00228 else if(c == 0xff)
00229 CVD::Internal::readImage<I, JPEG::reader>(im, i);
00230 #endif
00231 #ifdef CVD_HAVE_TIFF
00232 else if(c == 'I' || c == 'M')
00233 CVD::Internal::readImage<I, TIFF::tiff_reader>(im, i);
00234 #endif
00235 #ifdef CVD_HAVE_PNG
00236 else if(c == 0x89)
00237 CVD::Internal::readImage<I, PNG::png_reader>(im, i);
00238 #endif
00239 else if(c == 'B')
00240 BMP::readBMP(im, i);
00241 else if(c == 'S')
00242 CVD::Internal::readImage<I, FITS::reader>(im, i);
00243 else if(c == ' ' || c == '\t' || isdigit(c) || c == '-' || c == '+')
00244 CVD::Internal::readImage<I, TEXT::reader>(im, i);
00245 else
00246 throw Exceptions::Image_IO::UnsupportedImageType();
00247 }
00248
00249
00250 template<class I> void img_load(Image<I> &im, const std::string &s)
00251 {
00252 std::ifstream i(s.c_str(), std::ios::in|std::ios::binary);
00253
00254 if(!i.good())
00255 throw Exceptions::Image_IO::OpenError(s, "for reading", errno);
00256 img_load(im, i);
00257 }
00258
00259
00261
00262
00263
00264
00265
00268 ImageType::ImageType string_to_image_type(const std::string& name);
00269
00270
00278 template<class PixelType>
00279 void img_save(const BasicImage<PixelType>& im, std::ostream& o, ImageType::ImageType t)
00280 {
00281 switch (t) {
00282 default:
00283 case ImageType::PNM:
00284 case ImageType::Automatic:
00285 case ImageType::Unknown:
00286 Internal::writeImage<PixelType, PNM::pnm_writer>(im, o); break;
00287 #ifdef CVD_HAVE_JPEG
00288 case ImageType::JPEG: Internal::writeImage<PixelType, JPEG::writer>(im,o); break;
00289 #endif
00290 #ifdef CVD_HAVE_PNG
00291 case ImageType::PNG: Internal::writeImage<PixelType, PNG::png_writer>(im,o); break;
00292 #endif
00293 #ifdef CVD_HAVE_TIFF
00294 case ImageType::TIFF: Internal::writeImage<PixelType, TIFF::tiff_writer>(im,o); break;
00295 #endif
00296 case ImageType::BMP: BMP::writeBMP(im, o); break;
00297 case ImageType::TXT: Internal::writeImage<PixelType, TEXT::writer>(im, o); break;
00298 case ImageType::PS: Internal::writeImage<PixelType, PS::writer>(im, o); break;
00299 case ImageType::EPS: Internal::writeImage<PixelType, PS::eps_writer>(im, o); break;
00300 }
00301 }
00302
00303 template<class PixelType> void img_save(const BasicImage<PixelType>& im, const std::string& name, ImageType::ImageType t, ImageType::ImageType d = ImageType::PNM)
00304 {
00305 std::ofstream out(name.c_str(), std::ios::out|std::ios::binary);
00306 if(!out.good())
00307 throw Exceptions::Image_IO::OpenError(name, "for writing", errno);
00308
00309 if(t == ImageType::Automatic)
00310 {
00311 t = string_to_image_type(name);
00312 if(t == ImageType::Unknown)
00313 t = d;
00314 }
00315
00316 img_save(im, out, t);
00317 }
00318
00319 template<class PixelType> void img_save(const BasicImage<PixelType>& im, const std::string& name)
00320 {
00321 img_save(im, name, ImageType::Automatic);
00322 }
00323
00325
00326
00327
00328
00335 template<class PixelType> void pnm_save(const BasicImage<PixelType>& im, std::ostream& o)
00336 {
00337 img_save(im, o, ImageType::PNM);
00338 }
00339
00356 template<class PixelType> void pnm_load(Image<PixelType>& im, std::istream& i)
00357 {
00358 img_load(im, i);
00359 }
00360
00362
00363
00364
00365
00369 void output_eps_footer(std::ostream& o);
00370
00378 void output_eps_header(std::ostream& o, int xs, int ys);
00379
00380
00387 void output_eps_header(std::ostream & o, const ImageRef& s);
00388
00395 template<class PixelType> void output_eps_header(std::ostream& o, const BasicImage<PixelType>& im)
00396 {
00397 output_eps_header(o, im.size());
00398 }
00399
00400
00401
00402 }
00403
00404 #endif