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=0, 00067 const Alloc alloc_in = Alloc()) : 00068 _memory(0), _align_in_bytes(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=0, 00073 const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { 00074 allocate_and_default_construct(dimensions); 00075 } 00076 image(x_coord_t width, y_coord_t height, 00077 std::size_t alignment=0, 00078 const Alloc alloc_in = Alloc()) : _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { 00079 allocate_and_default_construct(point_t(width,height)); 00080 } 00081 image(const point_t& dimensions, 00082 const Pixel& p_in, 00083 std::size_t alignment, 00084 const Alloc alloc_in = Alloc()) : 00085 _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { 00086 allocate_and_fill(dimensions, p_in); 00087 } 00088 image(x_coord_t width, y_coord_t height, 00089 const Pixel& p_in, 00090 std::size_t alignment, 00091 const Alloc alloc_in = Alloc()) : 00092 _memory(0), _align_in_bytes(alignment), _alloc(alloc_in) { 00093 allocate_and_fill(point_t(width,height),p_in); 00094 } 00095 00096 image(const image& img) : 00097 _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) { 00098 allocate_and_copy(img.dimensions(),img._view); 00099 } 00100 00101 template <typename P2, bool IP2, typename Alloc2> 00102 image(const image<P2,IP2,Alloc2>& img) : 00103 _memory(0), _align_in_bytes(img._align_in_bytes), _alloc(img._alloc) { 00104 allocate_and_copy(img.dimensions(),img._view); 00105 } 00106 image& operator=(const image& img) { 00107 if (dimensions() == img.dimensions()) 00108 copy_pixels(img._view,_view); 00109 else { 00110 image tmp(img); 00111 swap(tmp); 00112 } 00113 return *this; 00114 } 00115 00116 template <typename Img> 00117 image& operator=(const Img& img) { 00118 if (dimensions() == img.dimensions()) 00119 copy_pixels(img._view,_view); 00120 else { 00121 image tmp(img); 00122 swap(tmp); 00123 } 00124 return *this; 00125 } 00126 00127 ~image() { 00128 destruct_pixels(_view); 00129 deallocate(_view.dimensions()); 00130 } 00131 00132 Alloc& allocator() { return _alloc; } 00133 Alloc const& allocator() const { return _alloc; } 00134 00135 void swap(image& img) { // required by MutableContainerConcept 00136 using std::swap; 00137 swap(_align_in_bytes, img._align_in_bytes); 00138 swap(_memory, img._memory); 00139 swap(_view, img._view); 00140 swap(_alloc, img._alloc); 00141 } 00142 00143 void recreate(const point_t& dims, std::size_t alignment=0, const Alloc alloc_in = Alloc()) { 00144 if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) { 00145 image tmp(dims, alignment, alloc_in); 00146 swap(tmp); 00147 } 00148 } 00149 void recreate(x_coord_t width, y_coord_t height, std::size_t alignment=0, const Alloc alloc_in = Alloc()) { 00150 recreate(point_t(width,height),alignment,alloc_in); 00151 } 00152 void recreate(const point_t& dims, 00153 const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) { 00154 if (dims!=_view.dimensions() || _align_in_bytes!=alignment || alloc_in!=_alloc) { 00155 image tmp(dims, p_in, alignment, alloc_in); 00156 swap(tmp); 00157 } 00158 } 00159 void recreate(x_coord_t width, y_coord_t height, 00160 const Pixel& p_in, std::size_t alignment, const Alloc alloc_in = Alloc()) { 00161 recreate(point_t(width,height),p_in,alignment,alloc_in); 00162 } 00163 00164 view_t _view; // contains pointer to the pixels, the image size and ways to navigate pixels 00165 private: 00166 unsigned char* _memory; 00167 std::size_t _align_in_bytes; 00168 allocator_type _alloc; 00169 00170 void allocate_and_default_construct(const point_t& dimensions) { 00171 try { 00172 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00173 default_construct_pixels(_view); 00174 } catch(...) { deallocate(dimensions); throw; } 00175 } 00176 00177 void allocate_and_fill(const point_t& dimensions, const Pixel& p_in) { 00178 try { 00179 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00180 uninitialized_fill_pixels(_view, p_in); 00181 } catch(...) { deallocate(dimensions); throw; } 00182 } 00183 00184 template <typename View> 00185 void allocate_and_copy(const point_t& dimensions, const View& v) { 00186 try { 00187 allocate_(dimensions,mpl::bool_<IsPlanar>()); 00188 uninitialized_copy_pixels(v,_view); 00189 } catch(...) { deallocate(dimensions); throw; } 00190 } 00191 00192 void deallocate(const point_t& dimensions) { 00193 if (_memory) _alloc.deallocate(_memory, total_allocated_size_in_bytes(dimensions)); 00194 } 00195 00196 std::size_t total_allocated_size_in_bytes(const point_t& dimensions) const { 00197 std::size_t size_in_units = get_row_size_in_memunits(dimensions.x)*dimensions.y; 00198 if (IsPlanar) 00199 size_in_units = size_in_units*num_channels<view_t>::value; 00200 00201 // return the size rounded up to the nearest byte 00202 return (size_in_units + byte_to_memunit<typename view_t::x_iterator>::value - 1) / byte_to_memunit<typename view_t::x_iterator>::value 00203 + (_align_in_bytes>0 ? _align_in_bytes-1:0); // add extra padding in case we need to align the first image pixel 00204 } 00205 00206 std::size_t get_row_size_in_memunits(x_coord_t width) const { // number of units per row 00207 std::size_t size_in_memunits = width*memunit_step(typename view_t::x_iterator()); 00208 if (_align_in_bytes>0) { 00209 std::size_t alignment_in_memunits=_align_in_bytes*byte_to_memunit<typename view_t::x_iterator>::value; 00210 return align(size_in_memunits, alignment_in_memunits); 00211 } 00212 return size_in_memunits; 00213 } 00214 00215 void allocate_(const point_t& dimensions, mpl::false_) { // if it throws and _memory!=0 the client must deallocate _memory 00216 _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); 00217 unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory; 00218 _view=view_t(dimensions,typename view_t::locator(typename view_t::x_iterator(tmp),get_row_size_in_memunits(dimensions.x))); 00219 } 00220 00221 void allocate_(const point_t& dimensions, mpl::true_) { // if it throws and _memory!=0 the client must deallocate _memory 00222 std::size_t row_size=get_row_size_in_memunits(dimensions.x); 00223 std::size_t plane_size=row_size*dimensions.y; 00224 _memory=_alloc.allocate(total_allocated_size_in_bytes(dimensions)); 00225 unsigned char* tmp=(_align_in_bytes>0) ? (unsigned char*)align((std::size_t)_memory,_align_in_bytes) : _memory; 00226 typename view_t::x_iterator first; 00227 for (int i=0; i<num_channels<view_t>::value; ++i) { 00228 dynamic_at_c(first,i) = (typename channel_type<view_t>::type*)tmp; 00229 memunit_advance(dynamic_at_c(first,i), plane_size*i); 00230 } 00231 _view=view_t(dimensions, typename view_t::locator(first, row_size)); 00232 } 00233 }; 00234 00235 template <typename Pixel, bool IsPlanar, typename Alloc> 00236 void swap(image<Pixel, IsPlanar, Alloc>& im1,image<Pixel, IsPlanar, Alloc>& im2) { 00237 im1.swap(im2); 00238 } 00239 00240 template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2> 00241 bool operator==(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) { 00242 if ((void*)(&im1)==(void*)(&im2)) return true; 00243 if (const_view(im1).dimensions()!=const_view(im2).dimensions()) return false; 00244 return equal_pixels(const_view(im1),const_view(im2)); 00245 } 00246 template <typename Pixel1, bool IsPlanar1, typename Alloc1, typename Pixel2, bool IsPlanar2, typename Alloc2> 00247 bool operator!=(const image<Pixel1,IsPlanar1,Alloc1>& im1,const image<Pixel2,IsPlanar2,Alloc2>& im2) {return !(im1==im2);} 00248 00252 00254 00256 template <typename Pixel, bool IsPlanar, typename Alloc> inline 00257 const typename image<Pixel,IsPlanar,Alloc>::view_t& view(image<Pixel,IsPlanar,Alloc>& img) { return img._view; } 00258 00260 template <typename Pixel, bool IsPlanar, typename Alloc> inline 00261 const typename image<Pixel,IsPlanar,Alloc>::const_view_t const_view(const image<Pixel,IsPlanar,Alloc>& img) { 00262 return static_cast<const typename image<Pixel,IsPlanar,Alloc>::const_view_t>(img._view); 00263 } 00265 00267 // PixelBasedConcept 00269 00270 template <typename Pixel, bool IsPlanar, typename Alloc> 00271 struct channel_type<image<Pixel,IsPlanar,Alloc> > : public channel_type<Pixel> {}; 00272 00273 template <typename Pixel, bool IsPlanar, typename Alloc> 00274 struct color_space_type<image<Pixel,IsPlanar,Alloc> > : public color_space_type<Pixel> {}; 00275 00276 template <typename Pixel, bool IsPlanar, typename Alloc> 00277 struct channel_mapping_type<image<Pixel,IsPlanar,Alloc> > : public channel_mapping_type<Pixel> {}; 00278 00279 template <typename Pixel, bool IsPlanar, typename Alloc> 00280 struct is_planar<image<Pixel,IsPlanar,Alloc> > : public mpl::bool_<IsPlanar> {}; 00281 00282 //#ifdef _MSC_VER 00283 //#pragma warning(pop) 00284 //#endif 00285 00286 } } // namespace boost::gil 00287 00288 #endif Generated on Sat May 2 13:50:14 2009 for Generic Image Library by 1.5.6 |