summaryrefslogtreecommitdiff
path: root/Source/DirectFB/src/gfx/convert.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/src/gfx/convert.c')
-rwxr-xr-xSource/DirectFB/src/gfx/convert.c1427
1 files changed, 1427 insertions, 0 deletions
diff --git a/Source/DirectFB/src/gfx/convert.c b/Source/DirectFB/src/gfx/convert.c
new file mode 100755
index 0000000..484f5a6
--- /dev/null
+++ b/Source/DirectFB/src/gfx/convert.c
@@ -0,0 +1,1427 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <directfb.h>
+#include <directfb_util.h>
+
+#include "convert.h"
+
+/* lookup tables for 2/3bit to 8bit color conversion */
+static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff};
+static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff};
+
+#define EXPAND_1to8(v) ((v) ? 0xff : 0x00)
+#define EXPAND_2to8(v) (lookup2to8[v])
+#define EXPAND_3to8(v) (lookup3to8[v])
+#define EXPAND_4to8(v) (((v) << 4) | ((v) ))
+#define EXPAND_5to8(v) (((v) << 3) | ((v) >> 2))
+#define EXPAND_6to8(v) (((v) << 2) | ((v) >> 4))
+#define EXPAND_7to8(v) (((v) << 1) | ((v) >> 6))
+
+
+DFBSurfacePixelFormat
+dfb_pixelformat_for_depth( int depth )
+{
+ switch (depth) {
+ case 2:
+ return DSPF_LUT2;
+ case 8:
+ return DSPF_LUT8;
+ case 12:
+ return DSPF_ARGB4444;
+ case 14:
+ return DSPF_ARGB2554;
+ case 15:
+ return DSPF_ARGB1555;
+ case 16:
+ return DSPF_RGB16;
+ case 18:
+ return DSPF_RGB18;
+ case 24:
+ return DSPF_RGB24;
+ case 32:
+ return DSPF_RGB32;
+ }
+
+ return DSPF_UNKNOWN;
+}
+
+void
+dfb_pixel_to_color( DFBSurfacePixelFormat format,
+ unsigned long pixel,
+ DFBColor *ret_color )
+{
+ ret_color->a = 0xff;
+
+ switch (format) {
+ case DSPF_RGB332:
+ ret_color->r = EXPAND_3to8( (pixel & 0xe0) >> 5 );
+ ret_color->g = EXPAND_3to8( (pixel & 0x1c) >> 2 );
+ ret_color->b = EXPAND_2to8( (pixel & 0x03) );
+ break;
+
+ case DSPF_ARGB1555:
+ ret_color->a = EXPAND_1to8( pixel >> 15 );
+ case DSPF_RGB555:
+ ret_color->r = EXPAND_5to8( (pixel & 0x7c00) >> 10 );
+ ret_color->g = EXPAND_5to8( (pixel & 0x03e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x001f) );
+ break;
+
+ case DSPF_BGR555:
+ ret_color->r = EXPAND_5to8( (pixel & 0x001f) );
+ ret_color->g = EXPAND_5to8( (pixel & 0x03e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x7c00) >> 10 );
+ break;
+
+ case DSPF_ARGB2554:
+ ret_color->a = EXPAND_2to8( pixel >> 14 );
+ ret_color->r = EXPAND_5to8( (pixel & 0x3e00) >> 9 );
+ ret_color->g = EXPAND_5to8( (pixel & 0x01f0) >> 4 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_ARGB4444:
+ ret_color->a = EXPAND_4to8( pixel >> 12 );
+ case DSPF_RGB444:
+ ret_color->r = EXPAND_4to8( (pixel & 0x0f00) >> 8 );
+ ret_color->g = EXPAND_4to8( (pixel & 0x00f0) >> 4 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_RGBA4444:
+ ret_color->r = EXPAND_4to8( (pixel ) >> 12 );
+ ret_color->g = EXPAND_4to8( (pixel & 0x0f00) >> 8 );
+ ret_color->b = EXPAND_4to8( (pixel & 0x00f0) >> 4 );
+ ret_color->a = EXPAND_4to8( (pixel & 0x000f) );
+ break;
+
+ case DSPF_RGB16:
+ ret_color->r = EXPAND_5to8( (pixel & 0xf800) >> 11 );
+ ret_color->g = EXPAND_6to8( (pixel & 0x07e0) >> 5 );
+ ret_color->b = EXPAND_5to8( (pixel & 0x001f) );
+ break;
+
+ case DSPF_ARGB:
+ ret_color->a = pixel >> 24;
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ ret_color->r = (pixel & 0xff0000) >> 16;
+ ret_color->g = (pixel & 0x00ff00) >> 8;
+ ret_color->b = (pixel & 0x0000ff);
+ break;
+
+ case DSPF_AiRGB:
+ ret_color->a = (pixel >> 24) ^ 0xff;
+ ret_color->r = (pixel & 0xff0000) >> 16;
+ ret_color->g = (pixel & 0x00ff00) >> 8;
+ ret_color->b = (pixel & 0x0000ff);
+ break;
+
+ default:
+ ret_color->r = 0;
+ ret_color->g = 0;
+ ret_color->b = 0;
+ }
+}
+
+unsigned long
+dfb_pixel_from_color( DFBSurfacePixelFormat format,
+ const DFBColor *color )
+{
+ u32 y, cb, cr;
+
+ switch (format) {
+ case DSPF_RGB332:
+ return PIXEL_RGB332( color->r, color->g, color->b );
+
+ case DSPF_ARGB1555:
+ return PIXEL_ARGB1555( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB555:
+ return PIXEL_RGB555( color->r, color->g, color->b );
+
+ case DSPF_BGR555:
+ return PIXEL_BGR555( color->r, color->g, color->b );
+
+ case DSPF_ARGB2554:
+ return PIXEL_ARGB2554( color->a, color->r, color->g, color->b );
+
+ case DSPF_ARGB4444:
+ return PIXEL_ARGB4444( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGBA4444:
+ return PIXEL_RGBA4444( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB444:
+ return PIXEL_RGB444( color->r, color->g, color->b );
+
+ case DSPF_RGB16:
+ return PIXEL_RGB16( color->r, color->g, color->b );
+
+ case DSPF_RGB18:
+ return PIXEL_RGB18( color->r, color->g, color->b );
+
+ case DSPF_ARGB1666:
+ return PIXEL_ARGB1666( color->a, color->r, color->g, color->b );
+
+ case DSPF_ARGB6666:
+ return PIXEL_ARGB6666( color->a, color->r, color->g, color->b );
+
+ case DSPF_RGB24:
+ return PIXEL_RGB32( color->r, color->g, color->b );
+
+ case DSPF_RGB32:
+ return PIXEL_RGB32( color->r, color->g, color->b );
+
+ case DSPF_ARGB:
+ return PIXEL_ARGB( color->a, color->r, color->g, color->b );
+
+ case DSPF_AiRGB:
+ return PIXEL_AiRGB( color->a, color->r, color->g, color->b );
+
+ case DSPF_AYUV:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_AYUV( color->a, y, cb, cr );
+
+ case DSPF_YUY2:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_YUY2( y, cb, cr );
+
+ case DSPF_UYVY:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return PIXEL_UYVY( y, cb, cr );
+
+ case DSPF_I420:
+ case DSPF_YV12:
+ RGB_TO_YCBCR( color->r, color->g, color->b, y, cb, cr );
+ return y | (cb << 8) | (cr << 16);
+
+ default:
+ D_WARN( "unknown format 0x%08x", format );
+ }
+
+ return 0x55555555;
+}
+
+const char *
+dfb_pixelformat_name( DFBSurfacePixelFormat format )
+{
+ int i = 0;
+
+ do {
+ if (format == dfb_pixelformat_names[i].format)
+ return dfb_pixelformat_names[i].name;
+ } while (dfb_pixelformat_names[i++].format != DSPF_UNKNOWN);
+
+ return "<invalid>";
+}
+
+void
+dfb_convert_to_rgb16( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp2 = dpitch / 2;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB16:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB16( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ),
+ EXPAND_4to8( (src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( EXPAND_4to8( (src16[x] & 0xf000) >> 12 ),
+ EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) << 1) | ((src16[x] & 0x03e0) << 1) | (src16[x] & 0x003f);
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) >> 10) | ((src16[x] & 0x03e0) << 1) | ((src16[x] & 0x001f) << 11 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB16( (src32[x] & 0xff0000) >> 16,
+ (src32[x] & 0x00ff00) >> 8,
+ (src32[x] & 0x0000ff) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB16( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb555( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u16 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp2 = dpitch / 2;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB555( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ),
+ EXPAND_4to8( (src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( EXPAND_4to8( (src16[x] & 0xf000) >> 12 ),
+ EXPAND_4to8( (src16[x] & 0x0f00) >> 8 ),
+ EXPAND_4to8( (src16[x] & 0x00f0) >> 4 ) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0xffc0) >> 1) | (src16[x] & 0x001f);
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ((src16[x] & 0x7c00) >> 10) | (src16[x] & 0x03e0) | ((src16[x] & 0x001f) << 10 );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB555( (src32[x] & 0xff0000) >> 16,
+ (src32[x] & 0x00ff00) >> 8,
+ (src32[x] & 0x0000ff) );
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB555( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp2;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb32( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+ int x;
+
+ switch (format) {
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ while (height--) {
+ direct_memcpy( dst, src, width * 4 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0; x<width; x++)
+#ifdef WORDS_BIGENDIAN
+ dst[x] = ( src8[x*3+0] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+2] );
+#else
+ dst[x] = ( src8[x*3+2] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+0] );
+#endif
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_RGB32( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_RGB32( r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB444:
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ARGB4444_TO_RGB32( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = RGBA4444_TO_RGB32( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_RGB32( ((src16[x] & 0xf800) >> 8) | ((src16[x] & 0xe000) >> 13),
+ ((src16[x] & 0x07e0) >> 3) | ((src16[x] & 0x0300) >> 8),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_argb( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+ int x;
+
+ switch (format) {
+ case DSPF_ARGB:
+ while (height--) {
+ direct_memcpy( dst, src, width * 4 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB32:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = src32[x] | 0xff000000;
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0; x<width; x++)
+#ifdef WORDS_BIGENDIAN
+ dst[x] = ( src8[x*3+0] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+2] ) | 0xff000000;
+#else
+ dst[x] = ( src8[x*3+2] << 16 ) |
+ ( src8[x*3+1] << 8 ) |
+ ( src8[x*3+0] ) | 0xff000000;
+#endif
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_AYUV:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+ YCBCR_TO_RGB( (src32[x] >> 16) & 0xff, (src32[x] >> 8) & 0xff, src32[x] & 0xff, r, g, b );
+
+ dst[x] = PIXEL_ARGB( src32[x] >> 24, r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_NV16:
+ while (height--) {
+ const u8 *src8 = src;
+ const u16 *src16 = src + surface_height * spitch;
+
+ for (x=0; x<width; x++) {
+ int r, g, b;
+
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[x], src16[x>>1] >> 8, src16[x>>1] & 0xff, r, g, b );
+#else
+ YCBCR_TO_RGB( src8[x], src16[x>>1] & 0xff, src16[x>>1] >> 8, r, g, b );
+#endif
+
+ dst[x] = PIXEL_ARGB( 0xff, r, g, b );
+ }
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = ARGB4444_TO_ARGB( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = RGBA4444_TO_ARGB( src16[x] );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x0f00) >> 4) | ((src16[x] & 0x0f00) >> 8),
+ ((src16[x] & 0x00f0) ) | ((src16[x] & 0x00f0) >> 4),
+ ((src16[x] & 0x000f) << 4) | ((src16[x] & 0x000f) ) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( (src16[x] & 0x8000) ? 0xff : 0x00,
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2),
+ ((src16[x] & 0x03e0) >> 2) | ((src16[x] & 0x0380) >> 7),
+ ((src16[x] & 0x7c00) >> 7) | ((src16[x] & 0x7000) >> 12) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0; x<width; x++)
+ dst[x] = PIXEL_ARGB( 0xff,
+ ((src16[x] & 0xf800) >> 8) | ((src16[x] & 0xe000) >> 13),
+ ((src16[x] & 0x07e0) >> 3) | ((src16[x] & 0x0300) >> 8),
+ ((src16[x] & 0x001f) << 3) | ((src16[x] & 0x001c) >> 2) );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_rgb24( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ int n, n3;
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = src8[n];
+ dst[n3+1] = src8[n];
+ dst[n3+2] = src8[n];
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_AiRGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_BGR555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+2] = (src16[n] & 0x7C00) >> 7;
+ dst[n3+1] = (src16[n] & 0x03E0) >> 2;
+ dst[n3+0] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB2554:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x3E00) >> 6;
+ dst[n3+1] = (src16[n] & 0x01F0) >> 1;
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+1] = (src16[n] & 0x00F0);
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0xF000) >> 8;
+ dst[n3+1] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+2] = (src16[n] & 0x00F0);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0x0F00) >> 4;
+ dst[n3+1] = (src16[n] & 0x00F0);
+ dst[n3+2] = (src16[n] & 0x000F) << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB332:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = lookup3to8[ (src8[n] >> 5) ];
+ dst[n3+1] = lookup3to8[ (src8[n] >> 2) & 0x07 ];
+ dst[n3+2] = lookup2to8[ (src8[n] ) & 0x03 ];
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB16:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src16[n] & 0xF800) >> 8;
+ dst[n3+1] = (src16[n] & 0x07E0) >> 3;
+ dst[n3+2] = (src16[n] & 0x001F) << 3;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB24:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+#ifdef WORDS_BIGENDIAN
+ dst[n3+0] = src8[n3+0];
+ dst[n3+1] = src8[n3+1];
+ dst[n3+2] = src8[n3+2];
+#else
+ dst[n3+0] = src8[n3+2];
+ dst[n3+1] = src8[n3+1];
+ dst[n3+2] = src8[n3+0];
+#endif
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGB32:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width; n++, n3+=3) {
+ dst[n3+0] = (src32[n] & 0xFF0000) >> 16;
+ dst[n3+1] = (src32[n] & 0x00FF00) >> 8;
+ dst[n3+2] = (src32[n] & 0x0000FF);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_YUY2:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+ register u32 y0, cb, y1, cr;
+ y0 = (src32[n] & 0x000000FF);
+ cb = (src32[n] & 0x0000FF00) >> 8;
+ y1 = (src32[n] & 0x00FF0000) >> 16;
+ cr = (src32[n] & 0xFF000000) >> 24;
+ YCBCR_TO_RGB( y0, cb, cr,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+ YCBCR_TO_RGB( y1, cb, cr,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_UYVY:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+ register u32 y0, cb, y1, cr;
+ cb = (src32[n] & 0x000000FF);
+ y0 = (src32[n] & 0x0000FF00) >> 8;
+ cr = (src32[n] & 0x00FF0000) >> 16;
+ y1 = (src32[n] & 0xFF000000) >> 24;
+ YCBCR_TO_RGB( y0, cb, cr,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+ YCBCR_TO_RGB( y1, cb, cr,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_NV16: {
+ while (height--) {
+ const u16 *cbcr = src + surface_height * spitch;
+ const u8 *src8 = src;
+
+ for (n=0, n3=0; n<width/2; n++, n3+=6) {
+#ifdef WORDS_BIGENDIAN
+ YCBCR_TO_RGB( src8[n*2+0], cbcr[n] >> 8, cbcr[n] & 0xff,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+
+ YCBCR_TO_RGB( src8[n*2+1], cbcr[n] >> 8, cbcr[n] & 0xff,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+#else
+ YCBCR_TO_RGB( src8[n*2+0], cbcr[n] & 0xff, cbcr[n] >> 8,
+ dst[n3+0], dst[n3+1], dst[n3+2] );
+
+ YCBCR_TO_RGB( src8[n*2+1], cbcr[n] & 0xff, cbcr[n] >> 8,
+ dst[n3+3], dst[n3+4], dst[n3+5] );
+#endif
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ }
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_a8( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ int n;
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ direct_memcpy( dst, src8, width );
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_AiRGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = ~(src32[n] >> 24);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = src32[n] >> 24;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = (src16[n] & 0x8000) ? 0xff : 0x00;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB2554:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ switch (src16[n] >> 14) {
+ case 0:
+ dst[n] = 0x00;
+ break;
+ case 1:
+ dst[n] = 0x55;
+ break;
+ case 2:
+ dst[n] = 0xAA;
+ break;
+ case 3:
+ dst[n] = 0xFF;
+ break;
+ }
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = (src16[n] >> 12);
+ dst[n] |= dst[n] << 4;
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (n=0; n<width; n++) {
+ dst[n] = EXPAND_4to8(src16[n] & 0xf);
+ }
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_RGB332:
+ case DSPF_RGB444:
+ case DSPF_RGB555:
+ case DSPF_BGR555:
+ case DSPF_RGB16:
+ case DSPF_RGB24:
+ case DSPF_RGB32:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_NV16:
+ while (height--) {
+ memset( dst, 0xff, width );
+
+ dst += dpitch;
+ }
+ break;
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_a4( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u8 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int w2 = width / 2;
+ int x, n;
+
+ D_ASSUME( (width & 1) == 0 );
+
+ switch (format) {
+ case DSPF_A8:
+ while (height--) {
+ const u8 *src8 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = (src8[n] & 0xf0) | ((src8[n+1] & 0xf0) >> 4);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0xf000) >> 8) | (src16[n+1] >> 12);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_RGBA4444:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0x000f) << 4) | (src16[n+1] & 0x000f);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB1555:
+ while (height--) {
+ const u16 *src16 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src16[n] & 0x8000) ? 0xf0 : 0) | ((src16[n+1] & 0x8000) ? 0x0f : 0);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ case DSPF_ARGB:
+ while (height--) {
+ const u32 *src32 = src;
+
+ for (x=0, n=0; x<w2; x++, n+=2)
+ dst[x] = ((src32[n] & 0xf0000000) >> 24) | ((src32[n+1] & 0xf0000000) >> 28);
+
+ src += spitch;
+ dst += dpitch;
+ }
+ break;
+
+ default:
+ if (DFB_PIXELFORMAT_HAS_ALPHA( format ))
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_yuy2( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+
+ switch (format) {
+ case DSPF_YUY2:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+
+void
+dfb_convert_to_uyvy( DFBSurfacePixelFormat format,
+ const void *src,
+ int spitch,
+ int surface_height,
+ u32 *dst,
+ int dpitch,
+ int width,
+ int height )
+{
+ const int dp4 = dpitch / 4;
+
+ switch (format) {
+ case DSPF_UYVY:
+ while (height--) {
+ direct_memcpy( dst, src, width * 2 );
+
+ src += spitch;
+ dst += dp4;
+ }
+ break;
+
+ default:
+ D_ONCE( "unsupported format" );
+ }
+}
+