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