21 #ifndef GV_CAPTURE_BUFFER__H
22 #define GV_CAPTURE_BUFFER__H
33 class CaptureBufferFormat ;
34 class CaptureBufferScale ;
35 class CaptureBufferComponent ;
36 class CaptureBufferIterator ;
49 CaptureBufferScale(
size_t buffersize_ ,
size_t linesize_ ,
size_t dx_ ,
size_t dy_ ) ;
81 CaptureBuffer(
size_t length ,
void * p ,
int (*unmap)(
void*,
size_t) ) ;
90 const unsigned char *
begin()
const ;
93 unsigned char *
begin() ;
96 const unsigned char *
end()
const ;
112 void copy(
int dx ,
int dy ,
char * p_out ,
size_t out_size )
const ;
115 void copy(
int dx ,
int dy ,
unsigned char * p_out ,
size_t out_size )
const ;
118 size_t offset_imp(
int c ,
int x ,
int y )
const ;
127 unsigned char luma_imp(
size_t ,
size_t ,
size_t )
const ;
133 unsigned int value(
int c ,
size_t )
const ;
134 unsigned int value(
int c ,
int x ,
int y )
const ;
135 unsigned char value8(
int c ,
int x ,
int y )
const ;
136 unsigned char value8(
int c ,
size_t )
const ;
137 void checkFormat()
const ;
138 static size_t size4(
size_t ) ;
143 mutable void * m_freeme ;
144 mutable void * m_start ;
146 int (*m_unmap)(
void*,size_t) ;
155 enum PlanarOffset { XY = 0x800 , XY2 = 0x400 , XY4 = 0x200 , XY8 = 0x100 } ;
156 enum Type { c_byte , c_word_le , c_word_be } ;
162 size_t step_ ,
unsigned short depth_ = 8 ,
unsigned short shift_ = 0 , Type type_ = c_byte ,
163 short linesize_shift_ = 0 ) ;
168 unsigned int value(
const unsigned char * p )
const ;
171 unsigned char value8(
const unsigned char * p )
const ;
185 unsigned short xshift()
const ;
188 unsigned short yshift()
const ;
191 size_t step()
const ;
194 unsigned short depth()
const ;
198 bool is_simple()
const ;
202 unsigned short m_x_shift ;
203 unsigned short m_y_shift ;
205 unsigned short m_depth ;
206 unsigned int m_mask ;
207 unsigned short m_shift ;
209 short m_linesize_shift ;
221 enum Type { rgb , yuv , grey } ;
247 unsigned int id()
const ;
250 const char *
name()
const ;
258 const char * m_name ;
270 size_t offset_0 ,
unsigned short x_shift_0 ,
size_t step_0 ,
271 size_t offset_1 ,
unsigned short x_shift_1 ,
size_t step_1 ,
272 size_t offset_2 ,
unsigned short x_shift_2 ,
size_t step_2 ) ;
281 unsigned char luma()
const ;
297 unsigned int m_x_shift_mask[3] ;
316 m_buffersize(buffersize_) ,
317 m_linesize(linesize_) ,
320 m_xy(dy_*linesize_) ,
325 G_ASSERT( m_buffersize > m_linesize && m_dy != 0U ) ;
333 return m_dy == dy && m_linesize == (dx*3U) && m_buffersize == (dx*dy*3U) ;
364 const unsigned short offset_small = m_offset & 0xff ;
365 const size_t linesize = m_linesize_shift == 0 ? scale.m_linesize :
366 ( m_linesize_shift >= 1 ? (scale.m_linesize>>m_linesize_shift) : (scale.m_linesize<<-m_linesize_shift) ) ;
367 const size_t offset_line = (y>>m_y_shift) * linesize ;
370 const bool add_xy = !!( m_offset & XY ) ;
371 const bool add_xy2 = !!( m_offset & XY2 ) ;
372 const bool add_xy4 = !!( m_offset & XY4 ) ;
373 const bool add_xy8 = !!( m_offset & XY8 ) ;
374 const size_t offset_plane =
375 (add_xy?scale.m_xy:0U) +
376 (add_xy2?scale.m_xy2:0U) +
377 (add_xy4?scale.m_xy4:0U) +
378 (add_xy8?scale.m_xy8:0U) ;
380 return offset_small + offset_plane + offset_line ;
386 return offset(y,scale) + ((x>>m_x_shift)*m_step) ;
392 unsigned int v = *p ;
393 if( m_type != c_byte )
395 unsigned int v2 = p[1] ;
396 v = m_type == c_word_be ? ((v<<8)|v2) : ((v2<<8)|v) ;
398 return ( v >> m_shift ) & m_mask ;
407 const unsigned int v = value(p) ;
410 else if( m_depth < 8 )
411 return v << (8-m_depth) ;
413 return v >> (m_depth-8) ;
417 bool Gv::CaptureBufferComponent::is_simple()
const
419 return m_simple && m_x_shift == 0 && m_y_shift == 0 && m_step == 3 ;
425 return is_simple() && m_offset == offset ;
432 return reinterpret_cast<const unsigned char *
>(m_start) ;
438 return reinterpret_cast<unsigned char *
>(m_start) ;
444 return begin() + size() ;
454 size_t Gv::CaptureBuffer::size4(
size_t n )
456 return n < 4U ? 0U : (n & ~size_t(3U)) ;
463 offset_imp(0,y) , m_format->component(0).xshift() , m_format->component(0).step() ,
464 offset_imp(1,y) , m_format->component(1).xshift() , m_format->component(1).step() ,
465 offset_imp(2,y) , m_format->component(2).xshift() , m_format->component(2).step() ) ;
471 return m_format->component(c).offset( y , m_scale ) ;
477 size_t result = m_format->component(c).offset( x , y , m_scale ) ;
478 G_ASSERT( result < size() ) ;
483 unsigned int Gv::CaptureBuffer::value(
int c ,
int x ,
int y )
const
485 return value( c , offset_imp(c,x,y) ) ;
489 unsigned int Gv::CaptureBuffer::value(
int c ,
size_t offset )
const
491 return m_format->component(c).value( begin() + offset ) ;
495 unsigned char Gv::CaptureBuffer::value8(
int c ,
int x ,
int y )
const
497 return value8( c , offset_imp(c,x,y) ) ;
501 unsigned char Gv::CaptureBuffer::value8(
int c ,
size_t offset )
const
503 return m_format->component(c).value8( begin() + offset ) ;
509 G_ASSERT( m_format !=
nullptr ) ;
511 if( m_format->is_grey() || m_format->is_yuv() )
513 return value8( 0 , offset_0 ) ;
524 G_ASSERT( m_format !=
nullptr ) ;
526 if( m_format->is_yuv() )
530 else if( m_format->is_rgb() )
532 return triple_t( value8(0,offset_0) , value8(1,offset_1) , value8(2,offset_2) ) ;
536 const unsigned char luma = value8( 0 , offset_0 ) ;
537 return triple_t( luma , luma , luma ) ;
544 size_t offset_0 ,
unsigned short x_shift_0 ,
size_t step_0 ,
545 size_t offset_1 ,
unsigned short x_shift_1 ,
size_t step_1 ,
546 size_t offset_2 ,
unsigned short x_shift_2 ,
size_t step_2 ) :
550 m_offset[0] = offset_0 ;
551 m_offset[1] = offset_1 ;
552 m_offset[2] = offset_2 ;
553 m_x_shift_mask[0] = ((1U<<x_shift_0)-1U) ;
554 m_x_shift_mask[1] = ((1U<<x_shift_1)-1U) ;
555 m_x_shift_mask[2] = ((1U<<x_shift_2)-1U) ;
564 return m_buffer.rgb_imp( m_offset[0] , m_offset[1] , m_offset[2] ) ;
570 return m_buffer.rgb_imp( m_offset[0] , m_offset[1] , m_offset[2] ) ;
576 return m_buffer.luma_imp( m_offset[0] , m_offset[1] , m_offset[2] ) ;
583 if( (m_x & m_x_shift_mask[0]) == 0 ) m_offset[0] += m_step[0] ;
584 if( (m_x & m_x_shift_mask[1]) == 0 ) m_offset[1] += m_step[1] ;
585 if( (m_x & m_x_shift_mask[2]) == 0 ) m_offset[2] += m_step[2] ;
592 return m_x == other.m_x ;
598 return !(*
this == other) ;
605 return m_type == grey ;
611 return m_type ==
rgb ;
617 return m_type ==
yuv ;
623 G_ASSERT( c >= 0 && c < 3 ) ;
triple< unsigned char > rgb(triple< unsigned char > yuv) g__noexcept
A top-level function that calculates rgb from yuv with default implementation options.
bool operator!=(const CaptureBufferIterator &) const
Comparison operator.
A holder for image data, having eight bits per sample and one or three channels.
CaptureBufferIterator row(int y) const
Returns a pixel iterator for the y'th row.
unsigned short xshift() const
Returns the x_shift.
triple< unsigned char > rgb_int(triple< unsigned char > yuv) g__noexcept
A fast conversion from yuv to rgb.
A const iterator for a single row of Gv::CaptureBuffer pixels.
unsigned short yshift() const
Returns the y_shift.
unsigned char value8(const unsigned char *p) const
Returns the 0..255 value at p.
size_t offset(int x, int y, const CaptureBufferScale &scale) const
Returns the buffer offset for the given pixel.
const unsigned char * begin() const
Returns a pointer to start of the dword-aligned data buffer.
Gr::ColourSpace::triple< unsigned char > operator*() const
Same as rgb().
Gr::ColourSpace::triple< unsigned char > rgb() const
Returns the three rgb values at the current position.
size_t offset_imp(int c, int x, int y) const
Used by Gv::CaptureBufferIterator.
bool is_simple(size_t offset) const
Returns true if the component x_shift and y_shift are zero, the depth is eight, the shift is zero...
const unsigned char * end() const
Returns a pointer off the end of the raw data buffer.
CaptureBuffer(size_t length)
Constructor for a malloc()ed buffer suitable for "read()" i/o.
void setFormat(const CaptureBufferFormat &, const CaptureBufferScale &)
Used by the Gv::Capture class to imbue the buffer with a particular format description and scale...
~CaptureBuffer()
Destructor.
unsigned int value(const unsigned char *p) const
Returns the value at p.
bool operator==(const CaptureBufferIterator &) const
Comparison operator.
A video-capture buffer class to hold image data, with overloaded constructors for the various V4l i/o...
CaptureBufferComponent()
Default constructor for a simple step-three component.
A structure holding capture buffer dimensions.
CaptureBufferIterator(const CaptureBuffer &, size_t offset_0, unsigned short x_shift_0, size_t step_0, size_t offset_1, unsigned short x_shift_1, size_t step_1, size_t offset_2, unsigned short x_shift_2, size_t step_2)
Constructor used CaptureBuffer::row().
Gr::ColourSpace::triple< unsigned char > rgb_imp(size_t, size_t, size_t) const
Used by Gv::CaptureBufferIterator.
unsigned char y_int(unsigned char r, unsigned char g, unsigned char b)
A fast conversion from rgb to y.
triple< unsigned char > yuv(triple< unsigned char > rgb) g__noexcept
A top-level function that calculates yuv from rgb with default implementation options.
unsigned char luma() const
Returns the luma value at the current position.
CaptureBufferIterator & operator++()
Advances the iterator to the next pixel in the row.
unsigned char luma_imp(size_t, size_t, size_t) const
Used by Gv::CaptureBufferIterator.
void copyTo(Gr::ImageData &) const
Copies the image to a correctly-sized image data buffer.
bool is_simple(int dx, int dy) const
Returns true if this buffer scale matches the given image size using packed rgb with no end-of-line p...
unsigned short depth() const
Returns the depth.
void copy(int dx, int dy, char *p_out, size_t out_size) const
Copies the image to an rgb output buffer.
size_t step() const
Returns the step.
size_t size() const
Returns the size of the buffer.
CaptureBufferScale()
Default constructor.
A descriptor for one colour component in a Gv::CaptureBufferFormat structure.