libpniio
strip_reader.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: Jun 22, 2011
21 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
22 //
23 //
24 #pragma once
25 
26 #include <iostream>
27 #include <fstream>
28 #include <vector>
29 
30 #include "ifd.hpp"
31 #include "../image_info.hpp"
32 
33 #include <pni/core/types.hpp>
34 #include <pni/core/arrays.hpp>
35 
36 
37 namespace pni {
38 namespace io {
39 namespace tiff {
40 
43  class strip_reader
44  {
45  private:
46  std::vector<size_t> _offsets;
47  std::vector<size_t> _byte_cnts;
48  std::vector<size_t> _bits_per_channel;
49  std::vector<pni::core::type_id_t> _channel_types;
50 
51  //-----------------------------------------------------------------
67  template<
68  typename IT,
69  typename CTYPE
70  >
71  void _read_interlace(size_t c,std::ifstream &stream,
72  CTYPE &data) const;
73 
74  public:
75  //====================constructors and destructor==================
77  strip_reader();
78 
79  //-----------------------------------------------------------------
81  strip_reader(const strip_reader &r);
82 
83  //-----------------------------------------------------------------
86 
87  //-----------------------------------------------------------------
98  strip_reader(const std::vector<size_t> &offsets,
99  const std::vector<size_t> &byte_counts,
100  const std::vector<size_t> &bits_per_channel,
101  const std::vector<pni::core::type_id_t> &channel_types);
102 
103  //------------------------------------------------------------------
105  ~strip_reader();
106 
107  //====================assignemnt operators==========================
110 
111  //------------------------------------------------------------------
114 
115  //===========static public member functions=========================
128  static strip_reader create(std::ifstream &stream,
129  const ifd &image_dir,
130  const image_info &info);
131 
132  //=====================public member methods========================
146  template<typename CTYPE>
147  void read(size_t c,std::ifstream &stream,CTYPE &data)
148  {
149  using namespace pni::core;
150  //first we need to determine the datatype of the
151 
152  if(this->_channel_types[c] == type_id_t::UINT8)
153  this->_read_interlace<uint8>(c,stream,data);
154  else if(this->_channel_types[c] == type_id_t::INT8)
155  this->_read_interlace<int8>(c,stream,data);
156  else if(this->_channel_types[c] == type_id_t::UINT16)
157  this->_read_interlace<uint16>(c,stream,data);
158  else if(this->_channel_types[c] == type_id_t::INT16)
159  this->_read_interlace<int16>(c,stream,data);
160  else if(this->_channel_types[c] == type_id_t::UINT32)
161  this->_read_interlace<uint32>(c,stream,data);
162  else if(this->_channel_types[c] == type_id_t::INT32)
163  this->_read_interlace<int32>(c,stream,data);
164  else if(this->_channel_types[c] == type_id_t::UINT64)
165  this->_read_interlace<uint64>(c,stream,data);
166  else if(this->_channel_types[c] == type_id_t::INT64)
167  this->_read_interlace<int64>(c,stream,data);
168  else if(this->_channel_types[c] == type_id_t::FLOAT32)
169  this->_read_interlace<float32>(c,stream,data);
170  else if(this->_channel_types[c] == type_id_t::FLOAT64)
171  this->_read_interlace<float64>(c,stream,data);
172  else
173  throw type_error(EXCEPTION_RECORD,
174  "StripReader cannot handle channel type!");
175  }
176 
177  //=====================output operator==============================
179  friend std::ostream &operator<<(std::ostream &o,
180  const strip_reader &r);
181  };
182 
183  //-------------------------------------------------------------------------
184  template<typename IT,typename CTYPE>
185  void strip_reader::_read_interlace(size_t channel,
186  std::ifstream &stream,CTYPE &data) const
187  {
188  typedef typename CTYPE::value_type value_type;
189  //compute the size of a pixel in bytes
190  size_t pixel_size = std::accumulate(_bits_per_channel.begin(),
191  _bits_per_channel.end(),0)/8;
192 
193  //compute the offset from the begining of a pixel to the requested
194  //sample. The offset is given in bytes
195  size_t sample_offset = std::accumulate(_bits_per_channel.begin(),
196  _bits_per_channel.begin()+channel,
197  0)/8;
198 
199  //size of the sample type
200  size_t sample_size = sizeof(IT);
201 
202  IT sample_buffer;
203 
204  typename CTYPE::iterator piter = data.begin(); //pixel iterator
205  while(piter != data.end())
206  {
207  //loop over all strips
208  for(size_t strip=0;strip<_offsets.size();strip++)
209  {
210  size_t npixels = _byte_cnts[strip]/pixel_size;
211 
212  //set the stream to the offset of the actual strip
213  stream.seekg(_offsets[strip]+sample_offset,std::ios::beg);
214 
215  //loop over all pixels in the strip
216  for(size_t i=0;i<npixels; ++i)
217  {
218  stream.read(reinterpret_cast<char*>(&sample_buffer),sample_size);
219  stream.seekg(pixel_size-sample_size,std::ios::cur);
220  *piter++ = value_type(sample_buffer);
221  }
222  }
223  }
224  }
225 
226 
227 //end of namespace
228 }
229 }
230 }
void _read_interlace(size_t c, std::ifstream &stream, CTYPE &data) const
template to read interlace data
Definition: strip_reader.hpp:185
friend std::ostream & operator<<(std::ostream &o, const strip_reader &r)
output operator
Definition: strip_reader.cpp:109
image information type
Definition: image_info.hpp:43
std::vector< size_t > _byte_cnts
array with byte counts for each strip
Definition: strip_reader.hpp:47
std::vector< size_t > _offsets
array with the file offsets of the strips
Definition: strip_reader.hpp:46
static strip_reader create(std::ifstream &stream, const ifd &image_dir, const image_info &info)
create StripReader instance
Definition: strip_reader.cpp:97
void read(size_t c, std::ifstream &stream, CTYPE &data)
template to read image data of various type
Definition: strip_reader.hpp:147
std::string strip(std::string &s, const char *begrem="\n ", const char *endrem=" \n")
strips a string
Definition: strutils.cpp:12
Definition: cbf_reader.hpp:41
std::vector< pni::core::type_id_t > _channel_types
type ids of channel data
Definition: strip_reader.hpp:49
strip_reader & operator=(const strip_reader &r)
copy assignment operator
Definition: strip_reader.cpp:72
strip_reader()
default constructor
Definition: strip_reader.cpp:33
IFD - Image File Directory class.
Definition: ifd.hpp:57
~strip_reader()
destructor
Definition: strip_reader.cpp:67
std::vector< size_t > _bits_per_channel
number of bits per channel
Definition: strip_reader.hpp:48
reader for strip data in a TIFF file
Definition: strip_reader.hpp:43