core/vil/file_formats/vil_tiff_header.h
Go to the documentation of this file.
00001 // This is core/vil/file_formats/vil_tiff_header.h
00002 #ifndef vil_tiff_header_h_
00003 #define vil_tiff_header_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author    J.L. Mundy
00010 // \date 22 Dec 2005
00011 // \brief A header structure for tiff files
00012 //
00013 // This class is responsible for extracting (putting) information
00014 // from (into) the tiff header that is required to specify a vil_image_resource
00015 // There are bool flags that indicate that the item has been successfuly
00016 // read (written) to the open tiff file.
00017 //
00018 // Notes:
00019 //   -  The size of each strip can be different and less than the full
00020 //      strip, i.e. bytes_per_line * rows_per_strip, would require.
00021 //      Perhaps this case should be rejected, but
00022 //      it has occurred in images that IrfanView and ImageMagick CAN read.
00023 //      In this case, the buffers are set up with capacity for a full strip.
00024 //   -  The number of rows in a strip can exceed the image length. The actual
00025 //      byte count is equal to the number of bytes in the image. In this
00026 //      case, the block size is truncated to the image_length.
00027 //   -  The width and height of a tile must be a multiple of 16
00028 //   -  The current implementation can't handle Planar Configuration =2,
00029 //      which is RGB in separate color bands.
00030 //   -  If rows_per_strip is missing, it is assumed to be infinity
00031 //      (http://www.awaresystems.be/imaging/tiff/tifftags/rowsperstrip.html)
00032 //
00033 // \verbatim
00034 //  Modifications
00035 //   November 8, 2007 - Added the case of four planes that is necessary to
00036 //                      read and write satellite multispectral image data - JLM
00037 // \endverbatim
00038 
00039 #include <vcl_string.h>
00040 #include <vcl_vector.h>
00041 #include <vxl_config.h>
00042 #include <vcl_cmath.h>
00043 #include <vil/vil_config.h>
00044 #include <vil/vil_pixel_format.h>
00045 #include <tiffio.h>
00046 
00047 struct ushort_tag
00048 {
00049   ushort_tag(): valid(false) {}
00050   vxl_uint_16 val;
00051   bool valid;
00052 };
00053 
00054 struct ulong_tag
00055 {
00056   ulong_tag() : valid(false) {}
00057   vxl_uint_32 val;
00058   bool valid;
00059 };
00060 
00061 // The tiff header elements (tags)
00062 // planar_configuration determines the layout of many of the
00063 // structures
00064 //  1 - pixel samples are contiguous, e.g. RGBRGB...
00065 //  2 - samples are in separate planes (analogous to vil nplanes)
00066 class vil_tiff_header
00067 {
00068  public:
00069   vil_tiff_header(TIFF* tif): tif_(tif) {format_supported = read_header();}
00070 
00071   vil_tiff_header(TIFF* tif, const unsigned ni, const unsigned nj,
00072                   const unsigned nplanes, vil_pixel_format const& fmt,
00073                   const unsigned size_block_i, const unsigned size_block_j);
00074 // the baseline tiff header stucture
00075   vcl_string artist;
00076 
00077   //**Issue** spec says this should be an array[samples_per_pixel] but
00078   //actual multi-sample tiff file headers have this as an
00079   //vxl_uint_16 CHECK (JLM)
00080   ushort_tag bits_per_sample;
00081   vxl_uint_16 bytes_per_sample() const
00082   { return bits_per_sample.valid ? static_cast<vxl_uint_16>((bits_per_sample.val + 7)/8) : 0u; }
00083 
00084   ushort_tag cell_length;
00085 
00086   ushort_tag cell_width;
00087 
00088   // color_map[index][pixel_sample] index ranges from 0->2^bits_per_sample-1
00089   // pixel_sample 0->samples_per_pixel -1
00090   vcl_vector<vcl_vector<vxl_uint_16> >color_map;
00091   bool color_map_valid;
00092 
00093   ushort_tag compression;
00094 
00095   vcl_string copyright;
00096 
00097   vcl_string date_time;
00098 
00099   //Additional samples per pixel, e.g. transparency
00100   ushort_tag extra_samples;
00101 
00102   ushort_tag fill_order;
00103 
00104   //for gray scale data provides a radiometry map, e.g. true reflectance
00105   //index ranges from 0->2^bits_per_sample-1
00106   vcl_vector<vxl_uint_16> gray_response_curve;
00107   bool grey_response_curve_valid;
00108 
00109   //the unit of radiometry
00110   ushort_tag gray_response_unit;
00111 
00112   vcl_string host_computer;
00113   vcl_string image_description;
00114 
00115   ulong_tag image_length;
00116 
00117   //:theoretical from samples per line
00118   vxl_uint_32 bytes_per_line() const;
00119 
00120   //:As returned by the TIFF library
00121   vxl_uint_32 actual_bytes_per_line() const;
00122 
00123   ulong_tag image_width;
00124 
00125   unsigned nplanes;
00126 
00127   vcl_string make;
00128 
00129   ushort_tag max_sample_value;
00130 
00131   ushort_tag min_sample_value;
00132 
00133   vcl_string model;
00134 
00135   ushort_tag orientation;
00136 
00137   ushort_tag photometric;
00138 
00139   ushort_tag planar_config;
00140 
00141   ushort_tag resolution_unit;
00142 
00143   ulong_tag rows_per_strip;
00144 
00145   vxl_uint_32 rows_in_strip() const;
00146 
00147   vxl_uint_32 strips_per_image() const
00148   { return rows_per_strip.valid ?
00149       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_length.val-1)/rows_per_strip.val)) : 1L;
00150   }
00151 
00152   //the acutal size of the strip in the file
00153   vxl_uint_32 actual_bytes_per_strip(const vxl_uint_32 strip_index) const;
00154 
00155   //the theoretical size based on rows_per_strip and bytes_per_line
00156  vxl_uint_32 bytes_per_strip() const;
00157 
00158   ushort_tag sample_format;
00159   ushort_tag samples_per_pixel;
00160 
00161   vcl_string software;
00162 
00163   //for planar_config = 1
00164   //[st0|st1|...|strips_per_image-1]
00165   //for planar_config = 2
00166   //[st0|st1|...|strips_per_image-1] ... [st0|st1|...|strips_per_image-1]
00167   //          sample 0               ...         samples_per_pixel-1
00168   vxl_uint_32* strip_byte_counts;
00169   bool strip_byte_counts_valid;
00170   vxl_uint_32* strip_offsets;
00171   bool strip_offsets_valid;
00172 
00173   ushort_tag subfile_type;
00174 
00175   ushort_tag thresholding;
00176 
00177   double x_resolution;
00178   bool x_resolution_valid;
00179 
00180   double y_resolution;
00181   bool y_resolution_valid;
00182 
00183   //tiff extension for blocking
00184   bool is_tiled_flag;
00185 
00186   ulong_tag tile_width;
00187 
00188   ulong_tag tile_length;
00189 
00190   //for planar_config = 1
00191   //[st0|st1|...|tiles_per_image-1]
00192   //for planar_config = 2
00193   //[st0|st1|...|tiles_per_image-1] ... [st0|st1|...|tiles_per_image-1]
00194   //          sample 0               ...         samples_per_pixel-1
00195   vxl_uint_32*  tile_offsets;
00196   bool tile_offsets_valid;
00197   vxl_uint_32* tile_byte_counts;
00198   bool tile_byte_counts_valid;
00199 
00200   vxl_uint_32 tiles_across() const
00201   { return tile_width.valid ?
00202       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_width.val-1)/tile_width.val)) : 0L;
00203   }
00204 
00205   vxl_uint_32 tiles_down() const
00206   { return tile_length.valid ?
00207       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_length.val-1)/tile_length.val)) : 0L;
00208   }
00209 
00210   vxl_uint_32 tiles_per_image() const {return tiles_across()*tiles_down();}
00211 
00212   vxl_uint_32 bytes_per_tile() const;
00213 
00214   //: the actual number of separate image planes in the tiff image
00215   unsigned n_separate_image_planes() const;
00216 
00217   //: the number of encoded bytes in a tile or strip
00218   unsigned encoded_bytes_per_block() const;
00219 
00220   //: the number of samples in a block
00221   unsigned samples_per_line() const;
00222 
00223   //: is the image tiled
00224   bool is_tiled() const;
00225 
00226   //: is the image striped (one of these must be true or read failed)
00227   bool is_striped() const;
00228 
00229 #if HAS_GEOTIFF
00230   bool is_GEOTIFF() const;
00231 #endif
00232 
00233   bool need_byte_swap()
00234   { return file_is_big_endian_!=machine_is_big_endian_ &&
00235            bits_per_sample.val%8 != 0;
00236   }
00237 
00238   vil_pixel_format pix_fmt;
00239 
00240   //: true if the specified format can be read or written.
00241   // check and return a null resource if false
00242   bool format_supported;
00243 
00244   //: the number of images in the file
00245   vxl_uint_16  n_images();
00246  private:
00247   TIFF* tif_;
00248   //: read/write mode true for read.
00249   // returns false if the format cannot be read by current version
00250   bool read_header();
00251   //:returns false if the format cannot be written by current version
00252   bool set_header(unsigned ni, unsigned nj, unsigned nplanes,
00253                   vil_pixel_format const& fmt,
00254                   const unsigned size_block_i,
00255                   const unsigned size_block_j);
00256   //:returns false if the format not handled by this reader
00257   bool compute_pixel_format();
00258   //:returns false if the format not handled by this writer
00259   bool parse_pixel_format(vil_pixel_format const& fmt);
00260   bool file_is_big_endian_;
00261   bool machine_is_big_endian_;
00262 };
00263 
00264 #endif //vil_tiff_header_h_