From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/tools/dfbfx.c | 630 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100755 Source/DirectFB/tools/dfbfx.c (limited to 'Source/DirectFB/tools/dfbfx.c') diff --git a/Source/DirectFB/tools/dfbfx.c b/Source/DirectFB/tools/dfbfx.c new file mode 100755 index 0000000..2d0cf1a --- /dev/null +++ b/Source/DirectFB/tools/dfbfx.c @@ -0,0 +1,630 @@ +/* + (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 , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This file is subject to the terms and conditions of the MIT License: + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "config.h" + +#include +#include + +#include +#include + +#include + +#include + + +static DirectFBSurfaceBlittingFlagsNames( m_bflags ); +static DirectFBSurfaceBlendFunctionNames( m_bfuncs ); + +#define MODULATE(a,b) do { (a) = (((int)(a) * ((int)(b) + 1)) >> 8); } while (0) + + +static DFBColor +blit_pixel( CardState *state, DFBColor src, DFBColor dst ) +{ + /* Scratch for blending stage. */ + DFBColor x; + + /* + * Input => short circuit to Output? (simple blits) + */ + + /* Without any flag the source is simply copied. */ + if (!state->blittingflags) + return src; + + /* Source color keying is the 2nd simplest operation. */ + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + /* If the source matches the color key, keep the destination. */ + if (PIXEL_RGB32(src.r,src.g,src.b) == state->src_colorkey) + return dst; + } + + /* Destination color keying already requires reading the destination. */ + if (state->blittingflags & DSBLIT_DST_COLORKEY) { + /* If the destination does not match the color key, keep the destination. */ + if (PIXEL_RGB32(dst.r,dst.g,dst.b) != state->dst_colorkey) + return dst; + } + + /* + * Modulation stage + */ + + /* Modulate source alpha value with global alpha factor? */ + if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { + /* Combine with source alpha value... */ + if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) + MODULATE( src.a, state->color.a ); + else + /* ...or replace it. */ + src.a = state->color.a; + } + + /* Modulate source colors with global color factors? */ + if (state->blittingflags & DSBLIT_COLORIZE) { + MODULATE( src.r, state->color.r ); + MODULATE( src.g, state->color.g ); + MODULATE( src.b, state->color.b ); + } + + /* + * Premultiplication stage + */ + + /* Premultiply source colors with (modulated) source alpha value? */ + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + MODULATE( src.r, src.a ); + MODULATE( src.g, src.a ); + MODULATE( src.b, src.a ); + } + + /* Premultiply source colors with global alpha factor only? */ + if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + MODULATE( src.r, state->color.a ); + MODULATE( src.g, state->color.a ); + MODULATE( src.b, state->color.a ); + } + + /* Premultiply destination colors with destination alpha value? */ + if (state->blittingflags & DSBLIT_DST_PREMULTIPLY) { + MODULATE( dst.r, dst.a ); + MODULATE( dst.g, dst.a ); + MODULATE( dst.b, dst.a ); + } + + /* + * XOR comes right before blending, after load, modulate and premultiply. + */ + if (state->blittingflags & DSBLIT_XOR) { + src.a ^= dst.a; + src.r ^= dst.r; + src.g ^= dst.g; + src.b ^= dst.b; + } + + /* + * Blending stage + */ + + /* Initialize scratch with source values, modify the copy according to the source blend function. + Could be done better by writing to the scratch only once after the calculation. */ + x = src; + + /* Blend scratch (source copy) and destination values accordingly. */ + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) { + /* Apply the source blend function to the scratch. */ + switch (state->src_blend) { + /* Sargb *= 0.0 */ + case DSBF_ZERO: + x.a = x.r = x.g = x.b = 0; + break; + + /* Sargb *= 1.0 */ + case DSBF_ONE: + break; + + /* Sargb *= Sargb */ + case DSBF_SRCCOLOR: + MODULATE( x.a, src.a ); + MODULATE( x.r, src.r ); + MODULATE( x.g, src.g ); + MODULATE( x.b, src.b ); + break; + + /* Sargb *= 1.0 - Sargb */ + case DSBF_INVSRCCOLOR: + MODULATE( x.a, src.a ^ 0xff ); + MODULATE( x.r, src.r ^ 0xff ); + MODULATE( x.g, src.g ^ 0xff ); + MODULATE( x.b, src.b ^ 0xff ); + break; + + /* Sargb *= Saaaa */ + case DSBF_SRCALPHA: + MODULATE( x.a, src.a ); + MODULATE( x.r, src.a ); + MODULATE( x.g, src.a ); + MODULATE( x.b, src.a ); + break; + + /* Sargb *= 1.0 - Saaaa */ + case DSBF_INVSRCALPHA: + MODULATE( x.a, src.a ^ 0xff ); + MODULATE( x.r, src.a ^ 0xff ); + MODULATE( x.g, src.a ^ 0xff ); + MODULATE( x.b, src.a ^ 0xff ); + break; + + /* Sargb *= Daaaa */ + case DSBF_DESTALPHA: + MODULATE( x.a, dst.a ); + MODULATE( x.r, dst.a ); + MODULATE( x.g, dst.a ); + MODULATE( x.b, dst.a ); + break; + + /* Sargb *= 1.0 - Daaaa */ + case DSBF_INVDESTALPHA: + MODULATE( x.a, dst.a ^ 0xff ); + MODULATE( x.r, dst.a ^ 0xff ); + MODULATE( x.g, dst.a ^ 0xff ); + MODULATE( x.b, dst.a ^ 0xff ); + break; + + /* Sargb *= Dargb */ + case DSBF_DESTCOLOR: + MODULATE( x.a, dst.a ); + MODULATE( x.r, dst.r ); + MODULATE( x.g, dst.g ); + MODULATE( x.b, dst.b ); + break; + + /* Sargb *= 1.0 - Dargb */ + case DSBF_INVDESTCOLOR: + MODULATE( x.a, dst.a ^ 0xff ); + MODULATE( x.r, dst.r ^ 0xff ); + MODULATE( x.g, dst.g ^ 0xff ); + MODULATE( x.b, dst.b ^ 0xff ); + break; + + /* ??? */ + case DSBF_SRCALPHASAT: + D_UNIMPLEMENTED(); + break; + + default: + D_BUG( "unknown blend function %d", state->src_blend ); + } + + /* Apply the destination blend function. */ + switch (state->dst_blend) { + /* Dargb *= 0.0 */ + case DSBF_ZERO: + dst.a = dst.r = dst.g = dst.b = 0; + break; + + /* Dargb *= 1.0 */ + case DSBF_ONE: + break; + + /* Dargb *= Sargb */ + case DSBF_SRCCOLOR: + MODULATE( dst.a, src.a ); + MODULATE( dst.r, src.r ); + MODULATE( dst.g, src.g ); + MODULATE( dst.b, src.b ); + break; + + /* Dargb *= 1.0 - Sargb */ + case DSBF_INVSRCCOLOR: + MODULATE( dst.a, src.a ^ 0xff ); + MODULATE( dst.r, src.r ^ 0xff ); + MODULATE( dst.g, src.g ^ 0xff ); + MODULATE( dst.b, src.b ^ 0xff ); + break; + + /* Dargb *= Saaaa */ + case DSBF_SRCALPHA: + MODULATE( dst.a, src.a ); + MODULATE( dst.r, src.a ); + MODULATE( dst.g, src.a ); + MODULATE( dst.b, src.a ); + break; + + /* Dargb *= 1.0 - Saaaa */ + case DSBF_INVSRCALPHA: + MODULATE( dst.a, src.a ^ 0xff ); + MODULATE( dst.r, src.a ^ 0xff ); + MODULATE( dst.g, src.a ^ 0xff ); + MODULATE( dst.b, src.a ^ 0xff ); + break; + + /* Dargb *= Daaaa */ + case DSBF_DESTALPHA: + MODULATE( dst.r, dst.a ); + MODULATE( dst.g, dst.a ); + MODULATE( dst.b, dst.a ); + MODULATE( dst.a, dst.a ); // + break; + + /* Dargb *= 1.0 - Daaaa */ + case DSBF_INVDESTALPHA: + MODULATE( dst.r, dst.a ^ 0xff ); + MODULATE( dst.g, dst.a ^ 0xff ); + MODULATE( dst.b, dst.a ^ 0xff ); + MODULATE( dst.a, dst.a ^ 0xff ); // + break; + + /* Dargb *= Dargb */ + case DSBF_DESTCOLOR: + MODULATE( dst.r, dst.r ); + MODULATE( dst.g, dst.g ); + MODULATE( dst.b, dst.b ); + MODULATE( dst.a, dst.a ); // + break; + + /* Dargb *= 1.0 - Dargb */ + case DSBF_INVDESTCOLOR: + MODULATE( dst.r, dst.r ^ 0xff ); + MODULATE( dst.g, dst.g ^ 0xff ); + MODULATE( dst.b, dst.b ^ 0xff ); + MODULATE( dst.a, dst.a ^ 0xff ); // + break; + + /* ??? */ + case DSBF_SRCALPHASAT: + D_UNIMPLEMENTED(); + break; + + default: + D_BUG( "unknown blend function %d", state->dst_blend ); + } + + /* + * Add blended destination values to the scratch. + */ + x.a += dst.a; + x.r += dst.r; + x.g += dst.g; + x.b += dst.b; + } + + /* Better not use the conversion from premultiplied to non-premultiplied! */ + if (state->blittingflags & DSBLIT_DEMULTIPLY) { + x.r = ((int)x.r << 8) / ((int)x.a + 1); + x.g = ((int)x.g << 8) / ((int)x.a + 1); + x.b = ((int)x.b << 8) / ((int)x.a + 1); + } + + /* + * Output + */ + return x; +} + +/**********************************************************************************************************************/ + +static const char * +blend_to_string( DFBSurfaceBlendFunction func ) +{ + int i; + + for (i=0; i"; +} + +/**********************************************************************************************************************/ + +static void +parse_flags( const char *arg, DFBSurfaceBlittingFlags *ret_flags ) +{ + int i; + + *ret_flags = DSBLIT_NOFX; + + for (i=0; ia = argb >> 24; + ret_color->r = (argb & 0xFF0000) >> 16; + ret_color->g = (argb & 0xFF00) >> 8; + ret_color->b = argb & 0xFF; + + return true; +} + +static bool +parse_blend_func( const char *arg, DFBSurfaceBlendFunction *ret_func ) +{ + int i; + + for (i=0; i[,] Set blitting flags\n" + " -D, --destination <0xAARRGGBB> Set destination value (ARGB32 in hex)\n" + " -S, --source <0xAARRGGBB> Set source value (ARGB32 in hex)\n" + " -c, --color <0xAARRGGBB> Set color (ARGB32 in hex)\n" + " -s, --srcblend Set source blend function\n" + " -d, --dstblend Set destination blend function\n" + "\n" + "Blitting flags:\n", DIRECTFB_VERSION, prg_name ); + + for (i=0; iblittingflags ); + + continue; + } + + if (strcmp (arg, "-D") == 0 || strcmp (arg, "--destination") == 0) { + if (++i == argc) { + print_usage (argv[0]); + return DFB_FALSE; + } + + if (parse_color( argv[i], dest )) + continue; + } + + if (strcmp (arg, "-S") == 0 || strcmp (arg, "--source") == 0) { + if (++i == argc) { + print_usage (argv[0]); + return DFB_FALSE; + } + + if (parse_color( argv[i], source )) + continue; + } + + if (strcmp (arg, "-c") == 0 || strcmp (arg, "--color") == 0) { + if (++i == argc) { + print_usage (argv[0]); + return DFB_FALSE; + } + + if (parse_color( argv[i], &state->color )) + continue; + } + + if (strcmp (arg, "-s") == 0 || strcmp (arg, "--srcblend") == 0) { + if (++i == argc) { + print_usage (argv[0]); + return DFB_FALSE; + } + + if (parse_blend_func( argv[i], &state->src_blend )) + continue; + } + + if (strcmp (arg, "-d") == 0 || strcmp (arg, "--dstblend") == 0) { + if (++i == argc) { + print_usage (argv[0]); + return DFB_FALSE; + } + + if (parse_blend_func( argv[i], &state->dst_blend )) + continue; + } + + print_usage (argv[0]); + + return DFB_FALSE; + } + + return DFB_TRUE; +} + +/**********************************************************************************************************************/ + +int +main( int argc, char *argv[] ) +{ + int i; + CardState state = { .blittingflags = DSBLIT_NOFX }; + DFBColor result; + + /* Initialize sample source and destination values. */ + //DFBColor src = { 0x93, 0x93, 0x93, 0x93 }; + DFBColor dst = { 0xf0, 0xe0, 0xe0, 0xe0 }; + +#define DRAWSTRING_PREMULT_FONT 1 + + /* Initialize default rendering state. */ +#if DRAWSTRING_PREMULT_FONT + /* Initialize sample source and destination values. */ + DFBColor src = { 0x93, 0x93, 0x93, 0x93 }; + + state.blittingflags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE; + state.src_blend = DSBF_ONE; + state.dst_blend = DSBF_INVSRCALPHA; + state.color.a = 0x81; + state.color.r = 0xff; + state.color.g = 0x80; + state.color.b = 0x23; +#elif DRAWSTRING_NONPREMULT_ALPHADROP + /* Initialize sample source and destination values. */ + DFBColor src = { 0x93, 0xff, 0xff, 0xff }; + + state.blittingflags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE; + state.src_blend = DSBF_SRCALPHA; + state.dst_blend = DSBF_INVSRCALPHA; + state.color.a = 0x81; + state.color.r = 0xff; + state.color.g = 0x80; + state.color.b = 0x23; +#endif + + /* Startup the blitting FX demonstrator. */ + printf( "\ndfbfx v" DIRECTFB_VERSION "\n\n" ); + + if (!parse_command_line( argc, argv, &state, &dst, &src )) + return -1; + + /* Show blitting flags being used. */ + printf( " blit_flags: " ); + for (i=0; i> 16, (state.src_colorkey >> 8) & 0xff, state.src_colorkey & 0xff ); + + /* Show original destination values. */ + printf( " dst: %02x %02x %02x %02x\n", dst.a, dst.r, dst.g, dst.b ); + + /* Show destination color key. */ + if (state.blittingflags & DSBLIT_DST_COLORKEY) + printf( " dst_key: %02x %02x %02x\n", + state.dst_colorkey >> 16, (state.dst_colorkey >> 8) & 0xff, state.dst_colorkey & 0xff ); + + /* Do magic... */ + result = blit_pixel( &state, src, dst ); + + /* Show resulting values. */ + printf( " result: %02x %02x %02x %02x\n", result.a, result.r, result.g, result.b ); + + return 0; +} + -- cgit