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 vil_blocked_image_resource::n_block_i() const
00021 {
00022 unsigned sbi = size_block_i();
00023 if (sbi==0)
00024 return 0;
00025 return (ni()+sbi -1)/sbi;
00026 }
00027
00028 unsigned vil_blocked_image_resource::n_block_j() const
00029 {
00030 unsigned 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 start_block_i, unsigned end_block_i,
00038 unsigned start_block_j, unsigned end_block_j,
00039 vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks ) const
00040 {
00041 for (unsigned bi = start_block_i; bi<=end_block_i; ++bi)
00042 {
00043 vcl_vector< vil_image_view_base_sptr > jblocks;
00044
00045 for (unsigned 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 start_block_i,
00059 unsigned end_block_i,
00060 unsigned start_block_j,
00061 unsigned end_block_j,
00062 vcl_vector< vcl_vector< vil_image_view_base_sptr > > const& blocks )
00063 {
00064 for (unsigned bi = start_block_i; bi<=end_block_i; ++bi)
00065 for (unsigned 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 output_width = 0;
00081 unsigned output_height = 0;
00082 unsigned 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 curr_i = 0;
00092 unsigned 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 bi = 0 ; bi < blocks.size() ; bi++) \
00101 { \
00102 for (unsigned 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 block_i, unsigned i,
00137 unsigned& i_offset) const
00138 {
00139 i_offset = 0;
00140 unsigned tw = size_block_i();
00141 if (tw==0)
00142 return false;
00143 unsigned 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 block_j, unsigned j,
00152 unsigned& j_offset) const
00153 {
00154 j_offset = 0;
00155 unsigned tl = size_block_j();
00156 if (tl==0)
00157 return false;
00158 unsigned 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 i0, unsigned ni,
00169 unsigned j0, unsigned nj,
00170 unsigned start_block_i,
00171 unsigned start_block_j,
00172 vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks) const
00173 {
00174
00175
00176 for (unsigned bi = 0 ; bi < blocks.size() ; bi++) {
00177 for (unsigned bj = 0 ; bj < blocks[bi].size() ; bj++) {
00178 if (!blocks[bi][bj]) continue;
00179 unsigned last_col_index = blocks.size()-1;
00180 unsigned last_row_index = blocks[bi].size()-1;
00181
00182 bool first_block_in_row = bi == 0;
00183 bool first_block_in_col = bj == 0;
00184 bool last_block_in_row = bi == last_col_index;
00185 bool last_block_in_col = bj == last_row_index;
00186
00187
00188 if (!first_block_in_row && !first_block_in_col &&
00189 !last_block_in_row && !last_block_in_col) continue;
00190
00191 unsigned bi0=0, bin=size_block_i()-1;
00192 unsigned bj0=0, bjn=size_block_j()-1;
00193 if (first_block_in_row)
00194 if (!block_i_offset(start_block_i+bi, i0, bi0))
00195 return false;
00196 if (last_block_in_row)
00197 if (!block_i_offset(start_block_i+bi, i0+ni-1, bin))
00198 return false;
00199 if (first_block_in_col)
00200 if (!block_j_offset(start_block_j+bj, j0, bj0))
00201 return false;
00202 if (last_block_in_col)
00203 if (!block_j_offset(start_block_j+bj, j0+nj-1, bjn))
00204 return false;
00205
00206 switch (vil_pixel_format_component_format(pixel_format()))
00207 {
00208 #define TRIM_BORDER_BLOCK_CASE(FORMAT, T) \
00209 case FORMAT: { \
00210 vil_image_view< T > currBlock = static_cast<vil_image_view< T >&>(*blocks[bi][bj]);\
00211 vil_image_view< T >* croppedBlock = new vil_image_view< T >();\
00212 *croppedBlock = vil_crop(currBlock, bi0, bin-bi0+1, bj0, bjn-bj0+1);\
00213 blocks[bi][bj] = croppedBlock;\
00214 } break
00215 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_BYTE, vxl_byte);
00216 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte);
00217 #if VXL_HAS_INT_64
00218 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_64, vxl_uint_64);
00219 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_64, vxl_int_64);
00220 #endif
00221 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32);
00222 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_32, vxl_int_32);
00223 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16);
00224 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_INT_16, vxl_int_16);
00225 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_BOOL, bool);
00226 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_FLOAT, float);
00227 TRIM_BORDER_BLOCK_CASE(VIL_PIXEL_FORMAT_DOUBLE, double);
00228 #undef TRIM_BORDER_BLOCK_CASE
00229
00230 default:
00231 assert(!"Unknown vil data type.");
00232 return false;
00233 }
00234 }
00235 }
00236 return true;
00237 }
00238
00239
00240 vil_image_view_base_sptr vil_blocked_image_resource::
00241 get_copy_view(unsigned i0, unsigned n_i, unsigned j0, unsigned n_j) const
00242 {
00243 vil_image_view_base_sptr view = 0;
00244
00245 unsigned tw = size_block_i(), tl = size_block_j();
00246 if (tw==0||tl==0)
00247 return view;
00248
00249
00250 unsigned bi_start = i0/tw, bi_end = (i0+n_i-1)/tw;
00251 unsigned bj_start = j0/tl, bj_end = (j0+n_j-1)/tl;
00252
00253 unsigned lbi = n_block_i()-1, lbj = n_block_j()-1;
00254
00255 if (bi_start>lbi||bi_end>lbi||bj_start>lbj||bj_end>lbj)
00256 return view;
00257
00258
00259 vcl_vector<vcl_vector< vil_image_view_base_sptr > > blocks;
00260
00261 this->get_blocks(bi_start, bi_end, bj_start, bj_end, blocks);
00262 if (!blocks.size())
00263 return view;
00264
00265 if (!trim_border_blocks(i0, n_i, j0, n_j, bi_start, bj_start, blocks))
00266 return view;
00267
00268 view = this->glue_blocks_together(blocks);
00269 #ifdef DEBUG
00270 unsigned nblocks = (bi_end-bi_start+1)*(bj_end-bj_start+1);
00271 if (nblocks>1)
00272 vcl_cout << "Get copy view of " << nblocks << " blocks in "
00273 << t.real() << "msecs\n";
00274 #endif
00275 return view;
00276 }
00277
00278 vil_blocked_image_resource_sptr blocked_image_resource(const vil_image_resource_sptr& ir)
00279 {
00280 if (!ir)
00281 return 0;
00282 unsigned sbi=0, sbj=0;
00283 if (ir->get_property(vil_property_size_block_i, &sbi)&&
00284 ir->get_property(vil_property_size_block_j, &sbj))
00285 return (vil_blocked_image_resource*)ir.ptr();
00286 else
00287 return 0;
00288 }