00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "vil_decimate.h"
00017 #include <vcl_cassert.h>
00018 #include <vil/vil_copy.h>
00019 #include <vil/vil_crop.h>
00020 #include <vil/vil_exception.h>
00021
00022 static const unsigned long large_image_limit = 1024ul * 1024ul * 8ul;
00023
00024 vil_image_resource_sptr vil_decimate(const vil_image_resource_sptr &src,
00025 unsigned i_factor,
00026 unsigned j_factor)
00027 {
00028 return new vil_decimate_image_resource(src, i_factor, j_factor);
00029 }
00030
00031
00032 vil_decimate_image_resource::vil_decimate_image_resource(vil_image_resource_sptr const& src,
00033 unsigned i_factor, unsigned j_factor):
00034 src_(src),
00035 i_factor_(i_factor),
00036 j_factor_(j_factor)
00037 {
00038 assert (i_factor > 0 && j_factor > 0);
00039 }
00040
00041
00042 vil_image_view_base_sptr vil_decimate_image_resource::get_copy_view(unsigned i0, unsigned ni,
00043 unsigned j0, unsigned nj) const
00044 {
00045 if ((unsigned long)i_factor_ * (unsigned long)ni *
00046 (unsigned long)j_factor_ * (unsigned long)nj < large_image_limit)
00047 {
00048 vil_image_view_base_sptr vs = src_->get_copy_view(i0*i_factor_, ni*i_factor_,
00049 j0*j_factor_, nj*j_factor_);
00050 if (!vs) return 0;
00051
00052 return vil_decimate( vs, i_factor_, j_factor_ );
00053 }
00054 else
00055 {
00056 if ((i0+ni)*i_factor_ > src_->ni() || (j0+nj)*j_factor_ > src_->nj())
00057 {
00058 vil_exception_warning(vil_exception_out_of_bounds(
00059 "vil_decimate_image_resource::get_copy_view") );
00060 return 0;
00061 }
00062
00063 switch (src_->pixel_format())
00064 {
00065 #define macro( F , T ) \
00066 case F : { \
00067 vil_image_view<T > view(ni,nj,src_->nplanes()); \
00068 for (unsigned j = 0; j < nj; ++j) \
00069 for (unsigned i = 0; i < ni; ++i) { \
00070 vil_image_view<T > pixel=src_->get_view((i+i0)*i_factor_,1,(j+j0)*j_factor_,1); \
00071 assert ((bool)pixel); \
00072 vil_copy_to_window(pixel, view, i, j); } \
00073 return new vil_image_view<T >(view); }
00074
00075 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00076 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00077 #if VXL_HAS_INT_64
00078 macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
00079 macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
00080 #endif
00081 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00082 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00083 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00084 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00085 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00086 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00087 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00088 macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , vcl_complex<float>)
00089 macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , vcl_complex<double>)
00090 #undef macro
00091 default:
00092 vil_exception_warning(vil_exception_unsupported_pixel_format(
00093 src_->pixel_format(), "vil_decimate_image_resource::get_copy_view") );
00094 return 0;
00095 }
00096 }
00097 }
00098
00099 vil_image_view_base_sptr vil_decimate_image_resource::get_view(unsigned i0, unsigned ni,
00100 unsigned j0, unsigned nj) const
00101 {
00102 if ((unsigned long)i_factor_ * (unsigned long)ni *
00103 (unsigned long)j_factor_ * (unsigned long)nj < large_image_limit)
00104 {
00105 vil_image_view_base_sptr vs = src_->get_view(i0*i_factor_, ni*i_factor_,
00106 j0*j_factor_, nj*j_factor_);
00107 if (!vs) return 0;
00108
00109 return vil_decimate( vs, i_factor_, j_factor_ );
00110 }
00111 else
00112 return get_copy_view(i0, ni, j0, nj);
00113 }
00114
00115 vil_image_view_base_sptr vil_decimate(const vil_image_view_base_sptr im, unsigned i_factor,
00116 unsigned j_factor)
00117 {
00118 if (j_factor==0) j_factor=i_factor;
00119 switch (im->pixel_format())
00120 {
00121 #define macro( F , T ) \
00122 case F : \
00123 return new vil_image_view<T >(vil_decimate(static_cast<vil_image_view<T >&>(*im), \
00124 i_factor, j_factor));
00125
00126 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00127 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00128 #if VXL_HAS_INT_64
00129 macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
00130 macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
00131 #endif
00132 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00133 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00134 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00135 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00136 macro(VIL_PIXEL_FORMAT_BOOL , bool )
00137 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00138 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00139 macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , vcl_complex<float>)
00140 macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , vcl_complex<double>)
00141 #undef macro
00142 default:
00143 vil_exception_warning(vil_exception_unsupported_pixel_format(
00144 im->pixel_format(), "vil_decimate") );
00145 return 0;
00146 }
00147 }
00148
00149
00150 #if 1
00151 bool vil_decimate_image_resource::put_view(const vil_image_view_base&, unsigned, unsigned)
00152 {
00153 vil_exception_warning(vil_exception_unsupported_operation(
00154 "vil_decimate_image_resource::put_view") );
00155 return false;
00156 }
00157 #else // disable put_view, because current implementation
00158
00159
00160
00161
00162 bool vil_decimate_image_resource::put_view(const vil_image_view_base& im, unsigned i0,
00163 unsigned j0)
00164 {
00165 if ((unsigned long)i_factor_ * (unsigned long)im.ni() *
00166 (unsigned long)j_factor_ * (unsigned long)im.nj() < large_image_limit)
00167 {
00168 vil_image_view_base_sptr vs = src_->get_view(i0*i_factor_, im.ni()*i_factor_,
00169 j0*j_factor_, im.nj()*j_factor_);
00170 if (!vs || im.pixel_format() != vs->pixel_format() ||
00171 im.nplanes() != vs->nplanes())
00172 return false;
00173
00174 switch (vs->pixel_format())
00175 {
00176 #define macro( F , T ) \
00177 case F : { \
00178 const vil_image_view<T > view = static_cast<const vil_image_view<T >&>(im); \
00179 vil_image_view<T > decimated = \
00180 vil_decimate(static_cast<vil_image_view<T >&>(*vs), i_factor_, j_factor_); \
00181 if (view == decimated) return true; \
00182 assert(view.ni() == decimated.ni() && view.nj() == decimated.nj()); \
00183 vil_copy_reformat(view, decimated); \
00184 return src_->put_view(*vs, i0, j0); }
00185
00186 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00187 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00188 #if VXL_HAS_INT_64
00189 macro(VIL_PIXEL_FORMAT_UINT_64 , vxl_uint_64 )
00190 macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
00191 #endif
00192 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00193 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00194 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00195 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00196 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00197 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00198 macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , vcl_complex<float>)
00199 macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , vcl_complex<double>)
00200 #undef macro
00201 default:
00202 return false;
00203 }
00204 }
00205 else
00206 {
00207 if ((i0+im.ni())*i_factor_ > src_->ni() || (j0+im.nj())*j_factor_ > src_->nj())
00208 return 0;
00209
00210 switch (src_->pixel_format())
00211 {
00212 #define macro( F , T ) \
00213 case F : { \
00214 const vil_image_view<T > &view = static_cast<const vil_image_view<T > &>(im); \
00215 for (unsigned j = 0; j < im.nj(); ++j) \
00216 for (unsigned i = 0; i < im.ni(); ++i) { \
00217 vil_image_view<T > pixel=vil_crop(view,i,1,j,1); \
00218 assert ((bool)pixel); \
00219 if (!src_->put_view(pixel, (i0+i)*i_factor_, (j0+j)*j_factor_)) \
00220 return false; } \
00221 return true; }
00222
00223 macro(VIL_PIXEL_FORMAT_BYTE , vxl_byte )
00224 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00225 #if VXL_HAS_INT_64
00226 macro(VIL_PIXEL_FORMAT_UINT_64 ,vxl_uint_64 )
00227 macro(VIL_PIXEL_FORMAT_INT_64 , vxl_int_64 )
00228 #endif
00229 macro(VIL_PIXEL_FORMAT_UINT_32 ,vxl_uint_32 )
00230 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00231 macro(VIL_PIXEL_FORMAT_UINT_16 ,vxl_uint_16 )
00232 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00233 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00234 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00235 macro(VIL_PIXEL_FORMAT_COMPLEX_FLOAT , vcl_complex<float>)
00236 macro(VIL_PIXEL_FORMAT_COMPLEX_DOUBLE , vcl_complex<double>)
00237 #undef macro
00238 default:
00239 return false;
00240 }
00241 }
00242 }
00243 #endif // 1