VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvbars.cpp
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 // gvbars.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gvbars.h"
23 #include "grcolourspace.h"
24 #include "gstr.h"
25 #include <algorithm>
26 
27 namespace
28 {
30  enum Colour { c_black , c_white , c_yellow , c_cyan , c_green , c_magenta ,
31  c_red , c_blue , c_orange , c_purple , c__max } ;
32 }
33 
34 namespace Gv
35 {
36  class BarsGenerator ;
37 }
38 
39 /// \class Gv::BarsGenerator
40 /// A implementation class for Gv::BarsImp.
41 ///
43 {
44 public:
45  static BarsGenerator make( int dx , int dy , int type ) ;
46  // Factory function.
47 
48  void move() ;
49  // Animates the image.
50 
51  Colour colour( int x , int y ) const ;
52  // Returns the pixel colour.
53 
54 private:
55  int colours() const ;
56  template <typename T> BarsGenerator( bool in_rows , int dx , int dy , int speed , T c_begin , T c_end ) ;
57 
58 private:
59  bool m_in_rows ;
60  int m_dx ;
61  int m_dy ;
62  int m_speed ;
63  int m_offset ;
64  std::vector<Colour> m_colours ;
65 } ;
66 
67 /// \class Gv::BarsImp
68 /// A pimple-pattern implementation class for Gv::Bars.
69 ///
71 {
72 public:
73  BarsImp( int dx , int dy , const std::string & type ) ;
74  // Constructor.
75 
76  void fillBuffer( CaptureBuffer & b , const CaptureBufferScale & ) ;
77  // Fills the buffer with the current frame.
78 
79 private:
80  int m_dx ;
81  int m_dy ;
82  std::vector<triple_t> m_colour_yuv ;
83  BarsGenerator m_generator ;
84 } ;
85 
86 // ==
87 
88 namespace
89 {
90  int type( const std::string & config )
91  {
92  return G::Str::splitMatch(config,"horizontal",";") ? 1 : 0 ;
93  }
94 }
95 
96 Gv::BarsImp::BarsImp( int dx , int dy , const std::string & config ) :
97  m_dx(dx) ,
98  m_dy(dy) ,
99  m_generator(BarsGenerator::make(m_dx,m_dy,type(config)))
100 {
101  m_colour_yuv.resize( c__max , triple_t(0,0,0) ) ;
102  m_colour_yuv[c_black] = Gr::ColourSpace::yuv_int( triple_t(0,0,0) ) ;
103  m_colour_yuv[c_white] = Gr::ColourSpace::yuv_int( triple_t(255,255,255) ) ;
104  m_colour_yuv[c_yellow] = Gr::ColourSpace::yuv_int( triple_t(255,255,0) ) ;
105  m_colour_yuv[c_cyan] = Gr::ColourSpace::yuv_int( triple_t(0,255,255) ) ;
106  m_colour_yuv[c_green] = Gr::ColourSpace::yuv_int( triple_t(0,255,0) ) ;
107  m_colour_yuv[c_magenta] = Gr::ColourSpace::yuv_int( triple_t(255,0,255) ) ;
108  m_colour_yuv[c_red] = Gr::ColourSpace::yuv_int( triple_t(255,0,0) ) ;
109  m_colour_yuv[c_blue] = Gr::ColourSpace::yuv_int( triple_t(0,0,255) ) ;
110  m_colour_yuv[c_orange] = Gr::ColourSpace::yuv_int( triple_t(255,128,0) ) ;
111  m_colour_yuv[c_purple] = Gr::ColourSpace::yuv_int( triple_t(150,10,150) ) ;
112 }
113 
114 void Gv::BarsImp::fillBuffer( Gv::CaptureBuffer & b , const CaptureBufferScale & scale )
115 {
116  G_ASSERT( int(scale.m_dx) == m_dx && int(scale.m_dy) == m_dy ) ;
117  m_generator.move() ;
118 
119  unsigned char * p_row = b.begin() ;
120  for( int y = 0 ; y < m_dy ; ++y , p_row += (m_dx*2) )
121  {
122  unsigned char * p = p_row ;
123  for( int x = 0 ; x < m_dx ; x++ , p += 2 )
124  {
125  triple_t yuv = m_colour_yuv.at(m_generator.colour(x,y)) ;
126  if( (p+1) >= b.end() ) return ; // just in case
127  p[0] = yuv.y() ;
128  p[1] = ( (long)p & 2 ) ? yuv.v() : yuv.u() ;
129  }
130  }
131 }
132 
133 // ==
134 
135 Gv::Bars::Bars( int dx , int dy , const std::string & config ) :
136  m_imp(new BarsImp(dx,dy,config))
137 {
138 }
139 
141 {
142  delete m_imp ;
143 }
144 
146 {
147  return false ; // yuyv
148 }
149 
151 {
152  m_imp->fillBuffer( b , scale ) ;
153 }
154 
155 // ==
156 
157 template <typename T>
158 Gv::BarsGenerator::BarsGenerator( bool in_rows , int dx , int dy , int speed , T c_begin , T c_end ) :
159  m_in_rows(in_rows) ,
160  m_dx(dx) ,
161  m_dy(dy) ,
162  m_speed(speed) ,
163  m_offset(0) ,
164  m_colours(c_begin,c_end)
165 {
166 }
167 
168 void Gv::BarsGenerator::move()
169 {
170  m_offset += m_speed ;
171  if( ( m_in_rows && m_offset == m_dy ) || m_offset == m_dx )
172  m_offset = 0 ;
173 }
174 
175 Colour Gv::BarsGenerator::colour( int x , int y ) const
176 {
177  return
178  m_in_rows ?
179  m_colours.at( (colours()*(y+m_offset)/m_dy) % colours() ) :
180  m_colours.at( (colours()*(x+m_offset)/m_dx) % colours() ) ;
181 }
182 
183 int Gv::BarsGenerator::colours() const
184 {
185  return static_cast<int>(m_colours.size()) ;
186 }
187 
188 Gv::BarsGenerator Gv::BarsGenerator::make( int dx , int dy , int type )
189 {
190  if( type == 0 )
191  {
192  Colour colours[] = { c_black , c_white , c_yellow , c_cyan , c_green , c_magenta , c_red , c_blue } ;
193  return BarsGenerator( false , dx , dy , 1 , colours , colours+8 ) ;
194  }
195  else
196  {
197  Colour colours[] = { c_red , c_orange , c_yellow , c_green , c_blue , c_purple } ;
198  return BarsGenerator( true , dx , dy , 1 , colours , colours+6 ) ;
199  }
200 }
201 
Bars(int dx, int dy, const std::string &config)
Constructor.
Definition: gvbars.cpp:135
virtual void fillBuffer(CaptureBuffer &, const CaptureBufferScale &) override
Override from Gv::ImageGenerator.
Definition: gvbars.cpp:150
const unsigned char * begin() const
Returns a pointer to start of the dword-aligned data buffer.
const unsigned char * end() const
Returns a pointer off the end of the raw data buffer.
virtual ~Bars()
Destructor.
Definition: gvbars.cpp:140
A implementation class for Gv::BarsImp.
Definition: gvbars.cpp:42
virtual bool init() override
Override from Gv::ImageGenerator.
Definition: gvbars.cpp:145
A video-capture buffer class to hold image data, with overloaded constructors for the various V4l i/o...
static bool splitMatch(const std::string &in, const std::string &s, const std::string &ws=Str::ws())
Returns true if any of the split parts of 'in' are equal to 's'.
Definition: gstr.cpp:927
A structure holding capture buffer dimensions.
triple< unsigned char > yuv(triple< unsigned char > rgb) g__noexcept
A top-level function that calculates yuv from rgb with default implementation options.
A pimple-pattern implementation class for Gv::Bars.
Definition: gvbars.cpp:70
triple< unsigned char > yuv_int(triple< unsigned char > rgb) g__noexcept
A fast conversion from rgb to yuv.