Dark Bit Factory & Gravity

PROGRAMMING => C / C++ /C# => Topic started by: Pixel_Outlaw on November 24, 2010

Title: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: Pixel_Outlaw on November 24, 2010
I'm currently up and running through the examples over at LazoFoo's site (which seems to be the defacto place to learn SDL) and I have realized that often the library wants an unsigned int value to assign color. I'm very used to working in RGB triplets I understand how they are stored in an int but I'm confused on how to manipulate the bits for converting between four bytes (for ABGR) and a single unsigned int.

I'm looking to write the 4 byte values to an int, and later to extract them from an unsigned int.

Alpha       Blue        Green       Red
00000000 00000000 00000000 00000000
Thanks again folks. Still getting my feet wet with this stuff. Bit level operators are not something I'm totally comfortable with yet.  ::)
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: LittleWhite on November 24, 2010
Hey,

It looks that the website is a place to learn SDL, all my classmates learnt there ...
I didn't go through :p but I know what you need. I think you should like to the documentation of SDL_MapRGB or SDL_MapRGBA :)

Otherwise:
Code: [Select]
unsigned int colour = 0xFF00FF00;
unsigned char a = colour >> 24 & 0xFF;
unsigned char r = colour >> 16 & 0xFF;
unsigned char g = colour >> 8 & 0xFF;
unsigned char b = colour & 0xFF;
Here we are :)

For putting all together, nearly the same:
Code: [Select]
unsigned char a = 0xFF;
unsigned char r =0xFF;
unsigned char g =0xFF;
unsigned char b = 0x00;
unsigned int colour = (a << 24) & 0xFF000000) + (r << 16) & 0x00FF0000) + ((g << 8) & 0x0000FF00) + (b & 0x000000FF)
Far to be optimised ... I am doing certainly some useless masking.

If you don't get the lines ... it's just moving bits (>> and <<) and masking (& -> AND)

Warning: Be careful with the endianness, because bits order will change ... so you should really use this SDL_MapRGB() :)
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: Pixel_Outlaw on November 24, 2010
Thank you.

This is pretty common in many of the graphics programming applications so this will be useful beyond SDL.
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: Jim on November 24, 2010
There's a small problem with Littlewhite's codes as they stand - you need brackets around the shifts, because & has a higher precedence than >>
Code: [Select]
unsigned int colour = 0xFF00FF00;
unsigned char a = (colour >> 24) & 0xFF;
unsigned char r = (colour >> 16) & 0xFF;
unsigned char g = (colour >> 8) & 0xFF;
unsigned char b = colour & 0xFF;

Jim
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: LittleWhite on November 24, 2010
Oops!
Jim is totally right of course :)
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: va!n on November 24, 2010
I think you can write more compact code to get r,g,b,a back to one uint value...

Code: [Select]
unsigned int colour = (a << 24 | (r << 16) | (g << 8) | b);
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: relsoft on November 26, 2010
You could also do it with macros:

Code: [Select]
#ifdef _ARGB
   #define ARGB_A(u) (((u) >> 24) & 0x000000FF) 
   #define ARGB_R(u) (((u) >> 16) & 0x000000FF)
   #define ARGB_G(u) (((u) >> 8)  & 0x000000FF)
   #define ARGB_B(u) (((u) >> 0)  & 0x000000FF)
   #define ARGB( r, g, b, a )   (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#else  //RGBA
   // reverse the process
#endif
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: energy on November 29, 2010
Perhaps working with pointers without shfting and bitmasking:

Its Masm but i think it can be done in inline asm for c++

.data
   color dd 0ffeeddcch               
.data?
   r db ?
   g db ?
   b db ?
   a db ?

 .code
main:
   invoke GetModuleHandle,NULL
      xor eax,eax
   
      ;Extracting RGBA bytes from DWORD
      lea edi,r
      lea esi,color
      mov ecx,4
      rep movsb
   
      mov color,0 ;Clear color

      ;Writing RGBA bytes to DWORD
      lea edi,color
      lea esi,r
      mov ecx,4
      rep movsb
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: hellfire on November 29, 2010
Real coders don't separate their RGBs ;)
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: Pixel_Outlaw on December 01, 2010
Yeah, real coders only use toggle switches for their Altairs too.

I'm really going to have to study more at the bit level. :crutches:
Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: hellfire on December 22, 2010
Alternatively you can avoid most of that bit-fiddling by using unions:
Code: [Select]
struct Color
{
   union
   {
      struct
      {
         unsigned char b,g,r,a;
      };
      unsigned int argb;
   };

   Color()
   {
   }

   Color(unsigned int col)
   {
      argb= col;
   }
};
This way the for bytes r,g,b,a occupy the same space as the integer argb.

Code: [Select]
   Color col;
   col= 0xffeeddcc;

   printf("Color: %d,%d,%d,%d \n", col.a, col.r, col.g, col.b);

Title: Re: [C++] Extracting 4 separate bytes from an unsigned int...
Post by: relsoft on December 23, 2010
OT: Hellfire:  "Can you see it?"

(http://rel.betterwebber.com/images/screenies/BF_EXscreenshot.png)