Menu

#205 Color conversion wrong

open
Spacy
Graphics (20)
5
2006-08-26
2006-04-18
JSensebe
No

The color conversion from 15-bit to 24-bit does not
use the whole precision of the 8-bit components. It
should look something like this:

Red8bit = (Red5bit << 3) | (Red5bit >> 2);

etc.

Discussion

  • Spacy

    Spacy - 2006-05-26

    Logged In: YES
    user_id=1355343

    May you please tell me in which source file and at which
    line you found those mistakes?

     
  • JSensebe

    JSensebe - 2006-05-26

    Logged In: YES
    user_id=1505049

    I don't have the source code. You can see it by inspecting
    the output, either by copying the VBA window and pasting
    it into a paint program or by saving a PNG or BMP
    screenshot.

     
  • Spacy

    Spacy - 2006-08-25
    • assigned_to: nobody --> spacy51
    • status: open --> pending
     
  • Spacy

    Spacy - 2006-08-25

    Logged In: YES
    user_id=1355343

    I don't really understand what you want to do with your
    code, the second part looks like your are mixing the 3 most
    significant bits of the red color into the 3 last
    significant bits of output 8-bit color, which is of course
    just wrong, because there has to be 3 empty bits when
    covnerting from 5-bit to 8-bit color.

    VBA's code seems to be ok for me:

    Util.cpp:
    void utilUpdateSystemColorMaps()
    {
    switch(systemColorDepth) {
    case 16:
    {
    for(int i = 0; i < 0x10000; i++) {
    systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
    (((i & 0x3e0) >> 5) << systemGreenShift) |
    (((i & 0x7c00) >> 10) << systemBlueShift);
    }
    }
    break;
    case 24:
    case 32:
    {
    for(int i = 0; i < 0x10000; i++) {
    systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
    (((i & 0x3e0) >> 5) << systemGreenShift) |
    (((i & 0x7c00) >> 10) << systemBlueShift);
    }
    }
    break;
    }
    }

     
  • JSensebe

    JSensebe - 2006-08-25

    Logged In: YES
    user_id=1505049

    You're wrong. That's precisely my point. White in 15-bit
    color = 0x7FFF and white in 24-bit color = 0x00FFFFFF.
    Your conversion produces 0x00F8F8F8, which is not white.

    My example code very closely approximates Red8bit =
    Red5Bit * 255 / 31 (the exact answer) without slowing the
    program down with a bunch of multiplication and division.

    Here's a side-by-side comparision. Note that my method is
    off by one at most, while yours is off by as much as seven:

    x x*255/31 x<<3 (x<<3)|(x>>2)
    0 0 0 0
    1 8 8 8
    2 16 16 16
    3 24 24 24
    4 32 32 33
    5 41 40 41
    6 49 48 49
    7 57 56 57
    8 65 64 66
    9 74 72 74
    10 82 80 82
    11 90 88 90
    12 98 96 99
    13 106 104 107
    14 115 112 115
    15 123 120 123
    16 131 128 132
    17 139 136 140
    18 148 144 148
    19 156 152 156
    20 164 160 165
    21 172 168 173
    22 180 176 181
    23 189 184 189
    24 197 192 198
    25 205 200 206
    26 213 208 214
    27 222 216 222
    28 230 224 231
    29 238 232 239
    30 246 240 247
    31 255 248 255

    Alternatively, you could create a 32-entry table with the
    proper conversion and use a lookup. That would even allow
    you to easily add a brightness, contrast, and gamma
    controls in the future. :-)

     
  • JSensebe

    JSensebe - 2006-08-25
    • status: pending --> open
     
  • Spacy

    Spacy - 2006-08-26

    Logged In: YES
    user_id=1355343

    Ah, now I get it. Thank you very much for the fast response
    and the detailed explanation and the formula. I will also
    try to make an assembler-version out of this few lines ^_^

     
  • Spacy

    Spacy - 2006-08-26
    • status: open --> pending
     
  • Spacy

    Spacy - 2006-08-26

    Logged In: YES
    user_id=1355343

    Hm, just when I think mroe about it, I can sue the slower
    version with x*255/32 since VBA does not need this in real
    time but only once for every color when starting up, so
    speed does not matter much.

     
  • Spacy

    Spacy - 2006-08-26

    Logged In: YES
    user_id=1355343

    Hm, when I look at it closely, there needs to be much more
    changes than I thought, because the display engine only
    specifies then necessary bit-shifts for each color from
    5BitPerColor to 8BitPerColor, so there is no information
    about the number of bits of the destination format. For
    example there are 2 possible 16bit color modes: one with 5
    bit green and one with 6 bit green. imo, it would be best to
    let the display API's code decide how to convert the colors,
    because Direct3D for example supports even drawing 16 bit
    surfaces onto 32 bit display modes.

     
  • Spacy

    Spacy - 2006-08-26
    • status: pending --> open
     

Log in to post a comment.