1 // This is core/vil1/vil1_vil.h
2 #ifndef vil1_vil_h_
3 #define vil1_vil_h_
4 //:
5 // \file
6 // \brief Provide inline vil wrappers of vil1 and vice-versa.
7 
8 #include <iostream>
9 #include "vil1_fwd.h"
10 #include "vil1_image.h"
11 #include "vil1_memory_image_of.h"
12 #include <vil/vil_image_resource.h>
13 #include <vil/vil_image_view.h>
14 #ifdef _MSC_VER
15 #  include <vcl_msvc_warnings.h>
16 #endif
17 #include <cassert>
18 #include <vil/vil_memory_chunk.h>
19 
20 //: Create a view of a vil1_memory_image_of<T>
21 // Warning, the created view does not share ownership of the underlying image. The
22 // vil1_memory_image_of<T> should not be destroyed while the view is in use.
23 // The function assumes that the addressing increments to the next column, row or plane
24 // are constant throughout the image.
25 
26 template <class T>
vil1_to_vil_image_view(const vil1_memory_image_of<T> & vil1_im)27 vil_image_view<T> vil1_to_vil_image_view(const vil1_memory_image_of<T> &vil1_im)
28 {
29   const T* tl = &vil1_im(0,0);
30 
31   std::ptrdiff_t planestep;
32 
33   if (vil1_im.planes() == 1)
34     planestep = vil1_im.cols()* vil1_im.rows();
35   else
36     planestep = &((vil1_memory_image_of<T>(vil1_im.get_plane(1)))(0,0)) - tl;
37 
38   return vil_image_view<T>(tl,
39                            vil1_im.cols(), vil1_im.rows(), vil1_im.planes(),
40                            &vil1_im(1,0) - tl, &vil1_im(0,1) - tl, planestep);
41 }
42 
43 
44 //: Create a vil1 memory image from a vil image view.
45 // Warning, the created vil1 image doesn't not share ownership of the underlying image. The
46 // vil_image_view<T> should not be destroyed while the vil1 image is in use.
47 template <class T>
vil1_from_vil_image_view(const vil_image_view<T> & vil_im)48 vil1_memory_image_of<T> vil1_from_vil_image_view(const vil_image_view<T> &vil_im)
49 {
50   if (!vil_im.is_contiguous() || vil_im.nplanes() != 1)
51   {
52     std::cerr << "WARNING vil1_vil1_from_image_view(): Unable to create vil1_memory_image_of<T>\n";
53     return vil1_memory_image_of<T>();
54   }
55 
56   return vil1_memory_image_of<T>(const_cast<T*>(vil_im.top_left_ptr()),
57                                                 vil_im.ni(), vil_im.nj());
58 }
59 
60 //: Create a vil_image_resource from a vil1_image.
61 inline vil_image_resource_sptr vil1_to_vil_image_resource(const vil1_image &vil1_im);
62 
63 
64 //: This class wraps a vil1_image to provide a vil style interface
65 class vil1_vil_image_resource: public vil_image_resource
66 {
vil1_vil_image_resource(const vil1_image & src)67   vil1_vil_image_resource(const vil1_image &src) : src_(src)
68   {
69     // can't cope with images organised RRR..GGG..BBB.. dues to vil1_images useless support for planes.
70     assert(src_.planes() == 1);
71     // can't cope with bool images because vil1_image packs the bits.
72     assert(src_.bits_per_component() > 1);
73   }
74 
75   friend vil_image_resource_sptr vil1_to_vil_image_resource(const vil1_image &vil1_im);
76   vil1_image src_;
77 
78  public:
pixel_format()79   vil_pixel_format pixel_format() const override
80   {
81     if (!src_)
82       return VIL_PIXEL_FORMAT_UNKNOWN;
83 
84     switch (src_.component_format())
85     {
86      case VIL1_COMPONENT_FORMAT_UNKNOWN:
87      case VIL1_COMPONENT_FORMAT_COMPLEX:
88       return VIL_PIXEL_FORMAT_UNKNOWN;
89      case VIL1_COMPONENT_FORMAT_UNSIGNED_INT:
90       if (src_.bits_per_component() == 1) return VIL_PIXEL_FORMAT_BOOL;
91       else if (src_.bits_per_component() <= 8) return VIL_PIXEL_FORMAT_BYTE;
92       else if (src_.bits_per_component() <= 16) return VIL_PIXEL_FORMAT_UINT_16;
93       else if (src_.bits_per_component() <= 32) return VIL_PIXEL_FORMAT_UINT_32;
94       else return VIL_PIXEL_FORMAT_UNKNOWN;
95      case VIL1_COMPONENT_FORMAT_SIGNED_INT:
96       if (src_.bits_per_component() == 1) return VIL_PIXEL_FORMAT_BOOL;
97       else if (src_.bits_per_component() <= 8) return VIL_PIXEL_FORMAT_SBYTE;
98       else if (src_.bits_per_component() <= 16) return VIL_PIXEL_FORMAT_INT_16;
99       else if (src_.bits_per_component() <= 32) return VIL_PIXEL_FORMAT_INT_32;
100       else return VIL_PIXEL_FORMAT_UNKNOWN;
101      case VIL1_COMPONENT_FORMAT_IEEE_FLOAT:
102       if (src_.bits_per_component() == 32) return VIL_PIXEL_FORMAT_FLOAT;
103       else if (src_.bits_per_component() <= 64) return VIL_PIXEL_FORMAT_DOUBLE;
104       else return VIL_PIXEL_FORMAT_UNKNOWN;
105      default: return VIL_PIXEL_FORMAT_UNKNOWN;
106     }
107   }
108 
ni()109   unsigned ni() const override { if (src_) return src_.width(); else return 0; }
nj()110   unsigned nj() const override { if (src_) return src_.height(); else return 0; }
nplanes()111   unsigned nplanes() const override { if (!src_) return 0; else return src_.components(); }
112 
113   bool get_property(char const *tag, void *property_value=nullptr) const override
114   {
115     if (src_)
116       return src_.get_property(tag, property_value);
117     else
118       return false;
119   }
120 
get_copy_view(unsigned i0,unsigned ni,unsigned j0,unsigned nj)121   vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned ni, unsigned j0, unsigned nj) const override
122   {
123     if (!src_)
124       return nullptr;
125 
126     switch (pixel_format())
127     {
128 #define macro( F , T ) \
129     case F: { \
130         vil_memory_chunk_sptr chunk = new \
131           vil_memory_chunk(ni*nj*nplanes()*sizeof(T ), F ); \
132         src_.get_section(chunk->data(), i0, j0, ni, nj); \
133         return new vil_image_view<T >(chunk, (const T *)chunk->data(), \
134                                       ni, nj, nplanes(), nplanes(), ni*nplanes(), 1); }
135 
136         macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
137         macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
138         macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
139         macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
140         macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
141         macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
142         macro(VIL_PIXEL_FORMAT_FLOAT , float )
143         macro(VIL_PIXEL_FORMAT_DOUBLE , double )
144 #undef macro
145     default: return nullptr;
146     }
147   }
148 
put_view(const vil_image_view_base & im,unsigned i0,unsigned j0)149   bool put_view(const vil_image_view_base &im, unsigned i0, unsigned j0) override
150   {
151     if (!view_fits(im, i0, j0)) return false;
152     if (!src_) return false;
153 
154     switch (pixel_format())
155     {
156 #define macro( F , T ) \
157     case F: { \
158         const vil_image_view<T > &view = \
159           static_cast<const vil_image_view<T > &>(im); \
160         assert(nplanes()==1 || view.planestep() == 1); \
161         src_.put_section(view.top_left_ptr(), i0, j0, im.ni(), im.nj()); }
162 
163         macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
164         macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
165         macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
166         macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
167         macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
168         macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
169         macro(VIL_PIXEL_FORMAT_FLOAT , float )
170         macro(VIL_PIXEL_FORMAT_DOUBLE , double )
171 #undef macro
172     default: return false;
173     }
174   }
175 };
176 
vil1_to_vil_image_resource(const vil1_image & vil1_im)177 inline vil_image_resource_sptr vil1_to_vil_image_resource(const vil1_image &vil1_im)
178 {
179   if (!vil1_im) return nullptr;
180   return new vil1_vil_image_resource(vil1_im);
181 }
182 
183 #endif // vil1_vil_h_
184