0x3a's code is a start start. What you're trying to do is move the 8-bit value at shift 0 to shift 16 and the 8-bit value at shift 16 to shift 0, so:
unsigned int RGBAtoARGB( unsigned int rgba )
{
return
(rgba & 0xFF00FF00) | /* copy A and G channels */
((rgba >> 16) & 0xFF) | /* move B channel down */
((rgba & 0xFF) << 16); /* move R channel up */
}
P.S. if to test kdmiller3's code with rgba = 0x11223344 , result (argb)= 0x11443322 (when expecting 0x44112233). It's just swapping R & B values like (RGBA -> BGRA).
Don't use _asm keyword (or instructions) to do ror. Use intrisic _rotr if you want to use compiler specific functionality: #include <stdio.h>
inline unsigned int RGBAtoARGB(unsigned int rgba)
{
return _rotr(rgba, 8);
}
This will give opportunity for compiler to do better optimizations, because compiler doesn't optimize anything if he sees __asm keyword.
I misread the request so I thought you wanted an ARGB to ABGR. Derp de derp...
This should do what you're asking for, though the _rotr() version above is much slicker.
unsigned int RGBAtoARGB( unsigned int rgba )
{
return
((rgba & 0xFF) << 24) | /* move A up */
((rgba >> 8) & 0xFFFFFF); /* move RGB channels down */
}
Are the extra & really required? I havnt checked the standards themselves, but everything Ive ever used has set the "new bits" to 0 with << and >>? Otherwise seems the same as what we already have?
The _rotr solution is intresting, espically if CPU's implement it efficiently
IIRC the right-shift operator either does an arithmetic shift (sign-extending), or a logical shift (non-sign-extending), decided by the implementation...
AFAIK though, most implementations only do sign-extension on signed integers, and do logical shifts on unsigned integers. So it's safe in practice to leave off the masks (&'s), but unpredictable in theory.
Afaik C standard says that implementation specific functionality is for shift right on signed values. For unsigned values right shift always is logical.