00001
00002 #ifndef vil_tiff_file_format_h_
00003 #define vil_tiff_file_format_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vcl_vector.h>
00028 #include <vcl_cassert.h>
00029 #include <vcl_iostream.h>
00030 #include <vil/vil_config.h>
00031 #include <vil/vil_file_format.h>
00032 #include <vil/vil_image_resource.h>
00033 #include <vil/vil_memory_chunk.h>
00034 #include <vil/vil_blocked_image_resource.h>
00035 #include <vil/vil_pyramid_image_resource.h>
00036 #include <vil/file_formats/vil_tiff_header.h>
00037 #include <tiffio.h>
00038 #if HAS_GEOTIFF
00039 #include <vil/file_formats/vil_geotiff_header.h>
00040 #endif
00041
00042
00043
00044 class vil_tiff_file_format : public vil_file_format
00045 {
00046 public:
00047 virtual char const *tag() const;
00048 virtual vil_image_resource_sptr make_input_image(vil_stream *vs);
00049
00050 virtual vil_pyramid_image_resource_sptr
00051 make_input_pyramid_image(char const* file);
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 virtual vil_pyramid_image_resource_sptr
00062 make_pyramid_image_from_base(char const* filename,
00063 vil_image_resource_sptr const& base_image,
00064 unsigned nlevels,
00065 char const* temp_dir);
00066
00067 virtual vil_image_resource_sptr make_output_image(vil_stream* vs,
00068 unsigned ni,
00069 unsigned nj,
00070 unsigned nplanes,
00071 enum vil_pixel_format);
00072
00073 virtual vil_blocked_image_resource_sptr
00074 make_blocked_output_image(vil_stream* vs,
00075 unsigned ni,
00076 unsigned nj,
00077 unsigned nplanes,
00078 unsigned size_block_i,
00079 unsigned size_block_j,
00080 enum vil_pixel_format);
00081
00082
00083 virtual vil_pyramid_image_resource_sptr
00084 make_pyramid_output_image(char const* file);
00085 };
00086
00087 struct tif_stream_structures;
00088 class vil_tiff_header;
00089
00090
00091
00092
00093 struct tif_ref_cnt
00094 {
00095 tif_ref_cnt(TIFF* tif):tif_(tif), cnt_(0){}
00096 TIFF* tif(){return tif_;}
00097 void ref(){cnt_++;}
00098 void unref(){
00099 if (--cnt_<=0)
00100 {
00101 TIFFClose(tif_);
00102 delete this;
00103 }
00104 }
00105 private:
00106 TIFF* tif_;
00107 unsigned cnt_;
00108 };
00109
00110
00111 struct tif_smart_ptr
00112 {
00113 tif_smart_ptr(): tptr_(0){}
00114
00115 tif_smart_ptr(tif_ref_cnt* tptr):tptr_(tptr)
00116 { if (tptr_) tptr_->ref(); }
00117
00118 tif_smart_ptr(tif_smart_ptr const& tp)
00119 {tptr_ = tp.tptr_; if (tptr_) tptr_->ref();}
00120
00121 ~tif_smart_ptr()
00122 {
00123
00124
00125 tif_ref_cnt* old_ptr = tptr_;
00126 tptr_ = 0;
00127 if (old_ptr)
00128 old_ptr->unref();
00129 }
00130
00131 bool operator!() const
00132 {
00133 return (tptr_ != (tif_ref_cnt*)0)? false : true;
00134 }
00135
00136
00137 TIFF* tif() const {if (tptr_) return tptr_->tif(); return (TIFF*)0;}
00138 private:
00139 tif_ref_cnt* tptr_;
00140 };
00141
00142
00143 class vil_tiff_image : public vil_blocked_image_resource
00144 {
00145 friend class vil_tiff_file_format;
00146 public:
00147
00148 vil_tiff_image(tif_smart_ptr const& tif,
00149 vil_tiff_header* th, const unsigned nimages = 1);
00150
00151 ~vil_tiff_image();
00152
00153
00154 virtual unsigned nplanes() const;
00155 virtual unsigned ni() const;
00156 virtual unsigned nj() const;
00157
00158 virtual enum vil_pixel_format pixel_format() const;
00159
00160
00161 char const *file_format() const;
00162
00163 #if HAS_GEOTIFF
00164
00165 bool is_GEOTIFF() { return h_->is_GEOTIFF(); }
00166 #endif
00167
00168
00169
00170
00171 virtual unsigned size_block_i() const;
00172
00173
00174 virtual unsigned size_block_j() const;
00175
00176
00177 virtual unsigned n_block_i() const;
00178
00179
00180 virtual unsigned n_block_j() const;
00181
00182 virtual vil_image_view_base_sptr get_block( unsigned block_index_i,
00183 unsigned block_index_j ) const;
00184
00185 virtual bool put_block( unsigned block_index_i, unsigned block_index_j,
00186 const vil_image_view_base& blk );
00187
00188
00189 virtual bool put_view(const vil_image_view_base& im, unsigned i0, unsigned j0);
00190
00191
00192
00193
00194
00195
00196 virtual bool get_property(char const *tag, void *prop = 0) const;
00197
00198 #if HAS_GEOTIFF
00199
00200 vil_geotiff_header* get_geotiff_header();
00201 #endif
00202
00203 friend class vil_tiff_pyramid_resource;
00204
00205
00206 unsigned int nimages() const {return nimages_;}
00207
00208
00209 unsigned int index() const {return index_;}
00210
00211 void set_index(const unsigned int index)
00212 {assert(index<nimages_); index_=index;}
00213 private:
00214
00215 tif_smart_ptr t_;
00216
00217
00218 vil_tiff_header* h_;
00219
00220 unsigned int index_;
00221
00222 unsigned int nimages_;
00223 #if 0
00224
00225
00226 void clear_TIFF() { t_ = 0; }
00227 #endif
00228
00229 unsigned samples_per_block() const;
00230
00231 enum vil_pixel_format compute_pixel_format();
00232
00233 void copy_byte_block(vxl_byte* data, const vxl_uint_32 nbytes,
00234 vil_memory_chunk_sptr& cnk) const;
00235
00236
00237 vil_image_view_base_sptr
00238 view_from_buffer(vil_pixel_format& fmt,
00239 vil_memory_chunk_sptr const& buf,
00240 unsigned samples_per_block,
00241 unsigned bits_per_sample) const;
00242
00243
00244 vil_image_view_base_sptr fill_block_from_tile(vil_memory_chunk_sptr const & buf) const;
00245
00246 vil_image_view_base_sptr fill_block_from_strip(vil_memory_chunk_sptr const & buf) const;
00247
00248 #if 0
00249 vil_image_view_base_sptr get_block_internal( unsigned block_index_i,
00250 unsigned block_index_j ) const;
00251 void
00252 get_blocks_internal( unsigned start_block_i,
00253 unsigned end_block_i,
00254 unsigned start_block_j,
00255 unsigned end_block_j,
00256 vcl_vector< vcl_vector< vil_image_view_base_sptr > >& blocks ) const;
00257 #endif
00258 bool put_block(unsigned bi, unsigned bj, unsigned i0,
00259 unsigned j0, const vil_image_view_base& im);
00260
00261 unsigned block_index(unsigned block_i, unsigned block_j) const;
00262
00263
00264 void pad_block_with_zeros(unsigned ioff, unsigned joff,
00265 unsigned iclip, unsigned jclip,
00266 unsigned bytes_per_pixel,
00267 vxl_byte* block_buf);
00268
00269
00270 void fill_block_from_view(unsigned bi, unsigned bj,
00271 unsigned i0, unsigned j0,
00272 unsigned ioff, unsigned joff,
00273 unsigned iclip, unsigned jclip,
00274 const vil_image_view_base& im,
00275 vxl_byte*& block_buf);
00276
00277 void bitpack_block(unsigned bytes_per_block,
00278 vxl_byte* in_block_buf,
00279 vxl_byte* out_block_buf);
00280
00281 bool write_block_to_file(unsigned bi, unsigned bj,
00282 unsigned block_size_bytes,
00283 vxl_byte* block_buf);
00284 };
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 struct tiff_pyramid_level
00295 {
00296 public:
00297 tiff_pyramid_level(unsigned header_index, unsigned ni,
00298 unsigned nj, unsigned nplanes, vil_pixel_format fmt)
00299 : header_index_(header_index), scale_(1.0f), ni_(ni), nj_(nj),
00300 nplanes_(nplanes), pix_fmt_(fmt), cur_level_(0)
00301 {}
00302
00303 ~tiff_pyramid_level() {}
00304
00305
00306 unsigned header_index_;
00307
00308
00309 float scale_;
00310
00311
00312 unsigned ni_;
00313
00314
00315 unsigned nj_;
00316
00317
00318 unsigned nplanes_;
00319
00320
00321 vil_pixel_format pix_fmt_;
00322
00323
00324 unsigned cur_level_;
00325
00326 void print(const unsigned l)
00327 { vcl_cout << "level[" << l << "] hindex " << header_index_ << " scale: " << scale_ << " width: " << ni_ << vcl_endl; }
00328 };
00329
00330
00331
00332 class vil_tiff_pyramid_resource : public vil_pyramid_image_resource
00333 {
00334 public:
00335 vil_tiff_pyramid_resource(tif_smart_ptr const& t, bool read = true);
00336
00337 virtual ~vil_tiff_pyramid_resource();
00338
00339
00340
00341
00342
00343 inline virtual unsigned nplanes() const
00344 { if (levels_[0]) return levels_[0]->nplanes_; return 1; }
00345
00346
00347
00348 inline virtual unsigned ni() const
00349 { if (levels_[0]) return levels_[0]->ni_; return 0; }
00350
00351
00352
00353 inline virtual unsigned nj() const
00354 { if (levels_[0]) return levels_[0]->nj_; return 0; }
00355
00356
00357 inline virtual enum vil_pixel_format pixel_format() const
00358 { if (levels_[0]) return levels_[0]->pix_fmt_; return VIL_PIXEL_FORMAT_UNKNOWN; }
00359
00360
00361
00362 virtual char const* file_format() const { return "ptif"; }
00363
00364
00365
00366
00367 virtual unsigned nlevels() const { return levels_.size(); }
00368
00369
00370 virtual vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned n_i,
00371 unsigned j0, unsigned n_j,
00372 unsigned level) const;
00373
00374
00375
00376
00377 virtual vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned n_i,
00378 unsigned j0, unsigned n_j,
00379 const float scale,
00380 float& actual_scale) const;
00381
00382
00383
00384
00385 bool put_resource(vil_image_resource_sptr const& resc);
00386
00387
00388 vil_image_resource_sptr get_resource(const unsigned level) const;
00389
00390
00391 void print(const unsigned level)
00392 { if (level<levels_.size()) levels_[level]->print(level); }
00393 protected:
00394
00395 vil_tiff_pyramid_resource();
00396
00397
00398 void normalize_scales();
00399
00400
00401 tiff_pyramid_level* closest(const float scale) const;
00402
00403
00404 bool read_;
00405
00406
00407 tif_smart_ptr t_;
00408
00409
00410 vcl_vector<tiff_pyramid_level*> levels_;
00411 };
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 template< class T >
00428 T tiff_get_bits( const T* in_val, unsigned i0, unsigned ni )
00429 {
00430 unsigned sample_offset = i0 / ( sizeof(T)*8 );
00431 unsigned bit_offset = i0 % ( sizeof(T)*8 );
00432
00433 unsigned strip_left = bit_offset;
00434 int strip_right = ( sizeof( T ) * 8 ) - ( bit_offset + ni );
00435 T temp = in_val[sample_offset];
00436 if ( strip_left > 0 ){
00437
00438 temp = temp << strip_left;
00439 temp = temp >> strip_left;
00440 }
00441 if ( strip_right > 0 ){
00442
00443
00444
00445 for ( int i = 0 ; i < strip_right ; i++ ) temp /= 2;
00446
00447 }
00448 else if ( strip_right < 0 ){
00449
00450
00451
00452 for ( int i = 0 ; i < (-strip_right) ; i++ ) temp *= 2;
00453 temp += tiff_get_bits<T>( in_val+sample_offset+1, 0, -strip_right );
00454
00455 #if 0
00456 T next = in_val[sample_offset+1];
00457
00458 int new_strip_right = strip_right + (sizeof(T)*8);
00459 for ( int i = 0 ; i < new_strip_right ; i++ ) next /= 2;
00460
00461 unsigned new_strip_left = 1- strip_right;
00462 temp = temp << new_strip_left;
00463 temp += next;
00464 #endif
00465 }
00466 #ifdef DEBUG
00467 vcl_cout << "Out val = " << vcl_hex << temp << vcl_dec << '\n';
00468 #endif
00469 return temp;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 template< class T >
00526 T* tiff_byte_align_data( T* in_data, unsigned num_samples, unsigned in_bits_per_sample, T* out_data )
00527 {
00528 assert( in_bits_per_sample < sizeof(T)*8 );
00529
00530
00531
00532 unsigned bit_offset = 0;
00533 for ( unsigned o = 0 ; o < num_samples ; o++ ){
00534 out_data[o] = tiff_get_bits<T>( in_data, bit_offset, in_bits_per_sample );
00535
00536 bit_offset+=in_bits_per_sample;
00537 }
00538
00539 return out_data;
00540 }
00541
00542 template<> bool* tiff_byte_align_data<bool>( bool* in_data, unsigned num_samples, unsigned in_bits_per_sample, bool* out_data );
00543
00544 #endif // vil_tiff_file_format_h_