This can be used to calculate (and return) the pixel address and pitch for split buffer formats, for the CbCr or Cb and Cr components (2-plane or 3-plane formats).
Signed-off-by: André Draszik <andre.dras...@st.com> --- src/core/surface.h | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/src/core/surface.h b/src/core/surface.h index aaa18d0..836ca89 100644 --- a/src/core/surface.h +++ b/src/core/surface.h @@ -504,6 +504,116 @@ dfb_surface_data_offset( const CoreSurface *surface, } static __inline__ void +dfb_surface_data_cbcr_offset( const CoreSurface * const surface, + const void * const data, + int pitch, + int x, + int y, + u8 ** const offset_cb, + int * const pitch_cb, + u8 ** const offset_cr, + int * const pitch_cr ) +{ + D_ASSERT( surface != NULL ); + D_ASSERT( data != NULL ); + D_ASSERT( pitch > 0 ); + D_ASSERT( x >= 0 ); + D_ASSERT( x < surface->config.size.w ); + D_ASSERT( y >= 0 ); + D_ASSERT( y < surface->config.size.h ); + D_ASSERT( offset_cb != NULL ); + D_ASSERT( pitch_cb != NULL ); + D_ASSERT( offset_cr != NULL ); + D_ASSERT( pitch_cr != NULL ); + + if (surface->config.caps & DSCAPS_SEPARATED) { + if (y & 1) + y += surface->config.size.h; + + y >>= 1; + } + + switch (surface->config.format) { + case DSPF_NV12: + case DSPF_NV21: + *pitch_cb = pitch; + *pitch_cr = 0; + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * y/2 + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + *offset_cr = NULL; + break; + case DSPF_NV16: + *pitch_cb = pitch; + *pitch_cr = 0; + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * y + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + *offset_cr = NULL; + break; + case DSPF_I420: + *pitch_cb = pitch / 2; + *pitch_cr = pitch / 2; + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * y/2 + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + *offset_cr = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * surface->config.size.h/2 + + *pitch_cr * y/2 + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + break; + case DSPF_YV12: + *pitch_cb = pitch / 2; + *pitch_cr = pitch / 2; + *offset_cr = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cr * y/2 + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cr * surface->config.size.h/2 + + *pitch_cb * y/2 + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + break; + case DSPF_YV16: + *pitch_cb = pitch / 2; + *pitch_cr = pitch / 2; + *offset_cr = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cr * y + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cr * surface->config.size.h + + *pitch_cb * y + + DFB_BYTES_PER_LINE( surface->config.format, x/2 )); + break; + case DSPF_YUV444P: + *pitch_cb = pitch; + *pitch_cr = pitch; + *offset_cb = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * y + + DFB_BYTES_PER_LINE( surface->config.format, x )); + *offset_cr = ((u8*)data + + pitch * surface->config.size.h + + *pitch_cb * surface->config.size.h + + *pitch_cr * y + + DFB_BYTES_PER_LINE( surface->config.format, x )); + break; + + default: + *offset_cb = *offset_cr = NULL; + *pitch_cb = *pitch_cr = 0; + break; + } +} + +static __inline__ void dfb_surface_calc_buffer_size( CoreSurface *surface, int byte_align, int pixel_align, -- 1.8.2 _______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev