# Problems with getpixel

I’m tying to get the pixel in red, green, blue components, using the
getpixel function explain in the examples and using SDL_GetRGB() to convert
from pixel to r, g, b.

My problem is this: in 16 bpp mode the value returned from white( 255, 255,
255 ) is r:248, g:252, b:248.
the exact values that say it “wouldn’t” return.

why is that?_________________________________________________________________
Tired of spam? Get advanced junk mail protection with MSN 8.
http://join.msn.com/?page=features/junkmail

I’d have to see the exact SDL_GetRGB() routine to fix
the code, but I’ve mentioned this before… it
basically stems from the descrepency of dividing by
2^N and not 2^N-1… this is a slight gyration of
that…

16-bit color is 565 meaning 5 red bits, 6 green bits,
and 5 blue bits… so, white is really 31,63,31 (not
255,255,255)… to normalize it back to 24 bit, the
current function is shifting the most significant bits
into the their correct positions …

if the source range is 0-31 and the dest range is
0-255, then you should multiply by 255, and divide by
31… to optimize this, this is converted into a
multiply by 256, divide by 32, which is the same as a
SHIFT left 8 and a SHIFT right of 5… (or a net shift
of 3)… Doing the actual multiply and divide would
be extremely slow. what I do recommend is if you look
at the bit pattern on the real divide, you’ll notice
that the bits repeat:

Lets take the bit pattern 10101 (or 21 decimal)…
(21*255)/31 is 172.72, so let’s round to 173… 173 is
10101101… (notice the 10101 that we shifted left 3
is right… but the 101 is the 3 MSBs from the original
number…) so… to convert from 0-31 to 0-255
quickly, we can shift left 3, and or that with
shifting right 2…

Appling that to the extremes 00000 (0) becomes
00000000 (0) and 11111(31) becomes 11111111(255)… It
might not be a perfect approximation, but it’s damn
close…

The approach should be easy to generalize at least
down to a 1:2 ratio of bits, and a loop can take care
of the remaining bits…

Email me (offlist) the existing SDL_GetRGB() function
(last I checked it was external to the SDL API in
several incarnations), and I can post the adjusted
function back to the list… (Not sure which FAQ you
found this incarnation of the function in, or who the
maintainer of that FAQ is, but they might want to
update the function there…)

Hope this helped,

-Loren Osborn
Software Engineer

— david roguin wrote:>

I’m tying to get the pixel in red, green, blue
components, using the
getpixel function explain in the examples and using
SDL_GetRGB() to convert
from pixel to r, g, b.

My problem is this: in 16 bpp mode the value
returned from white( 255, 255,
255 ) is r:248, g:252, b:248.
the exact values that say it “wouldn’t” return.

why is that?

Tired of spam? Get advanced junk mail protection
with MSN 8.
http://join.msn.com/?page=features/junkmail

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software

The SDL_GetRGB() function comes with the SDL 1.2.5 (the last version).
i figured out that it was something with the bits size, but in the docs says
crearly:

“This function uses the entire 8-bit [0…255] range when converting color
components from pixel formats with less than 8-bits per RGB component (e.g.,
a completely white pixel in 16-bit RGB565 format would return [0xff, 0xff,
0xff] not [0xf8, 0xfc, 0xf8]).”

so. if i want to know if something hit something red i have to ask for 248,
0, 0. and it will work in every PC running on 16 bits?> I’d have to see the exact SDL_GetRGB() routine to fix

the code, but I’ve mentioned this before… it
basically stems from the descrepency of dividing by
2^N and not 2^N-1… this is a slight gyration of
that…

16-bit color is 565 meaning 5 red bits, 6 green bits,
and 5 blue bits… so, white is really 31,63,31 (not
255,255,255)… to normalize it back to 24 bit, the
current function is shifting the most significant bits
into the their correct positions …

if the source range is 0-31 and the dest range is
0-255, then you should multiply by 255, and divide by
31… to optimize this, this is converted into a
multiply by 256, divide by 32, which is the same as a
SHIFT left 8 and a SHIFT right of 5… (or a net shift
of 3)… Doing the actual multiply and divide would
be extremely slow. what I do recommend is if you look
at the bit pattern on the real divide, you’ll notice
that the bits repeat:

Lets take the bit pattern 10101 (or 21 decimal)…
(21*255)/31 is 172.72, so let’s round to 173… 173 is
10101101… (notice the 10101 that we shifted left 3
is right… but the 101 is the 3 MSBs from the original
number…) so… to convert from 0-31 to 0-255
quickly, we can shift left 3, and or that with
shifting right 2…

Appling that to the extremes 00000 (0) becomes
00000000 (0) and 11111(31) becomes 11111111(255)… It
might not be a perfect approximation, but it’s damn
close…

The approach should be easy to generalize at least
down to a 1:2 ratio of bits, and a loop can take care
of the remaining bits…

Email me (offlist) the existing SDL_GetRGB() function
(last I checked it was external to the SDL API in
several incarnations), and I can post the adjusted
function back to the list… (Not sure which FAQ you
found this incarnation of the function in, or who the
maintainer of that FAQ is, but they might want to
update the function there…)

Hope this helped,

-Loren Osborn
Software Engineer

— david roguin wrote:

I’m tying to get the pixel in red, green, blue
components, using the
getpixel function explain in the examples and using
SDL_GetRGB() to convert
from pixel to r, g, b.

My problem is this: in 16 bpp mode the value
returned from white( 255, 255,
255 ) is r:248, g:252, b:248.
the exact values that say it “wouldn’t” return.

why is that?

Tired of spam? Get advanced junk mail protection
with MSN 8.
http://join.msn.com/?page=features/junkmail

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Ok… I did a little research. First, as far as
suggesting that SDL_GetRGB() wasn’t part of the the
SDL API, I appologize, I was confusing it with
sdl_get_pixel() that I’ve seen in many incarnations in
many FAQs here and there. Secondly, If you’re not
using SDL out of CVS, I suggest you try this.
“There’s an embarrassing bug in GetRGB/GetRGBA which
apparently has been there for years.”… fixed by
Mattias Engdeg?rd, and submitted to CVS only 13 days
ago (so I doubt it’s in 1.2.5). I glanced at the
code, and will examine it in a couple days, and get
back to you. (I am pretty confident it DOESN’T work
for color depths with less than 4 bits per channel,
but that affects almost NO users.)

So… the SHORT ANSWER is, there was a bug in
SDL_GetRGB() that was fixed in CVS 13 days ago, and
will PROBABLY solve your problem. (I will get back to
you in a couple days to hopefully expand the fix to
work with color-depths < 4 bits per channel.)

I hope that this helps,

-Loren

— David Roguin wrote:> The SDL_GetRGB() function comes with the SDL 1.2.5

(the last version).
i figured out that it was something with the bits
size, but in the docs says
crearly:

“This function uses the entire 8-bit [0…255] range
when converting color
components from pixel formats with less than 8-bits
per RGB component (e.g.,
a completely white pixel in 16-bit RGB565 format
would return [0xff, 0xff,
0xff] not [0xf8, 0xfc, 0xf8]).”

so. if i want to know if something hit something red
i have to ask for 248,
0, 0. and it will work in every PC running on 16
bits?

I’d have to see the exact SDL_GetRGB() routine to
fix
the code, but I’ve mentioned this before… it
basically stems from the descrepency of dividing
by
2^N and not 2^N-1… this is a slight gyration of
that…

16-bit color is 565 meaning 5 red bits, 6 green
bits,
and 5 blue bits… so, white is really 31,63,31
(not
255,255,255)… to normalize it back to 24 bit,
the
current function is shifting the most significant
bits
into the their correct positions …

if the source range is 0-31 and the dest range is
0-255, then you should multiply by 255, and divide
by
31… to optimize this, this is converted into a
multiply by 256, divide by 32, which is the same
as a
SHIFT left 8 and a SHIFT right of 5… (or a net
shift
of 3)… Doing the actual multiply and divide
would
be extremely slow. what I do recommend is if you
look
at the bit pattern on the real divide, you’ll
notice
that the bits repeat:

Lets take the bit pattern 10101 (or 21 decimal)…
(21*255)/31 is 172.72, so let’s round to 173…
173 is
10101101… (notice the 10101 that we shifted left
3
is right… but the 101 is the 3 MSBs from the
original
number…) so… to convert from 0-31 to 0-255
quickly, we can shift left 3, and or that with
shifting right 2…

Appling that to the extremes 00000 (0) becomes
00000000 (0) and 11111(31) becomes
11111111(255)… It
might not be a perfect approximation, but it’s
damn
close…

The approach should be easy to generalize at
least
down to a 1:2 ratio of bits, and a loop can take
care
of the remaining bits…

Email me (offlist) the existing SDL_GetRGB()
function
(last I checked it was external to the SDL API in
several incarnations), and I can post the adjusted
function back to the list… (Not sure which FAQ
you
found this incarnation of the function in, or who
the
maintainer of that FAQ is, but they might want to
update the function there…)

Hope this helped,

-Loren Osborn
Software Engineer

— david roguin wrote:

I’m tying to get the pixel in red, green, blue
components, using the
getpixel function explain in the examples and
using

SDL_GetRGB() to convert
from pixel to r, g, b.

My problem is this: in 16 bpp mode the value
returned from white( 255, 255,
255 ) is r:248, g:252, b:248.
the exact values that say it “wouldn’t” return.

why is that?

Tired of spam? Get advanced junk mail protection
with MSN 8.
http://join.msn.com/?page=features/junkmail

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site
design software
http://sitebuilder.yahoo.com

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software

it helps a lot thanks…!!
on more question:
will they put the fix in the sdl 1.2.6 or if i download the 1.2.5 it should
be fixed??> ----- Original Message -----

From: linux_dr@yahoo.com (Loren Osborn)
To:
Sent: Monday, August 25, 2003 3:48 PM
Subject: RE: [SDL] problems with getpixel

Ok… I did a little research. First, as far as
suggesting that SDL_GetRGB() wasn’t part of the the
SDL API, I appologize, I was confusing it with
sdl_get_pixel() that I’ve seen in many incarnations in
many FAQs here and there. Secondly, If you’re not
using SDL out of CVS, I suggest you try this.
“There’s an embarrassing bug in GetRGB/GetRGBA which
apparently has been there for years.”… fixed by
Mattias Engdeg?rd, and submitted to CVS only 13 days
ago (so I doubt it’s in 1.2.5). I glanced at the
code, and will examine it in a couple days, and get
back to you. (I am pretty confident it DOESN’T work
for color depths with less than 4 bits per channel,
but that affects almost NO users.)

So… the SHORT ANSWER is, there was a bug in
SDL_GetRGB() that was fixed in CVS 13 days ago, and
will PROBABLY solve your problem. (I will get back to
you in a couple days to hopefully expand the fix to
work with color-depths < 4 bits per channel.)

I hope that this helps,

-Loren

— David Roguin wrote:

The SDL_GetRGB() function comes with the SDL 1.2.5
(the last version).
i figured out that it was something with the bits
size, but in the docs says
crearly:

“This function uses the entire 8-bit [0…255] range
when converting color
components from pixel formats with less than 8-bits
per RGB component (e.g.,
a completely white pixel in 16-bit RGB565 format
would return [0xff, 0xff,
0xff] not [0xf8, 0xfc, 0xf8]).”

so. if i want to know if something hit something red
i have to ask for 248,
0, 0. and it will work in every PC running on 16
bits?

I’d have to see the exact SDL_GetRGB() routine to
fix
the code, but I’ve mentioned this before… it
basically stems from the descrepency of dividing
by
2^N and not 2^N-1… this is a slight gyration of
that…

16-bit color is 565 meaning 5 red bits, 6 green
bits,
and 5 blue bits… so, white is really 31,63,31
(not
255,255,255)… to normalize it back to 24 bit,
the
current function is shifting the most significant
bits
into the their correct positions …

if the source range is 0-31 and the dest range is
0-255, then you should multiply by 255, and divide
by
31… to optimize this, this is converted into a
multiply by 256, divide by 32, which is the same
as a
SHIFT left 8 and a SHIFT right of 5… (or a net
shift
of 3)… Doing the actual multiply and divide
would
be extremely slow. what I do recommend is if you
look
at the bit pattern on the real divide, you’ll
notice
that the bits repeat:

Lets take the bit pattern 10101 (or 21 decimal)…
(21*255)/31 is 172.72, so let’s round to 173…
173 is
10101101… (notice the 10101 that we shifted left
3
is right… but the 101 is the 3 MSBs from the
original
number…) so… to convert from 0-31 to 0-255
quickly, we can shift left 3, and or that with
shifting right 2…

Appling that to the extremes 00000 (0) becomes
00000000 (0) and 11111(31) becomes
11111111(255)… It
might not be a perfect approximation, but it’s
damn
close…

The approach should be easy to generalize at
least
down to a 1:2 ratio of bits, and a loop can take
care
of the remaining bits…

Email me (offlist) the existing SDL_GetRGB()
function
(last I checked it was external to the SDL API in
several incarnations), and I can post the adjusted
function back to the list… (Not sure which FAQ
you
found this incarnation of the function in, or who
the
maintainer of that FAQ is, but they might want to
update the function there…)

Hope this helped,

-Loren Osborn
Software Engineer

— david roguin wrote:

I’m tying to get the pixel in red, green, blue
components, using the
getpixel function explain in the examples and
using

SDL_GetRGB() to convert
from pixel to r, g, b.

My problem is this: in 16 bpp mode the value
returned from white( 255, 255,
255 ) is r:248, g:252, b:248.
the exact values that say it “wouldn’t” return.

why is that?

Tired of spam? Get advanced junk mail protection
with MSN 8.
http://join.msn.com/?page=features/junkmail

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site
design software
http://sitebuilder.yahoo.com

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

it helps a lot thanks…!!
on more question:
will they put the fix in the sdl 1.2.6 or if i download the 1.2.5 it should
be fixed??

The fix will be in SDL 1.2.6

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment