1 // This is core/vil1/vil1_memory_image_of.h
2 #ifndef vil1_memory_image_of_h_
3 #define vil1_memory_image_of_h_
4 //:
5 // \file
6 // \author awf@robots.ox.ac.uk
7 // \date 16 Feb 00
8 //
9 //\verbatim
10 // Modifications
11 //     960916 AWF Added save_pgm and more comments.
12 //     961209 Peter Vanroose added operator=() and copy constructor
13 //     980710 FSM Changed constructor to take a const Image *, not Image *
14 //     981105 AWF Made bilinear/bicubic return double.
15 //     990211 Peter Vanroose moved save_pgm() to Templates/ (EGCS complained)
16 //     990421 FSM Added constructor from a const fast_array<T> &
17 //     010126 BJM (mccane@cs.otago.ac.nz) added constructor from
18 //            previously allocated memory. This memory is not deallocated on
19 //            destruction.
20 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
21 //\endverbatim
22 
23 #include "vil1_image.h"
24 #include "vil1_memory_image.h"
25 
26 //: Image stored entirely in RAM
27 //
28 //    vil1_memory_image_of<Type> provides a templated interface to a
29 //    vil1_memory_image.  It is assumed that the user has queried the pixel size
30 //    of the image and is instantiating an ImageBuffer of the appropriate type.
31 //
32 //    This allows C-efficiency access with C++ notational convenience after the
33 //    type has been ascertained.  Note that this should not be used for images
34 //    too large to fit in memory.
35 //
36 //  CAVEAT PROGRAMMER:
37 //    Each raster (row) is stored in a contiguous chunk of memory and the
38 //    operator [] method gives a pointer to the beginning of a raster.
39 //    Thus image[i][j] is the element in the i-th row and j-th column.
40 //    However, image(x, y) is the element in the x-th column and y-th row.
41 
42 template <class T>
43 class vil1_memory_image_of : public vil1_memory_image
44 {
45  public:
46   // The pixel type of this image
47   typedef T pixel_type;
48 
49   // iterators
50   typedef T *iterator;
begin()51   inline iterator begin() { return get_buffer(); }
end()52   inline iterator end  () { return get_buffer() + rows()*cols(); }
53 
54   typedef T const *const_iterator;
begin()55   inline const_iterator begin() const { return get_buffer(); }
end()56   inline const_iterator end  () const { return get_buffer() + rows()*cols(); }
57 
size()58   inline unsigned size() const { return rows() * cols(); }
59 
60   //: Empty image.
61   vil1_memory_image_of();
62 
63   //: This is a copy constructor, but it doesn't make a new buffer.
64   vil1_memory_image_of(vil1_memory_image_of<T> const &);
65 
66   //: Copy given image into a memory buffer.
67   // If it's already a memory image, do as the copy constructor (above) does.
68   explicit
69   vil1_memory_image_of(vil1_image const& image);
70 
71   //: Construct a w x h image, pixel format is determined from T
72   vil1_memory_image_of(int sizex, int sizey);
73 
74   //: Construct a w x h image, pixel format is determined from T from memory previously created and pointed to by buf
75   vil1_memory_image_of(T *buf, int sizex, int sizey);
76 #if 0
77   //: Make memory imagebuffer, and fill with "value"
78   vil1_memory_image_of(int sizex, int sizey, T const& value);
79 #endif
80   //: Clearly, this will deallocate the memory buffer
81   inline ~vil1_memory_image_of() = default;
82 
83   //: This method hides the operator= in the base class.
84   vil1_memory_image_of<T>& operator=(vil1_memory_image_of<T> const &);
85 
86   //: Copy a vil1_image, only if it's in an appropriate format.
87   // This routine does not try to guess how to convert images which are
88   // not compatible with T.
89   vil1_memory_image_of<T>& operator=(vil1_image const &);
90 
91   //: Load image.
92   void set(vil1_image const& image);
93 
94   //: These override the methods in the base class.
95   void resize(int width, int height);
96  private:
97   // don't try to use this.
98   void resize(int planes, int width, int height);
99  public:
100 
101   // Data Access---------------------------------------------------------------
102 
103   //: Return read/write reference to pixel at (x,y)
operator()104   inline T&       operator () (int x, int y) { return ((T**)rows0_)[y][x]; }
operator()105   inline T const& operator () (int x, int y) const { return ((T const* const*)rows0_)[y][x]; }
106 
107   //: Return pointer to raster y.
108   inline T*       operator [] (int y) { return ((T**)rows0_)[y]; }
109   inline T const* operator [] (int y) const { return ((T const* const*)rows0_)[y]; }
110 
111   //: Return pointer to array of rasters. aka known as data_array() for matrices.
row_array()112   inline T*        const* row_array() { return (T**)rows0_; }
row_array()113   inline T const*  const* row_array() const { return (T**)rows0_; }
114 
115   //: Return pointer to the memory buffer.
get_buffer()116   inline T*       get_buffer() { return (T*)rows0_[0]; }
get_buffer()117   inline T const* get_buffer() const { return (T*)rows0_[0]; }
118 
119   //: Return true if (x,y) is a valid index into this buffer
in_range(int x,int y)120   inline bool in_range(int x, int y) const { return (0 <= x) && (0 <= y) && (x < width_) && (y < height_); }
121 
122   //: Return true if (x+/-w,y+/-h) are valid indices into this buffer
in_range_window(int x,int y,int w)123   inline bool in_range_window(int x, int y, int w) const {
124     return (w <= x) && (w <= y) && (x + w < width_) && (y + w < height_);
125   }
126 
127   //: Return true if the region of size w,h starting at x,y is valid in this buffer.
in_range(int x,int y,unsigned w,unsigned h)128   inline bool in_range(int x, int y, unsigned w, unsigned h) const {
129     return (0<=x && x+int(w)<=width_) && (0<=y && y+int(h)<=height_);
130   }
131 
132   //: Fill with given value
133   void fill(T const& );
134 };
135 
136 #endif // vil1_memory_image_of_h_
137