# RGB color conversion

Página 2/3
1 | | 3
NYYRIKKI wrote:

@Grauw If you want to take that approach then (VALUE+16)/32 is better... The problem is that you think that 255 should become 7 while actually you should think that 256 should become 8.

No, that way 8-bit values 0-47 translate to 3-bit value 0, you get way too much error there.

Simplifying the problem to grayscale, black is black and white is white. So the 8-bit (0-255) values are on a different scale than the 3-bit (0-7) values, they can’t be converted by simply dropping bits, you need to consider them on a linear scale as 0-1 where 0 is black and 1 is white.

The linear scale for 3-bit values is: 0.0, 0.143, 0.286, 0.429, 0.571, 0.714, 0.857, 1.0.

The linear scale for 8-bit values I’ll let you generate by yourself . But, for each value on the 8-bit scale, you need to pick the 3-bit scale’s value that is closest, in order to minimise the error.

Ok yes, I was wrong...

mars2000you wrote:

There's probably a better solution : screen 8 with his 256 colors ! Why degrad the colors to fit in screen 5 or 7 ?

Palette colors are fewer in number, but have a little bit more accuracy than screen 8 RGB values (to be exact: 1 bit extra for the blue value). So depending on input, conversion to screen 5 or 7 may provide better result than conversion to screen 8. Well okay - probably not for most images... If output as YJK data is allowed, then you can get much better results. Conversion formulas for this are in the V9958 data book.

Btw. good info there, Grauw! It's very easy: in true color, RGB goes from 0 to 255(256 levels), in MSX2 RGB goes from 0 to 7 (8 levels). To convert true color into MSX2 image, simply divide by 32 its 3 components:

RGB: 255, 153, 0
MSX2: 7, 4, 0

It's recommended a manual revision in order to get best aproximation, this is, perhaps in the example yo prefer something like 7,3,0 or 7,5,0 depending your image.

@AxelStone: So, you’re saying 8-bit colour (255, 224, 31) should convert to 3-bit colour (7, 7, 0)? As I elaborated above it should actually convert to (7, 6, 1). It becomes clear when you convert them to linear values in the range 0-1:

(255, 224, 31) -> (1.00, 0.88, 0.12)

(7, 7, 0) -> (1.00, 1.00, 0.00), error: (0.0, +0.12, -0.12)
(7, 6, 1) -> (1.00, 0.86, 0.14), error: (0.0, -0.02, +0.02)

As you can see, the value (7, 6, 1) is much closer to the actual colour represented by the 8-bit values. Therefore, divide-by-32 is not a good solution. In stead, divide-by-(255/7).

Consider that (0, 0, 0) is fully black in both scales, and (7, 7, 7) and (255, 255, 255) are fully white. Also consider the conversion from 3-bit values to 8-bit values. Does value 7 convert to 224, or to 255?

@Grauw But your aproximation of /32 is not well done: (255,224,31) / 32 = (7.9, 7, 0.96)

For me, 0.96 is clearly 1, so my first try should be (7,7,1), not (7,7,0). In the same point, 224 is in the limit. 255-224=31, so it seems wrong asign same color to 2 values separated by 31. The common sense is saying you "hey, they are not the same color", so most probably you should choose 6 not 7. In other words, you finally has selected (7,6,1) simply using human hand for final retouch.

You can see that even your method doesn't works if you don't apply human retouch: 255/7=36.4, if you divide 31/36.4 you get 0.85, so 3rd value (31) is even furhter from 1 than using /32 where you get 0.96.

In other words, whenever technique you could use, the human hand is finally needed.

AxelStone wrote:

@Grauw But your aproximation of /32 is not well done: (255,224,31) / 32 = (7.9, 7, 0.96)

But, 7 is the maximum value, so how can there be a value 7.9? I was assuming you were rounding down, but if you’re rounding normally, then 7.9 should become 8? Because 8 does not exist, it’s set to 7, introducing a new +0.13 error. The error should never get above 0.071 (= 1 / 7 / 2), if it does the colour is misallocated.

Colour (7, 7, 7) is the same as (255, 255, 255), both fully white. So, 255 must translate to 7.0, not 7.9. You are saying on PC there is a colour whiter than white? Or that (7, 7, 7) on the MSX is not actually white, but light gray?

Try to do the conversion the other way around. What is the 24-bit RGB value of (7, 3, 0)?

Uh... From the first post I could not see this coming such a big conversation Grauw wrote:

Try to do the conversion the other way around. What is the 24-bit RGB value of (7, 3, 0)?

Mmm perhaps you are right, your method needs less "human retouch" .

NYYRIKKI wrote:

Uh... From the first post I could not see this coming such a big conversation But it hasn't yet taken into acount the nonlinear DAC levels In the below code I got them in that l() function, I forgot from where I got them?

At the begining the differences between DAC levels are printed.
32, 40, 32, 40... mhm was that again about hardware savings or is it a trick suiting artists purposes?
some colors are in more harsh distance than 36, some are a more closer pack.

how does this fit a linear sheme of 9958 VUY mode - the 32,40,32,40 jumps would fit into a linear 5bit DAC, I assume things look identic on 9958.
the levels

```function l(n) {
c = new Array();
c = 0x06;
c = 0x20;
c = 0x48;
c = 0x68;
c = 0x90;
c = 0xb0;
c = 0xd8;
c = 0xf7;
return c[n];
}

the diffs:
0-1: 26
1-2: 40
2-3: 32
3-4: 40
4-5: 32
5-6: 40
6-7: 31
```

the html file showing the colors demo

```
function hex(n) {
n1 = n / 16; n2 = n%16;
s = "0123456789abcdef";
return "" + s.charAt(n1) + s.charAt(n2)
}

function l(n) {
c = new Array();
c = 0x06;
c = 0x20;
c = 0x48;
c = 0x68;
c = 0x90;
c = 0xb0;
c = 0xd8;
c = 0xf7;
return c[n];
}

for (i = 0; i < 7; i++) { document.write(''+i+'-'+(i+1)+': '+(l(i+1)-l(i))+'<br>'); }

for (g = 0; g <= 7; g++) {
document.write("<tr>");
for (b = 0; b <= 7; b++) {
for (r = 0; r <= 7; r++) {
document.write('<td width="16" height="16">');
document.write(" ");
document.write("</td>");
}
}
document.write("</tr>");
}

document.write('</tr><table>');
document.write('</td></tr><table>');

```
Página 2/3
1 | | 3