Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
• Status: Solved
• Priority: Medium
• Security: Public
• Views: 219

# 10-bit images Displaying

Hi,

I receive 10-bit of gray shades encapsulated in 16-bit of data (2 chars). How can I display them in Windows API?
Do I have to convert them to 24bit Images before I can display them? I need the full gray shades for analysis. All other solutions will be less efficient and will not give us the desired result, this is already verified.
Any solutions are greatly appreciated.

Kind regards,

Martin
0
mphanke
• 2
• 2
1 Solution

Commented:
Your main problem is that it is impossible to make a greyscale image on better than 256 different greyscale tones on a PC.

The truth is that windows uses at most 8 bit per each color and in a greyscale each of the R G and B values are always identical, i.e. they are either all 0x20 or all 0x37 etc. The result is that there are only 256 different greysscale values.

Therefore your best bet is to do it like this and use 8 bit per pixel for the image.

Do the following:

step 1. construct a BMP header and BMP file header, initialize them with values, you want 8 bits per pixel.

Step 2. Construct a palette with room for 256 entries. Each entry is either 24 or 32 bits, so the palette is either 3 * 256 = 768 bytes or it is 4 * 256 == 1024 bytes.

step 3. Construct the image, use 1 byte per pixel and place the value 8 most significant bits corresponding to the greyscale - well some modification is probably needed for values very close to white and very close to black but otherwise this is correct, see discussion below.

step 4. Write it to file.

The image must in BMP format look like this:

The image is an array of lines. Each line is a number of bytes that is divisible by 4. If you use 1 byte per pixel and you get a number of bytes per line that is not a multiple of 4 add 1-3 garbage bytes at end of each line to make the line a multiple of 4 bytes.

Each line is thus an array of pixel info and possibly 1-3 bytes of garbage at the end. The garbage bytes aren't used when displaying the image but they're there to make each line be on a 4 byte alignment.

Each pixel info is 1 byte for 8 bit per pixel and is simply the palette index to use. Again for 256 different greyscale tones you can use the upper bits to get the palette index, since palette index x should point to a palette entry with R = x, G = x and B = x and A if present = 0.

The A value is only present in 32 bit per palette entry image and is the transparency value, you probably want the image to have transparency 0 so that the A value is always 0. (This means no transparency). If you don't use RGBA entries for the palette this entry is simply not there.

For a given greyscale tone value you want to find a given index in the range 0..255. Here 0 means completely black and 255 means completely white. Care must therefore be taken when converting 10 bit greyscale values to the 8 bit value x.

For example you can simply shift the value down by 2 bits and use x = grey >> 2;

However, this will cause troubles, a greyscale value such as 0x3fc1 isn't quite white but will become completely white after such a shift. Therefore you must be careful at the edges of the translation, especially on the white edge.

Probably you should do:

if (grey == 1023)
x = 255;
else if ((x = grey >> 2) == 255)
x = 254;
else if (grey > 0 && x == 0)
x = 1;

This will ensure that only 1023 maps to white while any value close to 1023 will map to 254. This will most likely produce a better image than simply doing x = grey >> 2;

You could also try a 'round to nearest' but again you should be careful with the values close to white and values close to black.

(grey + 2) >> 2; since >> 2 is the same as division by 4, adding 2 will give proper rounding. However, again you should check for white and black:

if (grey == 1023)
x = 255;
else if ((x = (grey + 2) >> 2) == 255)
x = 254;
else if (grey > 0 && x == 0)
x = 1;

Now, if this isn't good enough for you, I am sorry but you have to find a different platform than windows. Windows doesn't support better greyscale images than 8 bits. You can always manipulate algorithmically in windows and create file formats for better greyscale but you can't display them on a windows machine.

Converting to 24 bit is a detour, unless you want to fake better than 8 bit greyscale by making a picture that isn't really greyscale. In that case you can use 24 bit but doing so is probably not something you would want to try unless you really have to. I would think that using a better OS that provide support for 10 bit greyscale would be much easier.

Alf
0

Author Commented:
Hi,
thanks, I would like to use Linux, but this would cause severe trouble with our software and our customers. So I have to find ways how to get along without some very nice features of other OS's.

Martin
0

Commented:
Well, if you are stuck to windows you have no choice but to accept 8 bit greyscale images. The reason is that tones of grey are all such that R == G and G == B for the color, if R == G == B == 0 you have black, and for R == G == B == 255 you have white and any value in between give a different greyscale tone.

This gives maximum 256 and 8 bit greyscale.

Ignoring the least significant bits is what you need to do but pay special attention to the values 255 (white) and 0 (black).

However, your situation in this regard is better than if you have a lower than 8 bit resolution to start with. For example if you wanted to copy from 6 bit to 8 bit greyscale you need to make sure that 63 maps to 255 and not to 63*4 = 252 as would the result if you mindlessly did grey << 2.

Your case is sort of opposite and so you can do a grey >> 2 and if you don't mind that 1020 becomes all white then that's fine.

Alf
0

Author Commented:
Hi,

great and very extended answer to my question.

Martin
0

## Featured Post

• 2
• 2
Tackle projects and never again get stuck behind a technical roadblock.