Hi, On 02/09/10 19:55, Vaclav Slavik wrote: > it looks like there's a bug in the optimized RGB24 -> RGB16 conversion > routine for little-endian machines (on master, for a long time now): it > swaps the red and blue channels. > > Attached is a patch against the df_porter example that modifies it to > show two bitmaps one under another. They should be identical, but the > top one is rendered directly from DSPF_RGB24 surface, while the bottom > one is first blitted into DSPF_RGB16 surface and then to the screen. But > the two images differ (LE machine, using SDL system). Works correctly if > I disable Bop_rgb24_to_Aop_rgb16_LE. > > Sorry for not providing a patch, I'm still getting lost in this code :( > I was hoping that perhaps the fix would be obvious to somebody more > familiar with this code.
Attached is a git-formatted patch by Anders Larsen that fixes the bug. Thanks, Vaclav
From: Anders Larsen <a...@alarsen.net> Date: Tue, 14 Sep 2010 11:57:15 +0200 Subject: [PATCH] Remove the BGR->RGB conversion from Bop_rgb24_to_Aop_rgb16_LE() DSPF_RGB24 and DSPF_RGB16 are both organised with blue at the lowest address, but Bop_rgb24_to_Aop_rgb16_LE() seemed to assume that DSPF_RGB24 had red at the lowest address and therefore swapped the red and blue colours. Removing this conversion fixes the issue reported in http://mail.directfb.org/pipermail/directfb-dev/2010-September/005820.html Signed-off-by: Anders Larsen <a...@alarsen.net> --- src/gfx/generic/generic.c | 16 ++++++---------- 1 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/gfx/generic/generic.c b/src/gfx/generic/generic.c index f098d16..96c037c 100644 --- a/src/gfx/generic/generic.c +++ b/src/gfx/generic/generic.c @@ -9366,10 +9366,6 @@ void gGetDeviceInfo( GraphicsDeviceInfo *info ) DSBLIT_XOR) #ifndef WORDS_BIGENDIAN -#define BGR_TO_RGB16(pixel) ( (((pixel) << 8) & 0xF800) | \ - (((pixel) >> 5) & 0x07E0) | \ - (((pixel) >> 19) & 0x001F) ) - /* * Fast RGB24 to RGB16 conversion. */ @@ -9381,20 +9377,20 @@ Bop_rgb24_to_Aop_rgb16_LE( GenefxState *gfxs ) u16 *D = gfxs->Aop[0]; while ((unsigned long)S & 3) { - *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + *D++ = PIXEL_RGB16( S[2], S[1], S[0] ); S += 3; w -= 1; } if ((unsigned long)D & 2) { - *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + *D++ = PIXEL_RGB16( S[2], S[1], S[0] ); w -= 1; S += 3; while (w > 1) { - *(u32*)D = PIXEL_RGB16( S[0], S[1], S[2] ) | (PIXEL_RGB16( S[3], S[4], S[5] ) << 16); + *(u32*)D = PIXEL_RGB16( S[2], S[1], S[0] ) | (PIXEL_RGB16( S[5], S[4], S[3] ) << 16); w -= 2; D += 2; @@ -9406,8 +9402,8 @@ Bop_rgb24_to_Aop_rgb16_LE( GenefxState *gfxs ) u32 *D32 = (u32*)D; while (w > 3) { - D32[0] = BGR_TO_RGB16( S32[0] ) | (BGR_TO_RGB16( (S32[0] >> 24) | (S32[1] << 8) ) << 16); - D32[1] = BGR_TO_RGB16( (S32[1] >> 16) | (S32[2] << 16) ) | (BGR_TO_RGB16( S32[2] >> 8 ) << 16); + D32[0] = RGB32_TO_RGB16( S32[0] ) | (RGB32_TO_RGB16( (S32[0] >> 24) | (S32[1] << 8) ) << 16); + D32[1] = RGB32_TO_RGB16( (S32[1] >> 16) | (S32[2] << 16) ) | (RGB32_TO_RGB16( S32[2] >> 8 ) << 16); D32 += 2; S32 += 3; @@ -9419,7 +9415,7 @@ Bop_rgb24_to_Aop_rgb16_LE( GenefxState *gfxs ) } while (w > 0) { - *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + *D++ = PIXEL_RGB16( S[2], S[1], S[0] ); w -= 1; S += 3; -- 1.5.4.3
_______________________________________________ directfb-dev mailing list directfb-dev@directfb.org http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev