1 // This is core/vil1/vil1_image.h
2 #ifndef vil1_image_h_
3 #define vil1_image_h_
4 //:
5 // \file
6 // \brief A reference-counted image object.
7 // \author fsm
8 
9 #include <iosfwd>
10 #ifdef _MSC_VER
11 #  include <vcl_msvc_warnings.h>
12 #endif
13 #include "vil1_image_impl.h"
14 
15 //: A smart pointer to an actual image.
16 // All operations are delegated to the vil1_image_impl object,
17 // which uses class inheritance to make various file images etc.
18 // For fuller documentation on any method, see vil1_image_impl
19 //
20 // Imagine that vil1_image is a class derived from
21 // vbl_smart_ptr<vil1_image_impl>, but with some extra convenience
22 // methods.  These methods might traditionally be attached to the abstract
23 // base class vil1_image_impl, but this avoids cluttering that interface.
24 //
25 // You should not derive from vil1_image to make a new image type.
26 // Derive from vil1_image_impl instead.
27 
28 class vil1_image
29 {
30 
31  public:
32 // use this delegation macro for consistency, not convenience.
33 #define vil1_image_delegate(m, args, default) { return ptr ? ptr->m args : default; }
34 
35   //: Dimensions:  Planes x W x H x Components
planes()36   int planes() const { vil1_image_delegate(planes, (), 0); }
37 
38   //: Dimensions:  Planes x W x H x Components
width()39   int width() const { vil1_image_delegate(width, (), 0); }
40 
41   //: Dimensions:  Planes x W x H x Components
height()42   int height() const { vil1_image_delegate(height, (), 0); }
43 
44   //: Dimensions:  Planes x W x H x Components
components()45   int components() const { vil1_image_delegate(components, (), 0); }
46 
47   //: Format.
bits_per_component()48   int bits_per_component() const { vil1_image_delegate(bits_per_component, (), 0); }
49 
50   //: Format.
component_format()51   enum vil1_component_format component_format() const
52   { vil1_image_delegate(component_format, (), VIL1_COMPONENT_FORMAT_UNKNOWN);  }
53 
54   //: return the ith plane.
get_plane(unsigned int p)55   vil1_image get_plane(unsigned int p) const { vil1_image_delegate(get_plane, (p), vil1_image()); }
56 
57   //: Copy from image to buf
get_section(void * buf,int x0,int y0,int wd,int ht)58   bool get_section(void *buf, int x0, int y0, int wd, int ht) const
59   { vil1_image_delegate(get_section, (buf, x0, y0, wd, ht), false); }
60 
61   //: Copy from buf to image
put_section(void const * buf,int x0,int y0,int wd,int ht)62   bool put_section(void const *buf, int x0, int y0, int wd, int ht)
63   { vil1_image_delegate(put_section, (buf, x0, y0, wd, ht), false); }
64 
65   //: Getting property information
66   bool get_property(char const *tag, void *property_value = nullptr) const
67   { vil1_image_delegate(get_property, (tag, property_value), false); }
68 
69   //: Setting property information
70   bool set_property(char const *tag, void const *property_value = nullptr)
71   { vil1_image_delegate(set_property, (tag, property_value), false); }
72 
73   //: Return a string describing the file format.
74   // Only file images have a format, others return 0
file_format()75   char const *file_format() const { vil1_image_delegate(file_format, (), "(null)"); }
76 
77 #undef vil1_image_delegate
78   // -------------------- convenience --------------------
79 
80   //: Number of rows
rows()81   int rows() const { return height(); }
82   //: Number of columns
cols()83   int cols() const { return width(); }
84 
85   //: return size in bytes.
86   int get_size_bytes() const;
87 
88   //: Print a 1-line summary of contents
89   std::ostream& print(std::ostream&) const;
90 
91   //------------ smart-pointer logic --------
92 
ptr(p)93   vil1_image(vil1_image_impl *p = nullptr) : ptr(p)
94   {
95     if (ptr)
96       ptr->up_ref();
97   }
98 
vil1_image(vil1_image const & that)99   vil1_image(vil1_image const& that) : ptr(that.ptr) {
100     if (ptr)
101       ptr->up_ref();
102   }
103 
104   //: Destructor
~vil1_image()105   ~vil1_image() {
106     if (ptr)
107       ptr->down_ref();
108     ptr = nullptr; // don't dangle
109   }
110 
111   vil1_image& operator=(vil1_image const &that) {
112     if (ptr != that.ptr) {
113       if (that.ptr)
114         that.ptr->up_ref();
115       if (ptr)
116         ptr->down_ref();
117       ptr = that.ptr;
118     }
119     return *this;
120   }
121 
122   vil1_image& operator=(vil1_image_impl *p) {
123     if (ptr)
124       ptr->down_ref();
125     ptr = p;
126     if (ptr)
127       ptr->up_ref();
128     return *this;
129   }
130 
131   //: equality means equality of implementation, not pixels.
132   bool operator==(vil1_image const &that) const {
133     return ptr == that.ptr;
134   }
135 
136   //: needed for sorted containers of images.
137   bool operator< (vil1_image const &that) const {
138     return ptr <  that.ptr;
139   }
140 
141   //: conversion to bool
142   /* The old 'safe_bool' did implicit conversions, best practice would be to use explicit operator bool */
143   operator bool () const
144     { return (ptr != nullptr)? true : false; }
145 
146   //: inverse conversion to bool
147   bool operator!() const
148     { return (ptr != nullptr)? false : true; }
149 
150   //: use "sptr.impl()" to get a pointer to the impl object.
impl()151   vil1_image_impl *impl() const {
152     return ptr;
153   }
154 
155  protected:
156   vil1_image_impl *ptr;
157 };
158 
159 //: Print a 1-line summary of contents
160 inline std::ostream& operator<<(std::ostream& s, vil1_image const& i)
161 {
162   return i.print(s);
163 }
164 
165 #endif // vil1_image_h_
166