vil_decimate.cxx
Go to the documentation of this file.
1 // This is core/vil/vil_decimate.cxx
2 //:
3 // \file
4 // \author Ian Scott.
5 //
6 // \verbatim
7 // Modifications
8 // 23 Oct.2003 - Peter Vanroose - Added support for 64-bit int pixels
9 // \endverbatim
10 //
11 //-----------------------------------------------------------------------------
12 
13 #include "vil_decimate.h"
14 #include <cassert>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 #include <vil/vil_copy.h>
19 #include <vil/vil_crop.h>
20 #include <vil/vil_exception.h>
21 
22 static const unsigned long large_image_limit = 1024ul * 1024ul * 8ul; //8M Pixels
23 
25  unsigned i_factor,
26  unsigned j_factor)
27 {
28  return new vil_decimate_image_resource(src, i_factor, j_factor);
29 }
30 
31 
33  unsigned i_factor, unsigned j_factor):
34  src_(src),
35  i_factor_(i_factor),
36  j_factor_(j_factor)
37 {
38  assert (i_factor > 0 && j_factor > 0);
39 }
40 
41 
43  unsigned j0, unsigned nj) const
44 {
45  if ((unsigned long)i_factor_ * (unsigned long)ni *
46  (unsigned long)j_factor_ * (unsigned long)nj < large_image_limit)
47  {
48  vil_image_view_base_sptr vs = src_->get_copy_view(i0*i_factor_, ni*i_factor_,
49  j0*j_factor_, nj*j_factor_);
50  if (!vs) return nullptr;
51 
52  return vil_decimate( vs, i_factor_, j_factor_ );
53  }
54  else // do large image case.
55  {
56  if ((i0+ni)*i_factor_ > src_->ni() || (j0+nj)*j_factor_ > src_->nj())
57  {
59  "vil_decimate_image_resource::get_copy_view") );
60  return nullptr;
61  }
62 
63  switch (src_->pixel_format())
64  {
65 #define macro( F , T ) \
66  case F : { \
67  vil_image_view<T > view(ni,nj,src_->nplanes()); \
68  for (unsigned j = 0; j < nj; ++j) \
69  for (unsigned i = 0; i < ni; ++i) { \
70  vil_image_view<T > pixel=src_->get_view((i+i0)*i_factor_,1,(j+j0)*j_factor_,1); \
71  assert ((bool)pixel); \
72  vil_copy_to_window(pixel, view, i, j); } \
73  return new vil_image_view<T >(view); }
74 
75  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
76  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
77 #if VXL_HAS_INT_64
78  macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
79  macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
80 #endif
81  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
82  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
83  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
84  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
88  macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , std::complex<float>)
89  macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , std::complex<double>)
90 #undef macro
91  default:
93  src_->pixel_format(), "vil_decimate_image_resource::get_copy_view") );
94  return nullptr;
95  }
96  }
97 }
98 
100  unsigned j0, unsigned nj) const
101 {
102  if ((unsigned long)i_factor_ * (unsigned long)ni *
103  (unsigned long)j_factor_ * (unsigned long)nj < large_image_limit)
104  {
106  j0*j_factor_, nj*j_factor_);
107  if (!vs) return nullptr;
108 
109  return vil_decimate( vs, i_factor_, j_factor_ );
110  }
111  else // do large image case.
112  return get_copy_view(i0, ni, j0, nj);
113 }
116  unsigned j_factor)
117 {
118  if (j_factor==0) j_factor=i_factor;
119  switch (im->pixel_format())
120  {
121 #define macro( F , T ) \
122  case F : \
123  return new vil_image_view<T >(vil_decimate(static_cast<vil_image_view<T >&>(*im), \
124  i_factor, j_factor));
125 
126  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
127  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
128 #if VXL_HAS_INT_64
129  macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
130  macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
131 #endif
132  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
133  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
134  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
135  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
137  macro(VIL_PIXEL_FORMAT_FLOAT , float )
138  macro(VIL_PIXEL_FORMAT_DOUBLE , double )
139  macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , std::complex<float>)
140  macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , std::complex<double>)
141 #undef macro
142  default:
144  im->pixel_format(), "vil_decimate") );
145  return nullptr;
146  }
147 }
148 
149 //: Put the data in this view back into the image source.
150 #if 1
151 bool vil_decimate_image_resource::put_view(const vil_image_view_base&, unsigned, unsigned)
152 {
154  "vil_decimate_image_resource::put_view") );
155  return false;
156 }
157 #else // disable put_view, because current implementation
158  // does something really stupid.
159  // This put_view, should not just modify the pixels
160  // selected by the decimation, but all the unselected
161  // pixels around it as well.
163  unsigned j0)
164 {
165  if ((unsigned long)i_factor_ * (unsigned long)im.ni() *
166  (unsigned long)j_factor_ * (unsigned long)im.nj() < large_image_limit)
167  {
168  vil_image_view_base_sptr vs = src_->get_view(i0*i_factor_, im.ni()*i_factor_,
169  j0*j_factor_, im.nj()*j_factor_);
170  if (!vs || im.pixel_format() != vs->pixel_format() ||
171  im.nplanes() != vs->nplanes())
172  return false;
173 
174  switch (vs->pixel_format())
175  {
176  #define macro( F , T ) \
177  case F : { \
178  const vil_image_view<T > view = static_cast<const vil_image_view<T >&>(im); \
179  vil_image_view<T > decimated = \
180  vil_decimate(static_cast<vil_image_view<T >&>(*vs), i_factor_, j_factor_); \
181  if (view == decimated) return true; /* If we have already modified the data, do nothing */ \
182  assert(view.ni() == decimated.ni() && view.nj() == decimated.nj()); \
183  vil_copy_reformat(view, decimated); \
184  return src_->put_view(*vs, i0, j0); }
185 
186  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
187  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
188 #if VXL_HAS_INT_64
189  macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
190  macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
191 #endif
192  macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
193  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
194  macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
195  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
196  macro(VIL_PIXEL_FORMAT_FLOAT , float )
197  macro(VIL_PIXEL_FORMAT_DOUBLE , double )
198  macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , std::complex<float>)
199  macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , std::complex<double>)
200 #undef macro
201  default:
202  return false;
203  }
204  }
205  else // do large image case.
206  {
207  if ((i0+im.ni())*i_factor_ > src_->ni() || (j0+im.nj())*j_factor_ > src_->nj())
208  return 0;
209 
210  switch (src_->pixel_format())
211  {
212 #define macro( F , T ) \
213  case F : { \
214  const vil_image_view<T > &view = static_cast<const vil_image_view<T > &>(im); \
215  for (unsigned j = 0; j < im.nj(); ++j) \
216  for (unsigned i = 0; i < im.ni(); ++i) { \
217  vil_image_view<T > pixel=vil_crop(view,i,1,j,1); \
218  assert ((bool)pixel); \
219  if (!src_->put_view(pixel, (i0+i)*i_factor_, (j0+j)*j_factor_)) \
220  return false; } \
221  return true; }
222 
223  macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
224  macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
225 #if VXL_HAS_INT_64
226  macro(VIL_PIXEL_FORMAT_UINT_64 ,vxl_uint_64 )
227  macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
228 #endif
229  macro(VIL_PIXEL_FORMAT_UINT_32 ,vxl_uint_32 )
230  macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
231  macro(VIL_PIXEL_FORMAT_UINT_16 ,vxl_uint_16 )
232  macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
233  macro(VIL_PIXEL_FORMAT_FLOAT , float )
234  macro(VIL_PIXEL_FORMAT_DOUBLE , double )
235  macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , std::complex<float>)
236  macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , std::complex<double>)
237 #undef macro
238  default:
239  return false;
240  }
241  }
242 }
243 #endif // 1
An abstract base class of smart pointers to actual image data in memory.
Indicates that a function call failed because a pixel format could not be handled.
Definition: vil_exception.h:62
std::complex<float> is a scalar for vil's purposes.
Indicates that some operation is not supported.
Definition: vil_exception.h:99
unsigned nj() const override
Dimensions: Planes x ni x nj.
Definition: vil_decimate.h:52
Exceptions thrown by vil, and a mechanism for turning them off.
unsigned ni() const
Width.
unsigned nj() const
Height.
virtual enum vil_pixel_format pixel_format() const =0
Return a description of the concrete data pixel type.
Indicates that some reference was made to pixels beyond the bounds of an image.
Definition: vil_exception.h:81
bool put_view(const vil_image_view_base &im, unsigned i0, unsigned j0) override
Put the data in this view back into the image source.
#define macro(F, T)
Various image copying functions.
vil_image_resource_sptr vil_decimate(const vil_image_resource_sptr &src, unsigned i_factor, unsigned j_factor=0)
decimate to a region of src.
vil_image_view_base_sptr get_copy_view() const
Create a read/write view of a copy of all the data.
A generic_image adaptor that behaves like a decimated version of its input.
Definition: vil_decimate.h:44
unsigned nplanes() const
Number of planes.
void vil_exception_warning(T exception)
Throw an exception indicating a potential problem.
Definition: vil_exception.h:37
vil_decimate_image_resource(vil_image_resource_sptr const &, unsigned i_factor, unsigned j_factor)
vil_image_view< T > vil_decimate(const vil_image_view< T > &im, unsigned i_factor, unsigned j_factor=0)
Create a view which is a decimated version of src.
Definition: vil_decimate.h:20
unsigned ni() const override
Dimensions: Planes x ni x nj.
Definition: vil_decimate.h:51
vil_image_resource_sptr src_
Definition: vil_decimate.h:73
vil_image_view_base_sptr get_view() const
Create a read/write view of all the data.
std::complex<double> is a scalar for vil's purposes.