Thread: 16 bit colors

  1. #1
    Registered User morbuz's Avatar
    Join Date
    Aug 2001
    Posts
    35

    16 bit colors

    I'm reading about how to build up a 16-bit high color mode.
    This is supposed to be done by "simple bit shifting and masking operations", but I just don't get it.
    Concider the following macros:

    Code:
    // This builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
    #define _RGB16BIT555(r,g,b) ((b%32) + ((g%32) << 5) + ((r%32) << 10))
    
    // This builds a 16 bit color value in 5.6.5 format (Green dominate mode)
    #define _RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 6) + ((r%32) << 11))
    What is really going on in these macros?
    [Signature here. (Remove this!)]

  2. #2
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    the modului of the macros mask off the unwanted bits [32 = 2 ^5. 64 = 2 ^ 6]... perhaps they should use the & operator for more clarity... the range of values for 5 bit and 6 bit data are 0 to 31, and 0 to 65 respectively. the << operator moves the masked r, g, and b values into place... since they are masked to 5 and 6 bits, shifting them and adding them keeps their r, g, and b values exclusive of eachother... does this clear it up?

    hth...
    hasafraggin shizigishin oppashigger...

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Two problems there.

    Clamping using modulus

    You really do not have to clamp the RGBs, just ensure that you never pass a value larger than 31 (green will wrap) to your pixel function. But just in case you want to clamp them:

    Modulo is slower than using logical AND with powers of 2.

    Example: to computer pixel offset
    pixeloffset % 65536 -> slower
    pixeloffset & 0xFFFF -> faster same result

    Precompute
    Don't compute those colors on every pixel. Use tables.

    Code:
    typedef unsigned int WORD;
    
    WORD red[32];
    WORD grn[32];
    WORD blu[32];
    
    for (int i=0;i<32;i++)
    {
      red[i]=i<<11;
      grn[i]=i<<5;  //depending on card
      blu[i]=i;
    }
    Now for color all you do is:

    Code:
    WORD color=red[rvalue]+grn[gvalue]+blu[bvalue]
    This is assuming you have computed the correct pixeloffset/bank.
    Inline asm looks a bit different than actual MASM,but same idea.
    Code:
    asm
    {
    mov ax,0a000h      //screen seg - for buffer move seg of buffer
    mov es,bx
    mov di,word(pixeloffset)   
    mov ax,color
    stosw
    }
    You could store all color values as WORDs in a table, but accessing it would be slower than accessing 3 one dimensional arrays. It would also incur a few more multiplies/adds which you don't have to do. However, all bitmaps should be stored as WORDs. Color would correspond to the WORD in the bitmap. All could be done is asm and would be very fast.

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    164
    Why use WORDs? I guess most of you doesn't program in 16-bit, so DWORDs would be much faster even if the result has to be converted to WORDs later.
    // Gliptic

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yes, you could use DWORDS, but in real mode I doubt the speed would change much. Besides my inline asm does not allow the use of 32-bit registers. It is a 32-bit compiler, but only for Windows and not DOS. So, for protected mode and access to 32-bit registers, I'll have to download DJGPP.....again!!

    So, to use DWORDs would just be wasting space in my array.

  6. #6
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    using dwords to fill 24-bit rgbs is faster than just using 24-bits... i know that much... but so far as using a dword in place a word, i agree... the speed difference [if any] is negligable... especially when compared to the waste of memory...
    hasafraggin shizigishin oppashigger...

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    164
    What do you mean? There is no memory waste! The result is stored in registers. You store the values as WORDs but you zero extend them when you retrieve them. Some compilers may do this wrong.

  8. #8
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    i was referring to the pixel format's use in when blitting, for example... where extended period storage is used...
    hasafraggin shizigishin oppashigger...

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    164
    Ohh, sorry for that then. But the speed different is pretty noticable between 32 and 24-bit. Moving data to a missaligned memory is very slow and only every fourth pixel is aligned in 24-bit mode. In 32-bit mode, all pixels are aligned.
    // Gliptic

  10. #10
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    right, that was my point... [bankswitching on a 24-bit mode was such a hassle... now LFB has freed my soul...] what's the deal about little endian word ordering in 15/16-bit formats with VESA again? i remeber it was used/mentioned, but i forget how or why... thanks...
    hasafraggin shizigishin oppashigger...

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well, the fastest way to do this would be to use one of the packed MMX instructions. However, since my compiler does not support this......well I can't use MMX.

    But, I've downloaded DJGPP again and an IDE for the 32-bit assembler I have. So, it looks like real-mode will also be a thing of the past for me too. Using assembly in protected mode looks.....interesting.

  12. #12
    Registered User
    Join Date
    Sep 2001
    Posts
    164
    You can use MMX if you are going to convert at least four colors at a time. If you aren't, you won't gain much using MMX. BTW. You can't do table lookups using MMX.
    // Gliptic

  13. #13
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If you are not going to use four colors, just zero the fourth one out. You could still use MMX depending on which instruction you use.

  14. #14
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    having an alpha byte is still very useful though... provided that it's in the context of every pixel however... but having 256 states for every pixel independant of color boggles the mind! maybe some really complicated lifesim would use it... somehow...
    hasafraggin shizigishin oppashigger...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Decimal to 16 bit unsigned?
    By blurx in forum C Programming
    Replies: 5
    Last Post: 10-16-2008, 01:56 PM
  2. Replies: 7
    Last Post: 12-10-2004, 08:18 AM
  3. bit patterns of negtive numbers?
    By chunlee in forum C Programming
    Replies: 4
    Last Post: 11-08-2004, 08:20 AM
  4. Copy bit to bit
    By Coder2Die4 in forum C Programming
    Replies: 15
    Last Post: 06-26-2003, 09:58 AM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM