CVD 0.8
|
00001 /* 00002 This file is part of the CVD Library. 00003 00004 Copyright (C) 2005 The Authors 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with this library; if not, write to the Free Software 00018 Foundation, Inc., 00019 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 #ifndef CVD_IMAGE_CONVERT_H 00022 #define CVD_IMAGE_CONVERT_H 00023 00024 #include <cvd/config.h> 00025 #include <cvd/internal/convert_pixel_types.h> 00026 #include <cvd/internal/rgb_components.h> 00027 #include <cvd/image.h> 00028 00029 namespace CVD 00030 { 00031 00032 // The most general case: one row at a time 00033 00034 template <class From, class To, class Conv=typename Pixel::DefaultConversion<From,To>::type, int both_pod=Internal::is_POD<From>::is_pod && Internal::is_POD<To>::is_pod> struct ConvertImage { 00035 static void convert(const SubImage<From>& from, SubImage<To>& to) { 00036 for (int r=0; r<from.size().y; r++) 00037 Pixel::ConvertPixels<From,To,Conv>::convert(from[r], to[r], from.size().x); 00038 }; 00039 }; 00040 00041 // The blat case: memcpy all data at once 00042 template <class T> struct ConvertImage<T,T,Pixel::GenericConversion<T,T>,1> { 00043 static void convert(const SubImage<T>& from, SubImage<T>& to) { 00044 memcpy(to.data(), from.data(), from.totalsize() * sizeof(T)); 00045 }; 00046 }; 00047 00048 template <> struct ConvertImage<Rgb<byte>, byte, Pixel::CIE<Rgb<byte>, byte>, 1> { 00049 static void convert(const SubImage<Rgb<byte> >& from, SubImage<byte>& to); 00050 }; 00051 00052 template<class Conv, class C, class D> void convert_image(const SubImage<C>& from, SubImage<D>& to) 00053 { 00054 if (from.size() != to.size()) 00055 throw Exceptions::Image::IncompatibleImageSizes(__FUNCTION__); 00056 ConvertImage<C,D,Conv>::convert(from, to); 00057 } 00058 00059 template<template <class From, class To> class Conv, class C, class D> void convert_image(const SubImage<C>& from, SubImage<D>& to) 00060 { 00061 if (from.size() != to.size()) 00062 throw Exceptions::Image::IncompatibleImageSizes(__FUNCTION__); 00063 ConvertImage<C,D,Conv<C,D> >::convert(from, to); 00064 } 00065 00066 template<class C, class D> void convert_image(const SubImage<C>& from, SubImage<D>& to) 00067 { 00068 if (from.size() != to.size()) 00069 throw Exceptions::Image::IncompatibleImageSizes(__FUNCTION__); 00070 ConvertImage<C,D>::convert(from, to); 00071 } 00072 00073 template<class C, class D> void convert_image(const BasicImage<C>& from, BasicImage<D>& to) 00074 { 00075 if (from.size() != to.size()) 00076 throw Exceptions::Image::IncompatibleImageSizes(__FUNCTION__); 00077 ConvertImage<C,D>::convert(from, to); 00078 } 00079 00086 template<class D, class Conv, class C> Image<D> convert_image(const SubImage<C>& from) 00087 { 00088 Image<D> to(from.size()); 00089 convert_image<Conv>(from, to); 00090 return to; 00091 } 00092 00093 template<class D, template <class From, class To> class Conv, class C> Image<D> convert_image(const SubImage<C>& from) 00094 { 00095 Image<D> to(from.size()); 00096 convert_image<Conv>(from, to); 00097 return to; 00098 } 00099 00105 template<class D, class C> Image<D> convert_image(const SubImage<C>& from) 00106 { 00107 Image<D> to(from.size()); 00108 convert_image(from, to); 00109 return to; 00110 } 00111 00117 template<class D, class C> Image<D> convert_image(const BasicImage<C>& from) 00118 { 00119 Image<D> to(from.size()); 00120 convert_image(from, to); 00121 return to; 00122 } 00123 00124 // Function name changed from 'convert_image' to prevent compile-time 00125 // error arising from the clash with a function of same name declared above. 00126 00133 template<class D1, class D2, class C> std::pair<Image<D1>, Image<D2> > convert_image_pair(const BasicImage<C>& from) 00134 { 00135 std::pair<Image<D1>, Image<D2> > to(Image<D1>(from.size()), Image<D2>(from.size())); 00136 convert_image(from, to.first); 00137 convert_image(from, to.second); 00138 return to; 00139 } 00140 00141 00142 #ifndef DOXYGEN_IGNORE_INTERNAL 00143 namespace Internal 00144 { 00145 template<class C> class ImageConverter{}; 00146 template<class C> struct ImagePromise<ImageConverter<C> > 00147 { 00148 ImagePromise(const BasicImage<C>& im) 00149 :i(im) 00150 {} 00151 00152 const BasicImage<C>& i; 00153 template<class D> void execute(Image<D>& j) 00154 { 00155 j.resize(i.size()); 00156 convert_image(i, j); 00157 } 00158 }; 00159 }; 00160 template<class C> Internal::ImagePromise<Internal::ImageConverter<C> > convert_image(const BasicImage<C>& c) 00161 { 00162 return Internal::ImagePromise<Internal::ImageConverter<C> >(c); 00163 } 00164 #else 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 template<class D> Image<D> convert_image(const BasicImage<C>& from); 00181 00182 #endif 00183 00184 00185 template<class In, class Out> struct IsConvertible 00186 { 00187 static const bool is=Pixel::DefaultConvertible<In>::is & Pixel::DefaultConvertible<Out>::is; 00188 }; 00189 00193 template<class In, class Out> struct PixelByPixelConvertible 00194 { 00195 static const bool is=Pixel::DefaultConvertible<In>::is & Pixel::DefaultConvertible<Out>::is; 00196 }; 00197 00199 template<class InOut> struct PixelByPixelConvertible<InOut, InOut> 00200 { 00201 static const bool is=1; 00202 }; 00203 00204 } 00205 00206 #endif