Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set a FourCC value in C++

Tags:

c++

fourcc

I want to set a FourCC value in C++, i.e. an unsigned 4 byte integer.

I suppose the obvious way is a #define, e.g.

#define FOURCC(a,b,c,d) ( (uint32) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) )

and then:

uint32 id( FOURCC('b','l','a','h') );

What is the most elegant way you can think to do this?

like image 280
Nick Avatar asked May 01 '09 13:05

Nick


3 Answers

You can make it a compile-time constant using:

template <int a, int b, int c, int d>
struct FourCC
{
    static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a;
};

unsigned int id(FourCC<'a', 'b', 'c', 'd'>::value);

With a little extra effort, you can make it check at compile time that each number passed in is between 0 and 255.

like image 117
James Hopkin Avatar answered Nov 12 '22 14:11

James Hopkin


uint32_t FourCC = *((uint32_t*)"blah");

Why not this?

EDIT: int -> uint32_t.

And no it does not cast a char** to uint32_t. It casts a (char*) to (uint32_t*) then dereferences the (uint32_t*). There is no endian-ness involved, since its assigning an uint32_tto an uint32_t. The only defects are the alignment and the I hadn't explicitly indicated a 32bit type.

like image 44
Sanjaya R Avatar answered Nov 12 '22 14:11

Sanjaya R


By using C++11 constexpr you can write something like:

constexpr uint32_t fourcc( char const p[5] )
{
    return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}

And then use it as:

fourcc( "blah" );

pros:

  • More readable,
  • if the string argument is known at compile time, then the function is evaluated at compile time (no run-time overhead).
  • doesn't depend on endianity (i.e. the first character of the argument will always be in the most significant byte of the fourcc).

cons:

  • Requires c++11 (or later) compiler.
like image 6
MaxP Avatar answered Nov 12 '22 15:11

MaxP