libpniio
ifd_entry.hpp
Go to the documentation of this file.
1 //
2 // (c) Copyright 2011 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpniio.
5 //
6 // libpniio is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpniio is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpniio. If not, see <http://www.gnu.org/licenses/>.
18 // ===========================================================================
19 //
20 // Created on: Apr 24, 2012
21 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
22 //
23 //
24 #pragma once
25 
26 #include <iostream>
27 #include <fstream>
28 #include <map>
29 #include <boost/current_function.hpp>
30 
31 #include <pni/core/types.hpp>
32 #include <pni/core/error.hpp>
33 #include "rational.hpp"
34 #include "ifd_entry_reader.hpp"
35 
36 using namespace pni::core;
37 
38 namespace pni{
39 namespace io{
40 namespace tiff{
41 
42  //possible data values of an IFD entry according to the TIFF standard
43  enum class ifd_entry_type_id
44  {
45  BYTE,
46  ASCII,
47  SHORT,
48  LONG,
49  RATIONAL,
50  SBYTE,
51  UNDEFINED,
52  SSHORT,
53  SLONG,
54  SRATIONAL,
55  FLOAT,
56  DOUBLE
57  };
58 
59 #ifdef ENUMBUG
61  bool operator>(ifd_entry_type_id a,ifd_entry_type_id b);
62  bool operator<=(ifd_entry_type_id a,ifd_entry_type_id b);
63  bool operator>=(ifd_entry_type_id a,ifd_entry_type_id b);
64 #endif
65 
72  class ifd_entry
73  {
74  private:
75  uint16 _tag;
77  size_t _size;
78  std::streampos _data;
79 
80  //===============private methods===================================
93  template<typename T>
94  void _read_entry_data(std::vector<T> &r,std::ifstream &stream);
95 
96  //----------------------------------------------------------------
107  void _read_entry_data(std::vector<string> &r,std::ifstream &stream);
108 
109  public:
110  //=============constructors and destructor=========================
112  ifd_entry();
113 
114  //-----------------------------------------------------------------
116  ifd_entry(const ifd_entry &e);
117 
118  //-----------------------------------------------------------------
120  ifd_entry(ifd_entry &&e);
121 
122  //-----------------------------------------------------------------
133  ifd_entry(uint16 tag,ifd_entry_type_id tid,size_t size,
134  std::streampos data);
135 
136  //-----------------------------------------------------------------
138  ~ifd_entry();
139 
140  //=====================assignment operators========================
142  ifd_entry &operator=(const ifd_entry &e);
143 
145  ifd_entry &operator=(ifd_entry &&e);
146 
147  //===============static methods====================================
157  static ifd_entry create_from_stream(std::ifstream &stream);
158 
159  //==================class methods==================================
166  size_t size() const;
167 
168  //-----------------------------------------------------------------
175  string name() const;
176 
177  //-----------------------------------------------------------------
184  type_id_t type_id() const;
185 
186  //-----------------------------------------------------------------
200  template<typename T> std::vector<T> value(std::ifstream &stream);
201 
202  //-----------------------------------------------------------------
204  friend std::ostream &operator<<(std::ostream &o,const ifd_entry &e);
205 
206  };
207 
208 
209  //==============implementation of public template methods===================
210  template<typename T> std::vector<T> ifd_entry::value(std::ifstream &stream)
211  {
212  //create a vector of appropriate length
213  std::vector<T> result(this->size());
214  //save the original stream position
215  std::streampos orig_stream_pos = stream.tellg();
216 
217  //set the stream to the begining of the data section
218  stream.seekg(this->_data,std::ios::beg);
219 
220  //here comes the tricky part. Though the user defines the type T he
221  //wants to have the IFD entry not all entry types can be converted to T
222  //without loss of information. Thus wee need a selection function that
223  //picks for each T all acceptable types and throws an exception if the
224  //entry is of an incompatible type.
225  //
226  //This operation is carried out by the next function which cann choose
227  //the proper version by argument type deduction.
228  try{
229  this->_read_entry_data(result,stream);
230  }
231  catch(type_error &e)
232  {
233  e.append(EXCEPTION_RECORD);
234  //reset the stream to its original position
235  stream.seekg(orig_stream_pos,std::ios::beg);
236  throw e;
237  }
238 
239 
240  //reset stream to its original position
241  stream.seekg(orig_stream_pos,std::ios::beg);
242 
243  return result;
244  }
245 
246  //--------------------------------------------------------------------------
247  template<typename T> void ifd_entry::
248  _read_entry_data(std::vector<T> &r,std::ifstream &stream)
249  {
250  if(this->_tid == ifd_entry_type_id::BYTE)
252  else if(this->_tid == ifd_entry_type_id::SHORT)
254  else if(this->_tid == ifd_entry_type_id::LONG)
256  else if(this->_tid == ifd_entry_type_id::RATIONAL)
258  else if(this->_tid == ifd_entry_type_id::SBYTE)
260  else if(this->_tid == ifd_entry_type_id::SSHORT)
262  else if(this->_tid == ifd_entry_type_id::SLONG)
264  else if(this->_tid == ifd_entry_type_id::SRATIONAL)
266  else if(this->_tid == ifd_entry_type_id::FLOAT)
268  else if(this->_tid == ifd_entry_type_id::DOUBLE)
270  else
271  //reset stream position
272  throw type_error(EXCEPTION_RECORD,"IFD entry ["+this->name()+
273  "] contains unknown data!");
274  }
275 
276 
277 //end of namespace
278 }
279 }
280 }
281 
std::ostream & operator<<(std::ostream &o, const column_info &ci)
Definition: column_info.cpp:95
string of 8Bit values with binary terminated with a binary 0
std::streampos _data
marks data position
Definition: ifd_entry.hpp:78
size_t size(const selection &s) noexcept
get selection size
Definition: selection.cpp:181
pni::core::type_id_t type_id(const h5datatype &o)
get type code
Definition: h5datatype.cpp:240
Definition: cbf_reader.hpp:41
class for IFD entries
Definition: ifd_entry.hpp:72
bool operator<(const index_value_type &lhs, const index_value_type &rhs)
comparison operator for index_value_type
Definition: dimensions.cpp:36
IFD entry reader template.
Definition: ifd_entry_reader.hpp:48
uint16 _tag
ID of the entry.
Definition: ifd_entry.hpp:75
ifd_entry_type_id _tid
type id of the entry
Definition: ifd_entry.hpp:76
void read(const OTYPE< IMPID > &o, ATYPE &a)
read data
Definition: read.hpp:63
size_t _size
number of elements of the entry
Definition: ifd_entry.hpp:77
ifd_entry_type_id
Definition: ifd_entry.hpp:43