core/vil/file_formats/vil_tiff.h
Go to the documentation of this file.
00001 // This is core/vil/file_formats/vil_tiff.h
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 // \file
00009 // \author awf@robots.ox.ac.uk
00010 // \date   16 Feb 2000
00011 //
00012 // \verbatim
00013 //  Modifications
00014 //   3 Oct 2001 Peter Vanroose - Implemented get_property and set_property
00015 //   5 Jan 2002 Ian Scott      - Converted to vil
00016 //   9 Dec 2003 Peter Vanroose - Added support for 1-bit pixel (bitmapped) images
00017 //   21 Dec 2005 J.L. Mundy - Substantial rewrite to handle a more
00018 //       complete tiff 6.0 standard. Files with tiles can now be read and
00019 //       written. Only tiled images are considered blocked, i.e. not strips.
00020 //       Block dimensions must be a multiple of 16, for compatibility with
00021 //       compression schemes. Tiff files with separate color bands are not handled
00022 //   24 Mar 2007 J.L. Mundy - added smart pointer on TIFF handle to support
00023 //       multiple resources from a single tiff file; required for pyramid
00024 //   KNOWN BUG - 24bit samples for both nplanes = 1 and nplanes = 3
00025 //   KNOWN BUG - bool pixel format write - crashes due to incorrect block size
00026 // \endverbatim
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 //: Loader for tiff files
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   //: Construct a pyramid image resource from a base image.
00055   //  All levels are stored in the same resource file. Each level has the same
00056   //  scale ratio (0.5) to the preceding level. Level 0 is the original
00057   //  base image. The resource is returned open for reading.
00058   //  The temporary directory is for storing intermediate image
00059   //  resources during the construction of the pyramid. Files are
00060   //  be removed from the directory after completion.  If temp_dir is 0
00061   //  then the intermediate resources are created in memory.
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 //Need to create a smartpointer mechanism for the tiff
00091 //file in order to handle multiple images, e.g. for pyramid
00092 //resource
00093 //A reference counting wrapper for the TIFF handle
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 //The smart pointer to the tiff handle
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     // the strange order of events in this function is to avoid
00125     // heap corruption if unref() causes *this to be deleted.
00126     tif_ref_cnt* old_ptr = tptr_;
00127     tptr_ = 0;
00128     if (old_ptr)
00129       old_ptr->unref();
00130   }
00131   //: Inverse bool
00132   bool operator!() const
00133   {
00134     return (tptr_ != (tif_ref_cnt*)0)? false : true;
00135   }
00136 
00137   //: Convenient get TIFF* for header construction; assumes temporary use
00138   TIFF* tif() const {if (tptr_) return tptr_->tif(); return (TIFF*)0;}
00139  private:
00140   tif_ref_cnt* tptr_;
00141 };
00142 
00143 //: Generic image interface for image TIFF image files (could have multiple images)
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   //: Dimensions:  planes x width x height x components
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   //: returns "tiff"
00162   char const *file_format() const;
00163 
00164 #if HAS_GEOTIFF
00165   //: are there any geotiff tags
00166   bool is_GEOTIFF() { return h_->is_GEOTIFF(); }
00167 #endif
00168 
00169            // --- Block interface ---
00170 
00171   //: Block size in columns (must be a multiple of 16)
00172   virtual unsigned size_block_i() const;
00173 
00174   //: Block size in rows (must be a multiple of 16)
00175   virtual unsigned size_block_j() const;
00176 
00177   //: Number of blocks in image width
00178   virtual unsigned n_block_i() const;
00179 
00180   //: Number of blocks in image height
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   //: Put the data in this view back into the image source.
00190   virtual bool put_view(const vil_image_view_base& im, unsigned i0, unsigned j0);
00191 
00192   //: Return true if the property given in the first argument has been set.
00193   // currently defined:
00194   //  "quantisation_depth" - number of relevant bits per pixel
00195   //  "size_block_i" and "size_block_j" - block dimensions
00196 
00197   virtual bool get_property(char const *tag, void *prop = 0) const;
00198 
00199 #if HAS_GEOTIFF
00200   //* returns null if the tiff file does not include any geotiff tags
00201   vil_geotiff_header* get_geotiff_header();
00202 #endif
00203 
00204   friend class vil_tiff_pyramid_resource;
00205 
00206   //:indicates the number of images in the tiff file
00207   unsigned int nimages() const {return nimages_;}
00208 
00209   //:the image index for multiple image files
00210   unsigned int index() const {return index_;}
00211   //:point to a particular image in the file
00212   void set_index(const unsigned int index)
00213     {assert(index<nimages_); index_=index;}
00214  private:
00215   //: the TIFF handle to the open resource file
00216   tif_smart_ptr t_;
00217 
00218   //: the TIFF header information
00219   vil_tiff_header* h_;
00220   //: the default image header index
00221   unsigned int index_;
00222   //: number of images in the file
00223   unsigned int nimages_;
00224 #if 0
00225   //to keep the tiff file open during reuse of multiple tiff resources
00226   //in a single file otherwise the resource destructor would close the file
00227   void clear_TIFF() { t_ = 0; }
00228 #endif
00229   //: the number of samples in a block
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   //: convert a packed block to an expanded view
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   //: the key methods for decoding the file data
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   //: fill out the block with leading zeros or trailing zeros if necessary
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   //: fill the block with view data
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 }; //End of single image TIFF resource
00286 
00287 
00288 ///--------- Representation of Pyramid Images by multi-image TIFF -------
00289 //
00290 //
00291 // It is assumed that image scales are not necessarily ordered with
00292 // respect to tiff header index. This data structure maintains essential
00293 // information about each pyramid level. The struct can be sorted on scale
00294 // to form an ordered pyramid.
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   //:the tiff header index
00307   unsigned header_index_;
00308 
00309   //:scale associated with level
00310   float scale_;
00311 
00312   //:the image width
00313   unsigned ni_;
00314 
00315   //: the image length
00316   unsigned nj_;
00317 
00318   //:the number of planes
00319   unsigned nplanes_;
00320 
00321   //: the pixel format
00322   vil_pixel_format pix_fmt_;
00323 
00324   //: temporary variable for current level
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 //:Pyramid resource built on the multi-image capability of the TIFF format
00332 // If read is true then the resource is open for reading else it is open for writing
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   //: The number of planes (or components) of the image.
00341   // This method refers to the base (max resolution) image
00342   // Dimensions:  Planes x ni x nj.
00343   // This concept is treated as a synonym to components.
00344   inline virtual unsigned nplanes() const
00345   { if (levels_[0]) return levels_[0]->nplanes_; return 1; }
00346 
00347   //: The number of pixels in each row.
00348   // Dimensions:  Planes x ni x nj.
00349   inline virtual unsigned ni() const
00350   { if (levels_[0]) return levels_[0]->ni_; return 0; }
00351 
00352   //: The number of pixels in each column.
00353   // Dimensions:  Planes x ni x nj.
00354   inline virtual unsigned nj() const
00355   { if (levels_[0]) return levels_[0]->nj_; return 0; }
00356 
00357   //: Pixel Format.
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   //: Return a string describing the file format.
00362   // Only file images have a format, others return 0
00363   virtual char const* file_format() const { return "ptif"; }
00364 
00365          // --- Methods particular to pyramid resource ---
00366 
00367   //: number of pyramid levels
00368   virtual unsigned nlevels() const { return (unsigned)(levels_.size()); }
00369 
00370   //:Get a partial view from the image from a specified pyramid level
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   //:Get a partial view from the image in the pyramid closest to scale.
00376   // The origin and size parameters are in the coordinate system of the base image.
00377   // The scale factor is with respect to the base image (base scale = 1.0).
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   // Caution! The resource is assigned a header and the data is permanently
00385   // written into the file. Be sure you want to commit to the file.
00386   bool put_resource(vil_image_resource_sptr const& resc);
00387 
00388   //: returns the image resource at the specified pyramid level
00389   vil_image_resource_sptr get_resource(const unsigned level) const;
00390 
00391   //: for debug purposes
00392   void print(const unsigned level)
00393   { if (level<levels_.size()) levels_[level]->print(level); }
00394  protected:
00395   //:default constructor
00396   vil_tiff_pyramid_resource();
00397   //utility methods
00398   //:normalize the scale factors so that the base image scale = 1.0
00399   void normalize_scales();
00400 
00401   //:find the image resource with scale closest to specified scale
00402   tiff_pyramid_level* closest(const float scale) const;
00403 
00404   //: If true resource is open for read, else open for write
00405   bool read_;
00406 
00407   //: the tiff handle
00408   tif_smart_ptr t_;
00409 
00410   //The set of images in the pyramid. levels_[0] is the base image
00411   vcl_vector<tiff_pyramid_level*> levels_;
00412 }; //End of pyramid image
00413 
00414 
00415 //------------------------ Lifted from vil_nitf2_image ------------------------
00416 //            If this happens again then maybe should elevate to a
00417 //            utility class -- JLM
00418 //
00419 
00420 //:
00421 // This function does a lot of work for \sa byte_align_data().  It will strip one value
00422 // of ni bits and return it as a value of type T (with zero padding on the MSBs).
00423 // Both io and ni are lengths (in bits - not bytes).
00424 //
00425 // \param i0: Offset (in bits - not bytes) from in_val[0].  This will be the start
00426 //            of the bits extracted from in_val.
00427 // \param ni: number of bits (starting from i0) that will be extracted from in_val.
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     //strip off the appropriate bits from the vcl_left (replacing them with zeros)
00439     temp <<= strip_left;
00440     temp >>= strip_left;
00441   }
00442   if ( strip_right > 0 ){
00443     //strip off the appropriate bits from the vcl_right
00444     //the bit shift operator wasn't having the correct effect, so that'w
00445     //why the for loop
00446     for ( int i = 0 ; i < strip_right ; i++ ) temp /= 2;
00447     //temp >>= strip_right;
00448   }
00449   else if ( strip_right < 0 ){
00450     //we didn't have enough bits in the first element of the in_val array
00451     //need to get some from the next element
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     //shift right a bigger amount
00459     int new_strip_right = strip_right + (sizeof(T)*8);
00460     for ( int i = 0 ; i < new_strip_right ; i++ ) next /= 2;
00461     // next is the LSB part
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 // This function will byte align the data in in_data and store the result in out_data.  For example, let's
00475 // say that you had in_data is of type unsigned char and contains the following data: 110010111001111010000110.
00476 // In other words:
00477 // in_data[0] = 203 (11001011)
00478 // in_data[1] = 158 (10011110)
00479 // in_data[2] = 134 (10000110)
00480 // Let's further say you called this function like this: byte_align_data( in_data, 8, 3, out_data ).
00481 // Then, when the function finished, out_data would look like this:
00482 // out_data[0] = 6 (00000110)
00483 // out_data[1] = 2 (00000010)
00484 // out_data[2] = 7 (00000111)
00485 // out_data[3] = 1 (00000001)
00486 // out_data[4] = 7 (00000111)
00487 // out_data[5] = 2 (00000010)
00488 // out_data[6] = 0 (00000000)
00489 // out_data[7] = 6 (00000110)
00490 //
00491 // Basically, what the function did was group the bitstream into groups of three and then store all of the
00492 // values into out_data.  It had to zero pad all the values (on the MSB side) to get them into out_data.  That's
00493 // why out_data is bigger.
00494 //
00495 // This function works with other unsigned types of data too.  For example, let's say in_data was of type unsigned int
00496 // and contained the following bits: 0100110010111000 0111101100000000 1111000011110000 (note that this bitstream is shown
00497 // in big endian notation, that will not be the case if you are on a little endian machine -- this is just for illustration)
00498 // in other words:
00499 // in_data[0] = 19640 (0100110010111000) [shown in big endian for illustrative purposes only]
00500 // in_data[1] = 31488 (0111101100000000) [shown in big endian for illustrative purposes only]
00501 // in_data[2] = 61680 (1111000011110000) [shown in big endian for illustrative purposes only]
00502 // Let's further say, you called this function like this byte_align_data( in_data, 4, 12, out_data ).
00503 // Then out_data would be aligned along two byte (sixteen bit) boundaries and would look like this:
00504 // out_data[0] = 1227 (0000010011001011) [shown in big endian for illustrative purposes only]
00505 // out_data[1] = 2171 (0000100001111011) [shown in big endian for illustrative purposes only]
00506 // out_data[2] = 15   (0000000000001111) [shown in big endian for illustrative purposes only]
00507 // out_data[3] = 240  (0000000011110000) [shown in big endian for illustrative purposes only]
00508 //
00509 // Because of the fact that this function uses bit shifting operators, and the behavior of the vcl_right
00510 // shift operator is implementation specific when applied to a negative number, you should probably
00511 // only use this function on unsigned data.
00512 //
00513 // \param in_data: The input data.  It must be at least (num_samples*in_bits_per_sample/8) bytes long.
00514 //                The values should have the endianness of your platform.
00515 // \param num_samples: The number of actual samples in in_data.
00516 // \param in_bits_per_sample: The bits per sample in in_data
00517 // \param out_data: I'll store the output data here.  It must be at least (num_samples*sizeof(T)) bytes long
00518 //                 The values will have the endianness of your platform.
00519 //
00520 // Note that inBitsPerSampe must not be >= sizeof(T).  If they were to be equal, then this function
00521 // would have nothing to do (in_data is already byte aligned).  If in_bits_per_sample were less than sizeof(T),
00522 // then each element of out_data would be too small to store the corresponding elements in in_data.
00523 //
00524 // Note that there is a specialization for the bool case which just casts it to an 8 bit quantity then calls
00525 // this same function.  This is because the logic in get_bits<> doesn't work for the bool case.
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   //grab each value from the bitstream (in_data) that we need... one
00532   //at a time
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     //printf("bo = %i, in = %x, out =  %x\n", bit_offset, in_data[o], out_data[o]);
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_