core/vil/vil_blocked_image_facade.cxx
Go to the documentation of this file.
00001 // This is core/vil/vil_blocked_image_facade.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 #include "vil_blocked_image_facade.h"
00006 
00007 #include <vcl_cstring.h>
00008 #include <vcl_cassert.h>
00009 #include <vil/vil_property.h>
00010 #include <vil/vil_image_view.h>
00011 #include <vil/vil_crop.h>
00012 #include <vil/vil_copy.h>
00013 
00014 //#define DEBUG
00015 
00016 static const unsigned vil_size_block_i = 256, vil_size_block_j = 256;
00017 
00018 vil_blocked_image_facade::vil_blocked_image_facade(const vil_image_resource_sptr &src, const unsigned sbi, const unsigned sbj):
00019   src_(src)
00020 {
00021   //cases
00022   // I the blocking is specified so use it
00023   if (sbi>0&&sbj>0)
00024   {
00025     sbi_ = sbi; sbj_=sbj;
00026     return;
00027   }
00028   // II Use the default block size
00029   sbi_ = vil_size_block_i;  sbj_ = vil_size_block_j;
00030   //set up the buffer
00031 }
00032 
00033 vil_image_view_base_sptr
00034 vil_blocked_image_facade::fill_block(vil_image_view_base_sptr& view) const
00035 {
00036   switch (vil_pixel_format_component_format(pixel_format()))
00037   {
00038 #define FILL_BLOCK_CASE(FORMAT, T) \
00039    case FORMAT: { \
00040     vil_image_view<T>* dest = new vil_image_view<T>(sbi_, sbj_, nplanes()); \
00041     vil_image_view_base_sptr ptr = dest; \
00042     vil_image_view<T>* src = reinterpret_cast<vil_image_view<T>* >(view.ptr()); \
00043     vil_copy_to_window<T>(*src, *dest, 0, 0); \
00044     return dest; \
00045    } break
00046     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00047     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00048     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00049     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00050     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00051     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00052     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00053     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00054     FILL_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00055 #undef FILL_BLOCK_CASE
00056    default:
00057     assert(!"Unknown vil data type.");
00058     return 0;
00059   }
00060   return 0;
00061 }
00062 
00063 //Get a view that is the size of a block. If the block is on the
00064 //border then the block pixels outside the image boundary are undefined
00065 vil_image_view_base_sptr
00066 vil_blocked_image_facade::get_block( unsigned  block_index_i,
00067                                      unsigned  block_index_j ) const
00068 {
00069   unsigned ni = src_->ni(), nj = src_->nj();
00070   unsigned i0 = block_index_i*sbi_, j0 =  block_index_j*sbj_;
00071   if (i0>ni-1||j0>nj-1) return 0;
00072   //check if the view that is supplied is smaller than a block
00073   unsigned icrop = ni-i0, jcrop = nj-j0;
00074   bool needs_fill = false;
00075   if (icrop>=sbi_)
00076     icrop = sbi_;
00077   else
00078     needs_fill = true;
00079 
00080   if (jcrop>=sbj_)
00081     jcrop = sbj_;
00082   else
00083     needs_fill = true;
00084   vil_image_view_base_sptr view = src_->get_view(i0, icrop, j0, jcrop);
00085   if (needs_fill)
00086     view = fill_block(view);
00087   return view;
00088 }
00089 
00090 bool vil_blocked_image_facade::put_block(unsigned  block_index_i,
00091                                          unsigned  block_index_j,
00092                                          const vil_image_view_base& view)
00093 {
00094   // convert to image coordinates
00095   unsigned i0 = block_index_i*sbi_, j0 = block_index_j*sbj_;
00096   // check if block is too big for the destination
00097   unsigned imax = i0 + sbi_, jmax = j0 + sbj_;
00098   unsigned icrop = sbi_, jcrop = sbj_;
00099   bool needs_trim = false;
00100   if (imax>src_->ni())
00101   {
00102     icrop = src_->ni()-i0;
00103     needs_trim = true;
00104   }
00105   if (jmax>src_->nj())
00106   {
00107     jcrop = src_->nj()-j0;
00108     needs_trim = true;
00109   }
00110 
00111   if (needs_trim)
00112     switch (vil_pixel_format_component_format(pixel_format()))
00113     {
00114 #define TRIM_BLOCK_CASE(FORMAT, T) \
00115      case FORMAT: { \
00116       const vil_image_view<T>& curr_view = \
00117         static_cast<const vil_image_view< T >& >(view); \
00118       vil_image_view< T > cview = \
00119         vil_crop(curr_view, 0, icrop, 0, jcrop); \
00120       return src_->put_view(cview, i0, j0); \
00121      } break
00122       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00123       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00124       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00125       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00126       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00127       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00128       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00129       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00130       TRIM_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00131 #undef TRIM_BLOCK_CASE
00132      default:
00133       assert(!"Unknown vil data type.");
00134       return false;
00135     }
00136   // no trim was required
00137 return src_->put_view(view, i0, j0);
00138 }
00139 
00140 
00141 bool vil_blocked_image_facade::get_property(char const * tag, void * value) const
00142 {
00143   if (vcl_strcmp(vil_property_quantisation_depth, tag)==0)
00144     return src_->get_property(tag, value);
00145 
00146   if (vcl_strcmp(vil_property_size_block_i, tag)==0)
00147   {
00148     if (value)
00149       *static_cast<unsigned*>(value) = this->size_block_i();
00150     return true;
00151   }
00152 
00153   if (vcl_strcmp(vil_property_size_block_j, tag)==0)
00154   {
00155     if (value)
00156       *static_cast<unsigned*>(value) = this->size_block_j();
00157     return true;
00158   }
00159 
00160   return false;
00161 }