VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
grvectors.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file grvectors.h
19 ///
20 
21 #ifndef GR_VECTORS__H
22 #define GR_VECTORS__H
23 
24 #include "gdef.h"
25 #include "grdef.h"
26 #include "grtraits.h"
27 #include "glimits.h"
28 #include "ghexdump.h"
29 #include <iostream>
30 #include <streambuf>
31 #include <algorithm>
32 #include <utility>
33 #include <vector>
34 
35 namespace Gr
36 {
37  /// A candidate for Gr::ImageBuffer that uses nested std::vectors.
38  ///
39  typedef std::vector<std::vector<char> > Vectors ;
40 
41  /// \namespace Gr::imp
42  /// A private implementation namespace.
43  ///
44  namespace imp
45  {
46  class vectors_const_byte_iterator ;
47  class vectors_streambuf ;
48  }
49 
50  /// \namespace Gr::traits
51  /// A namespace for traits classes.
52  ///
53  namespace traits
54  {
55  template <>
56  struct imagebuffer<Vectors> /// Specialisation for Gr::Vectors.
57  {
58  typedef imp::vectors_streambuf streambuf_type ;
59  typedef imp::vectors_const_byte_iterator const_byte_iterator ;
60  typedef Vectors::iterator row_iterator ;
61  typedef Vectors::const_iterator const_row_iterator ;
62  } ;
63  }
64 
65  /// \namespace Gr::imagebuffer
66  /// A namespace for low-level free functions that operate on container
67  /// classes that are Gr::ImageBuffer candidates.
68  ///
69  namespace imagebuffer
70  {
71  size_t size_of( const Vectors & vectors ) ;
72  void resize( Vectors & vectors , int dx , int dy , int channels ) ;
73  imp::vectors_const_byte_iterator bytes_begin( const Vectors & vectors ) ;
74  imp::vectors_const_byte_iterator bytes_end( const Vectors & ) ;
75  bool row_empty( Vectors::iterator row_p ) ;
76  void row_resize( Vectors::iterator row_p , size_t n ) ;
77  Vectors::iterator row_erase( Vectors & vectors , Vectors::iterator row_p ) ;
78  Vectors::const_iterator row_begin( const Vectors & vectors ) ;
79  Vectors::iterator row_begin( Vectors & vectors ) ;
80  Vectors::const_iterator row_end( const Vectors & vectors ) ;
81  Vectors::iterator row_end( Vectors & vectors ) ;
82  Vectors::iterator row_add( Vectors & vectors ) ;
83  char * row_ptr( Vectors::iterator row_p ) ;
84  const char * row_ptr( Vectors::const_iterator row_p ) ;
85  size_t row_size( Vectors::const_iterator row_p ) ;
86  }
87 }
88 std::istream & operator>>( std::istream & stream , Gr::Vectors & ) ;
89 std::ostream & operator<<( std::ostream & stream , const Gr::Vectors & ) ;
90 
91 /// \class Gr::imp::vectors_streambuf
92 /// A simple, read-only streambuf for Gr::Vectors.
93 ///
94 class Gr::imp::vectors_streambuf : public std::streambuf
95 {
96 public:
97  explicit vectors_streambuf( const Vectors & ) ;
98  ///< Constructor.
99 
100  virtual ~vectors_streambuf() ;
101  ///< Destructor.
102 
103  virtual std::streamsize xsgetn( char * s , std::streamsize n ) override ;
104  ///< Override from std::streambuf.
105 
106  virtual std::streampos seekpos( std::streampos pos , std::ios_base::openmode which ) override ;
107  ///< Override from std::streambuf.
108 
109  virtual std::streampos seekoff( std::streamoff off , std::ios_base::seekdir way , std::ios_base::openmode which ) override ;
110  ///< Override from std::streambuf.
111 
112  virtual int underflow() override ;
113  ///< Override from std::streambuf.
114 
115 private:
117  void operator=( const vectors_streambuf & ) ;
118  void setg_imp( const char * , const char * , const char * ) ;
119  std::streampos pos() const ;
120  std::streampos seek( std::streamoff off ) ;
121  bool next_buf() ;
122  const char * cbuf_head() const ;
123  const char * cbuf_tail() const ;
124  size_t cbuf_available() const ;
125  size_t cbuf_available( const char * ) const ;
126  size_t cbuf_offset() const ;
127  size_t cbuf_offset( const char * ) const ;
128 
129 private:
130  const Vectors & m_vectors ;
131  Vectors::const_iterator m_current ;
132  Vectors::const_iterator m_end ;
133  std::streampos m_size ;
134 } ;
135 
136 /// \class Gr::imp::vectors_const_byte_iterator
137 /// A forward byte-by-byte input iterator for Gr::ImageVectors.
138 ///
140 {
141 public:
143  ///< Default constructor for an end iterator.
144 
145  explicit vectors_const_byte_iterator( const Vectors & ) ;
146  ///< Constructor.
147 
148  char operator*() const ;
149  ///< Dereference operator.
150 
152  ///< Preincrement operator.
153 
155  ///< Postfix preincrement operator.
156 
157  bool operator==( const vectors_const_byte_iterator & ) const ;
158  ///< Equality operator.
159 
160  bool operator!=( const vectors_const_byte_iterator & ) const ;
161  ///< Inequality operator.
162 
163 private:
164  const Vectors * m_vectors ;
165  Vectors::const_iterator m_current ;
166  size_t m_current_offset ;
167  size_t m_offset ;
168 } ;
169 
170 
171 namespace G
172 {
173  template <int N>
174  imp::hexdump_streamable<N,Gr::Vectors,typename imp::hexdump_tohex,typename imp::hexdump_toprintable>
175  hexdump( const Gr::Vectors & v )
176  {
177  typedef Gr::imp::vectors_const_byte_iterator iterator ;
178  iterator begin( v ) ;
179  iterator const end ;
180  return hexdump<N>( begin , end ) ;
181  }
182 }
183 
184 
185 inline
186 size_t Gr::imagebuffer::size_of( const Vectors & vectors )
187 {
188  size_t n = 0U ;
189  add_size< std::vector<char> > adder( n ) ;
190  std::for_each( vectors.begin() , vectors.end() , adder ) ;
191  return n ;
192 }
193 
194 inline
195 void Gr::imagebuffer::resize( Vectors & vectors , int dx , int dy , int channels )
196 {
197  if( dx > 0 && dy > 0 && channels > 0 )
198  {
199  vectors.resize( dy ) ;
200  size_t drow = sizet(dx,channels) ;
201  for( int y = 0 ; y < dy ; y++ )
202  {
203  vectors.at(y).resize( drow ) ;
204  }
205  }
206 }
207 
208 inline
209 Gr::imp::vectors_const_byte_iterator Gr::imagebuffer::bytes_begin( const Vectors & vectors )
210 {
211  return imp::vectors_const_byte_iterator( vectors ) ;
212 }
213 
214 inline
215 Gr::imp::vectors_const_byte_iterator Gr::imagebuffer::bytes_end( const Vectors & )
216 {
217  return imp::vectors_const_byte_iterator() ;
218 }
219 
220 inline
221 bool Gr::imagebuffer::row_empty( Vectors::iterator row_p )
222 {
223  return (*row_p).empty() ;
224 }
225 
226 inline
227 void Gr::imagebuffer::row_resize( Vectors::iterator row_p , size_t n )
228 {
229  (*row_p).resize( n ) ;
230 }
231 
232 inline
233 Gr::Vectors::iterator Gr::imagebuffer::row_erase( Vectors & vectors , Vectors::iterator row_p )
234 {
235  return vectors.erase( row_p , vectors.end() ) ;
236 }
237 
238 inline
239 Gr::Vectors::const_iterator Gr::imagebuffer::row_begin( const Vectors & vectors )
240 {
241  return vectors.begin() ;
242 }
243 
244 inline
245 Gr::Vectors::iterator Gr::imagebuffer::row_begin( Vectors & vectors )
246 {
247  return vectors.begin() ;
248 }
249 
250 inline
251 Gr::Vectors::const_iterator Gr::imagebuffer::row_end( const Vectors & vectors )
252 {
253  return vectors.end() ;
254 }
255 
256 inline
257 Gr::Vectors::iterator Gr::imagebuffer::row_end( Vectors & vectors )
258 {
259  return vectors.end() ;
260 }
261 
262 inline
263 Gr::Vectors::iterator Gr::imagebuffer::row_add( Vectors & vectors )
264 {
265  vectors.push_back( std::vector<char>() ) ; // emplace_back
266  return vectors.begin() + (vectors.size()-1U) ;
267 }
268 
269 inline
270 char * Gr::imagebuffer::row_ptr( Vectors::iterator row_p )
271 {
272  return &(*row_p)[0] ;
273 }
274 
275 inline
276 const char * Gr::imagebuffer::row_ptr( Vectors::const_iterator row_p )
277 {
278  return &(*row_p)[0] ;
279 }
280 
281 inline
282 size_t Gr::imagebuffer::row_size( Vectors::const_iterator row_p )
283 {
284  return (*row_p).size() ;
285 }
286 
287 
288 inline
290  m_vectors(nullptr) ,
291  m_current_offset(0U) ,
292  m_offset(0U)
293 {
294 }
295 
296 inline
298  m_vectors(&vectors) ,
299  m_current(vectors.begin()) ,
300  m_current_offset(0U) ,
301  m_offset(0U)
302 {
303 }
304 
305 inline
307 {
308  if( m_vectors == nullptr || m_current == m_vectors->end() ) return '\0' ;
309  return (*m_current).at(m_current_offset) ;
310 }
311 
312 inline
314 {
315  if( m_vectors != nullptr && m_current != m_vectors->end() )
316  {
317  m_offset++ ;
318  m_current_offset++ ;
319  if( m_current_offset == (*m_current).size() )
320  {
321  for( ++m_current ; m_current != m_vectors->end() && (*m_current).empty() ; )
322  ++m_current ;
323  m_current_offset = 0U ;
324  }
325  }
326  return *this ;
327 }
328 
329 inline
331 {
332  vectors_const_byte_iterator orig( *this ) ;
333  ++(*this) ;
334  return orig ;
335 }
336 
337 inline
339 {
340  bool this_end = m_vectors == nullptr || m_current == m_vectors->end() ;
341  bool other_end = m_vectors == nullptr || m_current == m_vectors->end() ;
342  return
343  ( this_end && other_end ) ||
344  ( m_vectors == other.m_vectors && m_offset == other.m_offset ) ;
345 }
346 
347 inline
349 {
350  return !( *this == other ) ;
351 }
352 
353 #endif
A simple, read-only streambuf for Gr::Vectors.
Definition: grvectors.h:94
A forward byte-by-byte input iterator for Gr::ImageVectors.
Definition: grvectors.h:139
A traits class that can be specialised for Gr::ImageBuffer candidates.
Definition: grtraits.h:34
bool operator!=(const vectors_const_byte_iterator &) const
Inequality operator.
Definition: grvectors.h:348
Synopsis:
bool operator==(const vectors_const_byte_iterator &) const
Equality operator.
Definition: grvectors.h:338
std::vector< std::vector< char > > Vectors
A candidate for Gr::ImageBuffer that uses nested std::vectors.
Definition: grvectors.h:39
vectors_const_byte_iterator & operator++()
Preincrement operator.
Definition: grvectors.h:313
virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) override
Override from std::streambuf.
Definition: grvectors.cpp:159
vectors_const_byte_iterator()
Default constructor for an end iterator.
Definition: grvectors.h:289
virtual std::streampos seekpos(std::streampos pos, std::ios_base::openmode which) override
Override from std::streambuf.
Definition: grvectors.cpp:154
virtual std::streamsize xsgetn(char *s, std::streamsize n) override
Override from std::streambuf.
Definition: grvectors.cpp:97
virtual int underflow() override
Override from std::streambuf.
Definition: grvectors.cpp:44
virtual ~vectors_streambuf()
Destructor.
Definition: grvectors.cpp:40
vectors_streambuf(const Vectors &)
Constructor.
Definition: grvectors.cpp:30
char operator*() const
Dereference operator.
Definition: grvectors.h:306
imp::hexdump_streamable< N, T, Ttohex, Ttoprintable > hexdump(T begin, T end, unsigned int address_width, const char *prefix, const char *space, const char *bar, unsigned int width, Ttohex tohex, Ttoprintable toprintable)
Returns a streamable object that does a hex dump.
Definition: ghexdump.h:240