image.hppGo to the documentation of this file.00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 00004 Use, modification and distribution are subject to the Boost Software License, 00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00006 http://www.boost.org/LICENSE_1_0.txt). 00007 00008 See http://opensource.adobe.com/gil for most recent version including documentation. 00009 */ 00010 /*************************************************************************************************/ 00011 00012 #ifndef GIL_IMAGE_H 00013 #define GIL_IMAGE_H 00014 00023 00024 #include <cstddef> 00025 #include <memory> 00026 #include "gil_config.hpp" 00027 #include "image_view.hpp" 00028 #include "metafunctions.hpp" 00029 #include "algorithm.hpp" 00030 00031 namespace boost { namespace gil { 00032 00033 #ifdef _MSC_VER 00034 #pragma warning(push) 00035 #pragma warning(disable : 4244) // conversion from 'gil::image<V,Alloc>::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same) 00036 #endif 00037 00049 00050 template <typename Pixel, bool IsPlanar, typename Alloc=std::allocator<unsigned char> > 00051 class image { 00052 public: 00053 typedef typename Alloc::template rebind<unsigned char>::other allocator_type; 00054 typedef typename view_type_from_pixel<Pixel, IsPlanar>::type view_t; 00055 typedef typename view_t::const_t const_view_t; 00056 typedef typename view_t::point_t point_t; 00057 typedef typename view_t::coord_t coord_t; 00058 typedef typename view_t::value_type value_type; 00059 typedef coord_t x_coord_t; 00060 typedef coord_t y_coord_t; 00061 00062 const point_t& dimensions() const { return _view.dimensions(); } 00063 x_coord_t width() const { return _view.width(); } 00064 y_coord_t height() const { return _view.height(); } 00065 00066 explicit image(std::size_t alignment=1, 00067 const Alloc alloc_in = Alloc()) : 00068 _memory(0), _align(alignment), _alloc(alloc_in) {} 00069 00070 // Create with dimensions and optional initial value and alignment 00071 image(const point_t& dimensions, 00072 std::size_t alignment=1) : _memory(0), _align(alignment) { 00073 allocate_and_default_construct(dimensions); 00074 } 00075 image(x_coord_t width, y_coord_t height, 00076 std::size_t alignment=1) : _memory(0), _align(alignment) { 00077 allocate_and_default_construct(point_t(width,height)); 00078 } 00079 image(const point_t& dimensions, 00080 const Pixel& p_in, 00081 std::size_t alignment, 00082 const Alloc alloc_in = Alloc()) : 00083 _memory(0), _align(alignment), _alloc(alloc_in) { 00084 allocate_and_fill(dimensions, p_in); 00085 } 00086 image(x_coord_t width, y_coord_t height, 00087 const Pixel& p_in, 00088 std::size_t alignment, 00089 const Alloc alloc_in = Alloc()) : 00090 _memory(0), _align(alignment), _alloc(alloc_in) { 00091 allocate_and_fill(point_t(width,height),p_in); 00092 } 00093 00094 image(const image& img) : 00095 _memory(0), _align(img._align), _alloc(img._alloc) { 00096 allocate_and_copy(img.dimensions(),img._view); 00097 } 00098 00099 template <typename P2, bool IP2, typename Alloc2> 00100 image(const image<P2,IP2,Alloc2>& img) : 00101 _memory(0), _align(img._align), _alloc(img._alloc) { 00102 allocate_and_copy(img.dimensions(),img._view); 00103 } 00104 image& operator=(const image& img) { 00105 if (dimensions() == img.dimensions()) 00106 copy_pixels(img._view,_view); 00107 else { 00108 image tmp(img); 00109 swap(tmp); 00110 } 00111 return *this; 00112 } 00113 00114 template <typename Img> 00115 image& operator=(const Img& img) { 00116 if (dimensions() == img.dimensions()) 00117 copy_pixels(img._view,_view); 00118 else { 00119 image tmp(img); 00120 swap(tmp); 00121 } 00122 return *this; 00123 } 00124 00125 ~image() { 00126 destruct_pixels(_view); 00127 deallocate(_view.dimensions()); 00128 } 00129 00130 Alloc& allocator() { return _alloc; } 00131 Alloc const& allocator() const { return _alloc; } 00132 00133 void swap(image& img) { // required by MutableContainerConcept 00134 using std::swap; 00135 swap(_align, img._align); 00136 swap(_memory,img._memory); 00137 swap(_view, img._view); 00138 swap(_alloc, img._alloc); 00139 } 00140 00141 void recreate(const point_t& dims, std::size_t alignment=1) { 00142 if (dims!=_view.dimensions() || _align!=alignment) { 00143 image tmp(dims, alignment); 00144 swap(tmp); 00145 } 00146 } 00147 void recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1) { 00148 recreate(point_t(width,height),alignment); 00149 } 00150 void recreate(const point_t& dims, 00151 const Pixel& p_in, std::size_t alignment) { 00152 if (dims!=_view.dimensions() || _align!=alignment) { 00153 image tmp(dims, p_in, alignment); 00154 swap(tmp); 00155 } 00156 } 00157 void recreate(x_coord_t width, y_coord_t height, 00158 const Pixel& p_in, std::size_t alignment) { 00159 recreate(point_t(width,height),p_in,alignment); 00160 } 00161 00162 view_t _view; // contains pointer to the pixels, the image size and ways to navigate pixels 00163 private: 00164 unsigned char* _memory; 00165 std::size_t _align; 00166 allocator_type _alloc; 00167 00168 void allocate_and_default_construct(const point_t& dimensions) { 00169 try { 00170 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00171 default_construct_pixels(_view); 00172 } catch(...) { deallocate(dimensions); throw; } 00173 } 00174 00175 void allocate_and_fill(const point_t& dimensions, const Pixel& p_in) { 00176 try { 00177 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00178 uninitialized_fill_pixels(_view, p_in); 00179 } catch(...) { deallocate(dimensions); throw; } 00180 } 00181 00182 template <typename View> 00183 void allocate_and_copy(const point_t& dimensions, const View& v) { 00184 try { 00185 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00186 uninitialized_copy_pixels(v,_view); 00187 } catch(...) { deallocate(dimensions); throw; } 00188 } 00189 00190 void deallocate(const point_t& dimensions) { 00191 if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions)); 00192 } 00193 00194 std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const { 00195 std::size_t size_in_units = _total_allocated_size(dimensions, mpl::bool_<IsPlanar>()); 00196 // return the size rounded up to the nearest byte 00197 return (size_in_units + byte_to_memunit<typename view_t::x_iterator>::value - 1) / byte_to_memunit<typename view_t::x_iterator>::value; 00198 } 00199 00200 std::size_t get_row_size(x_coord_t width) const { // number of units per row 00201 return align(width*memunit_step(typename view_t::x_iterator()),_align); 00202 } 00203 00204 std::size_t _total_allocated_size(const point_t& dimensions,mpl::false_) const { 00205 return get_row_size(dimensions.x)*dimensions.y+_align-1; 00206 } 00207 std::size_t _total_allocated_size(const point_t& dimensions,mpl::true_) const { 00208 std::size_t plane_size=get_row_size(dimensions.x)*dimensions.y; 00209 return plane_size*num_channels<view_t>::value+_align-1; 00210 } 00211 00212 00213 void allocate_(const point_t& dimensions, mpl::false_) { // if it throws and _memory!=0 the client must deallocate _memory 00214 _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); 00215 unsigned char* tmp=(unsigned char*)align((std::size_t)_memory,_align); 00216 _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),get_row_size(dimensions.x))); 00217 } 00218 void allocate_(const point_t& dimensions, mpl::true_) { // if it throws and _memory!=0 the client must deallocate _memory 00219 std::size_t row_size=get_row_size(dimensions.x); 00220 std::size_t plane_size=row_size*dimensions.y; 00221 _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); 00222 unsigned char* tmp=(unsigned char*)align((std::size_t)_memory,_align); 00223 typename view_t::x_iterator first; 00224 for (int i=0; i<num_channels<view_t>::value; ++i) { 00225 dynamic_at_c(first,i) = (typename channel_type<view_t>::type*)tmp; 00226 memunit_advance(dynamic_at_c(first,i), plane_size*i); 00227 } 00228 _view=view_t(dimensions, typename view_t::locator(first, row_size)); 00229 } 00230 }; 00231 00232 template <typename Pixel, bool IsPlanar, typename Alloc> 00233 void swap(image<Pixel, IsPlanar, Alloc>& im1,image<Pixel, IsPlanar, Alloc>& im2) { 00234 im1.swap(im2); 00235 } 00236 00237 template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2> 00238 bool operator==(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) { 00239 if ((void*)(&im1)==(void*)(&im2)) return true; 00240 if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false; 00241 return equal_pixels(const_view(im1),const_view(im2)); 00242 } 00243 template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2> 00244 bool operator!=(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) {return !(im1==im2);} 00245 00249 00251 00253 template <typename Pixel, bool IsPlanar, typename Alloc> inline 00254 const typename image<Pixel,IsPlanar,Alloc>::view_t& view(image<Pixel,IsPlanar,Alloc>& img) { return img._view; } 00255 00257 template <typename Pixel, bool IsPlanar, typename Alloc> inline 00258 const typename image<Pixel,IsPlanar,Alloc>::const_view_t const_view(const image<Pixel,IsPlanar,Alloc>& img) { 00259 return static_cast<const typename image<Pixel,IsPlanar,Alloc>::const_view_t>(img._view); 00260 } 00262 00264 // PixelBasedConcept 00266 00267 template <typename Pixel, bool IsPlanar, typename Alloc> 00268 struct channel_type<image<Pixel,IsPlanar,Alloc> > : public channel_type<Pixel> {}; 00269 00270 template <typename Pixel, bool IsPlanar, typename Alloc> 00271 struct color_space_type<image<Pixel,IsPlanar,Alloc> > : public color_space_type<Pixel> {}; 00272 00273 template <typename Pixel, bool IsPlanar, typename Alloc> 00274 struct channel_mapping_type<image<Pixel,IsPlanar,Alloc> > : public channel_mapping_type<Pixel> {}; 00275 00276 template <typename Pixel, bool IsPlanar, typename Alloc> 00277 struct is_planar<image<Pixel,IsPlanar,Alloc> > : public mpl::bool_<IsPlanar> {}; 00278 00279 #ifdef _MSC_VER 00280 #pragma warning(pop) 00281 #endif 00282 00283 } } // namespace boost::gil 00284 00285 #endif Generated on Thu Nov 8 21:53:17 2007 for Generic Image Library by 1.4.4 |