Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_image_view.h

Go to the documentation of this file.
00001 // This is core/vil/vil_image_view.h
00002 #ifndef vil_image_view_h_
00003 #define vil_image_view_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief A base class reference-counting view of some image data.
00010 // \author Ian Scott - Manchester
00011 // \verbatim
00012 //  Modifications
00013 //   Peter Vanroose - 21 Aug.2003 - support added for interleaved planes
00014 // \endverbatim
00015 
00016 #include <vcl_iosfwd.h>
00017 #include <vcl_string.h>
00018 #include <vcl_cassert.h>
00019 #include <vcl_cstddef.h>
00020 #include <vil/vil_image_view_base.h>
00021 #include <vil/vil_memory_chunk.h>
00022 #include <vil/vil_pixel_format.h>
00023 
00024 
00025 //: Concrete view of image data of type T held in memory
00026 //  Views nplanes() planes of data each of size ni() x nj().
00027 //  The (i,j) element of the p'th plane is given by
00028 //  im.top_left_ptr()[i*im.istep() + j*im.jstep() + p*im.planestep]
00029 //  The actual image data is either allocated by the class
00030 //  (using set_size), in which case it is deleted
00031 //  only when it has no views observing it, or is allocated outside (and is not
00032 //  deleted on destruction).  This allows external images to be accessed
00033 //  without a deep copy.
00034 //
00035 //  Note that copying one vil_image_view<T> to another takes a shallow
00036 //  copy by default - it copies the view, not the raw image data.
00037 //  Use the explicit deep_copy() call to take a deep copy.
00038 
00039 template <class T>
00040 class vil_image_view : public vil_image_view_base
00041 {
00042  private:
00043   VCL_SAFE_BOOL_DEFINE;
00044  protected:
00045   //: Pointer to pixel at origin.
00046   T * top_left_;
00047   //: Add this to a pixel pointer to move one column left.
00048   vcl_ptrdiff_t istep_;
00049   //: Add this to a pixel pointer to move one row down.
00050   vcl_ptrdiff_t jstep_;
00051   //: Add this to a pixel pointer to move one plane back.
00052   vcl_ptrdiff_t planestep_;
00053 
00054   //: Reference to actual image data.
00055   vil_memory_chunk_sptr ptr_;
00056 
00057   //: Disconnect this view from the underlying data,
00058   void release_memory() { ptr_ = 0; }
00059 
00060  public:
00061 
00062   //: Dflt ctor
00063   //  Creates an empty one-plane image.
00064    vil_image_view(): top_left_(0),istep_(0),jstep_(0),planestep_(0) {}
00065 
00066   //: Create an image of ni x nj pixels in (n_planes * n_interleaved_planes) planes
00067   //  If n_interleaved_planes > 1, the planes are interleaved.
00068   //  If n_planes > 1, each plane of pixels is stored contiguously.
00069   //  n_planes and n_components should not be both different from 1.
00070   //  n_planes * n_interleaved_planes should be 1 unless T is scalar.
00071   vil_image_view(unsigned ni, unsigned nj, unsigned n_planes=1, unsigned n_interleaved_planes=1);
00072 
00073   //: Set this view to look at someone else's memory data.
00074   //  If the data goes out of scope then this view could be invalid, and
00075   //  there's no way of knowing until its too late - so take care!
00076   vil_image_view(const T* top_left, unsigned ni, unsigned nj, unsigned nplanes,
00077                  vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step, vcl_ptrdiff_t plane_step);
00078 
00079   //: Set this view to look at another view's data
00080   //  Typically used by functions which generate a manipulated view of
00081   //  another's image data.
00082   //  Need to pass the memory chunk to set up the internal smart ptr appropriately
00083   vil_image_view(const vil_memory_chunk_sptr& mem_chunk,
00084                  const T* top_left, unsigned ni, unsigned nj, unsigned nplanes,
00085                  vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step, vcl_ptrdiff_t plane_step);
00086 
00087   //: Copy construct.
00088   // The new object will point to the same underlying image as the rhs.
00089   vil_image_view(const vil_image_view<T>& rhs);
00090 
00091   //: Construct from various vil_image_view types.
00092   // The new object will point to the same underlying image as the rhs
00093   // You can assign a vil_image_view<compound_type<T>> to a vil_image_view<T>
00094   // in all reasonable cases - the lhs will have as many planes as the rhs has
00095   // components. You can assign a vil_image_view<T> to a vil_image_view<compound_type<T>>
00096   // when the underlying data is formatted appropriately and the lhs has
00097   // as many components as the rhs has planes. O(1).
00098   // If the view types are not compatible this object will be set to empty.
00099   vil_image_view(const vil_image_view_base& rhs);
00100 
00101   //: Construct from various vil_image_view types.
00102   // The new object will point to the same underlying image as the rhs.
00103   //
00104   // You can assign a vil_image_view<compound_type<T>> to a vil_image_view<T>
00105   // in all reasonable cases - the lhs will have as many planes as the rhs has
00106   // components. You can assign a vil_image_view<T> to a vil_image_view<compound_type<T>>
00107   // when the underlying data is formatted appropriately and the lhs has
00108   // as many components as the rhs has planes. O(1).
00109   // If the view types are not compatible this object will be set to empty.
00110   vil_image_view(const vil_image_view_base_sptr& rhs);
00111 
00112   //  Destructor
00113   virtual ~vil_image_view() {}
00114 
00115   // Standard container stuff
00116   // This assumes that the data is arranged contiguously.
00117   // Is this assumption good?
00118 
00119   //: The pixel type of this image
00120   typedef T pixel_type;
00121 
00122   //: True if data all in one unbroken block and top_left_ptr() is lowest data address
00123   bool is_contiguous() const;
00124 
00125   // iterators
00126   typedef T *iterator;
00127   inline iterator begin() { assert(is_contiguous()); return top_left_; }
00128   inline iterator end  () { assert(is_contiguous()); return top_left_ + size(); }
00129 
00130   typedef T const *const_iterator;
00131   inline const_iterator begin() const { assert(is_contiguous()); return top_left_; }
00132   inline const_iterator end  () const { assert(is_contiguous()); return top_left_ + size(); }
00133 
00134   // arithmetic indexing stuff
00135 
00136   //: Pointer to the first (top left in plane 0) pixel.
00137   //  Note that this is not necessarily the lowest data memory address.
00138   inline T * top_left_ptr() { return top_left_; }  // Make origin explicit
00139   //: Pointer to the first (top left in plane 0) pixel.
00140   //  Note that this is not necessarily the lowest data memory address.
00141   inline const T * top_left_ptr() const { return top_left_; }
00142 
00143   //: Add this to your pixel pointer to get next i pixel.
00144   //  Note that istep() may well be negative; see e.g. vil_flip_lr
00145   inline vcl_ptrdiff_t istep() const { return istep_; }
00146   //: Add this to your pixel pointer to get next j pixel.
00147   //  Note that jstep() may well be negative; see e.g. vil_flip_ud
00148   inline vcl_ptrdiff_t jstep() const { return jstep_; }
00149   //: Add this to your pixel pointer to get pixel on next plane.
00150   //  Note that planestep() may well be negative, e.g. with BMP file images
00151   inline vcl_ptrdiff_t planestep() const { return planestep_; }
00152 
00153   //: Cast to bool is true if pointing at some data.
00154   operator safe_bool () const
00155     { return (top_left_ != (T*)0)? VCL_SAFE_BOOL_TRUE : 0; }
00156 
00157   //: Return false if pointing at some data.
00158   bool operator!() const
00159     { return (top_left_ != (T*)0)? false : true; }
00160 
00161   //: The number of bytes in the data
00162   inline unsigned size_bytes() const { return size() * sizeof(T); }
00163 
00164   //: Smart pointer to the object holding the data for this view
00165   // Will be a null pointer if this view looks at `third-party' data,
00166   // e.g. using set_to_memory.
00167   //
00168   // Typically used when creating new views of the data
00169   inline const vil_memory_chunk_sptr& memory_chunk() const { return ptr_; }
00170 
00171   //: Smart pointer to the object holding the data for this view
00172   // Will be a null pointer if this view looks at `third-party' data,
00173   // e.g. using set_to_memory
00174   //
00175   // Typically used when creating new views of the data
00176   inline vil_memory_chunk_sptr& memory_chunk() { return ptr_; }
00177 
00178   // Ordinary image indexing stuff.
00179 
00180   //: Return true if (i,j) is a valid index into this buffer.
00181   inline bool in_range (int i, int j) const 
00182   { return (i>-1) && (i<(int)ni_) && (j>-1) && (j<(int)nj_); }
00183  
00184   //: Return true if (i,j,p) is a valid index into this buffer.
00185   inline bool in_range (int i, int j, int p) const 
00186   { return (i>-1) && (i<(int)ni_) && (j>-1) && (j<(int)nj_) 
00187       && (p>-1) && (p<(int)nplanes_); }
00188   
00189   //: Return read-only reference to pixel at (i,j) in plane 0.
00190   inline const T& operator()(unsigned i, unsigned j) const {
00191     assert(i<ni_); assert(j<nj_);
00192     return top_left_[jstep_*j+i*istep_]; }
00193 
00194   //: Return read/write reference to pixel at (i,j) in plane 0.
00195   inline T&       operator()(unsigned i, unsigned j) {
00196     assert(i<ni_); assert(j<nj_);
00197     return top_left_[istep_*i+j*jstep_]; }
00198 
00199   //: Return read-only reference to pixel at (i,j) in plane p.
00200   inline const T& operator()(unsigned i, unsigned j, unsigned p) const {
00201     assert(i<ni_); assert(j<nj_); assert(p<nplanes_);
00202     return top_left_[p*planestep_ + j*jstep_ + i*istep_]; }
00203 
00204   //: Return read-only reference to pixel at (i,j) in plane p.
00205   inline T&       operator()(unsigned i, unsigned j, unsigned p) {
00206     assert(i<ni_); assert(j<nj_); assert(p<nplanes_);
00207     return top_left_[p*planestep_ + j*jstep_ + i*istep_]; }
00208 
00209 
00210   // image stuff
00211 
00212   //: resize current planes to ni x nj
00213   // If already correct size, this function returns quickly
00214   virtual void set_size(unsigned ni, unsigned nj);
00215 
00216   //: resize to ni x nj x nplanes
00217   // If already correct size, this function returns quickly
00218   virtual void set_size(unsigned ni, unsigned nj, unsigned nplanes);
00219 
00220   //: Make a copy of the data in src and set this to view it
00221   void deep_copy(const vil_image_view<T>& src);
00222 
00223   //: Make empty.
00224   // Disconnects view from underlying data.
00225   inline void clear() { release_memory(); ni_=nj_=nplanes_=0; top_left_=0; }
00226 
00227   //: Set this view to look at someone else's memory data.
00228   //  If the data goes out of scope then this view could be invalid, and
00229   //  there's no way of knowing until it's too late -- so take care!
00230   //
00231   //  Note that though top_left is passed in as const, the data may be manipulated
00232   //  through the view.
00233   void set_to_memory(const T* top_left, unsigned ni, unsigned nj, unsigned nplanes,
00234                      vcl_ptrdiff_t i_step, vcl_ptrdiff_t j_step, vcl_ptrdiff_t plane_step);
00235 
00236   //: Fill view with given value
00237   void fill(T value);
00238 
00239   //: Print a 1-line summary of contents
00240   virtual void print(vcl_ostream&) const;
00241 
00242   //: Return class name
00243   virtual vcl_string is_a() const;
00244 
00245   //: True if this is (or is derived from) class s
00246   virtual bool is_class(vcl_string const& s) const;
00247 
00248   //: Return a description of the concrete data pixel type.
00249   // The value corresponds directly to pixel_type.
00250   inline vil_pixel_format pixel_format() const { return vil_pixel_format_of(T()); }
00251 
00252   //: True if they share same view of same image data.
00253   //  This does not do a deep equality on image data. If the images point
00254   //  to different image data objects that contain identical images, then
00255   //  the result will still be false.
00256   bool operator==(const vil_image_view_base& other) const;
00257 
00258   //: True if they do not share same view of same image data.
00259   //  This does not do a deep inequality on image data. If the images point
00260   //  to different image data objects that contain identical images, then
00261   //  the result will still be true.
00262   inline bool operator!=(const vil_image_view_base& rhs) const { return !operator==(rhs); }
00263 
00264   //: Provides an ordering.
00265   //  Useful for ordered containers.
00266   //  There is no guaranteed meaning to the less than operator, except that
00267   //  (a<b && b<a)  is false and  !(a<b) && !(b<a)  is equivalent to  a==b
00268   bool operator<(const vil_image_view_base& rhs) const;
00269 
00270   //: Provides an ordering.
00271   inline bool operator>=(const vil_image_view_base& rhs) const { return !operator<(rhs); }
00272 
00273   //: Provides an ordering.
00274   bool operator>(const vil_image_view_base& rhs) const;
00275 
00276   //: Provides an ordering.
00277   inline bool operator<=(const vil_image_view_base & rhs) const { return !operator>(rhs); }
00278 
00279   //: Copy a view. The rhs and lhs will point to the same image data.
00280   const vil_image_view<T>& operator=(const vil_image_view<T>& rhs);
00281 
00282   //: Copy a view. The rhs and lhs will point to the same image data.
00283   // You can assign a vil_image_view<compound_type<T>> to a vil_image_view<T>
00284   // in all reasonable cases - the lhs will have as many planes as the rhs has
00285   // components. You can assign a vil_image_view<T> to a vil_image_view<compound_type<T>>
00286   // when the underlying data is formatted appropriately and the lhs has
00287   // as many components as the rhs has planes. O(1).
00288   // If the view types are not compatible this object will be set to empty.
00289   const vil_image_view<T>& operator=(const vil_image_view_base & rhs);
00290 
00291   //: Copy a view. The rhs and lhs will point to the same image data.
00292   // You can assign a vil_image_view<compound_type<T>> to a vil_image_view<T>
00293   // in all reasonable cases - the lhs will have as many planes as the rhs has
00294   // components. You can assign a vil_image_view<T> to a vil_image_view<compound_type<T>>
00295   // when the underlying data is formatted appropriately and the lhs has
00296   // as many components as the rhs has planes. O(1).
00297   // If the view types are not compatible this object will be set to empty.
00298   // If the pointer is null, this object will be set to empty.
00299   // See also vil_convert_to_component_order().
00300   inline const vil_image_view<T>& operator=(const vil_image_view_base_sptr& rhs)
00301   {
00302     if (!rhs) clear();
00303     else *this = *rhs;
00304     return *this;
00305   }
00306 };
00307 
00308 //: Print a 1-line summary of contents
00309 template <class T>
00310 inline
00311 vcl_ostream& operator<<(vcl_ostream& s, vil_image_view<T> const& im)
00312 {
00313   im.print(s); return s;
00314 }
00315 
00316 //: True if the actual images are identical.
00317 // $\bigwedge_{i,j,p} {\textstyle src}(i,j,p) == {\textstyle dest}(i,j,p)$
00318 // The data may be formatted differently in each memory chunk.
00319 //  O(size).
00320 // \relates vil_image_view
00321 template<class T>
00322 bool vil_image_view_deep_equality(const vil_image_view<T> &lhs, const vil_image_view<T> &rhs);
00323 
00324 #endif // vil_image_view_h_

Generated on Thu Jan 10 14:40:01 2008 for core/vil by  doxygen 1.4.4