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