RGBA to ARGB

Started by
17 comments, last by rays 13 years ago
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 */
}

This also converts ARGB to RGBA, by the way. :)
Advertisement
...


Thanks for that correction. | is indeed the bitwise OR operator not a bitwise addition operator. Edited the post accordingly.
Here is my way to do that:



unsigned int RGBAtoARGB(unsigned int rgba)

{

 unsigned int argb;

  // using Assembler (it has a special command to do that "ror" -> rotate right counter's bits)

 _asm mov eax, [rgba]
  _asm ror eax, 8
  _asm mov [argb], eax
 // eax (extended accumulator buffer) is a 32-bit integer counter.

 return argb;

}


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).


-me
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.
you could do it a stupidly easy way.

return ARGB(rgba.a, rgba.r, rgba.g, rgba.b);
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
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
Given that rgba is unsigned, omitting the masks should be safe:

unsigned int RGBAtoARGB( unsigned int rgba )
{
return (rgba << 24) | (rgba >> 8);
}


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.

This topic is closed to new replies.

Advertisement