Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

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 05
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 //
00031 // \verbatim
00032 //  Modifications
00033 //   November 8, 2007 - Added the case of four planes that is necessary to
00034 //                      read and write satellite multispectral image data - JLM
00035 // \endverbatim
00036 
00037 #include <vcl_string.h>
00038 #include <vcl_vector.h>
00039 #include <vxl_config.h>
00040 #include <vcl_cmath.h>
00041 #include <vil/vil_config.h>
00042 #include <vil/vil_pixel_format.h>
00043 #include <tiffio.h>
00044 
00045 struct ushort_tag
00046 {
00047   ushort_tag(): valid(false) {}
00048   vxl_uint_16 val;
00049   bool valid;
00050 };
00051 
00052 struct ulong_tag
00053 {
00054   ulong_tag() : valid(false) {}
00055   vxl_uint_32 val;
00056   bool valid;
00057 };
00058 
00059 // The tiff header elements (tags)
00060 // planar_configuration determines the layout of many of the
00061 // structures
00062 //  1 - pixel samples are contiguous, e.g. RGBRGB...
00063 //  2 - samples are in separate planes (analogous to vil nplanes)
00064 class vil_tiff_header
00065 {
00066  public:
00067   vil_tiff_header(TIFF* tif): tif_(tif) {format_supported = read_header();}
00068 
00069   vil_tiff_header(TIFF* tif, const unsigned ni, const unsigned nj,
00070                   const unsigned nplanes, vil_pixel_format const& fmt,
00071                   const unsigned size_block_i, const unsigned size_block_j);
00072 // the baseline tiff header stucture
00073   vcl_string artist;
00074 
00075   //**Issue** spec says this should be an array[samples_per_pixel] but
00076   //actual multi-sample tiff file headers have this as an
00077   //vxl_uint_16 CHECK (JLM)
00078   ushort_tag bits_per_sample;
00079   vxl_uint_16 bytes_per_sample() const
00080     { return bits_per_sample.valid ? (bits_per_sample.val + 7)/8 : 0; }
00081 
00082   ushort_tag cell_length;
00083 
00084   ushort_tag cell_width;
00085 
00086   // color_map[index][pixel_sample] index ranges from 0->2^bits_per_sample-1
00087   // pixel_sample 0->samples_per_pixel -1
00088   vcl_vector<vcl_vector<vxl_uint_16> >color_map;
00089   bool color_map_valid;
00090 
00091   ushort_tag compression;
00092 
00093   vcl_string copyright;
00094 
00095   vcl_string date_time;
00096 
00097   //Additional samples per pixel, e.g. transparency
00098   ushort_tag extra_samples;
00099 
00100   ushort_tag fill_order;
00101 
00102   //for gray scale data provides a radiometry map, e.g. true reflectance
00103   //index ranges from 0->2^bits_per_sample-1
00104   vcl_vector<vxl_uint_16> gray_response_curve;
00105   bool grey_response_curve_valid;
00106 
00107   //the unit of radiometry
00108   ushort_tag gray_response_unit;
00109 
00110   vcl_string host_computer;
00111   vcl_string image_description;
00112 
00113   ulong_tag image_length;
00114 
00115   //:theoretical from samples per line
00116   vxl_uint_32 bytes_per_line() const;
00117 
00118   //:As returned by the TIFF library
00119   vxl_uint_32 actual_bytes_per_line() const;
00120 
00121   ulong_tag image_width;
00122 
00123   unsigned nplanes;
00124 
00125   vcl_string make;
00126 
00127   ushort_tag max_sample_value;
00128 
00129   ushort_tag min_sample_value;
00130 
00131   vcl_string model;
00132 
00133   ushort_tag orientation;
00134 
00135   ushort_tag photometric;
00136 
00137   ushort_tag planar_config;
00138 
00139   ushort_tag resolution_unit;
00140 
00141   ulong_tag rows_per_strip;
00142 
00143   vxl_uint_32 rows_in_strip() const;
00144 
00145   vxl_uint_32 strips_per_image() const
00146   { return rows_per_strip.valid ?
00147       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_length.val-1)/rows_per_strip.val)) : 0L;
00148   }
00149 
00150   //the acutal size of the strip in the file
00151   vxl_uint_32 actual_bytes_per_strip(const vxl_uint_32 strip_index) const;
00152 
00153   //the theoretical size based on rows_per_strip and bytes_per_line
00154  vxl_uint_32 bytes_per_strip() const;
00155 
00156   ushort_tag sample_format;
00157   ushort_tag samples_per_pixel;
00158 
00159   vcl_string software;
00160 
00161   //for planar_config = 1
00162   //[st0|st1|...|strips_per_image-1]
00163   //for planar_config = 2
00164   //[st0|st1|...|strips_per_image-1] ... [st0|st1|...|strips_per_image-1]
00165   //          sample 0               ...         samples_per_pixel-1
00166   vxl_uint_32* strip_byte_counts;
00167   bool strip_byte_counts_valid;
00168   vxl_uint_32* strip_offsets;
00169   bool strip_offsets_valid;
00170 
00171   ushort_tag subfile_type;
00172 
00173   ushort_tag thresholding;
00174 
00175   double x_resolution;
00176   bool x_resolution_valid;
00177 
00178   double y_resolution;
00179   bool y_resolution_valid;
00180 
00181   //tiff extension for blocking
00182   bool is_tiled_flag;
00183 
00184   ulong_tag tile_width;
00185 
00186   ulong_tag tile_length;
00187 
00188   //for planar_config = 1
00189   //[st0|st1|...|tiles_per_image-1]
00190   //for planar_config = 2
00191   //[st0|st1|...|tiles_per_image-1] ... [st0|st1|...|tiles_per_image-1]
00192   //          sample 0               ...         samples_per_pixel-1
00193   vxl_uint_32*  tile_offsets;
00194   bool tile_offsets_valid;
00195   vxl_uint_32* tile_byte_counts;
00196   bool tile_byte_counts_valid;
00197 
00198   vxl_uint_32 tiles_across() const
00199   { return tile_width.valid ?
00200       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_width.val-1)/tile_width.val)) : 0L;
00201   }
00202 
00203   vxl_uint_32 tiles_down() const
00204   { return tile_length.valid ?
00205       static_cast<vxl_uint_32>(vcl_floor(1.0+(image_length.val-1)/tile_length.val)) : 0L;
00206   }
00207 
00208   vxl_uint_32 tiles_per_image() const {return tiles_across()*tiles_down();}
00209 
00210   vxl_uint_32 bytes_per_tile() const;
00211 
00212   //: the actual number of separate image planes in the tiff image
00213   unsigned n_separate_image_planes() const;
00214 
00215   //: the number of encoded bytes in a tile or strip
00216   unsigned encoded_bytes_per_block() const;
00217 
00218   //: the number of samples in a block
00219   unsigned samples_per_line() const;
00220 
00221   //: is the image tiled
00222   bool is_tiled() const;
00223 
00224   //: is the image striped (one of these must be true or read failed)
00225   bool is_striped() const;
00226 
00227 #if HAS_GEOTIFF
00228   bool is_GEOTIFF() const;
00229 #endif
00230 
00231   bool need_byte_swap()
00232   { return file_is_big_endian_!=machine_is_big_endian_ &&
00233            bits_per_sample.val%8 != 0;
00234   }
00235 
00236   vil_pixel_format pix_fmt;
00237 
00238   //: true if the specified format can be read or written.
00239   // check and return a null resource if false
00240   bool format_supported;
00241 
00242   //: the number of images in the file
00243   vxl_uint_16  n_images();
00244  private:
00245   TIFF* tif_;
00246   //: read/write mode true for read.
00247   // returns false if the format cannot be read by current version
00248   bool read_header();
00249   //:returns false if the format cannot be written by current version
00250   bool set_header(unsigned ni, unsigned nj, unsigned nplanes,
00251                   vil_pixel_format const& fmt,
00252                   const unsigned size_block_i,
00253                   const unsigned size_block_j);
00254   //:returns false if the format not handled by this reader
00255   bool compute_pixel_format();
00256   //:returns false if the format not handled by this writer
00257   bool parse_pixel_format(vil_pixel_format const& fmt);
00258   bool file_is_big_endian_;
00259   bool machine_is_big_endian_;
00260 };
00261 
00262 #endif //vil_tiff_header_h_

Generated on Thu Jan 10 14:40:00 2008 for core/vil by  doxygen 1.4.4