Help with displaying grayscale buffers

I’m trying to use SDL to display a 16bpp grayscale buffer that is acquired
from a camera. I am using the following code:

SDLSurface *screen, *image, *temp;
SDL_Rect src, dest;
unsigned short buffer[1572864]

temp = SDL_CreateRGBSurfaceFrom(buffer, 1536, 1024, bytesPerPixel * 8, 1536

  • bytesPerPixel, 255, 255, 255, 0); // bytesPerPixel has value 2
    image = SDL_DisplayFormat(temp);
    dest.x = src.x = 0;
    dest.y = src.y = 0;
    dest.h = src.h = temp->h;
    dest.w = src.w = temp->w;
    SDL_BlitSurface(image, &src, screen, &dest);
    SDL_FreeSurface(image);
    SDL_Flip(screen);
    SDL_FreeSurface(temp);

That’s it. Now, the weird thing that I’m seeing is that the image displays,
sort of. What I get when I try to display the surface is something like a
negative of the image, with weird gradients instead of a nice smooth
grayscale. I have a routine that saves the buffer to a TIFF and when I look
at the TIFF file, everything looks exactly the way it’s supposed to.
However, I would also like to have a real time display of the buffer, and I
can’t figure out what I’m doing wrong.

I’ve included a sample image to illustrate the problem. You can ignore the
text on the screen but as you can see, it’s grainy rather than smooth and
there is some sort of weird sunburst on the right. I know that these are
artifacts of the display code since I have a TIFF file that looks normal (in
this case I’m looking at a dark piece of posterboard).

I would appreciate any help or hints as to how I can fix this problem.

Jerry
http://www.nabble.com/file/p16599288/camview.png camview.png–
View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16599288.html
Sent from the SDL mailing list archive at Nabble.com.

From a totally generic hardware POV, 16 bit color can be done in usually 3
different ways. You need to know how many bits each color really gets and
what their positions are in the 16 bit value. You will have something like
5:6:5; meaning 5 bits of red, 6 bits of green and 5 bits of blue. From the
description of what you see, it sounds like this is what is out of order.

Could be:

6:5:5
5:6:5
5:5:6

Another thing to point out here is that there is no proper translation to 24
bit RGB. Or if there is, I don’t get it. If you have only 5 bits to
represent from black to fully lit, that’s 32 levels. However, if you take
those 5 bits and tack 3 zeros on the end, you do not get 255; fully lit in 8
bits. What I did for this in EZFB was shift the 5 bits up to 8 and shift the
3 MSBs down to fill in the missing bits. I think this distributes the error
evenly.

James. :o)> ----- Original Message -----

From: grapesmoker@gmail.com (grapesmoker)
To:
Sent: Monday, April 14, 2008 5:05 PM
Subject: [SDL] help with displaying grayscale buffers

I’m trying to use SDL to display a 16bpp grayscale buffer that is acquired
from a camera. I am using the following code:

SDLSurface *screen, *image, *temp;
SDL_Rect src, dest;
unsigned short buffer[1572864]

temp = SDL_CreateRGBSurfaceFrom(buffer, 1536, 1024, bytesPerPixel * 8,
1536

  • bytesPerPixel, 255, 255, 255, 0); // bytesPerPixel has value 2
    image = SDL_DisplayFormat(temp);
    dest.x = src.x = 0;
    dest.y = src.y = 0;
    dest.h = src.h = temp->h;
    dest.w = src.w = temp->w;
    SDL_BlitSurface(image, &src, screen, &dest);
    SDL_FreeSurface(image);
    SDL_Flip(screen);
    SDL_FreeSurface(temp);

That’s it. Now, the weird thing that I’m seeing is that the image
displays,
sort of. What I get when I try to display the surface is something like a
negative of the image, with weird gradients instead of a nice smooth
grayscale. I have a routine that saves the buffer to a TIFF and when I
look
at the TIFF file, everything looks exactly the way it’s supposed to.
However, I would also like to have a real time display of the buffer, and
I
can’t figure out what I’m doing wrong.

I’ve included a sample image to illustrate the problem. You can ignore the
text on the screen but as you can see, it’s grainy rather than smooth and
there is some sort of weird sunburst on the right. I know that these are
artifacts of the display code since I have a TIFF file that looks normal
(in
this case I’m looking at a dark piece of posterboard).

I would appreciate any help or hints as to how I can fix this problem.

Jerry
http://www.nabble.com/file/p16599288/camview.png camview.png

View this message in context:
http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16599288.html
Sent from the SDL mailing list archive at Nabble.com.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Wait a minute!

You probably have only (1) 16-bit value to look at simply as a light
intensity.

Do you have a video card that can show you 16 bits of resolution of pure
intensity?
I think you’d need a card that can do 16 bits on each of the RGB DACs.

If SDL is structured all the way through to look at RGB color values as 8
bit values, then you’re kinda’ screwed.

What OS are you dealing with?

James. :o)> ----- Original Message -----

From: @James_Lehman (James Lehman)
To: "A list for developers using the SDL library. (includes SDL-announce)"

Sent: Monday, April 14, 2008 6:26 PM
Subject: Re: [SDL] help with displaying grayscale buffers

From a totally generic hardware POV, 16 bit color can be done in usually 3
different ways. You need to know how many bits each color really gets and
what their positions are in the 16 bit value. You will have something like
5:6:5; meaning 5 bits of red, 6 bits of green and 5 bits of blue. From the
description of what you see, it sounds like this is what is out of order.

Could be:

6:5:5
5:6:5
5:5:6

Another thing to point out here is that there is no proper translation to
24
bit RGB. Or if there is, I don’t get it. If you have only 5 bits to
represent from black to fully lit, that’s 32 levels. However, if you take
those 5 bits and tack 3 zeros on the end, you do not get 255; fully lit in
8
bits. What I did for this in EZFB was shift the 5 bits up to 8 and shift
the
3 MSBs down to fill in the missing bits. I think this distributes the
error
evenly.

James. :o)

----- Original Message -----
From: “grapesmoker”
To:
Sent: Monday, April 14, 2008 5:05 PM
Subject: [SDL] help with displaying grayscale buffers

I’m trying to use SDL to display a 16bpp grayscale buffer that is
acquired

from a camera. I am using the following code:

SDLSurface *screen, *image, *temp;
SDL_Rect src, dest;
unsigned short buffer[1572864]

temp = SDL_CreateRGBSurfaceFrom(buffer, 1536, 1024, bytesPerPixel * 8,
1536

  • bytesPerPixel, 255, 255, 255, 0); // bytesPerPixel has value 2
    image = SDL_DisplayFormat(temp);
    dest.x = src.x = 0;
    dest.y = src.y = 0;
    dest.h = src.h = temp->h;
    dest.w = src.w = temp->w;
    SDL_BlitSurface(image, &src, screen, &dest);
    SDL_FreeSurface(image);
    SDL_Flip(screen);
    SDL_FreeSurface(temp);

That’s it. Now, the weird thing that I’m seeing is that the image
displays,
sort of. What I get when I try to display the surface is something like
a

negative of the image, with weird gradients instead of a nice smooth
grayscale. I have a routine that saves the buffer to a TIFF and when I
look
at the TIFF file, everything looks exactly the way it’s supposed to.
However, I would also like to have a real time display of the buffer,
and
I

can’t figure out what I’m doing wrong.

I’ve included a sample image to illustrate the problem. You can ignore
the

text on the screen but as you can see, it’s grainy rather than smooth
and

there is some sort of weird sunburst on the right. I know that these are
artifacts of the display code since I have a TIFF file that looks normal
(in
this case I’m looking at a dark piece of posterboard).

I would appreciate any help or hints as to how I can fix this problem.

Jerry
http://www.nabble.com/file/p16599288/camview.png camview.png

View this message in context:

http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16599288.html

Sent from the SDL mailing list archive at Nabble.com.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi James,

You are correct, I only have one 16-bit value that represents the light
intensity. I should have made that clearer.

I am using Windows XP and the video card I have supports that resolution.
The weirdest thing is that I once got this code to work, but then I changed
something (I don’t remember what) and I no longer am able to view the image
the way I want (which would be as a smooth grayscale). I would settle for an
8-bit grayscale too, since the display itself is not for precision
measurements (those are done on the saved images).

Is the image I uploaded visible? I could upload another if it’s not. Thanks
for your attempt to help.

Jerry

another james wrote:>

Wait a minute!

You probably have only (1) 16-bit value to look at simply as a light
intensity.

Do you have a video card that can show you 16 bits of resolution of pure
intensity?
I think you’d need a card that can do 16 bits on each of the RGB DACs.

If SDL is structured all the way through to look at RGB color values as 8
bit values, then you’re kinda’ screwed.

What OS are you dealing with?

James. :o)


View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16692727.html
Sent from the SDL mailing list archive at Nabble.com.

Well, you could try to put just the top 8 bits of that 16 bit number into a
color statement like this:

SDL_MapRGB(screen->format, value >> 8, value >> 8, value >> 8);

James. :o)

grapesmoker wrote:>

Hi James,

You are correct, I only have one 16-bit value that represents the light
intensity. I should have made that clearer.

I am using Windows XP and the video card I have supports that resolution.
The weirdest thing is that I once got this code to work, but then I
changed something (I don’t remember what) and I no longer am able to view
the image the way I want (which would be as a smooth grayscale). I would
settle for an 8-bit grayscale too, since the display itself is not for
precision measurements (those are done on the saved images).

Is the image I uploaded visible? I could upload another if it’s not.
Thanks for your attempt to help.

Jerry

another james wrote:

Wait a minute!

You probably have only (1) 16-bit value to look at simply as a light
intensity.

Do you have a video card that can show you 16 bits of resolution of pure
intensity?
I think you’d need a card that can do 16 bits on each of the RGB DACs.

If SDL is structured all the way through to look at RGB color values as 8
bit values, then you’re kinda’ screwed.

What OS are you dealing with?

James. :o)


View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16692970.html
Sent from the SDL mailing list archive at Nabble.com.

Thanks, I’ll try that tomorrow.

another james wrote:>

Well, you could try to put just the top 8 bits of that 16 bit number into
a color statement like this:

Uint8 gray;

gray = value >> 8;
color = SDL_MapRGB(screen->format, gray, gray, gray);

James. :o)


View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16693739.html
Sent from the SDL mailing list archive at Nabble.com.

SDL has no support for any color component >8-bit. You have two options.

  • Truncate the color values with SDL using 0xFF00 instead of 0xFF or
    255 in your masks passed to CreateRGBSurface. It might not work, but
    it’s the easiest way to handle it.
  • Downsample (with or without dithering) the source image into an
    8-bit grayscale buffer. If you like, I could whip up some code to do
    it efficiently.
    -:sigma.SBOn 4/14/08, grapesmoker wrote:

I’m trying to use SDL to display a 16bpp grayscale buffer that is acquired
from a camera.

The reason I asked about what OS you are using is because the Linux frame
buffer architecture is set up for native 16 bit resolution on each of the
(possibly) 4 channels of RGBA internally.

I have never had a video card that can do that, so I have no way to test it,
but I bet I could get it to work in EZFB!

http://akrobiz.com/ezfb/

James. :o)–
View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16695624.html
Sent from the SDL mailing list archive at Nabble.com.

There was a previous thread on converting surfaces to grayscale. I
can’t seem to log into the mailing list page at the moment, but the
subject thread was:

[SDL] How to gray out a button image?

-Will

Hi Solra,

I think the second solution you are proposing might work for me. I tried
playing with the mask values passed to CreateRGBSurfaceFrom but it didn’t
seem to help. This does kind of seem like a dithering problem, but since I’m
not really well-versed in graphics programming, I’m not sure how to approach
it. Any suggestions would be appreciated.

Thanks,
Jerry

Solra Bizna wrote:>

On 4/14/08, grapesmoker <@grapesmoker> wrote:

I’m trying to use SDL to display a 16bpp grayscale buffer that is
acquired
from a camera.
SDL has no support for any color component >8-bit. You have two options.

  • Truncate the color values with SDL using 0xFF00 instead of 0xFF or
    255 in your masks passed to CreateRGBSurface. It might not work, but
    it’s the easiest way to handle it.
  • Downsample (with or without dithering) the source image into an
    8-bit grayscale buffer. If you like, I could whip up some code to do
    it efficiently.
    -:sigma.SB

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16700860.html
Sent from the SDL mailing list archive at Nabble.com.

So, I think I’ve figured out my problem. Looks like I’m pretty dumb:

I was so sure that I was saving 16-bit images that I didn’t even think about
double-checking that. I tried using the mask 0xFF00 on all the colors in
CreateRGBSurfaceFrom, and I got a smooth image, but it was very dim…
almost as if the higher order bits were all 0! So of course I double-checked
the image format and realized that there were only 12 bits of data there,
and the higher order bits were all 0. Then I got the bright idea of using a
12-bit mask, 0x0FF0, and it worked! I now have a very nice image of an LED
and a laser pointer side by side with what looks like all the appropriate
shades of gray.

So sorry if I wasted someone’s time. But maybe my foolish experience will be
beneficial to someone someday. Thanks to all the people who offered
suggestions.

Jerry–
View this message in context: http://www.nabble.com/help-with-displaying-grayscale-buffers-tp16599288p16701292.html
Sent from the SDL mailing list archive at Nabble.com.