?
Solved

10-bit images Displaying

Posted on 2003-03-17
4
Medium Priority
?
216 Views
Last Modified: 2010-04-01
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
Comment
Question by:mphanke
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 12

Accepted Solution

by:
Salte earned 1000 total points
ID: 8152447
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
 
LVL 1

Author Comment

by:mphanke
ID: 8152644
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
 
LVL 12

Expert Comment

by:Salte
ID: 8152857
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
 
LVL 1

Author Comment

by:mphanke
ID: 8159878
Hi,

great and very extended answer to my question.

Martin
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

800 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question