vil_tiff_header.h
Go to the documentation of this file.
1 // This is core/vil/file_formats/vil_tiff_header.h
2 #ifndef vil_tiff_header_h_
3 #define vil_tiff_header_h_
4 //:
5 // \file
6 // \author J.L. Mundy
7 // \date 22 Dec 2005
8 // \brief A header structure for tiff files
9 //
10 // This class is responsible for extracting (putting) information
11 // from (into) the tiff header that is required to specify a vil_image_resource
12 // There are bool flags that indicate that the item has been successfully
13 // read (written) to the open tiff file.
14 //
15 // Notes:
16 // - The size of each strip can be different and less than the full
17 // strip, i.e. bytes_per_line * rows_per_strip, would require.
18 // Perhaps this case should be rejected, but
19 // it has occurred in images that IrfanView and ImageMagick CAN read.
20 // In this case, the buffers are set up with capacity for a full strip.
21 // - The number of rows in a strip can exceed the image length. The actual
22 // byte count is equal to the number of bytes in the image. In this
23 // case, the block size is truncated to the image_length.
24 // - The width and height of a tile must be a multiple of 16
25 // - The current implementation can't handle Planar Configuration =2,
26 // which is RGB in separate color bands.
27 // - If rows_per_strip is missing, it is assumed to be infinity
28 // (http://www.awaresystems.be/imaging/tiff/tifftags/rowsperstrip.html)
29 //
30 // \verbatim
31 // Modifications
32 // November 8, 2007 - Added the case of four planes that is necessary to
33 // read and write satellite multispectral image data - JLM
34 // January 9, 2012 - Use default value (1) for images that do not have SamplesPerPixel tag - GY
35 // \endverbatim
36 
37 #include <string>
38 #include <vector>
39 #include <cmath>
40 #ifdef _MSC_VER
41 # include <vcl_msvc_warnings.h>
42 #endif
43 #include <vxl_config.h>
44 #include <vil/vil_config.h>
45 #include <vil/vil_pixel_format.h>
46 #include <tiffio.h>
47 
48 struct ushort_tag
49 {
50  ushort_tag(): valid(false) {}
51  vxl_uint_16 val;
52  bool valid;
53 };
54 
55 struct ulong_tag
56 {
57  ulong_tag() : valid(false) {}
58  vxl_uint_32 val;
59  bool valid;
60 };
61 
62 // The tiff header elements (tags)
63 // planar_configuration determines the layout of many of the
64 // structures
65 // 1 - pixel samples are contiguous, e.g. RGBRGB...
66 // 2 - samples are in separate planes (analogous to vil nplanes)
68 {
69  public:
71 
72  vil_tiff_header(TIFF* tif, const unsigned ni, const unsigned nj,
73  const unsigned nplanes, vil_pixel_format const& fmt,
74  const unsigned size_block_i, const unsigned size_block_j);
75 // the baseline tiff header stucture
76  std::string artist;
77 
78  //**Issue** spec says this should be an array[samples_per_pixel] but
79  //actual multi-sample tiff file headers have this as an
80  //vxl_uint_16 CHECK (JLM)
82  vxl_uint_16 bytes_per_sample() const
83  { return bits_per_sample.valid ? static_cast<vxl_uint_16>((bits_per_sample.val + 7)/8) : 0u; }
84 
86 
88 
89  // color_map[index][pixel_sample] index ranges from 0->2^bits_per_sample-1
90  // pixel_sample 0->samples_per_pixel -1
91  std::vector<std::vector<vxl_uint_16> >color_map;
93 
95 
96  std::string copyright;
97 
98  std::string date_time;
99 
100  //Additional samples per pixel, e.g. transparency
102 
104 
105  //for gray scale data provides a radiometry map, e.g. true reflectance
106  //index ranges from 0->2^bits_per_sample-1
107  std::vector<vxl_uint_16> gray_response_curve;
109 
110  //the unit of radiometry
112 
113  std::string host_computer;
114  std::string image_description;
115 
117 
118  //:theoretical from samples per line
119  vxl_uint_32 bytes_per_line() const;
120 
121  //:As returned by the TIFF library
122  vxl_uint_32 actual_bytes_per_line() const;
123 
125 
126  unsigned nplanes;
127 
128  std::string make;
129 
131 
133 
134  std::string model;
135 
137 
139 
141 
143 
145 
146  vxl_uint_32 rows_in_strip() const;
147 
148  vxl_uint_32 strips_per_image() const
149  { return rows_per_strip.valid ?
150  static_cast<vxl_uint_32>(std::floor(1.0+(image_length.val-1)/rows_per_strip.val)) : 1L;
151  }
152 
153  //the actual size of the strip in the file
154  vxl_uint_32 actual_bytes_per_strip(const vxl_uint_32 strip_index) const;
155 
156  //the theoretical size based on rows_per_strip and bytes_per_line
157  vxl_uint_32 bytes_per_strip() const;
158 
161 
162  std::string software;
163 
164  //for planar_config = 1
165  //[st0|st1|...|strips_per_image-1]
166  //for planar_config = 2
167  //[st0|st1|...|strips_per_image-1] ... [st0|st1|...|strips_per_image-1]
168  // sample 0 ... samples_per_pixel-1
169  vxl_uint_32* strip_byte_counts;
171  vxl_uint_32* strip_offsets;
173 
175 
177 
180 
183 
184  //tiff extension for blocking
186 
188 
190 
191  //for planar_config = 1
192  //[st0|st1|...|tiles_per_image-1]
193  //for planar_config = 2
194  //[st0|st1|...|tiles_per_image-1] ... [st0|st1|...|tiles_per_image-1]
195  // sample 0 ... samples_per_pixel-1
196  vxl_uint_32* tile_offsets;
198  vxl_uint_32* tile_byte_counts;
200 
201  vxl_uint_32 tiles_across() const
202  { return tile_width.valid ?
203  static_cast<vxl_uint_32>(std::floor(1.0+(image_width.val-1)/tile_width.val)) : 0L;
204  }
205 
206  vxl_uint_32 tiles_down() const
207  { return tile_length.valid ?
208  static_cast<vxl_uint_32>(std::floor(1.0+(image_length.val-1)/tile_length.val)) : 0L;
209  }
210 
211  vxl_uint_32 tiles_per_image() const {return tiles_across()*tiles_down();}
212 
213  vxl_uint_32 bytes_per_tile() const;
214 
215  //: the actual number of separate image planes in the tiff image
216  unsigned n_separate_image_planes() const;
217 
218  //: the number of encoded bytes in a tile or strip
219  unsigned encoded_bytes_per_block() const;
220 
221  //: the number of samples in a block
222  unsigned samples_per_line() const;
223 
224  //: is the image tiled
225  bool is_tiled() const;
226 
227  //: is the image striped (one of these must be true or read failed)
228  bool is_striped() const;
229 
230 #if HAS_GEOTIFF
231  bool is_GEOTIFF() const;
232 #endif
233 
236  bits_per_sample.val%8 != 0;
237  }
238 
240 
241  //: true if the specified format can be read or written.
242  // check and return a null resource if false
244 
245  //: the number of images in the file
246  vxl_uint_16 n_images();
247  private:
248  TIFF* tif_;
249  //: read/write mode true for read.
250  // returns false if the format cannot be read by current version
251  bool read_header();
252  //:returns false if the format cannot be written by current version
253  bool set_header(unsigned ni, unsigned nj, unsigned nplanes,
254  vil_pixel_format const& fmt,
255  const unsigned size_block_i,
256  const unsigned size_block_j);
257  //:returns false if the format not handled by this reader
258  bool compute_pixel_format();
259  //:returns false if the format not handled by this writer
260  bool parse_pixel_format(vil_pixel_format const& fmt);
263 };
264 
265 #endif //vil_tiff_header_h_
vxl_uint_32 tiles_down() const
vil_pixel_format
Describes the type of the concrete data.
ushort_tag subfile_type
ulong_tag tile_length
ushort_tag thresholding
vxl_uint_32 bytes_per_line() const
theoretical from samples per line.
vxl_uint_32 tiles_per_image() const
unsigned samples_per_line() const
the number of samples in a block.
std::string copyright
vil_tiff_header(TIFF *tif)
ushort_tag cell_width
unsigned encoded_bytes_per_block() const
the number of encoded bytes in a tile or strip.
ushort_tag extra_samples
ushort_tag orientation
bool format_supported
true if the specified format can be read or written.
ushort_tag compression
vxl_uint_32 strips_per_image() const
ushort_tag sample_format
ushort_tag fill_order
vxl_uint_32 bytes_per_strip() const
vxl_uint_32 actual_bytes_per_strip(const vxl_uint_32 strip_index) const
ulong_tag rows_per_strip
vxl_uint_32 * strip_byte_counts
vxl_uint_32 * tile_byte_counts
bool is_tiled() const
is the image tiled.
vxl_uint_32 rows_in_strip() const
std::vector< vxl_uint_16 > gray_response_curve
vil_pixel_format pix_fmt
vxl_uint_32 bytes_per_tile() const
ulong_tag tile_width
ulong_tag image_length
std::string host_computer
std::string image_description
vxl_uint_16 n_images()
the number of images in the file.
std::vector< std::vector< vxl_uint_16 > > color_map
ushort_tag gray_response_unit
ushort_tag photometric
bool is_striped() const
is the image striped (one of these must be true or read failed).
bool grey_response_curve_valid
ushort_tag planar_config
std::string software
ushort_tag bits_per_sample
std::string make
vxl_uint_32 val
vxl_uint_32 tiles_across() const
std::string date_time
vxl_uint_32 actual_bytes_per_line() const
As returned by the TIFF library.
ushort_tag max_sample_value
bool parse_pixel_format(vil_pixel_format const &fmt)
returns false if the format not handled by this writer.
vxl_uint_32 * tile_offsets
ushort_tag samples_per_pixel
bool compute_pixel_format()
returns false if the format not handled by this reader.
vxl_uint_16 val
ushort_tag min_sample_value
std::string model
std::string artist
ushort_tag resolution_unit
vxl_uint_32 * strip_offsets
bool set_header(unsigned ni, unsigned nj, unsigned nplanes, vil_pixel_format const &fmt, const unsigned size_block_i, const unsigned size_block_j)
returns false if the format cannot be written by current version.
vxl_uint_16 bytes_per_sample() const
ulong_tag image_width
ushort_tag cell_length
unsigned n_separate_image_planes() const
the actual number of separate image planes in the tiff image.
bool read_header()
read/write mode true for read.