BUG?: RGBA->screen blit has 1-off error with opaque colors

The attached program should print “First pixel: 00FFFFFF” but instead
of that I get “First pixel: 00FEFEFE”

Am I right in thinking that this is a bug in SDL?

OS is Linux (Knoppix 4.0.2)
SDL version is 1.2.11–
Markus Laire
-------------- next part --------------
A non-text attachment was scrubbed…
Name: bug.c
Type: text/x-csrc
Size: 1847 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070606/b963ec3d/attachment.c

Here is even smaller test-case. This program should print
"FFFFFF…FFFFFF" but prints “FEFEFE…FEFEFE” instead.

If the SDL_SetAlpha-call is uncommented, this works as expected, so
the problem seems to be in alpha-blitting.On 6/6/07, Markus Laire <@Markus_Laire> wrote:

The attached program should print “First pixel: 00FFFFFF” but instead
of that I get “First pixel: 00FEFEFE”

Am I right in thinking that this is a bug in SDL?

OS is Linux (Knoppix 4.0.2)
SDL version is 1.2.11


Markus Laire
-------------- next part --------------
A non-text attachment was scrubbed…
Name: bug2.c
Type: text/x-csrc
Size: 846 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070606/c9e12325/attachment.c

The attached file had small error: The SDL_SetAlpha-call should be
commented to get the error.On 6/6/07, Markus Laire <@Markus_Laire> wrote:

The attached program should print “First pixel: 00FFFFFF” but instead
of that I get “First pixel: 00FEFEFE”

Am I right in thinking that this is a bug in SDL?

OS is Linux (Knoppix 4.0.2)
SDL version is 1.2.11


Markus Laire

I think this is the result of the blitters multiplying by the alpha
value, and then dividing by 256 (8 bit right shift) rather than 255.
(Actual division is very expensive, compared to shift operations!)

One way around this is to scale the alpha value from [0, 255] to [0,
256]. In the case of full surface alpha, this costs virtually
nothing, but it would probably slow down alpha channel (RGBA) blits
quite a bit - although not nearly as much as actually dividing by 255
for each channel.

One could cheat by scaling the alpha channel to [0, 128] and shifting
7 bits, but obviosuly, that results in a “funny” pixel format, and
less accurate blending… Another hack is to add 1 somewhere, but
then you just get 1 instead of 0 for “fully” transparent.

I’m afraid there is no easy, low cost solution - which is why it is
the way it is, I would think.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Wednesday 06 June 2007, Markus Laire wrote:

The attached program should print “First pixel: 00FFFFFF” but
instead of that I get “First pixel: 00FEFEFE”

Am I right in thinking that this is a bug in SDL?

OS is Linux (Knoppix 4.0.2)
SDL version is 1.2.11

I think this is the result of the blitters multiplying by the alpha
value, and then dividing by 256 (8 bit right shift) rather than 255.
(Actual division is very expensive, compared to shift operations!)

What about checking whether the alpha value is 255, and in that case
just copying the color instead of multiply and bit-shift?

I find this bug to be quite annnoying as currently I can’t have fully
opaque colors when using the alpha-channel.On 6/6/07, David Olofson wrote:

One way around this is to scale the alpha value from [0, 255] to [0,
256]. In the case of full surface alpha, this costs virtually
nothing, but it would probably slow down alpha channel (RGBA) blits
quite a bit - although not nearly as much as actually dividing by 255
for each channel.

One could cheat by scaling the alpha channel to [0, 128] and shifting
7 bits, but obviosuly, that results in a “funny” pixel format, and
less accurate blending… Another hack is to add 1 somewhere, but
then you just get 1 instead of 0 for “fully” transparent.

I’m afraid there is no easy, low cost solution - which is why it is
the way it is, I would think.


Markus Laire

Markus Laire wrote:

I find this bug to be quite annnoying as currently I can’t have fully
opaque colors when using the alpha-channel.

I’ve come across something similar which causes problems when trying to
implement a cursor using xor. It’s more than just annoying in that case.

regards,

Colin–
Colin Tuckley | @Colin_Tuckley | PGP/GnuPG Key Id
+44(0)1903 236872 | +44(0)7799 143369 | 0x1B3045CE

Common Sense is the collection of prejudices acquired by age eighteen. - A.
Einstein

Hello !

I’ve come across something similar which causes problems when trying to
implement a cursor using xor. It’s more than just annoying in that case.

For me the first thing is that the blitting
of SDL should be exact. Speed comes after that.
If someone needs fast Alpha Bleding and if SDL
is not fast enough, he might use OpenGL.

CU

If accuracy is the primary concern, maybe SDL isn’t the right API in
the first place? It doesn’t really get alpha right at all anyway.
(Alpha should not be linear with normal gamma curves!) And, it
doesn’t do any other blending than alpha. There are other rendering
APIs that are much more powerful and much more accurate, if
performance is of less importance;
http://cairographics.org/
http://www.khronos.org/openvg/
http://www.antigrain.com/

Regardless of requirements, OpenGL is usually not an option on low end
hardware, such as handheld devices and embedded systems. These
usually have rather slow CPUs, so there really isn’t room for
anything but fast algorithms that deliver “reasonable” results. For
demanding 2D games, the only option would be 100% custom rendering
code, but SDL performs well enough that many applications can get
away without this, even on this kind of hardware. This would not be
realistically possible with an API that is required to maintain 100%
accuracy.

You could have both speed and accuracy through the same API - with
multiple implementations… How about an SDL 1.3/2.0 patch with
alternate, run time selectable software blitters? More code to
maintain, though, and I’m not ever sure it’s appropriate for SDL.

//David Olofson - Programmer, Composer, Open Source Advocate

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Wednesday 06 June 2007, Torsten Giebl wrote:

Hello !

I’ve come across something similar which causes problems when
trying to implement a cursor using xor. It’s more than just
annoying in that case.

For me the first thing is that the blitting
of SDL should be exact. Speed comes after that.
If someone needs fast Alpha Bleding and if SDL
is not fast enough, he might use OpenGL.