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 #include <cvd/internal/io/cvdimage.h>
00043
00044
00045 #ifdef CVD_HAVE_JPEG
00046 #include <cvd/internal/io/jpeg.h>
00047 #endif
00048
00049 #ifdef CVD_HAVE_TIFF
00050 #include <cvd/internal/io/tiff.h>
00051 #endif
00052
00053
00054 #ifdef CVD_HAVE_PNG
00055 #include <cvd/internal/io/png.h>
00056 #endif
00057
00058 namespace CVD
00059 {
00060
00061
00062
00064
00065
00066
00067
00068 #ifndef DOXYGEN_IGNORE_INTERNAL
00069 namespace ImageType
00070 {
00071 enum ImageType
00072 {
00073 Automatic= -2,
00074 Unknown = -1,
00075 PNM=0,
00076 PS=1,
00077 EPS=2,
00078 BMP=3,
00079 #ifdef CVD_HAVE_JPEG
00080 JPEG=4,
00081 #endif
00082 #ifdef CVD_HAVE_PNG
00083 PNG=5,
00084 #endif
00085 #ifdef CVD_HAVE_TIFF
00086 TIFF=6,
00087 #endif
00088 TXT=7,
00089 TEXT=7,
00090 FITS=8,
00091 CVD=9,
00092 };
00093 }
00094
00095 namespace Internal
00096 {
00097 class ImageLoaderIstream{};
00098 template<> struct ImagePromise<ImageLoaderIstream>
00099 {
00100 ImagePromise(std::istream& is)
00101 :i(is){}
00102
00103 std::istream& i;
00104 template<class C> void execute(Image<C>& im)
00105 {
00106 img_load(im, i);
00107 }
00108 };
00109
00110 class ImageLoaderString{};
00111 template<> struct ImagePromise<ImageLoaderString>
00112 {
00113 ImagePromise(const std::string& ss)
00114 :s(ss){}
00115
00116 const std::string& s;
00117 template<class C> void execute(Image<C>& im)
00118 {
00119 img_load(im, s);
00120 }
00121 };
00122 };
00123 #endif
00124
00125 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00126
00127
00129 namespace ImageType
00130 {
00132 enum ImageType
00133 {
00135 Automatic,
00137 Unknown,
00140 PNM,
00143 JPEG,
00145 BMP,
00148 PNG,
00152 TIFF,
00160 PS,
00162 EPS,
00166 TXT,
00171 CVD,
00174 FITS,
00175 };
00176 }
00177 #endif
00178
00179 #ifndef DOXYGEN_IGNORE_INTERNAL
00180
00181 Internal::ImagePromise<Internal::ImageLoaderIstream> img_load(std::istream& i);
00182 Internal::ImagePromise<Internal::ImageLoaderString> img_load(const std::string &s);
00183 #endif
00184
00185 #if DOXYGEN_INCLUDE_ONLY_FOR_DOCS
00186
00195 template<class C> Image<C> img_load(std::istream& i);
00196
00205 template<class C> Image<C> img_load(std::string& i);
00206
00207
00208
00209 #endif
00210
00211
00219 template<class I> void img_load(Image<I>& im, std::istream& i)
00220 {
00221 if(!i.good())
00222 {
00223
00224
00225 std::ifstream* fs;
00226 if((fs = dynamic_cast<std::ifstream*>(&i)) && !fs->is_open())
00227 throw Exceptions::Image_IO::IfstreamNotOpen();
00228 else
00229 throw Exceptions::Image_IO::EofBeforeImage();
00230 }
00231 unsigned char c = i.peek();
00232
00233 if(!i.good())
00234 throw Exceptions::Image_IO::EofBeforeImage();
00235
00236 if(c == 'P')
00237 PNM::readPNM(im, i);
00238 #ifdef CVD_HAVE_JPEG
00239 else if(c == 0xff)
00240 CVD::Internal::readImage<I, JPEG::reader>(im, i);
00241 #endif
00242 #ifdef CVD_HAVE_TIFF
00243 else if(c == 'I' || c == 'M')
00244 CVD::Internal::readImage<I, TIFF::tiff_reader>(im, i);
00245 #endif
00246 #ifdef CVD_HAVE_PNG
00247 else if(c == 0x89)
00248 CVD::Internal::readImage<I, PNG::png_reader>(im, i);
00249 #endif
00250 else if(c == 'B')
00251 BMP::readBMP(im, i);
00252 else if(c == 'S')
00253 CVD::Internal::readImage<I, FITS::reader>(im, i);
00254 else if(c == 'C')
00255 CVD::Internal::readImage<I, CVDimage::reader>(im, i);
00256 else if(c == ' ' || c == '\t' || isdigit(c) || c == '-' || c == '+')
00257 CVD::Internal::readImage<I, TEXT::reader>(im, i);
00258 else
00259 throw Exceptions::Image_IO::UnsupportedImageType();
00260 }
00261
00262
00263 template<class I> void img_load(Image<I> &im, const std::string &s)
00264 {
00265 std::ifstream i(s.c_str(), std::ios::in|std::ios::binary);
00266
00267 if(!i.good())
00268 throw Exceptions::Image_IO::OpenError(s, "for reading", errno);
00269 img_load(im, i);
00270 }
00271
00272
00274
00275
00276
00277
00278
00281 ImageType::ImageType string_to_image_type(const std::string& name);
00282
00283
00291 template<class PixelType>
00292 void img_save(const BasicImage<PixelType>& im, std::ostream& o, ImageType::ImageType t, const std::map<std::string, Parameter<> >& p = std::map<std::string, Parameter<> >())
00293 {
00294 switch (t) {
00295 default:
00296 case ImageType::PNM:
00297 case ImageType::Automatic:
00298 case ImageType::Unknown:
00299 Internal::writeImage<PixelType, PNM::pnm_writer>(im, o, p); break;
00300 #ifdef CVD_HAVE_JPEG
00301 case ImageType::JPEG: Internal::writeImage<PixelType, JPEG::writer>(im,o, p); break;
00302 #endif
00303 #ifdef CVD_HAVE_PNG
00304 case ImageType::PNG: Internal::writeImage<PixelType, PNG::png_writer>(im,o, p); break;
00305 #endif
00306 #ifdef CVD_HAVE_TIFF
00307 case ImageType::TIFF: Internal::writeImage<PixelType, TIFF::tiff_writer>(im,o, p); break;
00308 #endif
00309 case ImageType::FITS: Internal::writeImage<PixelType, FITS::writer>(im,o, p); break;
00310 case ImageType::BMP: BMP::writeBMP(im, o); break;
00311 case ImageType::TXT: Internal::writeImage<PixelType, TEXT::writer>(im, o, p); break;
00312 case ImageType::PS: Internal::writeImage<PixelType, PS::writer>(im, o, p); break;
00313 case ImageType::EPS: Internal::writeImage<PixelType, PS::eps_writer>(im, o, p); break;
00314 case ImageType::CVD: Internal::writeImage<PixelType, CVDimage::writer>(im,o, p); break;
00315 }
00316 }
00317
00318 template<class PixelType> void img_save(const BasicImage<PixelType>& im, const std::string& name, ImageType::ImageType t, ImageType::ImageType d = ImageType::PNM, const std::map<std::string, Parameter<> >& p = std::map<std::string, Parameter<> >())
00319 {
00320 std::ofstream out(name.c_str(), std::ios::out|std::ios::binary);
00321 if(!out.good())
00322 throw Exceptions::Image_IO::OpenError(name, "for writing", errno);
00323
00324 if(t == ImageType::Automatic)
00325 {
00326 t = string_to_image_type(name);
00327 if(t == ImageType::Unknown)
00328 t = d;
00329 }
00330
00331 img_save(im, out, t, p);
00332 }
00333
00334 template<class PixelType> void img_save(const BasicImage<PixelType>& im, const std::string& name, const std::map<std::string, Parameter<> >& p = std::map<std::string, Parameter<> >())
00335 {
00336 img_save(im, name, ImageType::Automatic, ImageType::PNM, p);
00337 }
00338
00340
00341
00342
00343
00350 template<class PixelType> void pnm_save(const BasicImage<PixelType>& im, std::ostream& o)
00351 {
00352 img_save(im, o, ImageType::PNM);
00353 }
00354
00371 template<class PixelType> void pnm_load(Image<PixelType>& im, std::istream& i)
00372 {
00373 img_load(im, i);
00374 }
00375
00377
00378
00379
00380
00384 void output_eps_footer(std::ostream& o);
00385
00393 void output_eps_header(std::ostream& o, int xs, int ys);
00394
00395
00402 void output_eps_header(std::ostream & o, const ImageRef& s);
00403
00410 template<class PixelType> void output_eps_header(std::ostream& o, const BasicImage<PixelType>& im)
00411 {
00412 output_eps_header(o, im.size());
00413 }
00414
00415
00416
00417 }
00418
00419 #endif