00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CVD_LOAD_AND_SAVE_H
00022 #define CVD_LOAD_AND_SAVE_H
00023
00024 #include <iostream>
00025 #include <string>
00026 #include <typeinfo>
00027 #include <map>
00028 #include <memory>
00029 #include <cvd/exceptions.h>
00030 #include <cvd/image_convert.h>
00031 #include <cvd/colourspace_convert.h>
00032 #include <cvd/internal/convert_pixel_types.h>
00033 #include <cvd/internal/name_CVD_rgb_types.h>
00034 #include <cvd/internal/io/parameter.h>
00035
00036 namespace CVD {
00037
00038 namespace Exceptions
00039 {
00042 namespace Image_IO
00043 {
00046 struct All: public CVD::Exceptions::All
00047 {};
00048
00051 struct UnsupportedImageType: public All
00052 {
00053 UnsupportedImageType();
00054 };
00055
00058 struct EofBeforeImage: public All
00059 {
00060 EofBeforeImage();
00061 };
00062
00065 struct IfstreamNotOpen: public All
00066 {
00067 IfstreamNotOpen();
00068 };
00069
00072 struct MalformedImage: public All
00073 {
00074 MalformedImage(const std::string &);
00075 };
00076
00079 struct ImageSizeMismatch: public All
00080 {
00081 ImageSizeMismatch(const ImageRef& src, const ImageRef& dest);
00082 };
00083
00086 struct WriteError: public All
00087 {
00088 WriteError(const std::string& err);
00089 };
00090
00093 struct UnseekableIstream: public All
00094 {
00095 UnseekableIstream(const std::string& type);
00096 };
00097
00100 struct ReadTypeMismatch: public All
00101 {
00102 ReadTypeMismatch(bool read8);
00103 ReadTypeMismatch(const std::string& available, const std::string& requested);
00104 };
00105
00108 struct WriteTypeMismatch: public All
00109 {
00110 WriteTypeMismatch(const std::string& available, const std::string& requested);
00111 };
00112
00115 struct InternalLibraryError: public All
00116 {
00117 InternalLibraryError(const std::string& lib, const std::string err);
00118 };
00119
00122 struct UnsupportedImageSubType: public All
00123 {
00124 UnsupportedImageSubType(const std::string &, const std::string&);
00125 };
00126
00129 struct OpenError: public All
00130 {
00131 OpenError(const std::string&, const std::string&, int);
00132 };
00133
00134
00135 }
00136 }
00137
00138 namespace Internal
00139 {
00140 template<class C, int i> struct save_default_
00141 {
00142 static const bool use_16bit=1;
00143 };
00144
00145 template<class C> struct save_default_<C,1>
00146 {
00147 static const bool use_16bit=(CVD::Pixel::traits<typename CVD::Pixel::Component<C>::type>::bits_used) > 8;
00148 };
00149
00150 template<class C> struct save_default
00151 {
00152 static const bool use_16bit = save_default_<C, CVD::Pixel::traits<typename CVD::Pixel::Component<C>::type>::integral>::use_16bit;
00153 };
00154
00155
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 struct Head{};
00170 template<class A, class B> struct TypeList
00171 {
00172 typedef A Type;
00173 typedef B Next;
00174 };
00175
00176
00177
00179
00180
00181
00182
00183 template<class PixelType, class DiskPixelType, class ImageLoader> struct read_and_maybe_process
00184 {
00185 static void exec(SubImage<PixelType>& im, ImageLoader& r)
00186 {
00187 Image<DiskPixelType> rowbuf(ImageRef(r.size().x, 1));
00188
00189 for(int row = 0; row < r.size().y; row++)
00190 {
00191 r.get_raw_pixel_line(rowbuf.data());
00192 Pixel::ConvertPixels<DiskPixelType, PixelType>::convert(rowbuf.data(), im[row], r.size().x);
00193 }
00194 }
00195 };
00196
00197 template<class PixelType, class ImageLoader> struct read_and_maybe_process<PixelType, PixelType, ImageLoader>
00198 {
00199 static void exec(SubImage<PixelType>& im, ImageLoader& r)
00200 {
00201 for(int row = 0; row < r.size().y; row++)
00202 r.get_raw_pixel_line(im[row]);
00203 }
00204 };
00205
00206 template<class PixelType, class DiskPixelType, class ImageLoader> struct read_and_then_process
00207 {
00208 static void exec(BasicImage<PixelType>& im, ImageLoader& r)
00209 {
00210 Image<DiskPixelType> imgbuf(r.size());
00211
00212 for(int row = 0; row < r.size().y; row++)
00213 {
00214 r.get_raw_pixel_line(imgbuf[row]);
00215 }
00216
00217 convert_image(imgbuf, im);
00218 }
00219 };
00220
00221
00223
00224
00225
00226 template<class PixelType, class ImageLoader, class List > struct Reader
00227 {
00228 static void read(BasicImage<PixelType>& im, ImageLoader& r)
00229 {
00230 if(r.datatype() == PNM::type_name<typename List::Type>::name())
00231 {
00232
00233 if (PixelByPixelConvertible<typename List::Type, PixelType>::is)
00234 read_and_maybe_process<PixelType, typename List::Type, ImageLoader>::exec(im, r);
00235 else if (IsConvertible<typename List::Type, PixelType>::is)
00236 read_and_then_process<PixelType, typename List::Type, ImageLoader>::exec(im, r);
00237 else
00238 throw CVD::Exceptions::Image_IO::ReadTypeMismatch(r.datatype(), PNM::type_name<PixelType>::name());
00239 }
00240 else
00241 Reader<PixelType, ImageLoader, typename List::Next>::read(im, r);
00242 }
00243 };
00244
00245 template<class PixelType, class ImageLoader> struct Reader<PixelType, ImageLoader, Head>
00246 {
00247 static void read(BasicImage<PixelType>&, ImageLoader& r)
00248 {
00249 throw Exceptions::Image_IO::UnsupportedImageSubType(r.name(), r.datatype() + " not yet supported");
00250 }
00251 };
00252
00253
00255
00256
00257
00258
00259 template<class T, class ImageLoader> void readImage(BasicImage<T>& im, ImageLoader& r)
00260 {
00261 Reader<T, ImageLoader, typename ImageLoader::Types>::read(im, r);
00262 }
00263
00264 template <class T, class ImageLoader> void readImage(BasicImage<T>& im, std::istream& in)
00265 {
00266 ImageLoader loader(in);
00267 ImageRef size = loader.size();
00268 if (im.size() != size)
00269 throw Exceptions::Image_IO::ImageSizeMismatch(size, im.size());
00270
00271 readImage(im, loader);
00272 }
00273
00274 template <class T, class ImageLoader> void readImage(Image<T>& im, std::istream& in)
00275 {
00276 ImageLoader loader(in);
00277 im.resize(loader.size());
00278 readImage(im, loader);
00279 }
00280
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00299
00300
00301
00302 template<class Pixel, class ImageWriter, class OutgoingPixel> struct maybe_process_and_write
00303 {
00304 static void write(std::ostream& os, const SubImage<Pixel>& im, const std::map<std::string, Parameter<> >& p)
00305 {
00306 ImageWriter w(os, im.size(), CVD::PNM::type_name<OutgoingPixel>::name(), p);
00307 Image<OutgoingPixel> row(ImageRef(im.size().x, 1));
00308
00309 for(int r=0; r < im.size().y; r++)
00310 {
00311 CVD::Pixel::ConvertPixels<Pixel, OutgoingPixel>::convert(im[r], row.data(), im.size().x);
00312 w.write_raw_pixel_line(row.data());
00313 }
00314 }
00315 };
00316
00317 template<class Pixel, class ImageWriter> struct maybe_process_and_write<Pixel, ImageWriter, Pixel>
00318 {
00319 static void write(std::ostream& os, const SubImage<Pixel>& im, const std::map<std::string, Parameter<> >& p)
00320 {
00321 ImageWriter w(os, im.size(), CVD::PNM::type_name<Pixel>::name(), p);
00322 for(int r=0; r < im.size().y; r++)
00323 w.write_raw_pixel_line(im[r]);
00324 }
00325 };
00326
00327 template<class Pixel, class Writer> void writeImage(const SubImage<Pixel>& im, std::ostream& o, const std::map<std::string, Parameter<> >& p)
00328 {
00329 maybe_process_and_write<Pixel, Writer, typename Writer::template Outgoing<Pixel>::type>::write(o, im, p);
00330 }
00331
00332
00333 }
00334
00335
00336 }
00337
00338 #endif