00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 #include "vil_blocked_image_resource.h"
00006
00007 #include <vcl_cassert.h>
00008 #include <vil/vil_property.h>
00009 #include <vil/vil_image_view.h>
00010 #include <vil/vil_crop.h>
00011 #include <vil/vil_copy.h>
00012
00013
00014 vil_blocked_image_resource::vil_blocked_image_resource()
00015 {}
00016
00017 vil_blocked_image_resource::~vil_blocked_image_resource()
00018 {}
00019
00020 unsigned int vil_blocked_image_resource::n_block_i() const
00021 {
00022 unsigned int sbi = size_block_i();
00023 if (sbi==0)
00024 return 0;
00025 return (ni()+sbi -1)/sbi;
00026 }
00027
00028 unsigned int vil_blocked_image_resource::n_block_j() const
00029 {
00030 unsigned int sbj = size_block_j();
00031 if (sbj==0)
00032 return 0;
00033 return (nj()+sbj -1)/sbj;
00034 }
00035
00036 bool vil_blocked_image_resource::
00037 get_blocks(unsigned int start_block_i, unsigned int end_block_i,
00038 unsigned int start_block_j, unsigned int end_block_j,
00039 vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks ) const
00040 {
00041 for (unsigned int bi = start_block_i; bi<=end_block_i; ++bi)
00042 {
00043 vcl_vector< vil_image_view_base_sptr > jblocks;
00044
00045 for (unsigned int bj = start_block_j; bj<=end_block_j; ++bj)
00046 {
00047 vil_image_view_base_sptr view =
00048 this->get_block(bi, bj);
00049 if (view) jblocks.push_back(view);
00050 else
00051 return false;
00052 }
00053 blocks.push_back(jblocks);
00054 }
00055 return true;
00056 }
00057
00058 bool vil_blocked_image_resource::put_blocks( unsigned int start_block_i,
00059 unsigned int end_block_i,
00060 unsigned int start_block_j,
00061 unsigned int end_block_j,
00062 vcl_vector< vcl_vector< vil_image_view_base_sptr > > const& blocks )
00063 {
00064 for (unsigned int bi = start_block_i; bi<=end_block_i; ++bi)
00065 for (unsigned int bj = start_block_j; bj<=end_block_j; ++bj)
00066 if (!this->put_block(bi, bj, *blocks[bi][bj]))
00067 return false;
00068 return true;
00069 }
00070
00071 vil_image_view_base_sptr vil_blocked_image_resource::
00072 glue_blocks_together(const vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks) const
00073 {
00074 vil_image_view_base_sptr result;
00075 if (blocks.size()==0)
00076 return result;
00077
00078
00079
00080 unsigned int output_width = 0;
00081 unsigned int output_height = 0;
00082 unsigned int i;
00083 for (i = 0 ; i < blocks.size() ; i++) {
00084 output_width += blocks[i][0]->ni();
00085 }
00086 for (i = 0 ; i < blocks[0].size() ; i++) {
00087 output_height += blocks[0][i]->nj();
00088 }
00089
00090
00091 unsigned int curr_i = 0;
00092 unsigned int curr_j = 0;
00093 vil_pixel_format fmt = vil_pixel_format_component_format(this->pixel_format());
00094 switch (fmt)
00095 {
00096 #define GLUE_BLOCK_CASE(FORMAT, T) \
00097 case FORMAT: { \
00098 vil_image_view<T>* output_image = \
00099 new vil_image_view<T>(output_width, output_height, 1, nplanes()); \
00100 for (unsigned int bi = 0 ; bi < blocks.size() ; bi++) \
00101 { \
00102 for (unsigned int bj = 0 ; bj < blocks[bi].size() ; bj++)\
00103 { \
00104 vil_copy_to_window(static_cast<vil_image_view<T>&>(*blocks[bi][bj]), *output_image, curr_i, curr_j); \
00105 curr_j += blocks[bi][bj]->nj(); \
00106 } \
00107 curr_j = 0; \
00108 curr_i += blocks[bi][0]->ni();\
00109 } \
00110 result = output_image; \
00111 return result; \
00112 }
00113 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00114 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00115 #if VXL_HAS_INT_64
00116 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64);
00117 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_64, vxl_int_64);
00118 #endif
00119 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00120 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00121 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00122 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00123 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00124 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00125 GLUE_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00126 #undef GLUE_BLOCK_CASE
00127
00128 default:
00129 assert(!"Unknown vil data type in tiff file format");
00130 break;
00131 }
00132 return result;
00133 }
00134
00135
00136 bool vil_blocked_image_resource::block_i_offset(unsigned int block_i, unsigned int i,
00137 unsigned int& i_offset) const
00138 {
00139 i_offset = 0;
00140 unsigned int tw = size_block_i();
00141 if (tw==0)
00142 return false;
00143 unsigned int bstrt = tw*block_i;
00144 if (i<bstrt)
00145 return false;
00146 i_offset = i-bstrt;
00147 return true;
00148 }
00149
00150
00151 bool vil_blocked_image_resource::block_j_offset(unsigned int block_j, unsigned int j,
00152 unsigned int& j_offset) const
00153 {
00154 j_offset = 0;
00155 unsigned int tl = size_block_j();
00156 if (tl==0)
00157 return false;
00158 unsigned int bstrt = tl*block_j;
00159 if (j<bstrt)
00160 return false;
00161 j_offset = j-bstrt;
00162 return true;
00163 }
00164
00165
00166
00167
00168 bool vil_blocked_image_resource::trim_border_blocks(unsigned int i0, unsigned int ni,
00169 unsigned int j0, unsigned int nj,
00170 unsigned int start_block_i,
00171 unsigned int start_block_j,
00172 vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks) const
00173 {
00174
00175 for (unsigned int bi = 0 ; bi < blocks.size() ; bi++) {
00176 for (unsigned int bj = 0 ; bj < blocks[bi].size() ; bj++) {
00177 if (!blocks[bi][bj]) continue;
00178 unsigned int last_col_index = (unsigned int)(blocks.size()-1);
00179 unsigned int last_row_index = (unsigned int)(blocks[bi].size()-1);
00180
00181 bool first_block_in_row = bi == 0;
00182 bool first_block_in_col = bj == 0;
00183 bool last_block_in_row = bi == last_col_index;
00184 bool last_block_in_col = bj == last_row_index;
00185
00186
00187 if (!first_block_in_row && !first_block_in_col &&
00188 !last_block_in_row && !last_block_in_col) continue;
00189
00190 unsigned int bi0=0, bin=size_block_i()-1;
00191 unsigned int bj0=0, bjn=size_block_j()-1;
00192 if (first_block_in_row)
00193 if (!block_i_offset(start_block_i+bi, i0, bi0))
00194 return false;
00195 if (last_block_in_row)
00196 if (!block_i_offset(start_block_i+bi, i0+ni-1, bin))
00197 return false;
00198 if (first_block_in_col)
00199 if (!block_j_offset(start_block_j+bj, j0, bj0))
00200 return false;
00201 if (last_block_in_col)
00202 if (!block_j_offset(start_block_j+bj, j0+nj-1, bjn))
00203 return false;
00204
00205 switch (vil_pixel_format_component_format(pixel_format()))
00206 {
00207 #define TRIM_BORDER_BLOCK_CASE(FORMAT, T) \
00208 case FORMAT: { \
00209 vil_image_view< T > currBlock = static_cast<vil_image_view< T >&>(*blocks[bi][bj]);\
00210 vil_image_view< T >* croppedBlock = new vil_image_view< T >();\
00211 *croppedBlock = vil_crop(currBlock, bi0, bin-bi0+1, bj0, bjn-bj0+1);\
00212 blocks[bi][bj] = croppedBlock;\
00213 } break
00214 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00215 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00216 #if VXL_HAS_INT_64
00217 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64);
00218 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_64, vxl_int_64);
00219 #endif
00220 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00221 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00222 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00223 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00224 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00225 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00226 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00227 #undef TRIM_BORDER_BLOCK_CASE
00228
00229 default:
00230 assert(!"Unknown vil data type.");
00231 return false;
00232 }
00233 }
00234 }
00235 return true;
00236 }
00237
00238
00239 vil_image_view_base_sptr vil_blocked_image_resource::
00240 get_copy_view(unsigned int i0, unsigned int n_i, unsigned int j0, unsigned int n_j) const
00241 {
00242 vil_image_view_base_sptr view = 0;
00243
00244 unsigned int tw = size_block_i(), tl = size_block_j();
00245 if (tw==0||tl==0)
00246 return view;
00247
00248
00249 unsigned int bi_start = i0/tw, bi_end = (i0+n_i-1)/tw;
00250 unsigned int bj_start = j0/tl, bj_end = (j0+n_j-1)/tl;
00251
00252 unsigned int lbi = n_block_i()-1, lbj = n_block_j()-1;
00253
00254 if (bi_start>lbi||bi_end>lbi||bj_start>lbj||bj_end>lbj)
00255 return view;
00256
00257
00258 vcl_vector<vcl_vector< vil_image_view_base_sptr > > blocks;
00259
00260 this->get_blocks(bi_start, bi_end, bj_start, bj_end, blocks);
00261 if (!blocks.size())
00262 return view;
00263
00264 if (!trim_border_blocks(i0, n_i, j0, n_j, bi_start, bj_start, blocks))
00265 return view;
00266
00267 view = this->glue_blocks_together(blocks);
00268 #ifdef DEBUG
00269 unsigned int nblocks = (bi_end-bi_start+1)*(bj_end-bj_start+1);
00270 if (nblocks>1)
00271 vcl_cout << "Get copy view of " << nblocks << " blocks in "
00272 << t.real() << "msecs\n";
00273 #endif
00274 return view;
00275 }
00276
00277 vil_blocked_image_resource_sptr blocked_image_resource(const vil_image_resource_sptr& ir)
00278 {
00279 if (!ir)
00280 return 0;
00281 unsigned int sbi=0, sbj=0;
00282 if (ir->get_property(vil_property_size_block_i, &sbi)&&
00283 ir->get_property(vil_property_size_block_j, &sbj))
00284 return (vil_blocked_image_resource*)ir.ptr();
00285 else
00286 return 0;
00287 }