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

Reply via email to